]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'cpus4096-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 24 Jul 2008 01:37:44 +0000 (18:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 24 Jul 2008 01:37:44 +0000 (18:37 -0700)
* 'cpus4096-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (31 commits)
  NR_CPUS: Replace NR_CPUS in speedstep-centrino.c
  cpumask: Provide a generic set of CPUMASK_ALLOC macros, FIXUP
  NR_CPUS: Replace NR_CPUS in cpufreq userspace routines
  NR_CPUS: Replace per_cpu(..., smp_processor_id()) with __get_cpu_var
  NR_CPUS: Replace NR_CPUS in arch/x86/kernel/genapic_flat_64.c
  NR_CPUS: Replace NR_CPUS in arch/x86/kernel/genx2apic_uv_x.c
  NR_CPUS: Replace NR_CPUS in arch/x86/kernel/cpu/proc.c
  NR_CPUS: Replace NR_CPUS in arch/x86/kernel/cpu/mcheck/mce_64.c
  cpumask: Optimize cpumask_of_cpu in lib/smp_processor_id.c, fix
  cpumask: Use optimized CPUMASK_ALLOC macros in the centrino_target
  cpumask: Provide a generic set of CPUMASK_ALLOC macros
  cpumask: Optimize cpumask_of_cpu in lib/smp_processor_id.c
  cpumask: Optimize cpumask_of_cpu in kernel/time/tick-common.c
  cpumask: Optimize cpumask_of_cpu in drivers/misc/sgi-xp/xpc_main.c
  cpumask: Optimize cpumask_of_cpu in arch/x86/kernel/ldt.c
  cpumask: Optimize cpumask_of_cpu in arch/x86/kernel/io_apic_64.c
  cpumask: Replace cpumask_of_cpu with cpumask_of_cpu_ptr
  Revert "cpumask: introduce new APIs"
  cpumask: make for_each_cpu_mask a bit smaller
  net: Pass reference to cpumask variable in net/sunrpc/svc.c
  ...

Fix up trivial conflicts in drivers/cpufreq/cpufreq.c manually

1648 files changed:
CREDITS
Documentation/ABI/testing/sysfs-dev [new file with mode: 0644]
Documentation/DMA-attributes.txt
Documentation/DocBook/gadget.tmpl
Documentation/DocBook/uio-howto.tmpl
Documentation/HOWTO
Documentation/feature-removal-schedule.txt
Documentation/filesystems/bfs.txt
Documentation/filesystems/sysfs.txt
Documentation/ia64/paravirt_ops.txt [new file with mode: 0644]
Documentation/input/gameport-programming.txt
Documentation/input/input.txt
Documentation/input/joystick-api.txt
Documentation/input/joystick-parport.txt
Documentation/input/joystick.txt
Documentation/kernel-parameters.txt
Documentation/md.txt
Documentation/networking/e1000.txt
Documentation/networking/udplite.txt
Documentation/powerpc/booting-without-of.txt
Documentation/powerpc/dts-bindings/fsl/cpm_qe/gpio.txt [new file with mode: 0644]
Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/usb.txt
Documentation/powerpc/dts-bindings/fsl/mcu-mpc8349emitx.txt [new file with mode: 0644]
Documentation/powerpc/dts-bindings/fsl/pmc.txt [new file with mode: 0644]
Documentation/powerpc/dts-bindings/fsl/tsec.txt
Documentation/powerpc/dts-bindings/fsl/upm-nand.txt [new file with mode: 0644]
Documentation/powerpc/dts-bindings/gpio/led.txt [new file with mode: 0644]
Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl
Documentation/specialix.txt
Documentation/sysfs-rules.txt
Documentation/telephony/ixj.txt
Documentation/usb/gadget_serial.txt
Documentation/usb/persist.txt
Documentation/usb/uhci.txt [deleted file]
Documentation/video4linux/w9968cf.txt
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/common/dmabounce.c
arch/arm/common/locomo.c
arch/arm/common/sa1111.c
arch/arm/common/scoop.c
arch/arm/configs/ezx_defconfig [new file with mode: 0644]
arch/arm/kernel/Makefile
arch/arm/kernel/ecard.c
arch/arm/kernel/kgdb.c [new file with mode: 0644]
arch/arm/kernel/setup.c
arch/arm/kernel/time.c
arch/arm/kernel/traps.c
arch/arm/mach-integrator/impd1.c
arch/arm/mach-integrator/lm.c
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/Makefile
arch/arm/mach-pxa/clock.c
arch/arm/mach-pxa/clock.h
arch/arm/mach-pxa/cm-x270-pci.c
arch/arm/mach-pxa/cm-x270-pci.h
arch/arm/mach-pxa/cm-x270.c
arch/arm/mach-pxa/corgi.c
arch/arm/mach-pxa/devices.c
arch/arm/mach-pxa/devices.h
arch/arm/mach-pxa/e400_lcd.c [new file with mode: 0644]
arch/arm/mach-pxa/e740_lcd.c [new file with mode: 0644]
arch/arm/mach-pxa/e750_lcd.c [new file with mode: 0644]
arch/arm/mach-pxa/e800_lcd.c [new file with mode: 0644]
arch/arm/mach-pxa/em-x270.c
arch/arm/mach-pxa/eseries.c
arch/arm/mach-pxa/eseries_udc.c [new file with mode: 0644]
arch/arm/mach-pxa/ezx.c [new file with mode: 0644]
arch/arm/mach-pxa/littleton.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/magician.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/mfp-pxa2xx.c
arch/arm/mach-pxa/palmtx.c [new file with mode: 0644]
arch/arm/mach-pxa/pcm027.c
arch/arm/mach-pxa/pcm990-baseboard.c
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa300.c
arch/arm/mach-pxa/pxa320.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/pxa930.c [new file with mode: 0644]
arch/arm/mach-pxa/reset.c [new file with mode: 0644]
arch/arm/mach-pxa/saar.c [new file with mode: 0644]
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/ssp.c
arch/arm/mach-pxa/tavorevb.c [new file with mode: 0644]
arch/arm/mach-pxa/tosa-bt.c [new file with mode: 0644]
arch/arm/mach-pxa/tosa.c
arch/arm/mach-pxa/trizeps4.c
arch/arm/mach-pxa/zylonite.c
arch/arm/mach-pxa/zylonite_pxa300.c
arch/arm/mach-pxa/zylonite_pxa320.c
arch/arm/mach-sa1100/clock.c
arch/arm/mm/Makefile
arch/arm/plat-omap/mailbox.c
arch/arm/tools/mach-types
arch/avr32/kernel/cpu.c
arch/avr32/mach-at32ap/at32ap700x.c
arch/blackfin/Kconfig
arch/ia64/Kconfig
arch/ia64/Makefile
arch/ia64/kernel/Makefile
arch/ia64/kernel/acpi.c
arch/ia64/kernel/cpufreq/acpi-cpufreq.c
arch/ia64/kernel/entry.S
arch/ia64/kernel/err_inject.c
arch/ia64/kernel/head.S
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/irq_ia64.c
arch/ia64/kernel/ivt.S
arch/ia64/kernel/minstate.h
arch/ia64/kernel/module.c
arch/ia64/kernel/nr-irqs.c [new file with mode: 0644]
arch/ia64/kernel/paravirt.c [new file with mode: 0644]
arch/ia64/kernel/paravirt_inst.h [new file with mode: 0644]
arch/ia64/kernel/paravirtentry.S [new file with mode: 0644]
arch/ia64/kernel/setup.c
arch/ia64/kernel/smpboot.c
arch/ia64/kernel/time.c
arch/ia64/kernel/vmlinux.lds.S
arch/mips/kernel/rtlx.c
arch/mips/sibyte/common/sb_tbprof.c
arch/powerpc/Kconfig
arch/powerpc/Kconfig.debug
arch/powerpc/boot/Makefile
arch/powerpc/boot/dts/mpc7448hpc2.dts
arch/powerpc/boot/dts/mpc8313erdb.dts
arch/powerpc/boot/dts/mpc8610_hpcd.dts
arch/powerpc/configs/85xx/mpc8544_ds_defconfig
arch/powerpc/configs/85xx/mpc8572_ds_defconfig
arch/powerpc/configs/mpc85xx_defconfig
arch/powerpc/configs/mpc8610_hpcd_defconfig
arch/powerpc/configs/mpc8641_hpcn_defconfig
arch/powerpc/configs/ppc6xx_defconfig [new file with mode: 0644]
arch/powerpc/configs/ps3_defconfig
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/head_fsl_booke.S
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/kgdb.c [new file with mode: 0644]
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/prom_parse.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/stacktrace.c
arch/powerpc/kernel/sysfs.c
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/lib/feature-fixups.c
arch/powerpc/lib/string.S
arch/powerpc/platforms/52xx/Kconfig
arch/powerpc/platforms/82xx/Kconfig
arch/powerpc/platforms/82xx/ep8248e.c
arch/powerpc/platforms/83xx/Kconfig
arch/powerpc/platforms/83xx/Makefile
arch/powerpc/platforms/83xx/mpc831x_rdb.c
arch/powerpc/platforms/83xx/mpc832x_mds.c
arch/powerpc/platforms/83xx/mpc832x_rdb.c
arch/powerpc/platforms/83xx/mpc834x_itx.c
arch/powerpc/platforms/83xx/mpc834x_mds.c
arch/powerpc/platforms/83xx/mpc836x_mds.c
arch/powerpc/platforms/83xx/mpc836x_rdk.c
arch/powerpc/platforms/83xx/mpc837x_mds.c
arch/powerpc/platforms/83xx/mpc837x_rdb.c
arch/powerpc/platforms/83xx/mpc83xx.h
arch/powerpc/platforms/83xx/pci.c [deleted file]
arch/powerpc/platforms/83xx/sbc834x.c
arch/powerpc/platforms/83xx/suspend-asm.S [new file with mode: 0644]
arch/powerpc/platforms/83xx/suspend.c [new file with mode: 0644]
arch/powerpc/platforms/83xx/usb.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/mpc85xx_ds.c
arch/powerpc/platforms/86xx/Kconfig
arch/powerpc/platforms/86xx/mpc8610_hpcd.c
arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
arch/powerpc/platforms/Kconfig
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/cell/Kconfig
arch/powerpc/platforms/cell/Makefile
arch/powerpc/platforms/cell/cbe_powerbutton.c [new file with mode: 0644]
arch/powerpc/platforms/cell/cbe_thermal.c
arch/powerpc/platforms/cell/cpufreq_spudemand.c [new file with mode: 0644]
arch/powerpc/platforms/cell/iommu.c
arch/powerpc/platforms/cell/pervasive.c
arch/powerpc/platforms/cell/pervasive.h
arch/powerpc/platforms/cell/ras.c
arch/powerpc/platforms/cell/spu_base.c
arch/powerpc/platforms/chrp/pci.c
arch/powerpc/platforms/fsl_uli1575.c
arch/powerpc/platforms/iseries/Kconfig
arch/powerpc/platforms/iseries/iommu.c
arch/powerpc/platforms/pasemi/iommu.c
arch/powerpc/platforms/powermac/setup.c
arch/powerpc/platforms/ps3/Kconfig
arch/powerpc/platforms/ps3/device-init.c
arch/powerpc/platforms/ps3/system-bus.c
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/pseries/eeh.c
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/sysdev/axonram.c
arch/powerpc/sysdev/dart_iommu.c
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/fsl_pci.h
arch/powerpc/sysdev/fsl_soc.c
arch/powerpc/sysdev/fsl_soc.h
arch/powerpc/sysdev/ipic.c
arch/powerpc/sysdev/qe_lib/qe.c
arch/powerpc/sysdev/qe_lib/ucc.c
arch/powerpc/sysdev/qe_lib/ucc_fast.c
arch/s390/kernel/smp.c
arch/s390/kernel/time.c
arch/sh/boards/renesas/migor/setup.c
arch/sh/drivers/dma/dma-sysfs.c
arch/sparc/Makefile
arch/sparc/kernel/apc.c
arch/sparc/kernel/asm-offsets.c
arch/sparc/kernel/ebus.c
arch/sparc/kernel/entry.S
arch/sparc/kernel/etrap.S
arch/sparc/kernel/head.S
arch/sparc/kernel/idprom.c
arch/sparc/kernel/ioport.c
arch/sparc/kernel/irq.c
arch/sparc/kernel/process.c
arch/sparc/kernel/rtrap.S
arch/sparc/kernel/setup.c
arch/sparc/kernel/smp.c
arch/sparc/kernel/sun4c_irq.c
arch/sparc/kernel/sun4d_irq.c
arch/sparc/kernel/sun4m_irq.c
arch/sparc/kernel/sun4m_smp.c
arch/sparc/kernel/time.c
arch/sparc/kernel/traps.c
arch/sparc/kernel/wof.S
arch/sparc/kernel/wuf.S
arch/sparc/mm/fault.c
arch/sparc/mm/init.c
arch/sparc/mm/srmmu.c
arch/sparc/mm/tsunami.S
arch/sparc64/Kconfig
arch/sparc64/Makefile
arch/sparc64/defconfig
arch/sparc64/kernel/central.c
arch/sparc64/kernel/ds.c
arch/sparc64/kernel/ebus.c
arch/sparc64/kernel/hvapi.c
arch/sparc64/kernel/of_device.c
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci_msi.c
arch/sparc64/kernel/pci_sun4v.c
arch/sparc64/kernel/process.c
arch/sparc64/kernel/smp.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/kernel/sys_sparc.c
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/sysfs.c
arch/sparc64/kernel/traps.c
arch/sparc64/kernel/ttable.S
arch/sparc64/kernel/unaligned.c
arch/sparc64/kernel/vio.c
arch/sparc64/lib/copy_page.S
arch/sparc64/mm/fault.c
arch/sparc64/mm/tsb.c
arch/sparc64/mm/ultra.S
arch/um/include/init.h
arch/x86/Kconfig
arch/x86/Kconfig.cpu
arch/x86/Kconfig.debug
arch/x86/boot/edd.c
arch/x86/boot/pm.c
arch/x86/configs/i386_defconfig
arch/x86/configs/x86_64_defconfig
arch/x86/ia32/ia32_signal.c
arch/x86/ia32/ia32entry.S
arch/x86/kernel/Makefile
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/acpi/sleep.c
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/amd_iommu_init.c
arch/x86/kernel/aperture_64.c
arch/x86/kernel/apic_32.c
arch/x86/kernel/apic_64.c
arch/x86/kernel/asm-offsets_64.c
arch/x86/kernel/bios_uv.c [new file with mode: 0644]
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/amd_64.c
arch/x86/kernel/cpu/bugs.c
arch/x86/kernel/cpu/common_64.c
arch/x86/kernel/cpu/cpufreq/powernow-k7.h
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/intel_cacheinfo.c
arch/x86/kernel/cpu/mcheck/mce_64.c
arch/x86/kernel/cpu/mcheck/p4.c
arch/x86/kernel/cpu/mcheck/therm_throt.c
arch/x86/kernel/cpu/perfctr-watchdog.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/e820.c
arch/x86/kernel/early-quirks.c
arch/x86/kernel/entry_32.S
arch/x86/kernel/entry_64.S
arch/x86/kernel/genx2apic_uv_x.c
arch/x86/kernel/head64.c
arch/x86/kernel/head_64.S
arch/x86/kernel/io_apic_32.c
arch/x86/kernel/io_apic_64.c
arch/x86/kernel/io_delay.c
arch/x86/kernel/ipi.c
arch/x86/kernel/irq_32.c
arch/x86/kernel/kdebugfs.c
arch/x86/kernel/kprobes.c
arch/x86/kernel/microcode.c
arch/x86/kernel/module_64.c
arch/x86/kernel/mpparse.c
arch/x86/kernel/msr.c
arch/x86/kernel/nmi.c
arch/x86/kernel/numaq_32.c
arch/x86/kernel/paravirt.c
arch/x86/kernel/pci-calgary_64.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/pci-gart_64.c
arch/x86/kernel/pci-nommu.c
arch/x86/kernel/pci-swiotlb_64.c
arch/x86/kernel/process.c
arch/x86/kernel/process_64.c
arch/x86/kernel/ptrace.c
arch/x86/kernel/reboot.c
arch/x86/kernel/setup.c
arch/x86/kernel/setup_percpu.c
arch/x86/kernel/signal_32.c
arch/x86/kernel/signal_64.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/smpcommon_32.c [deleted file]
arch/x86/kernel/step.c
arch/x86/kernel/time_32.c
arch/x86/kernel/traps_32.c
arch/x86/kernel/traps_64.c
arch/x86/kernel/visws_quirks.c
arch/x86/kernel/vmi_32.c
arch/x86/lguest/boot.c
arch/x86/mach-default/setup.c
arch/x86/mach-es7000/es7000plat.c
arch/x86/mm/Makefile
arch/x86/mm/dump_pagetables.c
arch/x86/mm/init_32.c
arch/x86/mm/init_64.c
arch/x86/mm/memtest.c [new file with mode: 0644]
arch/x86/mm/numa_64.c
arch/x86/mm/pat.c
arch/x86/pci/Makefile
arch/x86/pci/early.c
arch/x86/pci/legacy.c
arch/x86/pci/numaq_32.c [moved from arch/x86/pci/numa.c with 97% similarity]
arch/x86/pci/pci.h
arch/x86/pci/visws.c
arch/x86/vdso/Makefile
arch/x86/vdso/vdso32-setup.c
arch/x86/vdso/vdso32.S
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/multicalls.c
arch/x86/xen/setup.c
arch/x86/xen/smp.c
arch/x86/xen/suspend.c
arch/x86/xen/xen-asm_32.S [moved from arch/x86/xen/xen-asm.S with 100% similarity]
arch/x86/xen/xen-asm_64.S [new file with mode: 0644]
arch/x86/xen/xen-head.S
arch/x86/xen/xen-ops.h
arch/xtensa/Kconfig
block/bsg.c
block/genhd.c
crypto/async_tx/async_memcpy.c
crypto/async_tx/async_memset.c
crypto/async_tx/async_tx.c
crypto/async_tx/async_xor.c
drivers/acpi/fan.c
drivers/acpi/glue.c
drivers/acpi/processor_core.c
drivers/acpi/scan.c
drivers/acpi/thermal.c
drivers/acpi/video.c
drivers/base/Kconfig
drivers/base/base.h
drivers/base/class.c
drivers/base/core.c
drivers/base/cpu.c
drivers/base/memory.c
drivers/base/node.c
drivers/base/power/trace.c
drivers/base/sys.c
drivers/base/topology.c
drivers/block/aoe/aoechr.c
drivers/block/paride/pg.c
drivers/block/paride/pt.c
drivers/block/pktcdvd.c
drivers/char/Kconfig
drivers/char/Makefile
drivers/char/amiserial.c
drivers/char/cyclades.c
drivers/char/dsp56k.c
drivers/char/epca.c
drivers/char/esp.c
drivers/char/hw_random/Kconfig
drivers/char/hw_random/Makefile
drivers/char/hw_random/n2-asm.S [new file with mode: 0644]
drivers/char/hw_random/n2-drv.c [new file with mode: 0644]
drivers/char/hw_random/n2rng.h [new file with mode: 0644]
drivers/char/ip2/ip2main.c
drivers/char/ipmi/ipmi_devintf.c
drivers/char/isicom.c
drivers/char/istallion.c
drivers/char/keyboard.c
drivers/char/lp.c
drivers/char/mem.c
drivers/char/misc.c
drivers/char/mmtimer.c
drivers/char/moxa.c
drivers/char/mxser.c
drivers/char/n_hdlc.c
drivers/char/nvram.c
drivers/char/pcmcia/cm4000_cs.c
drivers/char/pcmcia/cm4040_cs.c
drivers/char/pcmcia/synclink_cs.c
drivers/char/ppdev.c
drivers/char/raw.c
drivers/char/riscom8.c
drivers/char/rocket.c
drivers/char/snsc.c
drivers/char/specialix.c
drivers/char/stallion.c
drivers/char/sx.c
drivers/char/synclink.c
drivers/char/synclink_gt.c
drivers/char/synclinkmp.c
drivers/char/tty_io.c
drivers/char/tty_ldisc.c [new file with mode: 0644]
drivers/char/vc_screen.c
drivers/char/viotape.c
drivers/char/vme_scc.c
drivers/char/vt.c
drivers/char/xilinx_hwicap/xilinx_hwicap.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_stats.c
drivers/cpufreq/freq_table.c
drivers/cpuidle/sysfs.c
drivers/dca/dca-core.c
drivers/dca/dca-sysfs.c
drivers/dma/Kconfig
drivers/dma/Makefile
drivers/dma/dmaengine.c
drivers/dma/dmatest.c [new file with mode: 0644]
drivers/dma/dw_dmac.c [new file with mode: 0644]
drivers/dma/dw_dmac_regs.h [new file with mode: 0644]
drivers/dma/fsldma.c
drivers/dma/ioat.c
drivers/dma/ioat_dca.c
drivers/dma/ioat_dma.c
drivers/dma/ioatdma.h
drivers/dma/ioatdma_hw.h
drivers/dma/ioatdma_registers.h
drivers/dma/iop-adma.c
drivers/dma/mv_xor.c [new file with mode: 0644]
drivers/dma/mv_xor.h [new file with mode: 0644]
drivers/edac/cell_edac.c
drivers/eisa/Makefile
drivers/eisa/eisa-bus.c
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/max7301.c [new file with mode: 0644]
drivers/gpio/pcf857x.c
drivers/hid/hid-core.c
drivers/hid/hid-input-quirks.c
drivers/hid/hid-input.c
drivers/hid/hidraw.c
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/hid-quirks.c
drivers/hid/usbhid/hiddev.c
drivers/hid/usbhid/usbkbd.c
drivers/hid/usbhid/usbmouse.c
drivers/hwmon/hdaps.c
drivers/hwmon/hwmon.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-dev.c
drivers/ide/Kconfig
drivers/ide/arm/icside.c
drivers/ide/arm/ide_arm.c
drivers/ide/arm/palm_bk3710.c
drivers/ide/arm/rapide.c
drivers/ide/h8300/ide-h8300.c
drivers/ide/ide-atapi.c
drivers/ide/ide-cd.c
drivers/ide/ide-cd.h
drivers/ide/ide-cd_ioctl.c
drivers/ide/ide-disk.c
drivers/ide/ide-dma.c
drivers/ide/ide-floppy.c
drivers/ide/ide-generic.c
drivers/ide/ide-io.c
drivers/ide/ide-iops.c
drivers/ide/ide-lib.c
drivers/ide/ide-pnp.c
drivers/ide/ide-probe.c
drivers/ide/ide-proc.c
drivers/ide/ide-tape.c
drivers/ide/ide-taskfile.c
drivers/ide/ide.c
drivers/ide/legacy/buddha.c
drivers/ide/legacy/falconide.c
drivers/ide/legacy/gayle.c
drivers/ide/legacy/ide-4drives.c
drivers/ide/legacy/ide-cs.c
drivers/ide/legacy/ide_platform.c
drivers/ide/legacy/macide.c
drivers/ide/legacy/q40ide.c
drivers/ide/mips/au1xxx-ide.c
drivers/ide/mips/swarm.c
drivers/ide/pci/aec62xx.c
drivers/ide/pci/alim15x3.c
drivers/ide/pci/amd74xx.c
drivers/ide/pci/cmd640.c
drivers/ide/pci/cmd64x.c
drivers/ide/pci/cs5520.c
drivers/ide/pci/cs5535.c
drivers/ide/pci/delkin_cb.c
drivers/ide/pci/hpt34x.c
drivers/ide/pci/hpt366.c
drivers/ide/pci/ns87415.c
drivers/ide/pci/pdc202xx_old.c
drivers/ide/pci/piix.c
drivers/ide/pci/scc_pata.c
drivers/ide/pci/serverworks.c
drivers/ide/pci/sgiioc4.c
drivers/ide/pci/siimage.c
drivers/ide/pci/sl82c105.c
drivers/ide/pci/tc86c001.c
drivers/ide/pci/via82cxxx.c
drivers/ide/ppc/pmac.c
drivers/ide/setup-pci.c
drivers/ieee1394/dv1394.c
drivers/ieee1394/nodemgr.c
drivers/ieee1394/raw1394.c
drivers/ieee1394/video1394.c
drivers/infiniband/core/cm.c
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/input/evbug.c
drivers/input/evdev.c
drivers/input/ff-memless.c
drivers/input/gameport/emu10k1-gp.c
drivers/input/gameport/gameport.c
drivers/input/gameport/lightning.c
drivers/input/gameport/ns558.c
drivers/input/input.c
drivers/input/joystick/a3d.c
drivers/input/joystick/amijoy.c
drivers/input/joystick/cobra.c
drivers/input/joystick/db9.c
drivers/input/joystick/gf2k.c
drivers/input/joystick/grip.c
drivers/input/joystick/grip_mp.c
drivers/input/joystick/guillemot.c
drivers/input/joystick/iforce/iforce-ff.c
drivers/input/joystick/iforce/iforce-main.c
drivers/input/joystick/iforce/iforce-packets.c
drivers/input/joystick/iforce/iforce-serio.c
drivers/input/joystick/iforce/iforce-usb.c
drivers/input/joystick/iforce/iforce.h
drivers/input/joystick/interact.c
drivers/input/joystick/joydump.c
drivers/input/joystick/magellan.c
drivers/input/joystick/spaceball.c
drivers/input/joystick/spaceorb.c
drivers/input/joystick/stinger.c
drivers/input/joystick/tmdc.c
drivers/input/joystick/turbografx.c
drivers/input/joystick/twidjoy.c
drivers/input/joystick/warrior.c
drivers/input/joystick/xpad.c
drivers/input/keyboard/amikbd.c
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/lkkbd.c
drivers/input/keyboard/pxa27x_keypad.c
drivers/input/keyboard/sunkbd.c
drivers/input/keyboard/tosakbd.c
drivers/input/keyboard/xtkbd.c
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/ati_remote.c
drivers/input/misc/ati_remote2.c
drivers/input/misc/keyspan_remote.c
drivers/input/misc/powermate.c
drivers/input/misc/sgi_btns.c [new file with mode: 0644]
drivers/input/misc/wistron_btns.c
drivers/input/misc/yealink.c
drivers/input/mouse/appletouch.c
drivers/input/mouse/atarimouse.c
drivers/input/mouse/hil_ptr.c
drivers/input/mouse/inport.c
drivers/input/mouse/logibm.c
drivers/input/mouse/pc110pad.c
drivers/input/mouse/sermouse.c
drivers/input/serio/Kconfig
drivers/input/serio/Makefile
drivers/input/serio/ct82c710.c
drivers/input/serio/hil_mlc.c
drivers/input/serio/hp_sdc.c
drivers/input/serio/hp_sdc_mlc.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/libps2.c
drivers/input/serio/q40kbd.c
drivers/input/serio/rpckbd.c
drivers/input/serio/serio.c
drivers/input/serio/xilinx_ps2.c [new file with mode: 0644]
drivers/input/tablet/acecad.c
drivers/input/tablet/aiptek.c
drivers/input/tablet/gtco.c
drivers/input/tablet/kbtab.c
drivers/input/tablet/wacom.h
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/gunze.c
drivers/input/touchscreen/h3600_ts_input.c
drivers/input/touchscreen/htcpen.c [new file with mode: 0644]
drivers/input/touchscreen/inexio.c [new file with mode: 0644]
drivers/input/touchscreen/migor_ts.c [new file with mode: 0644]
drivers/input/touchscreen/touchit213.c [new file with mode: 0644]
drivers/input/touchscreen/usbtouchscreen.c
drivers/input/touchscreen/wm9712.c
drivers/isdn/capi/capi.c
drivers/macintosh/adb.c
drivers/macintosh/adbhid.c
drivers/mca/mca-bus.c
drivers/md/bitmap.c
drivers/md/dm-crypt.c
drivers/md/dm-linear.c
drivers/md/dm-log.c
drivers/md/dm-mpath.c
drivers/md/dm-snap.c
drivers/md/dm-snap.h
drivers/md/dm-table.c
drivers/md/dm.c
drivers/md/dm.h
drivers/md/faulty.c
drivers/md/linear.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/dvb/dvb-core/dvbdev.c
drivers/memstick/host/jmb38x_ms.c
drivers/message/fusion/mptbase.c
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptfc.c
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/mfd-core.c [new file with mode: 0644]
drivers/mfd/tc6393xb.c [new file with mode: 0644]
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/hpilo.c [new file with mode: 0644]
drivers/misc/hpilo.h [new file with mode: 0644]
drivers/misc/phantom.c
drivers/mmc/card/mmc_test.c
drivers/mmc/card/queue.c
drivers/mmc/host/au1xmmc.c
drivers/mmc/host/pxamci.c
drivers/mmc/host/s3cmci.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
drivers/mtd/devices/block2mtd.c
drivers/mtd/mtdchar.c
drivers/mtd/nand/cmx270_nand.c
drivers/net/3c59x.c
drivers/net/8139too.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/arm/at91_ether.c
drivers/net/arm/at91_ether.h
drivers/net/arm/ep93xx_eth.c
drivers/net/arm/etherh.c
drivers/net/atl1e/Makefile [new file with mode: 0644]
drivers/net/atl1e/atl1e.h [new file with mode: 0644]
drivers/net/atl1e/atl1e_ethtool.c [new file with mode: 0644]
drivers/net/atl1e/atl1e_hw.c [new file with mode: 0644]
drivers/net/atl1e/atl1e_hw.h [new file with mode: 0644]
drivers/net/atl1e/atl1e_main.c [new file with mode: 0644]
drivers/net/atl1e/atl1e_param.c [new file with mode: 0644]
drivers/net/atlx/atl1.c
drivers/net/au1000_eth.c
drivers/net/bfin_mac.c
drivers/net/bonding/bond_main.c
drivers/net/cpmac.c
drivers/net/dm9000.c
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_main.c
drivers/net/e1000/e1000_osdep.h
drivers/net/e1000/e1000_param.c
drivers/net/fec_mpc52xx.c
drivers/net/fs_enet/Makefile
drivers/net/fs_enet/fs_enet-main.c
drivers/net/fs_enet/fs_enet.h
drivers/net/fs_enet/mac-fcc.c
drivers/net/fs_enet/mac-fec.c
drivers/net/fs_enet/mac-scc.c
drivers/net/fs_enet/mii-bitbang.c
drivers/net/fs_enet/mii-fec.c
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/gianfar_ethtool.c
drivers/net/hamradio/bpqether.c
drivers/net/hamradio/hdlcdrv.c
drivers/net/hp-plus.c
drivers/net/hp.c
drivers/net/igb/igb_main.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/macb.c
drivers/net/macvlan.c
drivers/net/meth.c
drivers/net/mv643xx_eth.c
drivers/net/myri10ge/myri10ge.c
drivers/net/ne.c
drivers/net/ne2.c
drivers/net/netxen/Makefile
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_ctx.c [new file with mode: 0644]
drivers/net/netxen/netxen_nic_ethtool.c
drivers/net/netxen/netxen_nic_hdr.h
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_hw.h
drivers/net/netxen/netxen_nic_init.c
drivers/net/netxen/netxen_nic_isr.c [deleted file]
drivers/net/netxen/netxen_nic_main.c
drivers/net/netxen/netxen_nic_niu.c
drivers/net/netxen/netxen_nic_phan_reg.h
drivers/net/phy/marvell.c
drivers/net/ppp_generic.c
drivers/net/r6040.c
drivers/net/r8169.c
drivers/net/sfc/efx.c
drivers/net/sfc/falcon.c
drivers/net/sfc/net_driver.h
drivers/net/sh_eth.c
drivers/net/smc91x.c
drivers/net/smc91x.h
drivers/net/sunhme.c
drivers/net/tc35815.c
drivers/net/tulip/de4x5.c
drivers/net/tulip/de4x5.h
drivers/net/tun.c
drivers/net/ucc_geth.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/rndis_host.c
drivers/net/wan/cosa.c
drivers/net/wireless/hostap/hostap_hw.c
drivers/net/wireless/ipw2200.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/xen-netfront.c
drivers/pci/hotplug/acpiphp.h
drivers/pci/intel-iommu.c
drivers/pci/pci.c
drivers/pcmcia/Kconfig
drivers/pcmcia/Makefile
drivers/pcmcia/pxa2xx_cm_x270.c
drivers/pcmcia/pxa2xx_palmtx.c [new file with mode: 0644]
drivers/power/Kconfig
drivers/power/Makefile
drivers/power/apm_power.c
drivers/power/palmtx_battery.c [new file with mode: 0644]
drivers/power/power_supply_core.c
drivers/rtc/interface.c
drivers/s390/char/raw3270.c
drivers/s390/char/tape_class.c
drivers/s390/char/vmur.c
drivers/s390/net/claw.c
drivers/s390/net/ctcm_dbug.c
drivers/s390/net/ctcm_dbug.h
drivers/s390/net/ctcm_fsms.c
drivers/s390/net/ctcm_main.c
drivers/s390/net/ctcm_main.h
drivers/s390/net/ctcm_mpc.c
drivers/s390/net/ctcm_mpc.h
drivers/s390/net/qeth_l3_main.c
drivers/sbus/char/uctrl.c
drivers/sbus/char/vfc.h
drivers/sbus/char/vfc_dev.c
drivers/sbus/char/vfc_i2c.c
drivers/sbus/dvma.c
drivers/sbus/sbus.c
drivers/scsi/dpt_i2o.c
drivers/scsi/hosts.c
drivers/scsi/ide-scsi.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/scsi_transport_iscsi.c
drivers/serial/8250.c
drivers/serial/cpm_uart/cpm_uart_core.c
drivers/serial/icom.c
drivers/serial/mpsc.c
drivers/serial/samsung.c
drivers/serial/serial_core.c
drivers/serial/serial_txx9.c
drivers/spi/spi.c
drivers/spi/spidev.c
drivers/uio/Kconfig
drivers/uio/Makefile
drivers/uio/uio.c
drivers/uio/uio_pdrv.c [new file with mode: 0644]
drivers/usb/atm/cxacru.c
drivers/usb/atm/speedtch.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-acm.h
drivers/usb/class/cdc-wdm.c
drivers/usb/core/devices.c
drivers/usb/core/devio.c
drivers/usb/core/driver.c
drivers/usb/core/endpoint.c
drivers/usb/core/file.c
drivers/usb/core/hcd.c
drivers/usb/core/hcd.h
drivers/usb/core/hub.c
drivers/usb/core/inode.c
drivers/usb/core/message.c
drivers/usb/core/usb.c
drivers/usb/core/usb.h
drivers/usb/gadget/Kconfig
drivers/usb/gadget/Makefile
drivers/usb/gadget/amd5536udc.c
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/cdc2.c [new file with mode: 0644]
drivers/usb/gadget/composite.c [new file with mode: 0644]
drivers/usb/gadget/config.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/epautoconf.c
drivers/usb/gadget/ether.c
drivers/usb/gadget/f_acm.c [new file with mode: 0644]
drivers/usb/gadget/f_ecm.c [new file with mode: 0644]
drivers/usb/gadget/f_loopback.c [new file with mode: 0644]
drivers/usb/gadget/f_rndis.c [new file with mode: 0644]
drivers/usb/gadget/f_serial.c [new file with mode: 0644]
drivers/usb/gadget/f_sourcesink.c [new file with mode: 0644]
drivers/usb/gadget/f_subset.c [new file with mode: 0644]
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/fsl_usb2_udc.c
drivers/usb/gadget/g_zero.h [new file with mode: 0644]
drivers/usb/gadget/gadget_chips.h
drivers/usb/gadget/goku_udc.c
drivers/usb/gadget/inode.c
drivers/usb/gadget/lh7a40x_udc.c
drivers/usb/gadget/m66592-udc.c
drivers/usb/gadget/ndis.h
drivers/usb/gadget/net2280.c
drivers/usb/gadget/omap_udc.c
drivers/usb/gadget/printer.c
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/gadget/pxa27x_udc.c
drivers/usb/gadget/rndis.c
drivers/usb/gadget/rndis.h
drivers/usb/gadget/serial.c
drivers/usb/gadget/u_ether.c [new file with mode: 0644]
drivers/usb/gadget/u_ether.h [new file with mode: 0644]
drivers/usb/gadget/u_serial.c [new file with mode: 0644]
drivers/usb/gadget/u_serial.h [new file with mode: 0644]
drivers/usb/gadget/zero.c
drivers/usb/host/ehci-au1xxx.c
drivers/usb/host/ehci-dbg.c
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-ixp4xx.c
drivers/usb/host/ehci-orion.c
drivers/usb/host/ehci-ps3.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci.h
drivers/usb/host/isp116x-hcd.c
drivers/usb/host/isp1760-hcd.c
drivers/usb/host/isp1760-hcd.h
drivers/usb/host/isp1760-if.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-au1xxx.c
drivers/usb/host/ohci-dbg.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/ohci-pnx4008.c
drivers/usb/host/ohci-ppc-of.c
drivers/usb/host/ohci-ps3.c
drivers/usb/host/ohci-q.c
drivers/usb/host/ohci-sm501.c
drivers/usb/host/ohci-ssb.c
drivers/usb/host/r8a66597-hcd.c
drivers/usb/host/sl811-hcd.c
drivers/usb/host/u132-hcd.c
drivers/usb/host/uhci-hub.c
drivers/usb/misc/auerswald.c
drivers/usb/misc/emi62.c
drivers/usb/misc/ftdi-elan.c
drivers/usb/misc/iowarrior.c
drivers/usb/misc/rio500.c
drivers/usb/misc/sisusbvga/sisusb.c
drivers/usb/misc/usblcd.c
drivers/usb/mon/mon_bin.c
drivers/usb/mon/mon_stat.c
drivers/usb/serial/Kconfig
drivers/usb/serial/Makefile
drivers/usb/serial/aircable.c
drivers/usb/serial/airprime.c [deleted file]
drivers/usb/serial/ark3116.c
drivers/usb/serial/belkin_sa.c
drivers/usb/serial/belkin_sa.h
drivers/usb/serial/bus.c
drivers/usb/serial/ch341.c
drivers/usb/serial/console.c
drivers/usb/serial/cp2101.c
drivers/usb/serial/cyberjack.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/cypress_m8.h
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/empeg.c
drivers/usb/serial/ezusb.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/funsoft.c
drivers/usb/serial/garmin_gps.c
drivers/usb/serial/generic.c
drivers/usb/serial/hp4x.c
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/io_tables.h
drivers/usb/serial/io_ti.c
drivers/usb/serial/ipaq.c
drivers/usb/serial/ipw.c
drivers/usb/serial/ir-usb.c
drivers/usb/serial/iuu_phoenix.c
drivers/usb/serial/keyspan.c
drivers/usb/serial/keyspan.h
drivers/usb/serial/keyspan_pda.c
drivers/usb/serial/kl5kusb105.c
drivers/usb/serial/kobil_sct.c
drivers/usb/serial/mct_u232.c
drivers/usb/serial/mos7720.c
drivers/usb/serial/mos7840.c
drivers/usb/serial/navman.c
drivers/usb/serial/omninet.c
drivers/usb/serial/option.c
drivers/usb/serial/oti6858.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/safe_serial.c
drivers/usb/serial/sierra.c
drivers/usb/serial/spcp8x5.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/usb-serial.c
drivers/usb/serial/usb_debug.c
drivers/usb/serial/visor.c
drivers/usb/serial/whiteheat.c
drivers/usb/serial/whiteheat.h
drivers/usb/storage/datafab.c
drivers/usb/storage/debug.c
drivers/usb/storage/debug.h
drivers/usb/storage/dpcm.c
drivers/usb/storage/dpcm.h
drivers/usb/storage/freecom.c
drivers/usb/storage/freecom.h
drivers/usb/storage/initializers.c
drivers/usb/storage/initializers.h
drivers/usb/storage/isd200.c
drivers/usb/storage/jumpshot.c
drivers/usb/storage/protocol.c
drivers/usb/storage/protocol.h
drivers/usb/storage/scsiglue.c
drivers/usb/storage/scsiglue.h
drivers/usb/storage/sddr09.c
drivers/usb/storage/sddr09.h
drivers/usb/storage/sddr55.c
drivers/usb/storage/sddr55.h
drivers/usb/storage/shuttle_usbat.c
drivers/usb/storage/shuttle_usbat.h
drivers/usb/storage/transport.c
drivers/usb/storage/transport.h
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
drivers/usb/storage/usb.h
drivers/video/aty/aty128fb.c
drivers/video/aty/radeonfb.h
drivers/video/console/fbcon.c
drivers/video/fbmem.c
drivers/video/offb.c
drivers/video/ps3fb.c
drivers/video/pxafb.c
drivers/xen/balloon.c
drivers/xen/events.c
drivers/xen/manage.c
fs/binfmt_elf.c
fs/coda/psdev.c
fs/debugfs/inode.c
fs/partitions/check.c
fs/proc/proc_net.c
fs/proc/task_mmu.c
fs/sysfs/dir.c
fs/sysfs/file.c
fs/sysfs/symlink.c
fs/sysfs/sysfs.h
include/asm-arm/arch-iop13xx/adma.h
include/asm-arm/arch-pxa/cm-x270.h [deleted file]
include/asm-arm/arch-pxa/eseries-gpio.h [new file with mode: 0644]
include/asm-arm/arch-pxa/eseries-irq.h [new file with mode: 0644]
include/asm-arm/arch-pxa/hardware.h
include/asm-arm/arch-pxa/irqs.h
include/asm-arm/arch-pxa/mfp-pxa2xx.h
include/asm-arm/arch-pxa/mfp-pxa930.h [new file with mode: 0644]
include/asm-arm/arch-pxa/mfp.h
include/asm-arm/arch-pxa/palmtx.h [new file with mode: 0644]
include/asm-arm/arch-pxa/pxa27x-udc.h
include/asm-arm/arch-pxa/pxa2xx_spi.h
include/asm-arm/arch-pxa/pxa3xx_nand.h
include/asm-arm/arch-pxa/pxafb.h
include/asm-arm/arch-pxa/regs-lcd.h
include/asm-arm/arch-pxa/regs-ssp.h
include/asm-arm/arch-pxa/system.h
include/asm-arm/arch-pxa/tosa.h
include/asm-arm/arch-pxa/tosa_bt.h [new file with mode: 0644]
include/asm-arm/arch-pxa/uncompress.h
include/asm-arm/arch-pxa/zylonite.h
include/asm-arm/hardware/iop3xx-adma.h
include/asm-arm/kgdb.h [new file with mode: 0644]
include/asm-arm/mach/udc_pxa2xx.h
include/asm-arm/plat-orion/mv_xor.h [new file with mode: 0644]
include/asm-arm/traps.h
include/asm-avr32/arch-at32ap/at32ap700x.h
include/asm-ia64/Kbuild
include/asm-ia64/gcc_intrin.h
include/asm-ia64/hw_irq.h
include/asm-ia64/intel_intrin.h
include/asm-ia64/intrinsics.h
include/asm-ia64/iosapic.h
include/asm-ia64/irq.h
include/asm-ia64/mmu_context.h
include/asm-ia64/native/inst.h [new file with mode: 0644]
include/asm-ia64/native/irq.h [new file with mode: 0644]
include/asm-ia64/paravirt.h [new file with mode: 0644]
include/asm-ia64/paravirt_privop.h [new file with mode: 0644]
include/asm-ia64/smp.h
include/asm-ia64/system.h
include/asm-ia64/uv/uv_mmrs.h
include/asm-powerpc/asm-compat.h
include/asm-powerpc/kgdb.h
include/asm-powerpc/machdep.h
include/asm-powerpc/pgtable-ppc32.h
include/asm-powerpc/pmi.h
include/asm-powerpc/ps3.h
include/asm-powerpc/reg.h
include/asm-powerpc/uaccess.h
include/asm-powerpc/ucc_fast.h
include/asm-sparc/Kbuild
include/asm-sparc/agp.h [new file with mode: 0644]
include/asm-sparc/apb.h [new file with mode: 0644]
include/asm-sparc/asi.h
include/asm-sparc/atomic.h
include/asm-sparc/atomic_32.h [new file with mode: 0644]
include/asm-sparc/atomic_64.h [new file with mode: 0644]
include/asm-sparc/auxio.h
include/asm-sparc/auxio_32.h [new file with mode: 0644]
include/asm-sparc/auxio_64.h [new file with mode: 0644]
include/asm-sparc/backoff.h [new file with mode: 0644]
include/asm-sparc/bbc.h [new file with mode: 0644]
include/asm-sparc/bitops.h
include/asm-sparc/bitops_32.h [new file with mode: 0644]
include/asm-sparc/bitops_64.h [new file with mode: 0644]
include/asm-sparc/cacheflush.h
include/asm-sparc/cacheflush_32.h [new file with mode: 0644]
include/asm-sparc/cacheflush_64.h [new file with mode: 0644]
include/asm-sparc/chafsr.h [new file with mode: 0644]
include/asm-sparc/checksum.h
include/asm-sparc/checksum_32.h [new file with mode: 0644]
include/asm-sparc/checksum_64.h [new file with mode: 0644]
include/asm-sparc/chmctrl.h [new file with mode: 0644]
include/asm-sparc/cmt.h [new file with mode: 0644]
include/asm-sparc/compat.h [new file with mode: 0644]
include/asm-sparc/compat_signal.h [new file with mode: 0644]
include/asm-sparc/cpudata.h
include/asm-sparc/cpudata_32.h [new file with mode: 0644]
include/asm-sparc/cpudata_64.h [new file with mode: 0644]
include/asm-sparc/dcr.h [new file with mode: 0644]
include/asm-sparc/dcu.h [new file with mode: 0644]
include/asm-sparc/delay.h
include/asm-sparc/delay_32.h [new file with mode: 0644]
include/asm-sparc/delay_64.h [new file with mode: 0644]
include/asm-sparc/display7seg.h [new file with mode: 0644]
include/asm-sparc/dma-mapping.h
include/asm-sparc/dma-mapping_32.h [new file with mode: 0644]
include/asm-sparc/dma-mapping_64.h [new file with mode: 0644]
include/asm-sparc/dma.h
include/asm-sparc/dma_32.h [new file with mode: 0644]
include/asm-sparc/dma_64.h [new file with mode: 0644]
include/asm-sparc/ebus.h
include/asm-sparc/ebus_32.h [new file with mode: 0644]
include/asm-sparc/ebus_64.h [new file with mode: 0644]
include/asm-sparc/elf.h
include/asm-sparc/elf_32.h [new file with mode: 0644]
include/asm-sparc/elf_64.h [new file with mode: 0644]
include/asm-sparc/envctrl.h [new file with mode: 0644]
include/asm-sparc/estate.h [new file with mode: 0644]
include/asm-sparc/fbio.h
include/asm-sparc/fcntl.h
include/asm-sparc/fhc.h [new file with mode: 0644]
include/asm-sparc/floppy.h
include/asm-sparc/floppy_32.h [new file with mode: 0644]
include/asm-sparc/floppy_64.h [new file with mode: 0644]
include/asm-sparc/fpumacro.h [new file with mode: 0644]
include/asm-sparc/futex.h
include/asm-sparc/futex_32.h [new file with mode: 0644]
include/asm-sparc/futex_64.h [new file with mode: 0644]
include/asm-sparc/hardirq.h
include/asm-sparc/hardirq_32.h [new file with mode: 0644]
include/asm-sparc/hardirq_64.h [new file with mode: 0644]
include/asm-sparc/head.h
include/asm-sparc/head_32.h [new file with mode: 0644]
include/asm-sparc/head_64.h [new file with mode: 0644]
include/asm-sparc/hugetlb.h [new file with mode: 0644]
include/asm-sparc/hvtramp.h [new file with mode: 0644]
include/asm-sparc/hypervisor.h [new file with mode: 0644]
include/asm-sparc/ide.h
include/asm-sparc/idprom.h
include/asm-sparc/intr_queue.h [new file with mode: 0644]
include/asm-sparc/io.h
include/asm-sparc/io_32.h [new file with mode: 0644]
include/asm-sparc/io_64.h [new file with mode: 0644]
include/asm-sparc/ioctls.h
include/asm-sparc/iommu.h
include/asm-sparc/iommu_32.h [new file with mode: 0644]
include/asm-sparc/iommu_64.h [new file with mode: 0644]
include/asm-sparc/ipcbuf.h
include/asm-sparc/ipcbuf_32.h [new file with mode: 0644]
include/asm-sparc/ipcbuf_64.h [new file with mode: 0644]
include/asm-sparc/irq.h
include/asm-sparc/irq_32.h [new file with mode: 0644]
include/asm-sparc/irq_64.h [new file with mode: 0644]
include/asm-sparc/irqflags.h
include/asm-sparc/irqflags_32.h [new file with mode: 0644]
include/asm-sparc/irqflags_64.h [new file with mode: 0644]
include/asm-sparc/kdebug.h
include/asm-sparc/kdebug_32.h [new file with mode: 0644]
include/asm-sparc/kdebug_64.h [new file with mode: 0644]
include/asm-sparc/kmap_types.h
include/asm-sparc/kprobes.h [new file with mode: 0644]
include/asm-sparc/ldc.h [new file with mode: 0644]
include/asm-sparc/lmb.h [new file with mode: 0644]
include/asm-sparc/lsu.h [new file with mode: 0644]
include/asm-sparc/machines.h
include/asm-sparc/mbus.h
include/asm-sparc/mc146818rtc.h
include/asm-sparc/mc146818rtc_32.h [new file with mode: 0644]
include/asm-sparc/mc146818rtc_64.h [new file with mode: 0644]
include/asm-sparc/mdesc.h [new file with mode: 0644]
include/asm-sparc/mmu.h
include/asm-sparc/mmu_32.h [new file with mode: 0644]
include/asm-sparc/mmu_64.h [new file with mode: 0644]
include/asm-sparc/mmu_context.h
include/asm-sparc/mmu_context_32.h [new file with mode: 0644]
include/asm-sparc/mmu_context_64.h [new file with mode: 0644]
include/asm-sparc/mmzone.h [new file with mode: 0644]
include/asm-sparc/module.h
include/asm-sparc/module_32.h [new file with mode: 0644]
include/asm-sparc/module_64.h [new file with mode: 0644]
include/asm-sparc/mostek.h
include/asm-sparc/mostek_32.h [new file with mode: 0644]
include/asm-sparc/mostek_64.h [new file with mode: 0644]
include/asm-sparc/msgbuf.h
include/asm-sparc/namei.h
include/asm-sparc/namei_32.h [new file with mode: 0644]
include/asm-sparc/namei_64.h [new file with mode: 0644]
include/asm-sparc/ns87303.h [new file with mode: 0644]
include/asm-sparc/of_platform.h
include/asm-sparc/of_platform_32.h [new file with mode: 0644]
include/asm-sparc/of_platform_64.h [new file with mode: 0644]
include/asm-sparc/openprom.h
include/asm-sparc/openprom_32.h [new file with mode: 0644]
include/asm-sparc/openprom_64.h [new file with mode: 0644]
include/asm-sparc/oplib.h
include/asm-sparc/oplib_32.h [new file with mode: 0644]
include/asm-sparc/oplib_64.h [new file with mode: 0644]
include/asm-sparc/page.h
include/asm-sparc/page_32.h [new file with mode: 0644]
include/asm-sparc/page_64.h [new file with mode: 0644]
include/asm-sparc/parport.h [new file with mode: 0644]
include/asm-sparc/pci.h
include/asm-sparc/pci_32.h [new file with mode: 0644]
include/asm-sparc/pci_64.h [new file with mode: 0644]
include/asm-sparc/percpu.h
include/asm-sparc/percpu_32.h [new file with mode: 0644]
include/asm-sparc/percpu_64.h [new file with mode: 0644]
include/asm-sparc/pgalloc.h
include/asm-sparc/pgalloc_32.h [new file with mode: 0644]
include/asm-sparc/pgalloc_64.h [new file with mode: 0644]
include/asm-sparc/pgtable.h
include/asm-sparc/pgtable_32.h [new file with mode: 0644]
include/asm-sparc/pgtable_64.h [new file with mode: 0644]
include/asm-sparc/pil.h [new file with mode: 0644]
include/asm-sparc/posix_types.h
include/asm-sparc/posix_types_32.h [new file with mode: 0644]
include/asm-sparc/posix_types_64.h [new file with mode: 0644]
include/asm-sparc/processor.h
include/asm-sparc/processor_32.h [new file with mode: 0644]
include/asm-sparc/processor_64.h [new file with mode: 0644]
include/asm-sparc/psrcompat.h [new file with mode: 0644]
include/asm-sparc/pstate.h [new file with mode: 0644]
include/asm-sparc/ptrace.h
include/asm-sparc/ptrace_32.h [new file with mode: 0644]
include/asm-sparc/ptrace_64.h [new file with mode: 0644]
include/asm-sparc/reboot.h [new file with mode: 0644]
include/asm-sparc/reg.h
include/asm-sparc/reg_32.h [new file with mode: 0644]
include/asm-sparc/reg_64.h [new file with mode: 0644]
include/asm-sparc/resource.h
include/asm-sparc/rwsem-const.h [new file with mode: 0644]
include/asm-sparc/rwsem.h [new file with mode: 0644]
include/asm-sparc/sbus.h
include/asm-sparc/sbus_32.h [new file with mode: 0644]
include/asm-sparc/sbus_64.h [new file with mode: 0644]
include/asm-sparc/scatterlist.h
include/asm-sparc/scatterlist_32.h [new file with mode: 0644]
include/asm-sparc/scatterlist_64.h [new file with mode: 0644]
include/asm-sparc/scratchpad.h [new file with mode: 0644]
include/asm-sparc/seccomp.h [new file with mode: 0644]
include/asm-sparc/sections.h
include/asm-sparc/sections_32.h [new file with mode: 0644]
include/asm-sparc/sections_64.h [new file with mode: 0644]
include/asm-sparc/sembuf.h
include/asm-sparc/setup.h
include/asm-sparc/sfafsr.h [new file with mode: 0644]
include/asm-sparc/sfp-machine.h
include/asm-sparc/sfp-machine_32.h [new file with mode: 0644]
include/asm-sparc/sfp-machine_64.h [new file with mode: 0644]
include/asm-sparc/shmbuf.h
include/asm-sparc/shmparam.h
include/asm-sparc/shmparam_32.h [new file with mode: 0644]
include/asm-sparc/shmparam_64.h [new file with mode: 0644]
include/asm-sparc/sigcontext.h
include/asm-sparc/sigcontext_32.h [new file with mode: 0644]
include/asm-sparc/sigcontext_64.h [new file with mode: 0644]
include/asm-sparc/siginfo.h
include/asm-sparc/siginfo_32.h [new file with mode: 0644]
include/asm-sparc/siginfo_64.h [new file with mode: 0644]
include/asm-sparc/signal.h
include/asm-sparc/signal_32.h [new file with mode: 0644]
include/asm-sparc/signal_64.h [new file with mode: 0644]
include/asm-sparc/smp.h
include/asm-sparc/smp_32.h [new file with mode: 0644]
include/asm-sparc/smp_64.h [new file with mode: 0644]
include/asm-sparc/sparsemem.h [new file with mode: 0644]
include/asm-sparc/spinlock.h
include/asm-sparc/spinlock_32.h [new file with mode: 0644]
include/asm-sparc/spinlock_64.h [new file with mode: 0644]
include/asm-sparc/spinlock_types.h
include/asm-sparc/spitfire.h [new file with mode: 0644]
include/asm-sparc/sstate.h [new file with mode: 0644]
include/asm-sparc/stacktrace.h [new file with mode: 0644]
include/asm-sparc/starfire.h [new file with mode: 0644]
include/asm-sparc/stat.h
include/asm-sparc/stat_32.h [new file with mode: 0644]
include/asm-sparc/stat_64.h [new file with mode: 0644]
include/asm-sparc/statfs.h
include/asm-sparc/statfs_32.h [new file with mode: 0644]
include/asm-sparc/statfs_64.h [new file with mode: 0644]
include/asm-sparc/string.h
include/asm-sparc/string_32.h [new file with mode: 0644]
include/asm-sparc/string_64.h [new file with mode: 0644]
include/asm-sparc/syscalls.h [new file with mode: 0644]
include/asm-sparc/system.h
include/asm-sparc/system_32.h [new file with mode: 0644]
include/asm-sparc/system_64.h [new file with mode: 0644]
include/asm-sparc/termbits.h
include/asm-sparc/termios.h
include/asm-sparc/thread_info.h
include/asm-sparc/thread_info_32.h [new file with mode: 0644]
include/asm-sparc/thread_info_64.h [new file with mode: 0644]
include/asm-sparc/timer.h
include/asm-sparc/timer_32.h [new file with mode: 0644]
include/asm-sparc/timer_64.h [new file with mode: 0644]
include/asm-sparc/timex.h
include/asm-sparc/timex_32.h [new file with mode: 0644]
include/asm-sparc/timex_64.h [new file with mode: 0644]
include/asm-sparc/tlb.h
include/asm-sparc/tlb_32.h [new file with mode: 0644]
include/asm-sparc/tlb_64.h [new file with mode: 0644]
include/asm-sparc/tlbflush.h
include/asm-sparc/tlbflush_32.h [new file with mode: 0644]
include/asm-sparc/tlbflush_64.h [new file with mode: 0644]
include/asm-sparc/topology.h
include/asm-sparc/topology_32.h [new file with mode: 0644]
include/asm-sparc/topology_64.h [new file with mode: 0644]
include/asm-sparc/tsb.h [new file with mode: 0644]
include/asm-sparc/ttable.h [new file with mode: 0644]
include/asm-sparc/types.h
include/asm-sparc/uaccess.h
include/asm-sparc/uaccess_32.h [new file with mode: 0644]
include/asm-sparc/uaccess_64.h [new file with mode: 0644]
include/asm-sparc/uctx.h [new file with mode: 0644]
include/asm-sparc/unistd.h
include/asm-sparc/unistd_32.h [new file with mode: 0644]
include/asm-sparc/unistd_64.h [new file with mode: 0644]
include/asm-sparc/upa.h [new file with mode: 0644]
include/asm-sparc/utrap.h [new file with mode: 0644]
include/asm-sparc/vaddrs.h
include/asm-sparc/vio.h [new file with mode: 0644]
include/asm-sparc/visasm.h [new file with mode: 0644]
include/asm-sparc/watchdog.h [new file with mode: 0644]
include/asm-sparc/xor.h
include/asm-sparc/xor_32.h [new file with mode: 0644]
include/asm-sparc/xor_64.h [new file with mode: 0644]
include/asm-sparc64/Kbuild
include/asm-sparc64/agp.h
include/asm-sparc64/apb.h
include/asm-sparc64/asi.h
include/asm-sparc64/atomic.h
include/asm-sparc64/auxio.h
include/asm-sparc64/backoff.h
include/asm-sparc64/bbc.h
include/asm-sparc64/bitops.h
include/asm-sparc64/cacheflush.h
include/asm-sparc64/chafsr.h
include/asm-sparc64/checksum.h
include/asm-sparc64/chmctrl.h
include/asm-sparc64/cmt.h
include/asm-sparc64/compat.h
include/asm-sparc64/compat_signal.h
include/asm-sparc64/cpudata.h
include/asm-sparc64/dcr.h
include/asm-sparc64/dcu.h
include/asm-sparc64/delay.h
include/asm-sparc64/display7seg.h
include/asm-sparc64/dma-mapping.h
include/asm-sparc64/dma.h
include/asm-sparc64/ebus.h
include/asm-sparc64/elf.h
include/asm-sparc64/envctrl.h
include/asm-sparc64/estate.h
include/asm-sparc64/fbio.h
include/asm-sparc64/fcntl.h
include/asm-sparc64/fhc.h
include/asm-sparc64/floppy.h
include/asm-sparc64/fpumacro.h
include/asm-sparc64/futex.h
include/asm-sparc64/hardirq.h
include/asm-sparc64/head.h
include/asm-sparc64/hugetlb.h
include/asm-sparc64/hvtramp.h
include/asm-sparc64/hw_irq.h
include/asm-sparc64/hypervisor.h
include/asm-sparc64/ide.h
include/asm-sparc64/idprom.h
include/asm-sparc64/intr_queue.h
include/asm-sparc64/io.h
include/asm-sparc64/ioctl.h
include/asm-sparc64/ioctls.h
include/asm-sparc64/iommu.h
include/asm-sparc64/ipcbuf.h
include/asm-sparc64/irq.h
include/asm-sparc64/irq_regs.h
include/asm-sparc64/irqflags.h
include/asm-sparc64/kdebug.h
include/asm-sparc64/kmap_types.h
include/asm-sparc64/kprobes.h
include/asm-sparc64/kvm.h
include/asm-sparc64/ldc.h
include/asm-sparc64/linkage.h
include/asm-sparc64/lmb.h
include/asm-sparc64/lsu.h
include/asm-sparc64/mc146818rtc.h
include/asm-sparc64/mdesc.h
include/asm-sparc64/mman.h
include/asm-sparc64/mmu.h
include/asm-sparc64/mmu_context.h
include/asm-sparc64/mmzone.h
include/asm-sparc64/module.h
include/asm-sparc64/mostek.h
include/asm-sparc64/msgbuf.h
include/asm-sparc64/mutex.h
include/asm-sparc64/namei.h
include/asm-sparc64/ns87303.h
include/asm-sparc64/of_platform.h
include/asm-sparc64/openprom.h
include/asm-sparc64/openpromio.h
include/asm-sparc64/oplib.h
include/asm-sparc64/page.h
include/asm-sparc64/param.h
include/asm-sparc64/parport.h
include/asm-sparc64/pci.h
include/asm-sparc64/percpu.h
include/asm-sparc64/perfctr.h
include/asm-sparc64/pgalloc.h
include/asm-sparc64/pgtable.h
include/asm-sparc64/pil.h
include/asm-sparc64/poll.h
include/asm-sparc64/posix_types.h
include/asm-sparc64/processor.h
include/asm-sparc64/psrcompat.h
include/asm-sparc64/pstate.h
include/asm-sparc64/ptrace.h
include/asm-sparc64/reboot.h
include/asm-sparc64/reg.h
include/asm-sparc64/resource.h
include/asm-sparc64/rtc.h
include/asm-sparc64/rwsem-const.h
include/asm-sparc64/rwsem.h
include/asm-sparc64/sbus.h
include/asm-sparc64/scatterlist.h
include/asm-sparc64/scratchpad.h
include/asm-sparc64/seccomp.h
include/asm-sparc64/sections.h
include/asm-sparc64/semaphore.h
include/asm-sparc64/sembuf.h
include/asm-sparc64/setup.h
include/asm-sparc64/sfafsr.h
include/asm-sparc64/sfp-machine.h
include/asm-sparc64/shmbuf.h
include/asm-sparc64/shmparam.h
include/asm-sparc64/sigcontext.h
include/asm-sparc64/siginfo.h
include/asm-sparc64/signal.h
include/asm-sparc64/smp.h
include/asm-sparc64/socket.h
include/asm-sparc64/sockios.h
include/asm-sparc64/sparsemem.h
include/asm-sparc64/spinlock.h
include/asm-sparc64/spinlock_types.h
include/asm-sparc64/spitfire.h
include/asm-sparc64/sstate.h
include/asm-sparc64/stacktrace.h
include/asm-sparc64/starfire.h
include/asm-sparc64/stat.h
include/asm-sparc64/statfs.h
include/asm-sparc64/string.h
include/asm-sparc64/sunbpp.h
include/asm-sparc64/syscalls.h
include/asm-sparc64/system.h
include/asm-sparc64/termbits.h
include/asm-sparc64/termios.h
include/asm-sparc64/thread_info.h
include/asm-sparc64/timer.h
include/asm-sparc64/timex.h
include/asm-sparc64/tlb.h
include/asm-sparc64/tlbflush.h
include/asm-sparc64/topology.h
include/asm-sparc64/tsb.h
include/asm-sparc64/ttable.h
include/asm-sparc64/types.h
include/asm-sparc64/uaccess.h
include/asm-sparc64/uctx.h
include/asm-sparc64/unaligned.h
include/asm-sparc64/unistd.h
include/asm-sparc64/upa.h
include/asm-sparc64/utrap.h
include/asm-sparc64/vga.h
include/asm-sparc64/vio.h
include/asm-sparc64/visasm.h
include/asm-sparc64/watchdog.h
include/asm-sparc64/xor.h
include/asm-x86/amd_iommu_types.h
include/asm-x86/apic.h
include/asm-x86/arch_hooks.h
include/asm-x86/bitops.h
include/asm-x86/calling.h
include/asm-x86/cpufeature.h
include/asm-x86/dma-mapping.h
include/asm-x86/e820.h
include/asm-x86/fixmap_32.h
include/asm-x86/ftrace.h
include/asm-x86/gart.h
include/asm-x86/iommu.h
include/asm-x86/kvm_host.h
include/asm-x86/mach-bigsmp/mach_apic.h
include/asm-x86/mach-default/mach_apic.h
include/asm-x86/mach-default/smpboot_hooks.h
include/asm-x86/mach-es7000/mach_apic.h
include/asm-x86/mach-generic/mach_mpspec.h
include/asm-x86/mach-summit/mach_apic.h
include/asm-x86/mach-visws/entry_arch.h [deleted file]
include/asm-x86/mach-visws/mach_apic.h [deleted file]
include/asm-x86/mach-visws/mach_apicdef.h [deleted file]
include/asm-x86/mach-visws/setup_arch.h [deleted file]
include/asm-x86/mach-visws/smpboot_hooks.h [deleted file]
include/asm-x86/page.h
include/asm-x86/paravirt.h
include/asm-x86/percpu.h
include/asm-x86/pgtable-3level.h
include/asm-x86/pgtable.h
include/asm-x86/pgtable_32.h
include/asm-x86/pgtable_64.h
include/asm-x86/processor.h
include/asm-x86/ptrace-abi.h
include/asm-x86/segment.h
include/asm-x86/setup.h
include/asm-x86/signal.h
include/asm-x86/smp.h
include/asm-x86/spinlock.h
include/asm-x86/spinlock_types.h
include/asm-x86/swiotlb.h
include/asm-x86/thread_info.h
include/asm-x86/traps.h [new file with mode: 0644]
include/asm-x86/uv/bios.h [new file with mode: 0644]
include/asm-x86/vdso.h
include/asm-x86/xen/events.h
include/asm-x86/xen/hypercall.h
include/asm-x86/xen/interface.h
include/asm-x86/xen/interface_32.h [new file with mode: 0644]
include/asm-x86/xen/interface_64.h [new file with mode: 0644]
include/asm-x86/xen/page.h
include/linux/async_tx.h
include/linux/auxvec.h
include/linux/cpufreq.h
include/linux/dca.h
include/linux/debugfs.h
include/linux/device-mapper.h
include/linux/device.h
include/linux/dm-ioctl.h
include/linux/dma-attrs.h
include/linux/dmaengine.h
include/linux/dw_dmac.h [new file with mode: 0644]
include/linux/eisa.h
include/linux/fs_enet_pd.h
include/linux/fsl_devices.h
include/linux/gameport.h
include/linux/gpio_keys.h
include/linux/hid.h
include/linux/ide.h
include/linux/input.h
include/linux/ipv6.h
include/linux/joystick.h
include/linux/kmod.h
include/linux/kobject.h
include/linux/libps2.h
include/linux/mfd/core.h [new file with mode: 0644]
include/linux/mfd/tc6393xb.h [new file with mode: 0644]
include/linux/mfd/tmio.h [new file with mode: 0644]
include/linux/module.h
include/linux/mtd/map.h
include/linux/mtd/mtd.h
include/linux/netdevice.h
include/linux/netfilter/nf_conntrack_common.h
include/linux/netfilter/nfnetlink_conntrack.h
include/linux/netfilter/nfnetlink_log.h
include/linux/of_gpio.h
include/linux/pci_ids.h
include/linux/proc_fs.h
include/linux/raid/bitmap.h
include/linux/raid/linear.h
include/linux/raid/md.h
include/linux/raid/md_k.h
include/linux/raid/md_p.h
include/linux/raid/raid5.h
include/linux/scatterlist.h
include/linux/sched.h
include/linux/serio.h
include/linux/smc91x.h
include/linux/spi/max7301.h [new file with mode: 0644]
include/linux/spi/spi.h
include/linux/synclink.h
include/linux/sysdev.h
include/linux/sysfs.h
include/linux/tty.h
include/linux/tty_driver.h
include/linux/uio_driver.h
include/linux/usb.h
include/linux/usb/composite.h [new file with mode: 0644]
include/linux/usb/gadget.h
include/linux/usb/irda.h [new file with mode: 0644]
include/linux/usb/serial.h
include/linux/usbdevice_fs.h
include/net/if_inet6.h
include/net/ip6_route.h
include/net/netfilter/nf_conntrack.h
include/net/netfilter/nf_conntrack_acct.h [new file with mode: 0644]
include/net/netfilter/nf_conntrack_extend.h
include/net/netlink.h
include/net/netns/ipv6.h
include/net/sctp/structs.h
include/scsi/scsi_host.h
include/scsi/scsi_transport_fc.h
include/scsi/scsi_transport_iscsi.h
include/xen/events.h
include/xen/hvc-console.h
include/xen/interface/callback.h
include/xen/xen-ops.h
init/Kconfig
kernel/cpuset.c
kernel/exec_domain.c
kernel/irq/manage.c
kernel/kmod.c
kernel/module.c
kernel/power/Kconfig
kernel/rtmutex-tester.c
kernel/sched.c
kernel/softlockup.c
kernel/sys_ni.c
kernel/sysctl.c
kernel/time/clocksource.c
kernel/time/tick-sched.c
lib/Kconfig.debug
lib/Kconfig.kgdb
lib/kobject.c
lib/kobject_uevent.c
lib/scatterlist.c
lib/textsearch.c
mm/slub.c
net/8021q/vlan_dev.c
net/bluetooth/hci_sysfs.c
net/core/dev.c
net/core/user_dma.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
net/ipv4/netfilter/nf_nat_core.c
net/ipv4/netfilter/nf_nat_sip.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/ip6_fib.c
net/ipv6/route.c
net/netfilter/Kconfig
net/netfilter/Makefile
net/netfilter/nf_conntrack_acct.c [new file with mode: 0644]
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nf_conntrack_standalone.c
net/netfilter/nfnetlink_log.c
net/netfilter/xt_TCPMSS.c
net/netfilter/xt_connbytes.c
net/netfilter/xt_time.c
net/netrom/af_netrom.c
net/rose/af_rose.c
net/sched/sch_api.c
net/sched/sch_generic.c
net/sctp/outqueue.c
net/sctp/proc.c
samples/firmware_class/firmware_sample_firmware_class.c
samples/kobject/kset-example.c
scripts/Makefile.modpost
scripts/mod/file2alias.c
scripts/mod/modpost.c
sound/core/init.c
sound/oss/soundcard.c
sound/soc/pxa/Kconfig
sound/soc/pxa/tosa.c
sound/sound_core.c

diff --git a/CREDITS b/CREDITS
index e97bea06b59ff12bc827c0661fb57974a6eff4d6..077b147388bd593c971ec2643e0c8b9ecd194b65 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -3344,8 +3344,7 @@ S: Spain
 N: Linus Torvalds
 E: torvalds@linux-foundation.org
 D: Original kernel hacker
-S: 12725 SW Millikan Way, Suite 400
-S: Beaverton, Oregon 97005
+S: Portland, Oregon 97005
 S: USA
 
 N: Marcelo Tosatti
diff --git a/Documentation/ABI/testing/sysfs-dev b/Documentation/ABI/testing/sysfs-dev
new file mode 100644 (file)
index 0000000..a9f2b8b
--- /dev/null
@@ -0,0 +1,20 @@
+What:          /sys/dev
+Date:          April 2008
+KernelVersion: 2.6.26
+Contact:       Dan Williams <dan.j.williams@intel.com>
+Description:   The /sys/dev tree provides a method to look up the sysfs
+               path for a device using the information returned from
+               stat(2).  There are two directories, 'block' and 'char',
+               beneath /sys/dev containing symbolic links with names of
+               the form "<major>:<minor>".  These links point to the
+               corresponding sysfs path for the given device.
+
+               Example:
+               $ readlink /sys/dev/block/8:32
+               ../../block/sdc
+
+               Entries in /sys/dev/char and /sys/dev/block will be
+               dynamically created and destroyed as devices enter and
+               leave the system.
+
+Users:         mdadm <linux-raid@vger.kernel.org>
index 6d772f84b477c9f5a4698e87d50fb63649af83d3..b768cc0e402b8e6f1cfa8ae0b0f23c4e1c50168a 100644 (file)
@@ -22,3 +22,12 @@ ready and available in memory.  The DMA of the "completion indication"
 could race with data DMA.  Mapping the memory used for completion
 indications with DMA_ATTR_WRITE_BARRIER would prevent the race.
 
+DMA_ATTR_WEAK_ORDERING
+----------------------
+
+DMA_ATTR_WEAK_ORDERING specifies that reads and writes to the mapping
+may be weakly ordered, that is that reads and writes may pass each other.
+
+Since it is optional for platforms to implement DMA_ATTR_WEAK_ORDERING,
+those that do not will simply ignore the attribute and exhibit default
+behavior.
index 5a8ffa761e09991bfc59dc97fa01a4deef94e9f7..ea3bc9565e6a7e7ae48a168841c222e07bfd0154 100644 (file)
@@ -524,6 +524,44 @@ These utilities include endpoint autoconfiguration.
 <!-- !Edrivers/usb/gadget/epautoconf.c -->
 </sect1>
 
+<sect1 id="composite"><title>Composite Device Framework</title>
+
+<para>The core API is sufficient for writing drivers for composite
+USB devices (with more than one function in a given configuration),
+and also multi-configuration devices (also more than one function,
+but not necessarily sharing a given configuration).
+There is however an optional framework which makes it easier to
+reuse and combine functions.
+</para>
+
+<para>Devices using this framework provide a <emphasis>struct
+usb_composite_driver</emphasis>, which in turn provides one or
+more <emphasis>struct usb_configuration</emphasis> instances.
+Each such configuration includes at least one
+<emphasis>struct usb_function</emphasis>, which packages a user
+visible role such as "network link" or "mass storage device".
+Management functions may also exist, such as "Device Firmware
+Upgrade".
+</para>
+
+!Iinclude/linux/usb/composite.h
+!Edrivers/usb/gadget/composite.c
+
+</sect1>
+
+<sect1 id="functions"><title>Composite Device Functions</title>
+
+<para>At this writing, a few of the current gadget drivers have
+been converted to this framework.
+Near-term plans include converting all of them, except for "gadgetfs".
+</para>
+
+!Edrivers/usb/gadget/f_acm.c
+!Edrivers/usb/gadget/f_serial.c
+
+</sect1>
+
+
 </chapter>
 
 <chapter id="controllers"><title>Peripheral Controller Drivers</title>
index fdd7f4f887b75ba7bc96b7ab81b9abc7d3348d73..df87d1b93605ac54cf400bd7b8d44b0866d0789a 100644 (file)
     </affiliation>
 </author>
 
+<copyright>
+       <year>2006-2008</year>
+       <holder>Hans-Jürgen Koch.</holder>
+</copyright>
+
+<legalnotice>
+<para>
+This documentation is Free Software licensed under the terms of the
+GPL version 2.
+</para>
+</legalnotice>
+
 <pubdate>2006-12-11</pubdate>
 
 <abstract>
 </abstract>
 
 <revhistory>
+       <revision>
+       <revnumber>0.5</revnumber>
+       <date>2008-05-22</date>
+       <authorinitials>hjk</authorinitials>
+       <revremark>Added description of write() function.</revremark>
+       </revision>
        <revision>
        <revnumber>0.4</revnumber>
        <date>2007-11-26</date>
 </bookinfo>
 
 <chapter id="aboutthisdoc">
-<?dbhtml filename="about.html"?>
+<?dbhtml filename="aboutthis.html"?>
 <title>About this document</title>
 
-<sect1 id="copyright">
-<?dbhtml filename="copyright.html"?>
-<title>Copyright and License</title>
-<para>
-      Copyright (c) 2006 by Hans-Jürgen Koch.</para>
-<para>
-This documentation is Free Software licensed under the terms of the
-GPL version 2.
-</para>
-</sect1>
-
 <sect1 id="translations">
 <?dbhtml filename="translations.html"?>
 <title>Translations</title>
@@ -189,6 +196,30 @@ interested in translating it, please email me
        represents the total interrupt count. You can use this number
        to figure out if you missed some interrupts.
        </para>
+       <para>
+       For some hardware that has more than one interrupt source internally,
+       but not separate IRQ mask and status registers, there might be
+       situations where userspace cannot determine what the interrupt source
+       was if the kernel handler disables them by writing to the chip's IRQ
+       register. In such a case, the kernel has to disable the IRQ completely
+       to leave the chip's register untouched. Now the userspace part can
+       determine the cause of the interrupt, but it cannot re-enable
+       interrupts. Another cornercase is chips where re-enabling interrupts
+       is a read-modify-write operation to a combined IRQ status/acknowledge
+       register. This would be racy if a new interrupt occurred
+       simultaneously.
+       </para>
+       <para>
+       To address these problems, UIO also implements a write() function. It
+       is normally not used and can be ignored for hardware that has only a
+       single interrupt source or has separate IRQ mask and status registers.
+       If you need it, however, a write to <filename>/dev/uioX</filename>
+       will call the <function>irqcontrol()</function> function implemented
+       by the driver. You have to write a 32-bit value that is usually either
+       0 or 1 to disable or enable interrupts. If a driver does not implement
+       <function>irqcontrol()</function>, <function>write()</function> will
+       return with <varname>-ENOSYS</varname>.
+       </para>
 
        <para>
        To handle interrupts properly, your custom kernel module can
@@ -362,6 +393,14 @@ device is actually used.
 <function>open()</function>, you will probably also want a custom
 <function>release()</function> function.
 </para></listitem>
+
+<listitem><para>
+<varname>int (*irqcontrol)(struct uio_info *info, s32 irq_on)
+</varname>: Optional. If you need to be able to enable or disable
+interrupts from userspace by writing to <filename>/dev/uioX</filename>,
+you can implement this function. The parameter <varname>irq_on</varname>
+will be 0 to disable interrupts and 1 to enable them.
+</para></listitem>
 </itemizedlist>
 
 <para>
index 619e8caf30db88508a3f2859d140f41ce363f552..c2371c5a98f99b5eaa785bd0affd6c40187e84e3 100644 (file)
@@ -358,7 +358,7 @@ Here is a list of some of the different kernel trees available:
     - pcmcia, Dominik Brodowski <linux@dominikbrodowski.net>
        git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
 
-    - SCSI, James Bottomley <James.Bottomley@SteelEye.com>
+    - SCSI, James Bottomley <James.Bottomley@hansenpartnership.com>
        git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
 
     - x86, Ingo Molnar <mingo@elte.hu>
index 86334b6f8238409409debbcab2e89f60f4b080f1..9f73587219e87a601f361b0942530888e56c3303 100644 (file)
@@ -336,3 +336,13 @@ When:      After the only user (hal) has seen a release with the patches
 Why:   Over 1K .text/.data size reduction, data is available in other
        ways (ioctls)
 Who:   Johannes Berg <johannes@sipsolutions.net>
+
+---------------------------
+
+What: CONFIG_NF_CT_ACCT
+When: 2.6.29
+Why:  Accounting can now be enabled/disabled without kernel recompilation.
+      Currently used only to set a default value for a feature that is also
+      controlled by a kernel/module/sysfs/sysctl parameter.
+Who:  Krzysztof Piotr Oledzki <ole@ans.pl>
+
index ea825e178e797b3b8af53d8d6d5fa2c1f1974a0d..78043d5a8fc35f01c343ced6f956aadee03e1026 100644 (file)
@@ -26,11 +26,11 @@ You can simplify mounting by just typing:
 
 this will allocate the first available loopback device (and load loop.o 
 kernel module if necessary) automatically. If the loopback driver is not
-loaded automatically, make sure that your kernel is compiled with kmod 
-support (CONFIG_KMOD) enabled. Beware that umount will not
-deallocate /dev/loopN device if /etc/mtab file on your system is a
-symbolic link to /proc/mounts. You will need to do it manually using
-"-d" switch of losetup(8). Read losetup(8) manpage for more info.
+loaded automatically, make sure that you have compiled the module and
+that modprobe is functioning. Beware that umount will not deallocate
+/dev/loopN device if /etc/mtab file on your system is a symbolic link to
+/proc/mounts. You will need to do it manually using "-d" switch of
+losetup(8). Read losetup(8) manpage for more info.
 
 To create the BFS image under UnixWare you need to find out first which
 slice contains it. The command prtvtoc(1M) is your friend:
index 7f27b8f840d06210df1511db6ef603cedb8f0e58..9e9c348275a96fd362acf9916d2789be8a08c4c8 100644 (file)
@@ -248,6 +248,7 @@ The top level sysfs directory looks like:
 block/
 bus/
 class/
+dev/
 devices/
 firmware/
 net/
@@ -274,6 +275,11 @@ fs/ contains a directory for some filesystems.  Currently each
 filesystem wanting to export attributes must create its own hierarchy
 below fs/ (see ./fuse.txt for an example).
 
+dev/ contains two directories char/ and block/. Inside these two
+directories there are symlinks named <major>:<minor>.  These symlinks
+point to the sysfs directory for the given device.  /sys/dev provides a
+quick way to lookup the sysfs interface for a device from the result of
+a stat(2) operation.
 
 More information can driver-model specific features can be found in
 Documentation/driver-model/. 
diff --git a/Documentation/ia64/paravirt_ops.txt b/Documentation/ia64/paravirt_ops.txt
new file mode 100644 (file)
index 0000000..39ded02
--- /dev/null
@@ -0,0 +1,137 @@
+Paravirt_ops on IA64
+====================
+                          21 May 2008, Isaku Yamahata <yamahata@valinux.co.jp>
+
+
+Introduction
+------------
+The aim of this documentation is to help with maintainability and/or to
+encourage people to use paravirt_ops/IA64.
+
+paravirt_ops (pv_ops in short) is a way for virtualization support of
+Linux kernel on x86. Several ways for virtualization support were
+proposed, paravirt_ops is the winner.
+On the other hand, now there are also several IA64 virtualization
+technologies like kvm/IA64, xen/IA64 and many other academic IA64
+hypervisors so that it is good to add generic virtualization
+infrastructure on Linux/IA64.
+
+
+What is paravirt_ops?
+---------------------
+It has been developed on x86 as virtualization support via API, not ABI.
+It allows each hypervisor to override operations which are important for
+hypervisors at API level. And it allows a single kernel binary to run on
+all supported execution environments including native machine.
+Essentially paravirt_ops is a set of function pointers which represent
+operations corresponding to low level sensitive instructions and high
+level functionalities in various area. But one significant difference
+from usual function pointer table is that it allows optimization with
+binary patch. It is because some of these operations are very
+performance sensitive and indirect call overhead is not negligible.
+With binary patch, indirect C function call can be transformed into
+direct C function call or in-place execution to eliminate the overhead.
+
+Thus, operations of paravirt_ops are classified into three categories.
+- simple indirect call
+  These operations correspond to high level functionality so that the
+  overhead of indirect call isn't very important.
+
+- indirect call which allows optimization with binary patch
+  Usually these operations correspond to low level instructions. They
+  are called frequently and performance critical. So the overhead is
+  very important.
+
+- a set of macros for hand written assembly code
+  Hand written assembly codes (.S files) also need paravirtualization
+  because they include sensitive instructions or some of code paths in
+  them are very performance critical.
+
+
+The relation to the IA64 machine vector
+---------------------------------------
+Linux/IA64 has the IA64 machine vector functionality which allows the
+kernel to switch implementations (e.g. initialization, ipi, dma api...)
+depending on executing platform.
+We can replace some implementations very easily defining a new machine
+vector. Thus another approach for virtualization support would be
+enhancing the machine vector functionality.
+But paravirt_ops approach was taken because
+- virtualization support needs wider support than machine vector does.
+  e.g. low level instruction paravirtualization. It must be
+       initialized very early before platform detection.
+
+- virtualization support needs more functionality like binary patch.
+  Probably the calling overhead might not be very large compared to the
+  emulation overhead of virtualization. However in the native case, the
+  overhead should be eliminated completely.
+  A single kernel binary should run on each environment including native,
+  and the overhead of paravirt_ops on native environment should be as
+  small as possible.
+
+- for full virtualization technology, e.g. KVM/IA64 or
+  Xen/IA64 HVM domain, the result would be
+  (the emulated platform machine vector. probably dig) + (pv_ops).
+  This means that the virtualization support layer should be under
+  the machine vector layer.
+
+Possibly it might be better to move some function pointers from
+paravirt_ops to machine vector. In fact, Xen domU case utilizes both
+pv_ops and machine vector.
+
+
+IA64 paravirt_ops
+-----------------
+In this section, the concrete paravirt_ops will be discussed.
+Because of the architecture difference between ia64 and x86, the
+resulting set of functions is very different from x86 pv_ops.
+
+- C function pointer tables
+They are not very performance critical so that simple C indirect
+function call is acceptable. The following structures are defined at
+this moment. For details see linux/include/asm-ia64/paravirt.h
+  - struct pv_info
+    This structure describes the execution environment.
+  - struct pv_init_ops
+    This structure describes the various initialization hooks.
+  - struct pv_iosapic_ops
+    This structure describes hooks to iosapic operations.
+  - struct pv_irq_ops
+    This structure describes hooks to irq related operations
+  - struct pv_time_op
+    This structure describes hooks to steal time accounting.
+
+- a set of indirect calls which need optimization
+Currently this class of functions correspond to a subset of IA64
+intrinsics. At this moment the optimization with binary patch isn't
+implemented yet.
+struct pv_cpu_op is defined. For details see
+linux/include/asm-ia64/paravirt_privop.h
+Mostly they correspond to ia64 intrinsics 1-to-1.
+Caveat: Now they are defined as C indirect function pointers, but in
+order to support binary patch optimization, they will be changed
+using GCC extended inline assembly code.
+
+- a set of macros for hand written assembly code (.S files)
+For maintenance purpose, the taken approach for .S files is single
+source code and compile multiple times with different macros definitions.
+Each pv_ops instance must define those macros to compile.
+The important thing here is that sensitive, but non-privileged
+instructions must be paravirtualized and that some privileged
+instructions also need paravirtualization for reasonable performance.
+Developers who modify .S files must be aware of that. At this moment
+an easy checker is implemented to detect paravirtualization breakage.
+But it doesn't cover all the cases.
+
+Sometimes this set of macros is called pv_cpu_asm_op. But there is no
+corresponding structure in the source code.
+Those macros mostly 1:1 correspond to a subset of privileged
+instructions. See linux/include/asm-ia64/native/inst.h.
+And some functions written in assembly also need to be overrided so
+that each pv_ops instance have to define some macros. Again see
+linux/include/asm-ia64/native/inst.h.
+
+
+Those structures must be initialized very early before start_kernel.
+Probably initialized in head.S using multi entry point or some other trick.
+For native case implementation see linux/arch/ia64/kernel/paravirt.c.
index 14e0a8b70225f5cce93c2cf8bdb85a0aa984b8ee..03a74fc3b49679c0326a59faa43b2e423751e0c5 100644 (file)
@@ -1,5 +1,3 @@
-$Id: gameport-programming.txt,v 1.3 2001/04/24 13:51:37 vojtech Exp $
-
 Programming gameport drivers
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
index ff8cea0225f90bdce6c28adc5b3af5816f9eea44..686ee9932dffd86fa78775859a97815ecc514be2 100644 (file)
@@ -1,7 +1,6 @@
                          Linux Input drivers v1.0
               (c) 1999-2001 Vojtech Pavlik <vojtech@ucw.cz>
                             Sponsored by SuSE
-           $Id: input.txt,v 1.8 2002/05/29 03:15:01 bradleym Exp $
 ----------------------------------------------------------------------------
 
 0. Disclaimer
index acbd32b88454dc5c48c7a10bb112757910d3c7e5..c507330740cd4fb14e37e617d01d95262057d129 100644 (file)
@@ -5,8 +5,6 @@
 
                              7 Aug 1998
 
-       $Id: joystick-api.txt,v 1.2 2001/05/08 21:21:23 vojtech Exp $
-
 1. Initialization
 ~~~~~~~~~~~~~~~~~
 
index ede5f33daad3dbc0f7346654a348fd4eb28d7387..1c856f32ff2c3bc880746533c149ec6cc146806f 100644 (file)
@@ -2,7 +2,6 @@
               (c) 1998-2000 Vojtech Pavlik <vojtech@ucw.cz>
               (c) 1998 Andree Borrmann <a.borrmann@tu-bs.de>
                             Sponsored by SuSE
-       $Id: joystick-parport.txt,v 1.6 2001/09/25 09:31:32 vojtech Exp $
 ----------------------------------------------------------------------------
 
 0. Disclaimer
index 389de9bd987894017bb25ddc95b911c98526bdcb..154d767b2acbc4be459044d78e7f63b975faa207 100644 (file)
@@ -1,7 +1,6 @@
                       Linux Joystick driver v2.0.0
               (c) 1996-2000 Vojtech Pavlik <vojtech@ucw.cz>
                             Sponsored by SuSE
-          $Id: joystick.txt,v 1.12 2002/03/03 12:13:07 jdeneux Exp $
 ----------------------------------------------------------------------------
 
 0. Disclaimer
index 09ad7450647bc81dff32a3eaf7ea3c0858f4a896..47e7d8794fc6fbad46c37edbc1d9a5bc4f6c3e82 100644 (file)
@@ -1206,7 +1206,7 @@ and is between 256 and 4096 characters. It is defined in the file
                                 or
                                 memmap=0x10000$0x18690000
 
-       memtest=        [KNL,X86_64] Enable memtest
+       memtest=        [KNL,X86] Enable memtest
                        Format: <integer>
                        range: 0,4 : pattern number
                        default : 0 <disable>
@@ -1279,6 +1279,13 @@ and is between 256 and 4096 characters. It is defined in the file
                        This usage is only documented in each driver source
                        file if at all.
 
+       nf_conntrack.acct=
+                       [NETFILTER] Enable connection tracking flow accounting
+                       0 to disable accounting
+                       1 to enable accounting
+                       Default value depends on CONFIG_NF_CT_ACCT that is
+                       going to be removed in 2.6.29.
+
        nfsaddrs=       [NFS]
                        See Documentation/filesystems/nfsroot.txt.
 
@@ -2027,6 +2034,9 @@ and is between 256 and 4096 characters. It is defined in the file
 
        snd-ymfpci=     [HW,ALSA]
 
+       softlockup_panic=
+                       [KNL] Should the soft-lockup detector generate panics.
+
        sonypi.*=       [HW] Sony Programmable I/O Control Device driver
                        See Documentation/sonypi.txt
 
@@ -2158,6 +2168,10 @@ and is between 256 and 4096 characters. It is defined in the file
                        Note that genuine overcurrent events won't be
                        reported either.
 
+       unknown_nmi_panic
+                       [X86-32,X86-64]
+                       Set unknown_nmi_panic=1 early on boot.
+
        usbcore.autosuspend=
                        [USB] The autosuspend time delay (in seconds) used
                        for newly-detected USB devices (default 2).  This
index a8b430627473aa243995ab6f6e173b9cf1ff819e..1da9d1b1793f3436b3561a48de7fbcd8c893e74e 100644 (file)
@@ -236,6 +236,11 @@ All md devices contain:
      writing the word for the desired state, however some states
      cannot be explicitly set, and some transitions are not allowed.
 
+     Select/poll works on this file.  All changes except between
+       active_idle and active (which can be frequent and are not
+       very interesting) are notified.  active->active_idle is
+       reported if the metadata is externally managed.
+
      clear
          No devices, no size, no level
          Writing is equivalent to STOP_ARRAY ioctl
@@ -292,6 +297,10 @@ Each directory contains:
              writemostly - device will only be subject to read
                         requests if there are no other options.
                         This applies only to raid1 arrays.
+             blocked  - device has failed, metadata is "external",
+                        and the failure hasn't been acknowledged yet.
+                        Writes that would write to this device if
+                        it were not faulty are blocked.
              spare    - device is working, but not a full member.
                         This includes spares that are in the process
                         of being recovered to
@@ -301,6 +310,12 @@ Each directory contains:
        Writing "remove" removes the device from the array.
        Writing "writemostly" sets the writemostly flag.
        Writing "-writemostly" clears the writemostly flag.
+       Writing "blocked" sets the "blocked" flag.
+       Writing "-blocked" clear the "blocked" flag and allows writes
+               to complete.
+
+       This file responds to select/poll. Any change to 'faulty'
+       or 'blocked' causes an event.
 
       errors
        An approximate count of read errors that have been detected on
@@ -332,7 +347,7 @@ Each directory contains:
         for storage of data.  This will normally be the same as the
        component_size.  This can be written while assembling an
         array.  If a value less than the current component_size is
-        written, component_size will be reduced to this value.
+        written, it will be rejected.
 
 
 An active md device will also contain and entry for each active device
@@ -381,6 +396,19 @@ also have
        'check' and 'repair' will start the appropriate process
            providing the current state is 'idle'.
 
+      This file responds to select/poll.  Any important change in the value
+      triggers a poll event.  Sometimes the value will briefly be
+      "recover" if a recovery seems to be needed, but cannot be
+      achieved. In that case, the transition to "recover" isn't
+      notified, but the transition away is.
+
+   degraded
+      This contains a count of the number of devices by which the
+      arrays is degraded.  So an optimal array with show '0'.  A
+      single failed/missing drive will show '1', etc.
+      This file responds to select/poll, any increase or decrease
+      in the count of missing devices will trigger an event.
+
    mismatch_count
       When performing 'check' and 'repair', and possibly when
       performing 'resync', md will count the number of errors that are
index 61b171cf5313c9b94c3e4fe185a9ff9edf9b5cbc..2df71861e578b6ebcb2b94371d4a32fbdf7fca61 100644 (file)
@@ -513,21 +513,11 @@ Additional Configurations
   Intel(R) PRO/1000 PT Dual Port Server Connection
   Intel(R) PRO/1000 PT Dual Port Server Adapter
   Intel(R) PRO/1000 PF Dual Port Server Adapter
-  Intel(R) PRO/1000 PT Quad Port Server Adapter 
+  Intel(R) PRO/1000 PT Quad Port Server Adapter
 
   NAPI
   ----
-  NAPI (Rx polling mode) is supported in the e1000 driver.  NAPI is enabled
-  or disabled based on the configuration of the kernel.  To override
-  the default, use the following compile-time flags.
-
-  To enable NAPI, compile the driver module, passing in a configuration option:
-
-       make CFLAGS_EXTRA=-DE1000_NAPI install
-
-  To disable NAPI, compile the driver module, passing in a configuration option:
-
-       make CFLAGS_EXTRA=-DE1000_NO_NAPI install
+  NAPI (Rx polling mode) is enabled in the e1000 driver.
 
   See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
 
index 3870f280280b34e6f81cce2229b896357091f7c6..855d8da57a232bd12f765205c4ef047b51264006 100644 (file)
         getsockopt(sockfd, SOL_SOCKET, SO_NO_CHECK, &value, ...);
 
   is meaningless (as in TCP). Packets with a zero checksum field are
-  illegal (cf. RFC 3828, sec. 3.1) will be silently discarded.
+  illegal (cf. RFC 3828, sec. 3.1) and will be silently discarded.
 
   4) Fragmentation
 
index aee243a846a21f78ae7c68f64f0dc439c92ad83f..ea1b70b357936b6e32ebfb8e3c7ae180f45f9209 100644 (file)
@@ -89,10 +89,12 @@ Table of Contents
     3) OpenPIC Interrupt Controllers
     4) ISA Interrupt Controllers
 
-  VIII - Specifying GPIO information for devices
+  IX - Specifying GPIO information for devices
     1) gpios property
     2) gpio-controller nodes
 
+  X - Specifying device power management information (sleep property)
+
   Appendix A - Sample SOC node for MPC8540
 
 
@@ -2488,8 +2490,8 @@ encodings listed below:
        2 =  high to low edge sensitive type enabled
        3 =  low to high edge sensitive type enabled
 
-VIII - Specifying GPIO information for devices
-==============================================
+IX - Specifying GPIO information for devices
+============================================
 
 1) gpios property
 -----------------
@@ -2537,116 +2539,151 @@ Example of two SOC GPIO banks defined as gpio-controller nodes:
                gpio-controller;
        };
 
+X - Specifying Device Power Management Information (sleep property)
+===================================================================
+
+Devices on SOCs often have mechanisms for placing devices into low-power
+states that are decoupled from the devices' own register blocks.  Sometimes,
+this information is more complicated than a cell-index property can
+reasonably describe.  Thus, each device controlled in such a manner
+may contain a "sleep" property which describes these connections.
+
+The sleep property consists of one or more sleep resources, each of
+which consists of a phandle to a sleep controller, followed by a
+controller-specific sleep specifier of zero or more cells.
+
+The semantics of what type of low power modes are possible are defined
+by the sleep controller.  Some examples of the types of low power modes
+that may be supported are:
+
+ - Dynamic: The device may be disabled or enabled at any time.
+ - System Suspend: The device may request to be disabled or remain
+   awake during system suspend, but will not be disabled until then.
+ - Permanent: The device is disabled permanently (until the next hard
+   reset).
+
+Some devices may share a clock domain with each other, such that they should
+only be suspended when none of the devices are in use.  Where reasonable,
+such nodes should be placed on a virtual bus, where the bus has the sleep
+property.  If the clock domain is shared among devices that cannot be
+reasonably grouped in this manner, then create a virtual sleep controller
+(similar to an interrupt nexus, except that defining a standardized
+sleep-map should wait until its necessity is demonstrated).
+
 Appendix A - Sample SOC node for MPC8540
 ========================================
 
-Note that the #address-cells and #size-cells for the SoC node
-in this example have been explicitly listed; these are likely
-not necessary as they are usually the same as the root node.
-
-       soc8540@e0000000 {
+       soc@e0000000 {
                #address-cells = <1>;
                #size-cells = <1>;
-               #interrupt-cells = <2>;
+               compatible = "fsl,mpc8540-ccsr", "simple-bus";
                device_type = "soc";
-               ranges = <00000000 e0000000 00100000>
-               reg = <e0000000 00003000>;
+               ranges = <0x00000000 0xe0000000 0x00100000>
                bus-frequency = <0>;
-
-               mdio@24520 {
-                       reg = <24520 20>;
-                       device_type = "mdio";
-                       compatible = "gianfar";
-
-                       ethernet-phy@0 {
-                               linux,phandle = <2452000>
-                               interrupt-parent = <40000>;
-                               interrupts = <35 1>;
-                               reg = <0>;
-                               device_type = "ethernet-phy";
-                       };
-
-                       ethernet-phy@1 {
-                               linux,phandle = <2452001>
-                               interrupt-parent = <40000>;
-                               interrupts = <35 1>;
-                               reg = <1>;
-                               device_type = "ethernet-phy";
-                       };
-
-                       ethernet-phy@3 {
-                               linux,phandle = <2452002>
-                               interrupt-parent = <40000>;
-                               interrupts = <35 1>;
-                               reg = <3>;
-                               device_type = "ethernet-phy";
-                       };
-
-               };
+               interrupt-parent = <&pic>;
 
                ethernet@24000 {
-                       #size-cells = <0>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
                        device_type = "network";
                        model = "TSEC";
-                       compatible = "gianfar";
-                       reg = <24000 1000>;
-                       mac-address = [ 00 E0 0C 00 73 00 ];
-                       interrupts = <d 3 e 3 12 3>;
-                       interrupt-parent = <40000>;
-                       phy-handle = <2452000>;
+                       compatible = "gianfar", "simple-bus";
+                       reg = <0x24000 0x1000>;
+                       local-mac-address = [ 00 E0 0C 00 73 00 ];
+                       interrupts = <29 2 30 2 34 2>;
+                       phy-handle = <&phy0>;
+                       sleep = <&pmc 00000080>;
+                       ranges;
+
+                       mdio@24520 {
+                               reg = <0x24520 0x20>;
+                               compatible = "fsl,gianfar-mdio";
+
+                               phy0: ethernet-phy@0 {
+                                       interrupts = <5 1>;
+                                       reg = <0>;
+                                       device_type = "ethernet-phy";
+                               };
+
+                               phy1: ethernet-phy@1 {
+                                       interrupts = <5 1>;
+                                       reg = <1>;
+                                       device_type = "ethernet-phy";
+                               };
+
+                               phy3: ethernet-phy@3 {
+                                       interrupts = <7 1>;
+                                       reg = <3>;
+                                       device_type = "ethernet-phy";
+                               };
+                       };
                };
 
                ethernet@25000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
                        device_type = "network";
                        model = "TSEC";
                        compatible = "gianfar";
-                       reg = <25000 1000>;
-                       mac-address = [ 00 E0 0C 00 73 01 ];
-                       interrupts = <13 3 14 3 18 3>;
-                       interrupt-parent = <40000>;
-                       phy-handle = <2452001>;
+                       reg = <0x25000 0x1000>;
+                       local-mac-address = [ 00 E0 0C 00 73 01 ];
+                       interrupts = <13 2 14 2 18 2>;
+                       phy-handle = <&phy1>;
+                       sleep = <&pmc 00000040>;
                };
 
                ethernet@26000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
                        device_type = "network";
                        model = "FEC";
                        compatible = "gianfar";
-                       reg = <26000 1000>;
-                       mac-address = [ 00 E0 0C 00 73 02 ];
-                       interrupts = <19 3>;
-                       interrupt-parent = <40000>;
-                       phy-handle = <2452002>;
+                       reg = <0x26000 0x1000>;
+                       local-mac-address = [ 00 E0 0C 00 73 02 ];
+                       interrupts = <41 2>;
+                       phy-handle = <&phy3>;
+                       sleep = <&pmc 00000020>;
                };
 
                serial@4500 {
-                       device_type = "serial";
-                       compatible = "ns16550";
-                       reg = <4500 100>;
-                       clock-frequency = <0>;
-                       interrupts = <1a 3>;
-                       interrupt-parent = <40000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,mpc8540-duart", "simple-bus";
+                       sleep = <&pmc 00000002>;
+                       ranges;
+
+                       serial@4500 {
+                               device_type = "serial";
+                               compatible = "ns16550";
+                               reg = <0x4500 0x100>;
+                               clock-frequency = <0>;
+                               interrupts = <42 2>;
+                       };
+
+                       serial@4600 {
+                               device_type = "serial";
+                               compatible = "ns16550";
+                               reg = <0x4600 0x100>;
+                               clock-frequency = <0>;
+                               interrupts = <42 2>;
+                       };
                };
 
-               pic@40000 {
-                       linux,phandle = <40000>;
+               pic: pic@40000 {
                        interrupt-controller;
                        #address-cells = <0>;
-                       reg = <40000 40000>;
+                       #interrupt-cells = <2>;
+                       reg = <0x40000 0x40000>;
                        compatible = "chrp,open-pic";
                        device_type = "open-pic";
                };
 
                i2c@3000 {
-                       interrupt-parent = <40000>;
-                       interrupts = <1b 3>;
-                       reg = <3000 18>;
-                       device_type = "i2c";
+                       interrupts = <43 2>;
+                       reg = <0x3000 0x100>;
                        compatible  = "fsl-i2c";
                        dfsrr;
+                       sleep = <&pmc 00000004>;
                };
 
+               pmc: power@e0070 {
+                       compatible = "fsl,mpc8540-pmc", "fsl,mpc8548-pmc";
+                       reg = <0xe0070 0x20>;
+               };
        };
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/gpio.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/gpio.txt
new file mode 100644 (file)
index 0000000..1815dfe
--- /dev/null
@@ -0,0 +1,38 @@
+Every GPIO controller node must have #gpio-cells property defined,
+this information will be used to translate gpio-specifiers.
+
+On CPM1 devices, all ports are using slightly different register layouts.
+Ports A, C and D are 16bit ports and Ports B and E are 32bit ports.
+
+On CPM2 devices, all ports are 32bit ports and use a common register layout.
+
+Required properties:
+- compatible : "fsl,cpm1-pario-bank-a", "fsl,cpm1-pario-bank-b",
+  "fsl,cpm1-pario-bank-c", "fsl,cpm1-pario-bank-d",
+  "fsl,cpm1-pario-bank-e", "fsl,cpm2-pario-bank"
+- #gpio-cells : Should be two. The first cell is the pin number and the
+  second cell is used to specify optional paramters (currently unused).
+- gpio-controller : Marks the port as GPIO controller.
+
+Example of three SOC GPIO banks defined as gpio-controller nodes:
+
+       CPM1_PIO_A: gpio-controller@950 {
+               #gpio-cells = <2>;
+               compatible = "fsl,cpm1-pario-bank-a";
+               reg = <0x950 0x10>;
+               gpio-controller;
+       };
+
+       CPM1_PIO_B: gpio-controller@ab8 {
+               #gpio-cells = <2>;
+               compatible = "fsl,cpm1-pario-bank-b";
+               reg = <0xab8 0x10>;
+               gpio-controller;
+       };
+
+       CPM1_PIO_E: gpio-controller@ac8 {
+               #gpio-cells = <2>;
+               compatible = "fsl,cpm1-pario-bank-e";
+               reg = <0xac8 0x18>;
+               gpio-controller;
+       };
index c8f44d6bcbcf6b85314b4f79c8c30ee32e1fc27c..9ccd5f30405b7828715186d2185d3636e3629207 100644 (file)
@@ -1,22 +1,37 @@
-* USB (Universal Serial Bus Controller)
+Freescale QUICC Engine USB Controller
 
 Required properties:
-- compatible : could be "qe_udc" or "fhci-hcd".
-- mode : the could be "host" or "slave".
-- reg : Offset and length of the register set for the device
-- interrupts : <a b> where a is the interrupt number and b is a
-  field that represents an encoding of the sense and level
-  information for the interrupt.  This should be encoded based on
-  the information in section 2) depending on the type of interrupt
-  controller you have.
-- interrupt-parent : the phandle for the interrupt controller that
-  services interrupts for this device.
+- compatible : should be "fsl,<chip>-qe-usb", "fsl,mpc8323-qe-usb".
+- reg : the first two cells should contain usb registers location and
+  length, the next two two cells should contain PRAM location and
+  length.
+- interrupts : should contain USB interrupt.
+- interrupt-parent : interrupt source phandle.
+- fsl,fullspeed-clock : specifies the full speed USB clock source:
+  "none": clock source is disabled
+  "brg1" through "brg16": clock source is BRG1-BRG16, respectively
+  "clk1" through "clk24": clock source is CLK1-CLK24, respectively
+- fsl,lowspeed-clock : specifies the low speed USB clock source:
+  "none": clock source is disabled
+  "brg1" through "brg16": clock source is BRG1-BRG16, respectively
+  "clk1" through "clk24": clock source is CLK1-CLK24, respectively
+- hub-power-budget : USB power budget for the root hub, in mA.
+- gpios : should specify GPIOs in this order: USBOE, USBTP, USBTN, USBRP,
+  USBRN, SPEED (optional), and POWER (optional).
 
-Example(slave):
-       usb@6c0 {
-               compatible = "qe_udc";
-               reg = <6c0 40>;
-               interrupts = <8b 0>;
-               interrupt-parent = <700>;
-               mode = "slave";
-       };
+Example:
+
+usb@6c0 {
+       compatible = "fsl,mpc8360-qe-usb", "fsl,mpc8323-qe-usb";
+       reg = <0x6c0 0x40 0x8b00 0x100>;
+       interrupts = <11>;
+       interrupt-parent = <&qeic>;
+       fsl,fullspeed-clock = "clk21";
+       gpios = <&qe_pio_b  2 0 /* USBOE */
+                &qe_pio_b  3 0 /* USBTP */
+                &qe_pio_b  8 0 /* USBTN */
+                &qe_pio_b  9 0 /* USBRP */
+                &qe_pio_b 11 0 /* USBRN */
+                &qe_pio_e 20 0 /* SPEED */
+                &qe_pio_e 21 0 /* POWER */>;
+};
diff --git a/Documentation/powerpc/dts-bindings/fsl/mcu-mpc8349emitx.txt b/Documentation/powerpc/dts-bindings/fsl/mcu-mpc8349emitx.txt
new file mode 100644 (file)
index 0000000..0f76633
--- /dev/null
@@ -0,0 +1,17 @@
+Freescale MPC8349E-mITX-compatible Power Management Micro Controller Unit (MCU)
+
+Required properties:
+- compatible : "fsl,<mcu-chip>-<board>", "fsl,mcu-mpc8349emitx".
+- reg : should specify I2C address (0x0a).
+- #gpio-cells : should be 2.
+- gpio-controller : should be present.
+
+Example:
+
+mcu@0a {
+       #gpio-cells = <2>;
+       compatible = "fsl,mc9s08qg8-mpc8349emitx",
+                    "fsl,mcu-mpc8349emitx";
+       reg = <0x0a>;
+       gpio-controller;
+};
diff --git a/Documentation/powerpc/dts-bindings/fsl/pmc.txt b/Documentation/powerpc/dts-bindings/fsl/pmc.txt
new file mode 100644 (file)
index 0000000..02f6f43
--- /dev/null
@@ -0,0 +1,63 @@
+* Power Management Controller
+
+Properties:
+- compatible: "fsl,<chip>-pmc".
+
+  "fsl,mpc8349-pmc" should be listed for any chip whose PMC is
+  compatible.  "fsl,mpc8313-pmc" should also be listed for any chip
+  whose PMC is compatible, and implies deep-sleep capability.
+
+  "fsl,mpc8548-pmc" should be listed for any chip whose PMC is
+  compatible.  "fsl,mpc8536-pmc" should also be listed for any chip
+  whose PMC is compatible, and implies deep-sleep capability.
+
+  "fsl,mpc8641d-pmc" should be listed for any chip whose PMC is
+  compatible; all statements below that apply to "fsl,mpc8548-pmc" also
+  apply to "fsl,mpc8641d-pmc".
+
+  Compatibility does not include bit assigments in SCCR/PMCDR/DEVDISR; these
+  bit assigments are indicated via the sleep specifier in each device's
+  sleep property.
+
+- reg: For devices compatible with "fsl,mpc8349-pmc", the first resource
+  is the PMC block, and the second resource is the Clock Configuration
+  block.
+
+  For devices compatible with "fsl,mpc8548-pmc", the first resource
+  is a 32-byte block beginning with DEVDISR.
+
+- interrupts: For "fsl,mpc8349-pmc"-compatible devices, the first
+  resource is the PMC block interrupt.
+
+- fsl,mpc8313-wakeup-timer: For "fsl,mpc8313-pmc"-compatible devices,
+  this is a phandle to an "fsl,gtm" node on which timer 4 can be used as
+  a wakeup source from deep sleep.
+
+Sleep specifiers:
+
+  fsl,mpc8349-pmc: Sleep specifiers consist of one cell.  For each bit
+  that is set in the cell, the corresponding bit in SCCR will be saved
+  and cleared on suspend, and restored on resume.  This sleep controller
+  supports disabling and resuming devices at any time.
+
+  fsl,mpc8536-pmc: Sleep specifiers consist of three cells, the third of
+  which will be ORed into PMCDR upon suspend, and cleared from PMCDR
+  upon resume.  The first two cells are as described for fsl,mpc8578-pmc.
+  This sleep controller only supports disabling devices during system
+  sleep, or permanently.
+
+  fsl,mpc8548-pmc: Sleep specifiers consist of one or two cells, the
+  first of which will be ORed into DEVDISR (and the second into
+  DEVDISR2, if present -- this cell should be zero or absent if the
+  hardware does not have DEVDISR2) upon a request for permanent device
+  disabling.  This sleep controller does not support configuring devices
+  to disable during system sleep (unless supported by another compatible
+  match), or dynamically.
+
+Example:
+
+       power@b00 {
+               compatible = "fsl,mpc8313-pmc", "fsl,mpc8349-pmc";
+               reg = <0xb00 0x100 0xa00 0x100>;
+               interrupts = <80 8>;
+       };
index 583ef6b56c43e5f65f2d9014dd06bf0b1473c962..cf55fa4112d2736de01e0989c5f11d417346326a 100644 (file)
@@ -24,46 +24,39 @@ Example:
 
 * Gianfar-compatible ethernet nodes
 
-Required properties:
+Properties:
 
   - device_type : Should be "network"
   - model : Model of the device.  Can be "TSEC", "eTSEC", or "FEC"
   - compatible : Should be "gianfar"
   - reg : Offset and length of the register set for the device
-  - mac-address : List of bytes representing the ethernet address of
+  - local-mac-address : List of bytes representing the ethernet address of
     this controller
-  - interrupts : <a b> where a is the interrupt number and b is a
-    field that represents an encoding of the sense and level
-    information for the interrupt.  This should be encoded based on
-    the information in section 2) depending on the type of interrupt
-    controller you have.
-  - interrupt-parent : the phandle for the interrupt controller that
-    services interrupts for this device.
+  - interrupts : For FEC devices, the first interrupt is the device's
+    interrupt.  For TSEC and eTSEC devices, the first interrupt is
+    transmit, the second is receive, and the third is error.
   - phy-handle : The phandle for the PHY connected to this ethernet
     controller.
   - fixed-link : <a b c d e> where a is emulated phy id - choose any,
     but unique to the all specified fixed-links, b is duplex - 0 half,
     1 full, c is link speed - d#10/d#100/d#1000, d is pause - 0 no
     pause, 1 pause, e is asym_pause - 0 no asym_pause, 1 asym_pause.
-
-Recommended properties:
-
   - phy-connection-type : a string naming the controller/PHY interface type,
     i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id", "sgmii",
     "tbi", or "rtbi".  This property is only really needed if the connection
     is of type "rgmii-id", as all other connection types are detected by
     hardware.
-
+  - fsl,magic-packet : If present, indicates that the hardware supports
+    waking up via magic packet.
 
 Example:
        ethernet@24000 {
-               #size-cells = <0>;
                device_type = "network";
                model = "TSEC";
                compatible = "gianfar";
-               reg = <24000 1000>;
-               mac-address = [ 00 E0 0C 00 73 00 ];
-               interrupts = <d 3 e 3 12 3>;
-               interrupt-parent = <40000>;
-               phy-handle = <2452000>
+               reg = <0x24000 0x1000>;
+               local-mac-address = [ 00 E0 0C 00 73 00 ];
+               interrupts = <29 2 30 2 34 2>;
+               interrupt-parent = <&mpic>;
+               phy-handle = <&phy0>
        };
diff --git a/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt b/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt
new file mode 100644 (file)
index 0000000..84a04d5
--- /dev/null
@@ -0,0 +1,28 @@
+Freescale Localbus UPM programmed to work with NAND flash
+
+Required properties:
+- compatible : "fsl,upm-nand".
+- reg : should specify localbus chip select and size used for the chip.
+- fsl,upm-addr-offset : UPM pattern offset for the address latch.
+- fsl,upm-cmd-offset : UPM pattern offset for the command latch.
+- gpios : may specify optional GPIO connected to the Ready-Not-Busy pin.
+
+Example:
+
+upm@1,0 {
+       compatible = "fsl,upm-nand";
+       reg = <1 0 1>;
+       fsl,upm-addr-offset = <16>;
+       fsl,upm-cmd-offset = <8>;
+       gpios = <&qe_pio_e 18 0>;
+
+       flash {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "...";
+
+               partition@0 {
+                       ...
+               };
+       };
+};
diff --git a/Documentation/powerpc/dts-bindings/gpio/led.txt b/Documentation/powerpc/dts-bindings/gpio/led.txt
new file mode 100644 (file)
index 0000000..ff51f4c
--- /dev/null
@@ -0,0 +1,15 @@
+LED connected to GPIO
+
+Required properties:
+- compatible : should be "gpio-led".
+- label : (optional) the label for this LED. If omitted, the label is
+  taken from the node name (excluding the unit address).
+- gpios : should specify LED GPIO.
+
+Example:
+
+led@0 {
+       compatible = "gpio-led";
+       label = "hdd";
+       gpios = <&mcu_pio 0 1>;
+};
index c4d2e3507af9187adb6a941f859fea9acff3ce61..9d644f7e241e43a0df46189ce3d5a678c0addcb0 100644 (file)
@@ -42,7 +42,7 @@
      <sect1><title>Device Components</title>
 !Esound/core/device.c
      </sect1>
-     <sect1><title>KMOD and Device File Entries</title>
+     <sect1><title>Module requests and Device File Entries</title>
 !Esound/core/sound.c
      </sect1>
      <sect1><title>Memory Management Helpers</title>
index 4a4b428ce8f67839cf3dd407c975d080f2c655f0..6eb6f3a3331c2656b69156b3c308308500b58d98 100644 (file)
@@ -270,8 +270,8 @@ The pinout of the connectors on the IO8+ is:
 Hardware handshaking issues.
 ============================
 
-The driver can be compiled in two different ways. The default
-("Specialix DTR/RTS pin is RTS" is off) the pin behaves as DTR when
+The driver can be told to operate in two different ways. The default
+behaviour is specialix.sx_rtscts = 0 where the pin behaves as DTR when
 hardware handshaking is off. It behaves as the RTS hardware
 handshaking signal when hardware handshaking is selected.
 
@@ -280,7 +280,7 @@ cable will either be compatible with hardware handshaking or with
 software handshaking. So switching on the fly is not really an
 option.
 
-I actually prefer to use the "Specialix DTR/RTS pin is RTS" option.
+I actually prefer to use the "specialix.sx_rtscts=1" option.
 This makes the DTR/RTS pin always an RTS pin, and ioctls to
 change DTR are always ignored. I have a cable that is configured
 for this. 
@@ -379,7 +379,5 @@ it doesn't fit in your computer, bring back the card.
             You have to WRITE to the address register to even 
             read-probe a CD186x register. Disable autodetection?
          -- Specialix: any suggestions?
-       - Arbitrary baud rates are not implemented yet. 
-            If you need this, bug me about it. 
 
 
index 80ef562160bba8697c5623ee3b5fa9b4c163ab4a..6049a2a84dda2111b9c35c628665566e0153b254 100644 (file)
@@ -3,9 +3,8 @@ Rules on how to access information in the Linux kernel sysfs
 The kernel-exported sysfs exports internal kernel implementation details
 and depends on internal kernel structures and layout. It is agreed upon
 by the kernel developers that the Linux kernel does not provide a stable
-internal API. As sysfs is a direct export of kernel internal
-structures, the sysfs interface cannot provide a stable interface either;
-it may always change along with internal kernel changes.
+internal API. Therefore, there are aspects of the sysfs interface that
+may not be stable across kernel releases.
 
 To minimize the risk of breaking users of sysfs, which are in most cases
 low-level userspace applications, with a new kernel release, the users
index 621024fd3a18e83d26b225a6b47ff2233c628ced..44d124005bad403bc22d4e09bb764393cd407beb 100644 (file)
@@ -305,21 +305,14 @@ driver, like this:
 
 which will result in the needed drivers getting loaded automatically.
 
-   g.  if you are planning on using kerneld to automatically load the 
-module for you, then you need to edit /etc/conf.modules and add the 
+   g.  if you are planning on having the kernel automatically request
+the module for you, then you need to edit /etc/conf.modules and add the
 following lines:
 
        options ixj dspio=0x340 xio=0x330 ixjdebug=0
 
 If you do this, then when you execute an application that uses the
-module kerneld will load the module for you.  Note that to do this,
-you need to have your kernel set to support kerneld.  You can check
-for this by looking at /usr/src/linux/.config and you should see this:
-
-       # Loadable module support
-       #
-       <snip>
-       CONFIG_KMOD=y
+module the kernel will request that it is loaded.
 
   h.  if you want non-root users to be able to read and write to the 
 ixj devices (this is a good idea!) you should do the following:
index 815f5c2301ffa8599ce35dd3d684bf66afbfcc02..9b22bd14c3481789ac126c34842002ef7093a72a 100644 (file)
@@ -1,6 +1,7 @@
 
                  Linux Gadget Serial Driver v2.0
                            11/20/2004
+                  (updated 8-May-2008 for v2.3)
 
 
 License and Disclaimer
@@ -31,7 +32,7 @@ Prerequisites
 -------------
 Versions of the gadget serial driver are available for the
 2.4 Linux kernels, but this document assumes you are using
-version 2.0 or later of the gadget serial driver in a 2.6
+version 2.3 or later of the gadget serial driver in a 2.6
 Linux kernel.
 
 This document assumes that you are familiar with Linux and
@@ -40,6 +41,12 @@ standard utilities, use minicom and HyperTerminal, and work with
 USB and serial devices.  It also assumes you configure the Linux
 gadget and usb drivers as modules.
 
+With version 2.3 of the driver, major and minor device nodes are
+no longer statically defined.  Your Linux based system should mount
+sysfs in /sys, and use "mdev" (in Busybox) or "udev" to make the
+/dev nodes matching the sysfs /sys/class/tty files.
+
+
 
 Overview
 --------
@@ -104,15 +111,8 @@ driver.  All this are listed under "USB Gadget Support" when
 configuring the kernel.  Then rebuild and install the kernel or
 modules.
 
-The gadget serial driver uses major number 127, for now.  So you
-will need to create a device node for it, like this:
-
-  mknod /dev/ttygserial c 127 0
-
-You only need to do this once.
-
 Then you must load the gadget serial driver.  To load it as an
-ACM device, do this:
+ACM device (recommended for interoperability), do this:
 
   modprobe g_serial use_acm=1
 
@@ -125,6 +125,23 @@ controller driver.  This must be done each time you reboot the gadget
 side Linux system.  You can add this to the start up scripts, if
 desired.
 
+Your system should use mdev (from busybox) or udev to make the
+device nodes.  After this gadget driver has been set up you should
+then see a /dev/ttyGS0 node:
+
+  # ls -l /dev/ttyGS0 | cat
+  crw-rw----    1 root     root     253,   0 May  8 14:10 /dev/ttyGS0
+  #
+
+Note that the major number (253, above) is system-specific.  If
+you need to create /dev nodes by hand, the right numbers to use
+will be in the /sys/class/tty/ttyGS0/dev file.
+
+When you link this gadget driver early, perhaps even statically,
+you may want to set up an /etc/inittab entry to run "getty" on it.
+The /dev/ttyGS0 line should work like most any other serial port.
+
+
 If gadget serial is loaded as an ACM device you will want to use
 either the Windows or Linux ACM driver on the host side.  If gadget
 serial is loaded as a bulk in/out device, you will want to use the
index d56cb1a1155073987fc2ca108c766f03100d35cf..074b159b77c20344aaa0a4abf7becc8603a2a065 100644 (file)
@@ -81,8 +81,11 @@ re-enumeration shows that the device now attached to that port has the
 same descriptors as before, including the Vendor and Product IDs, then
 the kernel continues to use the same device structure.  In effect, the
 kernel treats the device as though it had merely been reset instead of
-unplugged.  The same thing happens if the host controller is in the
-expected state but a USB device was unplugged and then replugged.
+unplugged.
+
+The same thing happens if the host controller is in the expected state
+but a USB device was unplugged and then replugged, or if a USB device
+fails to carry out a normal resume.
 
 If no device is now attached to the port, or if the descriptors are
 different from what the kernel remembers, then the treatment is what
diff --git a/Documentation/usb/uhci.txt b/Documentation/usb/uhci.txt
deleted file mode 100644 (file)
index 2f25952..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-Specification and Internals for the New UHCI Driver (Whitepaper...)
-
-       brought to you by
-
-       Georg Acher, acher@in.tum.de (executive slave) (base guitar)
-       Deti Fliegl, deti@fliegl.de (executive slave) (lead voice)
-       Thomas Sailer, sailer@ife.ee.ethz.ch (chief consultant) (cheer leader)
-       $Id: README.uhci,v 1.1 1999/12/14 14:03:02 fliegl Exp $
-
-This document and the new uhci sources can be found on
-               http://hotswap.in.tum.de/usb
-
-1. General issues
-
-1.1 Why a new UHCI driver, we already have one?!?
-
-Correct, but its internal structure got more and more mixed up by the (still
-ongoing) efforts to get isochronous transfers (ISO) to work.
-Since there is an increasing need for reliable ISO-transfers (especially 
-for USB-audio needed by TS and for a DAB-USB-Receiver build by GA and DF), 
-this state was a bit unsatisfying in our opinion, so we've decided (based
-on knowledge and experiences with the old UHCI driver) to start 
-from scratch with a new approach, much simpler but at the same time more 
-powerful.
-It is inspired by the way Win98/Win2000 handles USB requests via URBs,
-but it's definitely 100% free of MS-code and doesn't crash while 
-unplugging an used ISO-device like Win98 ;-)
-Some code for HW setup and root hub management was taken from the 
-original UHCI driver, but heavily modified to fit into the new code.
-The invention of the basic concept, and major coding were completed in two 
-days (and nights) on the 16th and 17th of October 1999, now known as the
-great USB-October-Revolution started by GA, DF, and TS ;-)
-
-Since the concept is in no way UHCI dependent, we hope that it will also be 
-transferred to the OHCI-driver, so both drivers share a common API.
-
-1.2. Advantages and disadvantages
-
-+ All USB transfer types work now!
-+ Asynchronous operation
-+ Simple, but powerful interface (only two calls for start and cancel)
-+ Easy migration to the new API, simplified by a compatibility API
-+ Simple usage of ISO transfers
-+ Automatic linking of requests
-+ ISO transfers allow variable length for each frame and striping
-+ No CPU dependent and non-portable atomic memory access, no asm()-inlines
-+ Tested on x86 and Alpha
-
-- Rewriting for ISO transfers needed
-
-1.3. Is there some compatibility to the old API?
-
-Yes, but only for control, bulk and interrupt transfers. We've implemented 
-some wrapper calls for these transfer types. The usbcore works fine with 
-these wrappers. For ISO there's no compatibility, because the old ISO-API 
-and its semantics were unnecessary complicated in our opinion.
-
-1.4. What's really working?
-
-As said above, CTRL and BULK already work fine even with the wrappers,
-so legacy code wouldn't notice the change.
-Regarding to Thomas, ISO transfers now run stable with USB audio.
-INT transfers (e.g. mouse driver) work fine, too.
-
-1.5. Are there any bugs?
-
-No ;-)
-Hm...
-Well, of course this implementation needs extensive testing on all available
-hardware, but we believe that any fixes shouldn't harm the overall concept.
-
-1.6. What should be done next?
-
-A large part of the request handling seems to be identical for UHCI and 
-OHCI, so it would be a good idea to extract the common parts and have only 
-the HW specific stuff in uhci.c. Furthermore, all other USB device drivers
-should need URBification, if they use isochronous or interrupt transfers.
-One thing missing in the current implementation (and the old UHCI driver) 
-is fair queueing for BULK transfers. Since this would need (in principle) 
-the alteration of already constructed TD chains (to switch from depth to 
-breadth execution), another way has to be found. Maybe some simple 
-heuristics work with the same effect.
-
----------------------------------------------------------------------------
-
-2. Internal structure and mechanisms
-
-To get quickly familiar with the internal structures, here's a short
-description how the new UHCI driver works. However, the ultimate source of
-truth is only uhci.c!
-
-2.1. Descriptor structure (QHs and TDs)
-
-During initialization, the following skeleton is allocated in init_skel:
-
-        framespecific           |           common chain     
-
-framelist[]
-[  0 ]-----> TD --> TD -------\
-[  1 ]-----> TD --> TD --------> TD ----> QH -------> QH -------> QH ---> NULL
-  ...        TD --> TD -------/
-[1023]-----> TD --> TD ------/
-            
-            ^^     ^^           ^^       ^^          ^^          ^^
-   1024 TDs for   7 TDs for    1 TD for   Start of    Start of    End Chain
-           ISO  INT (2-128ms) 1ms-INT    CTRL Chain  BULK Chain
-
-For each CTRL or BULK transfer a new QH is allocated and the containing data
-transfers are appended as (vertical) TDs. After building the whole QH with its
-dangling TDs, the QH is inserted before the BULK Chain QH (for CTRL) or
-before the End Chain QH (for BULK). Since only the QH->next pointers are
-affected, no atomic memory operation is required. The three QHs in the
-common chain are never equipped with TDs!
-
-For ISO or INT, the TD for each frame is simply inserted into the appropriate
-ISO/INT-TD-chain for the desired frame. The 7 skeleton INT-TDs are scattered
-among the 1024 frames similar to the old UHCI driver.
-
-For CTRL/BULK/ISO, the last TD in the transfer has the IOC-bit set. For INT,
-every TD (there is only one...) has the IOC-bit set.
-
-Besides the data for the UHCI controller (2 or 4 32bit words), the descriptors
-are double-linked through the .vertical and .horizontal elements in the 
-SW data of the descriptor (using the double-linked list structures and 
-operations), but SW-linking occurs only in closed domains, i.e. for each of
-the 1024 ISO-chains and the 8 INT-chains there is a closed cycle. This 
-simplifies all insertions and unlinking operations and avoids costly 
-bus_to_virt()-calls.
-
-2.2. URB structure and linking to QH/TDs
-
-During assembly of the QH and TDs of the requested action, these descriptors
-are stored in urb->urb_list, so the allocated QH/TD descriptors are bound to
-this URB.
-If the assembly was successful and the descriptors were added to the HW chain,
-the corresponding URB is inserted into a global URB list for this controller.
-This list stores all pending URBs.
-
-2.3. Interrupt processing
-
-Since UHCI provides no means to directly detect completed transactions, the
-following is done in each UHCI interrupt (uhci_interrupt()):
-
-For each URB in the pending queue (process_urb()), the ACTIVE-flag of the 
-associated TDs are processed (depending on the transfer type 
-process_{transfer|interrupt|iso}()). If the TDs are not active anymore, 
-they indicate the completion of the transaction and the status is calculated. 
-Inactive QH/TDs are removed from the HW chain (since the host controller
-already removed the TDs from the QH, no atomic access is needed) and 
-eventually the URB is marked as completed (OK or errors) and removed from the 
-pending queue. Then the next linked URB is submitted. After (or immediately 
-before) that, the completion handler is called.
-
-2.4. Unlinking URBs
-
-First, all QH/TDs stored in the URB are unlinked from the HW chain. 
-To ensure that the host controller really left a vertical TD chain, we 
-wait for one frame. After that, the TDs are physically destroyed.
-
-2.5. URB linking and the consequences
-
-Since URBs can be linked and the corresponding submit_urb is called in
-the UHCI-interrupt, all work associated with URB/QH/TD assembly has to be
-interrupt save. This forces kmalloc to use GFP_ATOMIC in the interrupt.
index e0bba8393c7780b96bd278a63d749fea23e88b35..05138e8aea07c7c3ca125072481c7b39dc0ea1a5 100644 (file)
@@ -193,9 +193,6 @@ Description:     Automatic 'ovcamchip' module loading: 0 disabled, 1 enabled.
                 loads that module automatically. This action is performed as
                 once soon as the 'w9968cf' module is loaded into memory.
 Default:         1
-Note:            The kernel must be compiled with the CONFIG_KMOD option
-                enabled for the 'ovcamchip' module to be loaded and for
-                this parameter to be present.
 -------------------------------------------------------------------------------
 Name:           simcams
 Type:           int
index ec0c9c914f17284d288cfa6cc96253c74951b37a..5d8971c76a7f31df8bda0ad2071f5738de610c93 100644 (file)
@@ -441,10 +441,7 @@ M: spyro@f2s.com
 S:     Maintained
 
 ARM PRIMECELL MMCI PL180/1 DRIVER
-P:     Russell King
-M:     rmk@arm.linux.org.uk
-L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-S:     Maintained
+S:     Orphan
 
 ARM/ADI ROADRUNNER MACHINE SUPPORT
 P:     Lennert Buytenhek
@@ -483,11 +480,28 @@ M:        kernel@wantstofly.org
 L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 S:     Maintained
 
+ARM/COMPULAB CM-X270/EM-X270 MACHINE SUPPORT
+P:     Mike Rapoport
+M:     mike@compulab.co.il
+L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S:     Maintained
+
 ARM/CORGI MACHINE SUPPORT
 P:     Richard Purdie
 M:     rpurdie@rpsys.net
 S:     Maintained
 
+ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6)
+P:     Daniel Ribeiro
+M:     drwyrm@gmail.com
+P:     Stefan Schmidt
+M:     stefan@openezx.org
+P:     Harald Welte
+M:     laforge@openezx.org
+L:     openezx-devel@lists.openezx.org (subscribers-only)
+W:     http://www.openezx.org/
+S:     Maintained
+
 ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
 P:     Lennert Buytenhek
 M:     kernel@wantstofly.org
@@ -575,10 +589,18 @@ L:        linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 S:     Maintained
 
 ARM/TOSA MACHINE SUPPORT
+P:     Dmitry Baryshkov
+M:     dbaryshkov@gmail.com
 P:     Dirk Opfer
 M:     dirk@opfer-online.de
 S:     Maintained
 
+ARM/PALMTX SUPPORT
+P:     Marek Vasut
+M:     marek.vasut@gmail.com
+W:     http://hackndev.com
+S:     Maintained
+
 ARM/PLEB SUPPORT
 P:     Peter Chubb
 M:     pleb@gelato.unsw.edu.au
@@ -1988,6 +2010,12 @@ M:       mikulas@artax.karlin.mff.cuni.cz
 W:     http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
 S:     Maintained
 
+HTCPEN TOUCHSCREEN DRIVER
+P:     Pau Oliva Fora
+M:     pof@eslack.org
+L:     linux-input@vger.kernel.org
+S:     Maintained
+
 HUGETLB FILESYSTEM
 P:     William Irwin
 M:     wli@holomorphy.com
@@ -3527,7 +3555,7 @@ S:        Supported
 
 S390 NETWORK DRIVERS
 P:     Ursula Braun
-M:     ubraun@linux.vnet.ibm.com
+M:     ursula.braun@de.ibm.com
 P:     Frank Blaschka
 M:     blaschka@linux.vnet.ibm.com
 M:     linux390@de.ibm.com
@@ -3547,7 +3575,7 @@ S:        Supported
 
 S390 IUCV NETWORK LAYER
 P:     Ursula Braun
-M:     ubraun@linux.vnet.ibm.com
+M:     ursula.braun@de.ibm.com
 M:     linux390@de.ibm.com
 L:     linux-s390@vger.kernel.org
 W:     http://www.ibm.com/developerworks/linux/linux390/
@@ -4041,9 +4069,10 @@ W:       http://www.buzzard.org.uk/toshiba/
 S:     Maintained
 
 TPM DEVICE DRIVER
-P:     Debora Velarde
-P:     Rajiv Andrade
-M:     tpmdd-devel@lists.sourceforge.net
+P:     Debora Velarde
+M:     debora@linux.vnet.ibm.com
+P:     Rajiv Andrade
+M:     srajiv@linux.vnet.ibm.com
 W:     http://tpmdd.sourceforge.net
 P:     Marcel Selhorst
 M:     tpm@selhorst.net
index 6192922de9c06e7d6b648944ebbde0db96d9c596..4bcd1cf90cb103e8578b4692ea7e75470f8cbe77 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1148,7 +1148,8 @@ clean: archclean $(clean-dirs)
        @find . $(RCS_FIND_IGNORE) \
                \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
                -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-               -o -name '*.symtypes' -o -name 'modules.order' \) \
+               -o -name '*.symtypes' -o -name 'modules.order' \
+               -o -name 'Module.markers' \) \
                -type f -print | xargs rm -f
 
 # mrproper - Delete all generated files, including .config
index c7ad324ddf2cf407c89839f75487f8e27f9fa0cc..d048f6887d0b0aff8e882283923c9a3640a6a816 100644 (file)
@@ -12,6 +12,7 @@ config ARM
        select RTC_LIB
        select SYS_SUPPORTS_APM_EMULATION
        select HAVE_OPROFILE
+       select HAVE_ARCH_KGDB
        select HAVE_KPROBES if (!XIP_KERNEL)
        select HAVE_KRETPROBES if (HAVE_KPROBES)
        select HAVE_FTRACE if (!XIP_KERNEL)
index 2744673314b470cb84b68d1ff9a040a0356d34af..dd2947342604b2ea43bdfa409dcc32b4b2609cf2 100644 (file)
@@ -554,9 +554,8 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
 
        device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC);
        if (!device_info) {
-               printk(KERN_ERR
-                       "Could not allocated dmabounce_device_info for %s",
-                       dev->bus_id);
+               dev_err(dev,
+                       "Could not allocated dmabounce_device_info\n");
                return -ENOMEM;
        }
 
@@ -594,8 +593,7 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
 
        dev->archdata.dmabounce = device_info;
 
-       printk(KERN_INFO "dmabounce: registered device %s on %s bus\n",
-               dev->bus_id, dev->bus->name);
+       dev_info(dev, "dmabounce: registered device\n");
 
        return 0;
 
@@ -614,16 +612,15 @@ dmabounce_unregister_dev(struct device *dev)
        dev->archdata.dmabounce = NULL;
 
        if (!device_info) {
-               printk(KERN_WARNING
-                       "%s: Never registered with dmabounce but attempting" \
-                       "to unregister!\n", dev->bus_id);
+               dev_warn(dev,
+                        "Never registered with dmabounce but attempting"
+                        "to unregister!\n");
                return;
        }
 
        if (!list_empty(&device_info->safe_buffers)) {
-               printk(KERN_ERR
-                       "%s: Removing from dmabounce with pending buffers!\n",
-                       dev->bus_id);
+               dev_err(dev,
+                       "Removing from dmabounce with pending buffers!\n");
                BUG();
        }
 
@@ -639,8 +636,7 @@ dmabounce_unregister_dev(struct device *dev)
 
        kfree(device_info);
 
-       printk(KERN_INFO "dmabounce: device %s on %s bus unregistered\n",
-               dev->bus_id, dev->bus->name);
+       dev_info(dev, "dmabounce: device unregistered\n");
 }
 
 
index d973c986f721aec8822f8ef0db8eeb97b0ec199e..c3c3a333904995273e5f7af7c68890c8baee361d 100644 (file)
@@ -543,7 +543,6 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
                goto out;
        }
 
-       strncpy(dev->dev.bus_id, info->name, sizeof(dev->dev.bus_id));
        /*
         * If the parent device has a DMA mask associated with it,
         * propagate it down to the children.
@@ -553,6 +552,7 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
                dev->dev.dma_mask = &dev->dma_mask;
        }
 
+       dev_set_name(&dev->dev, "%s", info->name);
        dev->devid       = info->devid;
        dev->dev.parent  = lchip->dev;
        dev->dev.bus     = &locomo_bus_type;
index eb06d0b2cb747344c47fb1395d6f2b6fecf080d9..0a8e1ff2af8a99255b0f419d6b7b82f7fe5721a9 100644 (file)
@@ -550,9 +550,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
                goto out;
        }
 
-       snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id),
-                "%4.4lx", info->offset);
-
+       dev_set_name(&dev->dev, "%4.4lx", info->offset);
        dev->devid       = info->devid;
        dev->dev.parent  = sachip->dev;
        dev->dev.bus     = &sa1111_bus_type;
@@ -560,7 +558,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
        dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask;
        dev->res.start   = sachip->phys + info->offset;
        dev->res.end     = dev->res.start + 511;
-       dev->res.name    = dev->dev.bus_id;
+       dev->res.name    = dev_name(&dev->dev);
        dev->res.flags   = IORESOURCE_MEM;
        dev->mapbase     = sachip->base + info->offset;
        dev->skpcr_mask  = info->skpcr_mask;
@@ -570,6 +568,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
        if (ret) {
                printk("SA1111: failed to allocate resource for %s\n",
                        dev->res.name);
+               dev_set_name(&dev->dev, NULL);
                kfree(dev);
                goto out;
        }
@@ -593,7 +592,8 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
                if (dev->dma_mask != 0xffffffffUL) {
                        ret = dmabounce_register_dev(&dev->dev, 1024, 4096);
                        if (ret) {
-                               printk("SA1111: Failed to register %s with dmabounce", dev->dev.bus_id);
+                               dev_err(&dev->dev, "SA1111: Failed to register"
+                                       " with dmabounce\n");
                                device_unregister(&dev->dev);
                        }
                }
@@ -627,7 +627,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
        if (!sachip)
                return -ENOMEM;
 
-       sachip->clk = clk_get(me, "GPIO27_CLK");
+       sachip->clk = clk_get(me, "SA1111_CLK");
        if (!sachip->clk) {
                ret = PTR_ERR(sachip->clk);
                goto err_free;
index bc299b07a6fa8a949ed72fdc352e2cea817f51ac..ae39553589ddbf34b37f37e0d2c3c3d67a1b4e9c 100644 (file)
@@ -247,7 +247,7 @@ static int __devinit scoop_probe(struct platform_device *pdev)
        devptr->gpio.base = -1;
 
        if (inf->gpio_base != 0) {
-               devptr->gpio.label = pdev->dev.bus_id;
+               devptr->gpio.label = dev_name(&pdev->dev);
                devptr->gpio.base = inf->gpio_base;
                devptr->gpio.ngpio = 12; /* PA11 = 0, PA12 = 1, etc. up to PA22 = 11 */
                devptr->gpio.set = scoop_gpio_set;
diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig
new file mode 100644 (file)
index 0000000..2a84d55
--- /dev/null
@@ -0,0 +1,1614 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.26-rc3
+# Mon Jul  7 17:52:21 2008
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION="-ezxdev"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+# CONFIG_MACH_TRIZEPS4 is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_COLIBRI is not set
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_PCM027 is not set
+CONFIG_PXA_EZX=y
+CONFIG_MACH_EZX_A780=y
+CONFIG_MACH_EZX_E680=y
+CONFIG_MACH_EZX_A1200=y
+CONFIG_MACH_EZX_A910=y
+CONFIG_MACH_EZX_E6=y
+CONFIG_MACH_EZX_E2=y
+CONFIG_PXA27x=y
+CONFIG_PXA_SSP=y
+CONFIG_PXA_PWM=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=tty1 root=/dev/mmcblk0p2 rootfstype=ext2 rootdelay=1 ip=192.168.0.202:192.168.0.200:192.168.0.200:255.255.255.0 debug"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+# CONFIG_NF_CT_PROTO_DCCP is not set
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_PROTO_UDPLITE=m
+CONFIG_NF_NAT_PROTO_SCTP=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_RAW=m
+
+#
+# Bridge: Netfilter Configuration
+#
+# CONFIG_BRIDGE_NF_EBTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_SCH_FIFO=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIUSB is not set
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+# CONFIG_BT_HCIUART_BCSP is not set
+# CONFIG_BT_HCIUART_LL is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+
+#
+# Wireless
+#
+CONFIG_CFG80211=m
+CONFIG_NL80211=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_MAC80211=m
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+# CONFIG_MAC80211_RC_DEFAULT_NONE is not set
+
+#
+# Selecting 'y' for an algorithm will
+#
+
+#
+# build the algorithm into mac80211.
+#
+CONFIG_MAC80211_RC_DEFAULT="pid"
+CONFIG_MAC80211_RC_PID=y
+# CONFIG_MAC80211_MESH is not set
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT is not set
+# CONFIG_MAC80211_DEBUG is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=m
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+# CONFIG_MTD_BLKDEVS is not set
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+# CONFIG_MTD_CFI_I2 is not set
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+CONFIG_MTD_XIP=y
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x0
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PXA2XX is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_SHARP_SL is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_APMPOWER is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_PXA27x=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+CONFIG_TOUCHSCREEN_PCAP=y
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+CONFIG_INPUT_UINPUT=y
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=8
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_PXA2XX=m
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_HAVE_GPIO_LIB=y
+
+#
+# GPIO Support
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TC6393XB is not set
+CONFIG_EZX_PCAP=y
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_V4L_USB_DRIVERS is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_VIDEO_PXA27x is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_SI470X is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_SMARTPANEL is not set
+CONFIG_FB_PXA_PARAMETERS=y
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_AM200EPD is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_PWM=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+CONFIG_FONT_MINI_4x6=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+# CONFIG_SND_PXA2XX_AC97 is not set
+
+#
+# SPI devices
+#
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+CONFIG_SND_SOC=y
+CONFIG_SND_PXA2XX_SOC=y
+
+#
+# ALSA SoC audio for Freescale SOCs
+#
+
+#
+# SoC Audio for the Texas Instruments OMAP
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_M66592 is not set
+CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=y
+# CONFIG_USB_ETH_RNDIS is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=y
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_PXA=y
+# CONFIG_MMC_SPI is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_GPIO is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SA1100=m
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=m
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=m
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+# CONFIG_NFS_V4 is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+# CONFIG_NFSD_V4 is not set
+# CONFIG_ROOT_NFS is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+# CONFIG_CIFS_STATS2 is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_SALSA20 is not set
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index eb9092ca80080cd4431951e46c6f2ce8daf70ab8..1d296fc8494e01f7f33a8cac97855506727f3e46 100644 (file)
@@ -28,6 +28,7 @@ obj-$(CONFIG_KPROBES)         += kprobes.o kprobes-decode.o
 obj-$(CONFIG_ATAGS_PROC)       += atags.o
 obj-$(CONFIG_OABI_COMPAT)      += sys_oabi-compat.o
 obj-$(CONFIG_ARM_THUMBEE)      += thumbee.o
+obj-$(CONFIG_KGDB)             += kgdb.o
 
 obj-$(CONFIG_CRUNCH)           += crunch.o crunch-bits.o
 AFLAGS_crunch-bits.o           := -Wa,-mcpu=ep9312
index 8bfd299bfe77a8e0dccb71fb47b330f834f73a2a..f5cfdabcb87dc8314d488dae8d864ecf4b4ca9e4 100644 (file)
@@ -783,7 +783,7 @@ static void ecard_proc_init(void)
 
 #define ec_set_resource(ec,nr,st,sz)                           \
        do {                                                    \
-               (ec)->resource[nr].name = ec->dev.bus_id;       \
+               (ec)->resource[nr].name = dev_name(&ec->dev);   \
                (ec)->resource[nr].start = st;                  \
                (ec)->resource[nr].end = (st) + (sz) - 1;       \
                (ec)->resource[nr].flags = IORESOURCE_MEM;      \
@@ -853,8 +853,7 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot)
        for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
                if (ec->resource[i].flags &&
                    request_resource(&iomem_resource, &ec->resource[i])) {
-                       printk(KERN_ERR "%s: resource(s) not available\n",
-                               ec->dev.bus_id);
+                       dev_err(&ec->dev, "resource(s) not available\n");
                        ec->resource[i].end -= ec->resource[i].start;
                        ec->resource[i].start = 0;
                        ec->resource[i].flags = 0;
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
new file mode 100644 (file)
index 0000000..aaffaec
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * arch/arm/kernel/kgdb.c
+ *
+ * ARM KGDB support
+ *
+ * Copyright (c) 2002-2004 MontaVista Software, Inc
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors:  George Davis <davis_g@mvista.com>
+ *           Deepak Saxena <dsaxena@plexity.net>
+ */
+#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)
+{
+       int regno;
+
+       /* Initialize all to zero. */
+       for (regno = 0; regno < GDB_MAX_REGS; regno++)
+               gdb_regs[regno] = 0;
+
+       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;
+}
+
+/* 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)
+{
+       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];
+}
+
+void
+sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
+{
+       struct pt_regs *thread_regs;
+       int regno;
+
+       /* Just making sure... */
+       if (task == NULL)
+               return;
+
+       /* Initialize to zero */
+       for (regno = 0; regno < GDB_MAX_REGS; regno++)
+               gdb_regs[regno] = 0;
+
+       /* Otherwise, we have only some registers from switch_to() */
+       thread_regs             = task_pt_regs(task);
+       gdb_regs[_R0]           = thread_regs->ARM_r0;
+       gdb_regs[_R1]           = thread_regs->ARM_r1;
+       gdb_regs[_R2]           = thread_regs->ARM_r2;
+       gdb_regs[_R3]           = thread_regs->ARM_r3;
+       gdb_regs[_R4]           = thread_regs->ARM_r4;
+       gdb_regs[_R5]           = thread_regs->ARM_r5;
+       gdb_regs[_R6]           = thread_regs->ARM_r6;
+       gdb_regs[_R7]           = thread_regs->ARM_r7;
+       gdb_regs[_R8]           = thread_regs->ARM_r8;
+       gdb_regs[_R9]           = thread_regs->ARM_r9;
+       gdb_regs[_R10]          = thread_regs->ARM_r10;
+       gdb_regs[_FP]           = thread_regs->ARM_fp;
+       gdb_regs[_IP]           = thread_regs->ARM_ip;
+       gdb_regs[_SPT]          = thread_regs->ARM_sp;
+       gdb_regs[_LR]           = thread_regs->ARM_lr;
+       gdb_regs[_PC]           = thread_regs->ARM_pc;
+       gdb_regs[_CPSR]         = thread_regs->ARM_cpsr;
+}
+
+static int compiled_break;
+
+int kgdb_arch_handle_exception(int exception_vector, int signo,
+                              int err_code, char *remcom_in_buffer,
+                              char *remcom_out_buffer,
+                              struct pt_regs *linux_regs)
+{
+       unsigned long addr;
+       char *ptr;
+
+       switch (remcom_in_buffer[0]) {
+       case 'D':
+       case 'k':
+       case 'c':
+               kgdb_contthread = NULL;
+
+               /*
+                * Try to read optional parameter, pc unchanged if no parm.
+                * If this was a compiled breakpoint, we need to move
+                * to the next instruction or we will just breakpoint
+                * over and over again.
+                */
+               ptr = &remcom_in_buffer[1];
+               if (kgdb_hex2long(&ptr, &addr))
+                       linux_regs->ARM_pc = addr;
+               else if (compiled_break == 1)
+                       linux_regs->ARM_pc += 4;
+
+               compiled_break = 0;
+
+               return 0;
+       }
+
+       return -1;
+}
+
+static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr)
+{
+       kgdb_handle_exception(1, SIGTRAP, 0, regs);
+
+       return 0;
+}
+
+static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
+{
+       compiled_break = 1;
+       kgdb_handle_exception(1, SIGTRAP, 0, regs);
+
+       return 0;
+}
+
+static struct undef_hook kgdb_brkpt_hook = {
+       .instr_mask             = 0xffffffff,
+       .instr_val              = KGDB_BREAKINST,
+       .fn                     = kgdb_brk_fn
+};
+
+static struct undef_hook kgdb_compiled_brkpt_hook = {
+       .instr_mask             = 0xffffffff,
+       .instr_val              = KGDB_COMPILED_BREAK,
+       .fn                     = kgdb_compiled_brk_fn
+};
+
+/**
+ *     kgdb_arch_init - Perform any architecture specific initalization.
+ *
+ *     This function will handle the initalization of any architecture
+ *     specific callbacks.
+ */
+int kgdb_arch_init(void)
+{
+       register_undef_hook(&kgdb_brkpt_hook);
+       register_undef_hook(&kgdb_compiled_brkpt_hook);
+
+       return 0;
+}
+
+/**
+ *     kgdb_arch_exit - Perform any architecture specific uninitalization.
+ *
+ *     This function will handle the uninitalization of any architecture
+ *     specific callbacks, for dynamic registration and unregistration.
+ */
+void kgdb_arch_exit(void)
+{
+       unregister_undef_hook(&kgdb_brkpt_hook);
+       unregister_undef_hook(&kgdb_compiled_brkpt_hook);
+}
+
+/*
+ * Register our undef instruction hooks with ARM undef core.
+ * We regsiter a hook specifically looking for the KGB break inst
+ * and we handle the normal undef case within the do_undefinstr
+ * handler.
+ */
+struct kgdb_arch arch_kgdb_ops = {
+#ifndef __ARMEB__
+       .gdb_bpt_instr          = {0xfe, 0xde, 0xff, 0xe7}
+#else /* ! __ARMEB__ */
+       .gdb_bpt_instr          = {0xe7, 0xff, 0xde, 0xfe}
+#endif
+};
index b7b0720bc1bbe8295ea3ca7b2849e4a5ad875bf2..38f0e7940a132b1c9e0458bc10e9d1dc3f2401ee 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
+#include <asm/traps.h>
 
 #include "compat.h"
 #include "atags.h"
@@ -853,6 +854,7 @@ void __init setup_arch(char **cmdline_p)
        conswitchp = &dummy_con;
 #endif
 #endif
+       early_trap_init();
 }
 
 
index cc5145b28e7f0997c3b9a9edd8b6c38ebf482c44..368d171754cf309acfabb1714f4b4dd915790086 100644 (file)
@@ -130,7 +130,9 @@ static const struct leds_evt_name evt_names[] = {
        { "red",   led_red_on,   led_red_off   },
 };
 
-static ssize_t leds_store(struct sys_device *dev, const char *buf, size_t size)
+static ssize_t leds_store(struct sys_device *dev,
+                       struct sysdev_attribute *attr,
+                       const char *buf, size_t size)
 {
        int ret = -EINVAL, len = strcspn(buf, " ");
 
index 5595fdd75e8200ec0e8d5ea8a54c750ed0398e1f..7277aef8309836fb74b6e2368beabf050757af9d 100644 (file)
@@ -707,6 +707,11 @@ void abort(void)
 EXPORT_SYMBOL(abort);
 
 void __init trap_init(void)
+{
+       return;
+}
+
+void __init early_trap_init(void)
 {
        unsigned long vectors = CONFIG_VECTORS_BASE;
        extern char __stubs_start[], __stubs_end[];
index 62e653a3ea1a9f7a651a41e43a19253af1c95241..5a1588cf8242a2cea12e98bef963eb2dc065ad53 100644 (file)
@@ -393,9 +393,7 @@ static int impd1_probe(struct lm_device *dev)
                if (!d)
                        continue;
 
-               snprintf(d->dev.bus_id, sizeof(d->dev.bus_id),
-                        "lm%x:%5.5lx", dev->id, idev->offset >> 12);
-
+               dev_set_name(&d->dev, "lm%x:%5.5lx", dev->id, idev->offset >> 12);
                d->dev.parent   = &dev->dev;
                d->res.start    = dev->resource.start + idev->offset;
                d->res.end      = d->res.start + SZ_4K - 1;
@@ -407,8 +405,7 @@ static int impd1_probe(struct lm_device *dev)
 
                ret = amba_device_register(d, &dev->resource);
                if (ret) {
-                       printk("unable to register device %s: %d\n",
-                               d->dev.bus_id, ret);
+                       dev_err(&d->dev, "unable to register device: %d\n");
                        kfree(d);
                }
        }
index 622cdc4212dd6f096ca7880f85d42334f0581da1..f939c50914054081407848ecd351f2c509839fe9 100644 (file)
@@ -81,8 +81,10 @@ int lm_device_register(struct lm_device *dev)
        dev->dev.release = lm_device_release;
        dev->dev.bus = &lm_bustype;
 
-       snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), "lm%d", dev->id);
-       dev->resource.name = dev->dev.bus_id;
+       ret = dev_set_name(&dev->dev, "lm%d", dev->id);
+       if (ret)
+               return ret;
+       dev->resource.name = dev_name(&dev->dev);
 
        ret = request_resource(&iomem_resource, &dev->resource);
        if (ret == 0) {
index 914bb33dab920e4deaff4f890916d8b3a140aee5..e8ee7ec9ff6dda45d0a0793c9887b37b2592769a 100644 (file)
@@ -16,18 +16,24 @@ config CPU_PXA310
 config CPU_PXA320
        bool "PXA320 (codename Monahans-P)"
 
+config CPU_PXA930
+       bool "PXA930 (codename Tavor-P)"
+
 endmenu
 
 endif
 
-menu "Select target boards"
-
 config ARCH_GUMSTIX
        bool "Gumstix XScale boards"
        help
          Say Y here if you intend to run this kernel on a
          Gumstix Full Function Minature Computer.
 
+config MACH_GUMSTIX_F
+       bool "Basix, Connex, ws-200ax, ws-400ax systems"
+       depends on ARCH_GUMSTIX
+       select PXA25x
+
 config ARCH_LUBBOCK
        bool "Intel DBPXA250 Development Platform"
        select PXA25x
@@ -58,6 +64,57 @@ config PXA_SHARPSL
          SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
          handheld computer.
 
+config MACH_POODLE
+       bool "Enable Sharp SL-5600 (Poodle) Support"
+       depends on PXA_SHARPSL
+       select PXA25x
+       select SHARP_LOCOMO
+       select PXA_SSP
+
+config MACH_CORGI
+       bool "Enable Sharp SL-C700 (Corgi) Support"
+       depends on PXA_SHARPSL
+       select PXA25x
+       select PXA_SHARP_C7xx
+
+config MACH_SHEPHERD
+       bool "Enable Sharp SL-C750 (Shepherd) Support"
+       depends on PXA_SHARPSL
+       select PXA25x
+       select PXA_SHARP_C7xx
+
+config MACH_HUSKY
+       bool "Enable Sharp SL-C760 (Husky) Support"
+       depends on PXA_SHARPSL
+       select PXA25x
+       select PXA_SHARP_C7xx
+
+config MACH_AKITA
+       bool "Enable Sharp SL-1000 (Akita) Support"
+       depends on PXA_SHARPSL
+       select PXA27x
+       select PXA_SHARP_Cxx00
+       select MACH_SPITZ
+       select I2C
+       select I2C_PXA
+
+config MACH_SPITZ
+       bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
+       depends on PXA_SHARPSL
+       select PXA27x
+       select PXA_SHARP_Cxx00
+
+config MACH_BORZOI
+       bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support"
+       depends on PXA_SHARPSL
+       select PXA27x
+       select PXA_SHARP_Cxx00
+
+config MACH_TOSA
+       bool "Enable Sharp SL-6000x (Tosa) Support"
+       depends on PXA_SHARPSL
+       select PXA25x
+
 config ARCH_PXA_ESERIES
        bool "PXA based Toshiba e-series PDAs"
        select PXA25x
@@ -70,10 +127,19 @@ config MACH_E330
          Say Y here if you intend to run this kernel on a Toshiba
          e330 family PDA.
 
+config MACH_E350
+       bool "Toshiba e350"
+       default y
+       depends on ARCH_PXA_ESERIES
+       help
+         Say Y here if you intend to run this kernel on a Toshiba
+         e350 family PDA.
+
 config MACH_E740
        bool "Toshiba e740"
        default y
        depends on ARCH_PXA_ESERIES
+       select FB_W100
        help
          Say Y here if you intend to run this kernel on a Toshiba
          e740 family PDA.
@@ -82,6 +148,7 @@ config MACH_E750
        bool "Toshiba e750"
        default y
        depends on ARCH_PXA_ESERIES
+       select FB_W100
        help
          Say Y here if you intend to run this kernel on a Toshiba
          e750 family PDA.
@@ -98,6 +165,7 @@ config MACH_E800
        bool "Toshiba e800"
        default y
        depends on ARCH_PXA_ESERIES
+       select FB_W100
        help
          Say Y here if you intend to run this kernel on a Toshiba
          e800 family PDA.
@@ -106,6 +174,10 @@ config MACH_TRIZEPS4
        bool "Keith und Koep Trizeps4 DIMM-Module"
        select PXA27x
 
+config MACH_TRIZEPS4_CONXS
+       bool "ConXS Eval Board"
+       depends on MACH_TRIZEPS4
+
 config MACH_EM_X270
        bool "CompuLab EM-x270 platform"
        select PXA27x
@@ -115,7 +187,7 @@ config MACH_COLIBRI
        select PXA27x
 
 config MACH_ZYLONITE
-       bool "PXA3xx Development Platform"
+       bool "PXA3xx Development Platform (aka Zylonite)"
        select PXA3xx
        select HAVE_PWM
 
@@ -124,6 +196,16 @@ config MACH_LITTLETON
        select PXA3xx
        select PXA_SSP
 
+config MACH_TAVOREVB
+       bool "PXA930 Evaluation Board (aka TavorEVB)"
+       select PXA3xx
+       select PXA930
+
+config MACH_SAAR
+       bool "PXA930 Handheld Platform (aka SAAR)"
+       select PXA3xx
+       select PXA930
+
 config MACH_ARMCORE
        bool "CompuLab CM-X270 modules"
        select PXA27x
@@ -131,7 +213,6 @@ config MACH_ARMCORE
 
 config MACH_MAGICIAN
        bool "Enable HTC Magician Support"
-       depends on ARCH_PXA
        select PXA27x
        select IWMMXT
 
@@ -139,18 +220,26 @@ config MACH_PCM027
        bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
        select PXA27x
        select IWMMXT
+       select PXA_SSP
 
-endmenu
+config ARCH_PXA_PALM
+       bool "PXA based Palm PDAs"
+       select HAVE_PWM
 
-choice
-       prompt "Used baseboard"
-       depends on MACH_PCM027
+config MACH_PALMTX
+       bool "Palm T|X"
+       default y
+       depends on ARCH_PXA_PALM
+       select PXA27x
+       select IWMMXT
+       help
+         Say Y here if you intend to run this kernel on a Palm T|X
+         handheld computer.
 
 config MACH_PCM990_BASEBOARD
        bool "PHYTEC PCM-990 development board"
        select HAVE_PWM
-
-endchoice
+       depends on MACH_PCM027
 
 choice
        prompt "display on pcm990"
@@ -167,88 +256,45 @@ config PCM990_DISPLAY_NONE
 
 endchoice
 
-if ARCH_GUMSTIX
-
-choice
-       prompt "Select target Gumstix board"
-
-config MACH_GUMSTIX_F
-       bool "Basix, Connex, ws-200ax, ws-400ax systems"
-       select PXA25x
-
-endchoice
-
-endif
 
+config PXA_EZX
+       bool "Motorola EZX Platform"
+       select PXA27x
+       select IWMMXT
+       select HAVE_PWM
 
-if MACH_TRIZEPS4
+config MACH_EZX_A780
+       bool "Motorola EZX A780"
+       default y
+       depends on PXA_EZX
 
-choice
-       prompt "Select base board for Trizeps 4 module"
+config MACH_EZX_E680
+       bool "Motorola EZX E680"
+       default y
+       depends on PXA_EZX
 
-config MACH_TRIZEPS4_CONXS
-       bool "ConXS Eval Board"
+config MACH_EZX_A1200
+       bool "Motorola EZX A1200"
+       default y
+       depends on PXA_EZX
 
-config MACH_TRIZEPS4_ANY
-       bool "another Board"
+config MACH_EZX_A910
+       bool "Motorola EZX A910"
+       default y
+       depends on PXA_EZX
 
-endchoice
+config MACH_EZX_E6
+       bool "Motorola EZX E6"
+       default y
+       depends on PXA_EZX
 
-endif
+config MACH_EZX_E2
+       bool "Motorola EZX E2"
+       default y
+       depends on PXA_EZX
 
 endmenu
 
-config MACH_POODLE
-       bool "Enable Sharp SL-5600 (Poodle) Support"
-       depends on PXA_SHARPSL
-       select PXA25x
-       select SHARP_LOCOMO
-       select PXA_SSP
-
-config MACH_CORGI
-       bool "Enable Sharp SL-C700 (Corgi) Support"
-       depends on PXA_SHARPSL
-       select PXA25x
-       select PXA_SHARP_C7xx
-
-config MACH_SHEPHERD
-       bool "Enable Sharp SL-C750 (Shepherd) Support"
-       depends on PXA_SHARPSL
-       select PXA25x
-       select PXA_SHARP_C7xx
-
-config MACH_HUSKY
-       bool "Enable Sharp SL-C760 (Husky) Support"
-       depends on PXA_SHARPSL
-       select PXA25x
-       select PXA_SHARP_C7xx
-
-config MACH_AKITA
-       bool "Enable Sharp SL-1000 (Akita) Support"
-       depends on PXA_SHARPSL
-       select PXA27x
-       select PXA_SHARP_Cxx00
-       select MACH_SPITZ
-       select I2C
-       select I2C_PXA
-
-config MACH_SPITZ
-       bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
-       depends on PXA_SHARPSL
-       select PXA27x
-       select PXA_SHARP_Cxx00
-
-config MACH_BORZOI
-       bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support"
-       depends on PXA_SHARPSL
-       select PXA27x
-       select PXA_SHARP_Cxx00
-
-config MACH_TOSA
-       bool "Enable Sharp SL-6000x (Tosa) Support"
-       depends on PXA_SHARPSL
-       select PXA25x
-
 config PXA25x
        bool
        help
@@ -288,4 +334,13 @@ config PXA_PWM
        default BACKLIGHT_PWM
        help
          Enable support for PXA2xx/PXA3xx PWM controllers
+
+config TOSA_BT
+       tristate "Control the state of built-in bluetooth chip on Sharp SL-6000"
+       depends on MACH_TOSA
+       select RFKILL
+       help
+         This is a simple driver that is able to control
+         the state of built in bluetooth chip on tosa.
+
 endif
index c4dfbe87fc4e4768f555b53a7f679836b0e70e5e..99ecbe7f85062a343db152dec067f7889c629a3b 100644 (file)
@@ -4,7 +4,7 @@
 
 # Common support (must be linked before board specific support)
 obj-y                          += clock.o devices.o generic.o irq.o dma.o \
-                                  time.o gpio.o
+                                  time.o gpio.o reset.o
 obj-$(CONFIG_PM)               += pm.o sleep.o standby.o
 obj-$(CONFIG_CPU_FREQ)         += cpu-pxa.o
 
@@ -18,6 +18,7 @@ obj-$(CONFIG_PXA27x)          += mfp-pxa2xx.o pxa2xx.o pxa27x.o
 obj-$(CONFIG_PXA3xx)           += mfp-pxa3xx.o pxa3xx.o smemc.o
 obj-$(CONFIG_CPU_PXA300)       += pxa300.o
 obj-$(CONFIG_CPU_PXA320)       += pxa320.o
+obj-$(CONFIG_CPU_PXA930)       += pxa930.o
 
 # Specific board support
 obj-$(CONFIG_ARCH_GUMSTIX)     += gumstix.o
@@ -36,7 +37,12 @@ obj-$(CONFIG_MACH_PCM990_BASEBOARD)  += pcm990-baseboard.o
 obj-$(CONFIG_MACH_TOSA)                += tosa.o
 obj-$(CONFIG_MACH_EM_X270)     += em-x270.o
 obj-$(CONFIG_MACH_MAGICIAN)    += magician.o
-obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o
+obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o eseries_udc.o
+obj-$(CONFIG_MACH_E740)                += e740_lcd.o
+obj-$(CONFIG_MACH_E750)                += e750_lcd.o
+obj-$(CONFIG_MACH_E400)                += e400_lcd.o
+obj-$(CONFIG_MACH_E800)                += e800_lcd.o
+obj-$(CONFIG_MACH_PALMTX)      += palmtx.o
 
 ifeq ($(CONFIG_MACH_ZYLONITE),y)
   obj-y                                += zylonite.o
@@ -44,8 +50,11 @@ ifeq ($(CONFIG_MACH_ZYLONITE),y)
   obj-$(CONFIG_CPU_PXA320)     += zylonite_pxa320.o
 endif
 obj-$(CONFIG_MACH_LITTLETON)   += littleton.o
+obj-$(CONFIG_MACH_TAVOREVB)    += tavorevb.o
+obj-$(CONFIG_MACH_SAAR)                += saar.o
 
 obj-$(CONFIG_MACH_ARMCORE)      += cm-x270.o
+obj-$(CONFIG_PXA_EZX)           += ezx.o
 
 # Support for blinky lights
 led-y := leds.o
@@ -59,3 +68,5 @@ obj-$(CONFIG_LEDS)            += $(led-y)
 ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
 endif
+
+obj-$(CONFIG_TOSA_BT)          += tosa-bt.o
index b4d04955dcb0a08774e0214aaac6a7c1453c2d52..630063ffa6fcec90b5f3fbbb66a2588440ac70be 100644 (file)
@@ -101,21 +101,6 @@ unsigned long clk_get_rate(struct clk *clk)
 EXPORT_SYMBOL(clk_get_rate);
 
 
-static void clk_gpio27_enable(struct clk *clk)
-{
-       pxa_gpio_mode(GPIO11_3_6MHz_MD);
-}
-
-static void clk_gpio27_disable(struct clk *clk)
-{
-}
-
-static const struct clkops clk_gpio27_ops = {
-       .enable         = clk_gpio27_enable,
-       .disable        = clk_gpio27_disable,
-};
-
-
 void clk_cken_enable(struct clk *clk)
 {
        CKEN |= 1 << clk->cken;
@@ -131,14 +116,6 @@ const struct clkops clk_cken_ops = {
        .disable        = clk_cken_disable,
 };
 
-static struct clk common_clks[] = {
-       {
-               .name           = "GPIO27_CLK",
-               .ops            = &clk_gpio27_ops,
-               .rate           = 3686400,
-       },
-};
-
 void clks_register(struct clk *clks, size_t num)
 {
        int i;
@@ -148,10 +125,3 @@ void clks_register(struct clk *clks, size_t num)
                list_add(&clks[i].node, &clocks);
        mutex_unlock(&clocks_mutex);
 }
-
-static int __init clk_init(void)
-{
-       clks_register(common_clks, ARRAY_SIZE(common_clks));
-       return 0;
-}
-arch_initcall(clk_init);
index 83cbfaba485de9a96badbc4107e228979f8e4497..1ec8f9178aaf48e41cde86c1c534d76f51283422 100644 (file)
@@ -47,9 +47,42 @@ struct clk {
                .other  = _other,                       \
        }
 
+#define INIT_CLK(_name, _ops, _rate, _delay, _dev)      \
+       {                                               \
+               .name   = _name,                        \
+               .dev    = _dev,                         \
+               .ops    = _ops,                         \
+               .rate   = _rate,                        \
+               .delay  = _delay,                       \
+       }
+
 extern const struct clkops clk_cken_ops;
 
 void clk_cken_enable(struct clk *clk);
 void clk_cken_disable(struct clk *clk);
 
+#ifdef CONFIG_PXA3xx
+#define PXA3xx_CKEN(_name, _cken, _rate, _delay, _dev) \
+       {                                               \
+               .name   = _name,                        \
+               .dev    = _dev,                         \
+               .ops    = &clk_pxa3xx_cken_ops,         \
+               .rate   = _rate,                        \
+               .cken   = CKEN_##_cken,                 \
+               .delay  = _delay,                       \
+       }
+
+#define PXA3xx_CK(_name, _cken, _ops, _dev)            \
+       {                                               \
+               .name   = _name,                        \
+               .dev    = _dev,                         \
+               .ops    = _ops,                         \
+               .cken   = CKEN_##_cken,                 \
+       }
+
+extern const struct clkops clk_pxa3xx_cken_ops;
+extern void clk_pxa3xx_cken_enable(struct clk *);
+extern void clk_pxa3xx_cken_disable(struct clk *);
+#endif
+
 void clks_register(struct clk *clks, size_t num);
index 319c9ff3ab9a29ca49179fe4f180a9db8c50725b..bcf0cde6ccc965ce2a3ba925ff868596f0d8c185 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Bits taken from various places.
  *
- * Copyright (C) 2007 Compulab, Ltd.
+ * Copyright (C) 2007, 2008 Compulab, Ltd.
  * Mike Rapoport <mike@compulab.co.il>
  *
  * This program is free software; you can redistribute it and/or modify
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
+#include <linux/gpio.h>
 
 #include <asm/mach/pci.h>
-#include <asm/arch/cm-x270.h>
 #include <asm/arch/pxa-regs.h>
-#include <asm/arch/pxa2xx-gpio.h>
 #include <asm/mach-types.h>
 
 #include <asm/hardware/it8152.h>
 
-unsigned long it8152_base_address = CMX270_IT8152_VIRT;
+unsigned long it8152_base_address;
+static int cmx270_it8152_irq_gpio;
 
 /*
  * Only first 64MB of memory can be accessed via PCI.
@@ -42,7 +42,7 @@ void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size,
        unsigned int sz = SZ_64M >> PAGE_SHIFT;
 
        if (machine_is_armcore()) {
-               pr_info("Adjusting zones for CM-x270\n");
+               pr_info("Adjusting zones for CM-X270\n");
 
                /*
                 * Only adjust if > 64M on current system
@@ -60,19 +60,20 @@ void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size,
 static void cmx270_it8152_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
        /* clear our parent irq */
-       GEDR(GPIO_IT8152_IRQ) = GPIO_bit(GPIO_IT8152_IRQ);
+       GEDR(cmx270_it8152_irq_gpio) = GPIO_bit(cmx270_it8152_irq_gpio);
 
        it8152_irq_demux(irq, desc);
 }
 
-void __cmx270_pci_init_irq(void)
+void __cmx270_pci_init_irq(int irq_gpio)
 {
        it8152_init_irq();
-       pxa_gpio_mode(IRQ_TO_GPIO(GPIO_IT8152_IRQ));
-       set_irq_type(IRQ_GPIO(GPIO_IT8152_IRQ), IRQT_RISING);
 
-       set_irq_chained_handler(IRQ_GPIO(GPIO_IT8152_IRQ),
-                               cmx270_it8152_irq_demux);
+       cmx270_it8152_irq_gpio = irq_gpio;
+
+       set_irq_type(gpio_to_irq(irq_gpio), IRQT_RISING);
+
+       set_irq_chained_handler(gpio_to_irq(irq_gpio), cmx270_it8152_irq_demux);
 }
 
 #ifdef CONFIG_PM
@@ -115,8 +116,8 @@ static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 
        /*
          Here comes the ugly part. The routing is baseboard specific,
-         but defining a platform for each possible base of CM-x270 is
-         unrealistic. Here we keep mapping for ATXBase and SB-x270.
+         but defining a platform for each possible base of CM-X270 is
+         unrealistic. Here we keep mapping for ATXBase and SB-X270.
        */
        /* ATXBASE PCI slot */
        if (slot == 7)
index ffe37b66f9a001c9290fc09e169263fb65caa4de..48f532f4cb51c4a5568994c6c86979abafc54a36 100644 (file)
@@ -1,13 +1,13 @@
-extern void __cmx270_pci_init_irq(void);
+extern void __cmx270_pci_init_irq(int irq_gpio);
 extern void __cmx270_pci_suspend(void);
 extern void __cmx270_pci_resume(void);
 
 #ifdef CONFIG_PCI
-#define cmx270_pci_init_irq __cmx270_pci_init_irq
-#define cmx270_pci_suspend __cmx270_pci_suspend
-#define cmx270_pci_resume __cmx270_pci_resume
+#define cmx270_pci_init_irq(x) __cmx270_pci_init_irq(x)
+#define cmx270_pci_suspend(x) __cmx270_pci_suspend(x)
+#define cmx270_pci_resume(x) __cmx270_pci_resume(x)
 #else
-#define cmx270_pci_init_irq() do {} while (0)
-#define cmx270_pci_suspend() do {} while (0)
-#define cmx270_pci_resume() do {} while (0)
+#define cmx270_pci_init_irq(x) do {} while (0)
+#define cmx270_pci_suspend(x) do {} while (0)
+#define cmx270_pci_resume(x) do {} while (0)
 #endif
index 01b9964acec1f39bd448114c4ee65aadbde05167..402e807eae54cef3fea7cd99d5422e87b9c0cc62 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/mach-pxa/cm-x270.c
  *
- * Copyright (C) 2007 CompuLab, Ltd.
+ * Copyright (C) 2007, 2008 CompuLab, Ltd.
  * Mike Rapoport <mike@compulab.co.il>
  *
  * This program is free software; you can redistribute it and/or modify
  * published by the Free Software Foundation.
  */
 
-#include <linux/types.h>
-#include <linux/pm.h>
-#include <linux/fb.h>
 #include <linux/platform_device.h>
-#include <linux/irq.h>
 #include <linux/sysdev.h>
-#include <linux/io.h>
-#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
 
 #include <linux/dm9000.h>
 #include <linux/rtc-v3020.h>
-#include <linux/serial_8250.h>
-
 #include <video/mbxfb.h>
+#include <linux/leds.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 
-#include <asm/arch/pxa-regs.h>
 #include <asm/arch/pxa2xx-regs.h>
-#include <asm/arch/pxa2xx-gpio.h>
+#include <asm/arch/mfp-pxa27x.h>
+#include <asm/arch/pxa-regs.h>
 #include <asm/arch/audio.h>
 #include <asm/arch/pxafb.h>
 #include <asm/arch/ohci.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/bitfield.h>
-#include <asm/arch/cm-x270.h>
 
 #include <asm/hardware/it8152.h>
 
 #include "generic.h"
 #include "cm-x270-pci.h"
 
+/* virtual addresses for statically mapped regions */
+#define CMX270_VIRT_BASE       (0xe8000000)
+#define CMX270_IT8152_VIRT     (CMX270_VIRT_BASE)
+
 #define RTC_PHYS_BASE          (PXA_CS1_PHYS + (5 << 22))
 #define DM9000_PHYS_BASE       (PXA_CS1_PHYS + (6 << 22))
 
-static struct resource cmx270_dm9k_resource[] = {
+/* GPIO IRQ usage */
+#define GPIO10_ETHIRQ          (10)
+#define GPIO22_IT8152_IRQ      (22)
+#define GPIO83_MMC_IRQ         (83)
+#define GPIO95_GFXIRQ          (95)
+
+#define CMX270_ETHIRQ          IRQ_GPIO(GPIO10_ETHIRQ)
+#define CMX270_IT8152_IRQ      IRQ_GPIO(GPIO22_IT8152_IRQ)
+#define CMX270_MMC_IRQ         IRQ_GPIO(GPIO83_MMC_IRQ)
+#define CMX270_GFXIRQ          IRQ_GPIO(GPIO95_GFXIRQ)
+
+/* MMC power enable */
+#define GPIO105_MMC_POWER      (105)
+
+static unsigned long cmx270_pin_config[] = {
+       /* AC'97 */
+       GPIO28_AC97_BITCLK,
+       GPIO29_AC97_SDATA_IN_0,
+       GPIO30_AC97_SDATA_OUT,
+       GPIO31_AC97_SYNC,
+       GPIO98_AC97_SYSCLK,
+       GPIO113_AC97_nRESET,
+
+       /* BTUART */
+       GPIO42_BTUART_RXD,
+       GPIO43_BTUART_TXD,
+       GPIO44_BTUART_CTS,
+       GPIO45_BTUART_RTS,
+
+       /* STUART */
+       GPIO46_STUART_RXD,
+       GPIO47_STUART_TXD,
+
+       /* MCI controller */
+       GPIO32_MMC_CLK,
+       GPIO112_MMC_CMD,
+       GPIO92_MMC_DAT_0,
+       GPIO109_MMC_DAT_1,
+       GPIO110_MMC_DAT_2,
+       GPIO111_MMC_DAT_3,
+
+       /* LCD */
+       GPIO58_LCD_LDD_0,
+       GPIO59_LCD_LDD_1,
+       GPIO60_LCD_LDD_2,
+       GPIO61_LCD_LDD_3,
+       GPIO62_LCD_LDD_4,
+       GPIO63_LCD_LDD_5,
+       GPIO64_LCD_LDD_6,
+       GPIO65_LCD_LDD_7,
+       GPIO66_LCD_LDD_8,
+       GPIO67_LCD_LDD_9,
+       GPIO68_LCD_LDD_10,
+       GPIO69_LCD_LDD_11,
+       GPIO70_LCD_LDD_12,
+       GPIO71_LCD_LDD_13,
+       GPIO72_LCD_LDD_14,
+       GPIO73_LCD_LDD_15,
+       GPIO74_LCD_FCLK,
+       GPIO75_LCD_LCLK,
+       GPIO76_LCD_PCLK,
+       GPIO77_LCD_BIAS,
+
+       /* I2C */
+       GPIO117_I2C_SCL,
+       GPIO118_I2C_SDA,
+
+       /* SSP1 */
+       GPIO23_SSP1_SCLK,
+       GPIO24_SSP1_SFRM,
+       GPIO25_SSP1_TXD,
+       GPIO26_SSP1_RXD,
+
+       /* SSP2 */
+       GPIO19_SSP2_SCLK,
+       GPIO14_SSP2_SFRM,
+       GPIO87_SSP2_TXD,
+       GPIO88_SSP2_RXD,
+
+       /* PC Card */
+       GPIO48_nPOE,
+       GPIO49_nPWE,
+       GPIO50_nPIOR,
+       GPIO51_nPIOW,
+       GPIO85_nPCE_1,
+       GPIO54_nPCE_2,
+       GPIO55_nPREG,
+       GPIO56_nPWAIT,
+       GPIO57_nIOIS16,
+
+       /* SDRAM and local bus */
+       GPIO15_nCS_1,
+       GPIO78_nCS_2,
+       GPIO79_nCS_3,
+       GPIO80_nCS_4,
+       GPIO33_nCS_5,
+       GPIO49_nPWE,
+       GPIO18_RDY,
+
+       /* GPIO */
+       GPIO0_GPIO      | WAKEUP_ON_EDGE_BOTH,
+       GPIO105_GPIO    | MFP_LPM_DRIVE_HIGH,   /* MMC/SD power */
+       GPIO53_GPIO,                            /* PC card reset */
+
+       /* NAND controls */
+       GPIO11_GPIO     | MFP_LPM_DRIVE_HIGH,   /* NAND CE# */
+       GPIO89_GPIO,                            /* NAND Ready/Busy */
+
+       /* interrupts */
+       GPIO10_GPIO,    /* DM9000 interrupt */
+       GPIO83_GPIO,    /* MMC card detect */
+};
+
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource cmx270_dm9000_resource[] = {
        [0] = {
                .start = DM9000_PHYS_BASE,
                .end   = DM9000_PHYS_BASE + 4,
@@ -64,31 +176,45 @@ static struct resource cmx270_dm9k_resource[] = {
        }
 };
 
-/* for the moment we limit ourselves to 32bit IO until some
- * better IO routines can be written and tested
- */
-static struct dm9000_plat_data cmx270_dm9k_platdata = {
+static struct dm9000_plat_data cmx270_dm9000_platdata = {
        .flags          = DM9000_PLATF_32BITONLY,
 };
 
-/* Ethernet device */
-static struct platform_device cmx270_device_dm9k = {
+static struct platform_device cmx270_dm9000_device = {
        .name           = "dm9000",
        .id             = 0,
-       .num_resources  = ARRAY_SIZE(cmx270_dm9k_resource),
-       .resource       = cmx270_dm9k_resource,
+       .num_resources  = ARRAY_SIZE(cmx270_dm9000_resource),
+       .resource       = cmx270_dm9000_resource,
        .dev            = {
-               .platform_data = &cmx270_dm9k_platdata,
+               .platform_data = &cmx270_dm9000_platdata,
        }
 };
 
-/* touchscreen controller */
+static void __init cmx270_init_dm9000(void)
+{
+       platform_device_register(&cmx270_dm9000_device);
+}
+#else
+static inline void cmx270_init_dm9000(void) {}
+#endif
+
+/* UCB1400 touchscreen controller */
+#if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
 static struct platform_device cmx270_ts_device = {
        .name           = "ucb1400_ts",
        .id             = -1,
 };
 
-/* RTC */
+static void __init cmx270_init_touchscreen(void)
+{
+       platform_device_register(&cmx270_ts_device);
+}
+#else
+static inline void cmx270_init_touchscreen(void) {}
+#endif
+
+/* V3020 RTC */
+#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
 static struct resource cmx270_v3020_resource[] = {
        [0] = {
                .start = RTC_PHYS_BASE,
@@ -111,28 +237,67 @@ static struct platform_device cmx270_rtc_device = {
        }
 };
 
-/*
- * CM-X270 LEDs
- */
+static void __init cmx270_init_rtc(void)
+{
+       platform_device_register(&cmx270_rtc_device);
+}
+#else
+static inline void cmx270_init_rtc(void) {}
+#endif
+
+/* CM-X270 LEDs */
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static struct gpio_led cmx270_leds[] = {
+       [0] = {
+               .name = "cm-x270:red",
+               .default_trigger = "nand-disk",
+               .gpio = 93,
+               .active_low = 1,
+       },
+       [1] = {
+               .name = "cm-x270:green",
+               .default_trigger = "heartbeat",
+               .gpio = 94,
+               .active_low = 1,
+       },
+};
+
+static struct gpio_led_platform_data cmx270_gpio_led_pdata = {
+       .num_leds = ARRAY_SIZE(cmx270_leds),
+       .leds = cmx270_leds,
+};
+
 static struct platform_device cmx270_led_device = {
-       .name           = "cm-x270-led",
+       .name           = "leds-gpio",
        .id             = -1,
+       .dev            = {
+               .platform_data = &cmx270_gpio_led_pdata,
+       },
 };
 
+static void __init cmx270_init_leds(void)
+{
+       platform_device_register(&cmx270_led_device);
+}
+#else
+static inline void cmx270_init_leds(void) {}
+#endif
+
 /* 2700G graphics */
+#if defined(CONFIG_FB_MBX) || defined(CONFIG_FB_MBX_MODULE)
 static u64 fb_dma_mask = ~(u64)0;
 
 static struct resource cmx270_2700G_resource[] = {
        /* frame buffer memory including ODFB and External SDRAM */
        [0] = {
-               .start = MARATHON_PHYS,
-               .end   = MARATHON_PHYS + 0x02000000,
+               .start = PXA_CS2_PHYS,
+               .end   = PXA_CS2_PHYS + 0x01ffffff,
                .flags = IORESOURCE_MEM,
        },
        /* Marathon registers */
        [1] = {
-               .start = MARATHON_PHYS + 0x03fe0000,
-               .end   = MARATHON_PHYS + 0x03ffffff,
+               .start = PXA_CS2_PHYS + 0x03fe0000,
+               .end   = PXA_CS2_PHYS + 0x03ffffff,
                .flags = IORESOURCE_MEM,
        },
 };
@@ -200,43 +365,15 @@ static struct platform_device cmx270_2700G = {
        .id             = -1,
 };
 
-static u64 ata_dma_mask = ~(u64)0;
-
-static struct platform_device cmx270_ata = {
-       .name = "pata_cm_x270",
-       .id = -1,
-       .dev            = {
-               .dma_mask       = &ata_dma_mask,
-               .coherent_dma_mask = 0xffffffff,
-       },
-};
-
-/* platform devices */
-static struct platform_device *platform_devices[] __initdata = {
-       &cmx270_device_dm9k,
-       &cmx270_rtc_device,
-       &cmx270_2700G,
-       &cmx270_led_device,
-       &cmx270_ts_device,
-       &cmx270_ata,
-};
-
-/* Map PCI companion and IDE/General Purpose CS statically */
-static struct map_desc cmx270_io_desc[] __initdata = {
-       [0] = { /* IDE/general purpose space */
-               .virtual        = CMX270_IDE104_VIRT,
-               .pfn            = __phys_to_pfn(CMX270_IDE104_PHYS),
-               .length         = SZ_64M - SZ_8M,
-               .type           = MT_DEVICE
-       },
-       [1] = { /* PCI bridge */
-               .virtual        = CMX270_IT8152_VIRT,
-               .pfn            = __phys_to_pfn(CMX270_IT8152_PHYS),
-               .length         = SZ_64M,
-               .type           = MT_DEVICE
-       },
-};
+static void __init cmx270_init_2700G(void)
+{
+       platform_device_register(&cmx270_2700G);
+}
+#else
+static inline void cmx270_init_2700G(void) {}
+#endif
 
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
 /*
   Display definitions
   keep these for backwards compatibility, although symbolic names (as
@@ -446,7 +583,16 @@ static int __init cmx270_set_display(char *str)
 */
 __setup("monitor=", cmx270_set_display);
 
+static void __init cmx270_init_display(void)
+{
+       set_pxa_fb_info(cmx270_display);
+}
+#else
+static inline void cmx270_init_display(void) {}
+#endif
+
 /* PXA27x OHCI controller setup */
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 static int cmx270_ohci_init(struct device *dev)
 {
        /* Set the Power Control Polarity Low */
@@ -461,35 +607,37 @@ static struct pxaohci_platform_data cmx270_ohci_platform_data = {
        .init           = cmx270_ohci_init,
 };
 
+static void __init cmx270_init_ohci(void)
+{
+       pxa_set_ohci_info(&cmx270_ohci_platform_data);
+}
+#else
+static inline void cmx270_init_ohci(void) {}
+#endif
 
+#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
 static int cmx270_mci_init(struct device *dev,
                           irq_handler_t cmx270_detect_int,
                           void *data)
 {
        int err;
 
-       /*
-        * setup GPIO for PXA27x MMC controller
-        */
-       pxa_gpio_mode(GPIO32_MMCCLK_MD);
-       pxa_gpio_mode(GPIO112_MMCCMD_MD);
-       pxa_gpio_mode(GPIO92_MMCDAT0_MD);
-       pxa_gpio_mode(GPIO109_MMCDAT1_MD);
-       pxa_gpio_mode(GPIO110_MMCDAT2_MD);
-       pxa_gpio_mode(GPIO111_MMCDAT3_MD);
-
-       /* SB-X270 uses GPIO105 as SD power enable */
-       pxa_gpio_mode(105 | GPIO_OUT);
+       err = gpio_request(GPIO105_MMC_POWER, "MMC/SD power");
+       if (err) {
+               dev_warn(dev, "power gpio unavailable\n");
+               return err;
+       }
 
-       /* card detect IRQ on GPIO 83 */
-       pxa_gpio_mode(IRQ_TO_GPIO(CMX270_MMC_IRQ));
+       gpio_direction_output(GPIO105_MMC_POWER, 0);
 
        err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int,
                          IRQF_DISABLED | IRQF_TRIGGER_FALLING,
                          "MMC card detect", data);
-       if (err)
-               printk(KERN_ERR "cmx270_mci_init: MMC/SD: can't"
-                      " request MMC card detect IRQ\n");
+       if (err) {
+               gpio_free(GPIO105_MMC_POWER);
+               dev_err(dev, "cmx270_mci_init: MMC/SD: can't"
+                       " request MMC card detect IRQ\n");
+       }
 
        return err;
 }
@@ -499,17 +647,18 @@ static void cmx270_mci_setpower(struct device *dev, unsigned int vdd)
        struct pxamci_platform_data *p_d = dev->platform_data;
 
        if ((1 << vdd) & p_d->ocr_mask) {
-               printk(KERN_DEBUG "%s: on\n", __func__);
-               GPCR(105) = GPIO_bit(105);
+               dev_dbg(dev, "power on\n");
+               gpio_set_value(GPIO105_MMC_POWER, 0);
        } else {
-               GPSR(105) = GPIO_bit(105);
-               printk(KERN_DEBUG "%s: off\n", __func__);
+               gpio_set_value(GPIO105_MMC_POWER, 1);
+               dev_dbg(dev, "power off\n");
        }
 }
 
 static void cmx270_mci_exit(struct device *dev, void *data)
 {
        free_irq(CMX270_MMC_IRQ, data);
+       gpio_free(GPIO105_MMC_POWER);
 }
 
 static struct pxamci_platform_data cmx270_mci_platform_data = {
@@ -519,6 +668,14 @@ static struct pxamci_platform_data cmx270_mci_platform_data = {
        .exit           = cmx270_mci_exit,
 };
 
+static void __init cmx270_init_mmc(void)
+{
+       pxa_set_mci_info(&cmx270_mci_platform_data);
+}
+#else
+static inline void cmx270_init_mmc(void) {}
+#endif
+
 #ifdef CONFIG_PM
 static unsigned long sleep_save_msc[10];
 
@@ -580,53 +737,63 @@ static int __init cmx270_pm_init(void)
 static int __init cmx270_pm_init(void) { return 0; }
 #endif
 
-static void __init cmx270_init(void)
+#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE)
+static void __init cmx270_init_ac97(void)
 {
-       cmx270_pm_init();
-
-       set_pxa_fb_info(cmx270_display);
-
-       /* register CM-X270 platform devices */
-       platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
        pxa_set_ac97_info(NULL);
+}
+#else
+static inline void cmx270_init_ac97(void) {}
+#endif
 
-       /* set MCI and OHCI platform parameters */
-       pxa_set_mci_info(&cmx270_mci_platform_data);
-       pxa_set_ohci_info(&cmx270_ohci_platform_data);
-
-       /* This enables the STUART */
-       pxa_gpio_mode(GPIO46_STRXD_MD);
-       pxa_gpio_mode(GPIO47_STTXD_MD);
+static void __init cmx270_init(void)
+{
+       cmx270_pm_init();
 
-       /* This enables the BTUART  */
-       pxa_gpio_mode(GPIO42_BTRXD_MD);
-       pxa_gpio_mode(GPIO43_BTTXD_MD);
-       pxa_gpio_mode(GPIO44_BTCTS_MD);
-       pxa_gpio_mode(GPIO45_BTRTS_MD);
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_pin_config));
+
+       cmx270_init_dm9000();
+       cmx270_init_rtc();
+       cmx270_init_display();
+       cmx270_init_mmc();
+       cmx270_init_ohci();
+       cmx270_init_ac97();
+       cmx270_init_touchscreen();
+       cmx270_init_leds();
+       cmx270_init_2700G();
 }
 
 static void __init cmx270_init_irq(void)
 {
        pxa27x_init_irq();
 
+       cmx270_pci_init_irq(GPIO22_IT8152_IRQ);
+}
 
-       cmx270_pci_init_irq();
+#ifdef CONFIG_PCI
+/* Map PCI companion statically */
+static struct map_desc cmx270_io_desc[] __initdata = {
+       [0] = { /* PCI bridge */
+               .virtual        = CMX270_IT8152_VIRT,
+               .pfn            = __phys_to_pfn(PXA_CS4_PHYS),
+               .length         = SZ_64M,
+               .type           = MT_DEVICE
+       },
+};
 
-       /* Setup interrupt for dm9000 */
-       pxa_gpio_mode(IRQ_TO_GPIO(CMX270_ETHIRQ));
-       set_irq_type(CMX270_ETHIRQ, IRQT_RISING);
+static void __init cmx270_map_io(void)
+{
+       pxa_map_io();
+       iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc));
 
-       /* Setup interrupt for 2700G */
-       pxa_gpio_mode(IRQ_TO_GPIO(CMX270_GFXIRQ));
-       set_irq_type(CMX270_GFXIRQ, IRQT_FALLING);
+       it8152_base_address = CMX270_IT8152_VIRT;
 }
-
+#else
 static void __init cmx270_map_io(void)
 {
        pxa_map_io();
-       iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc));
 }
-
+#endif
 
 MACHINE_START(ARMCORE, "Compulab CM-x270")
        .boot_params    = 0xa0000100,
index b37671b718868249e316ed503fa33b1d5fc687fe..e58504edb1404653b0bea3f5ac8ca956f6bd6db0 100644 (file)
@@ -465,6 +465,7 @@ static void corgi_irda_transceiver_mode(struct device *dev, int mode)
                GPSR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
        else
                GPCR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
+       pxa2xx_transceiver_mode(dev, mode);
 }
 
 static struct pxaficp_platform_data corgi_ficp_platform_data = {
index a6f2390ce662de674a520aca8bed2d5623148c0b..84489dc51d810126c08c444f91d4d10fb0823574 100644 (file)
 #include <asm/arch/mfp-pxa27x.h>
 #include <asm/arch/ohci.h>
 #include <asm/arch/pxa27x_keypad.h>
+#include <asm/arch/pxa2xx_spi.h>
 #include <asm/arch/camera.h>
 #include <asm/arch/audio.h>
+#include <asm/arch/pxa3xx_nand.h>
 
 #include "devices.h"
 #include "generic.h"
@@ -830,4 +832,63 @@ void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info)
        pxa_register_device(&pxa3xx_device_mci3, info);
 }
 
+static struct resource pxa3xx_resources_nand[] = {
+       [0] = {
+               .start  = 0x43100000,
+               .end    = 0x43100053,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_NAND,
+               .end    = IRQ_NAND,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               /* DRCMR for Data DMA */
+               .start  = 97,
+               .end    = 97,
+               .flags  = IORESOURCE_DMA,
+       },
+       [3] = {
+               /* DRCMR for Command DMA */
+               .start  = 99,
+               .end    = 99,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static u64 pxa3xx_nand_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device pxa3xx_device_nand = {
+       .name           = "pxa3xx-nand",
+       .id             = -1,
+       .dev            = {
+               .dma_mask = &pxa3xx_nand_dma_mask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+       },
+       .num_resources  = ARRAY_SIZE(pxa3xx_resources_nand),
+       .resource       = pxa3xx_resources_nand,
+};
+
+void __init pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info)
+{
+       pxa_register_device(&pxa3xx_device_nand, info);
+}
 #endif /* CONFIG_PXA3xx */
+
+/* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1.
+ * See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */
+void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info)
+{
+       struct platform_device *pd;
+
+       pd = platform_device_alloc("pxa2xx-spi", id);
+       if (pd == NULL) {
+               printk(KERN_ERR "pxa2xx-spi: failed to allocate device id %d\n",
+                      id);
+               return;
+       }
+
+       pd->dev.platform_data = info;
+       platform_device_add(pd);
+}
index b852eb18daa5f78526a2e40d835b4d166bc93594..887c738f5911dd6d333959b489aa3dad5af35731 100644 (file)
@@ -31,4 +31,6 @@ extern struct platform_device pxa25x_device_pwm1;
 extern struct platform_device pxa27x_device_pwm0;
 extern struct platform_device pxa27x_device_pwm1;
 
+extern struct platform_device pxa3xx_device_nand;
+
 void __init pxa_register_device(struct platform_device *dev, void *data);
diff --git a/arch/arm/mach-pxa/e400_lcd.c b/arch/arm/mach-pxa/e400_lcd.c
new file mode 100644 (file)
index 0000000..16c0236
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * e400_lcd.c
+ *
+ * (c) 2005 Ian Molton <spyro@f2s.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/mach-types.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxafb.h>
+
+static struct pxafb_mode_info e400_pxafb_mode_info = {
+       .pixclock       = 140703,
+       .xres           = 240,
+       .yres           = 320,
+       .bpp            = 16,
+       .hsync_len      = 4,
+       .left_margin    = 28,
+       .right_margin   = 8,
+       .vsync_len      = 3,
+       .upper_margin   = 5,
+       .lower_margin   = 6,
+       .sync           = 0,
+};
+
+static struct pxafb_mach_info e400_pxafb_mach_info = {
+       .modes          = &e400_pxafb_mode_info,
+       .num_modes      = 1,
+       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+       .lccr3          = 0,
+       .pxafb_backlight_power  = NULL,
+};
+
+static int __init e400_lcd_init(void)
+{
+       if (!machine_is_e400())
+               return -ENODEV;
+
+       set_pxa_fb_info(&e400_pxafb_mach_info);
+       return 0;
+}
+
+module_init(e400_lcd_init);
+
+MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
+MODULE_DESCRIPTION("e400 lcd driver");
+MODULE_LICENSE("GPLv2");
+
diff --git a/arch/arm/mach-pxa/e740_lcd.c b/arch/arm/mach-pxa/e740_lcd.c
new file mode 100644 (file)
index 0000000..26bd599
--- /dev/null
@@ -0,0 +1,123 @@
+/* e740_lcd.c
+ *
+ * This file contains the definitions for the LCD timings and functions
+ * to control the LCD power / frontlighting via the w100fb driver.
+ *
+ * (c) 2005 Ian Molton <spyro@f2s.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+
+#include <video/w100fb.h>
+
+/*
+**potential** shutdown routine - to be investigated
+devmem2 0x0c010528 w 0xff3fff00
+devmem2 0x0c010190 w 0x7FFF8000
+devmem2 0x0c0101b0 w 0x00FF0000
+devmem2 0x0c01008c w 0x00000000
+devmem2 0x0c010080 w 0x000000bf
+devmem2 0x0c010098 w 0x00000015
+devmem2 0x0c010088 w 0x4b000204
+devmem2 0x0c010098 w 0x0000001d
+*/
+
+static struct w100_gen_regs e740_lcd_regs = {
+       .lcd_format =            0x00008023,
+       .lcdd_cntl1 =            0x0f000000,
+       .lcdd_cntl2 =            0x0003ffff,
+       .genlcd_cntl1 =          0x00ffff03,
+       .genlcd_cntl2 =          0x003c0f03,
+       .genlcd_cntl3 =          0x000143aa,
+};
+
+static struct w100_mode e740_lcd_mode = {
+       .xres            = 240,
+       .yres            = 320,
+       .left_margin     = 20,
+       .right_margin    = 28,
+       .upper_margin    = 9,
+       .lower_margin    = 8,
+       .crtc_ss         = 0x80140013,
+       .crtc_ls         = 0x81150110,
+       .crtc_gs         = 0x80050005,
+       .crtc_vpos_gs    = 0x000a0009,
+       .crtc_rev        = 0x0040010a,
+       .crtc_dclk       = 0xa906000a,
+       .crtc_gclk       = 0x80050108,
+       .crtc_goe        = 0x80050108,
+       .pll_freq        = 57,
+       .pixclk_divider         = 4,
+       .pixclk_divider_rotated = 4,
+       .pixclk_src     = CLK_SRC_XTAL,
+       .sysclk_divider  = 1,
+       .sysclk_src     = CLK_SRC_PLL,
+       .crtc_ps1_active =       0x41060010,
+};
+
+
+static struct w100_gpio_regs e740_w100_gpio_info = {
+       .init_data1 = 0x21002103,
+       .gpio_dir1  = 0xffffdeff,
+       .gpio_oe1   = 0x03c00643,
+       .init_data2 = 0x003f003f,
+       .gpio_dir2  = 0xffffffff,
+       .gpio_oe2   = 0x000000ff,
+};
+
+static struct w100fb_mach_info e740_fb_info = {
+       .modelist   = &e740_lcd_mode,
+       .num_modes  = 1,
+       .regs       = &e740_lcd_regs,
+       .gpio       = &e740_w100_gpio_info,
+       .xtal_freq = 14318000,
+       .xtal_dbl   = 1,
+};
+
+static struct resource e740_fb_resources[] = {
+       [0] = {
+               .start          = 0x0c000000,
+               .end            = 0x0cffffff,
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+/* ----------------------- device declarations -------------------------- */
+
+
+static struct platform_device e740_fb_device = {
+       .name           = "w100fb",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &e740_fb_info,
+       },
+       .num_resources  = ARRAY_SIZE(e740_fb_resources),
+       .resource       = e740_fb_resources,
+};
+
+static int e740_lcd_init(void)
+{
+       int ret;
+
+       if (!machine_is_e740())
+               return -ENODEV;
+
+       return platform_device_register(&e740_fb_device);
+}
+
+module_init(e740_lcd_init);
+
+MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
+MODULE_DESCRIPTION("e740 lcd driver");
+MODULE_LICENSE("GPLv2");
diff --git a/arch/arm/mach-pxa/e750_lcd.c b/arch/arm/mach-pxa/e750_lcd.c
new file mode 100644 (file)
index 0000000..75edc3b
--- /dev/null
@@ -0,0 +1,109 @@
+/* e750_lcd.c
+ *
+ * This file contains the definitions for the LCD timings and functions
+ * to control the LCD power / frontlighting via the w100fb driver.
+ *
+ * (c) 2005 Ian Molton <spyro@f2s.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+
+#include <video/w100fb.h>
+
+static struct w100_gen_regs e750_lcd_regs = {
+       .lcd_format =            0x00008003,
+       .lcdd_cntl1 =            0x00000000,
+       .lcdd_cntl2 =            0x0003ffff,
+       .genlcd_cntl1 =          0x00fff003,
+       .genlcd_cntl2 =          0x003c0f03,
+       .genlcd_cntl3 =          0x000143aa,
+};
+
+static struct w100_mode e750_lcd_mode = {
+       .xres            = 240,
+       .yres            = 320,
+       .left_margin     = 21,
+       .right_margin    = 22,
+       .upper_margin    = 5,
+       .lower_margin    = 4,
+       .crtc_ss         = 0x80150014,
+       .crtc_ls         = 0x8014000d,
+       .crtc_gs         = 0xc1000005,
+       .crtc_vpos_gs    = 0x00020147,
+       .crtc_rev        = 0x0040010a,
+       .crtc_dclk       = 0xa1700030,
+       .crtc_gclk       = 0x80cc0015,
+       .crtc_goe        = 0x80cc0015,
+       .crtc_ps1_active = 0x61060017,
+       .pll_freq        = 57,
+       .pixclk_divider         = 4,
+       .pixclk_divider_rotated = 4,
+       .pixclk_src     = CLK_SRC_XTAL,
+       .sysclk_divider  = 1,
+       .sysclk_src     = CLK_SRC_PLL,
+};
+
+
+static struct w100_gpio_regs e750_w100_gpio_info = {
+       .init_data1 = 0x01192f1b,
+       .gpio_dir1  = 0xd5ffdeff,
+       .gpio_oe1   = 0x000020bf,
+       .init_data2 = 0x010f010f,
+       .gpio_dir2  = 0xffffffff,
+       .gpio_oe2   = 0x000001cf,
+};
+
+static struct w100fb_mach_info e750_fb_info = {
+       .modelist   = &e750_lcd_mode,
+       .num_modes  = 1,
+       .regs       = &e750_lcd_regs,
+       .gpio       = &e750_w100_gpio_info,
+       .xtal_freq  = 14318000,
+       .xtal_dbl   = 1,
+};
+
+static struct resource e750_fb_resources[] = {
+       [0] = {
+               .start          = 0x0c000000,
+               .end            = 0x0cffffff,
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+/* ----------------------- device declarations -------------------------- */
+
+
+static struct platform_device e750_fb_device = {
+       .name           = "w100fb",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &e750_fb_info,
+       },
+       .num_resources  = ARRAY_SIZE(e750_fb_resources),
+       .resource       = e750_fb_resources,
+};
+
+static int e750_lcd_init(void)
+{
+       if (!machine_is_e750())
+               return -ENODEV;
+
+       return platform_device_register(&e750_fb_device);
+}
+
+module_init(e750_lcd_init);
+
+MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
+MODULE_DESCRIPTION("e750 lcd driver");
+MODULE_LICENSE("GPLv2");
diff --git a/arch/arm/mach-pxa/e800_lcd.c b/arch/arm/mach-pxa/e800_lcd.c
new file mode 100644 (file)
index 0000000..e6aeab0
--- /dev/null
@@ -0,0 +1,159 @@
+/* e800_lcd.c
+ *
+ * This file contains the definitions for the LCD timings and functions
+ * to control the LCD power / frontlighting via the w100fb driver.
+ *
+ * (c) 2005 Ian Molton <spyro@f2s.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+
+#include <video/w100fb.h>
+
+static struct w100_gen_regs e800_lcd_regs = {
+       .lcd_format =            0x00008003,
+       .lcdd_cntl1 =            0x02a00000,
+       .lcdd_cntl2 =            0x0003ffff,
+       .genlcd_cntl1 =          0x000ff2a3,
+       .genlcd_cntl2 =          0x000002a3,
+       .genlcd_cntl3 =          0x000102aa,
+};
+
+static struct w100_mode e800_lcd_mode[2] = {
+       [0] = {
+               .xres            = 480,
+               .yres            = 640,
+               .left_margin     = 52,
+               .right_margin    = 148,
+               .upper_margin    = 2,
+               .lower_margin    = 6,
+               .crtc_ss         = 0x80350034,
+               .crtc_ls         = 0x802b0026,
+               .crtc_gs         = 0x80160016,
+               .crtc_vpos_gs    = 0x00020003,
+               .crtc_rev        = 0x0040001d,
+               .crtc_dclk       = 0xe0000000,
+               .crtc_gclk       = 0x82a50049,
+               .crtc_goe        = 0x80ee001c,
+               .crtc_ps1_active = 0x00000000,
+               .pll_freq        = 128,
+               .pixclk_divider         = 4,
+               .pixclk_divider_rotated = 6,
+               .pixclk_src     = CLK_SRC_PLL,
+               .sysclk_divider  = 0,
+               .sysclk_src     = CLK_SRC_PLL,
+       },
+       [1] = {
+               .xres            = 240,
+               .yres            = 320,
+               .left_margin     = 15,
+               .right_margin    = 88,
+               .upper_margin    = 0,
+               .lower_margin    = 7,
+               .crtc_ss         = 0xd010000f,
+               .crtc_ls         = 0x80070003,
+               .crtc_gs         = 0x80000000,
+               .crtc_vpos_gs    = 0x01460147,
+               .crtc_rev        = 0x00400003,
+               .crtc_dclk       = 0xa1700030,
+               .crtc_gclk       = 0x814b0008,
+               .crtc_goe        = 0x80cc0015,
+               .crtc_ps1_active = 0x00000000,
+               .pll_freq        = 100,
+               .pixclk_divider         = 6, /* Wince uses 14 which gives a 7MHz pclk. */
+               .pixclk_divider_rotated = 6, /* we want a 14MHz one (much nicer to look at) */
+               .pixclk_src     = CLK_SRC_PLL,
+               .sysclk_divider  = 0,
+               .sysclk_src     = CLK_SRC_PLL,
+       }
+};
+
+
+static struct w100_gpio_regs e800_w100_gpio_info = {
+       .init_data1 = 0xc13fc019,
+       .gpio_dir1  = 0x3e40df7f,
+       .gpio_oe1   = 0x003c3000,
+       .init_data2 = 0x00000000,
+       .gpio_dir2  = 0x00000000,
+       .gpio_oe2   = 0x00000000,
+};
+
+static struct w100_mem_info e800_w100_mem_info = {
+       .ext_cntl        = 0x09640011,
+       .sdram_mode_reg  = 0x00600021,
+       .ext_timing_cntl = 0x10001545,
+       .io_cntl         = 0x7ddd7333,
+       .size            = 0x1fffff,
+};
+
+static void e800_tg_change(struct w100fb_par *par)
+{
+       unsigned long tmp;
+
+       tmp = w100fb_gpio_read(W100_GPIO_PORT_A);
+       if (par->mode->xres == 480)
+               tmp |= 0x100;
+       else
+               tmp &= ~0x100;
+       w100fb_gpio_write(W100_GPIO_PORT_A, tmp);
+}
+
+static struct w100_tg_info e800_tg_info = {
+       .change = e800_tg_change,
+};
+
+static struct w100fb_mach_info e800_fb_info = {
+       .modelist   = e800_lcd_mode,
+       .num_modes  = 2,
+       .regs       = &e800_lcd_regs,
+       .gpio       = &e800_w100_gpio_info,
+       .mem        = &e800_w100_mem_info,
+       .tg         = &e800_tg_info,
+       .xtal_freq  = 16000000,
+};
+
+static struct resource e800_fb_resources[] = {
+       [0] = {
+               .start          = 0x0c000000,
+               .end            = 0x0cffffff,
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+/* ----------------------- device declarations -------------------------- */
+
+
+static struct platform_device e800_fb_device = {
+       .name           = "w100fb",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &e800_fb_info,
+       },
+       .num_resources  = ARRAY_SIZE(e800_fb_resources),
+       .resource       = e800_fb_resources,
+};
+
+static int e800_lcd_init(void)
+{
+       if (!machine_is_e800())
+               return -ENODEV;
+
+       return platform_device_register(&e800_fb_device);
+}
+
+module_init(e800_lcd_init);
+
+MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
+MODULE_DESCRIPTION("e800 lcd driver");
+MODULE_LICENSE("GPLv2");
index 1bf6807499284a3e298f8b12167267b8d7ce63f0..e5cc6ca63c754e687f75f0391fbb60f2fbb8d02e 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Support for CompuLab EM-x270 platform
+ * Support for CompuLab EM-X270 platform
  *
- * Copyright (C) 2007 CompuLab, Ltd.
+ * Copyright (C) 2007, 2008 CompuLab, Ltd.
  * Author: Mike Rapoport <mike@compulab.co.il>
  *
  * This program is free software; you can redistribute it and/or modify
 
 #include <linux/dm9000.h>
 #include <linux/rtc-v3020.h>
-
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio.h>
 
 #include <asm/mach-types.h>
-
 #include <asm/mach/arch.h>
 
+#include <asm/arch/mfp-pxa27x.h>
 #include <asm/arch/pxa-regs.h>
-#include <asm/arch/pxa2xx-gpio.h>
 #include <asm/arch/pxa27x-udc.h>
 #include <asm/arch/audio.h>
 #include <asm/arch/pxafb.h>
 #include <asm/arch/ohci.h>
 #include <asm/arch/mmc.h>
-#include <asm/arch/bitfield.h>
+#include <asm/arch/pxa27x_keypad.h>
 
 #include "generic.h"
 
 /* GPIO IRQ usage */
-#define EM_X270_MMC_PD         (105)
-#define EM_X270_ETHIRQ         IRQ_GPIO(41)
-#define EM_X270_MMC_IRQ                IRQ_GPIO(13)
+#define GPIO41_ETHIRQ          (41)
+#define GPIO13_MMC_CD          (13)
+#define EM_X270_ETHIRQ         IRQ_GPIO(GPIO41_ETHIRQ)
+#define EM_X270_MMC_CD         IRQ_GPIO(GPIO13_MMC_CD)
+
+/* NAND control GPIOs */
+#define GPIO11_NAND_CS (11)
+#define GPIO56_NAND_RB (56)
+
+static unsigned long em_x270_pin_config[] = {
+       /* AC'97 */
+       GPIO28_AC97_BITCLK,
+       GPIO29_AC97_SDATA_IN_0,
+       GPIO30_AC97_SDATA_OUT,
+       GPIO31_AC97_SYNC,
+       GPIO98_AC97_SYSCLK,
+       GPIO113_AC97_nRESET,
+
+       /* BTUART */
+       GPIO42_BTUART_RXD,
+       GPIO43_BTUART_TXD,
+       GPIO44_BTUART_CTS,
+       GPIO45_BTUART_RTS,
+
+       /* STUART */
+       GPIO46_STUART_RXD,
+       GPIO47_STUART_TXD,
+
+       /* MCI controller */
+       GPIO32_MMC_CLK,
+       GPIO112_MMC_CMD,
+       GPIO92_MMC_DAT_0,
+       GPIO109_MMC_DAT_1,
+       GPIO110_MMC_DAT_2,
+       GPIO111_MMC_DAT_3,
+
+       /* LCD */
+       GPIO58_LCD_LDD_0,
+       GPIO59_LCD_LDD_1,
+       GPIO60_LCD_LDD_2,
+       GPIO61_LCD_LDD_3,
+       GPIO62_LCD_LDD_4,
+       GPIO63_LCD_LDD_5,
+       GPIO64_LCD_LDD_6,
+       GPIO65_LCD_LDD_7,
+       GPIO66_LCD_LDD_8,
+       GPIO67_LCD_LDD_9,
+       GPIO68_LCD_LDD_10,
+       GPIO69_LCD_LDD_11,
+       GPIO70_LCD_LDD_12,
+       GPIO71_LCD_LDD_13,
+       GPIO72_LCD_LDD_14,
+       GPIO73_LCD_LDD_15,
+       GPIO74_LCD_FCLK,
+       GPIO75_LCD_LCLK,
+       GPIO76_LCD_PCLK,
+       GPIO77_LCD_BIAS,
+
+       /* QCI */
+       GPIO84_CIF_FV,
+       GPIO25_CIF_LV,
+       GPIO53_CIF_MCLK,
+       GPIO54_CIF_PCLK,
+       GPIO81_CIF_DD_0,
+       GPIO55_CIF_DD_1,
+       GPIO51_CIF_DD_2,
+       GPIO50_CIF_DD_3,
+       GPIO52_CIF_DD_4,
+       GPIO48_CIF_DD_5,
+       GPIO17_CIF_DD_6,
+       GPIO12_CIF_DD_7,
+
+       /* I2C */
+       GPIO117_I2C_SCL,
+       GPIO118_I2C_SDA,
+
+       /* Keypad */
+       GPIO100_KP_MKIN_0       | WAKEUP_ON_LEVEL_HIGH,
+       GPIO101_KP_MKIN_1       | WAKEUP_ON_LEVEL_HIGH,
+       GPIO102_KP_MKIN_2       | WAKEUP_ON_LEVEL_HIGH,
+       GPIO34_KP_MKIN_3        | WAKEUP_ON_LEVEL_HIGH,
+       GPIO39_KP_MKIN_4        | WAKEUP_ON_LEVEL_HIGH,
+       GPIO99_KP_MKIN_5        | WAKEUP_ON_LEVEL_HIGH,
+       GPIO91_KP_MKIN_6        | WAKEUP_ON_LEVEL_HIGH,
+       GPIO36_KP_MKIN_7        | WAKEUP_ON_LEVEL_HIGH,
+       GPIO103_KP_MKOUT_0,
+       GPIO104_KP_MKOUT_1,
+       GPIO105_KP_MKOUT_2,
+       GPIO106_KP_MKOUT_3,
+       GPIO107_KP_MKOUT_4,
+       GPIO108_KP_MKOUT_5,
+       GPIO96_KP_MKOUT_6,
+       GPIO22_KP_MKOUT_7,
+
+       /* SSP1 */
+       GPIO26_SSP1_RXD,
+       GPIO23_SSP1_SCLK,
+       GPIO24_SSP1_SFRM,
+       GPIO57_SSP1_TXD,
+
+       /* SSP2 */
+       GPIO19_SSP2_SCLK,
+       GPIO14_SSP2_SFRM,
+       GPIO89_SSP2_TXD,
+       GPIO88_SSP2_RXD,
+
+       /* SDRAM and local bus */
+       GPIO15_nCS_1,
+       GPIO78_nCS_2,
+       GPIO79_nCS_3,
+       GPIO80_nCS_4,
+       GPIO49_nPWE,
+       GPIO18_RDY,
+
+       /* GPIO */
+       GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
+
+       /* power controls */
+       GPIO20_GPIO     | MFP_LPM_DRIVE_LOW,    /* GPRS_PWEN */
+       GPIO115_GPIO    | MFP_LPM_DRIVE_LOW,    /* WLAN_PWEN */
+
+       /* NAND controls */
+       GPIO11_GPIO     | MFP_LPM_DRIVE_HIGH,   /* NAND CE# */
+       GPIO56_GPIO,                            /* NAND Ready/Busy */
+
+       /* interrupts */
+       GPIO13_GPIO,    /* MMC card detect */
+       GPIO41_GPIO,    /* DM9000 interrupt */
+};
 
-static struct resource em_x270_dm9k_resource[] = {
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource em_x270_dm9000_resource[] = {
        [0] = {
                .start = PXA_CS2_PHYS,
                .end   = PXA_CS2_PHYS + 3,
@@ -56,32 +184,30 @@ static struct resource em_x270_dm9k_resource[] = {
        }
 };
 
-/* for the moment we limit ourselves to 32bit IO until some
- * better IO routines can be written and tested
- */
-static struct dm9000_plat_data em_x270_dm9k_platdata = {
+static struct dm9000_plat_data em_x270_dm9000_platdata = {
        .flags          = DM9000_PLATF_32BITONLY,
 };
 
-/* Ethernet device */
-static struct platform_device em_x270_dm9k = {
+static struct platform_device em_x270_dm9000 = {
        .name           = "dm9000",
        .id             = 0,
-       .num_resources  = ARRAY_SIZE(em_x270_dm9k_resource),
-       .resource       = em_x270_dm9k_resource,
+       .num_resources  = ARRAY_SIZE(em_x270_dm9000_resource),
+       .resource       = em_x270_dm9000_resource,
        .dev            = {
-               .platform_data = &em_x270_dm9k_platdata,
+               .platform_data = &em_x270_dm9000_platdata,
        }
 };
 
-/* WM9712 touchscreen controller. Hopefully the driver will make it to
- * the mainstream sometime */
-static struct platform_device em_x270_ts = {
-       .name           = "wm97xx-ts",
-       .id             = -1,
-};
+static void __init em_x270_init_dm9000(void)
+{
+       platform_device_register(&em_x270_dm9000);
+}
+#else
+static inline void em_x270_init_dm9000(void) {}
+#endif
 
-/* RTC */
+/* V3020 RTC */
+#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
 static struct resource em_x270_v3020_resource[] = {
        [0] = {
                .start = PXA_CS4_PHYS,
@@ -104,20 +230,26 @@ static struct platform_device em_x270_rtc = {
        }
 };
 
-/* NAND flash */
-#define GPIO_NAND_CS   (11)
-#define GPIO_NAND_RB   (56)
+static void __init em_x270_init_rtc(void)
+{
+       platform_device_register(&em_x270_rtc);
+}
+#else
+static inline void em_x270_init_rtc(void) {}
+#endif
 
+/* NAND flash */
+#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
 static inline void nand_cs_on(void)
 {
-       GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
+       gpio_set_value(GPIO11_NAND_CS, 0);
 }
 
 static void nand_cs_off(void)
 {
        dsb();
 
-       GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
+       gpio_set_value(GPIO11_NAND_CS, 1);
 }
 
 /* hardware specific access to control-lines */
@@ -157,7 +289,7 @@ static int em_x270_nand_device_ready(struct mtd_info *mtd)
 {
        dsb();
 
-       return GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB);
+       return gpio_get_value(GPIO56_NAND_RB);
 }
 
 static struct mtd_partition em_x270_partition_info[] = {
@@ -210,16 +342,35 @@ static struct platform_device em_x270_nand = {
        }
 };
 
-/* platform devices */
-static struct platform_device *platform_devices[] __initdata = {
-       &em_x270_dm9k,
-       &em_x270_ts,
-       &em_x270_rtc,
-       &em_x270_nand,
-};
+static void __init em_x270_init_nand(void)
+{
+       int err;
 
+       err = gpio_request(GPIO11_NAND_CS, "NAND CS");
+       if (err) {
+               pr_warning("EM-X270: failed to request NAND CS gpio\n");
+               return;
+       }
+
+       gpio_direction_output(GPIO11_NAND_CS, 1);
+
+       err = gpio_request(GPIO56_NAND_RB, "NAND R/B");
+       if (err) {
+               pr_warning("EM-X270: failed to request NAND R/B gpio\n");
+               gpio_free(GPIO11_NAND_CS);
+               return;
+       }
+
+       gpio_direction_input(GPIO56_NAND_RB);
+
+       platform_device_register(&em_x270_nand);
+}
+#else
+static inline void em_x270_init_nand(void) {}
+#endif
 
 /* PXA27x OHCI controller setup */
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 static int em_x270_ohci_init(struct device *dev)
 {
        /* Set the Power Control Polarity Low */
@@ -237,27 +388,23 @@ static struct pxaohci_platform_data em_x270_ohci_platform_data = {
        .init           = em_x270_ohci_init,
 };
 
+static void __init em_x270_init_ohci(void)
+{
+       pxa_set_ohci_info(&em_x270_ohci_platform_data);
+}
+#else
+static inline void em_x270_init_ohci(void) {}
+#endif
 
+/* MCI controller setup */
+#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
 static int em_x270_mci_init(struct device *dev,
                            irq_handler_t em_x270_detect_int,
                            void *data)
 {
-       int err;
-
-       /* setup GPIO for PXA27x MMC controller */
-       pxa_gpio_mode(GPIO32_MMCCLK_MD);
-       pxa_gpio_mode(GPIO112_MMCCMD_MD);
-       pxa_gpio_mode(GPIO92_MMCDAT0_MD);
-       pxa_gpio_mode(GPIO109_MMCDAT1_MD);
-       pxa_gpio_mode(GPIO110_MMCDAT2_MD);
-       pxa_gpio_mode(GPIO111_MMCDAT3_MD);
-
-       /* EM-X270 uses GPIO13 as SD power enable */
-       pxa_gpio_mode(EM_X270_MMC_PD | GPIO_OUT);
-
-       err = request_irq(EM_X270_MMC_IRQ, em_x270_detect_int,
-                         IRQF_DISABLED | IRQF_TRIGGER_FALLING,
-                         "MMC card detect", data);
+       int err = request_irq(EM_X270_MMC_CD, em_x270_detect_int,
+                             IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+                             "MMC card detect", data);
        if (err) {
                printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n",
                       __func__, err);
@@ -279,7 +426,8 @@ static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
 
 static void em_x270_mci_exit(struct device *dev, void *data)
 {
-       free_irq(EM_X270_MMC_IRQ, data);
+       int irq = gpio_to_irq(GPIO13_MMC_CD);
+       free_irq(irq, data);
 }
 
 static struct pxamci_platform_data em_x270_mci_platform_data = {
@@ -289,7 +437,16 @@ static struct pxamci_platform_data em_x270_mci_platform_data = {
        .exit           = em_x270_mci_exit,
 };
 
+static void __init em_x270_init_mmc(void)
+{
+       pxa_set_mci_info(&em_x270_mci_platform_data);
+}
+#else
+static inline void em_x270_init_mmc(void) {}
+#endif
+
 /* LCD 480x640 */
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
 static struct pxafb_mode_info em_x270_lcd_mode = {
        .pixclock       = 50000,
        .bpp            = 16,
@@ -307,40 +464,96 @@ static struct pxafb_mode_info em_x270_lcd_mode = {
 static struct pxafb_mach_info em_x270_lcd = {
        .modes          = &em_x270_lcd_mode,
        .num_modes      = 1,
-       .cmap_inverse   = 0,
-       .cmap_static    = 0,
-       .lccr0          = LCCR0_PAS,
-       .lccr3          = LCCR3_PixClkDiv(0x01) | LCCR3_Acb(0xff),
+       .lcd_conn       = LCD_COLOR_TFT_16BPP,
 };
-
-static void __init em_x270_init(void)
+static void __init em_x270_init_lcd(void)
 {
-       /* setup LCD */
        set_pxa_fb_info(&em_x270_lcd);
+}
+#else
+static inline void em_x270_init_lcd(void) {}
+#endif
 
-       /* register EM-X270 platform devices */
-       platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE)
+static void __init em_x270_init_ac97(void)
+{
        pxa_set_ac97_info(NULL);
+}
+#else
+static inline void em_x270_init_ac97(void) {}
+#endif
+
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int em_x270_matrix_keys[] = {
+       KEY(0, 0, KEY_A), KEY(1, 0, KEY_UP), KEY(2, 1, KEY_B),
+       KEY(0, 2, KEY_LEFT), KEY(1, 1, KEY_ENTER), KEY(2, 0, KEY_RIGHT),
+       KEY(0, 1, KEY_C), KEY(1, 2, KEY_DOWN), KEY(2, 2, KEY_D),
+};
 
-       /* set MCI and OHCI platform parameters */
-       pxa_set_mci_info(&em_x270_mci_platform_data);
-       pxa_set_ohci_info(&em_x270_ohci_platform_data);
+struct pxa27x_keypad_platform_data em_x270_keypad_info = {
+       /* code map for the matrix keys */
+       .matrix_key_rows        = 3,
+       .matrix_key_cols        = 3,
+       .matrix_key_map         = em_x270_matrix_keys,
+       .matrix_key_map_size    = ARRAY_SIZE(em_x270_matrix_keys),
+};
+
+static void __init em_x270_init_keypad(void)
+{
+       pxa_set_keypad_info(&em_x270_keypad_info);
+}
+#else
+static inline void em_x270_init_keypad(void) {}
+#endif
 
-       /* setup STUART GPIOs */
-       pxa_gpio_mode(GPIO46_STRXD_MD);
-       pxa_gpio_mode(GPIO47_STTXD_MD);
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button gpio_keys_button[] = {
+       [0] = {
+               .desc   = "sleep/wakeup",
+               .code   = KEY_SUSPEND,
+               .type   = EV_PWR,
+               .gpio   = 1,
+               .wakeup = 1,
+       },
+};
 
-       /* setup BTUART GPIOs */
-       pxa_gpio_mode(GPIO42_BTRXD_MD);
-       pxa_gpio_mode(GPIO43_BTTXD_MD);
-       pxa_gpio_mode(GPIO44_BTCTS_MD);
-       pxa_gpio_mode(GPIO45_BTRTS_MD);
+static struct gpio_keys_platform_data em_x270_gpio_keys_data = {
+       .buttons        = gpio_keys_button,
+       .nbuttons       = 1,
+};
 
-       /* Setup interrupt for dm9000 */
-       set_irq_type(EM_X270_ETHIRQ, IRQT_RISING);
+static struct platform_device em_x270_gpio_keys = {
+       .name           = "gpio-keys",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &em_x270_gpio_keys_data,
+       },
+};
+
+static void __init em_x270_init_gpio_keys(void)
+{
+       platform_device_register(&em_x270_gpio_keys);
+}
+#else
+static inline void em_x270_init_gpio_keys(void) {}
+#endif
+
+static void __init em_x270_init(void)
+{
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config));
+
+       em_x270_init_dm9000();
+       em_x270_init_rtc();
+       em_x270_init_nand();
+       em_x270_init_lcd();
+       em_x270_init_mmc();
+       em_x270_init_ohci();
+       em_x270_init_keypad();
+       em_x270_init_gpio_keys();
+       em_x270_init_ac97();
 }
 
-MACHINE_START(EM_X270, "Compulab EM-x270")
+MACHINE_START(EM_X270, "Compulab EM-X270")
        .boot_params    = 0xa0000100,
        .phys_io        = 0x40000000,
        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
index ee0ae93c876a4c82971463cc27e77d25ff3da750..c29b7b21c11be82862accaa0c3aa7e9620b1d0b2 100644 (file)
@@ -17,7 +17,7 @@
 #include <asm/arch/hardware.h>
 #include <asm/mach-types.h>
 
-#include <generic.h>
+#include "generic.h"
 
 /* Only e800 has 128MB RAM */
 static void __init eseries_fixup(struct machine_desc *desc,
@@ -47,6 +47,19 @@ MACHINE_START(E330, "Toshiba e330")
 MACHINE_END
 #endif
 
+#ifdef CONFIG_MACH_E350
+MACHINE_START(E350, "Toshiba e350")
+       /* Maintainer: Ian Molton (spyro@f2s.com) */
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa25x_init_irq,
+       .fixup          = eseries_fixup,
+       .timer = &pxa_timer,
+MACHINE_END
+#endif
+
 #ifdef CONFIG_MACH_E740
 MACHINE_START(E740, "Toshiba e740")
         /* Maintainer: Ian Molton (spyro@f2s.com) */
diff --git a/arch/arm/mach-pxa/eseries_udc.c b/arch/arm/mach-pxa/eseries_udc.c
new file mode 100644 (file)
index 0000000..362847a
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * UDC functions for the Toshiba e-series PDAs
+ *
+ * Copyright (c) Ian Molton 2003
+ *
+ * This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/arch/udc.h>
+#include <asm/arch/eseries-gpio.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+#include <asm/domain.h>
+
+/* local PXA generic code */
+#include "generic.h"
+
+static struct pxa2xx_udc_mach_info e7xx_udc_mach_info = {
+       .gpio_vbus   = GPIO_E7XX_USB_DISC,
+       .gpio_pullup = GPIO_E7XX_USB_PULLUP,
+       .gpio_pullup_inverted = 1
+};
+
+static struct pxa2xx_udc_mach_info e800_udc_mach_info = {
+       .gpio_vbus   = GPIO_E800_USB_DISC,
+       .gpio_pullup = GPIO_E800_USB_PULLUP,
+       .gpio_pullup_inverted = 1
+};
+
+static int __init eseries_udc_init(void)
+{
+       if (machine_is_e330() || machine_is_e350() ||
+           machine_is_e740() || machine_is_e750() ||
+           machine_is_e400())
+               pxa_set_udc_info(&e7xx_udc_mach_info);
+       else if (machine_is_e800())
+               pxa_set_udc_info(&e800_udc_mach_info);
+
+       return 0;
+}
+
+module_init(eseries_udc_init);
+
+MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
+MODULE_DESCRIPTION("eseries UDC support");
+MODULE_LICENSE("GPLv2");
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c
new file mode 100644 (file)
index 0000000..0143eed
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ *  ezx.c - Common code for the EZX platform.
+ *
+ *  Copyright (C) 2005-2006 Harald Welte <laforge@openezx.org>,
+ *               2007-2008 Daniel Ribeiro <drwyrm@gmail.com>,
+ *               2007-2008 Stefan Schmidt <stefan@datenfreihafen.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/pwm_backlight.h>
+
+#include <asm/setup.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/ohci.h>
+#include <asm/arch/i2c.h>
+
+#include <asm/arch/mfp-pxa27x.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa2xx-regs.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "devices.h"
+#include "generic.h"
+
+static struct platform_pwm_backlight_data ezx_backlight_data = {
+       .pwm_id         = 0,
+       .max_brightness = 1023,
+       .dft_brightness = 1023,
+       .pwm_period_ns  = 78770,
+};
+
+static struct platform_device ezx_backlight_device = {
+       .name           = "pwm-backlight",
+       .dev            = {
+               .parent = &pxa27x_device_pwm0.dev,
+               .platform_data = &ezx_backlight_data,
+       },
+};
+
+static struct pxafb_mode_info mode_ezx_old = {
+       .pixclock               = 150000,
+       .xres                   = 240,
+       .yres                   = 320,
+       .bpp                    = 16,
+       .hsync_len              = 10,
+       .left_margin            = 20,
+       .right_margin           = 10,
+       .vsync_len              = 2,
+       .upper_margin           = 3,
+       .lower_margin           = 2,
+       .sync                   = 0,
+};
+
+static struct pxafb_mach_info ezx_fb_info_1 = {
+       .modes          = &mode_ezx_old,
+       .num_modes      = 1,
+       .lcd_conn       = LCD_COLOR_TFT_16BPP,
+};
+
+static struct pxafb_mode_info mode_72r89803y01 = {
+       .pixclock               = 192308,
+       .xres                   = 240,
+       .yres                   = 320,
+       .bpp                    = 32,
+       .depth                  = 18,
+       .hsync_len              = 10,
+       .left_margin            = 20,
+       .right_margin           = 10,
+       .vsync_len              = 2,
+       .upper_margin           = 3,
+       .lower_margin           = 2,
+       .sync                   = 0,
+};
+
+static struct pxafb_mach_info ezx_fb_info_2 = {
+       .modes          = &mode_72r89803y01,
+       .num_modes      = 1,
+       .lcd_conn       = LCD_COLOR_TFT_18BPP,
+};
+
+static struct platform_device *devices[] __initdata = {
+       &ezx_backlight_device,
+};
+
+static unsigned long ezx_pin_config[] __initdata = {
+       /* PWM backlight */
+       GPIO16_PWM0_OUT,
+
+       /* BTUART */
+       GPIO42_BTUART_RXD,
+       GPIO43_BTUART_TXD,
+       GPIO44_BTUART_CTS,
+       GPIO45_BTUART_RTS,
+
+       /* STUART */
+       GPIO46_STUART_RXD,
+       GPIO47_STUART_TXD,
+
+       /* For A780 support (connected with Neptune GSM chip) */
+       GPIO30_USB_P3_2,        /* ICL_TXENB */
+       GPIO31_USB_P3_6,        /* ICL_VPOUT */
+       GPIO90_USB_P3_5,        /* ICL_VPIN */
+       GPIO91_USB_P3_1,        /* ICL_XRXD */
+       GPIO56_USB_P3_4,        /* ICL_VMOUT */
+       GPIO113_USB_P3_3,       /* /ICL_VMIN */
+};
+
+static void __init ezx_init(void)
+{
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
+       pxa_set_i2c_info(NULL);
+       if (machine_is_ezx_a780() || machine_is_ezx_e680())
+               set_pxa_fb_info(&ezx_fb_info_1);
+       else
+               set_pxa_fb_info(&ezx_fb_info_2);
+
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init ezx_fixup(struct machine_desc *desc, struct tag *tags,
+               char **cmdline, struct meminfo *mi)
+{
+       /* We have two ram chips. First one with 32MB at 0xA0000000 and a second
+        * 16MB one at 0xAC000000
+        */
+       mi->nr_banks = 2;
+       mi->bank[0].start = 0xa0000000;
+       mi->bank[0].node = 0;
+       mi->bank[0].size = (32*1024*1024);
+       mi->bank[1].start = 0xac000000;
+       mi->bank[1].node = 1;
+       mi->bank[1].size = (16*1024*1024);
+}
+
+#ifdef CONFIG_MACH_EZX_A780
+MACHINE_START(EZX_A780, "Motorola EZX A780")
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .fixup                  = ezx_fixup,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa27x_init_irq,
+       .timer          = &pxa_timer,
+       .init_machine   = &ezx_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EZX_E680
+MACHINE_START(EZX_E680, "Motorola EZX E680")
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .fixup                  = ezx_fixup,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa27x_init_irq,
+       .timer          = &pxa_timer,
+       .init_machine   = &ezx_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EZX_A1200
+MACHINE_START(EZX_A1200, "Motorola EZX A1200")
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .fixup                  = ezx_fixup,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa27x_init_irq,
+       .timer          = &pxa_timer,
+       .init_machine   = &ezx_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EZX_A910
+MACHINE_START(EZX_A910, "Motorola EZX A910")
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .fixup                  = ezx_fixup,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa27x_init_irq,
+       .timer          = &pxa_timer,
+       .init_machine   = &ezx_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EZX_E6
+MACHINE_START(EZX_E6, "Motorola EZX E6")
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .fixup                  = ezx_fixup,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa27x_init_irq,
+       .timer          = &pxa_timer,
+       .init_machine   = &ezx_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EZX_E2
+MACHINE_START(EZX_E2, "Motorola EZX E2")
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .fixup                  = ezx_fixup,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa27x_init_irq,
+       .timer          = &pxa_timer,
+       .init_machine   = &ezx_init,
+MACHINE_END
+#endif
index 530654474bb23bda983e2909b6bbf802748d44d3..dd759d03a9fd90ff1d64ec37a2beaa83e3382a85 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/smc91x.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -38,6 +39,7 @@
 #include <asm/arch/pxafb.h>
 #include <asm/arch/ssp.h>
 #include <asm/arch/pxa27x_keypad.h>
+#include <asm/arch/pxa3xx_nand.h>
 #include <asm/arch/littleton.h>
 
 #include "generic.h"
@@ -101,18 +103,26 @@ static struct resource smc91x_resources[] = {
        [1] = {
                .start  = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)),
                .end    = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)),
-               .flags  = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
        }
 };
 
+static struct smc91x_platdata littleton_smc91x_info = {
+       .flags  = SMC91X_USE_8BIT | SMC91X_USE_16BIT |
+                 SMC91X_NOWAIT | SMC91X_USE_DMA,
+};
+
 static struct platform_device smc91x_device = {
        .name           = "smc91x",
        .id             = 0,
        .num_resources  = ARRAY_SIZE(smc91x_resources),
        .resource       = smc91x_resources,
+       .dev            = {
+               .platform_data = &littleton_smc91x_info,
+       },
 };
 
-#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULES)
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
 /* use bit 30, 31 as the indicator of command parameter number */
 #define CMD0(x)                ((0x00000000) | ((x) << 9))
 #define CMD1(x, x1)    ((0x40000000) | ((x) << 9) | 0x100 | (x1))
@@ -311,9 +321,9 @@ static void littleton_init_lcd(void)
 }
 #else
 static inline void littleton_init_lcd(void) {};
-#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULES */
+#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */
 
-#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULES)
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
 static unsigned int littleton_matrix_key_map[] = {
        /* KEY(row, col, key_code) */
        KEY(1, 3, KEY_0), KEY(0, 0, KEY_1), KEY(1, 0, KEY_2), KEY(2, 0, KEY_3),
@@ -361,6 +371,57 @@ static void __init littleton_init_keypad(void)
 static inline void littleton_init_keypad(void) {}
 #endif
 
+#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+static struct mtd_partition littleton_nand_partitions[] = {
+       [0] = {
+               .name        = "Bootloader",
+               .offset      = 0,
+               .size        = 0x060000,
+               .mask_flags  = MTD_WRITEABLE, /* force read-only */
+       },
+       [1] = {
+               .name        = "Kernel",
+               .offset      = 0x060000,
+               .size        = 0x200000,
+               .mask_flags  = MTD_WRITEABLE, /* force read-only */
+       },
+       [2] = {
+               .name        = "Filesystem",
+               .offset      = 0x0260000,
+               .size        = 0x3000000,     /* 48M - rootfs */
+       },
+       [3] = {
+               .name        = "MassStorage",
+               .offset      = 0x3260000,
+               .size        = 0x3d40000,
+       },
+       [4] = {
+               .name        = "BBT",
+               .offset      = 0x6FA0000,
+               .size        = 0x80000,
+               .mask_flags  = MTD_WRITEABLE,  /* force read-only */
+       },
+       /* NOTE: we reserve some blocks at the end of the NAND flash for
+        * bad block management, and the max number of relocation blocks
+        * differs on different platforms. Please take care with it when
+        * defining the partition table.
+        */
+};
+
+static struct pxa3xx_nand_platform_data littleton_nand_info = {
+       .enable_arbiter = 1,
+       .parts          = littleton_nand_partitions,
+       .nr_parts       = ARRAY_SIZE(littleton_nand_partitions),
+};
+
+static void __init littleton_init_nand(void)
+{
+       pxa3xx_set_nand_info(&littleton_nand_info);
+}
+#else
+static inline void littleton_init_nand(void) {}
+#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
+
 static void __init littleton_init(void)
 {
        /* initialize MFP configurations */
@@ -374,6 +435,7 @@ static void __init littleton_init(void)
 
        littleton_init_lcd();
        littleton_init_keypad();
+       littleton_init_nand();
 }
 
 MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleton)")
index a3fae4139203d42325f6ecc0f3b833e57bc804b5..ac26423cd20cbda2ce8db0667887625c4ef466da 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/smc91x.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
@@ -226,14 +227,6 @@ static struct pxa2xx_spi_master pxa_ssp_master_info = {
        .num_chipselect = 0,
 };
 
-static struct platform_device pxa_ssp = {
-       .name           = "pxa2xx-spi",
-       .id             = 1,
-       .dev = {
-               .platform_data  = &pxa_ssp_master_info,
-       },
-};
-
 static int lubbock_ads7846_pendown_state(void)
 {
        /* TS_BUSY is bit 8 in LUB_MISC_RD, but pendown is irq-only */
@@ -292,11 +285,18 @@ static struct resource smc91x_resources[] = {
        },
 };
 
+static struct smc91x_platdata lubbock_smc91x_info = {
+       .flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_IO_SHIFT_2,
+};
+
 static struct platform_device smc91x_device = {
        .name           = "smc91x",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(smc91x_resources),
        .resource       = smc91x_resources,
+       .dev            = {
+               .platform_data = &lubbock_smc91x_info,
+       },
 };
 
 static struct resource flash_resources[] = {
@@ -367,7 +367,6 @@ static struct platform_device *devices[] __initdata = {
        &smc91x_device,
        &lubbock_flash_device[0],
        &lubbock_flash_device[1],
-       &pxa_ssp,
 };
 
 static struct pxafb_mode_info sharp_lm8v31_mode = {
@@ -471,6 +470,7 @@ static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
        } else if (mode & IR_FIRMODE) {
                LUB_MISC_WR |= 1 << 4;
        }
+       pxa2xx_transceiver_mode(dev, mode);
        local_irq_restore(flags);
 }
 
@@ -501,6 +501,7 @@ static void __init lubbock_init(void)
        lubbock_flash_data[flashboot].name = "boot-rom";
        (void) platform_add_devices(devices, ARRAY_SIZE(devices));
 
+       pxa2xx_set_spi_info(1, &pxa_ssp_master_info);
        spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
 }
 
index 01b2fa7902179c952c2e5ff36381d07930016d01..c9d274f0048f6f85eb8278f6d50c24e2a11d3285 100644 (file)
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/mfd/htc-egpio.h>
 #include <linux/mfd/htc-pasic3.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
 #include <linux/mtd/physmap.h>
 #include <linux/pda_power.h>
 #include <linux/pwm_backlight.h>
 
-#include <asm/gpio.h>
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -44,7 +42,7 @@
 #include "devices.h"
 #include "generic.h"
 
-static unsigned long magician_pin_config[] = {
+static unsigned long magician_pin_config[] __initdata = {
 
        /* SDRAM and Static Memory I/O Signals */
        GPIO20_nSDCS_2,
@@ -134,6 +132,7 @@ static unsigned long magician_pin_config[] = {
 static void magician_irda_transceiver_mode(struct device *dev, int mode)
 {
        gpio_set_value(GPIO83_MAGICIAN_nIR_EN, mode & IR_OFF);
+       pxa2xx_transceiver_mode(dev, mode);
 }
 
 static struct pxaficp_platform_data magician_ficp_info = {
@@ -399,6 +398,7 @@ static struct platform_pwm_backlight_data backlight_data = {
 
 static struct platform_device backlight = {
        .name = "pwm-backlight",
+       .id   = -1,
        .dev  = {
                .parent        = &pxa27x_device_pwm0.dev,
                .platform_data = &backlight_data,
@@ -511,6 +511,37 @@ static struct platform_device pasic3 = {
  * External power
  */
 
+static int power_supply_init(struct device *dev)
+{
+       int ret;
+
+       ret = gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
+       if (ret)
+               goto err_cs_ac;
+       ret = gpio_request(EGPIO_MAGICIAN_CABLE_STATE_USB, "CABLE_STATE_USB");
+       if (ret)
+               goto err_cs_usb;
+       ret = gpio_request(EGPIO_MAGICIAN_CHARGE_EN, "CHARGE_EN");
+       if (ret)
+               goto err_chg_en;
+       ret = gpio_request(GPIO30_MAGICIAN_nCHARGE_EN, "nCHARGE_EN");
+       if (!ret)
+               ret = gpio_direction_output(GPIO30_MAGICIAN_nCHARGE_EN, 0);
+       if (ret)
+               goto err_nchg_en;
+
+       return 0;
+
+err_nchg_en:
+       gpio_free(EGPIO_MAGICIAN_CHARGE_EN);
+err_chg_en:
+       gpio_free(EGPIO_MAGICIAN_CABLE_STATE_USB);
+err_cs_usb:
+       gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
+err_cs_ac:
+       return ret;
+}
+
 static int magician_is_ac_online(void)
 {
        return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
@@ -527,14 +558,24 @@ static void magician_set_charge(int flags)
        gpio_set_value(EGPIO_MAGICIAN_CHARGE_EN, flags);
 }
 
+static void power_supply_exit(struct device *dev)
+{
+       gpio_free(GPIO30_MAGICIAN_nCHARGE_EN);
+       gpio_free(EGPIO_MAGICIAN_CHARGE_EN);
+       gpio_free(EGPIO_MAGICIAN_CABLE_STATE_USB);
+       gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
+}
+
 static char *magician_supplicants[] = {
        "ds2760-battery.0", "backup-battery"
 };
 
 static struct pda_power_pdata power_supply_info = {
+       .init            = power_supply_init,
        .is_ac_online    = magician_is_ac_online,
        .is_usb_online   = magician_is_usb_online,
        .set_charge      = magician_set_charge,
+       .exit            = power_supply_exit,
        .supplied_to     = magician_supplicants,
        .num_supplicants = ARRAY_SIZE(magician_supplicants),
 };
index f2e9e7c4da8e625988d3d401c84a3650795caea8..851ec2d9b699c178fe36aa723269150d67f409f4 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
 #include <linux/pwm_backlight.h>
+#include <linux/smc91x.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -110,9 +111,9 @@ static unsigned long mainstone_pin_config[] = {
        GPIO45_AC97_SYSCLK,
 
        /* Keypad */
-       GPIO93_KP_DKIN_0        | WAKEUP_ON_LEVEL_HIGH,
-       GPIO94_KP_DKIN_1        | WAKEUP_ON_LEVEL_HIGH,
-       GPIO95_KP_DKIN_2        | WAKEUP_ON_LEVEL_HIGH,
+       GPIO93_KP_DKIN_0,
+       GPIO94_KP_DKIN_1,
+       GPIO95_KP_DKIN_2,
        GPIO100_KP_MKIN_0       | WAKEUP_ON_LEVEL_HIGH,
        GPIO101_KP_MKIN_1       | WAKEUP_ON_LEVEL_HIGH,
        GPIO102_KP_MKIN_2       | WAKEUP_ON_LEVEL_HIGH,
@@ -240,11 +241,19 @@ static struct resource smc91x_resources[] = {
        }
 };
 
+static struct smc91x_platdata mainstone_smc91x_info = {
+       .flags  = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
+                 SMC91X_NOWAIT | SMC91X_USE_DMA,
+};
+
 static struct platform_device smc91x_device = {
        .name           = "smc91x",
        .id             = 0,
        .num_resources  = ARRAY_SIZE(smc91x_resources),
        .resource       = smc91x_resources,
+       .dev            = {
+               .platform_data = &mainstone_smc91x_info,
+       },
 };
 
 static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv)
@@ -455,6 +464,7 @@ static void mainstone_irda_transceiver_mode(struct device *dev, int mode)
        } else if (mode & IR_FIRMODE) {
                MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR;
        }
+       pxa2xx_transceiver_mode(dev, mode);
        if (mode & IR_OFF) {
                MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF;
        } else {
@@ -513,7 +523,7 @@ static struct pxaohci_platform_data mainstone_ohci_platform_data = {
        .init           = mainstone_ohci_init,
 };
 
-#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULES)
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
 static unsigned int mainstone_matrix_keys[] = {
        KEY(0, 0, KEY_A), KEY(1, 0, KEY_B), KEY(2, 0, KEY_C),
        KEY(3, 0, KEY_D), KEY(4, 0, KEY_E), KEY(5, 0, KEY_F),
index d1cdb4ecb0b8c28c38586af34f035e2baca0cfcb..fd4545eab8033172144a27f54edff48c4931872f 100644 (file)
@@ -39,6 +39,28 @@ struct gpio_desc {
 
 static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1];
 
+static int __mfp_config_lpm(unsigned gpio, unsigned long lpm)
+{
+       unsigned mask = GPIO_bit(gpio);
+
+       /* low power state */
+       switch (lpm) {
+       case MFP_LPM_DRIVE_HIGH:
+               PGSR(gpio) |= mask;
+               break;
+       case MFP_LPM_DRIVE_LOW:
+               PGSR(gpio) &= ~mask;
+               break;
+       case MFP_LPM_INPUT:
+               break;
+       default:
+               pr_warning("%s: invalid low power state for GPIO%d\n",
+                               __func__, gpio);
+               return -EINVAL;
+       }
+       return 0;
+}
+
 static int __mfp_config_gpio(unsigned gpio, unsigned long c)
 {
        unsigned long gafr, mask = GPIO_bit(gpio);
@@ -57,21 +79,8 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
        else
                GPDR(gpio) &= ~mask;
 
-       /* low power state */
-       switch (c & MFP_LPM_STATE_MASK) {
-       case MFP_LPM_DRIVE_HIGH:
-               PGSR(gpio) |= mask;
-               break;
-       case MFP_LPM_DRIVE_LOW:
-               PGSR(gpio) &= ~mask;
-               break;
-       case MFP_LPM_INPUT:
-               break;
-       default:
-               pr_warning("%s: invalid low power state for GPIO%d\n",
-                               __func__, gpio);
+       if (__mfp_config_lpm(gpio, c & MFP_LPM_STATE_MASK))
                return -EINVAL;
-       }
 
        /* give early warning if MFP_LPM_CAN_WAKEUP is set on the
         * configurations of those pins not able to wakeup
@@ -91,6 +100,18 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
        return 0;
 }
 
+static inline int __mfp_validate(int mfp)
+{
+       int gpio = mfp_to_gpio(mfp);
+
+       if ((mfp > MFP_PIN_GPIO127) || !gpio_desc[gpio].valid) {
+               pr_warning("%s: GPIO%d is invalid pin\n", __func__, gpio);
+               return -1;
+       }
+
+       return gpio;
+}
+
 void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
 {
        unsigned long flags;
@@ -99,13 +120,9 @@ void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
 
        for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
 
-               gpio = mfp_to_gpio(MFP_PIN(*c));
-
-               if (!gpio_desc[gpio].valid) {
-                       pr_warning("%s: GPIO%d is invalid pin\n",
-                               __func__, gpio);
+               gpio = __mfp_validate(MFP_PIN(*c));
+               if (gpio < 0)
                        continue;
-               }
 
                local_irq_save(flags);
 
@@ -116,6 +133,20 @@ void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
        }
 }
 
+void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm)
+{
+       unsigned long flags;
+       int gpio;
+
+       gpio = __mfp_validate(mfp);
+       if (gpio < 0)
+               return;
+
+       local_irq_save(flags);
+       __mfp_config_lpm(gpio, lpm);
+       local_irq_restore(flags);
+}
+
 int gpio_set_wake(unsigned int gpio, unsigned int on)
 {
        struct gpio_desc *d;
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
new file mode 100644 (file)
index 0000000..408657a
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ * Hardware definitions for PalmTX
+ *
+ * Author:     Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on work of:
+ *             Alex Osborne <ato@meshy.org>
+ *             Cristiano P. <cristianop@users.sourceforge.net>
+ *             Jan Herman <2hp@seznam.cz>
+ *             Michal Hrusecky
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (find more info at www.hackndev.com)
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/audio.h>
+#include <asm/arch/palmtx.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/mfp-pxa27x.h>
+#include <asm/arch/irda.h>
+#include <asm/arch/pxa27x_keypad.h>
+#include <asm/arch/udc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmtx_pin_config[] __initdata = {
+       /* MMC */
+       GPIO32_MMC_CLK,
+       GPIO92_MMC_DAT_0,
+       GPIO109_MMC_DAT_1,
+       GPIO110_MMC_DAT_2,
+       GPIO111_MMC_DAT_3,
+       GPIO112_MMC_CMD,
+
+       /* AC97 */
+       GPIO28_AC97_BITCLK,
+       GPIO29_AC97_SDATA_IN_0,
+       GPIO30_AC97_SDATA_OUT,
+       GPIO31_AC97_SYNC,
+
+       /* IrDA */
+       GPIO46_FICP_RXD,
+       GPIO47_FICP_TXD,
+
+       /* PWM */
+       GPIO16_PWM0_OUT,
+
+       /* USB */
+       GPIO13_GPIO,
+
+       /* PCMCIA */
+       GPIO48_nPOE,
+       GPIO49_nPWE,
+       GPIO50_nPIOR,
+       GPIO51_nPIOW,
+       GPIO85_nPCE_1,
+       GPIO54_nPCE_2,
+       GPIO79_PSKTSEL,
+       GPIO55_nPREG,
+       GPIO56_nPWAIT,
+       GPIO57_nIOIS16,
+};
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+static int palmtx_mci_init(struct device *dev, irq_handler_t palmtx_detect_int,
+                               void *data)
+{
+       int err = 0;
+
+       /* Setup an interrupt for detecting card insert/remove events */
+       err = request_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, palmtx_detect_int,
+                       IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
+                       IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+                       "SD/MMC card detect", data);
+       if (err) {
+               printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
+                               __func__);
+               return err;
+       }
+
+       err = gpio_request(GPIO_NR_PALMTX_SD_POWER, "SD_POWER");
+       if (err)
+               goto pwr_err;
+
+       err = gpio_request(GPIO_NR_PALMTX_SD_READONLY, "SD_READONLY");
+       if (err)
+               goto ro_err;
+
+       printk(KERN_DEBUG "%s: irq registered\n", __func__);
+
+       return 0;
+
+ro_err:
+       gpio_free(GPIO_NR_PALMTX_SD_POWER);
+pwr_err:
+       free_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, data);
+       return err;
+}
+
+static void palmtx_mci_exit(struct device *dev, void *data)
+{
+       gpio_free(GPIO_NR_PALMTX_SD_READONLY);
+       gpio_free(GPIO_NR_PALMTX_SD_POWER);
+       free_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, data);
+}
+
+static void palmtx_mci_power(struct device *dev, unsigned int vdd)
+{
+       struct pxamci_platform_data *p_d = dev->platform_data;
+       gpio_set_value(GPIO_NR_PALMTX_SD_POWER, p_d->ocr_mask & (1 << vdd));
+}
+
+static int palmtx_mci_get_ro(struct device *dev)
+{
+       return gpio_get_value(GPIO_NR_PALMTX_SD_READONLY);
+}
+
+static struct pxamci_platform_data palmtx_mci_platform_data = {
+       .ocr_mask       = MMC_VDD_32_33 | MMC_VDD_33_34,
+       .setpower       = palmtx_mci_power,
+       .get_ro         = palmtx_mci_get_ro,
+       .init           = palmtx_mci_init,
+       .exit           = palmtx_mci_exit,
+};
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+static unsigned int palmtx_matrix_keys[] = {
+       KEY(0, 0, KEY_POWER),
+       KEY(0, 1, KEY_F1),
+       KEY(0, 2, KEY_ENTER),
+
+       KEY(1, 0, KEY_F2),
+       KEY(1, 1, KEY_F3),
+       KEY(1, 2, KEY_F4),
+
+       KEY(2, 0, KEY_UP),
+       KEY(2, 2, KEY_DOWN),
+
+       KEY(3, 0, KEY_RIGHT),
+       KEY(3, 2, KEY_LEFT),
+
+};
+
+static struct pxa27x_keypad_platform_data palmtx_keypad_platform_data = {
+       .matrix_key_rows        = 4,
+       .matrix_key_cols        = 3,
+       .matrix_key_map         = palmtx_matrix_keys,
+       .matrix_key_map_size    = ARRAY_SIZE(palmtx_matrix_keys),
+
+       .debounce_interval      = 30,
+};
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+static struct gpio_keys_button palmtx_pxa_buttons[] = {
+       {KEY_F8, GPIO_NR_PALMTX_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
+};
+
+static struct gpio_keys_platform_data palmtx_pxa_keys_data = {
+       .buttons        = palmtx_pxa_buttons,
+       .nbuttons       = ARRAY_SIZE(palmtx_pxa_buttons),
+};
+
+static struct platform_device palmtx_pxa_keys = {
+       .name   = "gpio-keys",
+       .id     = -1,
+       .dev    = {
+               .platform_data = &palmtx_pxa_keys_data,
+       },
+};
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+static int palmtx_backlight_init(struct device *dev)
+{
+       int ret;
+
+       ret = gpio_request(GPIO_NR_PALMTX_BL_POWER, "BL POWER");
+       if (ret)
+               goto err;
+       ret = gpio_request(GPIO_NR_PALMTX_LCD_POWER, "LCD POWER");
+       if (ret)
+               goto err2;
+
+       return 0;
+err2:
+       gpio_free(GPIO_NR_PALMTX_BL_POWER);
+err:
+       return ret;
+}
+
+static int palmtx_backlight_notify(int brightness)
+{
+       gpio_set_value(GPIO_NR_PALMTX_BL_POWER, brightness);
+       gpio_set_value(GPIO_NR_PALMTX_LCD_POWER, brightness);
+       return brightness;
+}
+
+static void palmtx_backlight_exit(struct device *dev)
+{
+       gpio_free(GPIO_NR_PALMTX_BL_POWER);
+       gpio_free(GPIO_NR_PALMTX_LCD_POWER);
+}
+
+static struct platform_pwm_backlight_data palmtx_backlight_data = {
+       .pwm_id         = 0,
+       .max_brightness = PALMTX_MAX_INTENSITY,
+       .dft_brightness = PALMTX_MAX_INTENSITY,
+       .pwm_period_ns  = PALMTX_PERIOD_NS,
+       .init           = palmtx_backlight_init,
+       .notify         = palmtx_backlight_notify,
+       .exit           = palmtx_backlight_exit,
+};
+
+static struct platform_device palmtx_backlight = {
+       .name   = "pwm-backlight",
+       .dev    = {
+               .parent         = &pxa27x_device_pwm0.dev,
+               .platform_data  = &palmtx_backlight_data,
+       },
+};
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+static void palmtx_irda_transceiver_mode(struct device *dev, int mode)
+{
+       gpio_set_value(GPIO_NR_PALMTX_IR_DISABLE, mode & IR_OFF);
+       pxa2xx_transceiver_mode(dev, mode);
+}
+
+static struct pxaficp_platform_data palmtx_ficp_platform_data = {
+       .transceiver_cap        = IR_SIRMODE | IR_FIRMODE | IR_OFF,
+       .transceiver_mode       = palmtx_irda_transceiver_mode,
+};
+
+/******************************************************************************
+ * UDC
+ ******************************************************************************/
+static void palmtx_udc_command(int cmd)
+{
+       gpio_set_value(GPIO_NR_PALMTX_USB_POWER, !cmd);
+       udelay(50);
+       gpio_set_value(GPIO_NR_PALMTX_USB_PULLUP, !cmd);
+}
+
+static struct pxa2xx_udc_mach_info palmtx_udc_info __initdata = {
+       .gpio_vbus              = GPIO_NR_PALMTX_USB_DETECT_N,
+       .gpio_vbus_inverted     = 1,
+       .udc_command            = palmtx_udc_command,
+};
+
+/******************************************************************************
+ * Power supply
+ ******************************************************************************/
+static int power_supply_init(struct device *dev)
+{
+       int ret;
+
+       ret = gpio_request(GPIO_NR_PALMTX_POWER_DETECT, "CABLE_STATE_AC");
+       if (ret)
+               goto err_cs_ac;
+
+       ret = gpio_request(GPIO_NR_PALMTX_USB_DETECT_N, "CABLE_STATE_USB");
+       if (ret)
+               goto err_cs_usb;
+
+       return 0;
+
+err_cs_usb:
+       gpio_free(GPIO_NR_PALMTX_POWER_DETECT);
+err_cs_ac:
+       return ret;
+}
+
+static int palmtx_is_ac_online(void)
+{
+       return gpio_get_value(GPIO_NR_PALMTX_POWER_DETECT);
+}
+
+static int palmtx_is_usb_online(void)
+{
+       return !gpio_get_value(GPIO_NR_PALMTX_USB_DETECT_N);
+}
+
+static void power_supply_exit(struct device *dev)
+{
+       gpio_free(GPIO_NR_PALMTX_USB_DETECT_N);
+       gpio_free(GPIO_NR_PALMTX_POWER_DETECT);
+}
+
+static char *palmtx_supplicants[] = {
+       "main-battery",
+};
+
+static struct pda_power_pdata power_supply_info = {
+       .init            = power_supply_init,
+       .is_ac_online    = palmtx_is_ac_online,
+       .is_usb_online   = palmtx_is_usb_online,
+       .exit            = power_supply_exit,
+       .supplied_to     = palmtx_supplicants,
+       .num_supplicants = ARRAY_SIZE(palmtx_supplicants),
+};
+
+static struct platform_device power_supply = {
+       .name = "pda-power",
+       .id   = -1,
+       .dev  = {
+               .platform_data = &power_supply_info,
+       },
+};
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+static struct pxafb_mode_info palmtx_lcd_modes[] = {
+{
+       .pixclock       = 57692,
+       .xres           = 320,
+       .yres           = 480,
+       .bpp            = 16,
+
+       .left_margin    = 32,
+       .right_margin   = 1,
+       .upper_margin   = 7,
+       .lower_margin   = 1,
+
+       .hsync_len      = 4,
+       .vsync_len      = 1,
+},
+};
+
+static struct pxafb_mach_info palmtx_lcd_screen = {
+       .modes          = palmtx_lcd_modes,
+       .num_modes      = ARRAY_SIZE(palmtx_lcd_modes),
+       .lcd_conn       = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static struct platform_device *devices[] __initdata = {
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+       &palmtx_pxa_keys,
+#endif
+       &palmtx_backlight,
+       &power_supply,
+};
+
+static struct map_desc palmtx_io_desc[] __initdata = {
+{
+       .virtual        = PALMTX_PCMCIA_VIRT,
+       .pfn            = __phys_to_pfn(PALMTX_PCMCIA_PHYS),
+       .length         = PALMTX_PCMCIA_SIZE,
+       .type           = MT_DEVICE
+},
+};
+
+static void __init palmtx_map_io(void)
+{
+       pxa_map_io();
+       iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc));
+}
+
+static void __init palmtx_init(void)
+{
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtx_pin_config));
+
+       set_pxa_fb_info(&palmtx_lcd_screen);
+       pxa_set_mci_info(&palmtx_mci_platform_data);
+       pxa_set_udc_info(&palmtx_udc_info);
+       pxa_set_ac97_info(NULL);
+       pxa_set_ficp_info(&palmtx_ficp_platform_data);
+       pxa_set_keypad_info(&palmtx_keypad_platform_data);
+
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(PALMTX, "Palm T|X")
+       .phys_io        = PALMTX_PHYS_IO_START,
+       .io_pg_offst    = io_p2v(0x40000000),
+       .boot_params    = 0xa0000100,
+       .map_io         = palmtx_map_io,
+       .init_irq       = pxa27x_init_irq,
+       .timer          = &pxa_timer,
+       .init_machine   = palmtx_init
+MACHINE_END
index 3b945eb0aee3768a1c22b2efa12be75537b8a13a..377f3be8ce578fc5f04477cb12c9ef94532c7d41 100644 (file)
@@ -24,7 +24,9 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/physmap.h>
 #include <linux/spi/spi.h>
+#include <linux/spi/max7301.h>
 #include <linux/leds.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/arch/hardware.h>
@@ -108,6 +110,32 @@ static struct platform_device smc91x_device = {
        .resource       = smc91x_resources,
 };
 
+/*
+ * SPI host and devices
+ */
+static struct pxa2xx_spi_master pxa_ssp_master_info = {
+       .num_chipselect = 1,
+};
+
+static struct max7301_platform_data max7301_info = {
+       .base = -1,
+};
+
+/* bus_num must match id in pxa2xx_set_spi_info() call */
+static struct spi_board_info spi_board_info[] __initdata = {
+       {
+               .modalias       = "max7301",
+               .platform_data  = &max7301_info,
+               .max_speed_hz   = 13000000,
+               .bus_num        = 1,
+               .chip_select    = 0,
+               .mode           = SPI_MODE_0,
+       },
+};
+
+/*
+ * NOR flash
+ */
 static struct physmap_flash_data pcm027_flash_data = {
        .width  = 4,
 };
@@ -190,6 +218,9 @@ static void __init pcm027_init(void)
 #ifdef CONFIG_MACH_PCM990_BASEBOARD
        pcm990_baseboard_init();
 #endif
+
+       pxa2xx_set_spi_info(1, &pxa_ssp_master_info);
+       spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
 }
 
 static void __init pcm027_map_io(void)
index 5d87c7c866e4b30da57fa90a1693741220298815..30023b00e476161a691aa8a5603c1a0b08fa534d 100644 (file)
 #include <asm/arch/camera.h>
 #include <asm/mach/map.h>
 #include <asm/arch/pxa-regs.h>
-#include <asm/arch/pxa2xx-gpio.h>
 #include <asm/arch/audio.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/ohci.h>
 #include <asm/arch/pcm990_baseboard.h>
 #include <asm/arch/pxafb.h>
+#include <asm/arch/mfp-pxa27x.h>
 
 #include "devices.h"
+#include "generic.h"
+
+static unsigned long pcm990_pin_config[] __initdata = {
+       /* MMC */
+       GPIO32_MMC_CLK,
+       GPIO112_MMC_CMD,
+       GPIO92_MMC_DAT_0,
+       GPIO109_MMC_DAT_1,
+       GPIO110_MMC_DAT_2,
+       GPIO111_MMC_DAT_3,
+       /* USB */
+       GPIO88_USBH1_PWR,
+       GPIO89_USBH1_PEN,
+       /* PWM0 */
+       GPIO16_PWM0_OUT,
+};
 
 /*
  * pcm990_lcd_power - control power supply to the LCD
@@ -277,16 +293,6 @@ static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
 {
        int err;
 
-       /*
-        * enable GPIO for PXA27x MMC controller
-        */
-       pxa_gpio_mode(GPIO32_MMCCLK_MD);
-       pxa_gpio_mode(GPIO112_MMCCMD_MD);
-       pxa_gpio_mode(GPIO92_MMCDAT0_MD);
-       pxa_gpio_mode(GPIO109_MMCDAT1_MD);
-       pxa_gpio_mode(GPIO110_MMCDAT2_MD);
-       pxa_gpio_mode(GPIO111_MMCDAT3_MD);
-
        err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, IRQF_DISABLED,
                             "MMC card detect", data);
        if (err)
@@ -333,8 +339,6 @@ static struct pxamci_platform_data pcm990_mci_platform_data = {
  */
 static int pcm990_ohci_init(struct device *dev)
 {
-       pxa_gpio_mode(PCM990_USB_OVERCURRENT);
-       pxa_gpio_mode(PCM990_USB_PWR_EN);
        /*
         * disable USB port 2 and 3
         * power sense is active low
@@ -361,23 +365,27 @@ static struct pxaohci_platform_data pcm990_ohci_platform_data = {
  * PXA27x Camera specific stuff
  */
 #if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
+static unsigned long pcm990_camera_pin_config[] = {
+       /* CIF */
+       GPIO98_CIF_DD_0,
+       GPIO105_CIF_DD_1,
+       GPIO104_CIF_DD_2,
+       GPIO103_CIF_DD_3,
+       GPIO95_CIF_DD_4,
+       GPIO94_CIF_DD_5,
+       GPIO93_CIF_DD_6,
+       GPIO108_CIF_DD_7,
+       GPIO107_CIF_DD_8,
+       GPIO106_CIF_DD_9,
+       GPIO42_CIF_MCLK,
+       GPIO45_CIF_PCLK,
+       GPIO43_CIF_FV,
+       GPIO44_CIF_LV,
+};
+
 static int pcm990_pxacamera_init(struct device *dev)
 {
-       pxa_gpio_mode(GPIO98_CIF_DD_0_MD);
-       pxa_gpio_mode(GPIO105_CIF_DD_1_MD);
-       pxa_gpio_mode(GPIO104_CIF_DD_2_MD);
-       pxa_gpio_mode(GPIO103_CIF_DD_3_MD);
-       pxa_gpio_mode(GPIO95_CIF_DD_4_MD);
-       pxa_gpio_mode(GPIO94_CIF_DD_5_MD);
-       pxa_gpio_mode(GPIO93_CIF_DD_6_MD);
-       pxa_gpio_mode(GPIO108_CIF_DD_7_MD);
-       pxa_gpio_mode(GPIO107_CIF_DD_8_MD);
-       pxa_gpio_mode(GPIO106_CIF_DD_9_MD);
-       pxa_gpio_mode(GPIO42_CIF_MCLK_MD);
-       pxa_gpio_mode(GPIO45_CIF_PCLK_MD);
-       pxa_gpio_mode(GPIO43_CIF_FV_MD);
-       pxa_gpio_mode(GPIO44_CIF_LV_MD);
-
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_camera_pin_config));
        return 0;
 }
 
@@ -449,8 +457,10 @@ static struct map_desc pcm990_io_desc[] __initdata = {
  */
 void __init pcm990_baseboard_init(void)
 {
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_pin_config));
+
        /* register CPLD access */
-       iotable_init(pcm990_io_desc, ARRAY_SIZE(pcm990_io_desc));
+       iotable_init(ARRAY_AND_SIZE(pcm990_io_desc));
 
        /* register CPLD's IRQ controller */
        pcm990_init_irq();
@@ -458,7 +468,6 @@ void __init pcm990_baseboard_init(void)
 #ifndef CONFIG_PCM990_DISPLAY_NONE
        set_pxa_fb_info(&pcm990_fbinfo);
 #endif
-       pxa_gpio_mode(GPIO16_PWM0_MD);
        platform_device_register(&pcm990_backlight_device);
 
        /* MMC */
@@ -473,9 +482,8 @@ void __init pcm990_baseboard_init(void)
 #if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
        pxa_set_camera_info(&pcm990_pxacamera_platform_data);
 
-       i2c_register_board_info(0, pcm990_i2c_devices,
-               ARRAY_SIZE(pcm990_i2c_devices));
+       i2c_register_board_info(0, ARRAY_AND_SIZE(pcm990_i2c_devices));
 #endif
 
-       printk(KERN_INFO"PCM-990 Evaluation baseboard initialized\n");
+       printk(KERN_INFO "PCM-990 Evaluation baseboard initialized\n");
 }
index f81c10cafd485760f10fb30c1988533a1973f0b2..39612cfa0b4d79191f523b6e2dbb0c1855eddcfb 100644 (file)
@@ -267,6 +267,7 @@ static void poodle_irda_transceiver_mode(struct device *dev, int mode)
        } else {
                GPCR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
        }
+       pxa2xx_transceiver_mode(dev, mode);
 }
 
 static struct pxaficp_platform_data poodle_ficp_platform_data = {
index 4cd50e3005e90d6e538e3d8f412db149b8cc2169..c5b845b935bb6f5122826507bf640b2deb87e61e 100644 (file)
@@ -109,6 +109,52 @@ static const struct clkops clk_pxa25x_lcd_ops = {
        .getrate        = clk_pxa25x_lcd_getrate,
 };
 
+static unsigned long gpio12_config_32k[] = {
+       GPIO12_32KHz,
+};
+
+static unsigned long gpio12_config_gpio[] = {
+       GPIO12_GPIO,
+};
+
+static void clk_gpio12_enable(struct clk *clk)
+{
+       pxa2xx_mfp_config(gpio12_config_32k, 1);
+}
+
+static void clk_gpio12_disable(struct clk *clk)
+{
+       pxa2xx_mfp_config(gpio12_config_gpio, 1);
+}
+
+static const struct clkops clk_pxa25x_gpio12_ops = {
+       .enable         = clk_gpio12_enable,
+       .disable        = clk_gpio12_disable,
+};
+
+static unsigned long gpio11_config_3m6[] = {
+       GPIO11_3_6MHz,
+};
+
+static unsigned long gpio11_config_gpio[] = {
+       GPIO11_GPIO,
+};
+
+static void clk_gpio11_enable(struct clk *clk)
+{
+       pxa2xx_mfp_config(gpio11_config_3m6, 1);
+}
+
+static void clk_gpio11_disable(struct clk *clk)
+{
+       pxa2xx_mfp_config(gpio11_config_gpio, 1);
+}
+
+static const struct clkops clk_pxa25x_gpio11_ops = {
+       .enable         = clk_gpio11_enable,
+       .disable        = clk_gpio11_disable,
+};
+
 /*
  * 3.6864MHz -> OST, GPIO, SSP, PWM, PLLs (95.842MHz, 147.456MHz)
  * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz
@@ -128,6 +174,8 @@ static struct clk pxa25x_clks[] = {
        INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev),
        INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL),
        INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa25x_device_udc.dev),
+       INIT_CLK("GPIO11_CLK", &clk_pxa25x_gpio11_ops, 3686400, 0, NULL),
+       INIT_CLK("GPIO12_CLK", &clk_pxa25x_gpio12_ops, 32768, 0, NULL),
        INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev),
        INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev),
 
@@ -145,7 +193,10 @@ static struct clk pxa25x_clks[] = {
        INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL),
 };
 
-static struct clk gpio7_clk = INIT_CKOTHER("GPIO7_CK", &pxa25x_clks[4], NULL);
+static struct clk pxa2xx_clk_aliases[] = {
+       INIT_CKOTHER("GPIO7_CLK", &pxa25x_clks[4], NULL),
+       INIT_CKOTHER("SA1111_CLK", &pxa25x_clks[5], NULL),
+};
 
 #ifdef CONFIG_PM
 
@@ -293,7 +344,7 @@ static int __init pxa25x_init(void)
        int i, ret = 0;
 
        /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
-       if (cpu_is_pxa25x())
+       if (cpu_is_pxa255())
                clks_register(&pxa25x_hwuart_clk, 1);
 
        if (cpu_is_pxa21x() || cpu_is_pxa25x()) {
@@ -317,10 +368,10 @@ static int __init pxa25x_init(void)
        }
 
        /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
-       if (cpu_is_pxa25x())
+       if (cpu_is_pxa255())
                ret = platform_device_register(&pxa_device_hwuart);
 
-       clks_register(&gpio7_clk, 1);
+       clks_register(pxa2xx_clk_aliases, ARRAY_SIZE(pxa2xx_clk_aliases));
 
        return ret;
 }
index 0a0d3877f2125e65fa09db0aba2f401c080291fa..da92e9733886432edc3b38cfccceeac898ce45df 100644 (file)
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/platform_device.h>
 
 #include <asm/hardware.h>
+#include <asm/arch/pxa3xx-regs.h>
 #include <asm/arch/mfp-pxa300.h>
 
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
 static struct pxa3xx_mfp_addr_map pxa300_mfp_addr_map[] __initdata = {
 
        MFP_ADDR_X(GPIO0,   GPIO2,   0x00b4),
@@ -79,15 +85,26 @@ static struct pxa3xx_mfp_addr_map pxa310_mfp_addr_map[] __initdata = {
        MFP_ADDR_END,
 };
 
+static struct clk common_clks[] = {
+       PXA3xx_CKEN("NANDCLK", NAND, 156000000, 0, &pxa3xx_device_nand.dev),
+};
+
+static struct clk pxa310_clks[] = {
+       PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev),
+};
+
 static int __init pxa300_init(void)
 {
        if (cpu_is_pxa300() || cpu_is_pxa310()) {
                pxa3xx_init_mfp();
                pxa3xx_mfp_init_addr(pxa300_mfp_addr_map);
+               clks_register(ARRAY_AND_SIZE(common_clks));
        }
 
-       if (cpu_is_pxa310())
+       if (cpu_is_pxa310()) {
                pxa3xx_mfp_init_addr(pxa310_mfp_addr_map);
+               clks_register(ARRAY_AND_SIZE(pxa310_clks));
+       }
 
        return 0;
 }
index 74128eb8f8d0dd5983585c89203e45410e53cfbc..c557c23a1efeaa9cc5e00b0b5f140f78ca340d94 100644 (file)
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/platform_device.h>
 
 #include <asm/hardware.h>
 #include <asm/arch/mfp.h>
+#include <asm/arch/pxa3xx-regs.h>
 #include <asm/arch/mfp-pxa320.h>
 
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
 static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
 
        MFP_ADDR_X(GPIO0,  GPIO4,   0x0124),
@@ -74,16 +80,17 @@ static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
        MFP_ADDR_END,
 };
 
-static void __init pxa320_init_mfp(void)
-{
-       pxa3xx_init_mfp();
-       pxa3xx_mfp_init_addr(pxa320_mfp_addr_map);
-}
+static struct clk pxa320_clks[] = {
+       PXA3xx_CKEN("NANDCLK", NAND, 104000000, 0, &pxa3xx_device_nand.dev),
+};
 
 static int __init pxa320_init(void)
 {
-       if (cpu_is_pxa320())
-               pxa320_init_mfp();
+       if (cpu_is_pxa320()) {
+               pxa3xx_init_mfp();
+               pxa3xx_mfp_init_addr(pxa320_mfp_addr_map);
+               clks_register(ARRAY_AND_SIZE(pxa320_clks));
+       }
 
        return 0;
 }
index 15685d2b8f8ce4187a970b0f181ba90fc8ba613b..f491025a0c82c41873bf404494d8a64a35216d28 100644 (file)
@@ -144,7 +144,7 @@ static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk)
        return hsio_clk;
 }
 
-static void clk_pxa3xx_cken_enable(struct clk *clk)
+void clk_pxa3xx_cken_enable(struct clk *clk)
 {
        unsigned long mask = 1ul << (clk->cken & 0x1f);
 
@@ -154,7 +154,7 @@ static void clk_pxa3xx_cken_enable(struct clk *clk)
                CKENB |= mask;
 }
 
-static void clk_pxa3xx_cken_disable(struct clk *clk)
+void clk_pxa3xx_cken_disable(struct clk *clk)
 {
        unsigned long mask = 1ul << (clk->cken & 0x1f);
 
@@ -164,7 +164,7 @@ static void clk_pxa3xx_cken_disable(struct clk *clk)
                CKENB &= ~mask;
 }
 
-static const struct clkops clk_pxa3xx_cken_ops = {
+const struct clkops clk_pxa3xx_cken_ops = {
        .enable         = clk_pxa3xx_cken_enable,
        .disable        = clk_pxa3xx_cken_disable,
 };
@@ -196,24 +196,6 @@ static const struct clkops clk_pout_ops = {
        .disable        = clk_pout_disable,
 };
 
-#define PXA3xx_CKEN(_name, _cken, _rate, _delay, _dev) \
-       {                                               \
-               .name   = _name,                        \
-               .dev    = _dev,                         \
-               .ops    = &clk_pxa3xx_cken_ops,         \
-               .rate   = _rate,                        \
-               .cken   = CKEN_##_cken,                 \
-               .delay  = _delay,                       \
-       }
-
-#define PXA3xx_CK(_name, _cken, _ops, _dev)            \
-       {                                               \
-               .name   = _name,                        \
-               .dev    = _dev,                         \
-               .ops    = _ops,                         \
-               .cken   = CKEN_##_cken,                 \
-       }
-
 static struct clk pxa3xx_clks[] = {
        {
                .name           = "CLK_POUT",
@@ -244,7 +226,6 @@ static struct clk pxa3xx_clks[] = {
 
        PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev),
        PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev),
-       PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev),
 };
 
 #ifdef CONFIG_PM
diff --git a/arch/arm/mach-pxa/pxa930.c b/arch/arm/mach-pxa/pxa930.c
new file mode 100644 (file)
index 0000000..9503897
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa930.c
+ *
+ * Code specific to PXA930
+ *
+ * Copyright (C) 2007-2008 Marvell Internation Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/mfp-pxa930.h>
+
+static struct pxa3xx_mfp_addr_map pxa930_mfp_addr_map[] __initdata = {
+
+       MFP_ADDR(GPIO0, 0x02e0),
+       MFP_ADDR(GPIO1, 0x02dc),
+       MFP_ADDR(GPIO2, 0x02e8),
+       MFP_ADDR(GPIO3, 0x02d8),
+       MFP_ADDR(GPIO4, 0x02e4),
+       MFP_ADDR(GPIO5, 0x02ec),
+       MFP_ADDR(GPIO6, 0x02f8),
+       MFP_ADDR(GPIO7, 0x02fc),
+       MFP_ADDR(GPIO8, 0x0300),
+       MFP_ADDR(GPIO9, 0x02d4),
+       MFP_ADDR(GPIO10, 0x02f4),
+       MFP_ADDR(GPIO11, 0x02f0),
+       MFP_ADDR(GPIO12, 0x0304),
+       MFP_ADDR(GPIO13, 0x0310),
+       MFP_ADDR(GPIO14, 0x0308),
+       MFP_ADDR(GPIO15, 0x030c),
+       MFP_ADDR(GPIO16, 0x04e8),
+       MFP_ADDR(GPIO17, 0x04f4),
+       MFP_ADDR(GPIO18, 0x04f8),
+       MFP_ADDR(GPIO19, 0x04fc),
+       MFP_ADDR(GPIO20, 0x0518),
+       MFP_ADDR(GPIO21, 0x051c),
+       MFP_ADDR(GPIO22, 0x04ec),
+       MFP_ADDR(GPIO23, 0x0500),
+       MFP_ADDR(GPIO24, 0x04f0),
+       MFP_ADDR(GPIO25, 0x0504),
+       MFP_ADDR(GPIO26, 0x0510),
+       MFP_ADDR(GPIO27, 0x0514),
+       MFP_ADDR(GPIO28, 0x0520),
+       MFP_ADDR(GPIO29, 0x0600),
+       MFP_ADDR(GPIO30, 0x0618),
+       MFP_ADDR(GPIO31, 0x0610),
+       MFP_ADDR(GPIO32, 0x060c),
+       MFP_ADDR(GPIO33, 0x061c),
+       MFP_ADDR(GPIO34, 0x0620),
+       MFP_ADDR(GPIO35, 0x0628),
+       MFP_ADDR(GPIO36, 0x062c),
+       MFP_ADDR(GPIO37, 0x0630),
+       MFP_ADDR(GPIO38, 0x0634),
+       MFP_ADDR(GPIO39, 0x0638),
+       MFP_ADDR(GPIO40, 0x063c),
+       MFP_ADDR(GPIO41, 0x0614),
+       MFP_ADDR(GPIO42, 0x0624),
+       MFP_ADDR(GPIO43, 0x0608),
+       MFP_ADDR(GPIO44, 0x0604),
+       MFP_ADDR(GPIO45, 0x050c),
+       MFP_ADDR(GPIO46, 0x0508),
+       MFP_ADDR(GPIO47, 0x02bc),
+       MFP_ADDR(GPIO48, 0x02b4),
+       MFP_ADDR(GPIO49, 0x02b8),
+       MFP_ADDR(GPIO50, 0x02c8),
+       MFP_ADDR(GPIO51, 0x02c0),
+       MFP_ADDR(GPIO52, 0x02c4),
+       MFP_ADDR(GPIO53, 0x02d0),
+       MFP_ADDR(GPIO54, 0x02cc),
+       MFP_ADDR(GPIO55, 0x029c),
+       MFP_ADDR(GPIO56, 0x02a0),
+       MFP_ADDR(GPIO57, 0x0294),
+       MFP_ADDR(GPIO58, 0x0298),
+       MFP_ADDR(GPIO59, 0x02a4),
+       MFP_ADDR(GPIO60, 0x02a8),
+       MFP_ADDR(GPIO61, 0x02b0),
+       MFP_ADDR(GPIO62, 0x02ac),
+       MFP_ADDR(GPIO63, 0x0640),
+       MFP_ADDR(GPIO64, 0x065c),
+       MFP_ADDR(GPIO65, 0x0648),
+       MFP_ADDR(GPIO66, 0x0644),
+       MFP_ADDR(GPIO67, 0x0674),
+       MFP_ADDR(GPIO68, 0x0658),
+       MFP_ADDR(GPIO69, 0x0654),
+       MFP_ADDR(GPIO70, 0x0660),
+       MFP_ADDR(GPIO71, 0x0668),
+       MFP_ADDR(GPIO72, 0x0664),
+       MFP_ADDR(GPIO73, 0x0650),
+       MFP_ADDR(GPIO74, 0x066c),
+       MFP_ADDR(GPIO75, 0x064c),
+       MFP_ADDR(GPIO76, 0x0670),
+       MFP_ADDR(GPIO77, 0x0678),
+       MFP_ADDR(GPIO78, 0x067c),
+       MFP_ADDR(GPIO79, 0x0694),
+       MFP_ADDR(GPIO80, 0x069c),
+       MFP_ADDR(GPIO81, 0x06a0),
+       MFP_ADDR(GPIO82, 0x06a4),
+       MFP_ADDR(GPIO83, 0x0698),
+       MFP_ADDR(GPIO84, 0x06bc),
+       MFP_ADDR(GPIO85, 0x06b4),
+       MFP_ADDR(GPIO86, 0x06b0),
+       MFP_ADDR(GPIO87, 0x06c0),
+       MFP_ADDR(GPIO88, 0x06c4),
+       MFP_ADDR(GPIO89, 0x06ac),
+       MFP_ADDR(GPIO90, 0x0680),
+       MFP_ADDR(GPIO91, 0x0684),
+       MFP_ADDR(GPIO92, 0x0688),
+       MFP_ADDR(GPIO93, 0x0690),
+       MFP_ADDR(GPIO94, 0x068c),
+       MFP_ADDR(GPIO95, 0x06a8),
+       MFP_ADDR(GPIO96, 0x06b8),
+       MFP_ADDR(GPIO97, 0x0410),
+       MFP_ADDR(GPIO98, 0x0418),
+       MFP_ADDR(GPIO99, 0x041c),
+       MFP_ADDR(GPIO100, 0x0414),
+       MFP_ADDR(GPIO101, 0x0408),
+       MFP_ADDR(GPIO102, 0x0324),
+       MFP_ADDR(GPIO103, 0x040c),
+       MFP_ADDR(GPIO104, 0x0400),
+       MFP_ADDR(GPIO105, 0x0328),
+       MFP_ADDR(GPIO106, 0x0404),
+
+       MFP_ADDR(nXCVREN, 0x0204),
+       MFP_ADDR(DF_CLE_nOE, 0x020c),
+       MFP_ADDR(DF_nADV1_ALE, 0x0218),
+       MFP_ADDR(DF_SCLK_E, 0x0214),
+       MFP_ADDR(DF_SCLK_S, 0x0210),
+       MFP_ADDR(nBE0, 0x021c),
+       MFP_ADDR(nBE1, 0x0220),
+       MFP_ADDR(DF_nADV2_ALE, 0x0224),
+       MFP_ADDR(DF_INT_RnB, 0x0228),
+       MFP_ADDR(DF_nCS0, 0x022c),
+       MFP_ADDR(DF_nCS1, 0x0230),
+       MFP_ADDR(nLUA, 0x0254),
+       MFP_ADDR(nLLA, 0x0258),
+       MFP_ADDR(DF_nWE, 0x0234),
+       MFP_ADDR(DF_nRE_nOE, 0x0238),
+       MFP_ADDR(DF_ADDR0, 0x024c),
+       MFP_ADDR(DF_ADDR1, 0x0250),
+       MFP_ADDR(DF_ADDR2, 0x025c),
+       MFP_ADDR(DF_ADDR3, 0x0260),
+       MFP_ADDR(DF_IO0, 0x023c),
+       MFP_ADDR(DF_IO1, 0x0240),
+       MFP_ADDR(DF_IO2, 0x0244),
+       MFP_ADDR(DF_IO3, 0x0248),
+       MFP_ADDR(DF_IO4, 0x0264),
+       MFP_ADDR(DF_IO5, 0x0268),
+       MFP_ADDR(DF_IO6, 0x026c),
+       MFP_ADDR(DF_IO7, 0x0270),
+       MFP_ADDR(DF_IO8, 0x0274),
+       MFP_ADDR(DF_IO9, 0x0278),
+       MFP_ADDR(DF_IO10, 0x027c),
+       MFP_ADDR(DF_IO11, 0x0280),
+       MFP_ADDR(DF_IO12, 0x0284),
+       MFP_ADDR(DF_IO13, 0x0288),
+       MFP_ADDR(DF_IO14, 0x028c),
+       MFP_ADDR(DF_IO15, 0x0290),
+
+       MFP_ADDR(GSIM_UIO, 0x0314),
+       MFP_ADDR(GSIM_UCLK, 0x0318),
+       MFP_ADDR(GSIM_UDET, 0x031c),
+       MFP_ADDR(GSIM_nURST, 0x0320),
+
+       MFP_ADDR(PMIC_INT, 0x06c8),
+
+       MFP_ADDR(RDY, 0x0200),
+
+       MFP_ADDR_END,
+};
+
+static int __init pxa930_init(void)
+{
+       if (cpu_is_pxa930()) {
+               pxa3xx_init_mfp();
+               pxa3xx_mfp_init_addr(pxa930_mfp_addr_map);
+       }
+
+       return 0;
+}
+
+core_initcall(pxa930_init);
diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c
new file mode 100644 (file)
index 0000000..9d39dea
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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/delay.h>
+#include <linux/gpio.h>
+#include <asm/io.h>
+#include <asm/proc-fns.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa2xx-regs.h>
+
+static void do_hw_reset(void);
+
+static int reset_gpio = -1;
+
+int init_gpio_reset(int gpio)
+{
+       int rc;
+
+       rc = gpio_request(gpio, "reset generator");
+       if (rc) {
+               printk(KERN_ERR "Can't request reset_gpio\n");
+               goto out;
+       }
+
+       rc = gpio_direction_input(gpio);
+       if (rc) {
+               printk(KERN_ERR "Can't configure reset_gpio for input\n");
+               gpio_free(gpio);
+               goto out;
+       }
+
+out:
+       if (!rc)
+               reset_gpio = gpio;
+
+       return rc;
+}
+
+/*
+ * Trigger GPIO reset.
+ * This covers various types of logic connecting gpio pin
+ * to RESET pins (nRESET or GPIO_RESET):
+ */
+static void do_gpio_reset(void)
+{
+       BUG_ON(reset_gpio == -1);
+
+       /* drive it low */
+       gpio_direction_output(reset_gpio, 0);
+       mdelay(2);
+       /* rising edge or drive high */
+       gpio_set_value(reset_gpio, 1);
+       mdelay(2);
+       /* falling edge */
+       gpio_set_value(reset_gpio, 0);
+
+       /* give it some time */
+       mdelay(10);
+
+       WARN_ON(1);
+       /* fallback */
+       do_hw_reset();
+}
+
+static void do_hw_reset(void)
+{
+       /* Initialize the watchdog and let it fire */
+       OWER = OWER_WME;
+       OSSR = OSSR_M3;
+       OSMR3 = OSCR + 368640;  /* ... in 100 ms */
+}
+
+void arch_reset(char mode)
+{
+       if (cpu_is_pxa2xx())
+               RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
+       switch (mode) {
+       case 's':
+               /* Jump into ROM at address 0 */
+               cpu_reset(0);
+               break;
+       case 'h':
+               do_hw_reset();
+               break;
+       case 'g':
+               do_gpio_reset();
+               break;
+       }
+}
+
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c
new file mode 100644 (file)
index 0000000..d02bc6f
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ *  linux/arch/arm/mach-pxa/saar.c
+ *
+ *  Support for the Marvell PXA930 Handheld Platform (aka SAAR)
+ *
+ *  Copyright (C) 2007-2008 Marvell International Ltd.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware.h>
+#include <asm/arch/pxa3xx-regs.h>
+#include <asm/arch/mfp-pxa930.h>
+
+#include "devices.h"
+#include "generic.h"
+
+/* SAAR MFP configurations */
+static mfp_cfg_t saar_mfp_cfg[] __initdata = {
+       /* Ethernet */
+       DF_nCS1_nCS3,
+       GPIO97_GPIO,
+};
+
+#define SAAR_ETH_PHYS  (0x14000000)
+
+static struct resource smc91x_resources[] = {
+       [0] = {
+               .start  = (SAAR_ETH_PHYS + 0x300),
+               .end    = (SAAR_ETH_PHYS + 0xfffff),
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)),
+               .end    = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)),
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+       }
+};
+
+static struct smc91x_platdata saar_smc91x_info = {
+       .flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_USE_DMA,
+};
+
+static struct platform_device smc91x_device = {
+       .name           = "smc91x",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(smc91x_resources),
+       .resource       = smc91x_resources,
+       .dev            = {
+               .platform_data = &saar_smc91x_info,
+       },
+};
+
+static void __init saar_init(void)
+{
+       /* initialize MFP configurations */
+       pxa3xx_mfp_config(ARRAY_AND_SIZE(saar_mfp_cfg));
+
+       platform_device_register(&smc91x_device);
+}
+
+MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)")
+       /* Maintainer: Eric Miao <eric.miao@marvell.com> */
+       .phys_io        = 0x40000000,
+       .boot_params    = 0xa0000100,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa3xx_init_irq,
+       .timer          = &pxa_timer,
+       .init_machine   = saar_init,
+MACHINE_END
index e7d0fcd9b43ffbb2c749fe139b8649090e1e8ada..762249c03ded4e5d9311513e96b9b260e0dbc2a4 100644 (file)
@@ -38,6 +38,7 @@
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/pxa2xx-regs.h>
 #include <asm/arch/pxa2xx-gpio.h>
+#include <asm/arch/pxa27x-udc.h>
 #include <asm/arch/irda.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/ohci.h>
@@ -450,6 +451,7 @@ static void spitz_irda_transceiver_mode(struct device *dev, int mode)
                set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
        else
                reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
+       pxa2xx_transceiver_mode(dev, mode);
 }
 
 #ifdef CONFIG_MACH_AKITA
@@ -459,6 +461,7 @@ static void akita_irda_transceiver_mode(struct device *dev, int mode)
                akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON);
        else
                akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON);
+       pxa2xx_transceiver_mode(dev, mode);
 }
 #endif
 
@@ -529,11 +532,7 @@ static struct platform_device *devices[] __initdata = {
 
 static void spitz_poweroff(void)
 {
-       pxa_gpio_mode(SPITZ_GPIO_ON_RESET | GPIO_OUT);
-       GPSR(SPITZ_GPIO_ON_RESET) = GPIO_bit(SPITZ_GPIO_ON_RESET);
-
-       mdelay(1000);
-       arm_machine_restart('h');
+       arm_machine_restart('g');
 }
 
 static void spitz_restart(char mode)
@@ -547,6 +546,7 @@ static void spitz_restart(char mode)
 
 static void __init common_init(void)
 {
+       init_gpio_reset(SPITZ_GPIO_ON_RESET);
        pm_power_off = spitz_poweroff;
        arm_pm_restart = spitz_restart;
 
index 0bb31982fb6f1b5b5ffb7d89e8a3bee28284c101..89f38683787eaded0b2c30e417a96f9c86b6eeea 100644 (file)
  *  IO-based SSP applications and allows easy port setup for DMA access.
  *
  *  Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
- *
- *  Revision history:
- *   22nd Aug 2003 Initial version.
- *   20th Dec 2004 Added ssp_config for changing port config without
- *                 closing the port.
- *    4th Aug 2005 Added option to disable irq handler registration and
- *                 cleaned up irq and clock detection.
  */
 
 #include <linux/module.h>
@@ -285,7 +278,7 @@ int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags)
                        goto out_region;
                dev->irq = ssp->irq;
        } else
-               dev->irq = 0;
+               dev->irq = NO_IRQ;
 
        /* turn on SSP port clock */
        clk_enable(ssp->clk);
@@ -306,7 +299,8 @@ void ssp_exit(struct ssp_dev *dev)
        struct ssp_device *ssp = dev->ssp;
 
        ssp_disable(dev);
-       free_irq(dev->irq, dev);
+       if (dev->irq != NO_IRQ)
+               free_irq(dev->irq, dev);
        clk_disable(ssp->clk);
        ssp_free(ssp);
 }
@@ -360,6 +354,7 @@ static int __devinit ssp_probe(struct platform_device *pdev, int type)
                dev_err(&pdev->dev, "failed to allocate memory");
                return -ENOMEM;
        }
+       ssp->pdev = pdev;
 
        ssp->clk = clk_get(&pdev->dev, "SSPCLK");
        if (IS_ERR(ssp->clk)) {
diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c
new file mode 100644 (file)
index 0000000..ac28350
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ *  linux/arch/arm/mach-pxa/tavorevb.c
+ *
+ *  Support for the Marvell PXA930 Evaluation Board
+ *
+ *  Copyright (C) 2007-2008 Marvell International Ltd.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware.h>
+#include <asm/arch/pxa3xx-regs.h>
+#include <asm/arch/mfp-pxa930.h>
+
+#include "devices.h"
+#include "generic.h"
+
+/* Tavor EVB MFP configurations */
+static mfp_cfg_t tavorevb_mfp_cfg[] __initdata = {
+       /* Ethernet */
+       DF_nCS1_nCS3,
+       GPIO47_GPIO,
+};
+
+#define TAVOREVB_ETH_PHYS      (0x14000000)
+
+static struct resource smc91x_resources[] = {
+       [0] = {
+               .start  = (TAVOREVB_ETH_PHYS + 0x300),
+               .end    = (TAVOREVB_ETH_PHYS + 0xfffff),
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO47)),
+               .end    = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO47)),
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+       }
+};
+
+static struct smc91x_platdata tavorevb_smc91x_info = {
+       .flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_USE_DMA,
+};
+
+static struct platform_device smc91x_device = {
+       .name           = "smc91x",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(smc91x_resources),
+       .resource       = smc91x_resources,
+       .dev            = {
+               .platform_data = &tavorevb_smc91x_info,
+       },
+};
+
+static void __init tavorevb_init(void)
+{
+       /* initialize MFP configurations */
+       pxa3xx_mfp_config(ARRAY_AND_SIZE(tavorevb_mfp_cfg));
+
+       platform_device_register(&smc91x_device);
+}
+
+MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)")
+       /* Maintainer: Eric Miao <eric.miao@marvell.com> */
+       .phys_io        = 0x40000000,
+       .boot_params    = 0xa0000100,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa3xx_init_irq,
+       .timer          = &pxa_timer,
+       .init_machine   = tavorevb_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c
new file mode 100644 (file)
index 0000000..7d85054
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Bluetooth built-in chip control
+ *
+ * Copyright (c) 2008 Dmitry Baryshkov
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/rfkill.h>
+
+#include <asm/arch/tosa_bt.h>
+
+static void tosa_bt_on(struct tosa_bt_data *data)
+{
+       gpio_set_value(data->gpio_reset, 0);
+       gpio_set_value(data->gpio_pwr, 1);
+       gpio_set_value(data->gpio_reset, 1);
+       mdelay(20);
+       gpio_set_value(data->gpio_reset, 0);
+}
+
+static void tosa_bt_off(struct tosa_bt_data *data)
+{
+       gpio_set_value(data->gpio_reset, 1);
+       mdelay(10);
+       gpio_set_value(data->gpio_pwr, 0);
+       gpio_set_value(data->gpio_reset, 0);
+}
+
+static int tosa_bt_toggle_radio(void *data, enum rfkill_state state)
+{
+       pr_info("BT_RADIO going: %s\n",
+                       state == RFKILL_STATE_ON ? "on" : "off");
+
+       if (state == RFKILL_STATE_ON) {
+               pr_info("TOSA_BT: going ON\n");
+               tosa_bt_on(data);
+       } else {
+               pr_info("TOSA_BT: going OFF\n");
+               tosa_bt_off(data);
+       }
+       return 0;
+}
+
+static int tosa_bt_probe(struct platform_device *dev)
+{
+       int rc;
+       struct rfkill *rfk;
+
+       struct tosa_bt_data *data = dev->dev.platform_data;
+
+       rc = gpio_request(data->gpio_reset, "Bluetooth reset");
+       if (rc)
+               goto err_reset;
+       rc = gpio_direction_output(data->gpio_reset, 0);
+       if (rc)
+               goto err_reset_dir;
+       rc = gpio_request(data->gpio_pwr, "Bluetooth power");
+       if (rc)
+               goto err_pwr;
+       rc = gpio_direction_output(data->gpio_pwr, 0);
+       if (rc)
+               goto err_pwr_dir;
+
+       rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH);
+       if (!rfk) {
+               rc = -ENOMEM;
+               goto err_rfk_alloc;
+       }
+
+       rfk->name = "tosa-bt";
+       rfk->toggle_radio = tosa_bt_toggle_radio;
+       rfk->data = data;
+#ifdef CONFIG_RFKILL_LEDS
+       rfk->led_trigger.name = "tosa-bt";
+#endif
+
+       rc = rfkill_register(rfk);
+       if (rc)
+               goto err_rfkill;
+
+       platform_set_drvdata(dev, rfk);
+
+       return 0;
+
+err_rfkill:
+       if (rfk)
+               rfkill_free(rfk);
+       rfk = NULL;
+err_rfk_alloc:
+       tosa_bt_off(data);
+err_pwr_dir:
+       gpio_free(data->gpio_pwr);
+err_pwr:
+err_reset_dir:
+       gpio_free(data->gpio_reset);
+err_reset:
+       return rc;
+}
+
+static int __devexit tosa_bt_remove(struct platform_device *dev)
+{
+       struct tosa_bt_data *data = dev->dev.platform_data;
+       struct rfkill *rfk = platform_get_drvdata(dev);
+
+       platform_set_drvdata(dev, NULL);
+
+       if (rfk)
+               rfkill_unregister(rfk);
+       rfk = NULL;
+
+       tosa_bt_off(data);
+
+       gpio_free(data->gpio_pwr);
+       gpio_free(data->gpio_reset);
+
+       return 0;
+}
+
+static struct platform_driver tosa_bt_driver = {
+       .probe = tosa_bt_probe,
+       .remove = __devexit_p(tosa_bt_remove),
+
+       .driver = {
+               .name = "tosa-bt",
+               .owner = THIS_MODULE,
+       },
+};
+
+
+static int __init tosa_bt_init(void)
+{
+       return platform_driver_register(&tosa_bt_driver);
+}
+
+static void __exit tosa_bt_exit(void)
+{
+       platform_driver_unregister(&tosa_bt_driver);
+}
+
+module_init(tosa_bt_init);
+module_exit(tosa_bt_exit);
index ab4a9f57991352c82a5520701ceca365a66f21fc..fea17ce6b55f5a812fa5f89e57cf851fc78850c5 100644 (file)
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
 #include <linux/mmc/host.h>
+#include <linux/mfd/tc6393xb.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
 #include <linux/pm.h>
-#include <linux/delay.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/gpio.h>
+#include <linux/pda_power.h>
+#include <linux/rfkill.h>
 
 #include <asm/setup.h>
-#include <asm/memory.h>
 #include <asm/mach-types.h>
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/arch/pxa-regs.h>
 #include <asm/arch/pxa2xx-regs.h>
 #include <asm/arch/mfp-pxa25x.h>
 #include <asm/arch/irda.h>
 #include <asm/arch/i2c.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/udc.h>
+#include <asm/arch/tosa_bt.h>
 
 #include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
 #include <asm/arch/tosa.h>
 
 #include <asm/hardware/scoop.h>
@@ -86,7 +87,7 @@ static unsigned long tosa_pin_config[] = {
        GPIO6_MMC_CLK,
        GPIO8_MMC_CS0,
        GPIO9_GPIO, /* Detect */
-       // GPIO10 nSD_INT
+       GPIO10_GPIO, /* nSD_INT */
 
        /* CF */
        GPIO13_GPIO, /* CD_IRQ */
@@ -124,34 +125,34 @@ static unsigned long tosa_pin_config[] = {
        GPIO44_BTUART_CTS,
        GPIO45_BTUART_RTS,
 
-       /* IrDA */
-       GPIO46_STUART_RXD,
-       GPIO47_STUART_TXD,
-
        /* Keybd */
-       GPIO58_GPIO,
-       GPIO59_GPIO,
-       GPIO60_GPIO,
-       GPIO61_GPIO,
-       GPIO62_GPIO,
-       GPIO63_GPIO,
-       GPIO64_GPIO,
-       GPIO65_GPIO,
-       GPIO66_GPIO,
-       GPIO67_GPIO,
-       GPIO68_GPIO,
-       GPIO69_GPIO,
-       GPIO70_GPIO,
-       GPIO71_GPIO,
-       GPIO72_GPIO,
-       GPIO73_GPIO,
-       GPIO74_GPIO,
-       GPIO75_GPIO,
+       GPIO58_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO59_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO60_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO61_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO62_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO63_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO64_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO65_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO66_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO67_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO68_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO69_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO70_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO71_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO72_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO73_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO74_GPIO | MFP_LPM_DRIVE_LOW,
+       GPIO75_GPIO | MFP_LPM_DRIVE_LOW,
 
        /* SPI */
        GPIO81_SSP2_CLK_OUT,
        GPIO82_SSP2_FRM_OUT,
        GPIO83_SSP2_TXD,
+
+       /* IrDA is managed in other way */
+       GPIO46_GPIO,
+       GPIO47_GPIO,
 };
 
 /*
@@ -249,6 +250,15 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void
 
        tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
+       err = gpio_request(TOSA_GPIO_nSD_DETECT, "MMC/SD card detect");
+       if (err) {
+               printk(KERN_ERR "tosa_mci_init: can't request nSD_DETECT gpio\n");
+               goto err_gpio_detect;
+       }
+       err = gpio_direction_input(TOSA_GPIO_nSD_DETECT);
+       if (err)
+               goto err_gpio_detect_dir;
+
        err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int,
                          IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
                                "MMC/SD card detect", data);
@@ -257,7 +267,7 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void
                goto err_irq;
        }
 
-       err = gpio_request(TOSA_GPIO_SD_WP, "sd_wp");
+       err = gpio_request(TOSA_GPIO_SD_WP, "SD Write Protect");
        if (err) {
                printk(KERN_ERR "tosa_mci_init: can't request SD_WP gpio\n");
                goto err_gpio_wp;
@@ -266,7 +276,7 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void
        if (err)
                goto err_gpio_wp_dir;
 
-       err = gpio_request(TOSA_GPIO_PWR_ON, "sd_pwr");
+       err = gpio_request(TOSA_GPIO_PWR_ON, "SD Power");
        if (err) {
                printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n");
                goto err_gpio_pwr;
@@ -275,8 +285,20 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void
        if (err)
                goto err_gpio_pwr_dir;
 
+       err = gpio_request(TOSA_GPIO_nSD_INT, "SD Int");
+       if (err) {
+               printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n");
+               goto err_gpio_int;
+       }
+       err = gpio_direction_input(TOSA_GPIO_nSD_INT);
+       if (err)
+               goto err_gpio_int_dir;
+
        return 0;
 
+err_gpio_int_dir:
+       gpio_free(TOSA_GPIO_nSD_INT);
+err_gpio_int:
 err_gpio_pwr_dir:
        gpio_free(TOSA_GPIO_PWR_ON);
 err_gpio_pwr:
@@ -285,6 +307,9 @@ err_gpio_wp_dir:
 err_gpio_wp:
        free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
 err_irq:
+err_gpio_detect_dir:
+       gpio_free(TOSA_GPIO_nSD_DETECT);
+err_gpio_detect:
        return err;
 }
 
@@ -306,9 +331,11 @@ static int tosa_mci_get_ro(struct device *dev)
 
 static void tosa_mci_exit(struct device *dev, void *data)
 {
+       gpio_free(TOSA_GPIO_nSD_INT);
        gpio_free(TOSA_GPIO_PWR_ON);
        gpio_free(TOSA_GPIO_SD_WP);
        free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
+       gpio_free(TOSA_GPIO_nSD_DETECT);
 }
 
 static struct pxamci_platform_data tosa_mci_platform_data = {
@@ -322,29 +349,55 @@ static struct pxamci_platform_data tosa_mci_platform_data = {
 /*
  * Irda
  */
+static void tosa_irda_transceiver_mode(struct device *dev, int mode)
+{
+       if (mode & IR_OFF) {
+               gpio_set_value(TOSA_GPIO_IR_POWERDWN, 0);
+               pxa2xx_transceiver_mode(dev, mode);
+               gpio_direction_output(TOSA_GPIO_IRDA_TX, 0);
+       } else {
+               pxa2xx_transceiver_mode(dev, mode);
+               gpio_set_value(TOSA_GPIO_IR_POWERDWN, 1);
+       }
+}
+
 static int tosa_irda_startup(struct device *dev)
 {
        int ret;
 
+       ret = gpio_request(TOSA_GPIO_IRDA_TX, "IrDA TX");
+       if (ret)
+               goto err_tx;
+       ret = gpio_direction_output(TOSA_GPIO_IRDA_TX, 0);
+       if (ret)
+               goto err_tx_dir;
+
        ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown");
        if (ret)
-               return ret;
+               goto err_pwr;
 
        ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0);
        if (ret)
-               gpio_free(TOSA_GPIO_IR_POWERDWN);
+               goto err_pwr_dir;
 
-       return ret;
-       }
+       tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF);
 
-static void tosa_irda_shutdown(struct device *dev)
-{
+       return 0;
+
+err_pwr_dir:
        gpio_free(TOSA_GPIO_IR_POWERDWN);
+err_pwr:
+err_tx_dir:
+       gpio_free(TOSA_GPIO_IRDA_TX);
+err_tx:
+       return ret;
 }
 
-static void tosa_irda_transceiver_mode(struct device *dev, int mode)
+static void tosa_irda_shutdown(struct device *dev)
 {
-       gpio_set_value(TOSA_GPIO_IR_POWERDWN, !(mode & IR_OFF));
+       tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF);
+       gpio_free(TOSA_GPIO_IR_POWERDWN);
+       gpio_free(TOSA_GPIO_IRDA_TX);
 }
 
 static struct pxaficp_platform_data tosa_ficp_platform_data = {
@@ -354,6 +407,70 @@ static struct pxaficp_platform_data tosa_ficp_platform_data = {
        .shutdown = tosa_irda_shutdown,
 };
 
+/*
+ * Tosa AC IN
+ */
+static int tosa_power_init(struct device *dev)
+{
+       int ret = gpio_request(TOSA_GPIO_AC_IN, "ac in");
+       if (ret)
+               goto err_gpio_req;
+
+       ret = gpio_direction_input(TOSA_GPIO_AC_IN);
+       if (ret)
+               goto err_gpio_in;
+
+       return 0;
+
+err_gpio_in:
+       gpio_free(TOSA_GPIO_AC_IN);
+err_gpio_req:
+       return ret;
+}
+
+static void tosa_power_exit(struct device *dev)
+{
+       gpio_free(TOSA_GPIO_AC_IN);
+}
+
+static int tosa_power_ac_online(void)
+{
+       return gpio_get_value(TOSA_GPIO_AC_IN) == 0;
+}
+
+static char *tosa_ac_supplied_to[] = {
+       "main-battery",
+       "backup-battery",
+       "jacket-battery",
+};
+
+static struct pda_power_pdata tosa_power_data = {
+       .init                   = tosa_power_init,
+       .is_ac_online           = tosa_power_ac_online,
+       .exit                   = tosa_power_exit,
+       .supplied_to            = tosa_ac_supplied_to,
+       .num_supplicants        = ARRAY_SIZE(tosa_ac_supplied_to),
+};
+
+static struct resource tosa_power_resource[] = {
+       {
+               .name           = "ac",
+               .start          = gpio_to_irq(TOSA_GPIO_AC_IN),
+               .end            = gpio_to_irq(TOSA_GPIO_AC_IN),
+               .flags          = IORESOURCE_IRQ |
+                                 IORESOURCE_IRQ_HIGHEDGE |
+                                 IORESOURCE_IRQ_LOWEDGE,
+       },
+};
+
+static struct platform_device tosa_power_device = {
+       .name                   = "pda-power",
+       .id                     = -1,
+       .dev.platform_data      = &tosa_power_data,
+       .resource               = tosa_power_resource,
+       .num_resources          = ARRAY_SIZE(tosa_power_resource),
+};
+
 /*
  * Tosa Keyboard
  */
@@ -439,7 +556,7 @@ static struct gpio_led tosa_gpio_leds[] = {
        },
        {
                .name                   = "tosa:blue:bluetooth",
-               .default_trigger        = "none",
+               .default_trigger        = "tosa-bt",
                .gpio                   = TOSA_GPIO_BT_LED,
        },
 };
@@ -457,21 +574,184 @@ static struct platform_device tosaled_device = {
        },
 };
 
+/*
+ * Toshiba Mobile IO Controller
+ */
+static struct resource tc6393xb_resources[] = {
+       [0] = {
+               .start  = TOSA_LCDC_PHYS,
+               .end    = TOSA_LCDC_PHYS + 0x3ffffff,
+               .flags  = IORESOURCE_MEM,
+       },
+
+       [1] = {
+               .start  = TOSA_IRQ_GPIO_TC6393XB_INT,
+               .end    = TOSA_IRQ_GPIO_TC6393XB_INT,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+
+static int tosa_tc6393xb_enable(struct platform_device *dev)
+{
+       int rc;
+
+       rc = gpio_request(TOSA_GPIO_TC6393XB_REST_IN, "tc6393xb #pclr");
+       if (rc)
+               goto err_req_pclr;
+       rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend");
+       if (rc)
+               goto err_req_suspend;
+       rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "l3v");
+       if (rc)
+               goto err_req_l3v;
+       rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0);
+       if (rc)
+               goto err_dir_l3v;
+       rc = gpio_direction_output(TOSA_GPIO_TC6393XB_SUSPEND, 0);
+       if (rc)
+               goto err_dir_suspend;
+       rc = gpio_direction_output(TOSA_GPIO_TC6393XB_REST_IN, 0);
+       if (rc)
+               goto err_dir_pclr;
+
+       mdelay(1);
+
+       gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1);
+
+       mdelay(10);
+
+       gpio_set_value(TOSA_GPIO_TC6393XB_REST_IN, 1);
+       gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1);
+
+       return 0;
+err_dir_pclr:
+err_dir_suspend:
+err_dir_l3v:
+       gpio_free(TOSA_GPIO_TC6393XB_L3V_ON);
+err_req_l3v:
+       gpio_free(TOSA_GPIO_TC6393XB_SUSPEND);
+err_req_suspend:
+       gpio_free(TOSA_GPIO_TC6393XB_REST_IN);
+err_req_pclr:
+       return rc;
+}
+
+static int tosa_tc6393xb_disable(struct platform_device *dev)
+{
+       gpio_free(TOSA_GPIO_TC6393XB_L3V_ON);
+       gpio_free(TOSA_GPIO_TC6393XB_SUSPEND);
+       gpio_free(TOSA_GPIO_TC6393XB_REST_IN);
+
+       return 0;
+}
+
+static int tosa_tc6393xb_resume(struct platform_device *dev)
+{
+       gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1);
+       mdelay(10);
+       gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1);
+       mdelay(10);
+
+       return 0;
+}
+
+static int tosa_tc6393xb_suspend(struct platform_device *dev)
+{
+       gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 0);
+       gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 0);
+       return 0;
+}
+
+static struct mtd_partition tosa_nand_partition[] = {
+       {
+               .name   = "smf",
+               .offset = 0,
+               .size   = 7 * 1024 * 1024,
+       },
+       {
+               .name   = "root",
+               .offset = MTDPART_OFS_APPEND,
+               .size   = 28 * 1024 * 1024,
+       },
+       {
+               .name   = "home",
+               .offset = MTDPART_OFS_APPEND,
+               .size   = MTDPART_SIZ_FULL,
+       },
+};
+
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+
+static struct nand_bbt_descr tosa_tc6393xb_nand_bbt = {
+       .options        = 0,
+       .offs           = 4,
+       .len            = 2,
+       .pattern        = scan_ff_pattern
+};
+
+static struct tmio_nand_data tosa_tc6393xb_nand_config = {
+       .num_partitions = ARRAY_SIZE(tosa_nand_partition),
+       .partition      = tosa_nand_partition,
+       .badblock_pattern = &tosa_tc6393xb_nand_bbt,
+};
+
+static struct tc6393xb_platform_data tosa_tc6393xb_setup = {
+       .scr_pll2cr     = 0x0cc1,
+       .scr_gper       = 0x3300,
+       .scr_gpo_dsr    =
+               TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON),
+       .scr_gpo_doecr  =
+               TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON),
+
+       .irq_base       = IRQ_BOARD_START,
+       .gpio_base      = TOSA_TC6393XB_GPIO_BASE,
+
+       .enable         = tosa_tc6393xb_enable,
+       .disable        = tosa_tc6393xb_disable,
+       .suspend        = tosa_tc6393xb_suspend,
+       .resume         = tosa_tc6393xb_resume,
+
+       .nand_data      = &tosa_tc6393xb_nand_config,
+};
+
+
+static struct platform_device tc6393xb_device = {
+       .name   = "tc6393xb",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &tosa_tc6393xb_setup,
+       },
+       .num_resources  = ARRAY_SIZE(tc6393xb_resources),
+       .resource       = tc6393xb_resources,
+};
+
+static struct tosa_bt_data tosa_bt_data = {
+       .gpio_pwr       = TOSA_GPIO_BT_PWR_EN,
+       .gpio_reset     = TOSA_GPIO_BT_RESET,
+};
+
+static struct platform_device tosa_bt_device = {
+       .name   = "tosa-bt",
+       .id     = -1,
+       .dev.platform_data = &tosa_bt_data,
+};
+
+
 static struct platform_device *devices[] __initdata = {
        &tosascoop_device,
        &tosascoop_jc_device,
+       &tc6393xb_device,
+       &tosa_power_device,
        &tosakbd_device,
        &tosa_gpio_keys_device,
        &tosaled_device,
+       &tosa_bt_device,
 };
 
 static void tosa_poweroff(void)
 {
-       gpio_direction_output(TOSA_GPIO_ON_RESET, 0);
-       gpio_set_value(TOSA_GPIO_ON_RESET, 1);
-
-       mdelay(1000);
-       arm_machine_restart('h');
+       arm_machine_restart('g');
 }
 
 static void tosa_restart(char mode)
@@ -485,10 +765,14 @@ static void tosa_restart(char mode)
 
 static void __init tosa_init(void)
 {
+       int dummy;
+
        pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config));
        gpio_set_wake(MFP_PIN_GPIO1, 1);
        /* We can't pass to gpio-keys since it will drop the Reset altfunc */
 
+       init_gpio_reset(TOSA_GPIO_ON_RESET);
+
        pm_power_off = tosa_poweroff;
        arm_pm_restart = tosa_restart;
 
@@ -497,6 +781,10 @@ static void __init tosa_init(void)
        /* enable batt_fault */
        PMCR = 0x01;
 
+       dummy = gpiochip_reserve(TOSA_SCOOP_GPIO_BASE, 12);
+       dummy = gpiochip_reserve(TOSA_SCOOP_JC_GPIO_BASE, 12);
+       dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16);
+
        pxa_set_mci_info(&tosa_mci_platform_data);
        pxa_set_udc_info(&udc_info);
        pxa_set_ficp_info(&tosa_ficp_platform_data);
index 61e2440230896c2a056105629765af1eee47b52d..dee7bf36f013f76af3950eed48ecf299ec010fac 100644 (file)
@@ -254,6 +254,7 @@ static void board_irda_mode(struct device *dev, int mode)
                /* Fast mode */
                trizeps_conxs_ircr |= ConXS_IRCR_MODE;
        }
+       pxa2xx_transceiver_mode(dev, mode);
        if (mode & IR_OFF) {
                trizeps_conxs_ircr |= ConXS_IRCR_SD;
        } else {
index 66b446ca273dbbd06032207117153401ab046193..8fca6d890b7de5bd863b5c340bad375b31df10c5 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/pwm_backlight.h>
+#include <linux/smc91x.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -29,6 +30,7 @@
 #include <asm/arch/zylonite.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/pxa27x_keypad.h>
+#include <asm/arch/pxa3xx_nand.h>
 
 #include "devices.h"
 #include "generic.h"
@@ -37,6 +39,8 @@
 struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS];
 
 int gpio_eth_irq;
+int gpio_debug_led1;
+int gpio_debug_led2;
 
 int wm9713_irq;
 
@@ -56,13 +60,57 @@ static struct resource smc91x_resources[] = {
        }
 };
 
+static struct smc91x_platdata zylonite_smc91x_info = {
+       .flags  = SMC91X_USE_8BIT | SMC91X_USE_16BIT |
+                 SMC91X_NOWAIT | SMC91X_USE_DMA,
+};
+
 static struct platform_device smc91x_device = {
        .name           = "smc91x",
        .id             = 0,
        .num_resources  = ARRAY_SIZE(smc91x_resources),
        .resource       = smc91x_resources,
+       .dev            = {
+               .platform_data = &zylonite_smc91x_info,
+       },
+};
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static struct gpio_led zylonite_debug_leds[] = {
+       [0] = {
+               .name                   = "zylonite:yellow:1",
+               .default_trigger        = "heartbeat",
+       },
+       [1] = {
+               .name                   = "zylonite:yellow:2",
+               .default_trigger        = "default-on",
+       },
 };
 
+static struct gpio_led_platform_data zylonite_debug_leds_info = {
+       .leds           = zylonite_debug_leds,
+       .num_leds       = ARRAY_SIZE(zylonite_debug_leds),
+};
+
+static struct platform_device zylonite_device_leds = {
+       .name           = "leds-gpio",
+       .id             = -1,
+       .dev            = {
+               .platform_data = &zylonite_debug_leds_info,
+       }
+};
+
+static void __init zylonite_init_leds(void)
+{
+       zylonite_debug_leds[0].gpio = gpio_debug_led1;
+       zylonite_debug_leds[1].gpio = gpio_debug_led2;
+
+       platform_device_register(&zylonite_device_leds);
+}
+#else
+static inline void zylonite_init_leds(void) {}
+#endif
+
 #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
 static struct platform_pwm_backlight_data zylonite_backlight_data = {
        .pwm_id         = 3,
@@ -259,7 +307,7 @@ static void __init zylonite_init_mmc(void)
 static inline void zylonite_init_mmc(void) {}
 #endif
 
-#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULES)
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
 static unsigned int zylonite_matrix_key_map[] = {
        /* KEY(row, col, key_code) */
        KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_C), KEY(0, 5, KEY_D),
@@ -324,6 +372,57 @@ static void __init zylonite_init_keypad(void)
 static inline void zylonite_init_keypad(void) {}
 #endif
 
+#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+static struct mtd_partition zylonite_nand_partitions[] = {
+       [0] = {
+               .name        = "Bootloader",
+               .offset      = 0,
+               .size        = 0x060000,
+               .mask_flags  = MTD_WRITEABLE, /* force read-only */
+       },
+       [1] = {
+               .name        = "Kernel",
+               .offset      = 0x060000,
+               .size        = 0x200000,
+               .mask_flags  = MTD_WRITEABLE, /* force read-only */
+       },
+       [2] = {
+               .name        = "Filesystem",
+               .offset      = 0x0260000,
+               .size        = 0x3000000,     /* 48M - rootfs */
+       },
+       [3] = {
+               .name        = "MassStorage",
+               .offset      = 0x3260000,
+               .size        = 0x3d40000,
+       },
+       [4] = {
+               .name        = "BBT",
+               .offset      = 0x6FA0000,
+               .size        = 0x80000,
+               .mask_flags  = MTD_WRITEABLE,  /* force read-only */
+       },
+       /* NOTE: we reserve some blocks at the end of the NAND flash for
+        * bad block management, and the max number of relocation blocks
+        * differs on different platforms. Please take care with it when
+        * defining the partition table.
+        */
+};
+
+static struct pxa3xx_nand_platform_data zylonite_nand_info = {
+       .enable_arbiter = 1,
+       .parts          = zylonite_nand_partitions,
+       .nr_parts       = ARRAY_SIZE(zylonite_nand_partitions),
+};
+
+static void __init zylonite_init_nand(void)
+{
+       pxa3xx_set_nand_info(&zylonite_nand_info);
+}
+#else
+static inline void zylonite_init_nand(void) {}
+#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
+
 static void __init zylonite_init(void)
 {
        /* board-processor specific initialization */
@@ -342,6 +441,8 @@ static void __init zylonite_init(void)
        zylonite_init_lcd();
        zylonite_init_mmc();
        zylonite_init_keypad();
+       zylonite_init_nand();
+       zylonite_init_leds();
 }
 
 MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
index 6f7ae972b8db658e137b705ae5cc2df9602fa92e..b28d46e081d34e0d1a326e18ed4e74c74aed1882 100644 (file)
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
 
 #include <asm/gpio.h>
 #include <asm/arch/mfp-pxa300.h>
+#include <asm/arch/i2c.h>
 #include <asm/arch/zylonite.h>
 
 #include "generic.h"
@@ -109,6 +112,10 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = {
        GPIO12_MMC2_DAT3,
        GPIO13_MMC2_CLK,
        GPIO14_MMC2_CMD,
+
+       /* Standard I2C */
+       GPIO21_I2C_SCL,
+       GPIO22_I2C_SDA,
 };
 
 static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
@@ -192,6 +199,39 @@ static void __init zylonite_detect_lcd_panel(void)
                pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]);
 }
 
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static struct pca953x_platform_data gpio_exp[] = {
+       [0] = {
+               .gpio_base      = 128,
+       },
+       [1] = {
+               .gpio_base      = 144,
+       },
+};
+
+struct i2c_board_info zylonite_i2c_board_info[] = {
+       {
+               .type           = "pca9539",
+               .addr           = 0x74,
+               .platform_data  = &gpio_exp[0],
+               .irq            = IRQ_GPIO(18),
+       }, {
+               .type           = "pca9539",
+               .addr           = 0x75,
+               .platform_data  = &gpio_exp[1],
+               .irq            = IRQ_GPIO(19),
+       },
+};
+
+static void __init zylonite_init_i2c(void)
+{
+       pxa_set_i2c_info(NULL);
+       i2c_register_board_info(0, ARRAY_AND_SIZE(zylonite_i2c_board_info));
+}
+#else
+static inline void zylonite_init_i2c(void) {}
+#endif
+
 void __init zylonite_pxa300_init(void)
 {
        if (cpu_is_pxa300() || cpu_is_pxa310()) {
@@ -207,6 +247,8 @@ void __init zylonite_pxa300_init(void)
 
                /* WM9713 IRQ */
                wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO26);
+
+               zylonite_init_i2c();
        }
 
        if (cpu_is_pxa300()) {
@@ -222,4 +264,8 @@ void __init zylonite_pxa300_init(void)
                zylonite_mmc_slot[2].gpio_cd = EXT_GPIO(30);
                zylonite_mmc_slot[2].gpio_wp = EXT_GPIO(31);
        }
+
+       /* GPIOs for Debug LEDs */
+       gpio_debug_led1 = EXT_GPIO(25);
+       gpio_debug_led2 = EXT_GPIO(26);
 }
index 2b4fc34919ac3d59c54ef9b6be2fcb9d7f3c0f4d..2b7fba7a29211b0fcfa77af0db8ea26b1484ea4d 100644 (file)
@@ -116,6 +116,10 @@ static mfp_cfg_t mfp_cfg[] __initdata = {
        GPIO27_MMC2_DAT3,
        GPIO28_MMC2_CLK,
        GPIO29_MMC2_CMD,
+
+       /* Debug LEDs */
+       GPIO1_2_GPIO | MFP_LPM_DRIVE_HIGH,
+       GPIO4_2_GPIO | MFP_LPM_DRIVE_HIGH,
 };
 
 #define NUM_LCD_DETECT_PINS    7
@@ -189,6 +193,8 @@ void __init zylonite_pxa320_init(void)
 
                /* GPIO pin assignment */
                gpio_eth_irq    = mfp_to_gpio(MFP_PIN_GPIO9);
+               gpio_debug_led1 = mfp_to_gpio(MFP_PIN_GPIO1_2);
+               gpio_debug_led2 = mfp_to_gpio(MFP_PIN_GPIO4_2);
 
                /* MMC card detect & write protect for controller 0 */
                zylonite_mmc_slot[0].gpio_cd  = mfp_to_gpio(MFP_PIN_GPIO1);
index fc97fe57ee6feeb473ca4e178251db5c50b32617..b5809c51d13f60335965fdcfdd07ff7e11deb683 100644 (file)
@@ -103,7 +103,7 @@ static void clk_gpio27_disable(void)
 }
 
 static struct clk clk_gpio27 = {
-       .name           = "GPIO27_CLK",
+       .name           = "SA1111_CLK",
        .rate           = 3686400,
        .enable         = clk_gpio27_enable,
        .disable        = clk_gpio27_disable,
index f64b92557b11e82b8bebd08ff51b58d876182ab0..2e27a8c8372b0ffb3227cb8a3ceb9a5f67514693 100644 (file)
@@ -76,3 +76,5 @@ obj-$(CONFIG_CPU_V7)          += proc-v7.o
 
 obj-$(CONFIG_CACHE_FEROCEON_L2)        += cache-feroceon-l2.o
 obj-$(CONFIG_CACHE_L2X0)       += cache-l2x0.o
+obj-$(CONFIG_CACHE_XSC3L2)     += cache-xsc3l2.o
+
index 6f33f58bca4573184aaa7b5147b02d707ab6e496..ff1413eae0b84b73803c67754366e4ea09ea814f 100644 (file)
@@ -334,7 +334,7 @@ static int omap_mbox_init(struct omap_mbox *mbox)
        }
 
        mbox->dev.class = &omap_mbox_class;
-       strlcpy(mbox->dev.bus_id, mbox->name, KOBJ_NAME_LEN);
+       dev_set_name(&mbox->dev, "%s", mbox->name);
        dev_set_drvdata(&mbox->dev, mbox);
 
        ret = device_register(&mbox->dev);
index 0be5630ff568fe77780a88b64fc0b5c87c3a0cec..8b8f564c3aa25a5c59dea10c2c96fec47e54b349 100644 (file)
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Mon Jul 7 16:25:39 2008
+# Last update: Sun Jul 13 12:04:05 2008
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -1812,3 +1812,11 @@ jade                     MACH_JADE               JADE                    1821
 ks8695_softplc         MACH_KS8695_SOFTPLC     KS8695_SOFTPLC          1822
 gprisc4                        MACH_GPRISC4            GPRISC4                 1823
 stamp9260              MACH_STAMP9260          STAMP9260               1824
+smdk6430               MACH_SMDK6430           SMDK6430                1825
+smdkc100               MACH_SMDKC100           SMDKC100                1826
+tavorevb               MACH_TAVOREVB           TAVOREVB                1827
+saar                   MACH_SAAR               SAAR                    1828
+deister_eyecam         MACH_DEISTER_EYECAM     DEISTER_EYECAM          1829
+at91sam9m10ek          MACH_AT91SAM9M10EK      AT91SAM9M10EK           1830
+linkstation_produo     MACH_LINKSTATION_PRODUO LINKSTATION_PRODUO      1831
+hit_b0                 MACH_HIT_B0             HIT_B0                  1832
index b8409caeb23dccbca394127132bcdcc9e0360eab..e84faffbbecae2df573796128243947028a556a6 100644 (file)
@@ -26,14 +26,16 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
  * XXX: If/when a SMP-capable implementation of AVR32 will ever be
  * made, we must make sure that the code executes on the correct CPU.
  */
-static ssize_t show_pc0event(struct sys_device *dev, char *buf)
+static ssize_t show_pc0event(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        unsigned long pccr;
 
        pccr = sysreg_read(PCCR);
        return sprintf(buf, "0x%lx\n", (pccr >> 12) & 0x3f);
 }
-static ssize_t store_pc0event(struct sys_device *dev, const char *buf,
+static ssize_t store_pc0event(struct sys_device *dev,
+                       struct sysdev_attribute *attr, const char *buf,
                              size_t count)
 {
        unsigned long val;
@@ -46,15 +48,17 @@ static ssize_t store_pc0event(struct sys_device *dev, const char *buf,
        sysreg_write(PCCR, val);
        return count;
 }
-static ssize_t show_pc0count(struct sys_device *dev, char *buf)
+static ssize_t show_pc0count(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        unsigned long pcnt0;
 
        pcnt0 = sysreg_read(PCNT0);
        return sprintf(buf, "%lu\n", pcnt0);
 }
-static ssize_t store_pc0count(struct sys_device *dev, const char *buf,
-                             size_t count)
+static ssize_t store_pc0count(struct sys_device *dev,
+                               struct sysdev_attribute *attr,
+                               const char *buf, size_t count)
 {
        unsigned long val;
        char *endp;
@@ -67,14 +71,16 @@ static ssize_t store_pc0count(struct sys_device *dev, const char *buf,
        return count;
 }
 
-static ssize_t show_pc1event(struct sys_device *dev, char *buf)
+static ssize_t show_pc1event(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        unsigned long pccr;
 
        pccr = sysreg_read(PCCR);
        return sprintf(buf, "0x%lx\n", (pccr >> 18) & 0x3f);
 }
-static ssize_t store_pc1event(struct sys_device *dev, const char *buf,
+static ssize_t store_pc1event(struct sys_device *dev,
+                             struct sysdev_attribute *attr, const char *buf,
                              size_t count)
 {
        unsigned long val;
@@ -87,14 +93,16 @@ static ssize_t store_pc1event(struct sys_device *dev, const char *buf,
        sysreg_write(PCCR, val);
        return count;
 }
-static ssize_t show_pc1count(struct sys_device *dev, char *buf)
+static ssize_t show_pc1count(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        unsigned long pcnt1;
 
        pcnt1 = sysreg_read(PCNT1);
        return sprintf(buf, "%lu\n", pcnt1);
 }
-static ssize_t store_pc1count(struct sys_device *dev, const char *buf,
+static ssize_t store_pc1count(struct sys_device *dev,
+                               struct sysdev_attribute *attr, const char *buf,
                              size_t count)
 {
        unsigned long val;
@@ -108,14 +116,16 @@ static ssize_t store_pc1count(struct sys_device *dev, const char *buf,
        return count;
 }
 
-static ssize_t show_pccycles(struct sys_device *dev, char *buf)
+static ssize_t show_pccycles(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        unsigned long pccnt;
 
        pccnt = sysreg_read(PCCNT);
        return sprintf(buf, "%lu\n", pccnt);
 }
-static ssize_t store_pccycles(struct sys_device *dev, const char *buf,
+static ssize_t store_pccycles(struct sys_device *dev,
+                               struct sysdev_attribute *attr, const char *buf,
                              size_t count)
 {
        unsigned long val;
@@ -129,14 +139,16 @@ static ssize_t store_pccycles(struct sys_device *dev, const char *buf,
        return count;
 }
 
-static ssize_t show_pcenable(struct sys_device *dev, char *buf)
+static ssize_t show_pcenable(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        unsigned long pccr;
 
        pccr = sysreg_read(PCCR);
        return sprintf(buf, "%c\n", (pccr & 1)?'1':'0');
 }
-static ssize_t store_pcenable(struct sys_device *dev, const char *buf,
+static ssize_t store_pcenable(struct sys_device *dev,
+                             struct sysdev_attribute *attr, const char *buf,
                              size_t count)
 {
        unsigned long pccr, val;
index 021d5121718469387fc1c4d95dd797a12f40bb3b..604f44f5dd164833a9bfdb075a7d65a713617fff 100644 (file)
@@ -7,6 +7,7 @@
  */
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/dw_dmac.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -594,6 +595,17 @@ static void __init genclk_init_parent(struct clk *clk)
        clk->parent = parent;
 }
 
+static struct dw_dma_platform_data dw_dmac0_data = {
+       .nr_channels    = 3,
+};
+
+static struct resource dw_dmac0_resource[] = {
+       PBMEM(0xff200000),
+       IRQ(2),
+};
+DEFINE_DEV_DATA(dw_dmac, 0);
+DEV_CLK(hclk, dw_dmac0, hsb, 10);
+
 /* --------------------------------------------------------------------
  *  System peripherals
  * -------------------------------------------------------------------- */
@@ -708,17 +720,6 @@ static struct clk pico_clk = {
        .users          = 1,
 };
 
-static struct resource dmaca0_resource[] = {
-       {
-               .start  = 0xff200000,
-               .end    = 0xff20ffff,
-               .flags  = IORESOURCE_MEM,
-       },
-       IRQ(2),
-};
-DEFINE_DEV(dmaca, 0);
-DEV_CLK(hclk, dmaca0, hsb, 10);
-
 /* --------------------------------------------------------------------
  * HMATRIX
  * -------------------------------------------------------------------- */
@@ -831,7 +832,7 @@ void __init at32_add_system_devices(void)
        platform_device_register(&at32_eic0_device);
        platform_device_register(&smc0_device);
        platform_device_register(&pdc_device);
-       platform_device_register(&dmaca0_device);
+       platform_device_register(&dw_dmac0_device);
 
        platform_device_register(&at32_tcb0_device);
        platform_device_register(&at32_tcb1_device);
@@ -2032,7 +2033,7 @@ struct clk *at32_clock_list[] = {
        &smc0_mck,
        &pdc_hclk,
        &pdc_pclk,
-       &dmaca0_hclk,
+       &dw_dmac0_hclk,
        &pico_clk,
        &pio0_mck,
        &pio1_mck,
index b87634e75f20f6b4ac9cecb8068e430c27ba8885..b83b8ef84e91d3f6836f986570ca912e52f6ba77 100644 (file)
@@ -873,8 +873,8 @@ config HOTPLUG
          plugged into slots found on all modern laptop computers.  Another
          example, used on modern desktops as well as laptops, is USB.
 
-         Enable HOTPLUG and KMOD, and build a modular kernel.  Get agent
-         software (at <http://linux-hotplug.sourceforge.net/>) and install it.
+         Enable HOTPLUG and build a modular kernel.  Get agent software
+         (from <http://linux-hotplug.sourceforge.net/>) and install it.
          Then your kernel will automatically call out to a user mode "policy
          agent" (/sbin/hotplug) to load modules and set up software needed
          to use devices as you hotplug them.
index 18bcc10903b4f9f3be7e6dfe66ed6a7f5237cda9..451f2ffb137b53eb3ad0056fe6e7695579d3773a 100644 (file)
@@ -540,8 +540,8 @@ config KEXEC
          strongly in flux, so no good recommendation can be made.
 
 config CRASH_DUMP
-         bool "kernel crash dumps (EXPERIMENTAL)"
-         depends on EXPERIMENTAL && IA64_MCA_RECOVERY && !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
+         bool "kernel crash dumps"
+         depends on IA64_MCA_RECOVERY && !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
          help
            Generate crash dump after being started by kexec.
 
index e67ee3f276988d4ad2681359c572e309b4327916..905d25b13d5a10a9a988f2c546e5c968e99c38de 100644 (file)
@@ -100,3 +100,9 @@ define archhelp
   echo '  boot         - Build vmlinux and bootloader for Ski simulator'
   echo '* unwcheck     - Check vmlinux for invalid unwind info'
 endef
+
+archprepare: make_nr_irqs_h FORCE
+PHONY += make_nr_irqs_h FORCE
+
+make_nr_irqs_h: FORCE
+       $(Q)$(MAKE) $(build)=arch/ia64/kernel include/asm-ia64/nr-irqs.h
index 13fd10e8699edcaef4203ef5fcc4c628058532d9..87fea11aecb71b1f9464904a5be7b4833c10aa12 100644 (file)
@@ -36,6 +36,8 @@ obj-$(CONFIG_PCI_MSI)         += msi_ia64.o
 mca_recovery-y                 += mca_drv.o mca_drv_asm.o
 obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
 
+obj-$(CONFIG_PARAVIRT)         += paravirt.o paravirtentry.o
+
 obj-$(CONFIG_IA64_ESI)         += esi.o
 ifneq ($(CONFIG_IA64_ESI),)
 obj-y                          += esi_stub.o   # must be in kernel proper
@@ -70,3 +72,45 @@ $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
 # We must build gate.so before we can assemble it.
 # Note: kbuild does not track this dependency due to usage of .incbin
 $(obj)/gate-data.o: $(obj)/gate.so
+
+# Calculate NR_IRQ = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) based on config
+define sed-y
+       "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"
+endef
+quiet_cmd_nr_irqs = GEN     $@
+define cmd_nr_irqs
+       (set -e; \
+        echo "#ifndef __ASM_NR_IRQS_H__"; \
+        echo "#define __ASM_NR_IRQS_H__"; \
+        echo "/*"; \
+        echo " * DO NOT MODIFY."; \
+        echo " *"; \
+        echo " * This file was generated by Kbuild"; \
+        echo " *"; \
+        echo " */"; \
+        echo ""; \
+        sed -ne $(sed-y) $<; \
+        echo ""; \
+        echo "#endif" ) > $@
+endef
+
+# We use internal kbuild rules to avoid the "is up to date" message from make
+arch/$(SRCARCH)/kernel/nr-irqs.s: $(srctree)/arch/$(SRCARCH)/kernel/nr-irqs.c \
+                               $(wildcard $(srctree)/include/asm-ia64/*/irq.h)
+       $(Q)mkdir -p $(dir $@)
+       $(call if_changed_dep,cc_s_c)
+
+include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s
+       $(Q)mkdir -p $(dir $@)
+       $(call cmd,nr_irqs)
+
+clean-files += $(objtree)/include/asm-ia64/nr-irqs.h
+
+#
+# native ivt.S and entry.S
+#
+ASM_PARAVIRT_OBJS = ivt.o entry.o
+define paravirtualized_native
+AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE
+endef
+$(foreach obj,$(ASM_PARAVIRT_OBJS),$(eval $(call paravirtualized_native,$(obj))))
index 43687cc60dfb92d2a0d4697f439a7c5bca00e764..5d1eb7ee2bf6562282bdccd92520271ca7aedc13 100644 (file)
@@ -774,7 +774,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
  */
 #ifdef CONFIG_ACPI_HOTPLUG_CPU
 static
-int acpi_map_cpu2node(acpi_handle handle, int cpu, long physid)
+int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
 {
 #ifdef CONFIG_ACPI_NUMA
        int pxm_id;
@@ -854,8 +854,7 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu)
        union acpi_object *obj;
        struct acpi_madt_local_sapic *lsapic;
        cpumask_t tmp_map;
-       long physid;
-       int cpu;
+       int cpu, physid;
 
        if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
                return -EINVAL;
index b8498ea6206800b613f753cc75db7c84e71b9e93..7b435451b3dc225d05f453f14f8e77881f472e2b 100644 (file)
@@ -51,7 +51,7 @@ processor_set_pstate (
        retval = ia64_pal_set_pstate((u64)value);
 
        if (retval) {
-               dprintk("Failed to set freq to 0x%x, with error 0x%x\n",
+               dprintk("Failed to set freq to 0x%x, with error 0x%lx\n",
                        value, retval);
                return -ENODEV;
        }
@@ -74,7 +74,7 @@ processor_get_pstate (
 
        if (retval)
                dprintk("Failed to get current freq with "
-                       "error 0x%x, idx 0x%x\n", retval, *value);
+                       "error 0x%lx, idx 0x%x\n", retval, *value);
 
        return (int)retval;
 }
index ca2bb95726de7c24fad1f00013d37ca483d7217a..56ab156c48aed88303ddde98d6b085dd7e9ac6ea 100644 (file)
  * Patrick O'Rourke    <orourke@missioncriticallinux.com>
  * 11/07/2000
  */
+/*
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *                    pv_ops.
+ */
 /*
  * Global (preserved) predicate usage on syscall entry/exit path:
  *
@@ -45,6 +50,7 @@
 
 #include "minstate.h"
 
+#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
        /*
         * execve() is special because in case of success, we need to
         * setup a null register window frame.
@@ -173,6 +179,7 @@ GLOBAL_ENTRY(sys_clone)
        mov rp=loc0
        br.ret.sptk.many rp
 END(sys_clone)
+#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
 
 /*
  * prev_task <- ia64_switch_to(struct task_struct *next)
@@ -180,7 +187,7 @@ END(sys_clone)
  *     called.  The code starting at .map relies on this.  The rest of the code
  *     doesn't care about the interrupt masking status.
  */
-GLOBAL_ENTRY(ia64_switch_to)
+GLOBAL_ENTRY(__paravirt_switch_to)
        .prologue
        alloc r16=ar.pfs,1,0,0,0
        DO_SAVE_SWITCH_STACK
@@ -204,7 +211,7 @@ GLOBAL_ENTRY(ia64_switch_to)
        ;;
 .done:
        ld8 sp=[r21]                    // load kernel stack pointer of new task
-       mov IA64_KR(CURRENT)=in0        // update "current" application register
+       MOV_TO_KR(CURRENT, in0, r8, r9)         // update "current" application register
        mov r8=r13                      // return pointer to previously running task
        mov r13=in0                     // set "current" pointer
        ;;
@@ -216,26 +223,25 @@ GLOBAL_ENTRY(ia64_switch_to)
        br.ret.sptk.many rp             // boogie on out in new context
 
 .map:
-       rsm psr.ic                      // interrupts (psr.i) are already disabled here
+       RSM_PSR_IC(r25)                 // interrupts (psr.i) are already disabled here
        movl r25=PAGE_KERNEL
        ;;
        srlz.d
        or r23=r25,r20                  // construct PA | page properties
        mov r25=IA64_GRANULE_SHIFT<<2
        ;;
-       mov cr.itir=r25
-       mov cr.ifa=in0                  // VA of next task...
+       MOV_TO_ITIR(p0, r25, r8)
+       MOV_TO_IFA(in0, r8)             // VA of next task...
        ;;
        mov r25=IA64_TR_CURRENT_STACK
-       mov IA64_KR(CURRENT_STACK)=r26  // remember last page we mapped...
+       MOV_TO_KR(CURRENT_STACK, r26, r8, r9)   // remember last page we mapped...
        ;;
        itr.d dtr[r25]=r23              // wire in new mapping...
-       ssm psr.ic                      // reenable the psr.ic bit
-       ;;
-       srlz.d
+       SSM_PSR_IC_AND_SRLZ_D(r8, r9)   // reenable the psr.ic bit
        br.cond.sptk .done
-END(ia64_switch_to)
+END(__paravirt_switch_to)
 
+#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
 /*
  * Note that interrupts are enabled during save_switch_stack and load_switch_stack.  This
  * means that we may get an interrupt with "sp" pointing to the new kernel stack while
@@ -375,7 +381,7 @@ END(save_switch_stack)
  *     - b7 holds address to return to
  *     - must not touch r8-r11
  */
-ENTRY(load_switch_stack)
+GLOBAL_ENTRY(load_switch_stack)
        .prologue
        .altrp b7
 
@@ -571,7 +577,7 @@ GLOBAL_ENTRY(ia64_trace_syscall)
 .ret3:
 (pUStk)        cmp.eq.unc p6,p0=r0,r0                  // p6 <- pUStk
 (pUStk)        rsm psr.i                               // disable interrupts
-       br.cond.sptk .work_pending_syscall_end
+       br.cond.sptk ia64_work_pending_syscall_end
 
 strace_error:
        ld8 r3=[r2]                             // load pt_regs.r8
@@ -636,8 +642,17 @@ GLOBAL_ENTRY(ia64_ret_from_syscall)
        adds r2=PT(R8)+16,sp                    // r2 = &pt_regs.r8
        mov r10=r0                              // clear error indication in r10
 (p7)   br.cond.spnt handle_syscall_error       // handle potential syscall failure
+#ifdef CONFIG_PARAVIRT
+       ;;
+       br.cond.sptk.few ia64_leave_syscall
+       ;;
+#endif /* CONFIG_PARAVIRT */
 END(ia64_ret_from_syscall)
+#ifndef CONFIG_PARAVIRT
        // fall through
+#endif
+#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
+
 /*
  * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
  *     need to switch to bank 0 and doesn't restore the scratch registers.
@@ -682,7 +697,7 @@ END(ia64_ret_from_syscall)
  *           ar.csd: cleared
  *           ar.ssd: cleared
  */
-ENTRY(ia64_leave_syscall)
+GLOBAL_ENTRY(__paravirt_leave_syscall)
        PT_REGS_UNWIND_INFO(0)
        /*
         * work.need_resched etc. mustn't get changed by this CPU before it returns to
@@ -692,11 +707,11 @@ ENTRY(ia64_leave_syscall)
         * extra work.  We always check for extra work when returning to user-level.
         * With CONFIG_PREEMPT, we also check for extra work when the preempt_count
         * is 0.  After extra work processing has been completed, execution
-        * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check
+        * resumes at ia64_work_processed_syscall with p6 set to 1 if the extra-work-check
         * needs to be redone.
         */
 #ifdef CONFIG_PREEMPT
-       rsm psr.i                               // disable interrupts
+       RSM_PSR_I(p0, r2, r18)                  // disable interrupts
        cmp.eq pLvSys,p0=r0,r0                  // pLvSys=1: leave from syscall
 (pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
        ;;
@@ -706,11 +721,12 @@ ENTRY(ia64_leave_syscall)
        ;;
        cmp.eq p6,p0=r21,r0             // p6 <- pUStk || (preempt_count == 0)
 #else /* !CONFIG_PREEMPT */
-(pUStk)        rsm psr.i
+       RSM_PSR_I(pUStk, r2, r18)
        cmp.eq pLvSys,p0=r0,r0          // pLvSys=1: leave from syscall
 (pUStk)        cmp.eq.unc p6,p0=r0,r0          // p6 <- pUStk
 #endif
-.work_processed_syscall:
+.global __paravirt_work_processed_syscall;
+__paravirt_work_processed_syscall:
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        adds r2=PT(LOADRS)+16,r12
 (pUStk)        mov.m r22=ar.itc                        // fetch time at leave
@@ -744,7 +760,7 @@ ENTRY(ia64_leave_syscall)
 (pNonSys) break 0              //      bug check: we shouldn't be here if pNonSys is TRUE!
        ;;
        invala                  // M0|1 invalidate ALAT
-       rsm psr.i | psr.ic      // M2   turn off interrupts and interruption collection
+       RSM_PSR_I_IC(r28, r29, r30)     // M2   turn off interrupts and interruption collection
        cmp.eq p9,p0=r0,r0      // A    set p9 to indicate that we should restore cr.ifs
 
        ld8 r29=[r2],16         // M0|1 load cr.ipsr
@@ -765,7 +781,7 @@ ENTRY(ia64_leave_syscall)
        ;;
 #endif
        ld8 r26=[r2],PT(B0)-PT(AR_PFS)  // M0|1 load ar.pfs
-(pKStk)        mov r22=psr                     // M2   read PSR now that interrupts are disabled
+       MOV_FROM_PSR(pKStk, r22, r21)   // M2   read PSR now that interrupts are disabled
        nop 0
        ;;
        ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
@@ -798,7 +814,7 @@ ENTRY(ia64_leave_syscall)
 
        srlz.d                          // M0   ensure interruption collection is off (for cover)
        shr.u r18=r19,16                // I0|1 get byte size of existing "dirty" partition
-       cover                           // B    add current frame into dirty partition & set cr.ifs
+       COVER                           // B    add current frame into dirty partition & set cr.ifs
        ;;
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        mov r19=ar.bsp                  // M2   get new backing store pointer
@@ -823,8 +839,9 @@ ENTRY(ia64_leave_syscall)
        mov.m ar.ssd=r0                 // M2   clear ar.ssd
        mov f11=f0                      // F    clear f11
        br.cond.sptk.many rbs_switch    // B
-END(ia64_leave_syscall)
+END(__paravirt_leave_syscall)
 
+#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
 #ifdef CONFIG_IA32_SUPPORT
 GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
        PT_REGS_UNWIND_INFO(0)
@@ -835,10 +852,20 @@ GLOBAL_ENTRY(ia64_ret_from_ia32_execve)
        st8.spill [r2]=r8       // store return value in slot for r8 and set unat bit
        .mem.offset 8,0
        st8.spill [r3]=r0       // clear error indication in slot for r10 and set unat bit
+#ifdef CONFIG_PARAVIRT
+       ;;
+       // don't fall through, ia64_leave_kernel may be #define'd
+       br.cond.sptk.few ia64_leave_kernel
+       ;;
+#endif /* CONFIG_PARAVIRT */
 END(ia64_ret_from_ia32_execve)
+#ifndef CONFIG_PARAVIRT
        // fall through
+#endif
 #endif /* CONFIG_IA32_SUPPORT */
-GLOBAL_ENTRY(ia64_leave_kernel)
+#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
+
+GLOBAL_ENTRY(__paravirt_leave_kernel)
        PT_REGS_UNWIND_INFO(0)
        /*
         * work.need_resched etc. mustn't get changed by this CPU before it returns to
@@ -852,7 +879,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
         * needs to be redone.
         */
 #ifdef CONFIG_PREEMPT
-       rsm psr.i                               // disable interrupts
+       RSM_PSR_I(p0, r17, r31)                 // disable interrupts
        cmp.eq p0,pLvSys=r0,r0                  // pLvSys=0: leave from kernel
 (pKStk)        adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
        ;;
@@ -862,7 +889,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
        ;;
        cmp.eq p6,p0=r21,r0             // p6 <- pUStk || (preempt_count == 0)
 #else
-(pUStk)        rsm psr.i
+       RSM_PSR_I(pUStk, r17, r31)
        cmp.eq p0,pLvSys=r0,r0          // pLvSys=0: leave from kernel
 (pUStk)        cmp.eq.unc p6,p0=r0,r0          // p6 <- pUStk
 #endif
@@ -910,7 +937,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
        mov ar.csd=r30
        mov ar.ssd=r31
        ;;
-       rsm psr.i | psr.ic      // initiate turning off of interrupt and interruption collection
+       RSM_PSR_I_IC(r23, r22, r25)     // initiate turning off of interrupt and interruption collection
        invala                  // invalidate ALAT
        ;;
        ld8.fill r22=[r2],24
@@ -942,7 +969,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
        mov ar.ccv=r15
        ;;
        ldf.fill f11=[r2]
-       bsw.0                   // switch back to bank 0 (no stop bit required beforehand...)
+       BSW_0(r2, r3, r15)      // switch back to bank 0 (no stop bit required beforehand...)
        ;;
 (pUStk)        mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency)
        adds r16=PT(CR_IPSR)+16,r12
@@ -950,12 +977,12 @@ GLOBAL_ENTRY(ia64_leave_kernel)
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        .pred.rel.mutex pUStk,pKStk
-(pKStk)        mov r22=psr             // M2 read PSR now that interrupts are disabled
+       MOV_FROM_PSR(pKStk, r22, r29)   // M2 read PSR now that interrupts are disabled
 (pUStk)        mov.m r22=ar.itc        // M  fetch time at leave
        nop.i 0
        ;;
 #else
-(pKStk)        mov r22=psr             // M2 read PSR now that interrupts are disabled
+       MOV_FROM_PSR(pKStk, r22, r29)   // M2 read PSR now that interrupts are disabled
        nop.i 0
        nop.i 0
        ;;
@@ -1027,7 +1054,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
         * NOTE: alloc, loadrs, and cover can't be predicated.
         */
 (pNonSys) br.cond.dpnt dont_preserve_current_frame
-       cover                           // add current frame into dirty partition and set cr.ifs
+       COVER                           // add current frame into dirty partition and set cr.ifs
        ;;
        mov r19=ar.bsp                  // get new backing store pointer
 rbs_switch:
@@ -1130,16 +1157,16 @@ skip_rbs_switch:
 (pKStk)        dep r29=r22,r29,21,1    // I0 update ipsr.pp with psr.pp
 (pLvSys)mov r16=r0             // A  clear r16 for leave_syscall, no-op otherwise
        ;;
-       mov cr.ipsr=r29         // M2
+       MOV_TO_IPSR(p0, r29, r25)       // M2
        mov ar.pfs=r26          // I0
 (pLvSys)mov r17=r0             // A  clear r17 for leave_syscall, no-op otherwise
 
-(p9)   mov cr.ifs=r30          // M2
+       MOV_TO_IFS(p9, r30, r25)// M2
        mov b0=r21              // I0
 (pLvSys)mov r18=r0             // A  clear r18 for leave_syscall, no-op otherwise
 
        mov ar.fpsr=r20         // M2
-       mov cr.iip=r28          // M2
+       MOV_TO_IIP(r28, r25)    // M2
        nop 0
        ;;
 (pUStk)        mov ar.rnat=r24         // M2 must happen with RSE in lazy mode
@@ -1148,7 +1175,7 @@ skip_rbs_switch:
 
        mov ar.rsc=r27          // M2
        mov pr=r31,-1           // I0
-       rfi                     // B
+       RFI                     // B
 
        /*
         * On entry:
@@ -1174,35 +1201,36 @@ skip_rbs_switch:
        ;;
 (pKStk) st4 [r20]=r21
 #endif
-       ssm psr.i               // enable interrupts
+       SSM_PSR_I(p0, p6, r2)   // enable interrupts
        br.call.spnt.many rp=schedule
 .ret9: cmp.eq p6,p0=r0,r0      // p6 <- 1 (re-check)
-       rsm psr.i               // disable interrupts
+       RSM_PSR_I(p0, r2, r20)  // disable interrupts
        ;;
 #ifdef CONFIG_PREEMPT
 (pKStk)        adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
        ;;
 (pKStk)        st4 [r20]=r0            // preempt_count() <- 0
 #endif
-(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
+(pLvSys)br.cond.sptk.few  __paravirt_pending_syscall_end
        br.cond.sptk.many .work_processed_kernel
 
 .notify:
 (pUStk)        br.call.spnt.many rp=notify_resume_user
 .ret10:        cmp.ne p6,p0=r0,r0      // p6 <- 0 (don't re-check)
-(pLvSys)br.cond.sptk.few  .work_pending_syscall_end
+(pLvSys)br.cond.sptk.few  __paravirt_pending_syscall_end
        br.cond.sptk.many .work_processed_kernel
 
-.work_pending_syscall_end:
+.global __paravirt_pending_syscall_end;
+__paravirt_pending_syscall_end:
        adds r2=PT(R8)+16,r12
        adds r3=PT(R10)+16,r12
        ;;
        ld8 r8=[r2]
        ld8 r10=[r3]
-       br.cond.sptk.many .work_processed_syscall
-
-END(ia64_leave_kernel)
+       br.cond.sptk.many __paravirt_work_processed_syscall_target
+END(__paravirt_leave_kernel)
 
+#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
 ENTRY(handle_syscall_error)
        /*
         * Some system calls (e.g., ptrace, mmap) can return arbitrary values which could
@@ -1244,7 +1272,7 @@ END(ia64_invoke_schedule_tail)
         * We declare 8 input registers so the system call args get preserved,
         * in case we need to restart a system call.
         */
-ENTRY(notify_resume_user)
+GLOBAL_ENTRY(notify_resume_user)
        .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
        alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!
        mov r9=ar.unat
@@ -1306,7 +1334,7 @@ ENTRY(sys_rt_sigreturn)
        adds sp=16,sp
        ;;
        ld8 r9=[sp]                             // load new ar.unat
-       mov.sptk b7=r8,ia64_leave_kernel
+       mov.sptk b7=r8,ia64_native_leave_kernel
        ;;
        mov ar.unat=r9
        br.many b7
@@ -1665,3 +1693,4 @@ sys_call_table:
        data8 sys_timerfd_gettime
 
        .org sys_call_table + 8*NR_syscalls     // guard against failures to increase NR_syscalls
+#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
index b642648cc2acdbd7a1548d8d76685fec568cced7..c539c689493b786f63d2cbf5b6c2c0969b447dd2 100644 (file)
@@ -55,7 +55,8 @@ static u64 resources[NR_CPUS];
 
 #define show(name)                                                     \
 static ssize_t                                                                 \
-show_##name(struct sys_device *dev, char *buf)                         \
+show_##name(struct sys_device *dev, struct sysdev_attribute *attr,     \
+               char *buf)                                              \
 {                                                                      \
        u32 cpu=dev->id;                                                \
        return sprintf(buf, "%lx\n", name[cpu]);                        \
@@ -63,7 +64,8 @@ show_##name(struct sys_device *dev, char *buf)                                \
 
 #define store(name)                                                    \
 static ssize_t                                                                 \
-store_##name(struct sys_device *dev, const char *buf, size_t size)     \
+store_##name(struct sys_device *dev, struct sysdev_attribute *attr,    \
+                                       const char *buf, size_t size)   \
 {                                                                      \
        unsigned int cpu=dev->id;                                       \
        name[cpu] = simple_strtoull(buf, NULL, 16);                     \
@@ -76,7 +78,8 @@ show(call_start)
  * processor. The cpu number in driver is only used for storing data.
  */
 static ssize_t
-store_call_start(struct sys_device *dev, const char *buf, size_t size)
+store_call_start(struct sys_device *dev, struct sysdev_attribute *attr,
+               const char *buf, size_t size)
 {
        unsigned int cpu=dev->id;
        unsigned long call_start = simple_strtoull(buf, NULL, 16);
@@ -124,14 +127,16 @@ show(err_type_info)
 store(err_type_info)
 
 static ssize_t
-show_virtual_to_phys(struct sys_device *dev, char *buf)
+show_virtual_to_phys(struct sys_device *dev, struct sysdev_attribute *attr,
+                       char *buf)
 {
        unsigned int cpu=dev->id;
        return sprintf(buf, "%lx\n", phys_addr[cpu]);
 }
 
 static ssize_t
-store_virtual_to_phys(struct sys_device *dev, const char *buf, size_t size)
+store_virtual_to_phys(struct sys_device *dev, struct sysdev_attribute *attr,
+                       const char *buf, size_t size)
 {
        unsigned int cpu=dev->id;
        u64 virt_addr=simple_strtoull(buf, NULL, 16);
@@ -154,7 +159,8 @@ show(err_struct_info)
 store(err_struct_info)
 
 static ssize_t
-show_err_data_buffer(struct sys_device *dev, char *buf)
+show_err_data_buffer(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        unsigned int cpu=dev->id;
 
@@ -165,7 +171,9 @@ show_err_data_buffer(struct sys_device *dev, char *buf)
 }
 
 static ssize_t
-store_err_data_buffer(struct sys_device *dev, const char *buf, size_t size)
+store_err_data_buffer(struct sys_device *dev,
+                       struct sysdev_attribute *attr,
+                       const char *buf, size_t size)
 {
        unsigned int cpu=dev->id;
        int ret;
index ddeab4e36fd5fd3b19421349ea19678b9b33adb8..db540e58c783b9e43a7d2b99b0843a6089c470df 100644 (file)
 #include <asm/mmu_context.h>
 #include <asm/asm-offsets.h>
 #include <asm/pal.h>
+#include <asm/paravirt.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/ptrace.h>
 #include <asm/system.h>
 #include <asm/mca_asm.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
 
 #ifdef CONFIG_HOTPLUG_CPU
 #define SAL_PSR_BITS_TO_SET                            \
@@ -367,6 +370,44 @@ start_ap:
        ;;
 (isBP) st8 [r2]=r28            // save the address of the boot param area passed by the bootloader
 
+#ifdef CONFIG_PARAVIRT
+
+       movl r14=hypervisor_setup_hooks
+       movl r15=hypervisor_type
+       mov r16=num_hypervisor_hooks
+       ;;
+       ld8 r2=[r15]
+       ;;
+       cmp.ltu p7,p0=r2,r16    // array size check
+       shladd r8=r2,3,r14
+       ;;
+(p7)   ld8 r9=[r8]
+       ;;
+(p7)   mov b1=r9
+(p7)   cmp.ne.unc p7,p0=r9,r0  // no actual branch to NULL
+       ;;
+(p7)   br.call.sptk.many rp=b1
+
+       __INITDATA
+
+default_setup_hook = 0         // Currently nothing needs to be done.
+
+       .weak xen_setup_hook
+
+       .global hypervisor_type
+hypervisor_type:
+       data8           PARAVIRT_HYPERVISOR_TYPE_DEFAULT
+
+       // must have the same order with PARAVIRT_HYPERVISOR_TYPE_xxx
+
+hypervisor_setup_hooks:
+       data8           default_setup_hook
+       data8           xen_setup_hook
+num_hypervisor_hooks = (. - hypervisor_setup_hooks) / 8
+       .previous
+
+#endif
+
 #ifdef CONFIG_SMP
 (isAP) br.call.sptk.many rp=start_secondary
 .ret0:
index 39752cdef6ffd342210c237f60aa7c32782cbd87..3bc2fa64f87f7f55047646e600614150d6b3c0eb 100644 (file)
@@ -585,6 +585,15 @@ static inline int irq_is_shared (int irq)
        return (iosapic_intr_info[irq].count > 1);
 }
 
+struct irq_chip*
+ia64_native_iosapic_get_irq_chip(unsigned long trigger)
+{
+       if (trigger == IOSAPIC_EDGE)
+               return &irq_type_iosapic_edge;
+       else
+               return &irq_type_iosapic_level;
+}
+
 static int
 register_intr (unsigned int gsi, int irq, unsigned char delivery,
               unsigned long polarity, unsigned long trigger)
@@ -635,13 +644,10 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
        iosapic_intr_info[irq].dmode    = delivery;
        iosapic_intr_info[irq].trigger  = trigger;
 
-       if (trigger == IOSAPIC_EDGE)
-               irq_type = &irq_type_iosapic_edge;
-       else
-               irq_type = &irq_type_iosapic_level;
+       irq_type = iosapic_get_irq_chip(trigger);
 
        idesc = irq_desc + irq;
-       if (idesc->chip != irq_type) {
+       if (irq_type != NULL && idesc->chip != irq_type) {
                if (idesc->chip != &no_irq_type)
                        printk(KERN_WARNING
                               "%s: changing vector %d from %s to %s\n",
@@ -973,6 +979,22 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
        set_rte(gsi, irq, dest, 1);
 }
 
+void __init
+ia64_native_iosapic_pcat_compat_init(void)
+{
+       if (pcat_compat) {
+               /*
+                * Disable the compatibility mode interrupts (8259 style),
+                * needs IN/OUT support enabled.
+                */
+               printk(KERN_INFO
+                      "%s: Disabling PC-AT compatible 8259 interrupts\n",
+                      __func__);
+               outb(0xff, 0xA1);
+               outb(0xff, 0x21);
+       }
+}
+
 void __init
 iosapic_system_init (int system_pcat_compat)
 {
@@ -987,17 +1009,8 @@ iosapic_system_init (int system_pcat_compat)
        }
 
        pcat_compat = system_pcat_compat;
-       if (pcat_compat) {
-               /*
-                * Disable the compatibility mode interrupts (8259 style),
-                * needs IN/OUT support enabled.
-                */
-               printk(KERN_INFO
-                      "%s: Disabling PC-AT compatible 8259 interrupts\n",
-                      __func__);
-               outb(0xff, 0xA1);
-               outb(0xff, 0x21);
-       }
+       if (pcat_compat)
+               iosapic_pcat_compat_init();
 }
 
 static inline int
index 5538471e8d68dc663df1656d9564f74ad11fe806..28d3d483db9203e32ce3e642130c966194660403 100644 (file)
@@ -196,7 +196,7 @@ static void clear_irq_vector(int irq)
 }
 
 int
-assign_irq_vector (int irq)
+ia64_native_assign_irq_vector (int irq)
 {
        unsigned long flags;
        int vector, cpu;
@@ -222,7 +222,7 @@ assign_irq_vector (int irq)
 }
 
 void
-free_irq_vector (int vector)
+ia64_native_free_irq_vector (int vector)
 {
        if (vector < IA64_FIRST_DEVICE_VECTOR ||
            vector > IA64_LAST_DEVICE_VECTOR)
@@ -600,7 +600,6 @@ static irqreturn_t dummy_handler (int irq, void *dev_id)
 {
        BUG();
 }
-extern irqreturn_t handle_IPI (int irq, void *dev_id);
 
 static struct irqaction ipi_irqaction = {
        .handler =      handle_IPI,
@@ -623,7 +622,7 @@ static struct irqaction tlb_irqaction = {
 #endif
 
 void
-register_percpu_irq (ia64_vector vec, struct irqaction *action)
+ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action)
 {
        irq_desc_t *desc;
        unsigned int irq;
@@ -638,13 +637,21 @@ register_percpu_irq (ia64_vector vec, struct irqaction *action)
 }
 
 void __init
-init_IRQ (void)
+ia64_native_register_ipi(void)
 {
-       register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
 #ifdef CONFIG_SMP
        register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
        register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction);
        register_percpu_irq(IA64_IPI_LOCAL_TLB_FLUSH, &tlb_irqaction);
+#endif
+}
+
+void __init
+init_IRQ (void)
+{
+       ia64_register_ipi();
+       register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
+#ifdef CONFIG_SMP
 #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG)
        if (vector_domain_type != VECTOR_DOMAIN_NONE) {
                BUG_ON(IA64_FIRST_DEVICE_VECTOR != IA64_IRQ_MOVE_VECTOR);
index 80b44ea052d74420abca826c119d8ee192743144..c39627df3cde294650f95e1a4e44e65c8cbbc337 100644 (file)
  *
  * 00/08/23 Asit Mallick <asit.k.mallick@intel.com> TLB handling for SMP
  * 00/12/20 David Mosberger-Tang <davidm@hpl.hp.com> DTLB/ITLB handler now uses virtual PT.
+ *
+ * Copyright (C) 2005 Hewlett-Packard Co
+ *     Dan Magenheimer <dan.magenheimer@hp.com>
+ *      Xen paravirtualization
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *                    pv_ops.
+ *      Yaozu (Eddie) Dong <eddie.dong@intel.com>
  */
 /*
  * This file defines the interruption vector table used by the CPU.
@@ -102,13 +110,13 @@ ENTRY(vhpt_miss)
         *      - the faulting virtual address uses unimplemented address bits
         *      - the faulting virtual address has no valid page table mapping
         */
-       mov r16=cr.ifa                          // get address that caused the TLB miss
+       MOV_FROM_IFA(r16)                       // get address that caused the TLB miss
 #ifdef CONFIG_HUGETLB_PAGE
        movl r18=PAGE_SHIFT
-       mov r25=cr.itir
+       MOV_FROM_ITIR(r25)
 #endif
        ;;
-       rsm psr.dt                              // use physical addressing for data
+       RSM_PSR_DT                              // use physical addressing for data
        mov r31=pr                              // save the predicate registers
        mov r19=IA64_KR(PT_BASE)                // get page table base address
        shl r21=r16,3                           // shift bit 60 into sign bit
@@ -168,21 +176,21 @@ ENTRY(vhpt_miss)
        dep r21=r19,r20,3,(PAGE_SHIFT-3)        // r21=pte_offset(pmd,addr)
        ;;
 (p7)   ld8 r18=[r21]                           // read *pte
-       mov r19=cr.isr                          // cr.isr bit 32 tells us if this is an insn miss
+       MOV_FROM_ISR(r19)                       // cr.isr bit 32 tells us if this is an insn miss
        ;;
 (p7)   tbit.z p6,p7=r18,_PAGE_P_BIT            // page present bit cleared?
-       mov r22=cr.iha                          // get the VHPT address that caused the TLB miss
+       MOV_FROM_IHA(r22)                       // get the VHPT address that caused the TLB miss
        ;;                                      // avoid RAW on p7
 (p7)   tbit.nz.unc p10,p11=r19,32              // is it an instruction TLB miss?
        dep r23=0,r20,0,PAGE_SHIFT              // clear low bits to get page address
        ;;
-(p10)  itc.i r18                               // insert the instruction TLB entry
-(p11)  itc.d r18                               // insert the data TLB entry
+       ITC_I_AND_D(p10, p11, r18, r24)         // insert the instruction TLB entry and
+                                               // insert the data TLB entry
 (p6)   br.cond.spnt.many page_fault            // handle bad address/page not present (page fault)
-       mov cr.ifa=r22
+       MOV_TO_IFA(r22, r24)
 
 #ifdef CONFIG_HUGETLB_PAGE
-(p8)   mov cr.itir=r25                         // change to default page-size for VHPT
+       MOV_TO_ITIR(p8, r25, r24)               // change to default page-size for VHPT
 #endif
 
        /*
@@ -192,7 +200,7 @@ ENTRY(vhpt_miss)
         */
        adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23
        ;;
-(p7)   itc.d r24
+       ITC_D(p7, r24, r25)
        ;;
 #ifdef CONFIG_SMP
        /*
@@ -234,7 +242,7 @@ ENTRY(vhpt_miss)
 #endif
 
        mov pr=r31,-1                           // restore predicate registers
-       rfi
+       RFI
 END(vhpt_miss)
 
        .org ia64_ivt+0x400
@@ -248,11 +256,11 @@ ENTRY(itlb_miss)
         * mode, walk the page table, and then re-execute the PTE read and
         * go on normally after that.
         */
-       mov r16=cr.ifa                          // get virtual address
+       MOV_FROM_IFA(r16)                       // get virtual address
        mov r29=b0                              // save b0
        mov r31=pr                              // save predicates
 .itlb_fault:
-       mov r17=cr.iha                          // get virtual address of PTE
+       MOV_FROM_IHA(r17)                       // get virtual address of PTE
        movl r30=1f                             // load nested fault continuation point
        ;;
 1:     ld8 r18=[r17]                           // read *pte
@@ -261,7 +269,7 @@ ENTRY(itlb_miss)
        tbit.z p6,p0=r18,_PAGE_P_BIT            // page present bit cleared?
 (p6)   br.cond.spnt page_fault
        ;;
-       itc.i r18
+       ITC_I(p0, r18, r19)
        ;;
 #ifdef CONFIG_SMP
        /*
@@ -278,7 +286,7 @@ ENTRY(itlb_miss)
 (p7)   ptc.l r16,r20
 #endif
        mov pr=r31,-1
-       rfi
+       RFI
 END(itlb_miss)
 
        .org ia64_ivt+0x0800
@@ -292,11 +300,11 @@ ENTRY(dtlb_miss)
         * mode, walk the page table, and then re-execute the PTE read and
         * go on normally after that.
         */
-       mov r16=cr.ifa                          // get virtual address
+       MOV_FROM_IFA(r16)                       // get virtual address
        mov r29=b0                              // save b0
        mov r31=pr                              // save predicates
 dtlb_fault:
-       mov r17=cr.iha                          // get virtual address of PTE
+       MOV_FROM_IHA(r17)                       // get virtual address of PTE
        movl r30=1f                             // load nested fault continuation point
        ;;
 1:     ld8 r18=[r17]                           // read *pte
@@ -305,7 +313,7 @@ dtlb_fault:
        tbit.z p6,p0=r18,_PAGE_P_BIT            // page present bit cleared?
 (p6)   br.cond.spnt page_fault
        ;;
-       itc.d r18
+       ITC_D(p0, r18, r19)
        ;;
 #ifdef CONFIG_SMP
        /*
@@ -322,7 +330,7 @@ dtlb_fault:
 (p7)   ptc.l r16,r20
 #endif
        mov pr=r31,-1
-       rfi
+       RFI
 END(dtlb_miss)
 
        .org ia64_ivt+0x0c00
@@ -330,9 +338,9 @@ END(dtlb_miss)
 // 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
 ENTRY(alt_itlb_miss)
        DBG_FAULT(3)
-       mov r16=cr.ifa          // get address that caused the TLB miss
+       MOV_FROM_IFA(r16)       // get address that caused the TLB miss
        movl r17=PAGE_KERNEL
-       mov r21=cr.ipsr
+       MOV_FROM_IPSR(p0, r21)
        movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
        mov r31=pr
        ;;
@@ -341,9 +349,9 @@ ENTRY(alt_itlb_miss)
        ;;
        cmp.gt p8,p0=6,r22                      // user mode
        ;;
-(p8)   thash r17=r16
+       THASH(p8, r17, r16, r23)
        ;;
-(p8)   mov cr.iha=r17
+       MOV_TO_IHA(p8, r17, r23)
 (p8)   mov r29=b0                              // save b0
 (p8)   br.cond.dptk .itlb_fault
 #endif
@@ -358,9 +366,9 @@ ENTRY(alt_itlb_miss)
        or r19=r19,r18          // set bit 4 (uncached) if the access was to region 6
 (p8)   br.cond.spnt page_fault
        ;;
-       itc.i r19               // insert the TLB entry
+       ITC_I(p0, r19, r18)     // insert the TLB entry
        mov pr=r31,-1
-       rfi
+       RFI
 END(alt_itlb_miss)
 
        .org ia64_ivt+0x1000
@@ -368,11 +376,11 @@ END(alt_itlb_miss)
 // 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
 ENTRY(alt_dtlb_miss)
        DBG_FAULT(4)
-       mov r16=cr.ifa          // get address that caused the TLB miss
+       MOV_FROM_IFA(r16)       // get address that caused the TLB miss
        movl r17=PAGE_KERNEL
-       mov r20=cr.isr
+       MOV_FROM_ISR(r20)
        movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
-       mov r21=cr.ipsr
+       MOV_FROM_IPSR(p0, r21)
        mov r31=pr
        mov r24=PERCPU_ADDR
        ;;
@@ -381,9 +389,9 @@ ENTRY(alt_dtlb_miss)
        ;;
        cmp.gt p8,p0=6,r22                      // access to region 0-5
        ;;
-(p8)   thash r17=r16
+       THASH(p8, r17, r16, r25)
        ;;
-(p8)   mov cr.iha=r17
+       MOV_TO_IHA(p8, r17, r25)
 (p8)   mov r29=b0                              // save b0
 (p8)   br.cond.dptk dtlb_fault
 #endif
@@ -402,7 +410,7 @@ ENTRY(alt_dtlb_miss)
        tbit.nz p9,p0=r20,IA64_ISR_NA_BIT       // is non-access bit on?
        ;;
 (p10)  sub r19=r19,r26
-(p10)  mov cr.itir=r25
+       MOV_TO_ITIR(p10, r25, r24)
        cmp.ne p8,p0=r0,r23
 (p9)   cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22  // check isr.code field
 (p12)  dep r17=-1,r17,4,1                      // set ma=UC for region 6 addr
@@ -411,11 +419,11 @@ ENTRY(alt_dtlb_miss)
        dep r21=-1,r21,IA64_PSR_ED_BIT,1
        ;;
        or r19=r19,r17          // insert PTE control bits into r19
-(p6)   mov cr.ipsr=r21
+       MOV_TO_IPSR(p6, r21, r24)
        ;;
-(p7)   itc.d r19               // insert the TLB entry
+       ITC_D(p7, r19, r18)     // insert the TLB entry
        mov pr=r31,-1
-       rfi
+       RFI
 END(alt_dtlb_miss)
 
        .org ia64_ivt+0x1400
@@ -444,10 +452,10 @@ ENTRY(nested_dtlb_miss)
         *
         * Clobbered:   b0, r18, r19, r21, r22, psr.dt (cleared)
         */
-       rsm psr.dt                              // switch to using physical data addressing
+       RSM_PSR_DT                              // switch to using physical data addressing
        mov r19=IA64_KR(PT_BASE)                // get the page table base address
        shl r21=r16,3                           // shift bit 60 into sign bit
-       mov r18=cr.itir
+       MOV_FROM_ITIR(r18)
        ;;
        shr.u r17=r16,61                        // get the region number into r17
        extr.u r18=r18,2,6                      // get the faulting page size
@@ -507,33 +515,6 @@ ENTRY(ikey_miss)
        FAULT(6)
 END(ikey_miss)
 
-       //-----------------------------------------------------------------------------------
-       // call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address)
-ENTRY(page_fault)
-       ssm psr.dt
-       ;;
-       srlz.i
-       ;;
-       SAVE_MIN_WITH_COVER
-       alloc r15=ar.pfs,0,0,3,0
-       mov out0=cr.ifa
-       mov out1=cr.isr
-       adds r3=8,r2                            // set up second base pointer
-       ;;
-       ssm psr.ic | PSR_DEFAULT_BITS
-       ;;
-       srlz.i                                  // guarantee that interruption collectin is on
-       ;;
-(p15)  ssm psr.i                               // restore psr.i
-       movl r14=ia64_leave_kernel
-       ;;
-       SAVE_REST
-       mov rp=r14
-       ;;
-       adds out2=16,r12                        // out2 = pointer to pt_regs
-       br.call.sptk.many b6=ia64_do_page_fault // ignore return address
-END(page_fault)
-
        .org ia64_ivt+0x1c00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
@@ -556,10 +537,10 @@ ENTRY(dirty_bit)
         * page table TLB entry isn't present, we take a nested TLB miss hit where we look
         * up the physical address of the L3 PTE and then continue at label 1 below.
         */
-       mov r16=cr.ifa                          // get the address that caused the fault
+       MOV_FROM_IFA(r16)                       // get the address that caused the fault
        movl r30=1f                             // load continuation point in case of nested fault
        ;;
-       thash r17=r16                           // compute virtual address of L3 PTE
+       THASH(p0, r17, r16, r18)                // compute virtual address of L3 PTE
        mov r29=b0                              // save b0 in case of nested fault
        mov r31=pr                              // save pr
 #ifdef CONFIG_SMP
@@ -576,7 +557,7 @@ ENTRY(dirty_bit)
        ;;
 (p6)   cmp.eq p6,p7=r26,r18                    // Only compare if page is present
        ;;
-(p6)   itc.d r25                               // install updated PTE
+       ITC_D(p6, r25, r18)                     // install updated PTE
        ;;
        /*
         * Tell the assemblers dependency-violation checker that the above "itc" instructions
@@ -602,7 +583,7 @@ ENTRY(dirty_bit)
        itc.d r18                               // install updated PTE
 #endif
        mov pr=r31,-1                           // restore pr
-       rfi
+       RFI
 END(dirty_bit)
 
        .org ia64_ivt+0x2400
@@ -611,22 +592,22 @@ END(dirty_bit)
 ENTRY(iaccess_bit)
        DBG_FAULT(9)
        // Like Entry 8, except for instruction access
-       mov r16=cr.ifa                          // get the address that caused the fault
+       MOV_FROM_IFA(r16)                       // get the address that caused the fault
        movl r30=1f                             // load continuation point in case of nested fault
        mov r31=pr                              // save predicates
 #ifdef CONFIG_ITANIUM
        /*
         * Erratum 10 (IFA may contain incorrect address) has "NoFix" status.
         */
-       mov r17=cr.ipsr
+       MOV_FROM_IPSR(p0, r17)
        ;;
-       mov r18=cr.iip
+       MOV_FROM_IIP(r18)
        tbit.z p6,p0=r17,IA64_PSR_IS_BIT        // IA64 instruction set?
        ;;
 (p6)   mov r16=r18                             // if so, use cr.iip instead of cr.ifa
 #endif /* CONFIG_ITANIUM */
        ;;
-       thash r17=r16                           // compute virtual address of L3 PTE
+       THASH(p0, r17, r16, r18)                // compute virtual address of L3 PTE
        mov r29=b0                              // save b0 in case of nested fault)
 #ifdef CONFIG_SMP
        mov r28=ar.ccv                          // save ar.ccv
@@ -642,7 +623,7 @@ ENTRY(iaccess_bit)
        ;;
 (p6)   cmp.eq p6,p7=r26,r18                    // Only if page present
        ;;
-(p6)   itc.i r25                               // install updated PTE
+       ITC_I(p6, r25, r26)                     // install updated PTE
        ;;
        /*
         * Tell the assemblers dependency-violation checker that the above "itc" instructions
@@ -668,7 +649,7 @@ ENTRY(iaccess_bit)
        itc.i r18                               // install updated PTE
 #endif /* !CONFIG_SMP */
        mov pr=r31,-1
-       rfi
+       RFI
 END(iaccess_bit)
 
        .org ia64_ivt+0x2800
@@ -677,10 +658,10 @@ END(iaccess_bit)
 ENTRY(daccess_bit)
        DBG_FAULT(10)
        // Like Entry 8, except for data access
-       mov r16=cr.ifa                          // get the address that caused the fault
+       MOV_FROM_IFA(r16)                       // get the address that caused the fault
        movl r30=1f                             // load continuation point in case of nested fault
        ;;
-       thash r17=r16                           // compute virtual address of L3 PTE
+       THASH(p0, r17, r16, r18)                // compute virtual address of L3 PTE
        mov r31=pr
        mov r29=b0                              // save b0 in case of nested fault)
 #ifdef CONFIG_SMP
@@ -697,7 +678,7 @@ ENTRY(daccess_bit)
        ;;
 (p6)   cmp.eq p6,p7=r26,r18                    // Only if page is present
        ;;
-(p6)   itc.d r25                               // install updated PTE
+       ITC_D(p6, r25, r26)                     // install updated PTE
        /*
         * Tell the assemblers dependency-violation checker that the above "itc" instructions
         * cannot possibly affect the following loads:
@@ -721,7 +702,7 @@ ENTRY(daccess_bit)
 #endif
        mov b0=r29                              // restore b0
        mov pr=r31,-1
-       rfi
+       RFI
 END(daccess_bit)
 
        .org ia64_ivt+0x2c00
@@ -745,10 +726,10 @@ ENTRY(break_fault)
         */
        DBG_FAULT(11)
        mov.m r16=IA64_KR(CURRENT)              // M2 r16 <- current task (12 cyc)
-       mov r29=cr.ipsr                         // M2 (12 cyc)
+       MOV_FROM_IPSR(p0, r29)                  // M2 (12 cyc)
        mov r31=pr                              // I0 (2 cyc)
 
-       mov r17=cr.iim                          // M2 (2 cyc)
+       MOV_FROM_IIM(r17)                       // M2 (2 cyc)
        mov.m r27=ar.rsc                        // M2 (12 cyc)
        mov r18=__IA64_BREAK_SYSCALL            // A
 
@@ -767,7 +748,7 @@ ENTRY(break_fault)
        nop.m 0
        movl r30=sys_call_table                 // X
 
-       mov r28=cr.iip                          // M2 (2 cyc)
+       MOV_FROM_IIP(r28)                       // M2 (2 cyc)
        cmp.eq p0,p7=r18,r17                    // I0 is this a system call?
 (p7)   br.cond.spnt non_syscall                // B  no ->
        //
@@ -864,18 +845,17 @@ ENTRY(break_fault)
 #endif
        mov ar.rsc=0x3                          // M2   set eager mode, pl 0, LE, loadrs=0
        nop 0
-       bsw.1                                   // B (6 cyc) regs are saved, switch to bank 1
+       BSW_1(r2, r14)                          // B (6 cyc) regs are saved, switch to bank 1
        ;;
 
-       ssm psr.ic | PSR_DEFAULT_BITS           // M2   now it's safe to re-enable intr.-collection
+       SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r16) // M2   now it's safe to re-enable intr.-collection
+                                               // M0   ensure interruption collection is on
        movl r3=ia64_ret_from_syscall           // X
        ;;
-
-       srlz.i                                  // M0   ensure interruption collection is on
        mov rp=r3                               // I0   set the real return addr
 (p10)  br.cond.spnt.many ia64_ret_from_syscall // B    return if bad call-frame or r15 is a NaT
 
-(p15)  ssm psr.i                               // M2   restore psr.i
+       SSM_PSR_I(p15, p15, r16)                // M2   restore psr.i
 (p14)  br.call.sptk.many b6=b6                 // B    invoke syscall-handker (ignore return addr)
        br.cond.spnt.many ia64_trace_syscall    // B    do syscall-tracing thingamagic
        // NOT REACHED
@@ -895,27 +875,8 @@ END(break_fault)
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
 ENTRY(interrupt)
-       DBG_FAULT(12)
-       mov r31=pr              // prepare to save predicates
-       ;;
-       SAVE_MIN_WITH_COVER     // uses r31; defines r2 and r3
-       ssm psr.ic | PSR_DEFAULT_BITS
-       ;;
-       adds r3=8,r2            // set up second base pointer for SAVE_REST
-       srlz.i                  // ensure everybody knows psr.ic is back on
-       ;;
-       SAVE_REST
-       ;;
-       MCA_RECOVER_RANGE(interrupt)
-       alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
-       mov out0=cr.ivr         // pass cr.ivr as first arg
-       add out1=16,sp          // pass pointer to pt_regs as second arg
-       ;;
-       srlz.d                  // make sure we see the effect of cr.ivr
-       movl r14=ia64_leave_kernel
-       ;;
-       mov rp=r14
-       br.call.sptk.many b6=ia64_handle_irq
+       /* interrupt handler has become too big to fit this area. */
+       br.sptk.many __interrupt
 END(interrupt)
 
        .org ia64_ivt+0x3400
@@ -978,6 +939,7 @@ END(interrupt)
         *      - ar.fpsr: set to kernel settings
         *      -  b6: preserved (same as on entry)
         */
+#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
 GLOBAL_ENTRY(ia64_syscall_setup)
 #if PT(B6) != 0
 # error This code assumes that b6 is the first field in pt_regs.
@@ -1069,6 +1031,7 @@ GLOBAL_ENTRY(ia64_syscall_setup)
 (p10)  mov r8=-EINVAL
        br.ret.sptk.many b7
 END(ia64_syscall_setup)
+#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
 
        .org ia64_ivt+0x3c00
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -1082,7 +1045,7 @@ END(ia64_syscall_setup)
        DBG_FAULT(16)
        FAULT(16)
 
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+#if defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(__IA64_ASM_PARAVIRTUALIZED_NATIVE)
        /*
         * There is no particular reason for this code to be here, other than
         * that there happens to be space here that would go unused otherwise.
@@ -1092,7 +1055,7 @@ END(ia64_syscall_setup)
         * account_sys_enter is called from SAVE_MIN* macros if accounting is
         * enabled and if the macro is entered from user mode.
         */
-ENTRY(account_sys_enter)
+GLOBAL_ENTRY(account_sys_enter)
        // mov.m r20=ar.itc is called in advance, and r13 is current
        add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13
        add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13
@@ -1123,110 +1086,18 @@ END(account_sys_enter)
        DBG_FAULT(17)
        FAULT(17)
 
-ENTRY(non_syscall)
-       mov ar.rsc=r27                  // restore ar.rsc before SAVE_MIN_WITH_COVER
-       ;;
-       SAVE_MIN_WITH_COVER
-
-       // There is no particular reason for this code to be here, other than that
-       // there happens to be space here that would go unused otherwise.  If this
-       // fault ever gets "unreserved", simply moved the following code to a more
-       // suitable spot...
-
-       alloc r14=ar.pfs,0,0,2,0
-       mov out0=cr.iim
-       add out1=16,sp
-       adds r3=8,r2                    // set up second base pointer for SAVE_REST
-
-       ssm psr.ic | PSR_DEFAULT_BITS
-       ;;
-       srlz.i                          // guarantee that interruption collection is on
-       ;;
-(p15)  ssm psr.i                       // restore psr.i
-       movl r15=ia64_leave_kernel
-       ;;
-       SAVE_REST
-       mov rp=r15
-       ;;
-       br.call.sptk.many b6=ia64_bad_break     // avoid WAW on CFM and ignore return addr
-END(non_syscall)
-
        .org ia64_ivt+0x4800
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4800 Entry 18 (size 64 bundles) Reserved
        DBG_FAULT(18)
        FAULT(18)
 
-       /*
-        * There is no particular reason for this code to be here, other than that
-        * there happens to be space here that would go unused otherwise.  If this
-        * fault ever gets "unreserved", simply moved the following code to a more
-        * suitable spot...
-        */
-
-ENTRY(dispatch_unaligned_handler)
-       SAVE_MIN_WITH_COVER
-       ;;
-       alloc r14=ar.pfs,0,0,2,0                // now it's safe (must be first in insn group!)
-       mov out0=cr.ifa
-       adds out1=16,sp
-
-       ssm psr.ic | PSR_DEFAULT_BITS
-       ;;
-       srlz.i                                  // guarantee that interruption collection is on
-       ;;
-(p15)  ssm psr.i                               // restore psr.i
-       adds r3=8,r2                            // set up second base pointer
-       ;;
-       SAVE_REST
-       movl r14=ia64_leave_kernel
-       ;;
-       mov rp=r14
-       br.sptk.many ia64_prepare_handle_unaligned
-END(dispatch_unaligned_handler)
-
        .org ia64_ivt+0x4c00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4c00 Entry 19 (size 64 bundles) Reserved
        DBG_FAULT(19)
        FAULT(19)
 
-       /*
-        * There is no particular reason for this code to be here, other than that
-        * there happens to be space here that would go unused otherwise.  If this
-        * fault ever gets "unreserved", simply moved the following code to a more
-        * suitable spot...
-        */
-
-ENTRY(dispatch_to_fault_handler)
-       /*
-        * Input:
-        *      psr.ic: off
-        *      r19:    fault vector number (e.g., 24 for General Exception)
-        *      r31:    contains saved predicates (pr)
-        */
-       SAVE_MIN_WITH_COVER_R19
-       alloc r14=ar.pfs,0,0,5,0
-       mov out0=r15
-       mov out1=cr.isr
-       mov out2=cr.ifa
-       mov out3=cr.iim
-       mov out4=cr.itir
-       ;;
-       ssm psr.ic | PSR_DEFAULT_BITS
-       ;;
-       srlz.i                                  // guarantee that interruption collection is on
-       ;;
-(p15)  ssm psr.i                               // restore psr.i
-       adds r3=8,r2                            // set up second base pointer for SAVE_REST
-       ;;
-       SAVE_REST
-       movl r14=ia64_leave_kernel
-       ;;
-       mov rp=r14
-       br.call.sptk.many b6=ia64_fault
-END(dispatch_to_fault_handler)
-
 //
 // --- End of long entries, Beginning of short entries
 //
@@ -1236,8 +1107,8 @@ END(dispatch_to_fault_handler)
 // 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
 ENTRY(page_not_present)
        DBG_FAULT(20)
-       mov r16=cr.ifa
-       rsm psr.dt
+       MOV_FROM_IFA(r16)
+       RSM_PSR_DT
        /*
         * The Linux page fault handler doesn't expect non-present pages to be in
         * the TLB.  Flush the existing entry now, so we meet that expectation.
@@ -1256,8 +1127,8 @@ END(page_not_present)
 // 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52)
 ENTRY(key_permission)
        DBG_FAULT(21)
-       mov r16=cr.ifa
-       rsm psr.dt
+       MOV_FROM_IFA(r16)
+       RSM_PSR_DT
        mov r31=pr
        ;;
        srlz.d
@@ -1269,8 +1140,8 @@ END(key_permission)
 // 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
 ENTRY(iaccess_rights)
        DBG_FAULT(22)
-       mov r16=cr.ifa
-       rsm psr.dt
+       MOV_FROM_IFA(r16)
+       RSM_PSR_DT
        mov r31=pr
        ;;
        srlz.d
@@ -1282,8 +1153,8 @@ END(iaccess_rights)
 // 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
 ENTRY(daccess_rights)
        DBG_FAULT(23)
-       mov r16=cr.ifa
-       rsm psr.dt
+       MOV_FROM_IFA(r16)
+       RSM_PSR_DT
        mov r31=pr
        ;;
        srlz.d
@@ -1295,7 +1166,7 @@ END(daccess_rights)
 // 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
 ENTRY(general_exception)
        DBG_FAULT(24)
-       mov r16=cr.isr
+       MOV_FROM_ISR(r16)
        mov r31=pr
        ;;
        cmp4.eq p6,p0=0,r16
@@ -1324,8 +1195,8 @@ END(disabled_fp_reg)
 ENTRY(nat_consumption)
        DBG_FAULT(26)
 
-       mov r16=cr.ipsr
-       mov r17=cr.isr
+       MOV_FROM_IPSR(p0, r16)
+       MOV_FROM_ISR(r17)
        mov r31=pr                              // save PR
        ;;
        and r18=0xf,r17                         // r18 = cr.ipsr.code{3:0}
@@ -1335,10 +1206,10 @@ ENTRY(nat_consumption)
        dep r16=-1,r16,IA64_PSR_ED_BIT,1
 (p6)   br.cond.spnt 1f         // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH)
        ;;
-       mov cr.ipsr=r16         // set cr.ipsr.na
+       MOV_TO_IPSR(p0, r16, r18)
        mov pr=r31,-1
        ;;
-       rfi
+       RFI
 
 1:     mov pr=r31,-1
        ;;
@@ -1360,26 +1231,26 @@ ENTRY(speculation_vector)
         *
         * cr.imm contains zero_ext(imm21)
         */
-       mov r18=cr.iim
+       MOV_FROM_IIM(r18)
        ;;
-       mov r17=cr.iip
+       MOV_FROM_IIP(r17)
        shl r18=r18,43                  // put sign bit in position (43=64-21)
        ;;
 
-       mov r16=cr.ipsr
+       MOV_FROM_IPSR(p0, r16)
        shr r18=r18,39                  // sign extend (39=43-4)
        ;;
 
        add r17=r17,r18                 // now add the offset
        ;;
-       mov cr.iip=r17
+       MOV_FROM_IIP(r17)
        dep r16=0,r16,41,2              // clear EI
        ;;
 
-       mov cr.ipsr=r16
+       MOV_FROM_IPSR(p0, r16)
        ;;
 
-       rfi                             // and go back
+       RFI
 END(speculation_vector)
 
        .org ia64_ivt+0x5800
@@ -1517,11 +1388,11 @@ ENTRY(ia32_intercept)
        DBG_FAULT(46)
 #ifdef CONFIG_IA32_SUPPORT
        mov r31=pr
-       mov r16=cr.isr
+       MOV_FROM_ISR(r16)
        ;;
        extr.u r17=r16,16,8     // get ISR.code
        mov r18=ar.eflag
-       mov r19=cr.iim          // old eflag value
+       MOV_FROM_IIM(r19)       // old eflag value
        ;;
        cmp.ne p6,p0=2,r17
 (p6)   br.cond.spnt 1f         // not a system flag fault
@@ -1533,7 +1404,7 @@ ENTRY(ia32_intercept)
 (p6)   br.cond.spnt 1f         // eflags.ac bit didn't change
        ;;
        mov pr=r31,-1           // restore predicate registers
-       rfi
+       RFI
 
 1:
 #endif // CONFIG_IA32_SUPPORT
@@ -1673,6 +1544,137 @@ END(ia32_interrupt)
        DBG_FAULT(67)
        FAULT(67)
 
+       //-----------------------------------------------------------------------------------
+       // call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address)
+ENTRY(page_fault)
+       SSM_PSR_DT_AND_SRLZ_I
+       ;;
+       SAVE_MIN_WITH_COVER
+       alloc r15=ar.pfs,0,0,3,0
+       MOV_FROM_IFA(out0)
+       MOV_FROM_ISR(out1)
+       SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r14, r3)
+       adds r3=8,r2                            // set up second base pointer
+       SSM_PSR_I(p15, p15, r14)                // restore psr.i
+       movl r14=ia64_leave_kernel
+       ;;
+       SAVE_REST
+       mov rp=r14
+       ;;
+       adds out2=16,r12                        // out2 = pointer to pt_regs
+       br.call.sptk.many b6=ia64_do_page_fault // ignore return address
+END(page_fault)
+
+ENTRY(non_syscall)
+       mov ar.rsc=r27                  // restore ar.rsc before SAVE_MIN_WITH_COVER
+       ;;
+       SAVE_MIN_WITH_COVER
+
+       // There is no particular reason for this code to be here, other than that
+       // there happens to be space here that would go unused otherwise.  If this
+       // fault ever gets "unreserved", simply moved the following code to a more
+       // suitable spot...
+
+       alloc r14=ar.pfs,0,0,2,0
+       MOV_FROM_IIM(out0)
+       add out1=16,sp
+       adds r3=8,r2                    // set up second base pointer for SAVE_REST
+
+       SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r15, r24)
+                                       // guarantee that interruption collection is on
+       SSM_PSR_I(p15, p15, r15)        // restore psr.i
+       movl r15=ia64_leave_kernel
+       ;;
+       SAVE_REST
+       mov rp=r15
+       ;;
+       br.call.sptk.many b6=ia64_bad_break     // avoid WAW on CFM and ignore return addr
+END(non_syscall)
+
+ENTRY(__interrupt)
+       DBG_FAULT(12)
+       mov r31=pr              // prepare to save predicates
+       ;;
+       SAVE_MIN_WITH_COVER     // uses r31; defines r2 and r3
+       SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r14)
+                               // ensure everybody knows psr.ic is back on
+       adds r3=8,r2            // set up second base pointer for SAVE_REST
+       ;;
+       SAVE_REST
+       ;;
+       MCA_RECOVER_RANGE(interrupt)
+       alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
+       MOV_FROM_IVR(out0, r8)  // pass cr.ivr as first arg
+       add out1=16,sp          // pass pointer to pt_regs as second arg
+       ;;
+       srlz.d                  // make sure we see the effect of cr.ivr
+       movl r14=ia64_leave_kernel
+       ;;
+       mov rp=r14
+       br.call.sptk.many b6=ia64_handle_irq
+END(__interrupt)
+
+       /*
+        * There is no particular reason for this code to be here, other than that
+        * there happens to be space here that would go unused otherwise.  If this
+        * fault ever gets "unreserved", simply moved the following code to a more
+        * suitable spot...
+        */
+
+ENTRY(dispatch_unaligned_handler)
+       SAVE_MIN_WITH_COVER
+       ;;
+       alloc r14=ar.pfs,0,0,2,0                // now it's safe (must be first in insn group!)
+       MOV_FROM_IFA(out0)
+       adds out1=16,sp
+
+       SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24)
+                                               // guarantee that interruption collection is on
+       SSM_PSR_I(p15, p15, r3)                 // restore psr.i
+       adds r3=8,r2                            // set up second base pointer
+       ;;
+       SAVE_REST
+       movl r14=ia64_leave_kernel
+       ;;
+       mov rp=r14
+       br.sptk.many ia64_prepare_handle_unaligned
+END(dispatch_unaligned_handler)
+
+       /*
+        * There is no particular reason for this code to be here, other than that
+        * there happens to be space here that would go unused otherwise.  If this
+        * fault ever gets "unreserved", simply moved the following code to a more
+        * suitable spot...
+        */
+
+ENTRY(dispatch_to_fault_handler)
+       /*
+        * Input:
+        *      psr.ic: off
+        *      r19:    fault vector number (e.g., 24 for General Exception)
+        *      r31:    contains saved predicates (pr)
+        */
+       SAVE_MIN_WITH_COVER_R19
+       alloc r14=ar.pfs,0,0,5,0
+       MOV_FROM_ISR(out1)
+       MOV_FROM_IFA(out2)
+       MOV_FROM_IIM(out3)
+       MOV_FROM_ITIR(out4)
+       ;;
+       SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, out0)
+                                               // guarantee that interruption collection is on
+       mov out0=r15
+       ;;
+       SSM_PSR_I(p15, p15, r3)                 // restore psr.i
+       adds r3=8,r2                            // set up second base pointer for SAVE_REST
+       ;;
+       SAVE_REST
+       movl r14=ia64_leave_kernel
+       ;;
+       mov rp=r14
+       br.call.sptk.many b6=ia64_fault
+END(dispatch_to_fault_handler)
+
        /*
         * Squatting in this space ...
         *
@@ -1686,11 +1688,10 @@ ENTRY(dispatch_illegal_op_fault)
        .prologue
        .body
        SAVE_MIN_WITH_COVER
-       ssm psr.ic | PSR_DEFAULT_BITS
-       ;;
-       srlz.i          // guarantee that interruption collection is on
+       SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24)
+                               // guarantee that interruption collection is on
        ;;
-(p15)  ssm psr.i       // restore psr.i
+       SSM_PSR_I(p15, p15, r3) // restore psr.i
        adds r3=8,r2    // set up second base pointer for SAVE_REST
        ;;
        alloc r14=ar.pfs,0,0,1,0        // must be first in insn group
@@ -1729,12 +1730,11 @@ END(dispatch_illegal_op_fault)
 ENTRY(dispatch_to_ia32_handler)
        SAVE_MIN
        ;;
-       mov r14=cr.isr
-       ssm psr.ic | PSR_DEFAULT_BITS
-       ;;
-       srlz.i                                  // guarantee that interruption collection is on
+       MOV_FROM_ISR(r14)
+       SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24)
+                               // guarantee that interruption collection is on
        ;;
-(p15)  ssm psr.i
+       SSM_PSR_I(p15, p15, r3)
        adds r3=8,r2            // Base pointer for SAVE_REST
        ;;
        SAVE_REST
index 74b6d670aaef2d42a4c7574a3543b3fb26e6dd98..292e214a3b84ab323c959e4f7b68283d0275bd2f 100644 (file)
@@ -2,6 +2,7 @@
 #include <asm/cache.h>
 
 #include "entry.h"
+#include "paravirt_inst.h"
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 /* read ar.itc in advance, and use it before leaving bank 0 */
  * Note that psr.ic is NOT turned on by this macro.  This is so that
  * we can pass interruption state as arguments to a handler.
  */
-#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA,WORKAROUND)                                           \
+#define IA64_NATIVE_DO_SAVE_MIN(__COVER,SAVE_IFS,EXTRA,WORKAROUND)                             \
        mov r16=IA64_KR(CURRENT);       /* M */                                                 \
        mov r27=ar.rsc;                 /* M */                                                 \
        mov r20=r1;                     /* A */                                                 \
        mov r25=ar.unat;                /* M */                                                 \
-       mov r29=cr.ipsr;                /* M */                                                 \
+       MOV_FROM_IPSR(p0,r29);          /* M */                                                 \
        mov r26=ar.pfs;                 /* I */                                                 \
-       mov r28=cr.iip;                 /* M */                                                 \
+       MOV_FROM_IIP(r28);                      /* M */                                         \
        mov r21=ar.fpsr;                /* M */                                                 \
-       COVER;                          /* B;; (or nothing) */                                  \
+       __COVER;                                /* B;; (or nothing) */                          \
        ;;                                                                                      \
        adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16;                                         \
        ;;                                                                                      \
 1:                                             \
        .pred.rel "mutex", pKStk, pUStk
 
-#define SAVE_MIN_WITH_COVER    DO_SAVE_MIN(cover, mov r30=cr.ifs, , RSE_WORKAROUND)
-#define SAVE_MIN_WITH_COVER_R19        DO_SAVE_MIN(cover, mov r30=cr.ifs, mov r15=r19, RSE_WORKAROUND)
+#define SAVE_MIN_WITH_COVER    DO_SAVE_MIN(COVER, mov r30=cr.ifs, , RSE_WORKAROUND)
+#define SAVE_MIN_WITH_COVER_R19        DO_SAVE_MIN(COVER, mov r30=cr.ifs, mov r15=r19, RSE_WORKAROUND)
 #define SAVE_MIN                       DO_SAVE_MIN(     , mov r30=r0, , )
index e83e2ea3b3e0787ea673ae7451ae2855196f1c38..29aad349e0c4fafd49eb6b8c07bce2f3db3a24d6 100644 (file)
@@ -321,7 +321,8 @@ module_alloc (unsigned long size)
 void
 module_free (struct module *mod, void *module_region)
 {
-       if (mod->arch.init_unw_table && module_region == mod->module_init) {
+       if (mod && mod->arch.init_unw_table &&
+           module_region == mod->module_init) {
                unw_remove_unwind_table(mod->arch.init_unw_table);
                mod->arch.init_unw_table = NULL;
        }
diff --git a/arch/ia64/kernel/nr-irqs.c b/arch/ia64/kernel/nr-irqs.c
new file mode 100644 (file)
index 0000000..1ae0491
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * calculate
+ * NR_IRQS = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, FOO_NR_IRQS...)
+ * depending on config.
+ * This must be calculated before processing asm-offset.c.
+ */
+
+#define ASM_OFFSETS_C 1
+
+#include <linux/kbuild.h>
+#include <linux/threads.h>
+#include <asm-ia64/native/irq.h>
+
+void foo(void)
+{
+       union paravirt_nr_irqs_max {
+               char ia64_native_nr_irqs[IA64_NATIVE_NR_IRQS];
+#ifdef CONFIG_XEN
+               char xen_nr_irqs[XEN_NR_IRQS];
+#endif
+       };
+
+       DEFINE(NR_IRQS, sizeof (union paravirt_nr_irqs_max));
+}
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
new file mode 100644 (file)
index 0000000..afaf5b9
--- /dev/null
@@ -0,0 +1,369 @@
+/******************************************************************************
+ * arch/ia64/kernel/paravirt.c
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *     Yaozu (Eddie) Dong <eddie.dong@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/init.h>
+
+#include <linux/compiler.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include <asm/iosapic.h>
+#include <asm/paravirt.h>
+
+/***************************************************************************
+ * general info
+ */
+struct pv_info pv_info = {
+       .kernel_rpl = 0,
+       .paravirt_enabled = 0,
+       .name = "bare hardware"
+};
+
+/***************************************************************************
+ * pv_init_ops
+ * initialization hooks.
+ */
+
+struct pv_init_ops pv_init_ops;
+
+/***************************************************************************
+ * pv_cpu_ops
+ * intrinsics hooks.
+ */
+
+/* ia64_native_xxx are macros so that we have to make them real functions */
+
+#define DEFINE_VOID_FUNC1(name)                                        \
+       static void                                             \
+       ia64_native_ ## name ## _func(unsigned long arg)        \
+       {                                                       \
+               ia64_native_ ## name(arg);                      \
+       }                                                       \
+
+#define DEFINE_VOID_FUNC2(name)                                        \
+       static void                                             \
+       ia64_native_ ## name ## _func(unsigned long arg0,       \
+                                     unsigned long arg1)       \
+       {                                                       \
+               ia64_native_ ## name(arg0, arg1);               \
+       }                                                       \
+
+#define DEFINE_FUNC0(name)                     \
+       static unsigned long                    \
+       ia64_native_ ## name ## _func(void)     \
+       {                                       \
+               return ia64_native_ ## name();  \
+       }
+
+#define DEFINE_FUNC1(name, type)                       \
+       static unsigned long                            \
+       ia64_native_ ## name ## _func(type arg)         \
+       {                                               \
+               return ia64_native_ ## name(arg);       \
+       }                                               \
+
+DEFINE_VOID_FUNC1(fc);
+DEFINE_VOID_FUNC1(intrin_local_irq_restore);
+
+DEFINE_VOID_FUNC2(ptcga);
+DEFINE_VOID_FUNC2(set_rr);
+
+DEFINE_FUNC0(get_psr_i);
+
+DEFINE_FUNC1(thash, unsigned long);
+DEFINE_FUNC1(get_cpuid, int);
+DEFINE_FUNC1(get_pmd, int);
+DEFINE_FUNC1(get_rr, unsigned long);
+
+static void
+ia64_native_ssm_i_func(void)
+{
+       ia64_native_ssm(IA64_PSR_I);
+}
+
+static void
+ia64_native_rsm_i_func(void)
+{
+       ia64_native_rsm(IA64_PSR_I);
+}
+
+static void
+ia64_native_set_rr0_to_rr4_func(unsigned long val0, unsigned long val1,
+                               unsigned long val2, unsigned long val3,
+                               unsigned long val4)
+{
+       ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4);
+}
+
+#define CASE_GET_REG(id)                               \
+       case _IA64_REG_ ## id:                          \
+       res = ia64_native_getreg(_IA64_REG_ ## id);     \
+       break;
+#define CASE_GET_AR(id) CASE_GET_REG(AR_ ## id)
+#define CASE_GET_CR(id) CASE_GET_REG(CR_ ## id)
+
+unsigned long
+ia64_native_getreg_func(int regnum)
+{
+       unsigned long res = -1;
+       switch (regnum) {
+       CASE_GET_REG(GP);
+       CASE_GET_REG(IP);
+       CASE_GET_REG(PSR);
+       CASE_GET_REG(TP);
+       CASE_GET_REG(SP);
+
+       CASE_GET_AR(KR0);
+       CASE_GET_AR(KR1);
+       CASE_GET_AR(KR2);
+       CASE_GET_AR(KR3);
+       CASE_GET_AR(KR4);
+       CASE_GET_AR(KR5);
+       CASE_GET_AR(KR6);
+       CASE_GET_AR(KR7);
+       CASE_GET_AR(RSC);
+       CASE_GET_AR(BSP);
+       CASE_GET_AR(BSPSTORE);
+       CASE_GET_AR(RNAT);
+       CASE_GET_AR(FCR);
+       CASE_GET_AR(EFLAG);
+       CASE_GET_AR(CSD);
+       CASE_GET_AR(SSD);
+       CASE_GET_AR(CFLAG);
+       CASE_GET_AR(FSR);
+       CASE_GET_AR(FIR);
+       CASE_GET_AR(FDR);
+       CASE_GET_AR(CCV);
+       CASE_GET_AR(UNAT);
+       CASE_GET_AR(FPSR);
+       CASE_GET_AR(ITC);
+       CASE_GET_AR(PFS);
+       CASE_GET_AR(LC);
+       CASE_GET_AR(EC);
+
+       CASE_GET_CR(DCR);
+       CASE_GET_CR(ITM);
+       CASE_GET_CR(IVA);
+       CASE_GET_CR(PTA);
+       CASE_GET_CR(IPSR);
+       CASE_GET_CR(ISR);
+       CASE_GET_CR(IIP);
+       CASE_GET_CR(IFA);
+       CASE_GET_CR(ITIR);
+       CASE_GET_CR(IIPA);
+       CASE_GET_CR(IFS);
+       CASE_GET_CR(IIM);
+       CASE_GET_CR(IHA);
+       CASE_GET_CR(LID);
+       CASE_GET_CR(IVR);
+       CASE_GET_CR(TPR);
+       CASE_GET_CR(EOI);
+       CASE_GET_CR(IRR0);
+       CASE_GET_CR(IRR1);
+       CASE_GET_CR(IRR2);
+       CASE_GET_CR(IRR3);
+       CASE_GET_CR(ITV);
+       CASE_GET_CR(PMV);
+       CASE_GET_CR(CMCV);
+       CASE_GET_CR(LRR0);
+       CASE_GET_CR(LRR1);
+
+       default:
+               printk(KERN_CRIT "wrong_getreg %d\n", regnum);
+               break;
+       }
+       return res;
+}
+
+#define CASE_SET_REG(id)                               \
+       case _IA64_REG_ ## id:                          \
+       ia64_native_setreg(_IA64_REG_ ## id, val);      \
+       break;
+#define CASE_SET_AR(id) CASE_SET_REG(AR_ ## id)
+#define CASE_SET_CR(id) CASE_SET_REG(CR_ ## id)
+
+void
+ia64_native_setreg_func(int regnum, unsigned long val)
+{
+       switch (regnum) {
+       case _IA64_REG_PSR_L:
+               ia64_native_setreg(_IA64_REG_PSR_L, val);
+               ia64_dv_serialize_data();
+               break;
+       CASE_SET_REG(SP);
+       CASE_SET_REG(GP);
+
+       CASE_SET_AR(KR0);
+       CASE_SET_AR(KR1);
+       CASE_SET_AR(KR2);
+       CASE_SET_AR(KR3);
+       CASE_SET_AR(KR4);
+       CASE_SET_AR(KR5);
+       CASE_SET_AR(KR6);
+       CASE_SET_AR(KR7);
+       CASE_SET_AR(RSC);
+       CASE_SET_AR(BSP);
+       CASE_SET_AR(BSPSTORE);
+       CASE_SET_AR(RNAT);
+       CASE_SET_AR(FCR);
+       CASE_SET_AR(EFLAG);
+       CASE_SET_AR(CSD);
+       CASE_SET_AR(SSD);
+       CASE_SET_AR(CFLAG);
+       CASE_SET_AR(FSR);
+       CASE_SET_AR(FIR);
+       CASE_SET_AR(FDR);
+       CASE_SET_AR(CCV);
+       CASE_SET_AR(UNAT);
+       CASE_SET_AR(FPSR);
+       CASE_SET_AR(ITC);
+       CASE_SET_AR(PFS);
+       CASE_SET_AR(LC);
+       CASE_SET_AR(EC);
+
+       CASE_SET_CR(DCR);
+       CASE_SET_CR(ITM);
+       CASE_SET_CR(IVA);
+       CASE_SET_CR(PTA);
+       CASE_SET_CR(IPSR);
+       CASE_SET_CR(ISR);
+       CASE_SET_CR(IIP);
+       CASE_SET_CR(IFA);
+       CASE_SET_CR(ITIR);
+       CASE_SET_CR(IIPA);
+       CASE_SET_CR(IFS);
+       CASE_SET_CR(IIM);
+       CASE_SET_CR(IHA);
+       CASE_SET_CR(LID);
+       CASE_SET_CR(IVR);
+       CASE_SET_CR(TPR);
+       CASE_SET_CR(EOI);
+       CASE_SET_CR(IRR0);
+       CASE_SET_CR(IRR1);
+       CASE_SET_CR(IRR2);
+       CASE_SET_CR(IRR3);
+       CASE_SET_CR(ITV);
+       CASE_SET_CR(PMV);
+       CASE_SET_CR(CMCV);
+       CASE_SET_CR(LRR0);
+       CASE_SET_CR(LRR1);
+       default:
+               printk(KERN_CRIT "wrong setreg %d\n", regnum);
+               break;
+       }
+}
+
+struct pv_cpu_ops pv_cpu_ops = {
+       .fc             = ia64_native_fc_func,
+       .thash          = ia64_native_thash_func,
+       .get_cpuid      = ia64_native_get_cpuid_func,
+       .get_pmd        = ia64_native_get_pmd_func,
+       .ptcga          = ia64_native_ptcga_func,
+       .get_rr         = ia64_native_get_rr_func,
+       .set_rr         = ia64_native_set_rr_func,
+       .set_rr0_to_rr4 = ia64_native_set_rr0_to_rr4_func,
+       .ssm_i          = ia64_native_ssm_i_func,
+       .getreg         = ia64_native_getreg_func,
+       .setreg         = ia64_native_setreg_func,
+       .rsm_i          = ia64_native_rsm_i_func,
+       .get_psr_i      = ia64_native_get_psr_i_func,
+       .intrin_local_irq_restore
+                       = ia64_native_intrin_local_irq_restore_func,
+};
+EXPORT_SYMBOL(pv_cpu_ops);
+
+/******************************************************************************
+ * replacement of hand written assembly codes.
+ */
+
+void
+paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch)
+{
+       extern unsigned long paravirt_switch_to_targ;
+       extern unsigned long paravirt_leave_syscall_targ;
+       extern unsigned long paravirt_work_processed_syscall_targ;
+       extern unsigned long paravirt_leave_kernel_targ;
+
+       paravirt_switch_to_targ = cpu_asm_switch->switch_to;
+       paravirt_leave_syscall_targ = cpu_asm_switch->leave_syscall;
+       paravirt_work_processed_syscall_targ =
+               cpu_asm_switch->work_processed_syscall;
+       paravirt_leave_kernel_targ = cpu_asm_switch->leave_kernel;
+}
+
+/***************************************************************************
+ * pv_iosapic_ops
+ * iosapic read/write hooks.
+ */
+
+static unsigned int
+ia64_native_iosapic_read(char __iomem *iosapic, unsigned int reg)
+{
+       return __ia64_native_iosapic_read(iosapic, reg);
+}
+
+static void
+ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
+{
+       __ia64_native_iosapic_write(iosapic, reg, val);
+}
+
+struct pv_iosapic_ops pv_iosapic_ops = {
+       .pcat_compat_init = ia64_native_iosapic_pcat_compat_init,
+       .get_irq_chip = ia64_native_iosapic_get_irq_chip,
+
+       .__read = ia64_native_iosapic_read,
+       .__write = ia64_native_iosapic_write,
+};
+
+/***************************************************************************
+ * pv_irq_ops
+ * irq operations
+ */
+
+struct pv_irq_ops pv_irq_ops = {
+       .register_ipi = ia64_native_register_ipi,
+
+       .assign_irq_vector = ia64_native_assign_irq_vector,
+       .free_irq_vector = ia64_native_free_irq_vector,
+       .register_percpu_irq = ia64_native_register_percpu_irq,
+
+       .resend_irq = ia64_native_resend_irq,
+};
+
+/***************************************************************************
+ * pv_time_ops
+ * time operations
+ */
+
+static int
+ia64_native_do_steal_accounting(unsigned long *new_itm)
+{
+       return 0;
+}
+
+struct pv_time_ops pv_time_ops = {
+       .do_steal_accounting = ia64_native_do_steal_accounting,
+};
diff --git a/arch/ia64/kernel/paravirt_inst.h b/arch/ia64/kernel/paravirt_inst.h
new file mode 100644 (file)
index 0000000..5cad6fb
--- /dev/null
@@ -0,0 +1,29 @@
+/******************************************************************************
+ * linux/arch/ia64/xen/paravirt_inst.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifdef __IA64_ASM_PARAVIRTUALIZED_XEN
+#include <asm/xen/inst.h>
+#include <asm/xen/minstate.h>
+#else
+#include <asm/native/inst.h>
+#endif
+
diff --git a/arch/ia64/kernel/paravirtentry.S b/arch/ia64/kernel/paravirtentry.S
new file mode 100644 (file)
index 0000000..2f42fcb
--- /dev/null
@@ -0,0 +1,60 @@
+/******************************************************************************
+ * linux/arch/ia64/xen/paravirtentry.S
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 <asm/asmmacro.h>
+#include <asm/asm-offsets.h>
+#include "entry.h"
+
+#define DATA8(sym, init_value)                 \
+       .pushsection .data.read_mostly ;        \
+       .align 8 ;                              \
+       .global sym ;                           \
+       sym: ;                                  \
+       data8 init_value ;                      \
+       .popsection
+
+#define BRANCH(targ, reg, breg)                \
+       movl reg=targ ;                 \
+       ;;                              \
+       ld8 reg=[reg] ;                 \
+       ;;                              \
+       mov breg=reg ;                  \
+       br.cond.sptk.many breg
+
+#define BRANCH_PROC(sym, reg, breg)                            \
+       DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \
+       GLOBAL_ENTRY(paravirt_ ## sym) ;                        \
+               BRANCH(paravirt_ ## sym ## _targ, reg, breg) ;  \
+       END(paravirt_ ## sym)
+
+#define BRANCH_PROC_UNWINFO(sym, reg, breg)                    \
+       DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \
+       GLOBAL_ENTRY(paravirt_ ## sym) ;                        \
+               PT_REGS_UNWIND_INFO(0) ;                        \
+               BRANCH(paravirt_ ## sym ## _targ, reg, breg) ;  \
+       END(paravirt_ ## sym)
+
+
+BRANCH_PROC(switch_to, r22, b7)
+BRANCH_PROC_UNWINFO(leave_syscall, r22, b7)
+BRANCH_PROC(work_processed_syscall, r2, b7)
+BRANCH_PROC_UNWINFO(leave_kernel, r22, b7)
index 632cda8f2e7667fab870c85dd97af1fb2ed118f7..e5c2de9b29a5738484af3265f5713b286bbc8906 100644 (file)
@@ -51,6 +51,7 @@
 #include <asm/mca.h>
 #include <asm/meminit.h>
 #include <asm/page.h>
+#include <asm/paravirt.h>
 #include <asm/patch.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -341,6 +342,8 @@ reserve_memory (void)
        rsvd_region[n].end   = (unsigned long) ia64_imva(_end);
        n++;
 
+       n += paravirt_reserve_memory(&rsvd_region[n]);
+
 #ifdef CONFIG_BLK_DEV_INITRD
        if (ia64_boot_param->initrd_start) {
                rsvd_region[n].start = (unsigned long)__va(ia64_boot_param->initrd_start);
@@ -519,6 +522,8 @@ setup_arch (char **cmdline_p)
 {
        unw_init();
 
+       paravirt_arch_setup_early();
+
        ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist);
 
        *cmdline_p = __va(ia64_boot_param->command_line);
@@ -583,6 +588,9 @@ setup_arch (char **cmdline_p)
        acpi_boot_init();
 #endif
 
+       paravirt_banner();
+       paravirt_arch_setup_console(cmdline_p);
+
 #ifdef CONFIG_VT
        if (!conswitchp) {
 # if defined(CONFIG_DUMMY_CONSOLE)
@@ -602,6 +610,8 @@ setup_arch (char **cmdline_p)
 #endif
 
        /* enable IA-64 Machine Check Abort Handling unless disabled */
+       if (paravirt_arch_setup_nomca())
+               nomca = 1;
        if (!nomca)
                ia64_mca_init();
 
index 9d1d429c6c59a6c7b8f111cd43abeaa0b50ca6ae..03f1a9908afc6a3bb547674362cdda704b2ebcc0 100644 (file)
@@ -50,6 +50,7 @@
 #include <asm/machvec.h>
 #include <asm/mca.h>
 #include <asm/page.h>
+#include <asm/paravirt.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -642,6 +643,7 @@ void __devinit smp_prepare_boot_cpu(void)
        cpu_set(smp_processor_id(), cpu_online_map);
        cpu_set(smp_processor_id(), cpu_callin_map);
        per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
+       paravirt_post_smp_prepare_boot_cpu();
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
index aad1b7b1fff95e19ee19d3175ce3f9a5a7c8c1a6..65c10a42c88f37fbb998012a8f293bd4003f1485 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/machvec.h>
 #include <asm/delay.h>
 #include <asm/hw_irq.h>
+#include <asm/paravirt.h>
 #include <asm/ptrace.h>
 #include <asm/sal.h>
 #include <asm/sections.h>
@@ -48,6 +49,15 @@ EXPORT_SYMBOL(last_cli_ip);
 
 #endif
 
+#ifdef CONFIG_PARAVIRT
+static void
+paravirt_clocksource_resume(void)
+{
+       if (pv_time_ops.clocksource_resume)
+               pv_time_ops.clocksource_resume();
+}
+#endif
+
 static struct clocksource clocksource_itc = {
        .name           = "itc",
        .rating         = 350,
@@ -56,6 +66,9 @@ static struct clocksource clocksource_itc = {
        .mult           = 0, /*to be calculated*/
        .shift          = 16,
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+#ifdef CONFIG_PARAVIRT
+       .resume         = paravirt_clocksource_resume,
+#endif
 };
 static struct clocksource *itc_clocksource;
 
@@ -157,6 +170,9 @@ timer_interrupt (int irq, void *dev_id)
 
        profile_tick(CPU_PROFILING);
 
+       if (paravirt_do_steal_accounting(&new_itm))
+               goto skip_process_time_accounting;
+
        while (1) {
                update_process_times(user_mode(get_irq_regs()));
 
@@ -186,6 +202,8 @@ timer_interrupt (int irq, void *dev_id)
                local_irq_disable();
        }
 
+skip_process_time_accounting:
+
        do {
                /*
                 * If we're too close to the next clock tick for
@@ -335,6 +353,11 @@ ia64_init_itm (void)
                 */
                clocksource_itc.rating = 50;
 
+       paravirt_init_missing_ticks_accounting(smp_processor_id());
+
+       /* avoid softlock up message when cpu is unplug and plugged again. */
+       touch_softlockup_watchdog();
+
        /* Setup the CPU local timer tick */
        ia64_cpu_local_tick();
 
index 5929ab10a289d8adeec09ee13ba0a4b03ed4d2ca..5a77206c2492e0c000140a18a179d7d461ab3dee 100644 (file)
@@ -4,7 +4,6 @@
 #include <asm/system.h>
 #include <asm/pgtable.h>
 
-#define LOAD_OFFSET    (KERNEL_START - KERNEL_TR_PAGE_SIZE)
 #include <asm-generic/vmlinux.lds.h>
 
 #define IVT_TEXT                                                       \
index b556419612329a26fdf4493b8d4c1ee43073d4a7..dfd868b683640634f7d128f883f53165b73595fb 100644 (file)
@@ -522,8 +522,8 @@ static int __init rtlx_module_init(void)
                atomic_set(&channel_wqs[i].in_open, 0);
                mutex_init(&channel_wqs[i].mutex);
 
-               dev = device_create(mt_class, NULL, MKDEV(major, i),
-                                   "%s%d", module_name, i);
+               dev = device_create_drvdata(mt_class, NULL, MKDEV(major, i),
+                                           NULL, "%s%d", module_name, i);
                if (IS_ERR(dev)) {
                        err = PTR_ERR(dev);
                        goto out_chrdev;
index 28b012ab8dcb7ae6c06eaac75789cbf08d861a4c..66e3e3fb311f9a413ffb3dbc58aa9174fe101fe5 100644 (file)
@@ -576,7 +576,8 @@ static int __init sbprof_tb_init(void)
 
        tb_class = tbc;
 
-       dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), "tb");
+       dev = device_create_drvdata(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0),
+                                   NULL, "tb");
        if (IS_ERR(dev)) {
                err = PTR_ERR(dev);
                goto out_class;
index de88972c58961a99664aab3a540072d7d35677ef..737ebf9d12bb9aca170de68098c758f796d46b0f 100644 (file)
@@ -112,6 +112,7 @@ config PPC
        select HAVE_FTRACE
        select HAVE_IDE
        select HAVE_KPROBES
+       select HAVE_ARCH_KGDB
        select HAVE_KRETPROBES
        select HAVE_LMB
        select HAVE_DMA_ATTRS if PPC64
@@ -199,7 +200,7 @@ config ARCH_HIBERNATION_POSSIBLE
 
 config ARCH_SUSPEND_POSSIBLE
        def_bool y
-       depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200
+       depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx
 
 config PPC_DCR_NATIVE
        bool
@@ -568,11 +569,15 @@ config FSL_GTM
 config MCA
        bool
 
+# Platforms that what PCI turned unconditionally just do select PCI
+# in their config node.  Platforms that want to choose at config
+# time should select PPC_PCI_CHOICE
+config PPC_PCI_CHOICE
+       bool
+
 config PCI
-       bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
-               || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \
-               || PPC_PS3 || 44x
-       default y if !40x && !CPM2 && !8xx && !PPC_MPC512x && !PPC_83xx \
+       bool "PCI support" if PPC_PCI_CHOICE
+       default y if !40x && !CPM2 && !8xx && !PPC_83xx \
                && !PPC_85xx && !PPC_86xx
        default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
        default PCI_QSPAN if !4xx && !CPM2 && 8xx
index 2840ab69ef4ec73c28be7dc6acfcea9c2b5c020e..8c8aadbe9563ef14d3671929f2b6c17210e7c354 100644 (file)
@@ -41,22 +41,6 @@ config HCALL_STATS
          This option will add a small amount of overhead to all hypervisor
          calls.
 
-config DEBUGGER
-       bool "Enable debugger hooks"
-       depends on DEBUG_KERNEL
-       help
-         Include in-kernel hooks for kernel debuggers. Unless you are
-         intending to debug the kernel, say N here.
-
-config KGDB
-       bool "Include kgdb kernel debugger"
-       depends on DEBUGGER && (BROKEN || PPC_GEN550 || 4xx)
-       select DEBUG_INFO
-       help
-         Include in-kernel hooks for kgdb, the Linux kernel source level
-         debugger.  See <http://kgdb.sourceforge.net/> for more information.
-         Unless you are intending to debug the kernel, say N here.
-
 config CODE_PATCHING_SELFTEST
        bool "Run self-tests of the code-patching code."
        depends on DEBUG_KERNEL
@@ -67,36 +51,9 @@ config FTR_FIXUP_SELFTEST
        depends on DEBUG_KERNEL
        default n
 
-choice
-       prompt "Serial Port"
-       depends on KGDB
-       default KGDB_TTYS1
-
-config KGDB_TTYS0
-       bool "ttyS0"
-
-config KGDB_TTYS1
-       bool "ttyS1"
-
-config KGDB_TTYS2
-       bool "ttyS2"
-
-config KGDB_TTYS3
-       bool "ttyS3"
-
-endchoice
-
-config KGDB_CONSOLE
-       bool "Enable serial console thru kgdb port"
-       depends on KGDB && 8xx || CPM2
-       help
-         If you enable this, all serial console messages will be sent
-         over the gdb stub.
-         If unsure, say N.
-
 config XMON
        bool "Include xmon kernel debugger"
-       depends on DEBUGGER
+       depends on DEBUG_KERNEL
        help
          Include in-kernel hooks for the xmon kernel monitor/debugger.
          Unless you are intending to debug the kernel, say N here.
@@ -126,6 +83,11 @@ config XMON_DISASSEMBLY
          to say Y here, unless you're building for a memory-constrained
          system.
 
+config DEBUGGER
+       bool
+       depends on KGDB || XMON
+       default y
+
 config IRQSTACKS
        bool "Use separate kernel stacks when processing interrupts"
        help
index 19f83c8f219dcc7ba0fac3d88166b687e143f86b..14174aa240744783d6c0d77748a9b714d6cebea0 100644 (file)
@@ -163,12 +163,12 @@ quiet_cmd_flex = FLEX    $@
       cmd_flex = $(FLEX) -o$@ $<; cp $@ $@_shipped
 
 $(obj)/dtc-src/dtc-parser.tab.c: $(src)/dtc-src/dtc-parser.y FORCE
-     $(call if_changed,bison)
+       $(call if_changed,bison)
 
 $(obj)/dtc-src/dtc-parser.tab.h: $(obj)/dtc-src/dtc-parser.tab.c
 
 $(obj)/dtc-src/dtc-lexer.lex.c: $(src)/dtc-src/dtc-lexer.l FORCE
-     $(call if_changed,flex)
+       $(call if_changed,flex)
 endif
 
 #############
index 705c23c14f321d8b813d11bae54aa2963491074d..2544f3ecd6e9096fb60d06807176c58ebe83c7a0 100644 (file)
        #address-cells = <1>;
        #size-cells = <1>;
 
+       aliases {
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+
+               serial0 = &serial0;
+               serial1 = &serial1;
+
+               pci0 = &pci0;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells =<0>;
@@ -78,7 +88,7 @@
 
                };
 
-               ethernet@6200 {
+               enet0: ethernet@6200 {
                        linux,network-index = <0>;
                        #size-cells = <0>;
                        device_type = "network";
                        phy-handle = <&phy8>;
                };
 
-               ethernet@6600 {
+               enet1: ethernet@6600 {
                        linux,network-index = <1>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        phy-handle = <&phy9>;
                };
 
-               serial@7808 {
+               serial0: serial@7808 {
                        device_type = "serial";
                        compatible = "ns16550";
                        reg = <0x7808 0x200>;
                        interrupt-parent = <&mpic>;
                };
 
-               serial@7c08 {
+               serial1: serial@7c08 {
                        device_type = "serial";
                        compatible = "ns16550";
                        reg = <0x7c08 0x200>;
                        compatible = "chrp,open-pic";
                        device_type = "open-pic";
                };
-               pci@1000 {
+               pci0: pci@1000 {
                        compatible = "tsi108-pci";
                        device_type = "pci";
                        #interrupt-cells = <1>;
                        };
                };
        };
-       chosen {
-               linux,stdout-path = "/tsi108@c0000000/serial@7808";
-       };
-
 };
index 3664fb5840266a551ef06986a27585fd03ed4b46..2a94ae0dc8b875c5c080e69c894838ca21545263 100644 (file)
                        reg = <0x200 0x100>;
                };
 
-               i2c@3000 {
+               sleep-nexus {
                        #address-cells = <1>;
-                       #size-cells = <0>;
-                       cell-index = <0>;
-                       compatible = "fsl-i2c";
-                       reg = <0x3000 0x100>;
-                       interrupts = <14 0x8>;
-                       interrupt-parent = <&ipic>;
-                       dfsrr;
-                       rtc@68 {
-                               compatible = "dallas,ds1339";
-                               reg = <0x68>;
+                       #size-cells = <1>;
+                       compatible = "simple-bus";
+                       sleep = <&pmc 0x03000000>;
+                       ranges;
+
+                       i2c@3000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               cell-index = <0>;
+                               compatible = "fsl-i2c";
+                               reg = <0x3000 0x100>;
+                               interrupts = <14 0x8>;
+                               interrupt-parent = <&ipic>;
+                               dfsrr;
+                               rtc@68 {
+                                       compatible = "dallas,ds1339";
+                                       reg = <0x68>;
+                               };
+                       };
+
+                       crypto@30000 {
+                               compatible = "fsl,sec2.2", "fsl,sec2.1",
+                                            "fsl,sec2.0";
+                               reg = <0x30000 0x10000>;
+                               interrupts = <11 0x8>;
+                               interrupt-parent = <&ipic>;
+                               fsl,num-channels = <1>;
+                               fsl,channel-fifo-len = <24>;
+                               fsl,exec-units-mask = <0x4c>;
+                               fsl,descriptor-types-mask = <0x0122003f>;
                        };
                };
 
                        interrupt-parent = <&ipic>;
                        interrupts = <38 0x8>;
                        phy_type = "utmi_wide";
+                       sleep = <&pmc 0x00300000>;
                };
 
-               mdio@24520 {
+               enet0: ethernet@24000 {
                        #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "fsl,gianfar-mdio";
-                       reg = <0x24520 0x20>;
-                       phy1: ethernet-phy@1 {
-                               interrupt-parent = <&ipic>;
-                               interrupts = <19 0x8>;
-                               reg = <0x1>;
-                               device_type = "ethernet-phy";
-                       };
-                       phy4: ethernet-phy@4 {
-                               interrupt-parent = <&ipic>;
-                               interrupts = <20 0x8>;
-                               reg = <0x4>;
-                               device_type = "ethernet-phy";
-                       };
-               };
+                       #size-cells = <1>;
+                       sleep = <&pmc 0x20000000>;
+                       ranges;
 
-               enet0: ethernet@24000 {
                        cell-index = <0>;
                        device_type = "network";
                        model = "eTSEC";
-                       compatible = "gianfar";
+                       compatible = "gianfar", "simple-bus";
                        reg = <0x24000 0x1000>;
                        local-mac-address = [ 00 00 00 00 00 00 ];
                        interrupts = <37 0x8 36 0x8 35 0x8>;
                        interrupt-parent = <&ipic>;
                        phy-handle = < &phy1 >;
+                       fsl,magic-packet;
+
+                       mdio@24520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-mdio";
+                               reg = <0x24520 0x20>;
+                               phy1: ethernet-phy@1 {
+                                       interrupt-parent = <&ipic>;
+                                       interrupts = <19 0x8>;
+                                       reg = <0x1>;
+                                       device_type = "ethernet-phy";
+                               };
+                               phy4: ethernet-phy@4 {
+                                       interrupt-parent = <&ipic>;
+                                       interrupts = <20 0x8>;
+                                       reg = <0x4>;
+                                       device_type = "ethernet-phy";
+                               };
+                       };
                };
 
                enet1: ethernet@25000 {
                        interrupts = <34 0x8 33 0x8 32 0x8>;
                        interrupt-parent = <&ipic>;
                        phy-handle = < &phy4 >;
+                       sleep = <&pmc 0x10000000>;
+                       fsl,magic-packet;
                };
 
                serial0: serial@4500 {
                        interrupt-parent = <&ipic>;
                };
 
-               crypto@30000 {
-                       compatible = "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
-                       reg = <0x30000 0x10000>;
-                       interrupts = <11 0x8>;
-                       interrupt-parent = <&ipic>;
-                       fsl,num-channels = <1>;
-                       fsl,channel-fifo-len = <24>;
-                       fsl,exec-units-mask = <0x4c>;
-                       fsl,descriptor-types-mask = <0x0122003f>;
-               };
-
                /* IPIC
                 * interrupts cell = <intr #, sense>
                 * sense values match linux IORESOURCE_IRQ_* defines:
                        reg = <0x700 0x100>;
                        device_type = "ipic";
                };
+
+               pmc: power@b00 {
+                       compatible = "fsl,mpc8313-pmc", "fsl,mpc8349-pmc";
+                       reg = <0xb00 0x100 0xa00 0x100>;
+                       interrupts = <80 8>;
+                       interrupt-parent = <&ipic>;
+                       fsl,mpc8313-wakeup-timer = <&gtm1>;
+
+                       /* Remove this (or change to "okay") if you have
+                        * a REVA3 or later board, if you apply one of the
+                        * workarounds listed in section 8.5 of the board
+                        * manual, or if you are adapting this device tree
+                        * to a different board.
+                        */
+                       status = "fail";
+               };
+
+               gtm1: timer@500 {
+                       compatible = "fsl,mpc8313-gtm", "fsl,gtm";
+                       reg = <0x500 0x100>;
+                       interrupts = <90 8 78 8 84 8 72 8>;
+                       interrupt-parent = <&ipic>;
+               };
+
+               timer@600 {
+                       compatible = "fsl,mpc8313-gtm", "fsl,gtm";
+                       reg = <0x600 0x100>;
+                       interrupts = <91 8 79 8 85 8 73 8>;
+                       interrupt-parent = <&ipic>;
+               };
        };
 
-       pci0: pci@e0008500 {
-               cell-index = <1>;
-               interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
-               interrupt-map = <
-
-                               /* IDSEL 0x0E -mini PCI */
-                                0x7000 0x0 0x0 0x1 &ipic 18 0x8
-                                0x7000 0x0 0x0 0x2 &ipic 18 0x8
-                                0x7000 0x0 0x0 0x3 &ipic 18 0x8
-                                0x7000 0x0 0x0 0x4 &ipic 18 0x8
-
-                               /* IDSEL 0x0F - PCI slot */
-                                0x7800 0x0 0x0 0x1 &ipic 17 0x8
-                                0x7800 0x0 0x0 0x2 &ipic 18 0x8
-                                0x7800 0x0 0x0 0x3 &ipic 17 0x8
-                                0x7800 0x0 0x0 0x4 &ipic 18 0x8>;
-               interrupt-parent = <&ipic>;
-               interrupts = <66 0x8>;
-               bus-range = <0x0 0x0>;
-               ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
-                         0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
-                         0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
-               clock-frequency = <66666666>;
-               #interrupt-cells = <1>;
-               #size-cells = <2>;
-               #address-cells = <3>;
-               reg = <0xe0008500 0x100>;
-               compatible = "fsl,mpc8349-pci";
-               device_type = "pci";
+       sleep-nexus {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               sleep = <&pmc 0x00010000>;
+               ranges;
+
+               pci0: pci@e0008500 {
+                       cell-index = <1>;
+                       interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+                       interrupt-map = <
+                                       /* IDSEL 0x0E -mini PCI */
+                                        0x7000 0x0 0x0 0x1 &ipic 18 0x8
+                                        0x7000 0x0 0x0 0x2 &ipic 18 0x8
+                                        0x7000 0x0 0x0 0x3 &ipic 18 0x8
+                                        0x7000 0x0 0x0 0x4 &ipic 18 0x8
+
+                                       /* IDSEL 0x0F - PCI slot */
+                                        0x7800 0x0 0x0 0x1 &ipic 17 0x8
+                                        0x7800 0x0 0x0 0x2 &ipic 18 0x8
+                                        0x7800 0x0 0x0 0x3 &ipic 17 0x8
+                                        0x7800 0x0 0x0 0x4 &ipic 18 0x8>;
+                       interrupt-parent = <&ipic>;
+                       interrupts = <66 0x8>;
+                       bus-range = <0x0 0x0>;
+                       ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
+                                 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
+                                 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
+                       clock-frequency = <66666666>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       reg = <0xe0008500 0x100>;
+                       compatible = "fsl,mpc8349-pci";
+                       device_type = "pci";
+               };
+
+               dma@82a8 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,mpc8313-dma", "fsl,elo-dma";
+                       reg = <0xe00082a8 4>;
+                       ranges = <0 0xe0008100 0x1a8>;
+                       interrupt-parent = <&ipic>;
+                       interrupts = <71 8>;
+
+                       dma-channel@0 {
+                               compatible = "fsl,mpc8313-dma-channel",
+                                            "fsl,elo-dma-channel";
+                               reg = <0 0x28>;
+                               interrupt-parent = <&ipic>;
+                               interrupts = <71 8>;
+                               cell-index = <0>;
+                       };
+
+                       dma-channel@80 {
+                               compatible = "fsl,mpc8313-dma-channel",
+                                            "fsl,elo-dma-channel";
+                               reg = <0x80 0x28>;
+                               interrupt-parent = <&ipic>;
+                               interrupts = <71 8>;
+                               cell-index = <1>;
+                       };
+
+                       dma-channel@100 {
+                               compatible = "fsl,mpc8313-dma-channel",
+                                            "fsl,elo-dma-channel";
+                               reg = <0x100 0x28>;
+                               interrupt-parent = <&ipic>;
+                               interrupts = <71 8>;
+                               cell-index = <2>;
+                       };
+
+                       dma-channel@180 {
+                               compatible = "fsl,mpc8313-dma-channel",
+                                            "fsl,elo-dma-channel";
+                               reg = <0x180 0x28>;
+                               interrupt-parent = <&ipic>;
+                               interrupts = <71 8>;
+                               cell-index = <3>;
+                       };
+               };
        };
 };
index 981941e5d7a50bdadfb9f2cc130f9f98973c24c5..666185f594591fbd8e43f853fca1bc83f287e6b8 100644 (file)
                                          0x01000000 0x0 0x00000000
                                          0x01000000 0x0 0x00000000
                                          0x0 0x00100000>;
+
+                               isa@1e {
+                                       device_type = "isa";
+                                       #size-cells = <1>;
+                                       #address-cells = <2>;
+                                       reg = <0xf000 0 0 0 0>;
+                                       ranges = <1 0 0x01000000 0 0
+                                                 0x00001000>;
+
+                                       rtc@70 {
+                                               compatible = "pnpPNP,b00";
+                                               reg = <1 0x70 2>;
+                                       };
+                               };
                        };
                };
        };
index 042a85ea7b723b63eeed260e024fec4d70d402bc..a0583e5119f5b087fd15f62f5fa947c7170a7474 100644 (file)
@@ -997,10 +997,12 @@ CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
 # CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
index 03627cfebcb40cfa7467833a4c3a4a7602fc83aa..164fd9606ee6acf9e7e0a80b8ca1745abd532b9f 100644 (file)
@@ -997,10 +997,12 @@ CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
 # CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
index 3efab71a603b74a49d60b5507371e5f81c6ad287..fa0170504b88cfcabbb706a820d27680dccb6160 100644 (file)
@@ -1005,10 +1005,12 @@ CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
 # CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
index 5612d40d0463907067f261ed32445d1b05eab678..cdf98ae3682b1b71b16d8e5ab10a2c9a120240fd 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc5
-# Mon Jun  9 08:50:24 2008
+# Linux kernel version: 2.6.26
+# Tue Jul 15 08:31:01 2008
 #
 # CONFIG_PPC64 is not set
 
@@ -51,6 +51,8 @@ CONFIG_PPC_UDBG_16550=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DEFAULT_UIMAGE=y
+CONFIG_HIBERNATE_32=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -97,6 +99,7 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
+CONFIG_PCSPKR_PLATFORM=y
 CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
@@ -117,7 +120,7 @@ CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -153,31 +156,43 @@ CONFIG_CLASSIC_RCU=y
 #
 # Platform support
 #
-# CONFIG_PPC_MULTIPLATFORM is not set
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-CONFIG_PPC_86xx=y
+CONFIG_PPC_MULTIPLATFORM=y
+CONFIG_CLASSIC32=y
+CONFIG_PPC_CHRP=y
 # CONFIG_PPC_MPC512x is not set
 # CONFIG_PPC_MPC5121 is not set
+# CONFIG_MPC5121_ADS is not set
+# CONFIG_PPC_MPC52xx is not set
+CONFIG_PPC_PMAC=y
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
 # CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+CONFIG_PPC_86xx=y
 # CONFIG_MPC8641_HPCN is not set
 # CONFIG_SBC8641D is not set
 CONFIG_MPC8610_HPCD=y
 CONFIG_MPC8610=y
+# CONFIG_EMBEDDED6xx is not set
+CONFIG_PPC_NATIVE=y
+# CONFIG_UDBG_RTAS_CONSOLE is not set
 # CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
-# CONFIG_PPC_I8259 is not set
-# CONFIG_PPC_RTAS is not set
+CONFIG_PPC_I8259=y
+CONFIG_PPC_RTAS=y
+# CONFIG_RTAS_ERROR_LOGGING is not set
+CONFIG_RTAS_PROC=y
 # CONFIG_MMIO_NVRAM is not set
-# CONFIG_PPC_MPC106 is not set
+CONFIG_PPC_MPC106=y
 # CONFIG_PPC_970_NAP is not set
 # CONFIG_PPC_INDIRECT_IO is not set
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
-# CONFIG_FSL_ULI1575 is not set
+# CONFIG_PPC601_SYNC_FIX is not set
+# CONFIG_TAU is not set
+CONFIG_FSL_ULI1575=y
 
 #
 # Kernel options
@@ -202,6 +217,7 @@ CONFIG_BINFMT_ELF=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+# CONFIG_KEXEC is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -228,11 +244,13 @@ CONFIG_ISA_DMA_API=y
 #
 # Bus options
 #
+# CONFIG_ISA is not set
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
+CONFIG_PPC_PCI_CHOICE=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 CONFIG_PCI_SYSCALL=y
@@ -469,6 +487,7 @@ CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
+# CONFIG_MAC_FLOPPY is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -571,6 +590,8 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_MESH is not set
+# CONFIG_SCSI_MAC53C94 is not set
 # CONFIG_SCSI_SRP is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
@@ -639,6 +660,10 @@ CONFIG_PATA_ALI=y
 #
 # IEEE 1394 (FireWire) support
 #
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
@@ -655,6 +680,8 @@ CONFIG_DUMMY=y
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
@@ -762,14 +789,16 @@ CONFIG_SERIAL_8250_RSA=y
 # CONFIG_SERIAL_UARTLITE is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_PMACZILOG is not set
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
+# CONFIG_BRIQ_PANEL is not set
+# CONFIG_HVC_RTAS is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_NVRAM is not set
-# CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -787,9 +816,11 @@ CONFIG_I2C_BOARDINFO=y
 # CONFIG_I2C_ALI15X3 is not set
 # CONFIG_I2C_AMD756 is not set
 # CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_HYDRA is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
 # CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_POWERMAC=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_OCORES is not set
@@ -826,6 +857,7 @@ CONFIG_I2C_MPC=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -888,6 +920,9 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
 # CONFIG_FB_OF is not set
+# CONFIG_FB_CONTROL is not set
+# CONFIG_FB_PLATINUM is not set
+# CONFIG_FB_VALKYRIE is not set
 # CONFIG_FB_CT65550 is not set
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
@@ -1027,11 +1062,18 @@ CONFIG_SND_VERBOSE_PROCFS=y
 #
 # ALSA PowerMac devices
 #
+# CONFIG_SND_POWERMAC is not set
 
 #
 # ALSA PowerPC devices
 #
 
+#
+# Apple Onboard Audio driver
+#
+# CONFIG_SND_AOA is not set
+# CONFIG_SND_AOA_SOUNDBUS is not set
+
 #
 # System on Chip audio support
 #
@@ -1075,7 +1117,57 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_EDAC is not set
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+CONFIG_RTC_DRV_CMOS=y
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PPC is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
@@ -1295,8 +1387,11 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
 # CONFIG_DEBUGGER is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_IRQSTACKS is not set
 # CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
 # CONFIG_PPC_EARLY_DEBUG is not set
 
 #
index 4a8171507391996b0361974dc5ab282c53510a8e..867b8c0215f37cdb8b1013f27560eef26acffa48 100644 (file)
@@ -991,10 +991,12 @@ CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
 # CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
new file mode 100644 (file)
index 0000000..e6e91c8
--- /dev/null
@@ -0,0 +1,3304 @@
+# powerpc
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.26-git2
+# Tue Jul 15 23:54:18 2008
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+CONFIG_FSL_EMB_PERFMON=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_DEFAULT_UIMAGE=y
+CONFIG_REDBOOT=y
+CONFIG_HIBERNATE_32=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_AUDIT_TREE=y
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_NS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+# CONFIG_USER_SCHED is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+# CONFIG_CGROUP_MEM_RES_CTLR is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_PCSPKR_PLATFORM=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_MARKERS=y
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_KRETPROBES=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LSF=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_BLK_DEV_INTEGRITY=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+CONFIG_CLASSIC32=y
+CONFIG_PPC_CHRP=y
+# CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
+CONFIG_PPC_MPC52xx=y
+# CONFIG_PPC_MPC5200_SIMPLE is not set
+CONFIG_PPC_EFIKA=y
+# CONFIG_PPC_LITE5200 is not set
+CONFIG_PPC_MPC5200_BUGFIX=y
+CONFIG_PPC_MPC5200_GPIO=y
+CONFIG_PPC_PMAC=y
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+CONFIG_PPC_82xx=y
+CONFIG_MPC8272_ADS=y
+CONFIG_PQ2FADS=y
+CONFIG_EP8248E=y
+CONFIG_PQ2ADS=y
+CONFIG_8260=y
+CONFIG_8272=y
+CONFIG_PQ2_ADS_PCI_PIC=y
+CONFIG_PPC_83xx=y
+CONFIG_MPC831x_RDB=y
+CONFIG_MPC832x_MDS=y
+CONFIG_MPC832x_RDB=y
+CONFIG_MPC834x_MDS=y
+CONFIG_MPC834x_ITX=y
+CONFIG_MPC836x_MDS=y
+CONFIG_MPC836x_RDK=y
+CONFIG_MPC837x_MDS=y
+CONFIG_MPC837x_RDB=y
+CONFIG_SBC834x=y
+CONFIG_ASP834x=y
+CONFIG_PPC_MPC831x=y
+CONFIG_PPC_MPC832x=y
+CONFIG_PPC_MPC834x=y
+CONFIG_PPC_MPC837x=y
+CONFIG_PPC_86xx=y
+CONFIG_MPC8641_HPCN=y
+CONFIG_SBC8641D=y
+CONFIG_MPC8610_HPCD=y
+CONFIG_MPC8641=y
+CONFIG_MPC8610=y
+# CONFIG_EMBEDDED6xx is not set
+CONFIG_PPC_NATIVE=y
+# CONFIG_UDBG_RTAS_CONSOLE is not set
+CONFIG_IPIC=y
+CONFIG_MPIC=y
+# CONFIG_MPIC_WEIRD is not set
+CONFIG_PPC_I8259=y
+CONFIG_PPC_RTAS=y
+# CONFIG_RTAS_ERROR_LOGGING is not set
+CONFIG_RTAS_PROC=y
+# CONFIG_MMIO_NVRAM is not set
+CONFIG_PPC_MPC106=y
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# CPU Frequency drivers
+#
+CONFIG_CPU_FREQ_PMAC=y
+# CONFIG_PPC601_SYNC_FIX is not set
+CONFIG_TAU=y
+# CONFIG_TAU_INT is not set
+CONFIG_TAU_AVERAGE=y
+CONFIG_QUICC_ENGINE=y
+CONFIG_CPM2=y
+CONFIG_PPC_CPM_NEW_BINDING=y
+CONFIG_FSL_ULI1575=y
+CONFIG_CPM=y
+CONFIG_PPC_BESTCOMM=y
+CONFIG_PPC_BESTCOMM_ATA=m
+CONFIG_PPC_BESTCOMM_FEC=m
+CONFIG_PPC_BESTCOMM_GEN_BD=m
+
+#
+# Kernel options
+#
+CONFIG_HIGHMEM=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+# CONFIG_KEXEC is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+CONFIG_ARCH_WANTS_FREEZER_CONTROL=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_VERBOSE is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_STD_PARTITION=""
+CONFIG_APM_EMULATION=y
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ISA=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_FSL_PCI=y
+CONFIG_FSL_LBC=y
+CONFIG_FSL_GTM=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCI_8260=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEASPM=y
+# CONFIG_PCIEASPM_DEBUG is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_I82365=m
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_HAS_RAPIDIO=y
+# CONFIG_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+CONFIG_ADVANCED_OPTIONS=y
+# CONFIG_LOWMEM_SIZE_BOOL is not set
+CONFIG_LOWMEM_SIZE=0x30000000
+# CONFIG_PAGE_OFFSET_BOOL is not set
+CONFIG_PAGE_OFFSET=0xc0000000
+# CONFIG_KERNEL_START_BOOL is not set
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+# CONFIG_TASK_SIZE_BOOL is not set
+CONFIG_TASK_SIZE=0xc0000000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_NET_KEY=m
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_BIC=m
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+# CONFIG_DEFAULT_BIC is not set
+CONFIG_DEFAULT_CUBIC=y
+# CONFIG_DEFAULT_HTCP is not set
+# CONFIG_DEFAULT_VEGAS is not set
+# CONFIG_DEFAULT_WESTWOOD is not set
+# CONFIG_DEFAULT_RENO is not set
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETLABEL=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CT_ACCT=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=m
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_RATEEST=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV4=m
+# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_NF_NAT_PROTO_DCCP=m
+CONFIG_NF_NAT_PROTO_GRE=m
+CONFIG_NF_NAT_PROTO_UDPLITE=m
+CONFIG_NF_NAT_PROTO_SCTP=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+CONFIG_NF_NAT_TFTP=m
+CONFIG_NF_NAT_AMANDA=m
+CONFIG_NF_NAT_PPTP=m
+CONFIG_NF_NAT_H323=m
+CONFIG_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_RAW=m
+
+#
+# DECnet: Netfilter Configuration
+#
+# CONFIG_DECNET_NF_GRABULATOR is not set
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_BRIDGE_EBT_NFLOG=m
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID2=m
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
+CONFIG_IP_DCCP_CCID3=m
+# CONFIG_IP_DCCP_CCID3_DEBUG is not set
+CONFIG_IP_DCCP_CCID3_RTO=100
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+CONFIG_NET_DCCPPROBE=m
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+# CONFIG_ATM_MPOA is not set
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_DECNET_ROUTER=y
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_SCH_FIFO=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+CONFIG_KINGSUN_DONGLE=m
+CONFIG_KSDAZZLE_DONGLE=m
+CONFIG_KS959_DONGLE=m
+
+#
+# FIR device drivers
+#
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_NSC_FIR=m
+CONFIG_WINBOND_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_SMC_IRCC_FIR=m
+CONFIG_ALI_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_VIA_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+
+#
+# Wireless
+#
+CONFIG_CFG80211=m
+CONFIG_NL80211=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_QOS=y
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_PID=y
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+CONFIG_MAC80211_RC_DEFAULT="pid"
+CONFIG_MAC80211_MESH=y
+CONFIG_MAC80211_LEDS=y
+CONFIG_MAC80211_DEBUGFS=y
+# CONFIG_MAC80211_DEBUG_MENU is not set
+CONFIG_IEEE80211=m
+CONFIG_IEEE80211_DEBUG=y
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+# CONFIG_RFKILL is not set
+CONFIG_NET_9P=m
+CONFIG_NET_9P_VIRTIO=m
+# CONFIG_NET_9P_DEBUG is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+CONFIG_DEBUG_DEVRES=y
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_I2C=y
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_PC_PCMCIA is not set
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+CONFIG_PARPORT_NOT_PC=y
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_ISAPNP=y
+# CONFIG_PNPACPI is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+CONFIG_MAC_FLOPPY=m
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_VIRTIO_BLK=m
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+CONFIG_EEPROM_93CX6=m
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+CONFIG_ENCLOSURE_SERVICES=m
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+CONFIG_IDE_ATAPI=y
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=m
+# CONFIG_BLK_DEV_IDESCSI is not set
+CONFIG_IDE_TASK_IOCTL=y
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
+
+#
+# PCI IDE chipsets support
+#
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
+CONFIG_BLK_DEV_IDE_PMAC=y
+CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
+CONFIG_BLK_DEV_IDEDMA_PMAC=y
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_BLK_DEV_HD_ONLY=y
+CONFIG_BLK_DEV_HD=y
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=m
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_ENCLOSURE=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+CONFIG_SCSI_SPI_ATTRS=m
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_SRP_ATTRS=m
+CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_SCSI_MESH=m
+CONFIG_SCSI_MESH_SYNC_RATE=5
+CONFIG_SCSI_MESH_RESET_DELAY_MS=4000
+CONFIG_SCSI_MAC53C94=m
+CONFIG_SCSI_SRP=m
+CONFIG_SCSI_LOWLEVEL_PCMCIA=y
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
+CONFIG_SCSI_DH=y
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_PMP is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SIL24 is not set
+CONFIG_SATA_FSL=m
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_SVW is not set
+CONFIG_ATA_PIIX=m
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+CONFIG_PDC_ADMA=m
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+CONFIG_ATA_GENERIC=m
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_ISAPNP is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+CONFIG_PATA_MPC52xx=m
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+CONFIG_PATA_OPTIDMA=m
+# CONFIG_PATA_PCMCIA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_QDI is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+CONFIG_PATA_VIA=m
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_WINBOND_VLB is not set
+CONFIG_PATA_PLATFORM=m
+CONFIG_PATA_OF_PLATFORM=m
+CONFIG_PATA_SCH=m
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_DEBUG=y
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+# CONFIG_DM_DELAY is not set
+CONFIG_DM_UEVENT=y
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+CONFIG_FIREWIRE=m
+CONFIG_FIREWIRE_OHCI=m
+CONFIG_FIREWIRE_OHCI_DEBUG=y
+CONFIG_FIREWIRE_SBP2=m
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_MACINTOSH_DRIVERS=y
+CONFIG_ADB=y
+CONFIG_ADB_CUDA=y
+CONFIG_ADB_PMU=y
+CONFIG_ADB_PMU_LED=y
+CONFIG_ADB_PMU_LED_IDE=y
+CONFIG_PMAC_APM_EMU=y
+CONFIG_PMAC_MEDIABAY=y
+CONFIG_PMAC_BACKLIGHT=y
+# CONFIG_PMAC_BACKLIGHT_LEGACY is not set
+CONFIG_ADB_MACIO=y
+CONFIG_INPUT_ADBHID=y
+CONFIG_MAC_EMUMOUSEBTN=y
+CONFIG_THERM_WINDTUNNEL=m
+CONFIG_THERM_ADT746X=m
+CONFIG_WINDFARM=y
+# CONFIG_ANSLCD is not set
+CONFIG_PMAC_RACKMETER=m
+CONFIG_NETDEVICES=y
+CONFIG_NETDEVICES_MULTIQUEUE=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_NET_SB1000=m
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_ICPLUS_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_MDIO_BITBANG=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_MACE=m
+# CONFIG_MACE_AAUI_PORT is not set
+CONFIG_BMAC=m
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
+CONFIG_EL3=m
+# CONFIG_3C515 is not set
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+CONFIG_ULTRA=m
+# CONFIG_SMC9194 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+CONFIG_EWRK3=m
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
+CONFIG_NE2000=m
+# CONFIG_ZNET is not set
+# CONFIG_SEEQ8005 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+CONFIG_B44=m
+CONFIG_B44_PCI_AUTOSELECT=y
+CONFIG_B44_PCICORE_AUTOSELECT=y
+CONFIG_B44_PCI=y
+CONFIG_FORCEDETH=m
+CONFIG_FORCEDETH_NAPI=y
+# CONFIG_CS89x0 is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_R6040=m
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+# CONFIG_SUNDANCE_MMIO is not set
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_VIA_RHINE_NAPI=y
+CONFIG_SC92031=m
+CONFIG_NET_POCKET=y
+CONFIG_DE600=m
+CONFIG_DE620=m
+CONFIG_FEC_MPC52xx=m
+CONFIG_FEC_MPC52xx_MDIO=y
+# CONFIG_FS_ENET is not set
+CONFIG_NETDEV_1000=y
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+CONFIG_E1000E=m
+CONFIG_E1000E_ENABLED=y
+CONFIG_IP1000=m
+CONFIG_IGB=m
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+# CONFIG_SKGE_DEBUG is not set
+CONFIG_SKY2=m
+# CONFIG_SKY2_DEBUG is not set
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+CONFIG_GIANFAR=m
+CONFIG_GFAR_NAPI=y
+# CONFIG_UCC_GETH is not set
+CONFIG_MV643XX_ETH=m
+CONFIG_QLA3XXX=m
+CONFIG_ATL1=m
+CONFIG_NETDEV_10000=y
+CONFIG_CHELSIO_T1=m
+CONFIG_CHELSIO_T1_1G=y
+CONFIG_CHELSIO_T1_NAPI=y
+CONFIG_CHELSIO_T3=m
+CONFIG_IXGBE=m
+CONFIG_IXGB=m
+CONFIG_IXGB_NAPI=y
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+CONFIG_MYRI10GE=m
+CONFIG_NETXEN_NIC=m
+CONFIG_NIU=m
+# CONFIG_MLX4_CORE is not set
+CONFIG_TEHUTI=m
+CONFIG_BNX2X=m
+CONFIG_SFC=m
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_NET_ZAURUS=m
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+# CONFIG_WAN is not set
+CONFIG_ATM_DRIVERS=y
+# CONFIG_ATM_DUMMY is not set
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+# CONFIG_ATM_ENI_DEBUG is not set
+# CONFIG_ATM_ENI_TUNE_BURST is not set
+# CONFIG_ATM_FIRESTREAM is not set
+# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_NICSTAR=m
+# CONFIG_ATM_NICSTAR_USE_SUNI is not set
+# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
+CONFIG_ATM_IDT77252=m
+# CONFIG_ATM_IDT77252_DEBUG is not set
+# CONFIG_ATM_IDT77252_RCV_ALL is not set
+CONFIG_ATM_IDT77252_USE_SUNI=y
+# CONFIG_ATM_AMBASSADOR is not set
+# CONFIG_ATM_HORIZON is not set
+# CONFIG_ATM_IA is not set
+CONFIG_ATM_FORE200E_MAYBE=m
+# CONFIG_ATM_FORE200E_PCA is not set
+CONFIG_ATM_HE=m
+# CONFIG_ATM_HE_USE_SUNI is not set
+CONFIG_FDDI=y
+# CONFIG_DEFXX is not set
+CONFIG_SKFP=m
+# CONFIG_HIPPI is not set
+CONFIG_PLIP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_PPPOL2TP=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_NET_FC=y
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+CONFIG_VIRTIO_NET=m
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+CONFIG_INPUT_POLLDEV=m
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_APPLETOUCH=m
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+CONFIG_MOUSE_VSXXXAA=m
+# CONFIG_MOUSE_GPIO is not set
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_ZHENHUA=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_JOYSTICK_XPAD=m
+CONFIG_JOYSTICK_XPAD_FF=y
+CONFIG_JOYSTICK_XPAD_LEDS=y
+CONFIG_INPUT_TABLET=y
+CONFIG_TABLET_USB_ACECAD=m
+CONFIG_TABLET_USB_AIPTEK=m
+CONFIG_TABLET_USB_GTCO=m
+CONFIG_TABLET_USB_KBTAB=m
+CONFIG_TABLET_USB_WACOM=m
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=m
+CONFIG_INPUT_ATI_REMOTE=m
+CONFIG_INPUT_ATI_REMOTE2=m
+CONFIG_INPUT_KEYSPAN_REMOTE=m
+CONFIG_INPUT_POWERMATE=m
+CONFIG_INPUT_YEALINK=m
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+CONFIG_INPUT_LIRC=y
+CONFIG_LIRC_DEV=m
+CONFIG_LIRC_ATIUSB=m
+CONFIG_LIRC_BT829=m
+CONFIG_LIRC_CMDIR=m
+CONFIG_LIRC_I2C=m
+CONFIG_LIRC_IGORPLUGUSB=m
+CONFIG_LIRC_IMON=m
+CONFIG_LIRC_IT87=m
+CONFIG_LIRC_MCEUSB=m
+CONFIG_LIRC_MCEUSB2=m
+CONFIG_LIRC_PVR150=m
+CONFIG_LIRC_PARALLEL=m
+CONFIG_LIRC_SERIAL=m
+CONFIG_LIRC_SIR=m
+CONFIG_LIRC_STREAMZAP=m
+CONFIG_LIRC_TTUSBIR=m
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+CONFIG_ROCKETPORT=m
+CONFIG_CYCLADES=m
+# CONFIG_CYZ_INTR is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+CONFIG_SYNCLINK=m
+CONFIG_SYNCLINKMP=m
+CONFIG_SYNCLINK_GT=m
+CONFIG_N_HDLC=m
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+CONFIG_NOZOMI=m
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_UARTLITE=m
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_PMACZILOG=m
+# CONFIG_SERIAL_PMACZILOG_TTYS is not set
+# CONFIG_SERIAL_CPM is not set
+CONFIG_SERIAL_MPC52xx=y
+CONFIG_SERIAL_MPC52xx_CONSOLE=y
+CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
+CONFIG_SERIAL_JSM=m
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SERIAL_QE is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_CRASH is not set
+CONFIG_BRIQ_PANEL=m
+CONFIG_PRINTER=m
+CONFIG_LP_CONSOLE=y
+CONFIG_PPDEV=m
+# CONFIG_HVC_RTAS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_VIRTIO=m
+CONFIG_NVRAM=y
+CONFIG_DTLK=m
+CONFIG_R3964=m
+# CONFIG_APPLICOM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+CONFIG_CARDMAN_4000=m
+CONFIG_CARDMAN_4040=m
+CONFIG_IPWIRELESS=m
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# Mac SMBus host controller drivers
+#
+CONFIG_I2C_HYDRA=m
+CONFIG_I2C_POWERMAC=y
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_CPM is not set
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_MPC=m
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SIMTEC=m
+
+#
+# External I2C/SMBus adapter drivers
+#
+CONFIG_I2C_PARPORT=m
+CONFIG_I2C_PARPORT_LIGHT=m
+# CONFIG_I2C_TAOS_EVM is not set
+CONFIG_I2C_TINY_USB=m
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+CONFIG_I2C_VOODOO3=m
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_ELEKTOR is not set
+CONFIG_I2C_PCA_ISA=m
+CONFIG_I2C_PCA_PLATFORM=m
+CONFIG_I2C_STUB=m
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+CONFIG_AT24=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_PCF8575=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+# CONFIG_TPS65010 is not set
+CONFIG_SENSORS_MAX6875=m
+CONFIG_SENSORS_TSL2550=m
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_HAVE_GPIO_LIB=y
+
+#
+# GPIO Support
+#
+# CONFIG_DEBUG_GPIO is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# SPI GPIO expanders:
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_MATROX is not set
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_MASTER_DS2482=m
+# CONFIG_W1_MASTER_GPIO is not set
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2433_CRC=y
+CONFIG_W1_SLAVE_DS2760=m
+CONFIG_POWER_SUPPLY=m
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+CONFIG_APM_POWER=m
+# CONFIG_BATTERY_DS2760 is not set
+CONFIG_BATTERY_PMU=m
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+CONFIG_SENSORS_AD7418=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1029=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ADT7470=m
+CONFIG_SENSORS_ADT7473=m
+CONFIG_SENSORS_AMS=m
+CONFIG_SENSORS_AMS_PMU=y
+CONFIG_SENSORS_AMS_I2C=y
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+# CONFIG_SENSORS_I5K_AMB is not set
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_F71882FG=m
+CONFIG_SENSORS_F75375S=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_LM93=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_MAX6650=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_PC87427=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_DME1737=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_ADS7828=m
+CONFIG_SENSORS_THMC50=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT1211=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83L786NG=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+# CONFIG_HWMON_DEBUG_CHIP is not set
+CONFIG_THERMAL=y
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_MPC5200_WDT is not set
+CONFIG_83xx_WDT=m
+CONFIG_WATCHDOG_RTAS=m
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+CONFIG_USBPCWATCHDOG=m
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+CONFIG_SSB=m
+CONFIG_SSB_SPROM=y
+CONFIG_SSB_PCIHOST_POSSIBLE=y
+CONFIG_SSB_PCIHOST=y
+# CONFIG_SSB_B43_PCI_BRIDGE is not set
+CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
+CONFIG_SSB_PCMCIAHOST=y
+# CONFIG_SSB_DEBUG is not set
+CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
+CONFIG_SSB_DRIVER_PCICORE=y
+
+#
+# Multifunction device drivers
+#
+CONFIG_MFD_SM501=m
+# CONFIG_HTC_PASIC3 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_DVB_CORE=m
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+CONFIG_VIDEO_SAA7146=m
+CONFIG_VIDEO_SAA7146_VV=m
+CONFIG_MEDIA_ATTACH=y
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA827X=m
+CONFIG_MEDIA_TUNER_TDA18271=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_MT2060=m
+CONFIG_MEDIA_TUNER_MT2266=m
+CONFIG_MEDIA_TUNER_MT2131=m
+CONFIG_MEDIA_TUNER_QT1010=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MEDIA_TUNER_MXL5005S=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEOBUF_GEN=m
+CONFIG_VIDEOBUF_DMA_SG=m
+CONFIG_VIDEOBUF_VMALLOC=m
+CONFIG_VIDEOBUF_DVB=m
+CONFIG_VIDEO_BTCX=m
+CONFIG_VIDEO_IR_I2C=m
+CONFIG_VIDEO_IR=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+CONFIG_VIDEO_TVAUDIO=m
+CONFIG_VIDEO_TDA7432=m
+CONFIG_VIDEO_TDA9840=m
+CONFIG_VIDEO_TDA9875=m
+CONFIG_VIDEO_TEA6415C=m
+CONFIG_VIDEO_TEA6420=m
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS5345=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_M52790=m
+CONFIG_VIDEO_TLV320AIC23B=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_VP27SMPX=m
+
+#
+# Video decoders
+#
+CONFIG_VIDEO_BT819=m
+CONFIG_VIDEO_BT856=m
+CONFIG_VIDEO_BT866=m
+CONFIG_VIDEO_KS0127=m
+CONFIG_VIDEO_OV7670=m
+CONFIG_VIDEO_TCM825X=m
+CONFIG_VIDEO_SAA7110=m
+CONFIG_VIDEO_SAA7111=m
+CONFIG_VIDEO_SAA7114=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_SAA717X=m
+CONFIG_VIDEO_SAA7191=m
+CONFIG_VIDEO_TVP5150=m
+CONFIG_VIDEO_VPX3220=m
+
+#
+# Video and audio decoders
+#
+CONFIG_VIDEO_CX25840=m
+
+#
+# MPEG video encoders
+#
+CONFIG_VIDEO_CX2341X=m
+
+#
+# Video encoders
+#
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_SAA7185=m
+CONFIG_VIDEO_ADV7170=m
+CONFIG_VIDEO_ADV7175=m
+
+#
+# Video improvement chips
+#
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_BT848=m
+CONFIG_VIDEO_BT848_DVB=y
+CONFIG_VIDEO_SAA6588=m
+# CONFIG_VIDEO_PMS is not set
+CONFIG_VIDEO_BWQCAM=m
+CONFIG_VIDEO_CQCAM=m
+CONFIG_VIDEO_W9966=m
+CONFIG_VIDEO_CPIA=m
+CONFIG_VIDEO_CPIA_PP=m
+CONFIG_VIDEO_CPIA_USB=m
+CONFIG_VIDEO_CPIA2=m
+CONFIG_VIDEO_SAA5246A=m
+CONFIG_VIDEO_SAA5249=m
+CONFIG_TUNER_3036=m
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+CONFIG_VIDEO_SAA7134=m
+CONFIG_VIDEO_SAA7134_ALSA=m
+CONFIG_VIDEO_SAA7134_DVB=m
+CONFIG_VIDEO_MXB=m
+CONFIG_VIDEO_DPC=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_CX88=m
+CONFIG_VIDEO_CX88_ALSA=m
+CONFIG_VIDEO_CX88_BLACKBIRD=m
+CONFIG_VIDEO_CX88_DVB=m
+CONFIG_VIDEO_CX88_VP3054=m
+CONFIG_VIDEO_CX23885=m
+CONFIG_VIDEO_AU0828=m
+CONFIG_VIDEO_IVTV=m
+CONFIG_VIDEO_FB_IVTV=m
+CONFIG_VIDEO_CX18=m
+# CONFIG_VIDEO_CAFE_CCIC is not set
+CONFIG_V4L_USB_DRIVERS=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+CONFIG_VIDEO_PVRUSB2_DVB=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_EM28XX=m
+CONFIG_VIDEO_EM28XX_ALSA=m
+CONFIG_VIDEO_EM28XX_DVB=m
+CONFIG_VIDEO_USBVISION=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+CONFIG_USB_ET61X251=m
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+CONFIG_USB_ZC0301=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+CONFIG_USB_ZR364XX=m
+CONFIG_USB_STKWEBCAM=m
+CONFIG_SOC_CAMERA=m
+CONFIG_SOC_CAMERA_MT9M001=m
+# CONFIG_MT9M001_PCA9536_SWITCH is not set
+CONFIG_SOC_CAMERA_MT9V022=m
+# CONFIG_MT9V022_PCA9536_SWITCH is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+CONFIG_RADIO_GEMTEK_PCI=m
+CONFIG_RADIO_MAXIRADIO=m
+CONFIG_RADIO_MAESTRO=m
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+CONFIG_USB_DSBR=m
+CONFIG_USB_SI470X=m
+CONFIG_DVB_CAPTURE_DRIVERS=y
+
+#
+# Supported SAA7146 based PCI Adapters
+#
+CONFIG_TTPCI_EEPROM=m
+CONFIG_DVB_AV7110=m
+CONFIG_DVB_AV7110_OSD=y
+CONFIG_DVB_BUDGET_CORE=m
+CONFIG_DVB_BUDGET=m
+CONFIG_DVB_BUDGET_CI=m
+CONFIG_DVB_BUDGET_AV=m
+CONFIG_DVB_BUDGET_PATCH=m
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_DIB0700=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_M920X=m
+CONFIG_DVB_USB_GL861=m
+CONFIG_DVB_USB_AU6610=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_TTUSB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_USB_OPERA1=m
+CONFIG_DVB_USB_AF9005=m
+CONFIG_DVB_USB_AF9005_REMOTE=m
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+CONFIG_DVB_CINERGYT2_TUNING=y
+CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT=32
+CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE=512
+CONFIG_DVB_CINERGYT2_QUERY_INTERVAL=250
+CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE=y
+CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL=100
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+CONFIG_DVB_B2C2_FLEXCOP=m
+CONFIG_DVB_B2C2_FLEXCOP_PCI=m
+CONFIG_DVB_B2C2_FLEXCOP_USB=m
+# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
+
+#
+# Supported BT878 Adapters
+#
+CONFIG_DVB_BT8XX=m
+
+#
+# Supported Pluto2 Adapters
+#
+CONFIG_DVB_PLUTO2=m
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+# CONFIG_DVB_FE_CUSTOMISE is not set
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_S5H1420=m
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_TDA10086=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_TUNER_ITD1000=m
+CONFIG_DVB_TDA826X=m
+CONFIG_DVB_TUA6100=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+CONFIG_DVB_DIB7000M=m
+CONFIG_DVB_DIB7000P=m
+CONFIG_DVB_TDA10048=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_TDA10023=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+CONFIG_DVB_OR51211=m
+CONFIG_DVB_OR51132=m
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+CONFIG_DVB_S5H1409=m
+CONFIG_DVB_AU8522=m
+CONFIG_DVB_S5H1411=m
+
+#
+# Digital terrestrial only tuners/PLL
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_TUNER_DIB0070=m
+
+#
+# SEC control devices for DVB-S
+#
+CONFIG_DVB_LNBP21=m
+CONFIG_DVB_ISL6405=m
+CONFIG_DVB_ISL6421=m
+CONFIG_DAB=y
+CONFIG_USB_DABUSB=m
+
+#
+# Graphics support
+#
+CONFIG_AGP=y
+CONFIG_AGP_UNINORTH=y
+CONFIG_DRM=m
+CONFIG_DRM_TDFX=m
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_MGA=m
+CONFIG_DRM_SIS=m
+CONFIG_DRM_VIA=m
+CONFIG_DRM_SAVAGE=m
+CONFIG_VGASTATE=y
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB_DDC=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_SVGALIB=m
+CONFIG_FB_MACMODES=y
+CONFIG_FB_BACKLIGHT=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_CIRRUS=m
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_OF=y
+# CONFIG_FB_CONTROL is not set
+CONFIG_FB_PLATINUM=y
+CONFIG_FB_VALKYRIE=y
+CONFIG_FB_CT65550=y
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_NVIDIA=y
+CONFIG_FB_NVIDIA_I2C=y
+# CONFIG_FB_NVIDIA_DEBUG is not set
+CONFIG_FB_NVIDIA_BACKLIGHT=y
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_RIVA_BACKLIGHT=y
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+CONFIG_FB_RADEON_BACKLIGHT=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=y
+CONFIG_FB_ATY128_BACKLIGHT=y
+CONFIG_FB_ATY=y
+CONFIG_FB_ATY_CT=y
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_ATY_BACKLIGHT=y
+CONFIG_FB_S3=m
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=y
+CONFIG_FB_SAVAGE_ACCEL=y
+# CONFIG_FB_SIS is not set
+CONFIG_FB_NEOMAGIC=m
+CONFIG_FB_KYRO=m
+CONFIG_FB_3DFX=m
+CONFIG_FB_3DFX_ACCEL=y
+CONFIG_FB_VOODOO1=m
+# CONFIG_FB_VT8623 is not set
+CONFIG_FB_TRIDENT=m
+CONFIG_FB_TRIDENT_ACCEL=y
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_FSL_DIU is not set
+CONFIG_FB_SM501=m
+CONFIG_FB_IBM_GXT4500=y
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=m
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+CONFIG_VGACON_SOFT_SCROLLBACK=y
+CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DEBUG=y
+CONFIG_SND_DEBUG_VERBOSE=y
+CONFIG_SND_PCM_XRUN_DEBUG=y
+CONFIG_SND_VMASTER=y
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_DRIVERS=y
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+CONFIG_SND_MTS64=m
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+CONFIG_SND_PORTMAN2X4=m
+CONFIG_SND_AC97_POWER_SAVE=y
+CONFIG_SND_AC97_POWER_SAVE_DEFAULT=5
+CONFIG_SND_SB_COMMON=m
+CONFIG_SND_SB16_DSP=m
+CONFIG_SND_ISA=y
+# CONFIG_SND_ADLIB is not set
+# CONFIG_SND_AD1816A is not set
+# CONFIG_SND_AD1848 is not set
+# CONFIG_SND_ALS100 is not set
+# CONFIG_SND_AZT2320 is not set
+# CONFIG_SND_CMI8330 is not set
+# CONFIG_SND_CS4231 is not set
+# CONFIG_SND_CS4232 is not set
+# CONFIG_SND_CS4236 is not set
+# CONFIG_SND_DT019X is not set
+# CONFIG_SND_ES968 is not set
+# CONFIG_SND_ES1688 is not set
+# CONFIG_SND_ES18XX is not set
+# CONFIG_SND_SC6000 is not set
+# CONFIG_SND_GUSCLASSIC is not set
+# CONFIG_SND_GUSEXTREME is not set
+# CONFIG_SND_GUSMAX is not set
+# CONFIG_SND_INTERWAVE is not set
+# CONFIG_SND_INTERWAVE_STB is not set
+# CONFIG_SND_OPL3SA2 is not set
+# CONFIG_SND_OPTI92X_AD1848 is not set
+# CONFIG_SND_OPTI92X_CS4231 is not set
+# CONFIG_SND_OPTI93X is not set
+# CONFIG_SND_MIRO is not set
+# CONFIG_SND_SB8 is not set
+# CONFIG_SND_SB16 is not set
+# CONFIG_SND_SBAWE is not set
+# CONFIG_SND_SGALAXY is not set
+# CONFIG_SND_SSCAPE is not set
+# CONFIG_SND_WAVEFRONT is not set
+CONFIG_SND_PCI=y
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALS4000=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AW2=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+# CONFIG_SND_BT87X_OVERCLOCK is not set
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_OXYGEN_LIB=m
+CONFIG_SND_OXYGEN=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_CS46XX_NEW_DSP=y
+CONFIG_SND_CS5530=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_FM801_TEA575X_BOOL=y
+CONFIG_SND_FM801_TEA575X=m
+# CONFIG_SND_HDA_INTEL is not set
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_HIFIER=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VIRTUOSO=m
+CONFIG_SND_VX222=m
+# CONFIG_SND_YMFPCI is not set
+CONFIG_SND_PPC=y
+CONFIG_SND_POWERMAC=m
+CONFIG_SND_POWERMAC_AUTO_DRC=y
+CONFIG_SND_AOA=m
+CONFIG_SND_AOA_FABRIC_LAYOUT=m
+CONFIG_SND_AOA_ONYX=m
+CONFIG_SND_AOA_TAS=m
+CONFIG_SND_AOA_TOONIE=m
+CONFIG_SND_AOA_SOUNDBUS=m
+CONFIG_SND_AOA_SOUNDBUS_I2S=m
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_USX2Y=m
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+# CONFIG_SND_PCMCIA is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+CONFIG_HIDRAW=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT_POWERBOOK=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_PANTHERLORD_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_ZEROPLUS_FF=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_FSL=y
+CONFIG_USB_EHCI_HCD_PPC_OF=y
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_HCD_PPC_SOC=y
+CONFIG_USB_OHCI_HCD_PPC_OF=y
+CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
+CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
+CONFIG_USB_OHCI_HCD_PCI=y
+# CONFIG_USB_OHCI_HCD_SSB is not set
+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_U132_HCD=m
+CONFIG_USB_SL811_HCD=m
+# CONFIG_USB_SL811_CS is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_WDM=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+# CONFIG_USB_STORAGE_ISD200 is not set
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_EZUSB=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRCABLE=m
+CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_CH341=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CP2101=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+# CONFIG_USB_SERIAL_GARMIN is not set
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_IUU=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_MOS7720=m
+CONFIG_USB_SERIAL_MOS7840=m
+CONFIG_USB_SERIAL_MOTOROLA=m
+CONFIG_USB_SERIAL_NAVMAN=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OTI6858=m
+CONFIG_USB_SERIAL_SPCP8X5=m
+CONFIG_USB_SERIAL_HP4X=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_SAFE_PADDED=y
+CONFIG_USB_SERIAL_SIERRAWIRELESS=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_SERIAL_DEBUG=m
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_ADUTUX=m
+CONFIG_USB_AUERSWALD=m
+# CONFIG_USB_RIO500 is not set
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_BERRY_CHARGE=m
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+CONFIG_USB_PHIDGET=m
+CONFIG_USB_PHIDGETKIT=m
+CONFIG_USB_PHIDGETMOTORCONTROL=m
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_FTDI_ELAN=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_SISUSBVGA_CON=y
+CONFIG_USB_LD=m
+CONFIG_USB_TRANCEVIBRATOR=m
+CONFIG_USB_IOWARRIOR=m
+# CONFIG_USB_TEST is not set
+CONFIG_USB_ISIGHTFW=m
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_GPIO is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+CONFIG_ACCESSIBILITY=y
+CONFIG_A11Y_BRAILLE_CONSOLE=y
+# CONFIG_INFINIBAND is not set
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=m
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1374=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_MAX6900=m
+CONFIG_RTC_DRV_RS5C372=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_M41T80=m
+CONFIG_RTC_DRV_M41T80_WDT=y
+# CONFIG_RTC_DRV_S35390A is not set
+CONFIG_RTC_DRV_FM3130=m
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+CONFIG_RTC_DRV_CMOS=y
+CONFIG_RTC_DRV_DS1511=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_STK17TA8=m
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_M48T59=m
+CONFIG_RTC_DRV_V3020=m
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_PPC=y
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+# CONFIG_FSL_DMA is not set
+CONFIG_AUXDISPLAY=y
+CONFIG_KS0108=m
+CONFIG_KS0108_PORT=0x378
+CONFIG_KS0108_DELAY=2
+CONFIG_UIO=m
+CONFIG_UIO_CIF=m
+CONFIG_UIO_SMX=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4DEV_FS=m
+CONFIG_EXT4DEV_FS_XATTR=y
+CONFIG_EXT4DEV_FS_POSIX_ACL=y
+CONFIG_EXT4DEV_FS_SECURITY=y
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=m
+CONFIG_JBD2_DEBUG=y
+CONFIG_FS_MBCACHE=m
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_DLM=m
+CONFIG_OCFS2_FS=m
+CONFIG_OCFS2_FS_O2CB=m
+CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_DEBUG_MASKLOG is not set
+# CONFIG_OCFS2_DEBUG_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+CONFIG_VXFS_FS=m
+CONFIG_MINIX_FS=m
+# CONFIG_HPFS_FS is not set
+CONFIG_QNX4FS_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_SUNRPC_BIND34=y
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+CONFIG_CIFS_EXPERIMENTAL=y
+CONFIG_CIFS_UPCALL=y
+CONFIG_CIFS_DFS_UPCALL=y
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+# CONFIG_CODA_FS_OLD_API is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+CONFIG_DLM_DEBUG=y
+CONFIG_QE_GPIO=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=m
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_FS=y
+CONFIG_HEADERS_CHECK=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_OBJECTS=y
+# CONFIG_DEBUG_OBJECTS_SELFTEST is not set
+CONFIG_DEBUG_OBJECTS_FREE=y
+CONFIG_DEBUG_OBJECTS_TIMERS=y
+CONFIG_SLUB_DEBUG_ON=y
+# CONFIG_SLUB_STATS is not set
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_HIGHMEM=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_VM=y
+CONFIG_DEBUG_WRITECOUNT=y
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_SG=y
+CONFIG_FRAME_POINTER=y
+CONFIG_BOOT_PRINTK_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_LKDTM is not set
+CONFIG_FAULT_INJECTION=y
+CONFIG_FAILSLAB=y
+CONFIG_FAIL_PAGE_ALLOC=y
+CONFIG_FAIL_MAKE_REQUEST=y
+CONFIG_FAULT_INJECTION_DEBUG_FS=y
+CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
+CONFIG_LATENCYTOP=y
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_TRACER_MAX_TRACE=y
+CONFIG_TRACING=y
+CONFIG_FTRACE=y
+CONFIG_SCHED_TRACER=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set
+# CONFIG_SAMPLES is not set
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUGGER=y
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_KGDB_CONSOLE is not set
+CONFIG_XMON=y
+# CONFIG_XMON_DEFAULT is not set
+CONFIG_XMON_DISASSEMBLY=y
+CONFIG_IRQSTACKS=y
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_BDI_SWITCH is not set
+CONFIG_BOOTX_TEXT=y
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_NETWORK_XFRM=y
+CONFIG_SECURITY_FILE_CAPABILITIES=y
+# CONFIG_SECURITY_ROOTPLUG is not set
+CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT=y
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+# CONFIG_SECURITY_SMACK is not set
+CONFIG_XOR_BLOCKS=m
+CONFIG_ASYNC_CORE=m
+CONFIG_ASYNC_MEMCPY=m
+CONFIG_ASYNC_XOR=m
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_SEQIV=m
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CTR=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_HIFN_795X=m
+CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y
+CONFIG_CRYPTO_DEV_TALITOS=m
+CONFIG_PPC_CLOCK=y
+CONFIG_PPC_LIB_RHEAP=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_VIRTIO=m
+CONFIG_VIRTIO_RING=m
+CONFIG_VIRTIO_PCI=m
+CONFIG_VIRTIO_BALLOON=m
index 71d79e428d20ccabd786a0e7a880ff17c2bf2903..f9a3d3b394cfb5ce8694c6b5700507a855623193 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25
-# Mon Apr 28 12:39:10 2008
+# Linux kernel version: 2.6.26
+# Wed Jul 16 13:59:24 2008
 #
 CONFIG_PPC64=y
 
@@ -14,8 +14,9 @@ CONFIG_POWER4=y
 CONFIG_TUNE_CELL=y
 CONFIG_PPC_FPU=y
 CONFIG_ALTIVEC=y
+# CONFIG_VSX is not set
 CONFIG_PPC_STD_MMU=y
-# CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC_MM_SLICES=y
 CONFIG_VIRT_CPU_ACCOUNTING=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
@@ -31,6 +32,7 @@ CONFIG_GENERIC_HARDIRQS=y
 CONFIG_HAVE_SETUP_PER_CPU_AREA=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -90,6 +92,7 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
@@ -117,12 +120,15 @@ CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
 CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
@@ -132,6 +138,7 @@ CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 CONFIG_BLOCK_COMPAT=y
 
 #
@@ -152,13 +159,8 @@ CONFIG_CLASSIC_RCU=y
 # Platform support
 #
 CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-# CONFIG_PPC_86xx is not set
 # CONFIG_PPC_PSERIES is not set
 # CONFIG_PPC_ISERIES is not set
-# CONFIG_PPC_MPC512x is not set
-# CONFIG_PPC_MPC5121 is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_MAPLE is not set
 # CONFIG_PPC_PASEMI is not set
@@ -187,6 +189,7 @@ CONFIG_PPC_CELL=y
 # Cell Broadband Engine options
 #
 CONFIG_SPU_FS=y
+CONFIG_SPU_FS_64K_LS=y
 CONFIG_SPU_BASE=y
 # CONFIG_PQ2ADS is not set
 # CONFIG_IPIC is not set
@@ -222,6 +225,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_BINFMT_ELF=y
 CONFIG_COMPAT_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=y
+CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
 # CONFIG_IOMMU_VMERGE is not set
 CONFIG_IOMMU_HELPER=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
@@ -248,18 +252,22 @@ CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
 # CONFIG_SPARSEMEM_VMEMMAP is not set
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTPLUG_SPARSE=y
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_ARCH_MEMORY_PROBE=y
-# CONFIG_PPC_HAS_HASH_64K is not set
+CONFIG_PPC_HAS_HASH_64K=y
 # CONFIG_PPC_64K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=13
-# CONFIG_SCHED_SMT is not set
+CONFIG_SCHED_SMT=y
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
-# CONFIG_PM is not set
+CONFIG_EXTRA_TARGETS=""
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_VERBOSE is not set
 # CONFIG_SECCOMP is not set
 CONFIG_ISA_DMA_API=y
 
@@ -273,6 +281,7 @@ CONFIG_GENERIC_ISA_DMA=y
 # CONFIG_PCI_SYSCALL is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCCARD is not set
+# CONFIG_HAS_RAPIDIO is not set
 CONFIG_PAGE_OFFSET=0xc000000000000000
 CONFIG_KERNEL_START=0xc000000000000000
 CONFIG_PHYSICAL_START=0x00000000
@@ -412,6 +421,8 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
@@ -478,6 +489,7 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SAS_LIBSAS is not set
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
@@ -533,8 +545,18 @@ CONFIG_USB_NET_MCS7830=m
 # CONFIG_USB_NET_CDC_SUBSET is not set
 # CONFIG_USB_NET_ZAURUS is not set
 # CONFIG_WAN is not set
-# CONFIG_PPP is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -603,6 +625,7 @@ CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -618,23 +641,17 @@ CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=16
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
-CONFIG_GEN_RTC=y
-# CONFIG_GEN_RTC_X is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_HANGCHECK_TIMER is not set
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -652,8 +669,17 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
 # CONFIG_DAB is not set
 
 #
@@ -671,8 +697,8 @@ CONFIG_FB=y
 CONFIG_FB_SYS_FILLRECT=y
 CONFIG_FB_SYS_COPYAREA=y
 CONFIG_FB_SYS_IMAGEBLIT=y
+# CONFIG_FB_FOREIGN_ENDIAN is not set
 CONFIG_FB_SYS_FOPS=y
-CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
@@ -712,18 +738,12 @@ CONFIG_FB_LOGO_EXTRA=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=m
-
-#
-# Advanced Linux Sound Architecture
-#
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
 # CONFIG_SND_SEQUENCER is not set
 # CONFIG_SND_MIXER_OSS is not set
 # CONFIG_SND_PCM_OSS is not set
@@ -732,53 +752,20 @@ CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-
-#
-# ALSA PowerMac devices
-#
-
-#
-# ALSA PowerMac requires I2C
-#
-
-#
-# ALSA PowerPC devices
-#
+# CONFIG_SND_DRIVERS is not set
+CONFIG_SND_PPC=y
 CONFIG_SND_PS3=m
 CONFIG_SND_PS3_DEFAULT_START_DELAY=2000
-
-#
-# USB devices
-#
-# CONFIG_SND_USB_AUDIO is not set
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=m
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
-
-#
-# System on Chip audio support
-#
 # CONFIG_SND_SOC is not set
-
-#
-# ALSA SoC audio for Freescale SOCs
-#
-
-#
-# Open Sound System
-#
 # CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
-# CONFIG_HIDRAW is not set
+CONFIG_HIDRAW=y
 
 #
 # USB Input Devices
@@ -807,17 +794,20 @@ CONFIG_USB=m
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
 # CONFIG_USB_OTG is not set
 
 #
 # USB Host Controller Drivers
 #
+# CONFIG_USB_C67X00_HCD is not set
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
 CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_EHCI_HCD_PPC_OF is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=m
 # CONFIG_USB_OHCI_HCD_PPC_OF is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
@@ -831,6 +821,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 #
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -890,12 +881,45 @@ CONFIG_USB_MON=y
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_EDAC is not set
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_PPC=m
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
@@ -911,6 +935,7 @@ CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_SECURITY is not set
 # CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
@@ -959,8 +984,8 @@ CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -1059,12 +1084,15 @@ CONFIG_NLS_ISO8859_1=y
 #
 CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_FIRST_BIT is not set
-# CONFIG_CRC_CCITT is not set
+CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
 CONFIG_LZO_COMPRESS=m
 CONFIG_LZO_DECOMPRESS=m
 CONFIG_PLIST=y
@@ -1082,7 +1110,7 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=2048
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
@@ -1090,33 +1118,49 @@ CONFIG_DETECT_SOFTLOCKUP=y
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_PROVE_LOCKING is not set
+CONFIG_DEBUG_LOCK_ALLOC=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_LOCKDEP=y
 # CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_LOCKDEP=y
+CONFIG_TRACE_IRQFLAGS=y
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_WRITECOUNT=y
 CONFIG_DEBUG_LIST=y
 # CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_SAMPLES is not set
 CONFIG_DEBUG_STACKOVERFLOW=y
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
 # CONFIG_DEBUGGER is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
 CONFIG_IRQSTACKS=y
+# CONFIG_VIRQ_DEBUG is not set
 # CONFIG_BOOTX_TEXT is not set
 # CONFIG_PPC_EARLY_DEBUG is not set
 
@@ -1172,6 +1216,10 @@ CONFIG_CRYPTO_PCBC=m
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
index bf0b1fd0ec3470080de306d9b47c56db9a034650..1a4094704b1fc630386041239241008c5d457487 100644 (file)
@@ -74,6 +74,7 @@ obj-y                         += time.o prom.o traps.o setup-common.o \
                                   misc_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_PPC32)            += entry_32.o setup_32.o
 obj-$(CONFIG_PPC64)            += dma_64.o iommu.o
+obj-$(CONFIG_KGDB)             += kgdb.o
 obj-$(CONFIG_PPC_MULTIPLATFORM)        += prom_init.o
 obj-$(CONFIG_MODULES)          += ppc_ksyms.o
 obj-$(CONFIG_BOOTX_TEXT)       += btext.o
index f7f3c215d06f30f3251ceea62bf6521f3813bb81..b936a1dd0a500adcf63f40a24538b57b32bd2609 100644 (file)
@@ -355,6 +355,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .machine_check          = machine_check_generic,
+               .oprofile_cpu_type      = "ppc64/compat-power5+",
                .platform               = "power5+",
        },
        {       /* Power6 */
@@ -386,6 +387,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .machine_check          = machine_check_generic,
+               .oprofile_cpu_type      = "ppc64/compat-power6",
                .platform               = "power6",
        },
        {       /* 2.06-compliant processor, i.e. Power7 "architected" mode */
@@ -397,6 +399,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .machine_check          = machine_check_generic,
+               .oprofile_cpu_type      = "ppc64/compat-power7",
                .platform               = "power7",
        },
        {       /* Power7 */
@@ -1629,6 +1632,23 @@ struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr)
                                t->cpu_setup = s->cpu_setup;
                                t->cpu_restore = s->cpu_restore;
                                t->platform = s->platform;
+                               /*
+                                * If we have passed through this logic once
+                                * before and have pulled the default case
+                                * because the real PVR was not found inside
+                                * cpu_specs[], then we are possibly running in
+                                * compatibility mode. In that case, let the
+                                * oprofiler know which set of compatibility
+                                * counters to pull from by making sure the
+                                * oprofile_cpu_type string is set to that of
+                                * compatibility mode. If the oprofile_cpu_type
+                                * already has a value, then we are possibly
+                                * overriding a real PVR with a logical one, and,
+                                * in that case, keep the current value for
+                                * oprofile_cpu_type.
+                                */
+                               if (t->oprofile_cpu_type == NULL)
+                                       t->oprofile_cpu_type = s->oprofile_cpu_type;
                        } else
                                *t = *s;
                        *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
index c4268500e8567358ebf980d39bc3ea5f1478a216..3cb52fa0eda319a7ff52c496e89802b162a5c56f 100644 (file)
@@ -151,16 +151,11 @@ skpinv:   addi    r6,r6,1                         /* Increment */
        /* Invalidate TLB0 */
        li      r6,0x04
        tlbivax 0,r6
-#ifdef CONFIG_SMP
-       tlbsync
-#endif
+       TLBSYNC
        /* Invalidate TLB1 */
        li      r6,0x0c
        tlbivax 0,r6
-#ifdef CONFIG_SMP
-       tlbsync
-#endif
-       msync
+       TLBSYNC
 
 /* 3. Setup a temp mapping and jump to it */
        andi.   r5, r3, 0x1     /* Find an entry not used and is non-zero */
@@ -238,10 +233,7 @@ skpinv:    addi    r6,r6,1                         /* Increment */
        /* Invalidate TLB1 */
        li      r9,0x0c
        tlbivax 0,r9
-#ifdef CONFIG_SMP
-       tlbsync
-#endif
-       msync
+       TLBSYNC
 
 /* 6. Setup KERNELBASE mapping in TLB1[0] */
        lis     r6,0x1000               /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
@@ -283,10 +275,7 @@ skpinv:    addi    r6,r6,1                         /* Increment */
        /* Invalidate TLB1 */
        li      r9,0x0c
        tlbivax 0,r9
-#ifdef CONFIG_SMP
-       tlbsync
-#endif
-       msync
+       TLBSYNC
 
        /* Establish the interrupt vector offsets */
        SET_IVOR(0,  CriticalInput);
@@ -483,90 +472,16 @@ interrupt_base:
 
        /* Data Storage Interrupt */
        START_EXCEPTION(DataStorage)
-       mtspr   SPRN_SPRG0, r10         /* Save some working registers */
-       mtspr   SPRN_SPRG1, r11
-       mtspr   SPRN_SPRG4W, r12
-       mtspr   SPRN_SPRG5W, r13
-       mfcr    r11
-       mtspr   SPRN_SPRG7W, r11
-
-       /*
-        * Check if it was a store fault, if not then bail
-        * because a user tried to access a kernel or
-        * read-protected page.  Otherwise, get the
-        * offending address and handle it.
-        */
-       mfspr   r10, SPRN_ESR
-       andis.  r10, r10, ESR_ST@h
-       beq     2f
-
-       mfspr   r10, SPRN_DEAR          /* Get faulting address */
-
-       /* If we are faulting a kernel address, we have to use the
-        * kernel page tables.
-        */
-       lis     r11, PAGE_OFFSET@h
-       cmplw   0, r10, r11
-       bge     2f
-
-       /* Get the PGD for the current thread */
-3:
-       mfspr   r11,SPRN_SPRG3
-       lwz     r11,PGDIR(r11)
-4:
-       FIND_PTE
-
-       /* Are _PAGE_USER & _PAGE_RW set & _PAGE_HWWRITE not? */
-       andi.   r13, r11, _PAGE_RW|_PAGE_USER|_PAGE_HWWRITE
-       cmpwi   0, r13, _PAGE_RW|_PAGE_USER
-       bne     2f                      /* Bail if not */
-
-       /* Update 'changed'. */
-       ori     r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
-       stw     r11, PTE_FLAGS_OFFSET(r12) /* Update Linux page table */
-
-       /* MAS2 not updated as the entry does exist in the tlb, this
-          fault taken to detect state transition (eg: COW -> DIRTY)
-        */
-       andi.   r11, r11, _PAGE_HWEXEC
-       rlwimi  r11, r11, 31, 27, 27    /* SX <- _PAGE_HWEXEC */
-       ori     r11, r11, (MAS3_UW|MAS3_SW|MAS3_UR|MAS3_SR)@l /* set static perms */
-
-       /* update search PID in MAS6, AS = 0 */
-       mfspr   r12, SPRN_PID0
-       slwi    r12, r12, 16
-       mtspr   SPRN_MAS6, r12
-
-       /* find the TLB index that caused the fault.  It has to be here. */
-       tlbsx   0, r10
-
-       /* only update the perm bits, assume the RPN is fine */
-       mfspr   r12, SPRN_MAS3
-       rlwimi  r12, r11, 0, 20, 31
-       mtspr   SPRN_MAS3,r12
-       tlbwe
-
-       /* Done...restore registers and get out of here.  */
-       mfspr   r11, SPRN_SPRG7R
-       mtcr    r11
-       mfspr   r13, SPRN_SPRG5R
-       mfspr   r12, SPRN_SPRG4R
-       mfspr   r11, SPRN_SPRG1
-       mfspr   r10, SPRN_SPRG0
-       rfi                     /* Force context change */
-
-2:
-       /*
-        * The bailout.  Restore registers to pre-exception conditions
-        * and call the heavyweights to help us out.
-        */
-       mfspr   r11, SPRN_SPRG7R
-       mtcr    r11
-       mfspr   r13, SPRN_SPRG5R
-       mfspr   r12, SPRN_SPRG4R
-       mfspr   r11, SPRN_SPRG1
-       mfspr   r10, SPRN_SPRG0
-       b       data_access
+       NORMAL_EXCEPTION_PROLOG
+       mfspr   r5,SPRN_ESR             /* Grab the ESR, save it, pass arg3 */
+       stw     r5,_ESR(r11)
+       mfspr   r4,SPRN_DEAR            /* Grab the DEAR, save it, pass arg2 */
+       andis.  r10,r5,(ESR_ILK|ESR_DLK)@h
+       bne     1f
+       EXC_XFER_EE_LITE(0x0300, handle_page_fault)
+1:
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       EXC_XFER_EE_LITE(0x0300, CacheLockingException)
 
        /* Instruction Storage Interrupt */
        INSTRUCTION_STORAGE_EXCEPTION
@@ -645,15 +560,30 @@ interrupt_base:
        lwz     r11,PGDIR(r11)
 
 4:
+       /* Mask of required permission bits. Note that while we
+        * do copy ESR:ST to _PAGE_RW position as trying to write
+        * to an RO page is pretty common, we don't do it with
+        * _PAGE_DIRTY. We could do it, but it's a fairly rare
+        * event so I'd rather take the overhead when it happens
+        * rather than adding an instruction here. We should measure
+        * whether the whole thing is worth it in the first place
+        * as we could avoid loading SPRN_ESR completely in the first
+        * place...
+        *
+        * TODO: Is it worth doing that mfspr & rlwimi in the first
+        *       place or can we save a couple of instructions here ?
+        */
+       mfspr   r12,SPRN_ESR
+       li      r13,_PAGE_PRESENT|_PAGE_ACCESSED
+       rlwimi  r13,r12,11,29,29
+
        FIND_PTE
-       andi.   r13, r11, _PAGE_PRESENT /* Is the page present? */
-       beq     2f                      /* Bail if not present */
+       andc.   r13,r13,r11             /* Check permission */
+       bne     2f                      /* Bail if permission mismach */
 
 #ifdef CONFIG_PTE_64BIT
        lwz     r13, 0(r12)
 #endif
-       ori     r11, r11, _PAGE_ACCESSED
-       stw     r11, PTE_FLAGS_OFFSET(r12)
 
         /* Jump to common tlb load */
        b       finish_tlb_load
@@ -667,7 +597,7 @@ interrupt_base:
        mfspr   r12, SPRN_SPRG4R
        mfspr   r11, SPRN_SPRG1
        mfspr   r10, SPRN_SPRG0
-       b       data_access
+       b       DataStorage
 
        /* Instruction TLB Error Interrupt */
        /*
@@ -705,15 +635,16 @@ interrupt_base:
        lwz     r11,PGDIR(r11)
 
 4:
+       /* Make up the required permissions */
+       li      r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC
+
        FIND_PTE
-       andi.   r13, r11, _PAGE_PRESENT /* Is the page present? */
-       beq     2f                      /* Bail if not present */
+       andc.   r13,r13,r11             /* Check permission */
+       bne     2f                      /* Bail if permission mismach */
 
 #ifdef CONFIG_PTE_64BIT
        lwz     r13, 0(r12)
 #endif
-       ori     r11, r11, _PAGE_ACCESSED
-       stw     r11, PTE_FLAGS_OFFSET(r12)
 
        /* Jump to common TLB load point */
        b       finish_tlb_load
@@ -768,29 +699,13 @@ interrupt_base:
  * Local functions
  */
 
-       /*
-        * Data TLB exceptions will bail out to this point
-        * if they can't resolve the lightweight TLB fault.
-        */
-data_access:
-       NORMAL_EXCEPTION_PROLOG
-       mfspr   r5,SPRN_ESR             /* Grab the ESR, save it, pass arg3 */
-       stw     r5,_ESR(r11)
-       mfspr   r4,SPRN_DEAR            /* Grab the DEAR, save it, pass arg2 */
-       andis.  r10,r5,(ESR_ILK|ESR_DLK)@h
-       bne     1f
-       EXC_XFER_EE_LITE(0x0300, handle_page_fault)
-1:
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       EXC_XFER_EE_LITE(0x0300, CacheLockingException)
-
 /*
-
  * Both the instruction and data TLB miss get to this
  * point to load the TLB.
  *     r10 - EA of fault
  *     r11 - TLB (info from Linux PTE)
- *     r12, r13 - available to use
+ *     r12 - available to use
+ *     r13 - upper bits of PTE (if PTE_64BIT) or available to use
  *     CR5 - results of addr >= PAGE_OFFSET
  *     MAS0, MAS1 - loaded with proper value when we get here
  *     MAS2, MAS3 - will need additional info from Linux PTE
@@ -812,20 +727,14 @@ finish_tlb_load:
 #endif
        mtspr   SPRN_MAS2, r12
 
-       bge     5, 1f
-
-       /* is user addr */
-       andi.   r12, r11, (_PAGE_USER | _PAGE_HWWRITE | _PAGE_HWEXEC)
+       li      r10, (_PAGE_HWEXEC | _PAGE_PRESENT)
+       rlwimi  r10, r11, 31, 29, 29    /* extract _PAGE_DIRTY into SW */
+       and     r12, r11, r10
        andi.   r10, r11, _PAGE_USER    /* Test for _PAGE_USER */
-       srwi    r10, r12, 1
-       or      r12, r12, r10   /* Copy user perms into supervisor */
-       iseleq  r12, 0, r12
-       b       2f
-
-       /* is kernel addr */
-1:     rlwinm  r12, r11, 31, 29, 29    /* Extract _PAGE_HWWRITE into SW */
-       ori     r12, r12, (MAS3_SX | MAS3_SR)
-
+       slwi    r10, r12, 1
+       or      r10, r10, r12
+       iseleq  r12, r12, r10
+       
 #ifdef CONFIG_PTE_64BIT
 2:     rlwimi  r12, r13, 24, 0, 7      /* grab RPN[32:39] */
        rlwimi  r12, r11, 24, 8, 19     /* grab RPN[40:51] */
index 8c68ee9e5d1cfc23cd7d961557e7bbb8e95b733d..2385f68c1751d17774df413d44a30468cf8f5c5e 100644 (file)
@@ -186,7 +186,8 @@ static unsigned long iommu_range_alloc(struct device *dev,
 static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
                              void *page, unsigned int npages,
                              enum dma_data_direction direction,
-                             unsigned long mask, unsigned int align_order)
+                             unsigned long mask, unsigned int align_order,
+                             struct dma_attrs *attrs)
 {
        unsigned long entry, flags;
        dma_addr_t ret = DMA_ERROR_CODE;
@@ -205,7 +206,7 @@ static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
 
        /* Put the TCEs in the HW table */
        ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & IOMMU_PAGE_MASK,
-                        direction);
+                        direction, attrs);
 
 
        /* Flush/invalidate TLB caches if necessary */
@@ -336,7 +337,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
                            npages, entry, dma_addr);
 
                /* Insert into HW table */
-               ppc_md.tce_build(tbl, entry, npages, vaddr & IOMMU_PAGE_MASK, direction);
+               ppc_md.tce_build(tbl, entry, npages, vaddr & IOMMU_PAGE_MASK,
+                                direction, attrs);
 
                /* If we are in an open segment, try merging */
                if (segstart != s) {
@@ -573,7 +575,8 @@ dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
                        align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
 
                dma_handle = iommu_alloc(dev, tbl, vaddr, npages, direction,
-                                        mask >> IOMMU_PAGE_SHIFT, align);
+                                        mask >> IOMMU_PAGE_SHIFT, align,
+                                        attrs);
                if (dma_handle == DMA_ERROR_CODE) {
                        if (printk_ratelimit())  {
                                printk(KERN_INFO "iommu_alloc failed, "
@@ -642,7 +645,7 @@ void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
        nio_pages = size >> IOMMU_PAGE_SHIFT;
        io_order = get_iommu_order(size);
        mapping = iommu_alloc(dev, tbl, ret, nio_pages, DMA_BIDIRECTIONAL,
-                             mask >> IOMMU_PAGE_SHIFT, io_order);
+                             mask >> IOMMU_PAGE_SHIFT, io_order, NULL);
        if (mapping == DMA_ERROR_CODE) {
                free_pages((unsigned long)ret, order);
                return NULL;
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
new file mode 100644 (file)
index 0000000..b4fdf2f
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+ * PowerPC backend to the KGDB stub.
+ *
+ * 1998 (c) Michael AK Tesch (tesch@cs.wisc.edu)
+ * Copyright (C) 2003 Timesys Corporation.
+ * Copyright (C) 2004-2006 MontaVista Software, Inc.
+ * PPC64 Mods (C) 2005 Frank Rowand (frowand@mvista.com)
+ * PPC32 support restored by Vitaly Wool <vwool@ru.mvista.com> and
+ * Sergei Shtylyov <sshtylyov@ru.mvista.com>
+ * Copyright (C) 2007-2008 Wind River Systems, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program as licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/kgdb.h>
+#include <linux/smp.h>
+#include <linux/signal.h>
+#include <linux/ptrace.h>
+#include <asm/current.h>
+#include <asm/processor.h>
+#include <asm/machdep.h>
+
+/*
+ * This table contains the mapping between PowerPC hardware trap types, and
+ * signals, which are primarily what GDB understands.  GDB and the kernel
+ * don't always agree on values, so we use constants taken from gdb-6.2.
+ */
+static struct hard_trap_info
+{
+       unsigned int tt;                /* Trap type code for powerpc */
+       unsigned char signo;            /* Signal that we map this trap into */
+} hard_trap_info[] = {
+       { 0x0100, 0x02 /* SIGINT */  },         /* system reset */
+       { 0x0200, 0x0b /* SIGSEGV */ },         /* machine check */
+       { 0x0300, 0x0b /* SIGSEGV */ },         /* data access */
+       { 0x0400, 0x0b /* SIGSEGV */ },         /* instruction access */
+       { 0x0500, 0x02 /* SIGINT */  },         /* external interrupt */
+       { 0x0600, 0x0a /* SIGBUS */  },         /* alignment */
+       { 0x0700, 0x05 /* SIGTRAP */ },         /* program check */
+       { 0x0800, 0x08 /* SIGFPE */  },         /* fp unavailable */
+       { 0x0900, 0x0e /* SIGALRM */ },         /* decrementer */
+       { 0x0c00, 0x14 /* SIGCHLD */ },         /* system call */
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+       { 0x2002, 0x05 /* SIGTRAP */ },         /* debug */
+#if defined(CONFIG_FSL_BOOKE)
+       { 0x2010, 0x08 /* SIGFPE */  },         /* spe unavailable */
+       { 0x2020, 0x08 /* SIGFPE */  },         /* spe unavailable */
+       { 0x2030, 0x08 /* SIGFPE */  },         /* spe fp data */
+       { 0x2040, 0x08 /* SIGFPE */  },         /* spe fp data */
+       { 0x2050, 0x08 /* SIGFPE */  },         /* spe fp round */
+       { 0x2060, 0x0e /* SIGILL */  },         /* performace monitor */
+       { 0x2900, 0x08 /* SIGFPE */  },         /* apu unavailable */
+       { 0x3100, 0x0e /* SIGALRM */ },         /* fixed interval timer */
+       { 0x3200, 0x02 /* SIGINT */  },         /* watchdog */
+#else /* ! CONFIG_FSL_BOOKE */
+       { 0x1000, 0x0e /* SIGALRM */ },         /* prog interval timer */
+       { 0x1010, 0x0e /* SIGALRM */ },         /* fixed interval timer */
+       { 0x1020, 0x02 /* SIGINT */  },         /* watchdog */
+       { 0x2010, 0x08 /* SIGFPE */  },         /* fp unavailable */
+       { 0x2020, 0x08 /* SIGFPE */  },         /* ap unavailable */
+#endif
+#else /* ! (defined(CONFIG_40x) || defined(CONFIG_BOOKE)) */
+       { 0x0d00, 0x05 /* SIGTRAP */ },         /* single-step */
+#if defined(CONFIG_8xx)
+       { 0x1000, 0x04 /* SIGILL */  },         /* software emulation */
+#else /* ! CONFIG_8xx */
+       { 0x0f00, 0x04 /* SIGILL */  },         /* performance monitor */
+       { 0x0f20, 0x08 /* SIGFPE */  },         /* altivec unavailable */
+       { 0x1300, 0x05 /* SIGTRAP */ },         /* instruction address break */
+#if defined(CONFIG_PPC64)
+       { 0x1200, 0x05 /* SIGILL */  },         /* system error */
+       { 0x1500, 0x04 /* SIGILL */  },         /* soft patch */
+       { 0x1600, 0x04 /* SIGILL */  },         /* maintenance */
+       { 0x1700, 0x08 /* SIGFPE */  },         /* altivec assist */
+       { 0x1800, 0x04 /* SIGILL */  },         /* thermal */
+#else /* ! CONFIG_PPC64 */
+       { 0x1400, 0x02 /* SIGINT */  },         /* SMI */
+       { 0x1600, 0x08 /* SIGFPE */  },         /* altivec assist */
+       { 0x1700, 0x04 /* SIGILL */  },         /* TAU */
+       { 0x2000, 0x05 /* SIGTRAP */ },         /* run mode */
+#endif
+#endif
+#endif
+       { 0x0000, 0x00 }                        /* Must be last */
+};
+
+static int computeSignal(unsigned int tt)
+{
+       struct hard_trap_info *ht;
+
+       for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+               if (ht->tt == tt)
+                       return ht->signo;
+
+       return SIGHUP;          /* default for things we don't know about */
+}
+
+static int kgdb_call_nmi_hook(struct pt_regs *regs)
+{
+       kgdb_nmicallback(raw_smp_processor_id(), regs);
+       return 0;
+}
+
+#ifdef CONFIG_SMP
+void kgdb_roundup_cpus(unsigned long flags)
+{
+       smp_send_debugger_break(MSG_ALL_BUT_SELF);
+}
+#endif
+
+/* KGDB functions to use existing PowerPC64 hooks. */
+static int kgdb_debugger(struct pt_regs *regs)
+{
+       return kgdb_handle_exception(0, computeSignal(TRAP(regs)), 0, regs);
+}
+
+static int kgdb_handle_breakpoint(struct pt_regs *regs)
+{
+       if (user_mode(regs))
+               return 0;
+
+       if (kgdb_handle_exception(0, SIGTRAP, 0, regs) != 0)
+               return 0;
+
+       if (*(u32 *) (regs->nip) == *(u32 *) (&arch_kgdb_ops.gdb_bpt_instr))
+               regs->nip += 4;
+
+       return 1;
+}
+
+static int kgdb_singlestep(struct pt_regs *regs)
+{
+       struct thread_info *thread_info, *exception_thread_info;
+
+       if (user_mode(regs))
+               return 0;
+
+       /*
+        * On Book E and perhaps other processsors, singlestep is handled on
+        * the critical exception stack.  This causes current_thread_info()
+        * to fail, since it it locates the thread_info by masking off
+        * the low bits of the current stack pointer.  We work around
+        * this issue by copying the thread_info from the kernel stack
+        * before calling kgdb_handle_exception, and copying it back
+        * afterwards.  On most processors the copy is avoided since
+        * exception_thread_info == thread_info.
+        */
+       thread_info = (struct thread_info *)(regs->gpr[1] & ~(THREAD_SIZE-1));
+       exception_thread_info = current_thread_info();
+
+       if (thread_info != exception_thread_info)
+               memcpy(exception_thread_info, thread_info, sizeof *thread_info);
+
+       kgdb_handle_exception(0, SIGTRAP, 0, regs);
+
+       if (thread_info != exception_thread_info)
+               memcpy(thread_info, exception_thread_info, sizeof *thread_info);
+
+       return 1;
+}
+
+static int kgdb_iabr_match(struct pt_regs *regs)
+{
+       if (user_mode(regs))
+               return 0;
+
+       if (kgdb_handle_exception(0, computeSignal(TRAP(regs)), 0, regs) != 0)
+               return 0;
+       return 1;
+}
+
+static int kgdb_dabr_match(struct pt_regs *regs)
+{
+       if (user_mode(regs))
+               return 0;
+
+       if (kgdb_handle_exception(0, computeSignal(TRAP(regs)), 0, regs) != 0)
+               return 0;
+       return 1;
+}
+
+#define PACK64(ptr, src) do { *(ptr++) = (src); } while (0)
+
+#define PACK32(ptr, src) do {          \
+       u32 *ptr32;                   \
+       ptr32 = (u32 *)ptr;           \
+       *(ptr32++) = (src);           \
+       ptr = (unsigned long *)ptr32; \
+       } while (0)
+
+
+void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+       unsigned long *ptr = gdb_regs;
+       int reg;
+
+       memset(gdb_regs, 0, NUMREGBYTES);
+
+       for (reg = 0; reg < 32; reg++)
+               PACK64(ptr, regs->gpr[reg]);
+
+#ifdef CONFIG_FSL_BOOKE
+#ifdef CONFIG_SPE
+       for (reg = 0; reg < 32; reg++)
+               PACK64(ptr, current->thread.evr[reg]);
+#else
+       ptr += 32;
+#endif
+#else
+       /* fp registers not used by kernel, leave zero */
+       ptr += 32 * 8 / sizeof(long);
+#endif
+
+       PACK64(ptr, regs->nip);
+       PACK64(ptr, regs->msr);
+       PACK32(ptr, regs->ccr);
+       PACK64(ptr, regs->link);
+       PACK64(ptr, regs->ctr);
+       PACK32(ptr, regs->xer);
+
+       BUG_ON((unsigned long)ptr >
+              (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
+}
+
+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
+{
+       struct pt_regs *regs = (struct pt_regs *)(p->thread.ksp +
+                                                 STACK_FRAME_OVERHEAD);
+       unsigned long *ptr = gdb_regs;
+       int reg;
+
+       memset(gdb_regs, 0, NUMREGBYTES);
+
+       /* Regs GPR0-2 */
+       for (reg = 0; reg < 3; reg++)
+               PACK64(ptr, regs->gpr[reg]);
+
+       /* Regs GPR3-13 are caller saved, not in regs->gpr[] */
+       ptr += 11;
+
+       /* Regs GPR14-31 */
+       for (reg = 14; reg < 32; reg++)
+               PACK64(ptr, regs->gpr[reg]);
+
+#ifdef CONFIG_FSL_BOOKE
+#ifdef CONFIG_SPE
+       for (reg = 0; reg < 32; reg++)
+               PACK64(ptr, p->thread.evr[reg]);
+#else
+       ptr += 32;
+#endif
+#else
+       /* fp registers not used by kernel, leave zero */
+       ptr += 32 * 8 / sizeof(long);
+#endif
+
+       PACK64(ptr, regs->nip);
+       PACK64(ptr, regs->msr);
+       PACK32(ptr, regs->ccr);
+       PACK64(ptr, regs->link);
+       PACK64(ptr, regs->ctr);
+       PACK32(ptr, regs->xer);
+
+       BUG_ON((unsigned long)ptr >
+              (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
+}
+
+#define UNPACK64(dest, ptr) do { dest = *(ptr++); } while (0)
+
+#define UNPACK32(dest, ptr) do {       \
+       u32 *ptr32;                   \
+       ptr32 = (u32 *)ptr;           \
+       dest = *(ptr32++);            \
+       ptr = (unsigned long *)ptr32; \
+       } while (0)
+
+void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+       unsigned long *ptr = gdb_regs;
+       int reg;
+#ifdef CONFIG_SPE
+       union {
+               u32 v32[2];
+               u64 v64;
+       } acc;
+#endif
+
+       for (reg = 0; reg < 32; reg++)
+               UNPACK64(regs->gpr[reg], ptr);
+
+#ifdef CONFIG_FSL_BOOKE
+#ifdef CONFIG_SPE
+       for (reg = 0; reg < 32; reg++)
+               UNPACK64(current->thread.evr[reg], ptr);
+#else
+       ptr += 32;
+#endif
+#else
+       /* fp registers not used by kernel, leave zero */
+       ptr += 32 * 8 / sizeof(int);
+#endif
+
+       UNPACK64(regs->nip, ptr);
+       UNPACK64(regs->msr, ptr);
+       UNPACK32(regs->ccr, ptr);
+       UNPACK64(regs->link, ptr);
+       UNPACK64(regs->ctr, ptr);
+       UNPACK32(regs->xer, ptr);
+
+       BUG_ON((unsigned long)ptr >
+              (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
+}
+
+/*
+ * This function does PowerPC specific procesing for interfacing to gdb.
+ */
+int kgdb_arch_handle_exception(int vector, int signo, int err_code,
+                              char *remcom_in_buffer, char *remcom_out_buffer,
+                              struct pt_regs *linux_regs)
+{
+       char *ptr = &remcom_in_buffer[1];
+       unsigned long addr;
+
+       switch (remcom_in_buffer[0]) {
+               /*
+                * sAA..AA   Step one instruction from AA..AA
+                * This will return an error to gdb ..
+                */
+       case 's':
+       case 'c':
+               /* handle the optional parameter */
+               if (kgdb_hex2long(&ptr, &addr))
+                       linux_regs->nip = addr;
+
+               atomic_set(&kgdb_cpu_doing_single_step, -1);
+               /* set the trace bit if we're stepping */
+               if (remcom_in_buffer[0] == 's') {
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+                       mtspr(SPRN_DBCR0,
+                             mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
+                       linux_regs->msr |= MSR_DE;
+#else
+                       linux_regs->msr |= MSR_SE;
+#endif
+                       kgdb_single_step = 1;
+                       if (kgdb_contthread)
+                               atomic_set(&kgdb_cpu_doing_single_step,
+                                          raw_smp_processor_id());
+               }
+               return 0;
+       }
+
+       return -1;
+}
+
+/*
+ * Global data
+ */
+struct kgdb_arch arch_kgdb_ops = {
+       .gdb_bpt_instr = {0x7d, 0x82, 0x10, 0x08},
+};
+
+static int kgdb_not_implemented(struct pt_regs *regs)
+{
+       return 0;
+}
+
+static void *old__debugger_ipi;
+static void *old__debugger;
+static void *old__debugger_bpt;
+static void *old__debugger_sstep;
+static void *old__debugger_iabr_match;
+static void *old__debugger_dabr_match;
+static void *old__debugger_fault_handler;
+
+int kgdb_arch_init(void)
+{
+       old__debugger_ipi = __debugger_ipi;
+       old__debugger = __debugger;
+       old__debugger_bpt = __debugger_bpt;
+       old__debugger_sstep = __debugger_sstep;
+       old__debugger_iabr_match = __debugger_iabr_match;
+       old__debugger_dabr_match = __debugger_dabr_match;
+       old__debugger_fault_handler = __debugger_fault_handler;
+
+       __debugger_ipi = kgdb_call_nmi_hook;
+       __debugger = kgdb_debugger;
+       __debugger_bpt = kgdb_handle_breakpoint;
+       __debugger_sstep = kgdb_singlestep;
+       __debugger_iabr_match = kgdb_iabr_match;
+       __debugger_dabr_match = kgdb_dabr_match;
+       __debugger_fault_handler = kgdb_not_implemented;
+
+       return 0;
+}
+
+void kgdb_arch_exit(void)
+{
+       __debugger_ipi = old__debugger_ipi;
+       __debugger = old__debugger;
+       __debugger_bpt = old__debugger_bpt;
+       __debugger_sstep = old__debugger_sstep;
+       __debugger_iabr_match = old__debugger_iabr_match;
+       __debugger_dabr_match = old__debugger_dabr_match;
+       __debugger_fault_handler = old__debugger_fault_handler;
+}
index 063cdd4130497173eca006e49e310393e9b9df0b..224e9a11765c9d9088090130b39ac33f72b505ab 100644 (file)
@@ -598,6 +598,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
                        res->start = pci_addr;
                        break;
                case 2:         /* PCI Memory space */
+               case 3:         /* PCI 64 bits Memory space */
                        printk(KERN_INFO
                               " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
                               cpu_addr, cpu_addr + size - 1, pci_addr,
index 90eb3a3e383ef008d81c848097e1b9f0fd8cd506..bc1fb27368af4db2ff7627c5e1eb8ffa46a54013 100644 (file)
@@ -128,12 +128,35 @@ static void of_bus_pci_count_cells(struct device_node *np,
                *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 ((addr[0] ^ range[0]) & 0x03000000)
+       if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO))
                return OF_BAD_ADDR;
 
        /* Read address values, skipping high cell */
@@ -153,25 +176,6 @@ 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)
 {
index 4efebe88e64a9607c98281a3f8489430e35495df..066e65c59b58230091db2145e1e4115abe541b84 100644 (file)
 
 #define DBG(fmt...)
 
-#if defined CONFIG_KGDB
-#include <asm/kgdb.h>
-#endif
-
 extern void bootx_init(unsigned long r4, unsigned long phys);
 
 int boot_cpuid;
@@ -302,18 +298,6 @@ void __init setup_arch(char **cmdline_p)
 
        xmon_setup();
 
-#if defined(CONFIG_KGDB)
-       if (ppc_md.kgdb_map_scc)
-               ppc_md.kgdb_map_scc();
-       set_debug_traps();
-       if (strstr(cmd_line, "gdb")) {
-               if (ppc_md.progress)
-                       ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000);
-               printk("kgdb breakpoint activated\n");
-               breakpoint();
-       }
-#endif
-
        /*
         * Set cache line size based on type of cpu as a default.
         * Systems with OF can look in the properties on the cpu node(s)
index 071bee3ec7493781ccba25a4050aa80f4898fc94..f2589645870afe4d3aa009936c21f8d2e1fa7f22 100644 (file)
@@ -59,6 +59,6 @@ EXPORT_SYMBOL_GPL(save_stack_trace);
 
 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 {
-       save_context_stack(trace, tsk->thread.regs->gpr[1], tsk, 0);
+       save_context_stack(trace, tsk->thread.ksp, tsk, 0);
 }
 EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
index c8127f832df0f6d28d8efb0ee3a2097f8933dcce..aba0ba95f0629cf320df4c006a38923d805f0aa8 100644 (file)
@@ -28,7 +28,9 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
 /* Time in microseconds we delay before sleeping in the idle loop */
 DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 };
 
-static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf,
+static ssize_t store_smt_snooze_delay(struct sys_device *dev,
+                                     struct sysdev_attribute *attr,
+                                     const char *buf,
                                      size_t count)
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
@@ -44,7 +46,9 @@ static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf,
        return count;
 }
 
-static ssize_t show_smt_snooze_delay(struct sys_device *dev, char *buf)
+static ssize_t show_smt_snooze_delay(struct sys_device *dev,
+                                    struct sysdev_attribute *attr,
+                                    char *buf)
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
 
@@ -152,14 +156,17 @@ static unsigned long write_##NAME(unsigned long val) \
        mtspr(ADDRESS, val); \
        return 0; \
 } \
-static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+static ssize_t show_##NAME(struct sys_device *dev, \
+                       struct sysdev_attribute *attr, \
+                       char *buf) \
 { \
        struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
        unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \
        return sprintf(buf, "%lx\n", val); \
 } \
 static ssize_t __used \
-       store_##NAME(struct sys_device *dev, const char *buf, size_t count) \
+       store_##NAME(struct sys_device *dev, struct sysdev_attribute *attr, \
+                       const char *buf, size_t count) \
 { \
        struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
        unsigned long val; \
index 87a72c66ce27759d3cd087e0cf2abd378f144531..a914411bced5defb4179628c9b0049d68a360ab0 100644 (file)
@@ -9,6 +9,25 @@
 
 ENTRY(_stext)
 
+PHDRS {
+       kernel PT_LOAD FLAGS(7); /* RWX */
+       notes PT_NOTE FLAGS(0);
+       dummy PT_NOTE FLAGS(0);
+
+       /* binutils < 2.18 has a bug that makes it misbehave when taking an
+          ELF file with all segments at load address 0 as input.  This
+          happens when running "strip" on vmlinux, because of the AT() magic
+          in this linker script.  People using GCC >= 4.2 won't run into
+          this problem, because the "build-id" support will put some data
+          into the "notes" segment (at a non-zero load address).
+
+          To work around this, we force some data into both the "dummy"
+          segment and the kernel segment, so the dummy segment will get a
+          non-zero load address.  It's not enough to always create the
+          "notes" segment, since if nothing gets assigned to it, its load
+          address will be zero.  */
+}
+
 #ifdef CONFIG_PPC64
 OUTPUT_ARCH(powerpc:common64)
 jiffies = jiffies_64;
@@ -50,7 +69,7 @@ SECTIONS
                . = ALIGN(PAGE_SIZE);
                _etext = .;
                PROVIDE32 (etext = .);
-       }
+       } :kernel
 
        /* Read-only data */
        RODATA
@@ -62,7 +81,13 @@ SECTIONS
                __stop___ex_table = .;
        }
 
-       NOTES
+       NOTES :kernel :notes
+
+       /* The dummy segment contents for the bug workaround mentioned above
+          near PHDRS.  */
+       .dummy : {
+               LONG(0xf177)
+       } :kernel :dummy
 
 /*
  * Init sections discarded at runtime
@@ -74,7 +99,7 @@ SECTIONS
                _sinittext = .;
                INIT_TEXT
                _einittext = .;
-       }
+       } :kernel
 
        /* .exit.text is discarded at runtime, not link time,
         * to deal with references from __bug_table
index 4e43702b98135bb20934619ad628fce6669133ce..8c5a03be31e07766d123460cf8b273ed6dab6d0b 100644 (file)
@@ -99,7 +99,7 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
 
        for (; fcur < fend; fcur++) {
                if (patch_feature_section(value, fcur)) {
-                       __WARN();
+                       WARN_ON(1);
                        printk("Unable to patch feature section at %p - %p" \
                                " with %p - %p\n",
                                calc_addr(fcur, fcur->start_off),
index 49eb1f1a2bb4f5a240ff45a0d807bae129718155..64e2e499e32a6fecacf81cb6eba2d03a32c8e50d 100644 (file)
 #include <asm/ppc_asm.h>
 
        .section __ex_table,"a"
-#ifdef CONFIG_PPC64
-       .align  3
-#define EXTBL  .llong
-#else
-       .align  2
-#define EXTBL  .long
-#endif
+       PPC_LONG_ALIGN
        .text
        
 _GLOBAL(strcpy)
@@ -160,9 +154,9 @@ _GLOBAL(__clear_user)
        blr
 
        .section __ex_table,"a"
-       EXTBL   11b,90b
-       EXTBL   1b,91b
-       EXTBL   8b,92b
+       PPC_LONG        11b,90b
+       PPC_LONG        1b,91b
+       PPC_LONG        8b,92b
        .text
 
 _GLOBAL(__strncpy_from_user)
@@ -183,7 +177,7 @@ _GLOBAL(__strncpy_from_user)
        blr
 
        .section __ex_table,"a"
-       EXTBL   1b,99b
+       PPC_LONG        1b,99b
        .text
 
 /* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
@@ -208,4 +202,4 @@ _GLOBAL(__strnlen_user)
        blr
 
        .section __ex_table,"a"
-       EXTBL   1b,99b
+       PPC_LONG        1b,99b
index acd2fc8cf492086c83fecc7f69469c62b7c03c06..d664b1bce381afcc30b2988f4beb1d28e1508df0 100644 (file)
@@ -3,6 +3,7 @@ config PPC_MPC52xx
        depends on PPC_MULTIPLATFORM && PPC32
        select FSL_SOC
        select PPC_CLOCK
+       select PPC_PCI_CHOICE
 
 config PPC_MPC5200_SIMPLE
        bool "Generic support for simple MPC5200 based boards"
index 1c8034bfa796d24b7c89323ba57a55600a58c829..75eb1ede54978a26af11f5fc791febbb459aa647 100644 (file)
@@ -30,6 +30,7 @@ config EP8248E
        select 8272
        select 8260
        select FSL_SOC
+       select PHYLIB
        select MDIO_BITBANG
        help
          This enables support for the Embedded Planet EP8248E board.
index 373e993a5ed5c16d378a93061668d0c9e66ec3f2..d5770fdf7f0970701c033363f53013caa3e5b45e 100644 (file)
@@ -59,7 +59,6 @@ static void __init ep8248e_pic_init(void)
        of_node_put(np);
 }
 
-#ifdef CONFIG_FS_ENET_MDIO_FCC
 static void ep8248e_set_mdc(struct mdiobb_ctrl *ctrl, int level)
 {
        if (level)
@@ -165,7 +164,6 @@ static struct of_platform_driver ep8248e_mdio_driver = {
        .probe = ep8248e_mdio_probe,
        .remove = ep8248e_mdio_remove,
 };
-#endif
 
 struct cpm_pin {
        int port, pin, flags;
@@ -298,9 +296,7 @@ static  __initdata struct of_device_id of_bus_ids[] = {
 static int __init declare_of_platform_devices(void)
 {
        of_platform_bus_probe(NULL, of_bus_ids, NULL);
-#ifdef CONFIG_FS_ENET_MDIO_FCC
        of_register_platform_driver(&ep8248e_mdio_driver);
-#endif
 
        return 0;
 }
index 27d9bf86de011897fc775ebc7132ae411fa1850a..6159c5d4e5f1335d2fd3e7f44dbe887885dab183 100644 (file)
@@ -2,7 +2,8 @@ menuconfig PPC_83xx
        bool "83xx-based boards"
        depends on 6xx && PPC_MULTIPLATFORM
        select PPC_UDBG_16550
-       select PPC_INDIRECT_PCI
+       select PPC_PCI_CHOICE
+       select FSL_PCI if PCI
        select FSL_SOC
        select IPIC
 
index f331fd7dd836599db4fc1ce8b1a178f9669db925..ba5028e2989065a7484733b0833fda94fdf78354 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the PowerPC 83xx linux kernel.
 #
 obj-y                          := misc.o usb.o
-obj-$(CONFIG_PCI)              += pci.o
+obj-$(CONFIG_SUSPEND)          += suspend.o suspend-asm.o
 obj-$(CONFIG_MPC831x_RDB)      += mpc831x_rdb.o
 obj-$(CONFIG_MPC832x_RDB)      += mpc832x_rdb.o
 obj-$(CONFIG_MPC834x_MDS)      += mpc834x_mds.o
index c4db5172b27ab34de9af690f8a1af8075565def8..a428f8d1ac80c0d1a8b16964f99286c6b36a5397 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/time.h>
 #include <asm/ipic.h>
 #include <asm/udbg.h>
+#include <sysdev/fsl_pci.h>
 
 #include "mpc83xx.h"
 
index 6dbc6eabcb02a9465580e1b683e83f8fbf4c3ca4..dd4be4aee3149a3063ef002f6252373ea9c728aa 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/prom.h>
 #include <asm/udbg.h>
 #include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
 #include <asm/qe.h>
 #include <asm/qe_ic.h>
 
index e7f706b624feeb574a3e7f3a91d34c5b39192c0e..f049d692d4c82c16984abcb7ee935c7fd3773ce2 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/qe.h>
 #include <asm/qe_ic.h>
 #include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
 
 #include "mpc83xx.h"
 
index 50e8f632061c88397321d8808ecfbf0093f40626..7301d77a08eec283184c30362bc1585c0427fed4 100644 (file)
@@ -35,6 +35,7 @@
 #include <asm/prom.h>
 #include <asm/udbg.h>
 #include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
 
 #include "mpc83xx.h"
 
index 2b8a0a3f85573341749bdcc05fdb5b125d214d73..30d509aa9f082f610d59691e5031f25d78e40e89 100644 (file)
@@ -35,6 +35,7 @@
 #include <asm/prom.h>
 #include <asm/udbg.h>
 #include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
 
 #include "mpc83xx.h"
 
index c2e5de60c055242ac6384402fe177825fd0313cd..75b80e836576c1b214724653bab4c4d30c833fd6 100644 (file)
@@ -42,6 +42,7 @@
 #include <asm/prom.h>
 #include <asm/udbg.h>
 #include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
 #include <asm/qe.h>
 #include <asm/qe_ic.h>
 
index c10dec4bf1787fdb70dbc2c8e30599359be1fe36..a5273bb28e1bcaa23d5fd19b3f2342d5b056adbb 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/qe.h>
 #include <asm/qe_ic.h>
 #include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
 
 #include "mpc83xx.h"
 
index 64d17b0d64555cbd4a29271b7f7122abed2caba0..be62de23beadc1748a3d391c51578ddb74c0a4fc 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/ipic.h>
 #include <asm/udbg.h>
 #include <asm/prom.h>
+#include <sysdev/fsl_pci.h>
 
 #include "mpc83xx.h"
 
index c00356bdb1dda4d293d3dc57d97e8eaba0c2773f..da030afa2e2cd92039c82fe34f890cfb46f132c4 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/time.h>
 #include <asm/ipic.h>
 #include <asm/udbg.h>
+#include <sysdev/fsl_pci.h>
 
 #include "mpc83xx.h"
 
index 88a3b5cabb18c5f18834110d62aa99952d940c78..2a7cbabb410a89ead86b06b481eedd8b3673a8ba 100644 (file)
@@ -26,6 +26,8 @@
 #define MPC834X_SICRL_USB1         0x20000000
 #define MPC831X_SICRL_USB_MASK     0x00000c00
 #define MPC831X_SICRL_USB_ULPI     0x00000800
+#define MPC8315_SICRL_USB_MASK     0x000000fc
+#define MPC8315_SICRL_USB_ULPI     0x00000054
 #define MPC837X_SICRL_USB_MASK     0xf0000000
 #define MPC837X_SICRL_USB_ULPI     0x50000000
 
@@ -34,6 +36,8 @@
 #define MPC834X_SICRH_USB_UTMI     0x00020000
 #define MPC831X_SICRH_USB_MASK     0x000000e0
 #define MPC831X_SICRH_USB_ULPI     0x000000a0
+#define MPC8315_SICRH_USB_MASK     0x0000ff00
+#define MPC8315_SICRH_USB_ULPI     0x00000000
 
 /* USB Control Register */
 #define FSL_USB2_CONTROL_OFFS      0x500
@@ -55,7 +59,6 @@
  * mpc83xx_* files. Mostly for use by mpc83xx_setup
  */
 
-extern int mpc83xx_add_bridge(struct device_node *dev);
 extern void mpc83xx_restart(char *cmd);
 extern long mpc83xx_time_init(void);
 extern int mpc834x_usb_cfg(void);
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
deleted file mode 100644 (file)
index 14f1080..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * FSL SoC setup code
- *
- * Maintained by Kumar Gala (see MAINTAINERS for contact information)
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/module.h>
-
-#include <asm/system.h>
-#include <asm/atomic.h>
-#include <asm/io.h>
-#include <asm/pci-bridge.h>
-#include <asm/prom.h>
-#include <sysdev/fsl_soc.h>
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-int __init mpc83xx_add_bridge(struct device_node *dev)
-{
-       int len;
-       struct pci_controller *hose;
-       struct resource rsrc;
-       const int *bus_range;
-       int primary = 1, has_address = 0;
-       phys_addr_t immr = get_immrbase();
-
-       DBG("Adding PCI host bridge %s\n", dev->full_name);
-
-       /* Fetch host bridge registers address */
-       has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
-
-       /* Get bus range if any */
-       bus_range = of_get_property(dev, "bus-range", &len);
-       if (bus_range == NULL || len < 2 * sizeof(int)) {
-               printk(KERN_WARNING "Can't get bus-range for %s, assume"
-                      " bus 0\n", dev->full_name);
-       }
-
-       ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
-       hose = pcibios_alloc_controller(dev);
-       if (!hose)
-               return -ENOMEM;
-
-       hose->first_busno = bus_range ? bus_range[0] : 0;
-       hose->last_busno = bus_range ? bus_range[1] : 0xff;
-
-       /* MPC83xx supports up to two host controllers one at 0x8500 from immrbar
-        * the other at 0x8600, we consider the 0x8500 the primary controller
-        */
-       /* PCI 1 */
-       if ((rsrc.start & 0xfffff) == 0x8500) {
-               setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304, 0);
-       }
-       /* PCI 2 */
-       if ((rsrc.start & 0xfffff) == 0x8600) {
-               setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384, 0);
-               primary = 0;
-       }
-
-       printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. "
-              "Firmware bus number: %d->%d\n",
-              (unsigned long long)rsrc.start, hose->first_busno,
-              hose->last_busno);
-
-       DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
-           hose, hose->cfg_addr, hose->cfg_data);
-
-       /* Interpret the "ranges" property */
-       /* This also maps the I/O region and sets isa_io/mem_base */
-       pci_process_bridge_OF_ranges(hose, dev, primary);
-
-       return 0;
-}
index cf382474a83d0cd92cdbe87a236df3b0384dcd9b..fc21f5c15bab43e30b3612ada5510020adfe3bc4 100644 (file)
@@ -37,6 +37,7 @@
 #include <asm/prom.h>
 #include <asm/udbg.h>
 #include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
 
 #include "mpc83xx.h"
 
diff --git a/arch/powerpc/platforms/83xx/suspend-asm.S b/arch/powerpc/platforms/83xx/suspend-asm.S
new file mode 100644 (file)
index 0000000..1930543
--- /dev/null
@@ -0,0 +1,533 @@
+/*
+ * Enter and leave deep sleep state on MPC83xx
+ *
+ * Copyright (c) 2006-2008 Freescale Semiconductor, Inc.
+ * Author: Scott Wood <scottwood@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <asm/page.h>
+#include <asm/ppc_asm.h>
+#include <asm/reg.h>
+#include <asm/asm-offsets.h>
+
+#define SS_MEMSAVE     0x00 /* First 8 bytes of RAM */
+#define SS_HID         0x08 /* 3 HIDs */
+#define SS_IABR                0x14 /* 2 IABRs */
+#define SS_IBCR                0x1c
+#define SS_DABR                0x20 /* 2 DABRs */
+#define SS_DBCR                0x28
+#define SS_SP          0x2c
+#define SS_SR          0x30 /* 16 segment registers */
+#define SS_R2          0x70
+#define SS_MSR         0x74
+#define SS_SDR1                0x78
+#define SS_LR          0x7c
+#define SS_SPRG                0x80 /* 4 SPRGs */
+#define SS_DBAT                0x90 /* 8 DBATs */
+#define SS_IBAT                0xd0 /* 8 IBATs */
+#define SS_TB          0x110
+#define SS_CR          0x118
+#define SS_GPREG       0x11c /* r12-r31 */
+#define STATE_SAVE_SIZE 0x16c
+
+       .section .data
+       .align  5
+
+mpc83xx_sleep_save_area:
+       .space  STATE_SAVE_SIZE
+immrbase:
+       .long   0
+
+       .section .text
+       .align  5
+
+       /* r3 = physical address of IMMR */
+_GLOBAL(mpc83xx_enter_deep_sleep)
+       lis     r4, immrbase@ha
+       stw     r3, immrbase@l(r4)
+
+       /* The first 2 words of memory are used to communicate with the
+        * bootloader, to tell it how to resume.
+        *
+        * The first word is the magic number 0xf5153ae5, and the second
+        * is the pointer to mpc83xx_deep_resume.
+        *
+        * The original content of these two words is saved in SS_MEMSAVE.
+        */
+
+       lis     r3, mpc83xx_sleep_save_area@h
+       ori     r3, r3, mpc83xx_sleep_save_area@l
+
+       lis     r4, KERNELBASE@h
+       lwz     r5, 0(r4)
+       lwz     r6, 4(r4)
+
+       stw     r5, SS_MEMSAVE+0(r3)
+       stw     r6, SS_MEMSAVE+4(r3)
+
+       mfspr   r5, SPRN_HID0
+       mfspr   r6, SPRN_HID1
+       mfspr   r7, SPRN_HID2
+
+       stw     r5, SS_HID+0(r3)
+       stw     r6, SS_HID+4(r3)
+       stw     r7, SS_HID+8(r3)
+
+       mfspr   r4, SPRN_IABR
+       mfspr   r5, SPRN_IABR2
+       mfspr   r6, SPRN_IBCR
+       mfspr   r7, SPRN_DABR
+       mfspr   r8, SPRN_DABR2
+       mfspr   r9, SPRN_DBCR
+
+       stw     r4, SS_IABR+0(r3)
+       stw     r5, SS_IABR+4(r3)
+       stw     r6, SS_IBCR(r3)
+       stw     r7, SS_DABR+0(r3)
+       stw     r8, SS_DABR+4(r3)
+       stw     r9, SS_DBCR(r3)
+
+       mfspr   r4, SPRN_SPRG0
+       mfspr   r5, SPRN_SPRG1
+       mfspr   r6, SPRN_SPRG2
+       mfspr   r7, SPRN_SPRG3
+       mfsdr1  r8
+
+       stw     r4, SS_SPRG+0(r3)
+       stw     r5, SS_SPRG+4(r3)
+       stw     r6, SS_SPRG+8(r3)
+       stw     r7, SS_SPRG+12(r3)
+       stw     r8, SS_SDR1(r3)
+
+       mfspr   r4, SPRN_DBAT0U
+       mfspr   r5, SPRN_DBAT0L
+       mfspr   r6, SPRN_DBAT1U
+       mfspr   r7, SPRN_DBAT1L
+
+       stw     r4, SS_DBAT+0x00(r3)
+       stw     r5, SS_DBAT+0x04(r3)
+       stw     r6, SS_DBAT+0x08(r3)
+       stw     r7, SS_DBAT+0x0c(r3)
+
+       mfspr   r4, SPRN_DBAT2U
+       mfspr   r5, SPRN_DBAT2L
+       mfspr   r6, SPRN_DBAT3U
+       mfspr   r7, SPRN_DBAT3L
+
+       stw     r4, SS_DBAT+0x10(r3)
+       stw     r5, SS_DBAT+0x14(r3)
+       stw     r6, SS_DBAT+0x18(r3)
+       stw     r7, SS_DBAT+0x1c(r3)
+
+       mfspr   r4, SPRN_DBAT4U
+       mfspr   r5, SPRN_DBAT4L
+       mfspr   r6, SPRN_DBAT5U
+       mfspr   r7, SPRN_DBAT5L
+
+       stw     r4, SS_DBAT+0x20(r3)
+       stw     r5, SS_DBAT+0x24(r3)
+       stw     r6, SS_DBAT+0x28(r3)
+       stw     r7, SS_DBAT+0x2c(r3)
+
+       mfspr   r4, SPRN_DBAT6U
+       mfspr   r5, SPRN_DBAT6L
+       mfspr   r6, SPRN_DBAT7U
+       mfspr   r7, SPRN_DBAT7L
+
+       stw     r4, SS_DBAT+0x30(r3)
+       stw     r5, SS_DBAT+0x34(r3)
+       stw     r6, SS_DBAT+0x38(r3)
+       stw     r7, SS_DBAT+0x3c(r3)
+
+       mfspr   r4, SPRN_IBAT0U
+       mfspr   r5, SPRN_IBAT0L
+       mfspr   r6, SPRN_IBAT1U
+       mfspr   r7, SPRN_IBAT1L
+
+       stw     r4, SS_IBAT+0x00(r3)
+       stw     r5, SS_IBAT+0x04(r3)
+       stw     r6, SS_IBAT+0x08(r3)
+       stw     r7, SS_IBAT+0x0c(r3)
+
+       mfspr   r4, SPRN_IBAT2U
+       mfspr   r5, SPRN_IBAT2L
+       mfspr   r6, SPRN_IBAT3U
+       mfspr   r7, SPRN_IBAT3L
+
+       stw     r4, SS_IBAT+0x10(r3)
+       stw     r5, SS_IBAT+0x14(r3)
+       stw     r6, SS_IBAT+0x18(r3)
+       stw     r7, SS_IBAT+0x1c(r3)
+
+       mfspr   r4, SPRN_IBAT4U
+       mfspr   r5, SPRN_IBAT4L
+       mfspr   r6, SPRN_IBAT5U
+       mfspr   r7, SPRN_IBAT5L
+
+       stw     r4, SS_IBAT+0x20(r3)
+       stw     r5, SS_IBAT+0x24(r3)
+       stw     r6, SS_IBAT+0x28(r3)
+       stw     r7, SS_IBAT+0x2c(r3)
+
+       mfspr   r4, SPRN_IBAT6U
+       mfspr   r5, SPRN_IBAT6L
+       mfspr   r6, SPRN_IBAT7U
+       mfspr   r7, SPRN_IBAT7L
+
+       stw     r4, SS_IBAT+0x30(r3)
+       stw     r5, SS_IBAT+0x34(r3)
+       stw     r6, SS_IBAT+0x38(r3)
+       stw     r7, SS_IBAT+0x3c(r3)
+
+       mfmsr   r4
+       mflr    r5
+       mfcr    r6
+
+       stw     r4, SS_MSR(r3)
+       stw     r5, SS_LR(r3)
+       stw     r6, SS_CR(r3)
+       stw     r1, SS_SP(r3)
+       stw     r2, SS_R2(r3)
+
+1:     mftbu   r4
+       mftb    r5
+       mftbu   r6
+       cmpw    r4, r6
+       bne     1b
+
+       stw     r4, SS_TB+0(r3)
+       stw     r5, SS_TB+4(r3)
+
+       stmw    r12, SS_GPREG(r3)
+
+       li      r4, 0
+       addi    r6, r3, SS_SR-4
+1:     mfsrin  r5, r4
+       stwu    r5, 4(r6)
+       addis   r4, r4, 0x1000
+       cmpwi   r4, 0
+       bne     1b
+
+       /* Disable machine checks and critical exceptions */
+       mfmsr   r4
+       rlwinm  r4, r4, 0, ~MSR_CE
+       rlwinm  r4, r4, 0, ~MSR_ME
+       mtmsr   r4
+       isync
+
+#define TMP_VIRT_IMMR          0xf0000000
+#define DEFAULT_IMMR_VALUE     0xff400000
+#define IMMRBAR_BASE           0x0000
+
+       lis     r4, immrbase@ha
+       lwz     r4, immrbase@l(r4)
+
+       /* Use DBAT0 to address the current IMMR space */
+
+       ori     r4, r4, 0x002a
+       mtspr   SPRN_DBAT0L, r4
+       lis     r8, TMP_VIRT_IMMR@h
+       ori     r4, r8, 0x001e  /* 1 MByte accessable from Kernel Space only */
+       mtspr   SPRN_DBAT0U, r4
+       isync
+
+       /* Use DBAT1 to address the original IMMR space */
+
+       lis     r4, DEFAULT_IMMR_VALUE@h
+       ori     r4, r4, 0x002a
+       mtspr   SPRN_DBAT1L, r4
+       lis     r9, (TMP_VIRT_IMMR + 0x01000000)@h
+       ori     r4, r9, 0x001e  /* 1 MByte accessable from Kernel Space only */
+       mtspr   SPRN_DBAT1U, r4
+       isync
+
+       /* Use DBAT2 to address the beginning of RAM.  This isn't done
+        * using the normal virtual mapping, because with page debugging
+        * enabled it will be read-only.
+        */
+
+       li      r4, 0x0002
+       mtspr   SPRN_DBAT2L, r4
+       lis     r4, KERNELBASE@h
+       ori     r4, r4, 0x001e  /* 1 MByte accessable from Kernel Space only */
+       mtspr   SPRN_DBAT2U, r4
+       isync
+
+       /* Flush the cache with our BAT, as there will be TLB misses
+        * otherwise if page debugging is enabled, and these misses
+        * will disturb the PLRU algorithm.
+        */
+
+       bl      __flush_disable_L1
+
+       /* Keep the i-cache enabled, so the hack below for low-boot
+        * flash will work.
+        */
+       mfspr   r3, SPRN_HID0
+       ori     r3, r3, HID0_ICE
+       mtspr   SPRN_HID0, r3
+       isync
+
+       lis     r6, 0xf515
+       ori     r6, r6, 0x3ae5
+
+       lis     r7, mpc83xx_deep_resume@h
+       ori     r7, r7, mpc83xx_deep_resume@l
+       tophys(r7, r7)
+
+       lis     r5, KERNELBASE@h
+       stw     r6, 0(r5)
+       stw     r7, 4(r5)
+
+       /* Reset BARs */
+
+       li      r4, 0
+       stw     r4, 0x0024(r8)
+       stw     r4, 0x002c(r8)
+       stw     r4, 0x0034(r8)
+       stw     r4, 0x003c(r8)
+       stw     r4, 0x0064(r8)
+       stw     r4, 0x006c(r8)
+
+       /* Rev 1 of the 8313 has problems with wakeup events that are
+        * pending during the transition to deep sleep state (such as if
+        * the PCI host sets the state to D3 and then D0 in rapid
+        * succession).  This check shrinks the race window somewhat.
+        *
+        * See erratum PCI23, though the problem is not limited
+        * to PCI.
+        */
+
+       lwz     r3, 0x0b04(r8)
+       andi.   r3, r3, 1
+       bne-    mpc83xx_deep_resume
+
+       /* Move IMMR back to the default location, following the
+        * procedure specified in the MPC8313 manual.
+        */
+       lwz     r4, IMMRBAR_BASE(r8)
+       isync
+       lis     r4, DEFAULT_IMMR_VALUE@h
+       stw     r4, IMMRBAR_BASE(r8)
+       lis     r4, KERNELBASE@h
+       lwz     r4, 0(r4)
+       isync
+       lwz     r4, IMMRBAR_BASE(r9)
+       mr      r8, r9
+       isync
+
+       /* Check the Reset Configuration Word to see whether flash needs
+        * to be mapped at a low address or a high address.
+        */
+
+       lwz     r4, 0x0904(r8)
+       andis.  r4, r4, 0x0400
+       li      r4, 0
+       beq     boot_low
+       lis     r4, 0xff80
+boot_low:
+       stw     r4, 0x0020(r8)
+       lis     r7, 0x8000
+       ori     r7, r7, 0x0016
+
+       mfspr   r5, SPRN_HID0
+       rlwinm  r5, r5, 0, ~(HID0_DOZE | HID0_NAP)
+       oris    r5, r5, HID0_SLEEP@h
+       mtspr   SPRN_HID0, r5
+       isync
+
+       mfmsr   r5
+       oris    r5, r5, MSR_POW@h
+
+       /* Enable the flash mapping at the appropriate address.  This
+        * mapping will override the RAM mapping if booting low, so there's
+        * no need to disable the latter.  This must be done inside the same
+        * cache line as setting MSR_POW, so that no instruction fetches
+        * from RAM happen after the flash mapping is turned on.
+        */
+
+       .align  5
+       stw     r7, 0x0024(r8)
+       sync
+       isync
+       mtmsr   r5
+       isync
+1:     b       1b
+
+mpc83xx_deep_resume:
+       lis     r4, 1f@h
+       ori     r4, r4, 1f@l
+       tophys(r4, r4)
+       mtsrr0  r4
+
+       mfmsr   r4
+       rlwinm  r4, r4, 0, ~(MSR_IR | MSR_DR)
+       mtsrr1  r4
+
+       rfi
+
+1:     tlbia
+       bl      __inval_enable_L1
+
+       lis     r3, mpc83xx_sleep_save_area@h
+       ori     r3, r3, mpc83xx_sleep_save_area@l
+       tophys(r3, r3)
+
+       lwz     r5, SS_MEMSAVE+0(r3)
+       lwz     r6, SS_MEMSAVE+4(r3)
+
+       stw     r5, 0(0)
+       stw     r6, 4(0)
+
+       lwz     r5, SS_HID+0(r3)
+       lwz     r6, SS_HID+4(r3)
+       lwz     r7, SS_HID+8(r3)
+
+       mtspr   SPRN_HID0, r5
+       mtspr   SPRN_HID1, r6
+       mtspr   SPRN_HID2, r7
+
+       lwz     r4, SS_IABR+0(r3)
+       lwz     r5, SS_IABR+4(r3)
+       lwz     r6, SS_IBCR(r3)
+       lwz     r7, SS_DABR+0(r3)
+       lwz     r8, SS_DABR+4(r3)
+       lwz     r9, SS_DBCR(r3)
+
+       mtspr   SPRN_IABR, r4
+       mtspr   SPRN_IABR2, r5
+       mtspr   SPRN_IBCR, r6
+       mtspr   SPRN_DABR, r7
+       mtspr   SPRN_DABR2, r8
+       mtspr   SPRN_DBCR, r9
+
+       li      r4, 0
+       addi    r6, r3, SS_SR-4
+1:     lwzu    r5, 4(r6)
+       mtsrin  r5, r4
+       addis   r4, r4, 0x1000
+       cmpwi   r4, 0
+       bne     1b
+
+       lwz     r4, SS_DBAT+0x00(r3)
+       lwz     r5, SS_DBAT+0x04(r3)
+       lwz     r6, SS_DBAT+0x08(r3)
+       lwz     r7, SS_DBAT+0x0c(r3)
+
+       mtspr   SPRN_DBAT0U, r4
+       mtspr   SPRN_DBAT0L, r5
+       mtspr   SPRN_DBAT1U, r6
+       mtspr   SPRN_DBAT1L, r7
+
+       lwz     r4, SS_DBAT+0x10(r3)
+       lwz     r5, SS_DBAT+0x14(r3)
+       lwz     r6, SS_DBAT+0x18(r3)
+       lwz     r7, SS_DBAT+0x1c(r3)
+
+       mtspr   SPRN_DBAT2U, r4
+       mtspr   SPRN_DBAT2L, r5
+       mtspr   SPRN_DBAT3U, r6
+       mtspr   SPRN_DBAT3L, r7
+
+       lwz     r4, SS_DBAT+0x20(r3)
+       lwz     r5, SS_DBAT+0x24(r3)
+       lwz     r6, SS_DBAT+0x28(r3)
+       lwz     r7, SS_DBAT+0x2c(r3)
+
+       mtspr   SPRN_DBAT4U, r4
+       mtspr   SPRN_DBAT4L, r5
+       mtspr   SPRN_DBAT5U, r6
+       mtspr   SPRN_DBAT5L, r7
+
+       lwz     r4, SS_DBAT+0x30(r3)
+       lwz     r5, SS_DBAT+0x34(r3)
+       lwz     r6, SS_DBAT+0x38(r3)
+       lwz     r7, SS_DBAT+0x3c(r3)
+
+       mtspr   SPRN_DBAT6U, r4
+       mtspr   SPRN_DBAT6L, r5
+       mtspr   SPRN_DBAT7U, r6
+       mtspr   SPRN_DBAT7L, r7
+
+       lwz     r4, SS_IBAT+0x00(r3)
+       lwz     r5, SS_IBAT+0x04(r3)
+       lwz     r6, SS_IBAT+0x08(r3)
+       lwz     r7, SS_IBAT+0x0c(r3)
+
+       mtspr   SPRN_IBAT0U, r4
+       mtspr   SPRN_IBAT0L, r5
+       mtspr   SPRN_IBAT1U, r6
+       mtspr   SPRN_IBAT1L, r7
+
+       lwz     r4, SS_IBAT+0x10(r3)
+       lwz     r5, SS_IBAT+0x14(r3)
+       lwz     r6, SS_IBAT+0x18(r3)
+       lwz     r7, SS_IBAT+0x1c(r3)
+
+       mtspr   SPRN_IBAT2U, r4
+       mtspr   SPRN_IBAT2L, r5
+       mtspr   SPRN_IBAT3U, r6
+       mtspr   SPRN_IBAT3L, r7
+
+       lwz     r4, SS_IBAT+0x20(r3)
+       lwz     r5, SS_IBAT+0x24(r3)
+       lwz     r6, SS_IBAT+0x28(r3)
+       lwz     r7, SS_IBAT+0x2c(r3)
+
+       mtspr   SPRN_IBAT4U, r4
+       mtspr   SPRN_IBAT4L, r5
+       mtspr   SPRN_IBAT5U, r6
+       mtspr   SPRN_IBAT5L, r7
+
+       lwz     r4, SS_IBAT+0x30(r3)
+       lwz     r5, SS_IBAT+0x34(r3)
+       lwz     r6, SS_IBAT+0x38(r3)
+       lwz     r7, SS_IBAT+0x3c(r3)
+
+       mtspr   SPRN_IBAT6U, r4
+       mtspr   SPRN_IBAT6L, r5
+       mtspr   SPRN_IBAT7U, r6
+       mtspr   SPRN_IBAT7L, r7
+
+       lwz     r4, SS_SPRG+0(r3)
+       lwz     r5, SS_SPRG+4(r3)
+       lwz     r6, SS_SPRG+8(r3)
+       lwz     r7, SS_SPRG+12(r3)
+       lwz     r8, SS_SDR1(r3)
+
+       mtspr   SPRN_SPRG0, r4
+       mtspr   SPRN_SPRG1, r5
+       mtspr   SPRN_SPRG2, r6
+       mtspr   SPRN_SPRG3, r7
+       mtsdr1  r8
+
+       lwz     r4, SS_MSR(r3)
+       lwz     r5, SS_LR(r3)
+       lwz     r6, SS_CR(r3)
+       lwz     r1, SS_SP(r3)
+       lwz     r2, SS_R2(r3)
+
+       mtsrr1  r4
+       mtsrr0  r5
+       mtcr    r6
+
+       li      r4, 0
+       mtspr   SPRN_TBWL, r4
+
+       lwz     r4, SS_TB+0(r3)
+       lwz     r5, SS_TB+4(r3)
+
+       mtspr   SPRN_TBWU, r4
+       mtspr   SPRN_TBWL, r5
+
+       lmw     r12, SS_GPREG(r3)
+
+       /* Kick decrementer */
+       li      r0, 1
+       mtdec   r0
+
+       rfi
diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c
new file mode 100644 (file)
index 0000000..08e65fc
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * MPC83xx suspend support
+ *
+ * Author: Scott Wood <scottwood@freescale.com>
+ *
+ * Copyright (c) 2006-2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/suspend.h>
+#include <linux/fsl_devices.h>
+#include <linux/of_platform.h>
+
+#include <asm/reg.h>
+#include <asm/io.h>
+#include <asm/time.h>
+#include <asm/mpc6xx.h>
+
+#include <sysdev/fsl_soc.h>
+
+#define PMCCR1_NEXT_STATE       0x0C /* Next state for power management */
+#define PMCCR1_NEXT_STATE_SHIFT 2
+#define PMCCR1_CURR_STATE       0x03 /* Current state for power management*/
+#define IMMR_RCW_OFFSET         0x900
+#define RCW_PCI_HOST            0x80000000
+
+void mpc83xx_enter_deep_sleep(phys_addr_t immrbase);
+
+struct mpc83xx_pmc {
+       u32 config;
+#define PMCCR_DLPEN 2 /* DDR SDRAM low power enable */
+#define PMCCR_SLPEN 1 /* System low power enable */
+
+       u32 event;
+       u32 mask;
+/* All but PMCI are deep-sleep only */
+#define PMCER_GPIO   0x100
+#define PMCER_PCI    0x080
+#define PMCER_USB    0x040
+#define PMCER_ETSEC1 0x020
+#define PMCER_ETSEC2 0x010
+#define PMCER_TIMER  0x008
+#define PMCER_INT1   0x004
+#define PMCER_INT2   0x002
+#define PMCER_PMCI   0x001
+#define PMCER_ALL    0x1FF
+
+       /* deep-sleep only */
+       u32 config1;
+#define PMCCR1_USE_STATE  0x80000000
+#define PMCCR1_PME_EN     0x00000080
+#define PMCCR1_ASSERT_PME 0x00000040
+#define PMCCR1_POWER_OFF  0x00000020
+
+       /* deep-sleep only */
+       u32 config2;
+};
+
+struct mpc83xx_rcw {
+       u32 rcwlr;
+       u32 rcwhr;
+};
+
+struct mpc83xx_clock {
+       u32 spmr;
+       u32 occr;
+       u32 sccr;
+};
+
+struct pmc_type {
+       int has_deep_sleep;
+};
+
+static struct of_device *pmc_dev;
+static int has_deep_sleep, deep_sleeping;
+static int pmc_irq;
+static struct mpc83xx_pmc __iomem *pmc_regs;
+static struct mpc83xx_clock __iomem *clock_regs;
+static int is_pci_agent, wake_from_pci;
+static phys_addr_t immrbase;
+static int pci_pm_state;
+static DECLARE_WAIT_QUEUE_HEAD(agent_wq);
+
+int fsl_deep_sleep(void)
+{
+       return deep_sleeping;
+}
+
+static int mpc83xx_change_state(void)
+{
+       u32 curr_state;
+       u32 reg_cfg1 = in_be32(&pmc_regs->config1);
+
+       if (is_pci_agent) {
+               pci_pm_state = (reg_cfg1 & PMCCR1_NEXT_STATE) >>
+                              PMCCR1_NEXT_STATE_SHIFT;
+               curr_state = reg_cfg1 & PMCCR1_CURR_STATE;
+
+               if (curr_state != pci_pm_state) {
+                       reg_cfg1 &= ~PMCCR1_CURR_STATE;
+                       reg_cfg1 |= pci_pm_state;
+                       out_be32(&pmc_regs->config1, reg_cfg1);
+
+                       wake_up(&agent_wq);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static irqreturn_t pmc_irq_handler(int irq, void *dev_id)
+{
+       u32 event = in_be32(&pmc_regs->event);
+       int ret = IRQ_NONE;
+
+       if (mpc83xx_change_state())
+               ret = IRQ_HANDLED;
+
+       if (event) {
+               out_be32(&pmc_regs->event, event);
+               ret = IRQ_HANDLED;
+       }
+
+       return ret;
+}
+
+static int mpc83xx_suspend_enter(suspend_state_t state)
+{
+       int ret = -EAGAIN;
+
+       /* Don't go to sleep if there's a race where pci_pm_state changes
+        * between the agent thread checking it and the PM code disabling
+        * interrupts.
+        */
+       if (wake_from_pci) {
+               if (pci_pm_state != (deep_sleeping ? 3 : 2))
+                       goto out;
+
+               out_be32(&pmc_regs->config1,
+                        in_be32(&pmc_regs->config1) | PMCCR1_PME_EN);
+       }
+
+       /* Put the system into low-power mode and the RAM
+        * into self-refresh mode once the core goes to
+        * sleep.
+        */
+
+       out_be32(&pmc_regs->config, PMCCR_SLPEN | PMCCR_DLPEN);
+
+       /* If it has deep sleep (i.e. it's an 831x or compatible),
+        * disable power to the core upon entering sleep mode.  This will
+        * require going through the boot firmware upon a wakeup event.
+        */
+
+       if (deep_sleeping) {
+               out_be32(&pmc_regs->mask, PMCER_ALL);
+
+               out_be32(&pmc_regs->config1,
+                        in_be32(&pmc_regs->config1) | PMCCR1_POWER_OFF);
+
+               enable_kernel_fp();
+
+               mpc83xx_enter_deep_sleep(immrbase);
+
+               out_be32(&pmc_regs->config1,
+                        in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF);
+
+               out_be32(&pmc_regs->mask, PMCER_PMCI);
+       } else {
+               out_be32(&pmc_regs->mask, PMCER_PMCI);
+
+               mpc6xx_enter_standby();
+       }
+
+       ret = 0;
+
+out:
+       out_be32(&pmc_regs->config1,
+                in_be32(&pmc_regs->config1) & ~PMCCR1_PME_EN);
+
+       return ret;
+}
+
+static void mpc83xx_suspend_finish(void)
+{
+       deep_sleeping = 0;
+}
+
+static int mpc83xx_suspend_valid(suspend_state_t state)
+{
+       return state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM;
+}
+
+static int mpc83xx_suspend_begin(suspend_state_t state)
+{
+       switch (state) {
+               case PM_SUSPEND_STANDBY:
+                       deep_sleeping = 0;
+                       return 0;
+
+               case PM_SUSPEND_MEM:
+                       if (has_deep_sleep)
+                               deep_sleeping = 1;
+
+                       return 0;
+
+               default:
+                       return -EINVAL;
+       }
+}
+
+static int agent_thread_fn(void *data)
+{
+       while (1) {
+               wait_event_interruptible(agent_wq, pci_pm_state >= 2);
+               try_to_freeze();
+
+               if (signal_pending(current) || pci_pm_state < 2)
+                       continue;
+
+               /* With a preemptible kernel (or SMP), this could race with
+                * a userspace-driven suspend request.  It's probably best
+                * to avoid mixing the two with such a configuration (or
+                * else fix it by adding a mutex to state_store that we can
+                * synchronize with).
+                */
+
+               wake_from_pci = 1;
+
+               pm_suspend(pci_pm_state == 3 ? PM_SUSPEND_MEM :
+                                              PM_SUSPEND_STANDBY);
+
+               wake_from_pci = 0;
+       }
+
+       return 0;
+}
+
+static void mpc83xx_set_agent(void)
+{
+       out_be32(&pmc_regs->config1, PMCCR1_USE_STATE);
+       out_be32(&pmc_regs->mask, PMCER_PMCI);
+
+       kthread_run(agent_thread_fn, NULL, "PCI power mgt");
+}
+
+static int mpc83xx_is_pci_agent(void)
+{
+       struct mpc83xx_rcw __iomem *rcw_regs;
+       int ret;
+
+       rcw_regs = ioremap(get_immrbase() + IMMR_RCW_OFFSET,
+                          sizeof(struct mpc83xx_rcw));
+
+       if (!rcw_regs)
+               return -ENOMEM;
+
+       ret = !(in_be32(&rcw_regs->rcwhr) & RCW_PCI_HOST);
+
+       iounmap(rcw_regs);
+       return ret;
+}
+
+static struct platform_suspend_ops mpc83xx_suspend_ops = {
+       .valid = mpc83xx_suspend_valid,
+       .begin = mpc83xx_suspend_begin,
+       .enter = mpc83xx_suspend_enter,
+       .finish = mpc83xx_suspend_finish,
+};
+
+static int pmc_probe(struct of_device *ofdev,
+                     const struct of_device_id *match)
+{
+       struct device_node *np = ofdev->node;
+       struct resource res;
+       struct pmc_type *type = match->data;
+       int ret = 0;
+
+       if (!of_device_is_available(np))
+               return -ENODEV;
+
+       has_deep_sleep = type->has_deep_sleep;
+       immrbase = get_immrbase();
+       pmc_dev = ofdev;
+
+       is_pci_agent = mpc83xx_is_pci_agent();
+       if (is_pci_agent < 0)
+               return is_pci_agent;
+
+       ret = of_address_to_resource(np, 0, &res);
+       if (ret)
+               return -ENODEV;
+
+       pmc_irq = irq_of_parse_and_map(np, 0);
+       if (pmc_irq != NO_IRQ) {
+               ret = request_irq(pmc_irq, pmc_irq_handler, IRQF_SHARED,
+                                 "pmc", ofdev);
+
+               if (ret)
+                       return -EBUSY;
+       }
+
+       pmc_regs = ioremap(res.start, sizeof(struct mpc83xx_pmc));
+
+       if (!pmc_regs) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = of_address_to_resource(np, 1, &res);
+       if (ret) {
+               ret = -ENODEV;
+               goto out_pmc;
+       }
+
+       clock_regs = ioremap(res.start, sizeof(struct mpc83xx_pmc));
+
+       if (!clock_regs) {
+               ret = -ENOMEM;
+               goto out_pmc;
+       }
+
+       if (is_pci_agent)
+               mpc83xx_set_agent();
+
+       suspend_set_ops(&mpc83xx_suspend_ops);
+       return 0;
+
+out_pmc:
+       iounmap(pmc_regs);
+out:
+       if (pmc_irq != NO_IRQ)
+               free_irq(pmc_irq, ofdev);
+
+       return ret;
+}
+
+static int pmc_remove(struct of_device *ofdev)
+{
+       return -EPERM;
+};
+
+static struct pmc_type pmc_types[] = {
+       {
+               .has_deep_sleep = 1,
+       },
+       {
+               .has_deep_sleep = 0,
+       }
+};
+
+static struct of_device_id pmc_match[] = {
+       {
+               .compatible = "fsl,mpc8313-pmc",
+               .data = &pmc_types[0],
+       },
+       {
+               .compatible = "fsl,mpc8349-pmc",
+               .data = &pmc_types[1],
+       },
+       {}
+};
+
+static struct of_platform_driver pmc_driver = {
+       .name = "mpc83xx-pmc",
+       .match_table = pmc_match,
+       .probe = pmc_probe,
+       .remove = pmc_remove
+};
+
+static int pmc_init(void)
+{
+       return of_register_platform_driver(&pmc_driver);
+}
+
+module_init(pmc_init);
index 64bcf0a33c71903fa3978de2c28d9b4df8c4bbba..cc99c280aad943ea93631a51de1399db5a90565a 100644 (file)
@@ -137,15 +137,21 @@ int mpc831x_usb_cfg(void)
 
        /* Configure pin mux for ULPI.  There is no pin mux for UTMI */
        if (prop && !strcmp(prop, "ulpi")) {
-               temp = in_be32(immap + MPC83XX_SICRL_OFFS);
-               temp &= ~MPC831X_SICRL_USB_MASK;
-               temp |= MPC831X_SICRL_USB_ULPI;
-               out_be32(immap + MPC83XX_SICRL_OFFS, temp);
-
-               temp = in_be32(immap + MPC83XX_SICRH_OFFS);
-               temp &= ~MPC831X_SICRH_USB_MASK;
-               temp |= MPC831X_SICRH_USB_ULPI;
-               out_be32(immap + MPC83XX_SICRH_OFFS, temp);
+               if (of_device_is_compatible(immr_node, "fsl,mpc8315-immr")) {
+                       clrsetbits_be32(immap + MPC83XX_SICRL_OFFS,
+                                       MPC8315_SICRL_USB_MASK,
+                                       MPC8315_SICRL_USB_ULPI);
+                       clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,
+                                       MPC8315_SICRH_USB_MASK,
+                                       MPC8315_SICRH_USB_ULPI);
+               } else {
+                       clrsetbits_be32(immap + MPC83XX_SICRL_OFFS,
+                                       MPC831X_SICRL_USB_MASK,
+                                       MPC831X_SICRL_USB_ULPI);
+                       clrsetbits_be32(immap + MPC83XX_SICRH_OFFS,
+                                       MPC831X_SICRH_USB_MASK,
+                                       MPC831X_SICRH_USB_ULPI);
+               }
        }
 
        iounmap(immap);
index cebea5cadbc1e30cd94cd77f63c5dba03cea93fa..291675b0097a902d620b9f203857d925ce919127 100644 (file)
@@ -2,8 +2,8 @@ menuconfig MPC85xx
        bool "Machine Type"
        depends on PPC_85xx
        select PPC_UDBG_16550
-       select PPC_INDIRECT_PCI if PCI
        select MPIC
+       select PPC_PCI_CHOICE
        select FSL_PCI if PCI
        select SERIAL_8250_SHARE_IRQ if SERIAL_8250
        default y
@@ -86,7 +86,6 @@ config TQM8548
        help
          This option enables support for the TQ Components TQM8548 board.
        select DEFAULT_UIMAGE
-       select PPC_CPM_NEW_BINDING
        select TQM85xx
 
 config TQM8555
index 25f41cd2d33abad60d1fca7a1fb8501107bf2f5f..00c535806647993b6de07ff5e14eb5e06ddd109f 100644 (file)
@@ -115,7 +115,6 @@ void __init mpc85xx_ds_pic_init(void)
 
 #ifdef CONFIG_PCI
 static int primary_phb_addr;
-extern int uses_fsl_uli_m1575;
 extern int uli_exclude_device(struct pci_controller *hose,
                                u_char bus, u_char devfn);
 
@@ -161,7 +160,6 @@ static void __init mpc85xx_ds_setup_arch(void)
                }
        }
 
-       uses_fsl_uli_m1575 = 1;
        ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 #endif
 
index 80a81e02bb55ac820cf440066694f0a8d9e2e9d6..9355a52694314573d9960ccb292ef42d22b7e704 100644 (file)
@@ -27,6 +27,7 @@ config SBC8641D
 config MPC8610_HPCD
        bool "Freescale MPC8610 HPCD"
        select DEFAULT_UIMAGE
+       select FSL_ULI1575
        help
          This option enables support for the MPC8610 HPCD board.
 
@@ -34,6 +35,7 @@ endif
 
 config MPC8641
        bool
+       select PPC_PCI_CHOICE
        select FSL_PCI if PCI
        select PPC_UDBG_16550
        select MPIC
@@ -41,6 +43,7 @@ config MPC8641
 
 config MPC8610
        bool
+       select PPC_PCI_CHOICE
        select FSL_PCI if PCI
        select PPC_UDBG_16550
        select MPIC
index 30725302884a53cc43e10fc8173057a6e6256839..5eedb710896e7568b8fc29cb1c78b1f7f5def81b 100644 (file)
@@ -58,93 +58,6 @@ static int __init mpc8610_declare_of_platform_devices(void)
 }
 machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices);
 
-#ifdef CONFIG_PCI
-static void __devinit quirk_uli1575(struct pci_dev *dev)
-{
-       u32 temp32;
-
-       /* Disable INTx */
-       pci_read_config_dword(dev, 0x48, &temp32);
-       pci_write_config_dword(dev, 0x48, (temp32 | 1<<26));
-
-       /* Enable sideband interrupt */
-       pci_read_config_dword(dev, 0x90, &temp32);
-       pci_write_config_dword(dev, 0x90, (temp32 | 1<<22));
-}
-
-static void __devinit quirk_uli5288(struct pci_dev *dev)
-{
-       unsigned char c;
-       unsigned short temp;
-
-       /* Interrupt Disable, Needed when SATA disabled */
-       pci_read_config_word(dev, PCI_COMMAND, &temp);
-       temp |= 1<<10;
-       pci_write_config_word(dev, PCI_COMMAND, temp);
-
-       pci_read_config_byte(dev, 0x83, &c);
-       c |= 0x80;
-       pci_write_config_byte(dev, 0x83, c);
-
-       pci_write_config_byte(dev, PCI_CLASS_PROG, 0x01);
-       pci_write_config_byte(dev, PCI_CLASS_DEVICE, 0x06);
-
-       pci_read_config_byte(dev, 0x83, &c);
-       c &= 0x7f;
-       pci_write_config_byte(dev, 0x83, c);
-}
-
-/*
- * Since 8259PIC was disabled on the board, the IDE device can not
- * use the legacy IRQ, we need to let the IDE device work under
- * native mode and use the interrupt line like other PCI devices.
- * IRQ14 is a sideband interrupt from IDE device to CPU and we use this
- * as the interrupt for IDE device.
- */
-static void __devinit quirk_uli5229(struct pci_dev *dev)
-{
-       unsigned char c;
-
-       pci_read_config_byte(dev, 0x4b, &c);
-       c |= 0x10;
-       pci_write_config_byte(dev, 0x4b, c);
-}
-
-/*
- * SATA interrupt pin bug fix
- * There's a chip bug for 5288, The interrupt pin should be 2,
- * not the read only value 1, So it use INTB#, not INTA# which
- * actually used by the IDE device 5229.
- * As of this bug, during the PCI initialization, 5288 read the
- * irq of IDE device from the device tree, this function fix this
- * bug by re-assigning a correct irq to 5288.
- *
- */
-static void __devinit final_uli5288(struct pci_dev *dev)
-{
-       struct pci_controller *hose = pci_bus_to_host(dev->bus);
-       struct device_node *hosenode = hose ? hose->dn : NULL;
-       struct of_irq oirq;
-       int virq, pin = 2;
-       u32 laddr[3];
-
-       if (!hosenode)
-               return;
-
-       laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(31, 0) << 8);
-       laddr[1] = laddr[2] = 0;
-       of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq);
-       virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
-                                    oirq.size);
-       dev->irq = virq;
-}
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 0x5288, final_uli5288);
-#endif /* CONFIG_PCI */
-
 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
 
 static u32 get_busfreq(void)
index 7916599c9126c4a26f46900ba6434b96422727c6..f712d9c0991be7ef9c6c0cc3cdccec2e98e1094e 100644 (file)
@@ -45,7 +45,6 @@
 #endif
 
 #ifdef CONFIG_PCI
-extern int uses_fsl_uli_m1575;
 extern int uli_exclude_device(struct pci_controller *hose,
                                u_char bus, u_char devfn);
 
@@ -87,7 +86,6 @@ mpc86xx_hpcn_setup_arch(void)
                        fsl_add_bridge(np, 0);
        }
 
-       uses_fsl_uli_m1575 = 1;
        ppc_md.pci_exclude_device = mpc86xx_exclude_device;
 
 #endif
index 690c1f46e698401c0c1df535fd6f85296d9a31c7..1d0968775c0a855a84c8eee2b2366301f0de9950 100644 (file)
@@ -253,17 +253,13 @@ config CPM2
        depends on MPC85xx || 8260
        select CPM
        select PPC_LIB_RHEAP
+       select PPC_PCI_CHOICE
        help
          The CPM2 (Communications Processor Module) is a coprocessor on
          embedded CPUs made by Freescale.  Selecting this option means that
          you wish to build a kernel for a machine with a CPM2 coprocessor
          on it (826x, 827x, 8560).
 
-config PPC_CPM_NEW_BINDING
-       bool
-       depends on CPM1 || CPM2
-       default y
-
 config AXON_RAM
        tristate "Axon DDR2 memory device driver"
        depends on PPC_IBM_CELL_BLADE
index 5bc4b611ff882b715d5bfb0baa7982810ddbd96f..7f6512733862b02138f4e0370a994a223a1e9a07 100644 (file)
@@ -42,12 +42,14 @@ config 40x
        select PPC_DCR_NATIVE
        select PPC_UDBG_16550
        select 4xx_SOC
+       select PPC_PCI_CHOICE
 
 config 44x
        bool "AMCC 44x"
        select PPC_DCR_NATIVE
        select PPC_UDBG_16550
        select 4xx_SOC
+       select PPC_PCI_CHOICE
 
 config E200
        bool "Freescale e200"
@@ -84,9 +86,6 @@ config TUNE_CELL
          machines. When building a kernel that is supposed to run only
          on Cell, you should also select the POWER4_ONLY option.
 
-config 6xx
-       bool
-
 # this is temp to handle compat with arch=ppc
 config 8xx
        bool
index 3959fcfe731c4a99e01ed7a124a067de85bf4e1a..c14d7d8d96c853441a2bc6e4bbfac3b7753d558a 100644 (file)
@@ -83,6 +83,22 @@ config CBE_RAS
        depends on PPC_CELL_NATIVE
        default y
 
+config PPC_IBM_CELL_RESETBUTTON
+       bool "IBM Cell Blade Pinhole reset button"
+       depends on CBE_RAS && PPC_IBM_CELL_BLADE
+       default y
+       help
+         Support Pinhole Resetbutton on IBM Cell blades.
+         This adds a method to trigger system reset via front panel pinhole button.
+
+config PPC_IBM_CELL_POWERBUTTON
+       tristate "IBM Cell Blade power button"
+       depends on PPC_IBM_CELL_BLADE && PPC_PMI && INPUT_EVDEV
+       default y
+       help
+         Support Powerbutton on IBM Cell blades.
+         This will enable the powerbutton as an input device.
+
 config CBE_THERM
        tristate "CBE thermal support"
        default m
@@ -107,6 +123,15 @@ config CBE_CPUFREQ_PMI
          processor will not only be able to run at lower speed,
          but also at lower core voltage.
 
+config CBE_CPUFREQ_SPU_GOVERNOR
+       tristate "CBE frequency scaling based on SPU usage"
+       depends on SPU_FS && CPU_FREQ
+       default m
+       help
+         This governor checks for spu usage to adjust the cpu frequency.
+         If no spu is running on a given cpu, that cpu will be throttled to
+         the minimal possible frequency.
+
 endmenu
 
 config OPROFILE_CELL
index c2a7e4e5ddf983e5dacfbe45af4925a16d2dc122..7fd830872c43bf458bd68de22ff9384c411bed19 100644 (file)
@@ -8,6 +8,9 @@ obj-$(CONFIG_CBE_THERM)                 += cbe_thermal.o
 obj-$(CONFIG_CBE_CPUFREQ_PMI)          += cbe_cpufreq_pmi.o
 obj-$(CONFIG_CBE_CPUFREQ)              += cbe-cpufreq.o
 cbe-cpufreq-y                          += cbe_cpufreq_pervasive.o cbe_cpufreq.o
+obj-$(CONFIG_CBE_CPUFREQ_SPU_GOVERNOR) += cpufreq_spudemand.o
+
+obj-$(CONFIG_PPC_IBM_CELL_POWERBUTTON) += cbe_powerbutton.o
 
 ifeq ($(CONFIG_SMP),y)
 obj-$(CONFIG_PPC_CELL_NATIVE)          += smp.o
diff --git a/arch/powerpc/platforms/cell/cbe_powerbutton.c b/arch/powerpc/platforms/cell/cbe_powerbutton.c
new file mode 100644 (file)
index 0000000..dcddaa5
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * driver for powerbutton on IBM cell blades
+ *
+ * (C) Copyright IBM Corp. 2005-2008
+ *
+ * Author: Christian Krafft <krafft@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the 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/input.h>
+#include <linux/platform_device.h>
+#include <asm/pmi.h>
+#include <asm/prom.h>
+
+static struct input_dev *button_dev;
+static struct platform_device *button_pdev;
+
+static void cbe_powerbutton_handle_pmi(pmi_message_t pmi_msg)
+{
+       BUG_ON(pmi_msg.type != PMI_TYPE_POWER_BUTTON);
+
+       input_report_key(button_dev, KEY_POWER, 1);
+       input_sync(button_dev);
+       input_report_key(button_dev, KEY_POWER, 0);
+       input_sync(button_dev);
+}
+
+static struct pmi_handler cbe_pmi_handler = {
+       .type                   = PMI_TYPE_POWER_BUTTON,
+       .handle_pmi_message     = cbe_powerbutton_handle_pmi,
+};
+
+static int __init cbe_powerbutton_init(void)
+{
+       int ret = 0;
+       struct input_dev *dev;
+
+       if (!machine_is_compatible("IBM,CBPLUS-1.0")) {
+               printk(KERN_ERR "%s: Not a cell blade.\n", __func__);
+               ret = -ENODEV;
+               goto out;
+       }
+
+       dev = input_allocate_device();
+       if (!dev) {
+               ret = -ENOMEM;
+               printk(KERN_ERR "%s: Not enough memory.\n", __func__);
+               goto out;
+       }
+
+       set_bit(EV_KEY, dev->evbit);
+       set_bit(KEY_POWER, dev->keybit);
+
+       dev->name = "Power Button";
+       dev->id.bustype = BUS_HOST;
+
+       /* this makes the button look like an acpi power button
+        * no clue whether anyone relies on that though */
+       dev->id.product = 0x02;
+       dev->phys = "LNXPWRBN/button/input0";
+
+       button_pdev = platform_device_register_simple("power_button", 0, NULL, 0);
+       if (IS_ERR(button_pdev)) {
+               ret = PTR_ERR(button_pdev);
+               goto out_free_input;
+       }
+
+       dev->dev.parent = &button_pdev->dev;
+       ret = input_register_device(dev);
+       if (ret) {
+               printk(KERN_ERR "%s: Failed to register device\n", __func__);
+               goto out_free_pdev;
+       }
+
+       button_dev = dev;
+
+       ret = pmi_register_handler(&cbe_pmi_handler);
+       if (ret) {
+               printk(KERN_ERR "%s: Failed to register with pmi.\n", __func__);
+               goto out_free_pdev;
+       }
+
+       goto out;
+
+out_free_pdev:
+       platform_device_unregister(button_pdev);
+out_free_input:
+       input_free_device(dev);
+out:
+       return ret;
+}
+
+static void __exit cbe_powerbutton_exit(void)
+{
+       pmi_unregister_handler(&cbe_pmi_handler);
+       platform_device_unregister(button_pdev);
+       input_free_device(button_dev);
+}
+
+module_init(cbe_powerbutton_init);
+module_exit(cbe_powerbutton_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
index 4852bf312d83c0d60a224eb9ab292dd832c96a64..4d4c8c169124eb8899315bf97c895c4e22a8919f 100644 (file)
@@ -97,7 +97,8 @@ static u8 spu_read_register_value(struct sys_device *sysdev, union spe_reg __iom
        return value.spe[spu->spe_id];
 }
 
-static ssize_t spu_show_temp(struct sys_device *sysdev, char *buf)
+static ssize_t spu_show_temp(struct sys_device *sysdev, struct sysdev_attribute *attr,
+                       char *buf)
 {
        u8 value;
        struct cbe_pmd_regs __iomem *pmd_regs;
@@ -146,32 +147,38 @@ static ssize_t store_throttle(struct cbe_pmd_regs __iomem *pmd_regs, const char
        return size;
 }
 
-static ssize_t spu_show_throttle_end(struct sys_device *sysdev, char *buf)
+static ssize_t spu_show_throttle_end(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return show_throttle(get_pmd_regs(sysdev), buf, 0);
 }
 
-static ssize_t spu_show_throttle_begin(struct sys_device *sysdev, char *buf)
+static ssize_t spu_show_throttle_begin(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return show_throttle(get_pmd_regs(sysdev), buf, 8);
 }
 
-static ssize_t spu_show_throttle_full_stop(struct sys_device *sysdev, char *buf)
+static ssize_t spu_show_throttle_full_stop(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return show_throttle(get_pmd_regs(sysdev), buf, 16);
 }
 
-static ssize_t spu_store_throttle_end(struct sys_device *sysdev, const char *buf, size_t size)
+static ssize_t spu_store_throttle_end(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, const char *buf, size_t size)
 {
        return store_throttle(get_pmd_regs(sysdev), buf, size, 0);
 }
 
-static ssize_t spu_store_throttle_begin(struct sys_device *sysdev, const char *buf, size_t size)
+static ssize_t spu_store_throttle_begin(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, const char *buf, size_t size)
 {
        return store_throttle(get_pmd_regs(sysdev), buf, size, 8);
 }
 
-static ssize_t spu_store_throttle_full_stop(struct sys_device *sysdev, const char *buf, size_t size)
+static ssize_t spu_store_throttle_full_stop(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, const char *buf, size_t size)
 {
        return store_throttle(get_pmd_regs(sysdev), buf, size, 16);
 }
@@ -192,43 +199,51 @@ static ssize_t ppe_show_temp(struct sys_device *sysdev, char *buf, int pos)
 
 /* shows the temperature of the DTS on the PPE,
  * located near the linear thermal sensor */
-static ssize_t ppe_show_temp0(struct sys_device *sysdev, char *buf)
+static ssize_t ppe_show_temp0(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return ppe_show_temp(sysdev, buf, 32);
 }
 
 /* shows the temperature of the second DTS on the PPE */
-static ssize_t ppe_show_temp1(struct sys_device *sysdev, char *buf)
+static ssize_t ppe_show_temp1(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return ppe_show_temp(sysdev, buf, 0);
 }
 
-static ssize_t ppe_show_throttle_end(struct sys_device *sysdev, char *buf)
+static ssize_t ppe_show_throttle_end(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 32);
 }
 
-static ssize_t ppe_show_throttle_begin(struct sys_device *sysdev, char *buf)
+static ssize_t ppe_show_throttle_begin(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 40);
 }
 
-static ssize_t ppe_show_throttle_full_stop(struct sys_device *sysdev, char *buf)
+static ssize_t ppe_show_throttle_full_stop(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 48);
 }
 
-static ssize_t ppe_store_throttle_end(struct sys_device *sysdev, const char *buf, size_t size)
+static ssize_t ppe_store_throttle_end(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, const char *buf, size_t size)
 {
        return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 32);
 }
 
-static ssize_t ppe_store_throttle_begin(struct sys_device *sysdev, const char *buf, size_t size)
+static ssize_t ppe_store_throttle_begin(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, const char *buf, size_t size)
 {
        return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 40);
 }
 
-static ssize_t ppe_store_throttle_full_stop(struct sys_device *sysdev, const char *buf, size_t size)
+static ssize_t ppe_store_throttle_full_stop(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, const char *buf, size_t size)
 {
        return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 48);
 }
diff --git a/arch/powerpc/platforms/cell/cpufreq_spudemand.c b/arch/powerpc/platforms/cell/cpufreq_spudemand.c
new file mode 100644 (file)
index 0000000..a3c6c01
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * spu aware cpufreq governor for the cell processor
+ *
+ * Â© Copyright IBM Corporation 2006-2008
+ *
+ * Author: Christian Krafft <krafft@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the 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/cpufreq.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <asm/atomic.h>
+#include <asm/machdep.h>
+#include <asm/spu.h>
+
+#define POLL_TIME      100000          /* in Âµs */
+#define EXP            753             /* exp(-1) in fixed-point */
+
+struct spu_gov_info_struct {
+       unsigned long busy_spus;        /* fixed-point */
+       struct cpufreq_policy *policy;
+       struct delayed_work work;
+       unsigned int poll_int;          /* Âµs */
+};
+static DEFINE_PER_CPU(struct spu_gov_info_struct, spu_gov_info);
+
+static struct workqueue_struct *kspugov_wq;
+
+static int calc_freq(struct spu_gov_info_struct *info)
+{
+       int cpu;
+       int busy_spus;
+
+       cpu = info->policy->cpu;
+       busy_spus = atomic_read(&cbe_spu_info[cpu_to_node(cpu)].busy_spus);
+
+       CALC_LOAD(info->busy_spus, EXP, busy_spus * FIXED_1);
+       pr_debug("cpu %d: busy_spus=%d, info->busy_spus=%ld\n",
+                       cpu, busy_spus, info->busy_spus);
+
+       return info->policy->max * info->busy_spus / FIXED_1;
+}
+
+static void spu_gov_work(struct work_struct *work)
+{
+       struct spu_gov_info_struct *info;
+       int delay;
+       unsigned long target_freq;
+
+       info = container_of(work, struct spu_gov_info_struct, work.work);
+
+       /* after cancel_delayed_work_sync we unset info->policy */
+       BUG_ON(info->policy == NULL);
+
+       target_freq = calc_freq(info);
+       __cpufreq_driver_target(info->policy, target_freq, CPUFREQ_RELATION_H);
+
+       delay = usecs_to_jiffies(info->poll_int);
+       queue_delayed_work_on(info->policy->cpu, kspugov_wq, &info->work, delay);
+}
+
+static void spu_gov_init_work(struct spu_gov_info_struct *info)
+{
+       int delay = usecs_to_jiffies(info->poll_int);
+       INIT_DELAYED_WORK_DEFERRABLE(&info->work, spu_gov_work);
+       queue_delayed_work_on(info->policy->cpu, kspugov_wq, &info->work, delay);
+}
+
+static void spu_gov_cancel_work(struct spu_gov_info_struct *info)
+{
+       cancel_delayed_work_sync(&info->work);
+}
+
+static int spu_gov_govern(struct cpufreq_policy *policy, unsigned int event)
+{
+       unsigned int cpu = policy->cpu;
+       struct spu_gov_info_struct *info, *affected_info;
+       int i;
+       int ret = 0;
+
+       info = &per_cpu(spu_gov_info, cpu);
+
+       switch (event) {
+       case CPUFREQ_GOV_START:
+               if (!cpu_online(cpu)) {
+                       printk(KERN_ERR "cpu %d is not online\n", cpu);
+                       ret = -EINVAL;
+                       break;
+               }
+
+               if (!policy->cur) {
+                       printk(KERN_ERR "no cpu specified in policy\n");
+                       ret = -EINVAL;
+                       break;
+               }
+
+               /* initialize spu_gov_info for all affected cpus */
+               for_each_cpu_mask(i, policy->cpus) {
+                       affected_info = &per_cpu(spu_gov_info, i);
+                       affected_info->policy = policy;
+               }
+
+               info->poll_int = POLL_TIME;
+
+               /* setup timer */
+               spu_gov_init_work(info);
+
+               break;
+
+       case CPUFREQ_GOV_STOP:
+               /* cancel timer */
+               spu_gov_cancel_work(info);
+
+               /* clean spu_gov_info for all affected cpus */
+               for_each_cpu_mask (i, policy->cpus) {
+                       info = &per_cpu(spu_gov_info, i);
+                       info->policy = NULL;
+               }
+
+               break;
+       }
+
+       return ret;
+}
+
+static struct cpufreq_governor spu_governor = {
+       .name = "spudemand",
+       .governor = spu_gov_govern,
+       .owner = THIS_MODULE,
+};
+
+/*
+ * module init and destoy
+ */
+
+static int __init spu_gov_init(void)
+{
+       int ret;
+
+       kspugov_wq = create_workqueue("kspugov");
+       if (!kspugov_wq) {
+               printk(KERN_ERR "creation of kspugov failed\n");
+               ret = -EFAULT;
+               goto out;
+       }
+
+       ret = cpufreq_register_governor(&spu_governor);
+       if (ret) {
+               printk(KERN_ERR "registration of governor failed\n");
+               destroy_workqueue(kspugov_wq);
+               goto out;
+       }
+out:
+       return ret;
+}
+
+static void __exit spu_gov_exit(void)
+{
+       cpufreq_unregister_governor(&spu_governor);
+       destroy_workqueue(kspugov_wq);
+}
+
+
+module_init(spu_gov_init);
+module_exit(spu_gov_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
+
index eeacb3a52ca13c55edac28556e5ba4e8bd61c332..208005ca262c62ac58b466c94e21ff3f47932924 100644 (file)
@@ -173,7 +173,8 @@ static void invalidate_tce_cache(struct cbe_iommu *iommu, unsigned long *pte,
 }
 
 static void tce_build_cell(struct iommu_table *tbl, long index, long npages,
-               unsigned long uaddr, enum dma_data_direction direction)
+               unsigned long uaddr, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
 {
        int i;
        unsigned long *io_pte, base_pte;
@@ -198,6 +199,8 @@ static void tce_build_cell(struct iommu_table *tbl, long index, long npages,
        base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW |
                (window->ioid & IOPTE_IOID_Mask);
 #endif
+       if (unlikely(dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs)))
+               base_pte &= ~IOPTE_SO_RW;
 
        io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
 
@@ -519,7 +522,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
 
        __set_bit(0, window->table.it_map);
        tce_build_cell(&window->table, window->table.it_offset, 1,
-                      (unsigned long)iommu->pad_page, DMA_TO_DEVICE);
+                      (unsigned long)iommu->pad_page, DMA_TO_DEVICE, NULL);
        window->table.it_hint = window->table.it_blocksize;
 
        return window;
@@ -538,7 +541,9 @@ static struct cbe_iommu *cell_iommu_for_node(int nid)
 static unsigned long cell_dma_direct_offset;
 
 static unsigned long dma_iommu_fixed_base;
-struct dma_mapping_ops dma_iommu_fixed_ops;
+
+/* iommu_fixed_is_weak is set if booted with iommu_fixed=weak */
+static int iommu_fixed_is_weak;
 
 static struct iommu_table *cell_get_iommu_table(struct device *dev)
 {
@@ -562,6 +567,98 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev)
        return &window->table;
 }
 
+/* A coherent allocation implies strong ordering */
+
+static void *dma_fixed_alloc_coherent(struct device *dev, size_t size,
+                                     dma_addr_t *dma_handle, gfp_t flag)
+{
+       if (iommu_fixed_is_weak)
+               return iommu_alloc_coherent(dev, cell_get_iommu_table(dev),
+                                           size, dma_handle,
+                                           device_to_mask(dev), flag,
+                                           dev->archdata.numa_node);
+       else
+               return dma_direct_ops.alloc_coherent(dev, size, dma_handle,
+                                                    flag);
+}
+
+static void dma_fixed_free_coherent(struct device *dev, size_t size,
+                                   void *vaddr, dma_addr_t dma_handle)
+{
+       if (iommu_fixed_is_weak)
+               iommu_free_coherent(cell_get_iommu_table(dev), size, vaddr,
+                                   dma_handle);
+       else
+               dma_direct_ops.free_coherent(dev, size, vaddr, dma_handle);
+}
+
+static dma_addr_t dma_fixed_map_single(struct device *dev, void *ptr,
+                                      size_t size,
+                                      enum dma_data_direction direction,
+                                      struct dma_attrs *attrs)
+{
+       if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs))
+               return dma_direct_ops.map_single(dev, ptr, size, direction,
+                                                attrs);
+       else
+               return iommu_map_single(dev, cell_get_iommu_table(dev), ptr,
+                                       size, device_to_mask(dev), direction,
+                                       attrs);
+}
+
+static void dma_fixed_unmap_single(struct device *dev, dma_addr_t dma_addr,
+                                  size_t size,
+                                  enum dma_data_direction direction,
+                                  struct dma_attrs *attrs)
+{
+       if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs))
+               dma_direct_ops.unmap_single(dev, dma_addr, size, direction,
+                                           attrs);
+       else
+               iommu_unmap_single(cell_get_iommu_table(dev), dma_addr, size,
+                                  direction, attrs);
+}
+
+static int dma_fixed_map_sg(struct device *dev, struct scatterlist *sg,
+                          int nents, enum dma_data_direction direction,
+                          struct dma_attrs *attrs)
+{
+       if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs))
+               return dma_direct_ops.map_sg(dev, sg, nents, direction, attrs);
+       else
+               return iommu_map_sg(dev, cell_get_iommu_table(dev), sg, nents,
+                                   device_to_mask(dev), direction, attrs);
+}
+
+static void dma_fixed_unmap_sg(struct device *dev, struct scatterlist *sg,
+                              int nents, enum dma_data_direction direction,
+                              struct dma_attrs *attrs)
+{
+       if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs))
+               dma_direct_ops.unmap_sg(dev, sg, nents, direction, attrs);
+       else
+               iommu_unmap_sg(cell_get_iommu_table(dev), sg, nents, direction,
+                              attrs);
+}
+
+static int dma_fixed_dma_supported(struct device *dev, u64 mask)
+{
+       return mask == DMA_64BIT_MASK;
+}
+
+static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask);
+
+struct dma_mapping_ops dma_iommu_fixed_ops = {
+       .alloc_coherent = dma_fixed_alloc_coherent,
+       .free_coherent  = dma_fixed_free_coherent,
+       .map_single     = dma_fixed_map_single,
+       .unmap_single   = dma_fixed_unmap_single,
+       .map_sg         = dma_fixed_map_sg,
+       .unmap_sg       = dma_fixed_unmap_sg,
+       .dma_supported  = dma_fixed_dma_supported,
+       .set_dma_mask   = dma_set_mask_and_switch,
+};
+
 static void cell_dma_dev_setup_fixed(struct device *dev);
 
 static void cell_dma_dev_setup(struct device *dev)
@@ -918,9 +1015,16 @@ static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
 
        pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase);
 
-       base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW
+       base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M
                    | (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask);
 
+       if (iommu_fixed_is_weak)
+               pr_info("IOMMU: Using weak ordering for fixed mapping\n");
+       else {
+               pr_info("IOMMU: Using strong ordering for fixed mapping\n");
+               base_pte |= IOPTE_SO_RW;
+       }
+
        for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) {
                /* Don't touch the dynamic region */
                ioaddr = uaddr + fbase;
@@ -1036,9 +1140,6 @@ static int __init cell_iommu_fixed_mapping_init(void)
                cell_iommu_setup_window(iommu, np, dbase, dsize, 0);
        }
 
-       dma_iommu_fixed_ops = dma_direct_ops;
-       dma_iommu_fixed_ops.set_dma_mask = dma_set_mask_and_switch;
-
        dma_iommu_ops.set_dma_mask = dma_set_mask_and_switch;
        set_pci_dma_ops(&dma_iommu_ops);
 
@@ -1052,6 +1153,9 @@ static int __init setup_iommu_fixed(char *str)
        if (strcmp(str, "off") == 0)
                iommu_fixed_disabled = 1;
 
+       else if (strcmp(str, "weak") == 0)
+               iommu_fixed_is_weak = 1;
+
        return 1;
 }
 __setup("iommu_fixed=", setup_iommu_fixed);
index 8a3631ce912ba52782640bd41b41e7f20e8c56f6..efdacc829576582a0b4da52384f80ad62082cd4e 100644 (file)
@@ -38,8 +38,6 @@
 
 #include "pervasive.h"
 
-static int sysreset_hack;
-
 static void cbe_power_save(void)
 {
        unsigned long ctrl, thread_switch_control;
@@ -87,9 +85,6 @@ static void cbe_power_save(void)
 
 static int cbe_system_reset_exception(struct pt_regs *regs)
 {
-       int cpu;
-       struct cbe_pmd_regs __iomem *pmd;
-
        switch (regs->msr & SRR1_WAKEMASK) {
        case SRR1_WAKEEE:
                do_IRQ(regs);
@@ -98,19 +93,7 @@ static int cbe_system_reset_exception(struct pt_regs *regs)
                timer_interrupt(regs);
                break;
        case SRR1_WAKEMT:
-               /*
-                * The BMC can inject user triggered system reset exceptions,
-                * but cannot set the system reset reason in srr1,
-                * so check an extra register here.
-                */
-               if (sysreset_hack && (cpu = smp_processor_id()) == 0) {
-                       pmd = cbe_get_cpu_pmd_regs(cpu);
-                       if (in_be64(&pmd->ras_esc_0) & 0xffff) {
-                               out_be64(&pmd->ras_esc_0, 0);
-                               return 0;
-                       }
-               }
-               break;
+               return cbe_sysreset_hack();
 #ifdef CONFIG_CBE_RAS
        case SRR1_WAKESYSERR:
                cbe_system_error_exception(regs);
@@ -134,8 +117,6 @@ void __init cbe_pervasive_init(void)
        if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO))
                return;
 
-       sysreset_hack = machine_is_compatible("IBM,CBPLUS-1.0");
-
        for_each_possible_cpu(cpu) {
                struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu);
                if (!regs)
@@ -144,12 +125,6 @@ void __init cbe_pervasive_init(void)
                 /* Enable Pause(0) control bit */
                out_be64(&regs->pmcr, in_be64(&regs->pmcr) |
                                            CBE_PMD_PAUSE_ZERO_CONTROL);
-
-               /* Enable JTAG system-reset hack */
-               if (sysreset_hack)
-                       out_be32(&regs->fir_mode_reg,
-                               in_be32(&regs->fir_mode_reg) |
-                               CBE_PMD_FIR_MODE_M8);
        }
 
        ppc_md.power_save = cbe_power_save;
index 7b50947f8044418969aba9f48f1999b184a1300f..fd4d7b7092b43ad1c1d64a2dc460cb0f8a92e2eb 100644 (file)
@@ -30,4 +30,13 @@ extern void cbe_system_error_exception(struct pt_regs *regs);
 extern void cbe_maintenance_exception(struct pt_regs *regs);
 extern void cbe_thermal_exception(struct pt_regs *regs);
 
+#ifdef CONFIG_PPC_IBM_CELL_RESETBUTTON
+extern int cbe_sysreset_hack(void);
+#else
+static inline int cbe_sysreset_hack(void)
+{
+       return 1;
+}
+#endif /* CONFIG_PPC_IBM_CELL_RESETBUTTON */
+
 #endif
index 505f9b9bdf0c8bb8932594c4419bff6a6bb29653..2a14b052abcd7617b251d1e69555e0233b773d3d 100644 (file)
@@ -236,6 +236,52 @@ static struct notifier_block cbe_ptcal_reboot_notifier = {
        .notifier_call = cbe_ptcal_notify_reboot
 };
 
+#ifdef CONFIG_PPC_IBM_CELL_RESETBUTTON
+static int sysreset_hack;
+
+static int __init cbe_sysreset_init(void)
+{
+       struct cbe_pmd_regs __iomem *regs;
+
+       sysreset_hack = machine_is_compatible("IBM,CBPLUS-1.0");
+       if (!sysreset_hack)
+               return 0;
+
+       regs = cbe_get_cpu_pmd_regs(0);
+       if (!regs)
+               return 0;
+
+       /* Enable JTAG system-reset hack */
+       out_be32(&regs->fir_mode_reg,
+               in_be32(&regs->fir_mode_reg) |
+               CBE_PMD_FIR_MODE_M8);
+
+       return 0;
+}
+device_initcall(cbe_sysreset_init);
+
+int cbe_sysreset_hack(void)
+{
+       struct cbe_pmd_regs __iomem *regs;
+
+       /*
+        * The BMC can inject user triggered system reset exceptions,
+        * but cannot set the system reset reason in srr1,
+        * so check an extra register here.
+        */
+       if (sysreset_hack && (smp_processor_id() == 0)) {
+               regs = cbe_get_cpu_pmd_regs(0);
+               if (!regs)
+                       return 0;
+               if (in_be64(&regs->ras_esc_0) & 0x0000ffff) {
+                       out_be64(&regs->ras_esc_0, 0);
+                       return 0;
+               }
+       }
+       return 1;
+}
+#endif /* CONFIG_PPC_IBM_CELL_RESETBUTTON */
+
 int __init cbe_ptcal_init(void)
 {
        int ret;
index 78f905bc6a42dd7774edca80287a58bd921c01dd..a5bdb89a17c3bf4b40894a0e7025877579398a06 100644 (file)
@@ -703,7 +703,8 @@ static unsigned long long spu_acct_time(struct spu *spu,
 }
 
 
-static ssize_t spu_stat_show(struct sys_device *sysdev, char *buf)
+static ssize_t spu_stat_show(struct sys_device *sysdev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct spu *spu = container_of(sysdev, struct spu, sysdev);
 
index 609c46db4a1bc36e493250ee9231697656bd4da8..768c262b936891eeaebb361a1c2612e8ef429588 100644 (file)
@@ -367,7 +367,7 @@ static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
        viaisa = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);
        if (!viaisa)
                return;
-       printk("Fixing VIA IDE, force legacy mode on '%s'\n", viaide->dev.bus_id);
+       dev_info(&viaide->dev, "Fixing VIA IDE, force legacy mode on\n");
 
        pci_read_config_byte(viaide, PCI_CLASS_PROG, &progif);
        pci_write_config_byte(viaide, PCI_CLASS_PROG, progif & ~0x5);
index afc9141be63eaf5f72d31ad82c155e45e2fc127e..ef74a0763ec124a063c67992b99ac9e8f6d6f316 100644 (file)
@@ -51,15 +51,13 @@ u8 uli_pirq_to_irq[8] = {
        ULI_8259_NONE,          /* PIRQH */
 };
 
-/* set in board code if you want this quirks to do something */
-int uses_fsl_uli_m1575;
-
 /* Bridge */
 static void __devinit early_uli5249(struct pci_dev *dev)
 {
        unsigned char temp;
 
-       if (!uses_fsl_uli_m1575)
+       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
+                       !machine_is(mpc8572_ds))
                return;
 
        pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO |
@@ -82,7 +80,8 @@ static void __devinit quirk_uli1575(struct pci_dev *dev)
 {
        int i;
 
-       if (!uses_fsl_uli_m1575)
+       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
+                       !machine_is(mpc8572_ds))
                return;
 
        /*
@@ -150,7 +149,8 @@ static void __devinit quirk_final_uli1575(struct pci_dev *dev)
         * IRQ 14: Edge
         * IRQ 15: Edge
         */
-       if (!uses_fsl_uli_m1575)
+       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
+                       !machine_is(mpc8572_ds))
                return;
 
        outb(0xfa, 0x4d0);
@@ -176,7 +176,8 @@ static void __devinit quirk_uli5288(struct pci_dev *dev)
        unsigned char c;
        unsigned int d;
 
-       if (!uses_fsl_uli_m1575)
+       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
+                       !machine_is(mpc8572_ds))
                return;
 
        /* read/write lock */
@@ -200,7 +201,8 @@ static void __devinit quirk_uli5229(struct pci_dev *dev)
 {
        unsigned short temp;
 
-       if (!uses_fsl_uli_m1575)
+       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
+                       !machine_is(mpc8572_ds))
                return;
 
        pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE |
@@ -221,7 +223,7 @@ static void __devinit quirk_final_uli5249(struct pci_dev *dev)
        for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
                if ((bus->resource[i]) &&
                        (bus->resource[i]->flags & IORESOURCE_MEM)) {
-                       dummy = ioremap(bus->resource[i]->start, 0x4);
+                       dummy = ioremap(bus->resource[i]->end - 3, 0x4);
                        if (dummy) {
                                in_8(dummy);
                                iounmap(dummy);
@@ -238,6 +240,103 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 0x5249, quirk_final_uli5249);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 0x1575, quirk_final_uli1575);
 
+static void __devinit hpcd_quirk_uli1575(struct pci_dev *dev)
+{
+       u32 temp32;
+
+       if (!machine_is(mpc86xx_hpcd))
+               return;
+
+       /* Disable INTx */
+       pci_read_config_dword(dev, 0x48, &temp32);
+       pci_write_config_dword(dev, 0x48, (temp32 | 1<<26));
+
+       /* Enable sideband interrupt */
+       pci_read_config_dword(dev, 0x90, &temp32);
+       pci_write_config_dword(dev, 0x90, (temp32 | 1<<22));
+}
+
+static void __devinit hpcd_quirk_uli5288(struct pci_dev *dev)
+{
+       unsigned char c;
+       unsigned short temp;
+
+       if (!machine_is(mpc86xx_hpcd))
+               return;
+
+       /* Interrupt Disable, Needed when SATA disabled */
+       pci_read_config_word(dev, PCI_COMMAND, &temp);
+       temp |= 1<<10;
+       pci_write_config_word(dev, PCI_COMMAND, temp);
+
+       pci_read_config_byte(dev, 0x83, &c);
+       c |= 0x80;
+       pci_write_config_byte(dev, 0x83, c);
+
+       pci_write_config_byte(dev, PCI_CLASS_PROG, 0x01);
+       pci_write_config_byte(dev, PCI_CLASS_DEVICE, 0x06);
+
+       pci_read_config_byte(dev, 0x83, &c);
+       c &= 0x7f;
+       pci_write_config_byte(dev, 0x83, c);
+}
+
+/*
+ * Since 8259PIC was disabled on the board, the IDE device can not
+ * use the legacy IRQ, we need to let the IDE device work under
+ * native mode and use the interrupt line like other PCI devices.
+ * IRQ14 is a sideband interrupt from IDE device to CPU and we use this
+ * as the interrupt for IDE device.
+ */
+static void __devinit hpcd_quirk_uli5229(struct pci_dev *dev)
+{
+       unsigned char c;
+
+       if (!machine_is(mpc86xx_hpcd))
+               return;
+
+       pci_read_config_byte(dev, 0x4b, &c);
+       c |= 0x10;
+       pci_write_config_byte(dev, 0x4b, c);
+}
+
+/*
+ * SATA interrupt pin bug fix
+ * There's a chip bug for 5288, The interrupt pin should be 2,
+ * not the read only value 1, So it use INTB#, not INTA# which
+ * actually used by the IDE device 5229.
+ * As of this bug, during the PCI initialization, 5288 read the
+ * irq of IDE device from the device tree, this function fix this
+ * bug by re-assigning a correct irq to 5288.
+ *
+ */
+static void __devinit hpcd_final_uli5288(struct pci_dev *dev)
+{
+       struct pci_controller *hose = pci_bus_to_host(dev->bus);
+       struct device_node *hosenode = hose ? hose->dn : NULL;
+       struct of_irq oirq;
+       int virq, pin = 2;
+       u32 laddr[3];
+
+       if (!machine_is(mpc86xx_hpcd))
+               return;
+
+       if (!hosenode)
+               return;
+
+       laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(31, 0) << 8);
+       laddr[1] = laddr[2] = 0;
+       of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq);
+       virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+                                    oirq.size);
+       dev->irq = virq;
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, hpcd_quirk_uli1575);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, hpcd_quirk_uli5288);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, hpcd_quirk_uli5229);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 0x5288, hpcd_final_uli5288);
+
 int uli_exclude_device(struct pci_controller *hose,
                        u_char bus, u_char devfn)
 {
index 761d9e971fc4bacb5413efc9dd4b02cb3da4bd8c..ea3e541ac74f306d1dee49cedc96dad2d8ebbdad 100644 (file)
@@ -2,6 +2,7 @@ config PPC_ISERIES
        bool "IBM Legacy iSeries"
        depends on PPC_MULTIPLATFORM && PPC64
        select PPC_INDIRECT_IO
+       select PPC_PCI_CHOICE if EMBEDDED
 
 menu "iSeries device drivers"
        depends on PPC_ISERIES
index ab5d8687c3cfbf250058972d1f373d4c5bc3b410..bc818e4e203321b50557361ae2f5c4f2717cd4dc 100644 (file)
@@ -42,7 +42,8 @@
 #include <asm/iseries/iommu.h>
 
 static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
-               unsigned long uaddr, enum dma_data_direction direction)
+               unsigned long uaddr, enum dma_data_direction direction,
+               struct dma_attrs *attrs)
 {
        u64 rc;
        u64 tce, rpn;
index 86967bdd8774db20ae04d13fb7f4b65c80482192..70541b7a5013ab68faed9758d86487be360bbe8c 100644 (file)
@@ -85,7 +85,8 @@ static int iommu_table_iobmap_inited;
 
 static void iobmap_build(struct iommu_table *tbl, long index,
                         long npages, unsigned long uaddr,
-                        enum dma_data_direction direction)
+                        enum dma_data_direction direction,
+                        struct dma_attrs *attrs)
 {
        u32 *ip;
        u32 rpn;
index 00bd0166d07fd78261a4230bbcb30555f313a356..31635446901a95bbbab17a69543912c95f79ab5e 100644 (file)
@@ -97,8 +97,6 @@ extern struct machdep_calls pmac_md;
 int sccdbg;
 #endif
 
-extern void zs_kgdb_hook(int tty_num);
-
 sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
 EXPORT_SYMBOL(sys_ctrler);
 
@@ -329,10 +327,6 @@ static void __init pmac_setup_arch(void)
        l2cr_init();
 #endif /* CONFIG_PPC32 */
 
-#ifdef CONFIG_KGDB
-       zs_kgdb_hook(0);
-#endif
-
        find_via_cuda();
        find_via_pmu();
        smu_init();
index a5f4e95dfc3d277732767f2c887ac56bd0e56187..920cf7a454b1d26df440baf93409dad33c9b2394 100644 (file)
@@ -8,6 +8,7 @@ config PPC_PS3
        select USB_ARCH_HAS_EHCI
        select USB_EHCI_BIG_ENDIAN_MMIO
        select MEMORY_HOTPLUG
+       select PPC_PCI_CHOICE
        help
          This option enables support for the Sony PS3 game console
          and other platforms using the PS3 hypervisor.  Enabling this
index 3866debfa3c41d0062851f0fcfdbb47ab7cc7c8e..ffdd8e963fbdf04032b79afcd640748c4f4b77a9 100644 (file)
@@ -486,6 +486,7 @@ static int __init ps3_register_graphics_devices(void)
                return -ENOMEM;
 
        p->dev.match_id = PS3_MATCH_ID_GRAPHICS;
+       p->dev.match_sub_id = PS3_MATCH_SUB_ID_FB;
        p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
 
        result = ps3_system_bus_device_register(&p->dev);
index d66c3628a1121919474dece2d123f15270ce5e84..280ee88cb0b001c21449c18694d498a9c58e6de0 100644 (file)
@@ -347,16 +347,23 @@ static int ps3_system_bus_match(struct device *_dev,
        struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);
        struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 
-       result = dev->match_id == drv->match_id;
+       if (!dev->match_sub_id)
+               result = dev->match_id == drv->match_id;
+       else
+               result = dev->match_sub_id == drv->match_sub_id &&
+                       dev->match_id == drv->match_id;
 
        if (result)
-               pr_info("%s:%d: dev=%u(%s), drv=%u(%s): match\n", __func__,
-                       __LINE__, dev->match_id, dev->core.bus_id,
-                       drv->match_id, drv->core.name);
+               pr_info("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): match\n",
+                       __func__, __LINE__,
+                       dev->match_id, dev->match_sub_id, dev->core.bus_id,
+                       drv->match_id, drv->match_sub_id, drv->core.name);
        else
-               pr_debug("%s:%d: dev=%u(%s), drv=%u(%s): miss\n", __func__,
-                       __LINE__, dev->match_id, dev->core.bus_id,
-                       drv->match_id, drv->core.name);
+               pr_debug("%s:%d: dev=%u.%u(%s), drv=%u.%u(%s): miss\n",
+                       __func__, __LINE__,
+                       dev->match_id, dev->match_sub_id, dev->core.bus_id,
+                       drv->match_id, drv->match_sub_id, drv->core.name);
+
        return result;
 }
 
index 07fe5b69b9e25f8c1c930c18a28a29920e525c89..757c0296e0b83e7456d28f5402f5db3c5918d4f4 100644 (file)
@@ -7,6 +7,7 @@ config PPC_PSERIES
        select RTAS_ERROR_LOGGING
        select PPC_UDBG_16550
        select PPC_NATIVE
+       select PPC_PCI_CHOICE if EMBEDDED
        default y
 
 config PPC_SPLPAR
index c027f0a70a04d111af01e5242431299fb0f4fbd6..54816d75b5787b8d0f134c4de71f78854fd5d27a 100644 (file)
@@ -75,9 +75,9 @@
  */
 
 /* If a device driver keeps reading an MMIO register in an interrupt
- * handler after a slot isolation event has occurred, we assume it
- * is broken and panic.  This sets the threshold for how many read
- * attempts we allow before panicking.
+ * handler after a slot isolation event, it might be broken.
+ * This sets the threshold for how many read attempts we allow
+ * before printing an error message.
  */
 #define EEH_MAX_FAILS  2100000
 
@@ -470,6 +470,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
        unsigned long flags;
        struct pci_dn *pdn;
        int rc = 0;
+       const char *location;
 
        total_mmio_ffs++;
 
@@ -509,18 +510,15 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
        rc = 1;
        if (pdn->eeh_mode & EEH_MODE_ISOLATED) {
                pdn->eeh_check_count ++;
-               if (pdn->eeh_check_count >= EEH_MAX_FAILS) {
-                       printk (KERN_ERR "EEH: Device driver ignored %d bad reads, panicing\n",
-                               pdn->eeh_check_count);
+               if (pdn->eeh_check_count % EEH_MAX_FAILS == 0) {
+                       location = of_get_property(dn, "ibm,loc-code", NULL);
+                       printk (KERN_ERR "EEH: %d reads ignored for recovering device at "
+                               "location=%s driver=%s pci addr=%s\n",
+                               pdn->eeh_check_count, location,
+                               dev->driver->name, pci_name(dev));
+                       printk (KERN_ERR "EEH: Might be infinite loop in %s driver\n",
+                               dev->driver->name);
                        dump_stack();
-                       msleep(5000);
-                       
-                       /* re-read the slot reset state */
-                       if (read_slot_reset_state(pdn, rets) != 0)
-                               rets[0] = -1;   /* reset state unknown */
-
-                       /* If we are here, then we hit an infinite loop. Stop. */
-                       panic("EEH: MMIO halt (%d) on device:%s\n", rets[0], pci_name(dev));
                }
                goto dn_unlock;
        }
index 9a12908510fbaaefbb92ab2e73489b9b49f86376..5377dd4b849a5bc8fced028eae7bd2b59c758207 100644 (file)
@@ -50,7 +50,8 @@
 
 static void tce_build_pSeries(struct iommu_table *tbl, long index,
                              long npages, unsigned long uaddr,
-                             enum dma_data_direction direction)
+                             enum dma_data_direction direction,
+                             struct dma_attrs *attrs)
 {
        u64 proto_tce;
        u64 *tcep;
@@ -95,7 +96,8 @@ static unsigned long tce_get_pseries(struct iommu_table *tbl, long index)
 
 static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
                                long npages, unsigned long uaddr,
-                               enum dma_data_direction direction)
+                               enum dma_data_direction direction,
+                               struct dma_attrs *attrs)
 {
        u64 rc;
        u64 proto_tce, tce;
@@ -127,7 +129,8 @@ static DEFINE_PER_CPU(u64 *, tce_page) = NULL;
 
 static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
                                     long npages, unsigned long uaddr,
-                                    enum dma_data_direction direction)
+                                    enum dma_data_direction direction,
+                                    struct dma_attrs *attrs)
 {
        u64 rc;
        u64 proto_tce;
@@ -136,7 +139,8 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
        long l, limit;
 
        if (npages == 1) {
-               tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, direction);
+               tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
+                                   direction, attrs);
                return;
        }
 
@@ -150,7 +154,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
                /* If allocation fails, fall back to the loop implementation */
                if (!tcep) {
                        tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
-                                           direction);
+                                           direction, attrs);
                        return;
                }
                __get_cpu_var(tce_page) = tcep;
index 7f59188cd9a111fdb89cd36a9ae0dfafb3d8cff6..9e105cbc5e5f4c3fb3f10654485d009cb37bb111 100644 (file)
@@ -57,6 +57,8 @@
 #define AXON_RAM_SECTOR_SIZE           1 << AXON_RAM_SECTOR_SHIFT
 #define AXON_RAM_IRQ_FLAGS             IRQF_SHARED | IRQF_TRIGGER_RISING
 
+static int azfs_major, azfs_minor;
+
 struct axon_ram_bank {
        struct of_device        *device;
        struct gendisk          *disk;
@@ -148,7 +150,10 @@ axon_ram_direct_access(struct block_device *device, sector_t sector,
        struct axon_ram_bank *bank = device->bd_disk->private_data;
        loff_t offset;
 
-       offset = sector << AXON_RAM_SECTOR_SHIFT;
+       offset = sector;
+       if (device->bd_part != NULL)
+               offset += device->bd_part->start_sect;
+       offset <<= AXON_RAM_SECTOR_SHIFT;
        if (offset >= bank->size) {
                dev_err(&bank->device->dev, "Access outside of address space\n");
                return -ERANGE;
@@ -227,19 +232,14 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id)
                goto failed;
        }
 
-       bank->disk->first_minor = 0;
+       bank->disk->major = azfs_major;
+       bank->disk->first_minor = azfs_minor;
        bank->disk->fops = &axon_ram_devops;
        bank->disk->private_data = bank;
        bank->disk->driverfs_dev = &device->dev;
 
        sprintf(bank->disk->disk_name, "%s%d",
                        AXON_RAM_DEVICE_NAME, axon_ram_bank_id);
-       bank->disk->major = register_blkdev(0, bank->disk->disk_name);
-       if (bank->disk->major < 0) {
-               dev_err(&device->dev, "Cannot register block device\n");
-               rc = -EFAULT;
-               goto failed;
-       }
 
        bank->disk->queue = blk_alloc_queue(GFP_KERNEL);
        if (bank->disk->queue == NULL) {
@@ -276,6 +276,8 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id)
                goto failed;
        }
 
+       azfs_minor += bank->disk->minors;
+
        return 0;
 
 failed:
@@ -310,7 +312,6 @@ axon_ram_remove(struct of_device *device)
 
        device_remove_file(&device->dev, &dev_attr_ecc);
        free_irq(bank->irq_id, device);
-       unregister_blkdev(bank->disk->major, bank->disk->disk_name);
        del_gendisk(bank->disk);
        iounmap((void __iomem *) bank->io_addr);
        kfree(bank);
@@ -341,6 +342,14 @@ static struct of_platform_driver axon_ram_driver = {
 static int __init
 axon_ram_init(void)
 {
+       azfs_major = register_blkdev(azfs_major, AXON_RAM_DEVICE_NAME);
+       if (azfs_major < 0) {
+               printk(KERN_ERR "%s cannot become block device major number\n",
+                               AXON_RAM_MODULE_NAME);
+               return -EFAULT;
+       }
+       azfs_minor = 0;
+
        return of_register_platform_driver(&axon_ram_driver);
 }
 
@@ -351,6 +360,7 @@ static void __exit
 axon_ram_exit(void)
 {
        of_unregister_platform_driver(&axon_ram_driver);
+       unregister_blkdev(azfs_major, AXON_RAM_DEVICE_NAME);
 }
 
 module_init(axon_ram_init);
index 005c2ecf976fe810f2f02ddee3f78200d8d3f010..de8c8b542cfa157d76281163e7ca21dfe1071b36 100644 (file)
@@ -149,7 +149,8 @@ static void dart_flush(struct iommu_table *tbl)
 
 static void dart_build(struct iommu_table *tbl, long index,
                       long npages, unsigned long uaddr,
-                      enum dma_data_direction direction)
+                      enum dma_data_direction direction,
+                      struct dma_attrs *attrs)
 {
        unsigned int *dp;
        unsigned int rpn;
index 87b0aa13ab483e8754da14865d8039b44456367d..61e6d77efa4fcec7d17fe31d6b5763786ba58319 100644 (file)
@@ -27,6 +27,7 @@
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 
+#if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)
 /* atmu setup for fsl pci/pcie controller */
 void __init setup_pci_atmu(struct pci_controller *hose, struct resource *rsrc)
 {
@@ -248,3 +249,63 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8536, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);
+#endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */
+
+#if defined(CONFIG_PPC_83xx)
+int __init mpc83xx_add_bridge(struct device_node *dev)
+{
+       int len;
+       struct pci_controller *hose;
+       struct resource rsrc;
+       const int *bus_range;
+       int primary = 1, has_address = 0;
+       phys_addr_t immr = get_immrbase();
+
+       pr_debug("Adding PCI host bridge %s\n", dev->full_name);
+
+       /* Fetch host bridge registers address */
+       has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
+
+       /* Get bus range if any */
+       bus_range = of_get_property(dev, "bus-range", &len);
+       if (bus_range == NULL || len < 2 * sizeof(int)) {
+               printk(KERN_WARNING "Can't get bus-range for %s, assume"
+                      " bus 0\n", dev->full_name);
+       }
+
+       ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
+       hose = pcibios_alloc_controller(dev);
+       if (!hose)
+               return -ENOMEM;
+
+       hose->first_busno = bus_range ? bus_range[0] : 0;
+       hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+       /* MPC83xx supports up to two host controllers one at 0x8500 from immrbar
+        * the other at 0x8600, we consider the 0x8500 the primary controller
+        */
+       /* PCI 1 */
+       if ((rsrc.start & 0xfffff) == 0x8500) {
+               setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304, 0);
+       }
+       /* PCI 2 */
+       if ((rsrc.start & 0xfffff) == 0x8600) {
+               setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384, 0);
+               primary = 0;
+       }
+
+       printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. "
+              "Firmware bus number: %d->%d\n",
+              (unsigned long long)rsrc.start, hose->first_busno,
+              hose->last_busno);
+
+       pr_debug(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
+           hose, hose->cfg_addr, hose->cfg_data);
+
+       /* Interpret the "ranges" property */
+       /* This also maps the I/O region and sets isa_io/mem_base */
+       pci_process_bridge_OF_ranges(hose, dev, primary);
+
+       return 0;
+}
+#endif /* CONFIG_PPC_83xx */
index 37b04ad26571cd4fc59920ba615a4ed869428646..13f30c2a61e76a906684cff73f60709e5b5ccff4 100644 (file)
@@ -83,6 +83,7 @@ struct ccsr_pci {
 
 extern int fsl_add_bridge(struct device_node *dev, int is_primary);
 extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);
+extern int mpc83xx_add_bridge(struct device_node *dev);
 
 #endif /* __POWERPC_FSL_PCI_H */
 #endif /* __KERNEL__ */
index ebcec7362f95c75552d77203069843f8efe6dd2d..214388e11807a039d05a9d6baf4fcf1a25b2f18a 100644 (file)
@@ -207,66 +207,58 @@ static int __init of_add_fixed_phys(void)
 arch_initcall(of_add_fixed_phys);
 #endif /* CONFIG_FIXED_PHY */
 
-static int __init gfar_mdio_of_init(void)
+static int gfar_mdio_of_init_one(struct device_node *np)
 {
-       struct device_node *np = NULL;
+       int k;
+       struct device_node *child = NULL;
+       struct gianfar_mdio_data mdio_data;
        struct platform_device *mdio_dev;
        struct resource res;
        int ret;
 
-       np = of_find_compatible_node(np, NULL, "fsl,gianfar-mdio");
+       memset(&res, 0, sizeof(res));
+       memset(&mdio_data, 0, sizeof(mdio_data));
 
-       /* try the deprecated version */
-       if (!np)
-               np = of_find_compatible_node(np, "mdio", "gianfar");
+       ret = of_address_to_resource(np, 0, &res);
+       if (ret)
+               return ret;
 
-       if (np) {
-               int k;
-               struct device_node *child = NULL;
-               struct gianfar_mdio_data mdio_data;
+       mdio_dev = platform_device_register_simple("fsl-gianfar_mdio",
+                       res.start&0xfffff, &res, 1);
+       if (IS_ERR(mdio_dev))
+               return PTR_ERR(mdio_dev);
 
-               memset(&res, 0, sizeof(res));
-               memset(&mdio_data, 0, sizeof(mdio_data));
+       for (k = 0; k < 32; k++)
+               mdio_data.irq[k] = PHY_POLL;
 
-               ret = of_address_to_resource(np, 0, &res);
-               if (ret)
-                       goto err;
-
-               mdio_dev =
-                   platform_device_register_simple("fsl-gianfar_mdio",
-                                                   res.start, &res, 1);
-               if (IS_ERR(mdio_dev)) {
-                       ret = PTR_ERR(mdio_dev);
-                       goto err;
+       while ((child = of_get_next_child(np, child)) != NULL) {
+               int irq = irq_of_parse_and_map(child, 0);
+               if (irq != NO_IRQ) {
+                       const u32 *id = of_get_property(child, "reg", NULL);
+                       mdio_data.irq[*id] = irq;
                }
+       }
 
-               for (k = 0; k < 32; k++)
-                       mdio_data.irq[k] = PHY_POLL;
+       ret = platform_device_add_data(mdio_dev, &mdio_data,
+                               sizeof(struct gianfar_mdio_data));
+       if (ret)
+               platform_device_unregister(mdio_dev);
 
-               while ((child = of_get_next_child(np, child)) != NULL) {
-                       int irq = irq_of_parse_and_map(child, 0);
-                       if (irq != NO_IRQ) {
-                               const u32 *id = of_get_property(child,
-                                                       "reg", NULL);
-                               mdio_data.irq[*id] = irq;
-                       }
-               }
+       return ret;
+}
 
-               ret =
-                   platform_device_add_data(mdio_dev, &mdio_data,
-                                            sizeof(struct gianfar_mdio_data));
-               if (ret)
-                       goto unreg;
-       }
+static int __init gfar_mdio_of_init(void)
+{
+       struct device_node *np = NULL;
 
-       of_node_put(np);
-       return 0;
+       for_each_compatible_node(np, NULL, "fsl,gianfar-mdio")
+               gfar_mdio_of_init_one(np);
 
-unreg:
-       platform_device_unregister(mdio_dev);
-err:
-       of_node_put(np);
-       return ret;
+       /* try the deprecated version */
+       for_each_compatible_node(np, "mdio", "gianfar");
+               gfar_mdio_of_init_one(np);
+
+       return 0;
 }
 
 arch_initcall(gfar_mdio_of_init);
@@ -296,6 +288,9 @@ static int __init gfar_of_init(void)
                const phandle *ph;
                int n_res = 2;
 
+               if (!of_device_is_available(np))
+                       continue;
+
                memset(r, 0, sizeof(r));
                memset(&gfar_data, 0, sizeof(gfar_data));
 
@@ -357,6 +352,9 @@ static int __init gfar_of_init(void)
                else
                        gfar_data.interface = PHY_INTERFACE_MODE_MII;
 
+               if (of_get_property(np, "fsl,magic-packet", NULL))
+                       gfar_data.device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET;
+
                ph = of_get_property(np, "phy-handle", NULL);
                if (ph == NULL) {
                        u32 *fixed_link;
@@ -390,7 +388,7 @@ static int __init gfar_of_init(void)
 
                        gfar_data.phy_id = *id;
                        snprintf(gfar_data.bus_id, MII_BUS_ID_SIZE, "%llx",
-                                (unsigned long long)res.start);
+                                (unsigned long long)res.start&0xfffff);
 
                        of_node_put(phy);
                        of_node_put(mdio);
index 52c831fa1886f544f5b389b31a3aaecf78262698..0242998873526c32ada0e52e3b3f45283f407395 100644 (file)
@@ -10,6 +10,7 @@ extern u32 get_baudrate(void);
 extern u32 fsl_get_sys_freq(void);
 
 struct spi_board_info;
+struct device_node;
 
 extern int fsl_spi_init(struct spi_board_info *board_infos,
                        unsigned int num_board_infos,
index caba1c0be5a761e975b12392b3839442a92f34dd..88a983ece5c9aa4e25749072f962c3317dba3a34 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/device.h>
 #include <linux/bootmem.h>
 #include <linux/spinlock.h>
+#include <linux/fsl_devices.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/prom.h>
@@ -889,8 +890,78 @@ unsigned int ipic_get_irq(void)
        return irq_linear_revmap(primary_ipic->irqhost, irq);
 }
 
+#ifdef CONFIG_PM
+static struct {
+       u32 sicfr;
+       u32 siprr[2];
+       u32 simsr[2];
+       u32 sicnr;
+       u32 smprr[2];
+       u32 semsr;
+       u32 secnr;
+       u32 sermr;
+       u32 sercr;
+} ipic_saved_state;
+
+static int ipic_suspend(struct sys_device *sdev, pm_message_t state)
+{
+       struct ipic *ipic = primary_ipic;
+
+       ipic_saved_state.sicfr = ipic_read(ipic->regs, IPIC_SICFR);
+       ipic_saved_state.siprr[0] = ipic_read(ipic->regs, IPIC_SIPRR_A);
+       ipic_saved_state.siprr[1] = ipic_read(ipic->regs, IPIC_SIPRR_D);
+       ipic_saved_state.simsr[0] = ipic_read(ipic->regs, IPIC_SIMSR_H);
+       ipic_saved_state.simsr[1] = ipic_read(ipic->regs, IPIC_SIMSR_L);
+       ipic_saved_state.sicnr = ipic_read(ipic->regs, IPIC_SICNR);
+       ipic_saved_state.smprr[0] = ipic_read(ipic->regs, IPIC_SMPRR_A);
+       ipic_saved_state.smprr[1] = ipic_read(ipic->regs, IPIC_SMPRR_B);
+       ipic_saved_state.semsr = ipic_read(ipic->regs, IPIC_SEMSR);
+       ipic_saved_state.secnr = ipic_read(ipic->regs, IPIC_SECNR);
+       ipic_saved_state.sermr = ipic_read(ipic->regs, IPIC_SERMR);
+       ipic_saved_state.sercr = ipic_read(ipic->regs, IPIC_SERCR);
+
+       if (fsl_deep_sleep()) {
+               /* In deep sleep, make sure there can be no
+                * pending interrupts, as this can cause
+                * problems on 831x.
+                */
+               ipic_write(ipic->regs, IPIC_SIMSR_H, 0);
+               ipic_write(ipic->regs, IPIC_SIMSR_L, 0);
+               ipic_write(ipic->regs, IPIC_SEMSR, 0);
+               ipic_write(ipic->regs, IPIC_SERMR, 0);
+       }
+
+       return 0;
+}
+
+static int ipic_resume(struct sys_device *sdev)
+{
+       struct ipic *ipic = primary_ipic;
+
+       ipic_write(ipic->regs, IPIC_SICFR, ipic_saved_state.sicfr);
+       ipic_write(ipic->regs, IPIC_SIPRR_A, ipic_saved_state.siprr[0]);
+       ipic_write(ipic->regs, IPIC_SIPRR_D, ipic_saved_state.siprr[1]);
+       ipic_write(ipic->regs, IPIC_SIMSR_H, ipic_saved_state.simsr[0]);
+       ipic_write(ipic->regs, IPIC_SIMSR_L, ipic_saved_state.simsr[1]);
+       ipic_write(ipic->regs, IPIC_SICNR, ipic_saved_state.sicnr);
+       ipic_write(ipic->regs, IPIC_SMPRR_A, ipic_saved_state.smprr[0]);
+       ipic_write(ipic->regs, IPIC_SMPRR_B, ipic_saved_state.smprr[1]);
+       ipic_write(ipic->regs, IPIC_SEMSR, ipic_saved_state.semsr);
+       ipic_write(ipic->regs, IPIC_SECNR, ipic_saved_state.secnr);
+       ipic_write(ipic->regs, IPIC_SERMR, ipic_saved_state.sermr);
+       ipic_write(ipic->regs, IPIC_SERCR, ipic_saved_state.sercr);
+
+       return 0;
+}
+#else
+#define ipic_suspend NULL
+#define ipic_resume NULL
+#endif
+
 static struct sysdev_class ipic_sysclass = {
        .name = "ipic",
+       .suspend = ipic_suspend,
+       .resume = ipic_resume,
 };
 
 static struct sys_device device_ipic = {
index 9e82d7e725a5e7ad46016db87dd398c610dac0d5..b3b73ae57d6d6ba96974732f04d81c11956d8fe5 100644 (file)
@@ -64,7 +64,7 @@ static phys_addr_t qebase = -1;
 phys_addr_t get_qe_base(void)
 {
        struct device_node *qe;
-       unsigned int size;
+       int size;
        const u32 *prop;
 
        if (qebase != -1)
@@ -158,7 +158,7 @@ static unsigned int brg_clk = 0;
 unsigned int qe_get_brg_clk(void)
 {
        struct device_node *qe;
-       unsigned int size;
+       int size;
        const u32 *prop;
 
        if (brg_clk)
@@ -305,7 +305,7 @@ EXPORT_SYMBOL(qe_put_snum);
 
 static int qe_sdma_init(void)
 {
-       struct sdma *sdma = &qe_immr->sdma;
+       struct sdma __iomem *sdma = &qe_immr->sdma;
        unsigned long sdma_buf_offset;
 
        if (!sdma)
index d3c7f5af9bc8e6113d7789999ba0c7dde433fda0..1d78071aad7d9c80ebaa6a88c78d7cd6752709eb 100644 (file)
@@ -88,7 +88,7 @@ int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed)
        return 0;
 }
 
-static void get_cmxucr_reg(unsigned int ucc_num, __be32 **cmxucr,
+static void get_cmxucr_reg(unsigned int ucc_num, __be32 __iomem **cmxucr,
        unsigned int *reg_num, unsigned int *shift)
 {
        unsigned int cmx = ((ucc_num & 1) << 1) + (ucc_num > 3);
@@ -100,7 +100,7 @@ static void get_cmxucr_reg(unsigned int ucc_num, __be32 **cmxucr,
 
 int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask)
 {
-       __be32 *cmxucr;
+       __be32 __iomem *cmxucr;
        unsigned int reg_num;
        unsigned int shift;
 
@@ -121,7 +121,7 @@ int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask)
 int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock,
        enum comm_dir mode)
 {
-       __be32 *cmxucr;
+       __be32 __iomem *cmxucr;
        unsigned int reg_num;
        unsigned int shift;
        u32 clock_bits = 0;
index bcf88e6ce962c872819d86cde1cfd22fb76f0953..1aecb075a72e693f70f2d91a97b91117e281ba3d 100644 (file)
@@ -46,7 +46,7 @@ void ucc_fast_dump_regs(struct ucc_fast_private * uccf)
        printk(KERN_INFO "uccm  : addr=0x%p, val=0x%08x\n",
                  &uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm));
        printk(KERN_INFO "uccs  : addr=0x%p, val=0x%02x\n",
-                 &uccf->uf_regs->uccs, uccf->uf_regs->uccs);
+                 &uccf->uf_regs->uccs, in_8(&uccf->uf_regs->uccs));
        printk(KERN_INFO "urfb  : addr=0x%p, val=0x%08x\n",
                  &uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb));
        printk(KERN_INFO "urfs  : addr=0x%p, val=0x%04x\n",
@@ -68,7 +68,7 @@ void ucc_fast_dump_regs(struct ucc_fast_private * uccf)
        printk(KERN_INFO "urtry : addr=0x%p, val=0x%08x\n",
                  &uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry));
        printk(KERN_INFO "guemr : addr=0x%p, val=0x%02x\n",
-                 &uccf->uf_regs->guemr, uccf->uf_regs->guemr);
+                 &uccf->uf_regs->guemr, in_8(&uccf->uf_regs->guemr));
 }
 EXPORT_SYMBOL(ucc_fast_dump_regs);
 
@@ -96,7 +96,7 @@ EXPORT_SYMBOL(ucc_fast_transmit_on_demand);
 
 void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode)
 {
-       struct ucc_fast *uf_regs;
+       struct ucc_fast __iomem *uf_regs;
        u32 gumr;
 
        uf_regs = uccf->uf_regs;
@@ -117,7 +117,7 @@ EXPORT_SYMBOL(ucc_fast_enable);
 
 void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode)
 {
-       struct ucc_fast *uf_regs;
+       struct ucc_fast __iomem *uf_regs;
        u32 gumr;
 
        uf_regs = uccf->uf_regs;
@@ -139,7 +139,7 @@ EXPORT_SYMBOL(ucc_fast_disable);
 int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret)
 {
        struct ucc_fast_private *uccf;
-       struct ucc_fast *uf_regs;
+       struct ucc_fast __iomem *uf_regs;
        u32 gumr;
        int ret;
 
@@ -216,10 +216,10 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
        uccf->stopped_tx = 0;
        uccf->stopped_rx = 0;
        uf_regs = uccf->uf_regs;
-       uccf->p_ucce = (u32 *) & (uf_regs->ucce);
-       uccf->p_uccm = (u32 *) & (uf_regs->uccm);
+       uccf->p_ucce = &uf_regs->ucce;
+       uccf->p_uccm = &uf_regs->uccm;
 #ifdef CONFIG_UGETH_TX_ON_DEMAND
-       uccf->p_utodr = (u16 *) & (uf_regs->utodr);
+       uccf->p_utodr = &uf_regs->utodr;
 #endif
 #ifdef STATISTICS
        uccf->tx_frames = 0;
index b6781030cfbd5f7ef84bf567d26a9e23abf5e134..b795b3e24afde40a4a0f24b36e26d1759adfb905 100644 (file)
@@ -864,7 +864,8 @@ int setup_profiling_timer(unsigned int multiplier)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-static ssize_t cpu_configure_show(struct sys_device *dev, char *buf)
+static ssize_t cpu_configure_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        ssize_t count;
 
@@ -874,8 +875,9 @@ static ssize_t cpu_configure_show(struct sys_device *dev, char *buf)
        return count;
 }
 
-static ssize_t cpu_configure_store(struct sys_device *dev, const char *buf,
-                                  size_t count)
+static ssize_t cpu_configure_store(struct sys_device *dev,
+                                 struct sysdev_attribute *attr,
+                                 const char *buf, size_t count)
 {
        int cpu = dev->id;
        int val, rc;
@@ -922,7 +924,8 @@ out:
 static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
 #endif /* CONFIG_HOTPLUG_CPU */
 
-static ssize_t cpu_polarization_show(struct sys_device *dev, char *buf)
+static ssize_t cpu_polarization_show(struct sys_device *dev,
+                                    struct sysdev_attribute *attr, char *buf)
 {
        int cpu = dev->id;
        ssize_t count;
@@ -950,7 +953,8 @@ static ssize_t cpu_polarization_show(struct sys_device *dev, char *buf)
 }
 static SYSDEV_ATTR(polarization, 0444, cpu_polarization_show, NULL);
 
-static ssize_t show_cpu_address(struct sys_device *dev, char *buf)
+static ssize_t show_cpu_address(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        return sprintf(buf, "%d\n", __cpu_logical_map[dev->id]);
 }
@@ -970,7 +974,8 @@ static struct attribute_group cpu_common_attr_group = {
        .attrs = cpu_common_attrs,
 };
 
-static ssize_t show_capability(struct sys_device *dev, char *buf)
+static ssize_t show_capability(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        unsigned int capability;
        int rc;
@@ -982,7 +987,8 @@ static ssize_t show_capability(struct sys_device *dev, char *buf)
 }
 static SYSDEV_ATTR(capability, 0444, show_capability, NULL);
 
-static ssize_t show_idle_count(struct sys_device *dev, char *buf)
+static ssize_t show_idle_count(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct s390_idle_data *idle;
        unsigned long long idle_count;
@@ -995,7 +1001,8 @@ static ssize_t show_idle_count(struct sys_device *dev, char *buf)
 }
 static SYSDEV_ATTR(idle_count, 0444, show_idle_count, NULL);
 
-static ssize_t show_idle_time(struct sys_device *dev, char *buf)
+static ssize_t show_idle_time(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct s390_idle_data *idle;
        unsigned long long new_time;
@@ -1112,7 +1119,9 @@ out:
        return rc;
 }
 
-static ssize_t __ref rescan_store(struct sys_device *dev, const char *buf,
+static ssize_t __ref rescan_store(struct sys_device *dev,
+                                 struct sysdev_attribute *attr,
+                                 const char *buf,
                                  size_t count)
 {
        int rc;
@@ -1123,7 +1132,9 @@ static ssize_t __ref rescan_store(struct sys_device *dev, const char *buf,
 static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store);
 #endif /* CONFIG_HOTPLUG_CPU */
 
-static ssize_t dispatching_show(struct sys_device *dev, char *buf)
+static ssize_t dispatching_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr,
+                               char *buf)
 {
        ssize_t count;
 
@@ -1133,8 +1144,9 @@ static ssize_t dispatching_show(struct sys_device *dev, char *buf)
        return count;
 }
 
-static ssize_t dispatching_store(struct sys_device *dev, const char *buf,
-                                size_t count)
+static ssize_t dispatching_store(struct sys_device *dev,
+                                struct sysdev_attribute *attr,
+                                const char *buf, size_t count)
 {
        int val, rc;
        char delim;
index f2cede3947b231b25d493a8c643be76721780145..ab70d9bd92616decb488820101543ebf4218f82b 100644 (file)
@@ -1100,7 +1100,9 @@ static inline struct etr_aib *etr_aib_from_dev(struct sys_device *dev)
                return etr_port1_online ? &etr_port1 : NULL;
 }
 
-static ssize_t etr_online_show(struct sys_device *dev, char *buf)
+static ssize_t etr_online_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr,
+                               char *buf)
 {
        unsigned int online;
 
@@ -1109,7 +1111,8 @@ static ssize_t etr_online_show(struct sys_device *dev, char *buf)
 }
 
 static ssize_t etr_online_store(struct sys_device *dev,
-                             const char *buf, size_t count)
+                               struct sysdev_attribute *attr,
+                               const char *buf, size_t count)
 {
        unsigned int value;
 
@@ -1136,7 +1139,9 @@ static ssize_t etr_online_store(struct sys_device *dev,
 
 static SYSDEV_ATTR(online, 0600, etr_online_show, etr_online_store);
 
-static ssize_t etr_stepping_control_show(struct sys_device *dev, char *buf)
+static ssize_t etr_stepping_control_show(struct sys_device *dev,
+                                       struct sysdev_attribute *attr,
+                                       char *buf)
 {
        return sprintf(buf, "%i\n", (dev == &etr_port0_dev) ?
                       etr_eacr.e0 : etr_eacr.e1);
@@ -1144,7 +1149,8 @@ static ssize_t etr_stepping_control_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(stepping_control, 0400, etr_stepping_control_show, NULL);
 
-static ssize_t etr_mode_code_show(struct sys_device *dev, char *buf)
+static ssize_t etr_mode_code_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        if (!etr_port0_online && !etr_port1_online)
                /* Status word is not uptodate if both ports are offline. */
@@ -1155,7 +1161,8 @@ static ssize_t etr_mode_code_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(state_code, 0400, etr_mode_code_show, NULL);
 
-static ssize_t etr_untuned_show(struct sys_device *dev, char *buf)
+static ssize_t etr_untuned_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1166,7 +1173,8 @@ static ssize_t etr_untuned_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(untuned, 0400, etr_untuned_show, NULL);
 
-static ssize_t etr_network_id_show(struct sys_device *dev, char *buf)
+static ssize_t etr_network_id_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1177,7 +1185,8 @@ static ssize_t etr_network_id_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(network, 0400, etr_network_id_show, NULL);
 
-static ssize_t etr_id_show(struct sys_device *dev, char *buf)
+static ssize_t etr_id_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1188,7 +1197,8 @@ static ssize_t etr_id_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(id, 0400, etr_id_show, NULL);
 
-static ssize_t etr_port_number_show(struct sys_device *dev, char *buf)
+static ssize_t etr_port_number_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1199,7 +1209,8 @@ static ssize_t etr_port_number_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(port, 0400, etr_port_number_show, NULL);
 
-static ssize_t etr_coupled_show(struct sys_device *dev, char *buf)
+static ssize_t etr_coupled_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1210,7 +1221,8 @@ static ssize_t etr_coupled_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(coupled, 0400, etr_coupled_show, NULL);
 
-static ssize_t etr_local_time_show(struct sys_device *dev, char *buf)
+static ssize_t etr_local_time_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1221,7 +1233,8 @@ static ssize_t etr_local_time_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(local_time, 0400, etr_local_time_show, NULL);
 
-static ssize_t etr_utc_offset_show(struct sys_device *dev, char *buf)
+static ssize_t etr_utc_offset_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
index 01af44245b57761c5f4f5004d3b438a93e7fcc07..963c99322095176767963c31cb6feee68573c3db 100644 (file)
@@ -30,7 +30,6 @@
 
 static struct smc91x_platdata smc91x_info = {
        .flags = SMC91X_USE_16BIT,
-       .irq_flags = IRQF_TRIGGER_HIGH,
 };
 
 static struct resource smc91x_eth_resources[] = {
@@ -42,7 +41,7 @@ static struct resource smc91x_eth_resources[] = {
        },
        [1] = {
                .start  = 32, /* IRQ0 */
-               .flags  = IORESOURCE_IRQ,
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
        },
 };
 
index 51b57c0d1a3c01f98d99e4bb5071cdb1478b89d3..347ee11351ec6c4375c06a8bf3f970733f022181 100644 (file)
@@ -23,7 +23,8 @@ static struct sysdev_class dma_sysclass = {
 };
 EXPORT_SYMBOL(dma_sysclass);
 
-static ssize_t dma_show_devices(struct sys_device *dev, char *buf)
+static ssize_t dma_show_devices(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        ssize_t len = 0;
        int i;
@@ -57,13 +58,15 @@ static int __init dma_sysclass_init(void)
 }
 postcore_initcall(dma_sysclass_init);
 
-static ssize_t dma_show_dev_id(struct sys_device *dev, char *buf)
+static ssize_t dma_show_dev_id(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct dma_channel *channel = to_dma_channel(dev);
        return sprintf(buf, "%s\n", channel->dev_id);
 }
 
 static ssize_t dma_store_dev_id(struct sys_device *dev,
+                               struct sysdev_attribute *attr,
                                const char *buf, size_t count)
 {
        struct dma_channel *channel = to_dma_channel(dev);
@@ -74,6 +77,7 @@ static ssize_t dma_store_dev_id(struct sys_device *dev,
 static SYSDEV_ATTR(dev_id, S_IRUGO | S_IWUSR, dma_show_dev_id, dma_store_dev_id);
 
 static ssize_t dma_store_config(struct sys_device *dev,
+                               struct sysdev_attribute *attr,
                                const char *buf, size_t count)
 {
        struct dma_channel *channel = to_dma_channel(dev);
@@ -87,13 +91,15 @@ static ssize_t dma_store_config(struct sys_device *dev,
 
 static SYSDEV_ATTR(config, S_IWUSR, NULL, dma_store_config);
 
-static ssize_t dma_show_mode(struct sys_device *dev, char *buf)
+static ssize_t dma_show_mode(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct dma_channel *channel = to_dma_channel(dev);
        return sprintf(buf, "0x%08x\n", channel->mode);
 }
 
 static ssize_t dma_store_mode(struct sys_device *dev,
+                             struct sysdev_attribute *attr,
                              const char *buf, size_t count)
 {
        struct dma_channel *channel = to_dma_channel(dev);
@@ -104,7 +110,8 @@ static ssize_t dma_store_mode(struct sys_device *dev,
 static SYSDEV_ATTR(mode, S_IRUGO | S_IWUSR, dma_show_mode, dma_store_mode);
 
 #define dma_ro_attr(field, fmt)                                                \
-static ssize_t dma_show_##field(struct sys_device *dev, char *buf)     \
+static ssize_t dma_show_##field(struct sys_device *dev,                \
+                               struct sysdev_attribute *attr, char *buf)\
 {                                                                      \
        struct dma_channel *channel = to_dma_channel(dev);              \
        return sprintf(buf, fmt, channel->field);                       \
index fef28e267a52fc1e2943d85c7bf3daea8603170e..6668e6037af647adbc9c31b4282027d5ed26fd65 100644 (file)
@@ -18,6 +18,7 @@ CHECKFLAGS    += -D__sparc__
 #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7
 KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
 KBUILD_AFLAGS += -m32
+CPPFLAGS_vmlinux.lds += -m32
 
 #LDFLAGS_vmlinux = -N -Ttext 0xf0004000
 #  Since 2.5.40, the first stage is left not btfix-ed.
index 6707422c98479547dc8901cac04acf698d6ca503..5267d48fb2c6a36e5a777f4b51041c58944d95bc 100644 (file)
@@ -56,7 +56,7 @@ __setup("apc=", apc_setup);
  * CPU idle callback function
  * See .../arch/sparc/kernel/process.c
  */
-void apc_swift_idle(void)
+static void apc_swift_idle(void)
 {
 #ifdef APC_DEBUG_LED
        set_auxio(0x00, AUXIO_LED); 
@@ -85,54 +85,70 @@ static int apc_release(struct inode *inode, struct file *f)
        return 0;
 }
 
-static int apc_ioctl(struct inode *inode, struct file *f, 
-                    unsigned int cmd, unsigned long __arg)
+static long apc_ioctl(struct file *f, unsigned int cmd, unsigned long __arg)
 {
        __u8 inarg, __user *arg;
 
        arg = (__u8 __user *) __arg;
+
+       lock_kernel();
+
        switch (cmd) {
        case APCIOCGFANCTL:
-               if (put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, arg))
-                               return -EFAULT;
+               if (put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, arg)) {
+                       unlock_kernel();
+                       return -EFAULT;
+               }
                break;
 
        case APCIOCGCPWR:
-               if (put_user(apc_readb(APC_CPOWER_REG) & APC_REGMASK, arg))
+               if (put_user(apc_readb(APC_CPOWER_REG) & APC_REGMASK, arg)) {
+                       unlock_kernel();
                        return -EFAULT;
+               }
                break;
 
        case APCIOCGBPORT:
-               if (put_user(apc_readb(APC_BPORT_REG) & APC_BPMASK, arg))
+               if (put_user(apc_readb(APC_BPORT_REG) & APC_BPMASK, arg)) {
+                       unlock_kernel();
                        return -EFAULT;
+               }
                break;
 
        case APCIOCSFANCTL:
-               if (get_user(inarg, arg))
+               if (get_user(inarg, arg)) {
+                       unlock_kernel();
                        return -EFAULT;
+               }
                apc_writeb(inarg & APC_REGMASK, APC_FANCTL_REG);
                break;
        case APCIOCSCPWR:
-               if (get_user(inarg, arg))
+               if (get_user(inarg, arg)) {
+                       unlock_kernel();
                        return -EFAULT;
+               }
                apc_writeb(inarg & APC_REGMASK, APC_CPOWER_REG);
                break;
        case APCIOCSBPORT:
-               if (get_user(inarg, arg))
+               if (get_user(inarg, arg)) {
+                       unlock_kernel();
                        return -EFAULT;
+               }
                apc_writeb(inarg & APC_BPMASK, APC_BPORT_REG);
                break;
        default:
+               unlock_kernel();
                return -EINVAL;
        };
 
+       unlock_kernel();
        return 0;
 }
 
 static const struct file_operations apc_fops = {
-       .ioctl =        apc_ioctl,
-       .open =         apc_open,
-       .release =      apc_release,
+       .unlocked_ioctl =       apc_ioctl,
+       .open =                 apc_open,
+       .release =              apc_release,
 };
 
 static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops };
index cd3f7694e9b9240e20455a5cb3933c1a343b0f3b..b5bb99ed892cc459b5f38f919750c8e33e87bc13 100644 (file)
@@ -18,18 +18,6 @@ int foo(void)
 {
        DEFINE(AOFF_task_thread, offsetof(struct task_struct, thread));
        BLANK();
-       /* XXX This is the stuff for sclow.S, kill it. */
-       DEFINE(AOFF_task_pid, offsetof(struct task_struct, pid));
-       DEFINE(AOFF_task_uid, offsetof(struct task_struct, uid));
-       DEFINE(AOFF_task_gid, offsetof(struct task_struct, gid));
-       DEFINE(AOFF_task_euid, offsetof(struct task_struct, euid));
-       DEFINE(AOFF_task_egid, offsetof(struct task_struct, egid));
-       /* DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); */
-       DEFINE(ASIZ_task_uid,   sizeof(current->uid));
-       DEFINE(ASIZ_task_gid,   sizeof(current->gid));
-       DEFINE(ASIZ_task_euid,  sizeof(current->euid));
-       DEFINE(ASIZ_task_egid,  sizeof(current->egid));
-       BLANK();
        DEFINE(AOFF_thread_fork_kpsr,
                        offsetof(struct thread_struct, fork_kpsr));
        BLANK();
index 92c6fc07e59c100ab96edb6f297f05facff12265..97294232259c764a7461a6d19cfdcbd45b7f9ab3 100644 (file)
@@ -69,7 +69,7 @@ static inline unsigned long ebus_alloc(size_t size)
 
 /*
  */
-int __init ebus_blacklist_irq(const char *name)
+static int __init ebus_blacklist_irq(const char *name)
 {
        struct ebus_device_irq *dp;
 
@@ -83,8 +83,8 @@ int __init ebus_blacklist_irq(const char *name)
        return 0;
 }
 
-void __init fill_ebus_child(struct device_node *dp,
-                           struct linux_ebus_child *dev)
+static void __init fill_ebus_child(struct device_node *dp,
+                                  struct linux_ebus_child *dev)
 {
        const int *regs;
        const int *irqs;
@@ -144,7 +144,8 @@ void __init fill_ebus_child(struct device_node *dp,
        }
 }
 
-void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
+static void __init fill_ebus_device(struct device_node *dp,
+                                   struct linux_ebus_device *dev)
 {
        const struct linux_prom_registers *regs;
        struct linux_ebus_child *child;
index 4bcfe54f878d3250c98ed613cdc899770aaaa850..2f96256dc5153bf04e06b176bff63da240495c3f 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/vaddrs.h>
 #include <asm/memreg.h>
 #include <asm/page.h>
+#include <asm/pgtable.h>
 #ifdef CONFIG_SUN4
 #include <asm/pgtsun4.h>
 #else
@@ -1317,7 +1318,6 @@ linux_sparc_syscall:
        bne     linux_fast_syscall
         /* Just do first insn from SAVE_ALL in the delay slot */
 
-       .globl  syscall_is_too_hard
 syscall_is_too_hard:
        SAVE_ALL_HEAD
         rd     %wim, %l3
@@ -1544,8 +1544,7 @@ kgdb_trap_low:
 #endif
 
        .align  4
-       .globl  __handle_exception, flush_patch_exception
-__handle_exception:
+       .globl  flush_patch_exception
 flush_patch_exception:
        FLUSH_ALL_KERNEL_WINDOWS;
        ldd     [%o0], %o6
index f37d961d67a63160244611828f7232d7448b6273..e806fcdc46db7ba87ebae3c59af2ecf6b83fd6d8 100644 (file)
@@ -228,7 +228,6 @@ tsetup_mmu_patchme:
         */
 #define glob_tmp     g1
 
-       .globl  tsetup_sun4c_stackchk
 tsetup_sun4c_stackchk:
        /* Done by caller: andcc %sp, 0x7, %g0 */
        bne     trap_setup_user_stack_is_bolixed
index 3bfd6085a91d7c2b2b1771ac773b445bd75d08b8..50d9a16af795c5d675fefd40a3e17cab5f486840 100644 (file)
@@ -32,7 +32,6 @@
  */
 
        .align 4
-        .globl  cputyp
 cputyp:
         .word   1
 
@@ -1280,7 +1279,6 @@ halt_me:
  * gets initialized in c-code so all routines can use it.
  */
 
-       .globl  prom_vector_p
 prom_vector_p:
                .word 0
 
index 7220562cdb3485573fa0962db1d46599c0a2b5e6..fc511f3c4c18a32bd1395447ba6b32c886b37db0 100644 (file)
@@ -24,7 +24,7 @@ static struct idprom idprom_buffer;
  * of the Sparc CPU and have a meaningful IDPROM machtype value that we
  * know about.  See asm-sparc/machines.h for empirical constants.
  */
-struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = {
+static struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = {
 /* First, Sun4's */
 { "Sun 4/100 Series", (SM_SUN4 | SM_4_110) },
 { "Sun 4/200 Series", (SM_SUN4 | SM_4_260) },
index 7b17522f59bfbf680b808c41a41fbdf56511f060..487960919f1f404cf598cb5aa0b8ce8cb07b3f79 100644 (file)
 
 #define mmu_inval_dma_area(p, l)       /* Anton pulled it out for 2.4.0-xx */
 
-struct resource *_sparc_find_resource(struct resource *r, unsigned long);
+static struct resource *_sparc_find_resource(struct resource *r,
+                                            unsigned long);
 
 static void __iomem *_sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz);
 static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys,
     unsigned long size, char *name);
 static void _sparc_free_io(struct resource *res);
 
+static void register_proc_sparc_ioport(void);
+
 /* This points to the next to use virtual memory for DVMA mappings */
 static struct resource _sparc_dvma = {
        .name = "sparc_dvma", .start = DVMA_VADDR, .end = DVMA_END - 1
@@ -539,8 +542,6 @@ void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp)
 
 int __init sbus_arch_preinit(void)
 {
-       extern void register_proc_sparc_ioport(void);
-
        register_proc_sparc_ioport();
 
 #ifdef CONFIG_SUN4
@@ -853,8 +854,8 @@ _sparc_io_get_info(char *buf, char **start, off_t fpos, int length, int *eof,
  * XXX Too slow. Can have 8192 DVMA pages on sun4m in the worst case.
  * This probably warrants some sort of hashing.
  */
-struct resource *
-_sparc_find_resource(struct resource *root, unsigned long hit)
+static struct resource *_sparc_find_resource(struct resource *root,
+                                            unsigned long hit)
 {
         struct resource *tmp;
 
@@ -865,7 +866,7 @@ _sparc_find_resource(struct resource *root, unsigned long hit)
        return NULL;
 }
 
-void register_proc_sparc_ioport(void)
+static void register_proc_sparc_ioport(void)
 {
 #ifdef CONFIG_PROC_FS
        create_proc_read_entry("io_map",0,NULL,_sparc_io_get_info,&sparc_iomap);
index 087390b092b01854fad73270c382866185cd9d56..93e1d1c65290b8008aef53d02d4de1f0e24c250a 100644 (file)
@@ -154,7 +154,7 @@ void (*sparc_init_timers)(irq_handler_t ) =
 struct irqaction static_irqaction[MAX_STATIC_ALLOC];
 int static_irq_count;
 
-struct {
+static struct {
        struct irqaction *action;
        int flags;
 } sparc_irq[NR_IRQS];
index da48d248cc17d6d9da5f9cb4faf96d1cb41e17e2..4bb430940a61d3c353a7501bd86b6019e5253dc5 100644 (file)
@@ -1,6 +1,6 @@
 /*  linux/arch/sparc/kernel/process.c
  *
- *  Copyright (C) 1995 David S. Miller (davem@davemloft.net)
+ *  Copyright (C) 1995, 2008 David S. Miller (davem@davemloft.net)
  *  Copyright (C) 1996 Eddie C. Dost   (ecd@skynet.be)
  */
 
@@ -14,7 +14,6 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
-#include <linux/kallsyms.h>
 #include <linux/mm.h>
 #include <linux/stddef.h>
 #include <linux/ptrace.h>
@@ -177,6 +176,8 @@ void machine_power_off(void)
        machine_halt();
 }
 
+#if 0
+
 static DEFINE_SPINLOCK(sparc_backtrace_lock);
 
 void __show_backtrace(unsigned long fp)
@@ -196,7 +197,7 @@ void __show_backtrace(unsigned long fp)
                       rw->ins[4], rw->ins[5],
                       rw->ins[6],
                       rw->ins[7]);
-               print_symbol("%s\n", rw->ins[7]);
+               printk("%pS\n", (void *) rw->ins[7]);
                rw = (struct reg_window *) rw->ins[6];
        }
        spin_unlock_irqrestore(&sparc_backtrace_lock, flags);
@@ -228,7 +229,6 @@ void smp_show_backtrace_all_cpus(void)
 }
 #endif
 
-#if 0
 void show_stackframe(struct sparc_stackf *sf)
 {
        unsigned long size;
@@ -264,14 +264,14 @@ void show_regs(struct pt_regs *r)
 
         printk("PSR: %08lx PC: %08lx NPC: %08lx Y: %08lx    %s\n",
               r->psr, r->pc, r->npc, r->y, print_tainted());
-       print_symbol("PC: <%s>\n", r->pc);
+       printk("PC: <%pS>\n", (void *) r->pc);
        printk("%%G: %08lx %08lx  %08lx %08lx  %08lx %08lx  %08lx %08lx\n",
               r->u_regs[0], r->u_regs[1], r->u_regs[2], r->u_regs[3],
               r->u_regs[4], r->u_regs[5], r->u_regs[6], r->u_regs[7]);
        printk("%%O: %08lx %08lx  %08lx %08lx  %08lx %08lx  %08lx %08lx\n",
               r->u_regs[8], r->u_regs[9], r->u_regs[10], r->u_regs[11],
               r->u_regs[12], r->u_regs[13], r->u_regs[14], r->u_regs[15]);
-       print_symbol("RPC: <%s>\n", r->u_regs[15]);
+       printk("RPC: <%pS>\n", (void *) r->u_regs[15]);
 
        printk("%%L: %08lx %08lx  %08lx %08lx  %08lx %08lx  %08lx %08lx\n",
               rw->locals[0], rw->locals[1], rw->locals[2], rw->locals[3],
@@ -306,7 +306,7 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
                rw = (struct reg_window *) fp;
                pc = rw->ins[7];
                printk("[%08lx : ", pc);
-               print_symbol("%s ] ", pc);
+               printk("%pS ] ", (void *) pc);
                fp = rw->ins[6];
        } while (++count < 16);
        printk("\n");
index ce30082ab266b7b2338f2eaa1a4d2c55b7feb901..891f460b7b96ab1e8fb47d3483ba2aadf7361826 100644 (file)
@@ -224,8 +224,6 @@ ret_trap_user_stack_is_bolixed:
        b       signal_p
         ld     [%curptr + TI_FLAGS], %g2
 
-
-       .globl  sun4c_rett_stackchk
 sun4c_rett_stackchk:
        be      1f
         and    %fp, 0xfff, %g1         ! delay slot
index a0ea0bc6f4718dc8a89256958cbf89256b4c9d12..9e451b21202e927a4c3bf809490e4e5237e15354 100644 (file)
@@ -67,7 +67,7 @@ struct screen_info screen_info = {
 extern unsigned long trapbase;
 
 /* Pretty sick eh? */
-void prom_sync_me(void)
+static void prom_sync_me(void)
 {
        unsigned long prom_tbr, flags;
 
@@ -97,7 +97,7 @@ void prom_sync_me(void)
        return;
 }
 
-unsigned int boot_flags __initdata = 0;
+static unsigned int boot_flags __initdata = 0;
 #define BOOTME_DEBUG  0x1
 
 /* Exported for mm/init.c:paging_init. */
index 6724ab90f82bc6868f2c47eb81540d7909a2ade9..1619ec15c099493a85ba4f21c93e3ecbbe594576 100644 (file)
 
 #include "irq.h"
 
-int smp_num_cpus = 1;
 volatile unsigned long cpu_callin_map[NR_CPUS] __initdata = {0,};
 unsigned char boot_cpu_id = 0;
 unsigned char boot_cpu_id4 = 0; /* boot_cpu_id << 2 */
-int smp_activated = 0;
-volatile int __cpu_number_map[NR_CPUS];
-volatile int __cpu_logical_map[NR_CPUS];
 
 cpumask_t cpu_online_map = CPU_MASK_NONE;
 cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
@@ -55,9 +51,6 @@ cpumask_t smp_commenced_mask = CPU_MASK_NONE;
  * instruction which is much better...
  */
 
-/* Used to make bitops atomic */
-unsigned char bitops_spinlock = 0;
-
 void __cpuinit smp_store_cpu_info(int id)
 {
        int cpu_node;
index c6ac9fc525632d96548e84cb4750874c57f015dc..340fc395fe2dd7491cc8bf6e351525fc506f34cc 100644 (file)
@@ -68,7 +68,8 @@ unsigned char *interrupt_enable = NULL;
 
 static int sun4c_pil_map[] = { 0, 1, 2, 3, 5, 7, 8, 9 };
 
-unsigned int sun4c_sbint_to_irq(struct sbus_dev *sdev, unsigned int sbint)
+static unsigned int sun4c_sbint_to_irq(struct sbus_dev *sdev,
+                                      unsigned int sbint)
 {
        if (sbint >= sizeof(sun4c_pil_map)) {
                printk(KERN_ERR "%s: bogus SBINT %d\n", sdev->prom_name, sbint);
index 8ac5661cafff52215b2e94630c0fb43b3b689cfb..1290b5998f831ede12dd28416cf967e088ba267c 100644 (file)
@@ -52,13 +52,13 @@ extern struct irqaction static_irqaction[MAX_STATIC_ALLOC];
 extern int static_irq_count;
 unsigned char cpu_leds[32];
 #ifdef CONFIG_SMP
-unsigned char sbus_tid[32];
+static unsigned char sbus_tid[32];
 #endif
 
 static struct irqaction *irq_action[NR_IRQS];
 extern spinlock_t irq_action_lock;
 
-struct sbus_action {
+static struct sbus_action {
        struct irqaction *action;
        /* For SMP this needs to be extended */
 } *sbus_actions;
@@ -267,7 +267,8 @@ unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq)
                return irq;
 }
 
-unsigned int sun4d_sbint_to_irq(struct sbus_dev *sdev, unsigned int sbint)
+static unsigned int sun4d_sbint_to_irq(struct sbus_dev *sdev,
+                                      unsigned int sbint)
 {
        if (sbint >= sizeof(sbus_to_pil)) {
                printk(KERN_ERR "%s: bogus SBINT %d\n", sdev->prom_name, sbint);
index b92d6d2d5b04c8f0ea98a7b07baa0c7f27c02667..94e02de960ea8ca614ef8b408c882082abd97940 100644 (file)
@@ -154,7 +154,8 @@ static unsigned long irq_mask[] = {
 
 static int sun4m_pil_map[] = { 0, 2, 3, 5, 7, 9, 11, 13 };
 
-unsigned int sun4m_sbint_to_irq(struct sbus_dev *sdev, unsigned int sbint) 
+static unsigned int sun4m_sbint_to_irq(struct sbus_dev *sdev,
+                                      unsigned int sbint)
 {
        if (sbint >= sizeof(sun4m_pil_map)) {
                printk(KERN_ERR "%s: bogus SBINT %d\n", sdev->prom_name, sbint);
@@ -163,7 +164,7 @@ unsigned int sun4m_sbint_to_irq(struct sbus_dev *sdev, unsigned int sbint)
        return sun4m_pil_map[sbint] | 0x30;
 }
 
-inline unsigned long sun4m_get_irqmask(unsigned int irq)
+static unsigned long sun4m_get_irqmask(unsigned int irq)
 {
        unsigned long mask;
     
@@ -281,7 +282,7 @@ static void sun4m_set_udt(int cpu)
 #define TIMER_IRQ      (OBIO_INTR | 10)
 #define PROFILE_IRQ    (OBIO_INTR | 14)
 
-struct sun4m_timer_regs *sun4m_timers;
+static struct sun4m_timer_regs *sun4m_timers;
 unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10);
 
 static void sun4m_clear_clock_irq(void)
index ffb875aacb7e4ccb14b5e4c9f248f24eb48a5844..406ac1abc83a8645f559b435690b5f12594f6e5a 100644 (file)
@@ -244,8 +244,9 @@ static struct smp_funcall {
 static DEFINE_SPINLOCK(cross_call_lock);
 
 /* Cross calls must be serialized, at least currently. */
-void smp4m_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
-                   unsigned long arg3, unsigned long arg4, unsigned long arg5)
+static void smp4m_cross_call(smpfunc_t func, unsigned long arg1,
+                            unsigned long arg2, unsigned long arg3,
+                            unsigned long arg4, unsigned long arg5)
 {
                register int ncpus = SUN4M_NCPUS;
                unsigned long flags;
@@ -344,7 +345,7 @@ static void __init smp_setup_percpu_timer(void)
                enable_pil_irq(14);
 }
 
-void __init smp4m_blackbox_id(unsigned *addr)
+static void __init smp4m_blackbox_id(unsigned *addr)
 {
        int rd = *addr & 0x3e000000;
        int rs1 = rd >> 11;
@@ -354,7 +355,7 @@ void __init smp4m_blackbox_id(unsigned *addr)
        addr[2] = 0x80082003 | rd | rs1;        /* and reg, 3, reg */
 }
 
-void __init smp4m_blackbox_current(unsigned *addr)
+static void __init smp4m_blackbox_current(unsigned *addr)
 {
        int rd = *addr & 0x3e000000;
        int rs1 = rd >> 11;
index 53caacbb3982e20c3feb464facdbe10352122dcf..ab3dd0b257d3337029f76a67d2cf1126ad02183c 100644 (file)
@@ -46,7 +46,7 @@
 #include "irq.h"
 
 DEFINE_SPINLOCK(rtc_lock);
-enum sparc_clock_type sp_clock_typ;
+static enum sparc_clock_type sp_clock_typ;
 DEFINE_SPINLOCK(mostek_lock);
 void __iomem *mstk48t02_regs = NULL;
 static struct mostek48t08 __iomem *mstk48t08_regs = NULL;
@@ -366,7 +366,7 @@ static int __init clock_init(void)
 fs_initcall(clock_init);
 #endif /* !CONFIG_SUN4 */
 
-void __init sbus_time_init(void)
+static void __init sbus_time_init(void)
 {
 
        BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM);
index 978e9d85949eeab9424d654fc44795bc8445e6eb..5d45d5fd8c99a150d75a6e2f0f1b489181b9c3a2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * arch/sparc/kernel/traps.c
  *
- * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright 1995, 2008 David S. Miller (davem@davemloft.net)
  * Copyright 2000 Jakub Jelinek (jakub@redhat.com)
  */
 
@@ -11,7 +11,6 @@
 
 #include <linux/sched.h>  /* for jiffies */
 #include <linux/kernel.h>
-#include <linux/kallsyms.h>
 #include <linux/signal.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
@@ -33,9 +32,6 @@ struct trap_trace_entry {
        unsigned long type;
 };
 
-int trap_curbuf = 0;
-struct trap_trace_entry trapbuf[1024];
-
 void syscall_trace_entry(struct pt_regs *regs)
 {
        printk("%s[%d]: ", current->comm, task_pid_nr(current));
@@ -72,7 +68,7 @@ void sun4d_nmi(struct pt_regs *regs)
        prom_halt();
 }
 
-void instruction_dump (unsigned long *pc)
+static void instruction_dump(unsigned long *pc)
 {
        int i;
        
@@ -119,8 +115,8 @@ void die_if_kernel(char *str, struct pt_regs *regs)
                      count++ < 30                              &&
                       (((unsigned long) rw) >= PAGE_OFFSET)    &&
                      !(((unsigned long) rw) & 0x7)) {
-                       printk("Caller[%08lx]", rw->ins[7]);
-                       print_symbol(": %s\n", rw->ins[7]);
+                       printk("Caller[%08lx]: %pS\n", rw->ins[7],
+                              (void *) rw->ins[7]);
                        rw = (struct reg_window *)rw->ins[6];
                }
        }
@@ -479,10 +475,6 @@ void do_BUG(const char *file, int line)
 
 extern void sparc_cpu_startup(void);
 
-int linux_smp_still_initting;
-unsigned int thiscpus_tbr;
-int thiscpus_mid;
-
 void trap_init(void)
 {
        extern void thread_info_offsets_are_bolixed_pete(void);
index 4bce38dfe3c5162dca0ed6cd92e346c3125bb438..3bbcd8dc9abf6622a26525fe5de2278ccd83edec 100644 (file)
@@ -306,7 +306,6 @@ spwin_bad_ustack_from_kernel:
  * As noted above %curptr cannot be touched by this routine at all.
  */
 
-       .globl  spwin_sun4c_stackchk
 spwin_sun4c_stackchk:
        /* LOCATION: Window to be saved on the stack */
 
index 82e5145b0f775a111bcb08f31e0598e1cf5e5a4a..779ff750603d0c546454b9f0dafb763ee7cd4acc 100644 (file)
@@ -243,7 +243,6 @@ fwin_user_finish_up:
         */
 
        .align  4
-       .globl  sun4c_fwin_stackchk
 sun4c_fwin_stackchk:
        /* LOCATION: Window 'W' */
 
index 0a3cd8f6cfe4690d43817152ce8e4f67b1ea2e82..3604c2e86709800455e949d27beabac11fdea949 100644 (file)
@@ -451,7 +451,7 @@ asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
 }
 
 /* This always deals with user addresses. */
-inline void force_user_fault(unsigned long address, int write)
+static void force_user_fault(unsigned long address, int write)
 {
        struct vm_area_struct *vma;
        struct task_struct *tsk = current;
index 7794ecb896e32284c8c1d3225faa285e87d088fd..e103f1bb3777ebdb11e72aea72fa399e11c02ac1 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <linux/bootmem.h>
+#include <linux/pagemap.h>
 
 #include <asm/system.h>
 #include <asm/vac-ops.h>
@@ -128,7 +129,7 @@ unsigned long calc_highpages(void)
        return nr;
 }
 
-unsigned long calc_max_low_pfn(void)
+static unsigned long calc_max_low_pfn(void)
 {
        int i;
        unsigned long tmp = pfn_base + (SRMMU_MAXMEM >> PAGE_SHIFT);
@@ -292,7 +293,7 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
  *
  * We simply copy the 2.4 implementation for now.
  */
-int pgt_cache_water[2] = { 25, 50 };
+static int pgt_cache_water[2] = { 25, 50 };
 
 void check_pgt_cache(void)
 {
@@ -356,8 +357,6 @@ void __init paging_init(void)
        device_scan();
 }
 
-struct cache_palias *sparc_aliases;
-
 static void __init taint_real_pages(void)
 {
        int i;
@@ -375,7 +374,7 @@ static void __init taint_real_pages(void)
        }
 }
 
-void map_high_region(unsigned long start_pfn, unsigned long end_pfn)
+static void map_high_region(unsigned long start_pfn, unsigned long end_pfn)
 {
        unsigned long tmp;
 
index 23d3291a3e81e65736c862e03e3b24e3047ffa22..c624e04ff03e4e03ad8c851a51dde6de88444c9d 100644 (file)
@@ -50,7 +50,7 @@
 #include <asm/btfixup.h>
 
 enum mbus_module srmmu_modtype;
-unsigned int hwbug_bitmask;
+static unsigned int hwbug_bitmask;
 int vac_cache_size;
 int vac_line_size;
 
@@ -60,7 +60,7 @@ extern unsigned long last_valid_pfn;
 
 extern unsigned long page_kernel;
 
-pgd_t *srmmu_swapper_pg_dir;
+static pgd_t *srmmu_swapper_pg_dir;
 
 #ifdef CONFIG_SMP
 #define FLUSH_BEGIN(mm)
@@ -83,12 +83,12 @@ BTFIXUPDEF_CALL(void, local_flush_page_for_dma, unsigned long)
 char *srmmu_name;
 
 ctxd_t *srmmu_ctx_table_phys;
-ctxd_t *srmmu_context_table;
+static ctxd_t *srmmu_context_table;
 
 int viking_mxcc_present;
 static DEFINE_SPINLOCK(srmmu_context_spinlock);
 
-int is_hypersparc;
+static int is_hypersparc;
 
 /*
  * In general all page table modifications should use the V8 atomic
@@ -112,11 +112,11 @@ static inline int srmmu_device_memory(unsigned long x)
        return ((x & 0xF0000000) != 0);
 }
 
-int srmmu_cache_pagetables;
+static int srmmu_cache_pagetables;
 
 /* these will be initialized in srmmu_nocache_calcsize() */
-unsigned long srmmu_nocache_size;
-unsigned long srmmu_nocache_end;
+static unsigned long srmmu_nocache_size;
+static unsigned long srmmu_nocache_end;
 
 /* 1 bit <=> 256 bytes of nocache <=> 64 PTEs */
 #define SRMMU_NOCACHE_BITMAP_SHIFT (PAGE_SHIFT - 4)
@@ -324,7 +324,7 @@ static unsigned long __srmmu_get_nocache(int size, int align)
        return (SRMMU_NOCACHE_VADDR + (offset << SRMMU_NOCACHE_BITMAP_SHIFT));
 }
 
-unsigned inline long srmmu_get_nocache(int size, int align)
+static unsigned long srmmu_get_nocache(int size, int align)
 {
        unsigned long tmp;
 
@@ -336,7 +336,7 @@ unsigned inline long srmmu_get_nocache(int size, int align)
        return tmp;
 }
 
-void srmmu_free_nocache(unsigned long vaddr, int size)
+static void srmmu_free_nocache(unsigned long vaddr, int size)
 {
        int offset;
 
@@ -369,7 +369,8 @@ void srmmu_free_nocache(unsigned long vaddr, int size)
        bit_map_clear(&srmmu_nocache_map, offset, size);
 }
 
-void srmmu_early_allocate_ptable_skeleton(unsigned long start, unsigned long end);
+static void srmmu_early_allocate_ptable_skeleton(unsigned long start,
+                                                unsigned long end);
 
 extern unsigned long probe_memory(void);       /* in fault.c */
 
@@ -377,7 +378,7 @@ extern unsigned long probe_memory(void);    /* in fault.c */
  * Reserve nocache dynamically proportionally to the amount of
  * system RAM. -- Tomas Szepe <szepe@pinerecords.com>, June 2002
  */
-void srmmu_nocache_calcsize(void)
+static void srmmu_nocache_calcsize(void)
 {
        unsigned long sysmemavail = probe_memory() / 1024;
        int srmmu_nocache_npages;
@@ -398,7 +399,7 @@ void srmmu_nocache_calcsize(void)
        srmmu_nocache_end = SRMMU_NOCACHE_VADDR + srmmu_nocache_size;
 }
 
-void __init srmmu_nocache_init(void)
+static void __init srmmu_nocache_init(void)
 {
        unsigned int bitmap_bits;
        pgd_t *pgd;
@@ -645,7 +646,7 @@ static void srmmu_unmapiorange(unsigned long virt_addr, unsigned int len)
  * mappings on the kernel stack without any special code as we did
  * need on the sun4c.
  */
-struct thread_info *srmmu_alloc_thread_info(void)
+static struct thread_info *srmmu_alloc_thread_info(void)
 {
        struct thread_info *ret;
 
@@ -1045,13 +1046,14 @@ extern void hypersparc_setup_blockops(void);
  *       around 8mb mapped for us.
  */
 
-void __init early_pgtable_allocfail(char *type)
+static void __init early_pgtable_allocfail(char *type)
 {
        prom_printf("inherit_prom_mappings: Cannot alloc kernel %s.\n", type);
        prom_halt();
 }
 
-void __init srmmu_early_allocate_ptable_skeleton(unsigned long start, unsigned long end)
+static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start,
+                                                       unsigned long end)
 {
        pgd_t *pgdp;
        pmd_t *pmdp;
@@ -1081,7 +1083,8 @@ void __init srmmu_early_allocate_ptable_skeleton(unsigned long start, unsigned l
        }
 }
 
-void __init srmmu_allocate_ptable_skeleton(unsigned long start, unsigned long end)
+static void __init srmmu_allocate_ptable_skeleton(unsigned long start,
+                                                 unsigned long end)
 {
        pgd_t *pgdp;
        pmd_t *pmdp;
@@ -1116,7 +1119,8 @@ void __init srmmu_allocate_ptable_skeleton(unsigned long start, unsigned long en
  * looking at the prom's page table directly which is what most
  * other OS's do.  Yuck... this is much better.
  */
-void __init srmmu_inherit_prom_mappings(unsigned long start,unsigned long end)
+static void __init srmmu_inherit_prom_mappings(unsigned long start,
+                                              unsigned long end)
 {
        pgd_t *pgdp;
        pmd_t *pmdp;
index db0d6de33a87cdbff398ed8f0a90835a6811c226..4e55e8f76648a27da7ff666b0fae21590e182651 100644 (file)
@@ -93,7 +93,6 @@ tsunami_flush_tlb_page_out:
        ldd     [src + offset + 0x00], t2; \
        std     t2, [dst + offset + 0x00];
 
-       .globl  tsunami_copy_1page
 tsunami_copy_1page:
 /* NOTE: This routine has to be shorter than 70insns --jj */
        or      %g0, (PAGE_SIZE >> 8), %g1
index fca9246470b11e3beb0be6e6fe1ba65c1e7a183b..7c88263256af216c2b6889481297eeb95434949c 100644 (file)
@@ -16,6 +16,7 @@ config SPARC64
        select HAVE_IDE
        select HAVE_LMB
        select HAVE_ARCH_KGDB
+       select USE_GENERIC_SMP_HELPERS if SMP
 
 config GENERIC_TIME
        bool
@@ -81,6 +82,10 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
        bool
        def_bool y
 
+source "init/Kconfig"
+
+menu "Processor type and features"
+
 choice
        prompt "Kernel page size"
        default SPARC64_PAGE_SIZE_8KB
@@ -93,19 +98,11 @@ config SPARC64_PAGE_SIZE_8KB
          8KB and 64KB work quite well, since SPARC ELF sections
          provide for up to 64KB alignment.
 
-         Therefore, 512KB and 4MB are for expert hackers only.
-
          If you don't know what to do, choose 8KB.
 
 config SPARC64_PAGE_SIZE_64KB
        bool "64KB"
 
-config SPARC64_PAGE_SIZE_512KB
-       bool "512KB"
-
-config SPARC64_PAGE_SIZE_4MB
-       bool "4MB"
-
 endchoice
 
 config SECCOMP
@@ -136,14 +133,10 @@ config HOTPLUG_CPU
          can be controlled through /sys/devices/system/cpu/cpu#.
          Say N if you want to disable CPU hotplug.
 
-source "init/Kconfig"
-
 config GENERIC_HARDIRQS
        bool
        default y
 
-menu "General machine setup"
-
 source "kernel/time/Kconfig"
 
 config SMP
@@ -225,11 +218,10 @@ config HUGETLB_PAGE_SIZE_4MB
        bool "4MB"
 
 config HUGETLB_PAGE_SIZE_512K
-       depends on !SPARC64_PAGE_SIZE_4MB && !SPARC64_PAGE_SIZE_512KB
        bool "512K"
 
 config HUGETLB_PAGE_SIZE_64K
-       depends on !SPARC64_PAGE_SIZE_4MB && !SPARC64_PAGE_SIZE_512KB && !SPARC64_PAGE_SIZE_64KB
+       depends on !SPARC64_PAGE_SIZE_64KB
        bool "64K"
 
 endchoice
index 4b8f2b084c21f35ee0932f08836a9c0f7cda5164..b785a395b12f1d1793be9127898866cb6285e289 100644 (file)
@@ -9,7 +9,9 @@
 
 CHECKFLAGS     += -D__sparc__ -D__sparc_v9__ -m64
 
-CPPFLAGS_vmlinux.lds += -Usparc
+# Undefine sparc when processing vmlinux.lds - it is used
+# And teach CPP we are doing 64 bit builds (for this case)
+CPPFLAGS_vmlinux.lds += -m64 -Usparc
 
 LDFLAGS                := -m elf64_sparc
 
index 76eb832527f29b093dd1d3232bcf420aa51ded8c..82cab5cc8070f013bb491d8c1ccd46a756d991f9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc2
-# Fri May 16 13:36:07 2008
+# Linux kernel version: 2.6.26
+# Fri Jul 18 00:47:07 2008
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -22,18 +22,6 @@ CONFIG_HAVE_SETUP_PER_CPU_AREA=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_OF=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_SPARC64_PAGE_SIZE_8KB=y
-# CONFIG_SPARC64_PAGE_SIZE_64KB is not set
-# CONFIG_SPARC64_PAGE_SIZE_512KB is not set
-# CONFIG_SPARC64_PAGE_SIZE_4MB is not set
-CONFIG_SECCOMP=y
-CONFIG_HZ_100=y
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_300 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=100
-# CONFIG_SCHED_HRTICK is not set
-CONFIG_HOTPLUG_CPU=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -105,6 +93,7 @@ CONFIG_KRETPROBES=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 # CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_USE_GENERIC_SMP_HELPERS=y
 CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -121,6 +110,7 @@ CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
 CONFIG_BLK_DEV_IO_TRACE=y
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 CONFIG_BLOCK_COMPAT=y
 
 #
@@ -136,11 +126,21 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
-CONFIG_GENERIC_HARDIRQS=y
 
 #
-# General machine setup
+# Processor type and features
 #
+CONFIG_SPARC64_PAGE_SIZE_8KB=y
+# CONFIG_SPARC64_PAGE_SIZE_64KB is not set
+CONFIG_SECCOMP=y
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_HOTPLUG_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -342,6 +342,8 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
@@ -366,6 +368,7 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_CDROM_PKTCDVD_WCACHE=y
 CONFIG_ATA_OVER_ETH=m
 CONFIG_SUNVDC=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
 # CONFIG_EEPROM_93CX6 is not set
@@ -379,6 +382,7 @@ CONFIG_BLK_DEV_IDE=y
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_TIMINGS=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
@@ -429,8 +433,6 @@ CONFIG_BLK_DEV_ALI15X3=y
 # CONFIG_BLK_DEV_VIA82CXXX is not set
 # CONFIG_BLK_DEV_TC86C001 is not set
 CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -504,6 +506,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SUNESP is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
 # CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
@@ -529,6 +532,10 @@ CONFIG_DM_ZERO=m
 #
 # IEEE 1394 (FireWire) support
 #
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
@@ -745,7 +752,8 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
+CONFIG_HW_RANDOM=m
+CONFIG_HW_RANDOM_N2RNG=m
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -759,38 +767,58 @@ CONFIG_I2C_ALGOBIT=y
 #
 # I2C Hardware Bus support
 #
+
+#
+# PC SMBus host controller drivers
+#
 # CONFIG_I2C_ALI1535 is not set
 # CONFIG_I2C_ALI1563 is not set
 # CONFIG_I2C_ALI15X3 is not set
 # CONFIG_I2C_AMD756 is not set
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_ISCH is not set
 # CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIMTEC is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TINY_USB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
 # CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
 # CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
@@ -856,6 +884,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -985,15 +1014,7 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_SUN_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=m
-
-#
-# Advanced Linux Sound Architecture
-#
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
@@ -1010,21 +1031,17 @@ CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
+CONFIG_SND_VMASTER=y
 CONFIG_SND_MPU401_UART=m
 CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_DRIVERS=y
 CONFIG_SND_DUMMY=m
 CONFIG_SND_VIRMIDI=m
 CONFIG_SND_MTPAV=m
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
-
-#
-# PCI devices
-#
+# CONFIG_SND_AC97_POWER_SAVE is not set
+CONFIG_SND_PCI=y
 # CONFIG_SND_AD1889 is not set
 # CONFIG_SND_ALS300 is not set
 CONFIG_SND_ALI5451=m
@@ -1084,37 +1101,14 @@ CONFIG_SND_ALI5451=m
 # CONFIG_SND_VIRTUOSO is not set
 # CONFIG_SND_VX222 is not set
 # CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_AC97_POWER_SAVE is not set
-
-#
-# USB devices
-#
+CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
 # CONFIG_SND_USB_CAIAQ is not set
-
-#
-# ALSA Sparc devices
-#
+CONFIG_SND_SPARC=y
 # CONFIG_SND_SUN_AMD7930 is not set
 CONFIG_SND_SUN_CS4231=m
 # CONFIG_SND_SUN_DBRI is not set
-
-#
-# System on Chip audio support
-#
 # CONFIG_SND_SOC is not set
-
-#
-# ALSA SoC audio for Freescale SOCs
-#
-
-#
-# SoC Audio for the Texas Instruments OMAP
-#
-
-#
-# Open Sound System
-#
 # CONFIG_SOUND_PRIME is not set
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
@@ -1167,6 +1161,7 @@ CONFIG_USB_UHCI_HCD=m
 #
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1226,6 +1221,7 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1420,6 +1416,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1486,6 +1488,10 @@ CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 CONFIG_CRYPTO_SHA1=y
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1527,6 +1533,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_FIRST_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index b61b8dfb09cfc6db9581bb1533d90ff00e813809..f2e87d0d7e1d7ab2c17020443d39b09dc9de193c 100644 (file)
@@ -16,8 +16,8 @@
 #include <asm/fhc.h>
 #include <asm/starfire.h>
 
-struct linux_central *central_bus = NULL;
-struct linux_fhc *fhc_list = NULL;
+static struct linux_central *central_bus = NULL;
+static struct linux_fhc *fhc_list = NULL;
 
 #define IS_CENTRAL_FHC(__fhc)  ((__fhc) == central_bus->child)
 
@@ -79,9 +79,9 @@ static void adjust_regs(struct linux_prom_registers *regp, int nregs,
 }
 
 /* Apply probed fhc ranges to registers passed, if no ranges return. */
-void apply_fhc_ranges(struct linux_fhc *fhc,
-                     struct linux_prom_registers *regs,
-                     int nregs)
+static void apply_fhc_ranges(struct linux_fhc *fhc,
+                            struct linux_prom_registers *regs,
+                            int nregs)
 {
        if (fhc->num_fhc_ranges)
                adjust_regs(regs, nregs, fhc->fhc_ranges,
@@ -89,8 +89,8 @@ void apply_fhc_ranges(struct linux_fhc *fhc,
 }
 
 /* Apply probed central ranges to registers passed, if no ranges return. */
-void apply_central_ranges(struct linux_central *central,
-                         struct linux_prom_registers *regs, int nregs)
+static void apply_central_ranges(struct linux_central *central,
+                                struct linux_prom_registers *regs, int nregs)
 {
        if (central->num_central_ranges)
                adjust_regs(regs, nregs, central->central_ranges,
index edb74f5a1186ebd82f973378e961de4a7e64d7fe..d0fa5aa389341cf3020b40180f86c696b22600fd 100644 (file)
@@ -159,7 +159,7 @@ static void ds_var_data(struct ds_info *dp,
                        struct ds_cap_state *cp,
                        void *buf, int len);
 
-struct ds_cap_state ds_states_template[] = {
+static struct ds_cap_state ds_states_template[] = {
        {
                .service_id     = "md-update",
                .data           = md_update_data,
index c49d0388b793852af4bf1ce99ac2d20868e6e3fc..4d58d7ce708dc87206d1f0602e334c54d72c6260 100644 (file)
@@ -401,7 +401,7 @@ static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_de
        dev->ofdev.node = dp;
        dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
        dev->ofdev.dev.bus = &ebus_bus_type;
-       sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node);
+       dev_set_name(&dev->ofdev.dev, "ebus[%08x]", dp->node);
 
        /* Register with core */
        if (of_device_register(&dev->ofdev) != 0)
@@ -501,7 +501,7 @@ void __init ebus_init(void)
                ebus->ofdev.node = dp;
                ebus->ofdev.dev.parent = &pdev->dev;
                ebus->ofdev.dev.bus = &ebus_bus_type;
-               sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus);
+               dev_set_name(&ebus->ofdev.dev, "ebus%d", num_ebus);
 
                /* Register with core */
                if (of_device_register(&ebus->ofdev) != 0)
index f34f5d6181eff1af2dbd4197cf5ad9eeaae11996..691760b5b0127e5143da2bfa4056ac63e86ba238 100644 (file)
@@ -34,8 +34,12 @@ static struct api_info api_table[] = {
        { .group = HV_GRP_LDOM,                                 },
        { .group = HV_GRP_SVC_CHAN,     .flags = FLAG_PRE_API   },
        { .group = HV_GRP_NCS,          .flags = FLAG_PRE_API   },
+       { .group = HV_GRP_RNG,                                  },
        { .group = HV_GRP_NIAG_PERF,    .flags = FLAG_PRE_API   },
        { .group = HV_GRP_FIRE_PERF,                            },
+       { .group = HV_GRP_N2_CPU,                               },
+       { .group = HV_GRP_NIU,                                  },
+       { .group = HV_GRP_VF_CPU,                               },
        { .group = HV_GRP_DIAG,         .flags = FLAG_PRE_API   },
 };
 
index d569f60c24b87fd4fc23d6e749fc37d083bb22a3..4fd48ab7dda40bef2a290e08cb07558122b3be35 100644 (file)
@@ -797,9 +797,9 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
        op->dev.parent = parent;
        op->dev.bus = &of_platform_bus_type;
        if (!parent)
-               strcpy(op->dev.bus_id, "root");
+               dev_set_name(&op->dev, "root");
        else
-               sprintf(op->dev.bus_id, "%08x", dp->node);
+               dev_set_name(&op->dev, "%08x", dp->node);
 
        if (of_device_register(op)) {
                printk("%s: Could not register of device.\n",
index d00a3656c287fed07c13b4609997e1ff09f8e375..55096195458fa0d358364075c5c7f06617112a55 100644 (file)
@@ -408,7 +408,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
        dev->class = class >> 8;
        dev->revision = class & 0xff;
 
-       sprintf(dev->dev.bus_id, "%04x:%02x:%02x.%d", pci_domain_nr(bus),
+       dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(bus),
                dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
 
        if (ofpci_verbose)
index db5e8fd8f6742281bea1a643f46eefb317551ae5..60c71e35021253fde9a38501e3e61b5de0b9f0d8 100644 (file)
@@ -120,9 +120,9 @@ static struct irq_chip msi_irq = {
        /* XXX affinity XXX */
 };
 
-int sparc64_setup_msi_irq(unsigned int *virt_irq_p,
-                         struct pci_dev *pdev,
-                         struct msi_desc *entry)
+static int sparc64_setup_msi_irq(unsigned int *virt_irq_p,
+                                struct pci_dev *pdev,
+                                struct msi_desc *entry)
 {
        struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
        const struct sparc64_msiq_ops *ops = pbm->msi_ops;
@@ -179,8 +179,8 @@ out_err:
        return err;
 }
 
-void sparc64_teardown_msi_irq(unsigned int virt_irq,
-                             struct pci_dev *pdev)
+static void sparc64_teardown_msi_irq(unsigned int virt_irq,
+                                    struct pci_dev *pdev)
 {
        struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
        const struct sparc64_msiq_ops *ops = pbm->msi_ops;
index e2bb9790039c5b47f9e6b85a8bd35f387665d7ce..a104c80d319debf8a76c3d658b12fea47cd39d91 100644 (file)
@@ -531,7 +531,7 @@ static void dma_4v_sync_sg_for_cpu(struct device *dev,
        /* Nothing to do... */
 }
 
-const struct dma_ops sun4v_dma_ops = {
+static const struct dma_ops sun4v_dma_ops = {
        .alloc_coherent                 = dma_4v_alloc_coherent,
        .free_coherent                  = dma_4v_free_coherent,
        .map_single                     = dma_4v_map_single,
index 2084f81a76e1d49319af047470f9348977d9968e..31ea752d307be15132530cbc1f7aa9ad1b97c630 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
-#include <linux/kallsyms.h>
 #include <linux/mm.h>
 #include <linux/fs.h>
 #include <linux/smp.h>
@@ -211,7 +210,7 @@ static void show_regwindow(struct pt_regs *regs)
        printk("i4: %016lx i5: %016lx i6: %016lx i7: %016lx\n",
               rwk->ins[4], rwk->ins[5], rwk->ins[6], rwk->ins[7]);
        if (regs->tstate & TSTATE_PRIV)
-               print_symbol("I7: <%s>\n", rwk->ins[7]);
+               printk("I7: <%pS>\n", (void *) rwk->ins[7]);
 }
 
 #ifdef CONFIG_SMP
@@ -232,7 +231,7 @@ void __show_regs(struct pt_regs * regs)
 #endif
        printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x    %s\n", regs->tstate,
               regs->tpc, regs->tnpc, regs->y, print_tainted());
-       print_symbol("TPC: <%s>\n", regs->tpc);
+       printk("TPC: <%pS>\n", (void *) regs->tpc);
        printk("g0: %016lx g1: %016lx g2: %016lx g3: %016lx\n",
               regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
               regs->u_regs[3]);
@@ -245,7 +244,7 @@ void __show_regs(struct pt_regs * regs)
        printk("o4: %016lx o5: %016lx sp: %016lx ret_pc: %016lx\n",
               regs->u_regs[12], regs->u_regs[13], regs->u_regs[14],
               regs->u_regs[15]);
-       print_symbol("RPC: <%s>\n", regs->u_regs[15]);
+       printk("RPC: <%pS>\n", (void *) regs->u_regs[15]);
        show_regwindow(regs);
 #ifdef CONFIG_SMP
        spin_unlock(&regdump_lock);
@@ -346,9 +345,6 @@ static void sysrq_handle_globreg(int key, struct tty_struct *tty)
 {
        struct thread_info *tp = current_thread_info();
        struct pt_regs *regs = get_irq_regs();
-#ifdef CONFIG_KALLSYMS
-       char buffer[KSYM_SYMBOL_LEN];
-#endif
        unsigned long flags;
        int this_cpu, cpu;
 
@@ -377,17 +373,13 @@ static void sysrq_handle_globreg(int key, struct tty_struct *tty)
                       gp->tstate, gp->tpc, gp->tnpc,
                       ((tp && tp->task) ? tp->task->comm : "NULL"),
                       ((tp && tp->task) ? tp->task->pid : -1));
-#ifdef CONFIG_KALLSYMS
+
                if (gp->tstate & TSTATE_PRIV) {
-                       sprint_symbol(buffer, gp->tpc);
-                       printk("             TPC[%s] ", buffer);
-                       sprint_symbol(buffer, gp->o7);
-                       printk("O7[%s] ", buffer);
-                       sprint_symbol(buffer, gp->i7);
-                       printk("I7[%s]\n", buffer);
-               } else
-#endif
-               {
+                       printk("             TPC[%pS] O7[%pS] I7[%pS]\n",
+                              (void *) gp->tpc,
+                              (void *) gp->o7,
+                              (void *) gp->i7);
+               } else {
                        printk("             TPC[%lx] O7[%lx] I7[%lx]\n",
                               gp->tpc, gp->o7, gp->i7);
                }
@@ -691,9 +683,9 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
                  ((unsigned long) child_sf) - STACK_BIAS;
 
                /* Special case, if we are spawning a kernel thread from
-                * a userspace task (via KMOD, NFS, or similar) we must
-                * disable performance counters in the child because the
-                * address space and protection realm are changing.
+                * a userspace task (usermode helper, NFS or similar), we
+                * must disable performance counters in the child because
+                * the address space and protection realm are changing.
                 */
                if (t->flags & _TIF_PERFCTR) {
                        t->user_cntd0 = t->user_cntd1 = NULL;
index c099d96f12397c00f2f8d7ef45b9bfff9530c4c0..7cf72b4bb1089498348be341ee02a840161a1af3 100644 (file)
@@ -788,89 +788,36 @@ static void smp_start_sync_tick_client(int cpu)
                              0, 0, 0, mask);
 }
 
-/* Send cross call to all processors except self. */
-#define smp_cross_call(func, ctx, data1, data2) \
-       smp_cross_call_masked(func, ctx, data1, data2, cpu_online_map)
-
-struct call_data_struct {
-       void (*func) (void *info);
-       void *info;
-       atomic_t finished;
-       int wait;
-};
-
-static struct call_data_struct *call_data;
-
 extern unsigned long xcall_call_function;
 
-/**
- * smp_call_function(): Run a function on all other CPUs.
- * @func: The function to run. This must be fast and non-blocking.
- * @info: An arbitrary pointer to pass to the function.
- * @wait: If true, wait (atomically) until function has completed on other CPUs.
- *
- * Returns 0 on success, else a negative status code. Does not return until
- * remote CPUs are nearly ready to execute <<func>> or are or have executed.
- *
- * You must not call this function with disabled interrupts or from a
- * hardware interrupt handler or from a bottom half handler.
- */
-static int sparc64_smp_call_function_mask(void (*func)(void *info), void *info,
-                                         int wait, cpumask_t mask)
+void arch_send_call_function_ipi(cpumask_t mask)
 {
-       struct call_data_struct data;
-       int cpus;
-
-       /* Can deadlock when called with interrupts disabled */
-       WARN_ON(irqs_disabled());
-
-       data.func = func;
-       data.info = info;
-       atomic_set(&data.finished, 0);
-       data.wait = wait;
-
-       spin_lock(&call_lock);
-
-       cpu_clear(smp_processor_id(), mask);
-       cpus = cpus_weight(mask);
-       if (!cpus)
-               goto out_unlock;
-
-       call_data = &data;
-       mb();
-
        smp_cross_call_masked(&xcall_call_function, 0, 0, 0, mask);
+}
 
-       /* Wait for response */
-       while (atomic_read(&data.finished) != cpus)
-               cpu_relax();
+extern unsigned long xcall_call_function_single;
 
-out_unlock:
-       spin_unlock(&call_lock);
+void arch_send_call_function_single_ipi(int cpu)
+{
+       cpumask_t mask = cpumask_of_cpu(cpu);
 
-       return 0;
+       smp_cross_call_masked(&xcall_call_function_single, 0, 0, 0, mask);
 }
 
-int smp_call_function(void (*func)(void *info), void *info, int wait)
-{
-       return sparc64_smp_call_function_mask(func, info, wait, cpu_online_map);
-}
+/* Send cross call to all processors except self. */
+#define smp_cross_call(func, ctx, data1, data2) \
+       smp_cross_call_masked(func, ctx, data1, data2, cpu_online_map)
 
 void smp_call_function_client(int irq, struct pt_regs *regs)
 {
-       void (*func) (void *info) = call_data->func;
-       void *info = call_data->info;
+       clear_softint(1 << irq);
+       generic_smp_call_function_interrupt();
+}
 
+void smp_call_function_single_client(int irq, struct pt_regs *regs)
+{
        clear_softint(1 << irq);
-       if (call_data->wait) {
-               /* let initiator proceed only after completion */
-               func(info);
-               atomic_inc(&call_data->finished);
-       } else {
-               /* let initiator proceed after getting data */
-               atomic_inc(&call_data->finished);
-               func(info);
-       }
+       generic_smp_call_function_single_interrupt();
 }
 
 static void tsb_sync(void *info)
@@ -890,7 +837,7 @@ static void tsb_sync(void *info)
 
 void smp_tsb_sync(struct mm_struct *mm)
 {
-       sparc64_smp_call_function_mask(tsb_sync, mm, 1, mm->cpu_vm_mask);
+       smp_call_function_mask(mm->cpu_vm_mask, tsb_sync, mm, 1);
 }
 
 extern unsigned long xcall_flush_tlb_mm;
index 49d3ea50c24797f22532aa4a7b6f42605ee74ce3..504e678ee128e3998af12688e0678aa4568204a1 100644 (file)
@@ -108,8 +108,6 @@ EXPORT_SYMBOL(__read_unlock);
 EXPORT_SYMBOL(__write_lock);
 EXPORT_SYMBOL(__write_unlock);
 EXPORT_SYMBOL(__write_trylock);
-
-EXPORT_SYMBOL(smp_call_function);
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_MCOUNT
index ac1bff58c1ac8319eb0178e0980eeda35dfb1a32..e1f4eba2e5760191a728f472345ead476fc72ba5 100644 (file)
@@ -542,7 +542,7 @@ asmlinkage long sparc64_personality(unsigned long personality)
        return ret;
 }
 
-int sparc64_mmap_check(unsigned long addr, unsigned long len)
+int sparc_mmap_check(unsigned long addr, unsigned long len)
 {
        if (test_thread_flag(TIF_32BIT)) {
                if (len >= STACK_TOP32)
@@ -614,9 +614,9 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr,
                goto out;
        if (unlikely(new_len >= VA_EXCLUDE_START))
                goto out;
-       if (unlikely(sparc64_mmap_check(addr, old_len)))
+       if (unlikely(sparc_mmap_check(addr, old_len)))
                goto out;
-       if (unlikely(sparc64_mmap_check(new_addr, new_len)))
+       if (unlikely(sparc_mmap_check(new_addr, new_len)))
                goto out;
 
        down_write(&current->mm->mmap_sem);
index ba5bd626b39e39a263a2aec0a1b6939ea0d70c94..97b77fb5c50e8d127750bfd4dd8c5c917f137c35 100644 (file)
@@ -359,7 +359,8 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
        return err;
 }
 
-int cp_compat_stat64(struct kstat *stat, struct compat_stat64 __user *statbuf)
+static int cp_compat_stat64(struct kstat *stat,
+                           struct compat_stat64 __user *statbuf)
 {
        int err;
 
@@ -870,9 +871,9 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr,
        unsigned long ret = -EINVAL;
        unsigned long new_addr = __new_addr;
 
-       if (unlikely(sparc64_mmap_check(addr, old_len)))
+       if (unlikely(sparc_mmap_check(addr, old_len)))
                goto out;
-       if (unlikely(sparc64_mmap_check(new_addr, new_len)))
+       if (unlikely(sparc_mmap_check(new_addr, new_len)))
                goto out;
        down_write(&current->mm->mmap_sem);
        ret = do_mremap(addr, old_len, new_len, flags, new_addr);
index e885034a6b73a865c049fa5ca62ca5dab3a88fc1..84e5ce146713383922f07f9e5b1c677874067344 100644 (file)
@@ -14,7 +14,8 @@
 static DEFINE_PER_CPU(struct hv_mmu_statistics, mmu_stats) __attribute__((aligned(64)));
 
 #define SHOW_MMUSTAT_ULONG(NAME) \
-static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+static ssize_t show_##NAME(struct sys_device *dev, \
+                       struct sysdev_attribute *attr, char *buf) \
 { \
        struct hv_mmu_statistics *p = &per_cpu(mmu_stats, dev->id); \
        return sprintf(buf, "%lu\n", p->NAME); \
@@ -135,13 +136,16 @@ static unsigned long write_mmustat_enable(unsigned long val)
        return sun4v_mmustat_conf(ra, &orig_ra);
 }
 
-static ssize_t show_mmustat_enable(struct sys_device *s, char *buf)
+static ssize_t show_mmustat_enable(struct sys_device *s,
+                               struct sysdev_attribute *attr, char *buf)
 {
        unsigned long val = run_on_cpu(s->id, read_mmustat_enable, 0);
        return sprintf(buf, "%lx\n", val);
 }
 
-static ssize_t store_mmustat_enable(struct sys_device *s, const char *buf, size_t count)
+static ssize_t store_mmustat_enable(struct sys_device *s,
+                       struct sysdev_attribute *attr, const char *buf,
+                       size_t count)
 {
        unsigned long val, err;
        int ret = sscanf(buf, "%ld", &val);
@@ -179,14 +183,16 @@ static void unregister_mmu_stats(struct sys_device *s)
 #endif
 
 #define SHOW_CPUDATA_ULONG_NAME(NAME, MEMBER) \
-static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+static ssize_t show_##NAME(struct sys_device *dev, \
+               struct sysdev_attribute *attr, char *buf) \
 { \
        cpuinfo_sparc *c = &cpu_data(dev->id); \
        return sprintf(buf, "%lu\n", c->MEMBER); \
 }
 
 #define SHOW_CPUDATA_UINT_NAME(NAME, MEMBER) \
-static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+static ssize_t show_##NAME(struct sys_device *dev, \
+               struct sysdev_attribute *attr, char *buf) \
 { \
        cpuinfo_sparc *c = &cpu_data(dev->id); \
        return sprintf(buf, "%u\n", c->MEMBER); \
index 36974926265367824d5f7061badfef0d92d909b1..bd30ecba563010bfced1ad54950875e59f160418 100644 (file)
@@ -1,6 +1,6 @@
 /* arch/sparc64/kernel/traps.c
  *
- * Copyright (C) 1995,1997 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1995,1997,2008 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com)
  */
 
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
-#include <linux/kallsyms.h>
 #include <linux/signal.h>
 #include <linux/smp.h>
 #include <linux/mm.h>
@@ -37,9 +36,6 @@
 #include <asm/processor.h>
 #include <asm/timer.h>
 #include <asm/head.h>
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
 #include <asm/prom.h>
 
 #include "entry.h"
@@ -74,7 +70,7 @@ static void dump_tl1_traplog(struct tl1_traplog *p)
                       i + 1,
                       p->trapstack[i].tstate, p->trapstack[i].tpc,
                       p->trapstack[i].tnpc, p->trapstack[i].tt);
-               print_symbol("TRAPLOG: TPC<%s>\n", p->trapstack[i].tpc);
+               printk("TRAPLOG: TPC<%pS>\n", (void *) p->trapstack[i].tpc);
        }
 }
 
@@ -1081,7 +1077,7 @@ static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *in
               regs->tpc, regs->tnpc, regs->u_regs[UREG_I7], regs->tstate);
        printk("%s" "ERROR(%d): ",
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id());
-       print_symbol("TPC<%s>\n", regs->tpc);
+       printk("TPC<%pS>\n", (void *) regs->tpc);
        printk("%s" "ERROR(%d): M_SYND(%lx),  E_SYND(%lx)%s%s\n",
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
               (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT,
@@ -1689,7 +1685,7 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs)
                       smp_processor_id(),
                       (type & 0x1) ? 'I' : 'D',
                       regs->tpc);
-               print_symbol(KERN_EMERG "TPC<%s>\n", regs->tpc);
+               printk(KERN_EMERG "TPC<%pS>\n", (void *) regs->tpc);
                panic("Irrecoverable Cheetah+ parity error.");
        }
 
@@ -1697,7 +1693,7 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs)
               smp_processor_id(),
               (type & 0x1) ? 'I' : 'D',
               regs->tpc);
-       print_symbol(KERN_WARNING "TPC<%s>\n", regs->tpc);
+       printk(KERN_WARNING "TPC<%pS>\n", (void *) regs->tpc);
 }
 
 struct sun4v_error_entry {
@@ -1904,9 +1900,10 @@ void sun4v_itlb_error_report(struct pt_regs *regs, int tl)
 
        printk(KERN_EMERG "SUN4V-ITLB: Error at TPC[%lx], tl %d\n",
               regs->tpc, tl);
-       print_symbol(KERN_EMERG "SUN4V-ITLB: TPC<%s>\n", regs->tpc);
+       printk(KERN_EMERG "SUN4V-ITLB: TPC<%pS>\n", (void *) regs->tpc);
        printk(KERN_EMERG "SUN4V-ITLB: O7[%lx]\n", regs->u_regs[UREG_I7]);
-       print_symbol(KERN_EMERG "SUN4V-ITLB: O7<%s>\n", regs->u_regs[UREG_I7]);
+       printk(KERN_EMERG "SUN4V-ITLB: O7<%pS>\n",
+              (void *) regs->u_regs[UREG_I7]);
        printk(KERN_EMERG "SUN4V-ITLB: vaddr[%lx] ctx[%lx] "
               "pte[%lx] error[%lx]\n",
               sun4v_err_itlb_vaddr, sun4v_err_itlb_ctx,
@@ -1927,9 +1924,10 @@ void sun4v_dtlb_error_report(struct pt_regs *regs, int tl)
 
        printk(KERN_EMERG "SUN4V-DTLB: Error at TPC[%lx], tl %d\n",
               regs->tpc, tl);
-       print_symbol(KERN_EMERG "SUN4V-DTLB: TPC<%s>\n", regs->tpc);
+       printk(KERN_EMERG "SUN4V-DTLB: TPC<%pS>\n", (void *) regs->tpc);
        printk(KERN_EMERG "SUN4V-DTLB: O7[%lx]\n", regs->u_regs[UREG_I7]);
-       print_symbol(KERN_EMERG "SUN4V-DTLB: O7<%s>\n", regs->u_regs[UREG_I7]);
+       printk(KERN_EMERG "SUN4V-DTLB: O7<%pS>\n",
+              (void *) regs->u_regs[UREG_I7]);
        printk(KERN_EMERG "SUN4V-DTLB: vaddr[%lx] ctx[%lx] "
               "pte[%lx] error[%lx]\n",
               sun4v_err_dtlb_vaddr, sun4v_err_dtlb_ctx,
@@ -2111,10 +2109,7 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
        fp = ksp + STACK_BIAS;
        thread_base = (unsigned long) tp;
 
-       printk("Call Trace:");
-#ifdef CONFIG_KALLSYMS
-       printk("\n");
-#endif
+       printk("Call Trace:\n");
        do {
                struct sparc_stackf *sf;
                struct pt_regs *regs;
@@ -2137,12 +2132,8 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
                        fp = (unsigned long)sf->fp + STACK_BIAS;
                }
 
-               printk(" [%016lx] ", pc);
-               print_symbol("%s\n", pc);
+               printk(" [%016lx] %pS\n", pc, (void *) pc);
        } while (++count < 16);
-#ifndef CONFIG_KALLSYMS
-       printk("\n");
-#endif
 }
 
 void dump_stack(void)
@@ -2211,9 +2202,8 @@ void die_if_kernel(char *str, struct pt_regs *regs)
                while (rw &&
                       count++ < 30&&
                       is_kernel_stack(current, rw)) {
-                       printk("Caller[%016lx]", rw->ins[7]);
-                       print_symbol(": %s", rw->ins[7]);
-                       printk("\n");
+                       printk("Caller[%016lx]: %pS\n", rw->ins[7],
+                              (void *) rw->ins[7]);
 
                        rw = kernel_stack_up(rw);
                }
index 450053af039e48abd0d6c92faca49a69e6d2107f..1ade3d6fb7fc7d1bd748a7c47852c027328efa76 100644 (file)
@@ -58,7 +58,12 @@ tl0_irq3:    BTRAP(0x43)
 tl0_irq4:      BTRAP(0x44)
 #endif
 tl0_irq5:      TRAP_IRQ(handler_irq, 5)
-tl0_irq6:      BTRAP(0x46) BTRAP(0x47) BTRAP(0x48) BTRAP(0x49)
+#ifdef CONFIG_SMP
+tl0_irq6:      TRAP_IRQ(smp_call_function_single_client, 6)
+#else
+tl0_irq6:      BTRAP(0x46)
+#endif
+tl0_irq7:      BTRAP(0x47) BTRAP(0x48) BTRAP(0x49)
 tl0_irq10:     BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d)
 tl0_irq14:     TRAP_IRQ(timer_interrupt, 14)
 tl0_irq15:     TRAP_IRQ(handler_irq, 15)
index afa7fc4f519373e5637cf6b936ea140c99c92758..203ddfad9f27f3c6067760916085624503eee9ff 100644 (file)
@@ -2,7 +2,7 @@
  * unaligned.c: Unaligned load/store trap handling with special
  *              cases for the kernel to do them more quickly.
  *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996,2008 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  */
 
@@ -20,7 +20,6 @@
 #include <asm/uaccess.h>
 #include <linux/smp.h>
 #include <linux/bitops.h>
-#include <linux/kallsyms.h>
 #include <asm/fpumacro.h>
 
 /* #define DEBUG_MNA */
@@ -289,8 +288,8 @@ static void log_unaligned(struct pt_regs *regs)
        if (count < 5) {
                last_time = jiffies;
                count++;
-               printk("Kernel unaligned access at TPC[%lx] ", regs->tpc);
-               print_symbol("%s\n", regs->tpc);
+               printk("Kernel unaligned access at TPC[%lx] %pS\n",
+                      regs->tpc, (void *) regs->tpc);
        }
 }
 
index e78b3517940b6a252a13d36b544c371341f1aae0..a490077891a4c532e399e062830d3e932269af65 100644 (file)
@@ -224,7 +224,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        if (!strcmp(type, "domain-services-port"))
                bus_id_name = "ds";
 
-       if (strlen(bus_id_name) >= KOBJ_NAME_LEN - 4) {
+       if (strlen(bus_id_name) >= BUS_ID_SIZE - 4) {
                printk(KERN_ERR "VIO: bus_id_name [%s] is too long.\n",
                       bus_id_name);
                return NULL;
@@ -260,16 +260,14 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        vio_fill_channel_info(hp, mp, vdev);
 
        if (!id) {
-               snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s",
-                        bus_id_name);
+               dev_set_name(&vdev->dev, "%s", bus_id_name);
                vdev->dev_no = ~(u64)0;
        } else if (!cfg_handle) {
-               snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu",
-                        bus_id_name, *id);
+               dev_set_name(&vdev->dev, "%s-%lu", bus_id_name, *id);
                vdev->dev_no = *id;
        } else {
-               snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu-%lu",
-                        bus_id_name, *cfg_handle, *id);
+               dev_set_name(&vdev->dev, "%s-%lu-%lu", bus_id_name,
+                            *cfg_handle, *id);
                vdev->dev_no = *cfg_handle;
        }
 
@@ -292,12 +290,12 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        }
        vdev->dp = dp;
 
-       printk(KERN_INFO "VIO: Adding device %s\n", vdev->dev.bus_id);
+       printk(KERN_INFO "VIO: Adding device %s\n", dev_name(&vdev->dev));
 
        err = device_register(&vdev->dev);
        if (err) {
                printk(KERN_ERR "VIO: Could not register device %s, err=%d\n",
-                      vdev->dev.bus_id, err);
+                      dev_name(&vdev->dev), err);
                kfree(vdev);
                return NULL;
        }
@@ -330,7 +328,7 @@ static void vio_remove(struct mdesc_handle *hp, u64 node)
        dev = device_find_child(&root_vdev->dev, (void *) node,
                                vio_md_node_match);
        if (dev) {
-               printk(KERN_INFO "VIO: Removing device %s\n", dev->bus_id);
+               printk(KERN_INFO "VIO: Removing device %s\n", dev_name(dev));
 
                device_unregister(dev);
        }
index 37460666a5c3250177742db6409e2f69714421d7..b243d3b606ba447106ea4ce756b1e31171b6aeb7 100644 (file)
@@ -25,9 +25,9 @@
 
 #define        DCACHE_SIZE     (PAGE_SIZE * 2)
 
-#if (PAGE_SHIFT == 13) || (PAGE_SHIFT == 19)
+#if (PAGE_SHIFT == 13)
 #define PAGE_SIZE_REM  0x80
-#elif (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22)
+#elif (PAGE_SHIFT == 16)
 #define PAGE_SIZE_REM  0x100
 #else
 #error Wrong PAGE_SHIFT specified
@@ -198,7 +198,7 @@ cheetah_copy_page_insn:
        cmp             %o2, PAGE_SIZE_REM
        bne,pt          %xcc, 1b
         add            %o0, 0x40, %o0
-#if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22)
+#if (PAGE_SHIFT == 16)
        TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
        ldda            [%o1] ASI_BLK_P, %f32
        stda            %f48, [%o0] %asi
index 236f4d228d2bc962908af77a37b012ce9d1e8bc5..ea7d7ae76bc24d20f3e731507b478f032986f150 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
  *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996, 2008 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
  */
 
@@ -18,7 +18,6 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/kprobes.h>
-#include <linux/kallsyms.h>
 #include <linux/kdebug.h>
 
 #include <asm/page.h>
@@ -115,7 +114,7 @@ static void bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr)
        printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
               regs->tpc);
        printk(KERN_CRIT "OOPS: RPC [%016lx]\n", regs->u_regs[15]);
-       print_symbol("RPC: <%s>\n", regs->u_regs[15]);
+       printk("OOPS: RPC <%pS>\n", (void *) regs->u_regs[15]);
        printk(KERN_CRIT "OOPS: Fault was to vaddr[%lx]\n", vaddr);
        dump_stack();
        unhandled_fault(regs->tpc, current, regs);
index fe70c8a557b58ae1c96cb4312878797b8d881d49..3547937b17a2f2d43c5d9f667dcfca7e8ce0c1eb 100644 (file)
@@ -96,12 +96,6 @@ void flush_tsb_user(struct mmu_gather *mp)
 #elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
 #define HV_PGSZ_IDX_BASE       HV_PGSZ_IDX_64K
 #define HV_PGSZ_MASK_BASE      HV_PGSZ_MASK_64K
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_512KB)
-#define HV_PGSZ_IDX_BASE       HV_PGSZ_IDX_512K
-#define HV_PGSZ_MASK_BASE      HV_PGSZ_MASK_512K
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_4MB)
-#define HV_PGSZ_IDX_BASE       HV_PGSZ_IDX_4MB
-#define HV_PGSZ_MASK_BASE      HV_PGSZ_MASK_4MB
 #else
 #error Broken base page size setting...
 #endif
index 9bb2d90a9df6ba948e566f6c7c11d92a0a437837..4c8ca131ffaf467ec329fc70753f32b076bff392 100644 (file)
@@ -688,6 +688,11 @@ xcall_call_function:
        wr              %g0, (1 << PIL_SMP_CALL_FUNC), %set_softint
        retry
 
+       .globl          xcall_call_function_single
+xcall_call_function_single:
+       wr              %g0, (1 << PIL_SMP_CALL_FUNC_SNGL), %set_softint
+       retry
+
        .globl          xcall_receive_signal
 xcall_receive_signal:
        wr              %g0, (1 << PIL_SMP_RECEIVE_SIGNAL), %set_softint
index b00a95741d4115339db192cddf54a7ba1b977ab7..37dd097c16c07131282b8ddd484d52e1cb6fd369 100644 (file)
@@ -45,12 +45,20 @@ typedef void (*exitcall_t)(void);
 # define __section(S) __attribute__ ((__section__(#S)))
 #endif
 
+#if __GNUC__ == 3
+
 #if __GNUC_MINOR__ >= 3
 # define __used                        __attribute__((__used__))
 #else
 # define __used                        __attribute__((__unused__))
 #endif
 
+#else
+#if __GNUC__ == 4
+# define __used                        __attribute__((__used__))
+#endif
+#endif
+
 #else
 #include <linux/compiler.h>
 #endif
index 96e0c2ebc3885713a5d6290f5e8eb959d0d0d36e..03980cb042916c6f37bd131c1d43553f51c8ade6 100644 (file)
@@ -447,7 +447,6 @@ config PARAVIRT_DEBUG
 
 config MEMTEST
        bool "Memtest"
-       depends on X86_64
        help
          This option adds a kernel parameter 'memtest', which allows memtest
          to be set.
index abff1b84ed5bf2e009908110a9de93cd783ca745..2c518fbc52ece13221e587ee71f11c81a4d5cec7 100644 (file)
@@ -362,10 +362,6 @@ config X86_ALIGNMENT_16
        def_bool y
        depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
 
-config X86_GOOD_APIC
-       def_bool y
-       depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 || X86_64
-
 config X86_INTEL_USERCOPY
        def_bool y
        depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2
@@ -418,4 +414,4 @@ config X86_MINIMUM_CPU_FAMILY
 
 config X86_DEBUGCTLMSR
        def_bool y
-       depends on !(M586MMX || M586TSC || M586 || M486 || M386)
+       depends on !(MK6 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486 || M386)
index ae36bfa814e5b389d706b9cc3fa1d879f16abe8b..092f019e033a7a42d65b9d9297c02435c45347d0 100644 (file)
@@ -5,13 +5,15 @@ config TRACE_IRQFLAGS_SUPPORT
 
 source "lib/Kconfig.debug"
 
-config NONPROMISC_DEVMEM
+config STRICT_DEVMEM
        bool "Filter access to /dev/mem"
        help
-         If this option is left off, you allow userspace access to all
+         If this option is disabled, you allow userspace (root) access to all
          of memory, including kernel and userspace memory. Accidental
          access to this is obviously disastrous, but specific access can
-         be used by people debugging the kernel.
+         be used by people debugging the kernel. Note that with PAT support
+         enabled, even in this case there are restrictions on /dev/mem
+         use due to the cache aliasing requirements.
 
          If this option is switched on, the /dev/mem file only allows
          userspace access to PCI space and the BIOS code and data regions.
@@ -287,7 +289,6 @@ config CPA_DEBUG
 
 config OPTIMIZE_INLINING
        bool "Allow gcc to uninline functions marked 'inline'"
-       depends on BROKEN
        help
          This option determines if the kernel forces gcc to inline the functions
          developers have marked 'inline'. Doing so takes away freedom from gcc to
@@ -298,5 +299,7 @@ config OPTIMIZE_INLINING
          become the default in the future, until then this option is there to
          test gcc for this.
 
+         If unsure, say N.
+
 endmenu
 
index 03399d64013b21459f63942c06bc6c33b803f425..d93cbc6464d0f8aa8aed3479b1b88a66993afa67 100644 (file)
@@ -167,9 +167,8 @@ void query_edd(void)
                 * Scan the BIOS-supported hard disks and query EDD
                 * information...
                 */
-               get_edd_info(devno, &ei);
-
-               if (boot_params.eddbuf_entries < EDDMAXNR) {
+               if (!get_edd_info(devno, &ei)
+                   && boot_params.eddbuf_entries < EDDMAXNR) {
                        memcpy(edp, &ei, sizeof ei);
                        edp++;
                        boot_params.eddbuf_entries++;
index 328956fdb59e79dc354e96f47e98c5cb5dff4a6b..85a1cd8a8ff8a4daee99ee11d86176bd7a97c166 100644 (file)
@@ -98,12 +98,6 @@ static void reset_coprocessor(void)
 /*
  * Set up the GDT
  */
-#define GDT_ENTRY(flags, base, limit)          \
-       (((u64)(base & 0xff000000) << 32) |     \
-        ((u64)flags << 40) |                   \
-        ((u64)(limit & 0x00ff0000) << 32) |    \
-        ((u64)(base & 0x00ffffff) << 16) |     \
-        ((u64)(limit & 0x0000ffff)))
 
 struct gdt_ptr {
        u16 len;
index 9bc34e2033ecf9ec0518f59210449a07414ad5a1..4d73f53287b6acf795c5cdf1ae5197b37f04bfab 100644 (file)
@@ -2047,7 +2047,7 @@ CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
 # CONFIG_SAMPLES is not set
 # CONFIG_KGDB is not set
 CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_NONPROMISC_DEVMEM is not set
+# CONFIG_STRICT_DEVMEM is not set
 CONFIG_EARLY_PRINTK=y
 CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DEBUG_STACK_USAGE=y
index ae5124e064d4c881b0d5fa56f0826cdb00c7d8c4..a4045242962552c3c39558c32a68dddfbf867210 100644 (file)
@@ -2012,7 +2012,7 @@ CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
 # CONFIG_SAMPLES is not set
 # CONFIG_KGDB is not set
 CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_NONPROMISC_DEVMEM is not set
+# CONFIG_STRICT_DEVMEM is not set
 CONFIG_EARLY_PRINTK=y
 CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DEBUG_STACK_USAGE=y
index cb3856a18c8544e1ffe722d33a7713439043829d..20af4c79579a88ce1da6860e774c7440bc793b56 100644 (file)
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
+#define FIX_EFLAGS     (X86_EFLAGS_AC | X86_EFLAGS_OF | \
+                        X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \
+                        X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \
+                        X86_EFLAGS_CF)
+
 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
 
@@ -248,7 +253,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
        regs->ss |= 3;
 
        err |= __get_user(tmpflags, &sc->flags);
-       regs->flags = (regs->flags & ~0x40DD5) | (tmpflags & 0x40DD5);
+       regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
        /* disable syscall checks */
        regs->orig_ax = -1;
 
@@ -515,7 +520,6 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                        compat_sigset_t *set, struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
-       struct exec_domain *ed = current_thread_info()->exec_domain;
        void __user *restorer;
        int err = 0;
 
@@ -538,8 +542,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                goto give_sigsegv;
 
-       err |= __put_user((ed && ed->signal_invmap && sig < 32
-                          ? ed->signal_invmap[sig] : sig), &frame->sig);
+       err |= __put_user(sig, &frame->sig);
        err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
        err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
        err |= copy_siginfo_to_user32(&frame->info, info);
index 20371d0635e44975850ea37b5a8a03a2f52f0d58..23d146ce676bc0e1b8c6b65ead1e2971479e1708 100644 (file)
        movq    %rax,R8(%rsp)
        .endm
 
+       /*
+        * Reload arg registers from stack in case ptrace changed them.
+        * We don't reload %eax because syscall_trace_enter() returned
+        * the value it wants us to use in the table lookup.
+        */
        .macro LOAD_ARGS32 offset
        movl \offset(%rsp),%r11d
        movl \offset+8(%rsp),%r10d
@@ -46,7 +51,6 @@
        movl \offset+48(%rsp),%edx
        movl \offset+56(%rsp),%esi
        movl \offset+64(%rsp),%edi
-       movl \offset+72(%rsp),%eax
        .endm
        
        .macro CFI_STARTPROC32 simple
@@ -137,13 +141,12 @@ ENTRY(ia32_sysenter_target)
        .previous       
        GET_THREAD_INFO(%r10)
        orl    $TS_COMPAT,TI_status(%r10)
-       testl  $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP), \
-                TI_flags(%r10)
+       testl  $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
        CFI_REMEMBER_STATE
        jnz  sysenter_tracesys
-sysenter_do_call:      
        cmpl    $(IA32_NR_syscalls-1),%eax
        ja      ia32_badsys
+sysenter_do_call:
        IA32_ARG_FIXUP 1
        call    *ia32_sys_call_table(,%rax,8)
        movq    %rax,RAX-ARGOFFSET(%rsp)
@@ -242,8 +245,7 @@ ENTRY(ia32_cstar_target)
        .previous       
        GET_THREAD_INFO(%r10)
        orl   $TS_COMPAT,TI_status(%r10)
-       testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP), \
-               TI_flags(%r10)
+       testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
        CFI_REMEMBER_STATE
        jnz   cstar_tracesys
 cstar_do_call: 
@@ -321,6 +323,7 @@ ENTRY(ia32_syscall)
        /*CFI_REL_OFFSET        rflags,EFLAGS-RIP*/
        /*CFI_REL_OFFSET        cs,CS-RIP*/
        CFI_REL_OFFSET  rip,RIP-RIP
+       PARAVIRT_ADJUST_EXCEPTION_FRAME
        SWAPGS
        /*
         * No need to follow this irqs on/off section: the syscall
@@ -336,8 +339,7 @@ ENTRY(ia32_syscall)
        SAVE_ARGS 0,0,1
        GET_THREAD_INFO(%r10)
        orl   $TS_COMPAT,TI_status(%r10)
-       testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP), \
-               TI_flags(%r10)
+       testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10)
        jnz ia32_tracesys
 ia32_do_syscall:       
        cmpl $(IA32_NR_syscalls-1),%eax
index da140611bb57593ed401a5de6ee63a84cc408349..3db651fc8ec5828468355151fae160ae65b7a267 100644 (file)
@@ -7,9 +7,10 @@ extra-y                := head_$(BITS).o head$(BITS).o head.o init_task.o vmlinu
 CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE)
 
 ifdef CONFIG_FTRACE
-# Do not profile debug utilities
+# Do not profile debug and lowlevel utilities
 CFLAGS_REMOVE_tsc.o = -pg
 CFLAGS_REMOVE_rtc.o = -pg
+CFLAGS_REMOVE_paravirt.o = -pg
 endif
 
 #
@@ -102,6 +103,7 @@ obj-$(CONFIG_OLPC)          += olpc.o
 # 64 bit specific files
 ifeq ($(CONFIG_X86_64),y)
         obj-y                          += genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o
+       obj-y                           += bios_uv.o
         obj-$(CONFIG_X86_PM_TIMER)     += pmtimer_64.o
         obj-$(CONFIG_AUDIT)            += audit_64.o
 
index f489d7a9be92ffd00c662c4b18554637e4311406..fa88a1d7129094fcc85b1b2425234a80e2418581 100644 (file)
@@ -1021,7 +1021,7 @@ void __init mp_config_acpi_legacy_irqs(void)
        mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA;
 #endif
        set_bit(MP_ISA_BUS, mp_bus_not_pci);
-       Dprintk("Bus #%d is ISA\n", MP_ISA_BUS);
+       pr_debug("Bus #%d is ISA\n", MP_ISA_BUS);
 
 #ifdef CONFIG_X86_ES7000
        /*
@@ -1127,8 +1127,8 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
                return gsi;
        }
        if (test_bit(ioapic_pin, mp_ioapic_routing[ioapic].pin_programmed)) {
-               Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
-                       mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
+               pr_debug(KERN_DEBUG "Pin %d-%d already programmed\n",
+                        mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
 #ifdef CONFIG_X86_32
                return (gsi < IRQ_COMPRESSION_START ? gsi : gsi_to_irq[gsi]);
 #else
index 868de3d5c39de9144bfc42574bcb8dd0d24cca3e..a3ddad18aaa35b37c5344c4080b59d3a46c99021 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/bootmem.h>
 #include <linux/dmi.h>
 #include <linux/cpumask.h>
+#include <asm/segment.h>
 
 #include "realmode/wakeup.h"
 #include "sleep.h"
@@ -23,15 +24,6 @@ static unsigned long acpi_realmode;
 static char temp_stack[10240];
 #endif
 
-/* XXX: this macro should move to asm-x86/segment.h and be shared with the
-   boot code... */
-#define GDT_ENTRY(flags, base, limit)          \
-       (((u64)(base & 0xff000000) << 32) |     \
-        ((u64)flags << 40) |                   \
-        ((u64)(limit & 0x00ff0000) << 32) |    \
-        ((u64)(base & 0x00ffffff) << 16) |     \
-        ((u64)(limit & 0x0000ffff)))
-
 /**
  * acpi_save_state_mem - save kernel state
  *
index f2766d84c7a00c78c4f24951a7f2912f550ef475..c25210e6ac888e94224b460e6eb82f3c556d7616 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/scatterlist.h>
 #include <linux/iommu-helper.h>
 #include <asm/proto.h>
-#include <asm/gart.h>
+#include <asm/iommu.h>
 #include <asm/amd_iommu_types.h>
 #include <asm/amd_iommu.h>
 
 #define to_pages(addr, size) \
         (round_up(((addr) & ~PAGE_MASK) + (size), PAGE_SIZE) >> PAGE_SHIFT)
 
+#define EXIT_LOOP_COUNT 10000000
+
 static DEFINE_RWLOCK(amd_iommu_devtable_lock);
 
-struct command {
+/*
+ * general struct to manage commands send to an IOMMU
+ */
+struct iommu_cmd {
        u32 data[4];
 };
 
 static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
                             struct unity_map_entry *e);
 
+/* returns !0 if the IOMMU is caching non-present entries in its TLB */
 static int iommu_has_npcache(struct amd_iommu *iommu)
 {
        return iommu->cap & IOMMU_CAP_NPCACHE;
 }
 
-static int __iommu_queue_command(struct amd_iommu *iommu, struct command *cmd)
+/****************************************************************************
+ *
+ * IOMMU command queuing functions
+ *
+ ****************************************************************************/
+
+/*
+ * Writes the command to the IOMMUs command buffer and informs the
+ * hardware about the new command. Must be called with iommu->lock held.
+ */
+static int __iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
 {
        u32 tail, head;
        u8 *target;
@@ -63,7 +79,11 @@ static int __iommu_queue_command(struct amd_iommu *iommu, struct command *cmd)
        return 0;
 }
 
-static int iommu_queue_command(struct amd_iommu *iommu, struct command *cmd)
+/*
+ * General queuing function for commands. Takes iommu->lock and calls
+ * __iommu_queue_command().
+ */
+static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
 {
        unsigned long flags;
        int ret;
@@ -75,16 +95,24 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct command *cmd)
        return ret;
 }
 
+/*
+ * This function is called whenever we need to ensure that the IOMMU has
+ * completed execution of all commands we sent. It sends a
+ * COMPLETION_WAIT command and waits for it to finish. The IOMMU informs
+ * us about that by writing a value to a physical address we pass with
+ * the command.
+ */
 static int iommu_completion_wait(struct amd_iommu *iommu)
 {
        int ret;
-       struct command cmd;
+       struct iommu_cmd cmd;
        volatile u64 ready = 0;
        unsigned long ready_phys = virt_to_phys(&ready);
+       unsigned long i = 0;
 
        memset(&cmd, 0, sizeof(cmd));
        cmd.data[0] = LOW_U32(ready_phys) | CMD_COMPL_WAIT_STORE_MASK;
-       cmd.data[1] = HIGH_U32(ready_phys);
+       cmd.data[1] = upper_32_bits(ready_phys);
        cmd.data[2] = 1; /* value written to 'ready' */
        CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT);
 
@@ -95,15 +123,23 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
        if (ret)
                return ret;
 
-       while (!ready)
+       while (!ready && (i < EXIT_LOOP_COUNT)) {
+               ++i;
                cpu_relax();
+       }
+
+       if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit()))
+               printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n");
 
        return 0;
 }
 
+/*
+ * Command send function for invalidating a device table entry
+ */
 static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid)
 {
-       struct command cmd;
+       struct iommu_cmd cmd;
 
        BUG_ON(iommu == NULL);
 
@@ -116,20 +152,23 @@ static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid)
        return iommu_queue_command(iommu, &cmd);
 }
 
+/*
+ * Generic command send function for invalidaing TLB entries
+ */
 static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu,
                u64 address, u16 domid, int pde, int s)
 {
-       struct command cmd;
+       struct iommu_cmd cmd;
 
        memset(&cmd, 0, sizeof(cmd));
        address &= PAGE_MASK;
        CMD_SET_TYPE(&cmd, CMD_INV_IOMMU_PAGES);
        cmd.data[1] |= domid;
        cmd.data[2] = LOW_U32(address);
-       cmd.data[3] = HIGH_U32(address);
-       if (s)
+       cmd.data[3] = upper_32_bits(address);
+       if (s) /* size bit - we flush more than one 4kb page */
                cmd.data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
-       if (pde)
+       if (pde) /* PDE bit - we wan't flush everything not only the PTEs */
                cmd.data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;
 
        iommu->need_sync = 1;
@@ -137,6 +176,11 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu,
        return iommu_queue_command(iommu, &cmd);
 }
 
+/*
+ * TLB invalidation function which is called from the mapping functions.
+ * It invalidates a single PTE if the range to flush is within a single
+ * page. Otherwise it flushes the whole TLB of the IOMMU.
+ */
 static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid,
                u64 address, size_t size)
 {
@@ -159,6 +203,20 @@ static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid,
        return 0;
 }
 
+/****************************************************************************
+ *
+ * The functions below are used the create the page table mappings for
+ * unity mapped regions.
+ *
+ ****************************************************************************/
+
+/*
+ * Generic mapping functions. It maps a physical address into a DMA
+ * address space. It allocates the page table pages if necessary.
+ * In the future it can be extended to a generic mapping function
+ * supporting all features of AMD IOMMU page tables like level skipping
+ * and full 64 bit address spaces.
+ */
 static int iommu_map(struct protection_domain *dom,
                     unsigned long bus_addr,
                     unsigned long phys_addr,
@@ -209,6 +267,10 @@ static int iommu_map(struct protection_domain *dom,
        return 0;
 }
 
+/*
+ * This function checks if a specific unity mapping entry is needed for
+ * this specific IOMMU.
+ */
 static int iommu_for_unity_map(struct amd_iommu *iommu,
                               struct unity_map_entry *entry)
 {
@@ -223,6 +285,12 @@ static int iommu_for_unity_map(struct amd_iommu *iommu,
        return 0;
 }
 
+/*
+ * Init the unity mappings for a specific IOMMU in the system
+ *
+ * Basically iterates over all unity mapping entries and applies them to
+ * the default domain DMA of that IOMMU if necessary.
+ */
 static int iommu_init_unity_mappings(struct amd_iommu *iommu)
 {
        struct unity_map_entry *entry;
@@ -239,6 +307,10 @@ static int iommu_init_unity_mappings(struct amd_iommu *iommu)
        return 0;
 }
 
+/*
+ * This function actually applies the mapping to the page table of the
+ * dma_ops domain.
+ */
 static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
                             struct unity_map_entry *e)
 {
@@ -261,6 +333,9 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
        return 0;
 }
 
+/*
+ * Inits the unity mappings required for a specific device
+ */
 static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom,
                                          u16 devid)
 {
@@ -278,12 +353,26 @@ static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom,
        return 0;
 }
 
+/****************************************************************************
+ *
+ * The next functions belong to the address allocator for the dma_ops
+ * interface functions. They work like the allocators in the other IOMMU
+ * drivers. Its basically a bitmap which marks the allocated pages in
+ * the aperture. Maybe it could be enhanced in the future to a more
+ * efficient allocator.
+ *
+ ****************************************************************************/
 static unsigned long dma_mask_to_pages(unsigned long mask)
 {
        return (mask >> PAGE_SHIFT) +
                (PAGE_ALIGN(mask & ~PAGE_MASK) >> PAGE_SHIFT);
 }
 
+/*
+ * The address allocator core function.
+ *
+ * called with domain->lock held
+ */
 static unsigned long dma_ops_alloc_addresses(struct device *dev,
                                             struct dma_ops_domain *dom,
                                             unsigned int pages)
@@ -317,6 +406,11 @@ static unsigned long dma_ops_alloc_addresses(struct device *dev,
        return address;
 }
 
+/*
+ * The address free function.
+ *
+ * called with domain->lock held
+ */
 static void dma_ops_free_addresses(struct dma_ops_domain *dom,
                                   unsigned long address,
                                   unsigned int pages)
@@ -325,6 +419,16 @@ static void dma_ops_free_addresses(struct dma_ops_domain *dom,
        iommu_area_free(dom->bitmap, address, pages);
 }
 
+/****************************************************************************
+ *
+ * The next functions belong to the domain allocation. A domain is
+ * allocated for every IOMMU as the default domain. If device isolation
+ * is enabled, every device get its own domain. The most important thing
+ * about domains is the page table mapping the DMA address space they
+ * contain.
+ *
+ ****************************************************************************/
+
 static u16 domain_id_alloc(void)
 {
        unsigned long flags;
@@ -342,6 +446,10 @@ static u16 domain_id_alloc(void)
        return id;
 }
 
+/*
+ * Used to reserve address ranges in the aperture (e.g. for exclusion
+ * ranges.
+ */
 static void dma_ops_reserve_addresses(struct dma_ops_domain *dom,
                                      unsigned long start_page,
                                      unsigned int pages)
@@ -382,6 +490,10 @@ static void dma_ops_free_pagetable(struct dma_ops_domain *dma_dom)
        free_page((unsigned long)p1);
 }
 
+/*
+ * Free a domain, only used if something went wrong in the
+ * allocation path and we need to free an already allocated page table
+ */
 static void dma_ops_domain_free(struct dma_ops_domain *dom)
 {
        if (!dom)
@@ -396,6 +508,11 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom)
        kfree(dom);
 }
 
+/*
+ * Allocates a new protection domain usable for the dma_ops functions.
+ * It also intializes the page table and the address allocator data
+ * structures required for the dma_ops interface
+ */
 static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu,
                                                   unsigned order)
 {
@@ -436,6 +553,7 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu,
        dma_dom->bitmap[0] = 1;
        dma_dom->next_bit = 0;
 
+       /* Intialize the exclusion range if necessary */
        if (iommu->exclusion_start &&
            iommu->exclusion_start < dma_dom->aperture_size) {
                unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT;
@@ -444,6 +562,11 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu,
                dma_ops_reserve_addresses(dma_dom, startpage, pages);
        }
 
+       /*
+        * At the last step, build the page tables so we don't need to
+        * allocate page table pages in the dma_ops mapping/unmapping
+        * path.
+        */
        num_pte_pages = dma_dom->aperture_size / (PAGE_SIZE * 512);
        dma_dom->pte_pages = kzalloc(num_pte_pages * sizeof(void *),
                        GFP_KERNEL);
@@ -472,6 +595,10 @@ free_dma_dom:
        return NULL;
 }
 
+/*
+ * Find out the protection domain structure for a given PCI device. This
+ * will give us the pointer to the page table root for example.
+ */
 static struct protection_domain *domain_for_device(u16 devid)
 {
        struct protection_domain *dom;
@@ -484,6 +611,10 @@ static struct protection_domain *domain_for_device(u16 devid)
        return dom;
 }
 
+/*
+ * If a device is not yet associated with a domain, this function does
+ * assigns it visible for the hardware
+ */
 static void set_device_domain(struct amd_iommu *iommu,
                              struct protection_domain *domain,
                              u16 devid)
@@ -508,6 +639,19 @@ static void set_device_domain(struct amd_iommu *iommu,
        iommu->need_sync = 1;
 }
 
+/*****************************************************************************
+ *
+ * The next functions belong to the dma_ops mapping/unmapping code.
+ *
+ *****************************************************************************/
+
+/*
+ * In the dma_ops path we only have the struct device. This function
+ * finds the corresponding IOMMU, the protection domain and the
+ * requestor id for a given device.
+ * If the device is not yet associated with a domain this is also done
+ * in this function.
+ */
 static int get_device_resources(struct device *dev,
                                struct amd_iommu **iommu,
                                struct protection_domain **domain,
@@ -520,8 +664,9 @@ static int get_device_resources(struct device *dev,
        BUG_ON(!dev || dev->bus != &pci_bus_type || !dev->dma_mask);
 
        pcidev = to_pci_dev(dev);
-       _bdf = (pcidev->bus->number << 8) | pcidev->devfn;
+       _bdf = calc_devid(pcidev->bus->number, pcidev->devfn);
 
+       /* device not translated by any IOMMU in the system? */
        if (_bdf >= amd_iommu_last_bdf) {
                *iommu = NULL;
                *domain = NULL;
@@ -547,6 +692,10 @@ static int get_device_resources(struct device *dev,
        return 1;
 }
 
+/*
+ * This is the generic map function. It maps one 4kb page at paddr to
+ * the given address in the DMA address space for the domain.
+ */
 static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu,
                                     struct dma_ops_domain *dom,
                                     unsigned long address,
@@ -578,6 +727,9 @@ static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu,
        return (dma_addr_t)address;
 }
 
+/*
+ * The generic unmapping function for on page in the DMA address space.
+ */
 static void dma_ops_domain_unmap(struct amd_iommu *iommu,
                                 struct dma_ops_domain *dom,
                                 unsigned long address)
@@ -597,6 +749,12 @@ static void dma_ops_domain_unmap(struct amd_iommu *iommu,
        *pte = 0ULL;
 }
 
+/*
+ * This function contains common code for mapping of a physically
+ * contiguous memory region into DMA address space. It is uses by all
+ * mapping functions provided by this IOMMU driver.
+ * Must be called with the domain lock held.
+ */
 static dma_addr_t __map_single(struct device *dev,
                               struct amd_iommu *iommu,
                               struct dma_ops_domain *dma_dom,
@@ -628,6 +786,10 @@ out:
        return address;
 }
 
+/*
+ * Does the reverse of the __map_single function. Must be called with
+ * the domain lock held too
+ */
 static void __unmap_single(struct amd_iommu *iommu,
                           struct dma_ops_domain *dma_dom,
                           dma_addr_t dma_addr,
@@ -652,6 +814,9 @@ static void __unmap_single(struct amd_iommu *iommu,
        dma_ops_free_addresses(dma_dom, dma_addr, pages);
 }
 
+/*
+ * The exported map_single function for dma_ops.
+ */
 static dma_addr_t map_single(struct device *dev, phys_addr_t paddr,
                             size_t size, int dir)
 {
@@ -664,6 +829,7 @@ static dma_addr_t map_single(struct device *dev, phys_addr_t paddr,
        get_device_resources(dev, &iommu, &domain, &devid);
 
        if (iommu == NULL || domain == NULL)
+               /* device not handled by any AMD IOMMU */
                return (dma_addr_t)paddr;
 
        spin_lock_irqsave(&domain->lock, flags);
@@ -683,6 +849,9 @@ out:
        return addr;
 }
 
+/*
+ * The exported unmap_single function for dma_ops.
+ */
 static void unmap_single(struct device *dev, dma_addr_t dma_addr,
                         size_t size, int dir)
 {
@@ -692,6 +861,7 @@ static void unmap_single(struct device *dev, dma_addr_t dma_addr,
        u16 devid;
 
        if (!get_device_resources(dev, &iommu, &domain, &devid))
+               /* device not handled by any AMD IOMMU */
                return;
 
        spin_lock_irqsave(&domain->lock, flags);
@@ -706,6 +876,10 @@ static void unmap_single(struct device *dev, dma_addr_t dma_addr,
        spin_unlock_irqrestore(&domain->lock, flags);
 }
 
+/*
+ * This is a special map_sg function which is used if we should map a
+ * device which is not handled by an AMD IOMMU in the system.
+ */
 static int map_sg_no_iommu(struct device *dev, struct scatterlist *sglist,
                           int nelems, int dir)
 {
@@ -720,6 +894,10 @@ static int map_sg_no_iommu(struct device *dev, struct scatterlist *sglist,
        return nelems;
 }
 
+/*
+ * The exported map_sg function for dma_ops (handles scatter-gather
+ * lists).
+ */
 static int map_sg(struct device *dev, struct scatterlist *sglist,
                  int nelems, int dir)
 {
@@ -775,6 +953,10 @@ unmap:
        goto out;
 }
 
+/*
+ * The exported map_sg function for dma_ops (handles scatter-gather
+ * lists).
+ */
 static void unmap_sg(struct device *dev, struct scatterlist *sglist,
                     int nelems, int dir)
 {
@@ -804,6 +986,9 @@ static void unmap_sg(struct device *dev, struct scatterlist *sglist,
        spin_unlock_irqrestore(&domain->lock, flags);
 }
 
+/*
+ * The exported alloc_coherent function for dma_ops.
+ */
 static void *alloc_coherent(struct device *dev, size_t size,
                            dma_addr_t *dma_addr, gfp_t flag)
 {
@@ -851,6 +1036,11 @@ out:
        return virt_addr;
 }
 
+/*
+ * The exported free_coherent function for dma_ops.
+ * FIXME: fix the generic x86 DMA layer so that it actually calls that
+ *        function.
+ */
 static void free_coherent(struct device *dev, size_t size,
                          void *virt_addr, dma_addr_t dma_addr)
 {
@@ -879,6 +1069,8 @@ free_mem:
 }
 
 /*
+ * The function for pre-allocating protection domains.
+ *
  * If the driver core informs the DMA layer if a driver grabs a device
  * we don't need to preallocate the protection domains anymore.
  * For now we have to.
@@ -921,12 +1113,20 @@ static struct dma_mapping_ops amd_iommu_dma_ops = {
        .unmap_sg = unmap_sg,
 };
 
+/*
+ * The function which clues the AMD IOMMU driver into dma_ops.
+ */
 int __init amd_iommu_init_dma_ops(void)
 {
        struct amd_iommu *iommu;
        int order = amd_iommu_aperture_order;
        int ret;
 
+       /*
+        * first allocate a default protection domain for every IOMMU we
+        * found in the system. Devices not assigned to any other
+        * protection domain will be assigned to the default one.
+        */
        list_for_each_entry(iommu, &amd_iommu_list, list) {
                iommu->default_dom = dma_ops_domain_alloc(iommu, order);
                if (iommu->default_dom == NULL)
@@ -936,6 +1136,10 @@ int __init amd_iommu_init_dma_ops(void)
                        goto free_domains;
        }
 
+       /*
+        * If device isolation is enabled, pre-allocate the protection
+        * domains for each device.
+        */
        if (amd_iommu_isolate)
                prealloc_protection_domains();
 
@@ -947,6 +1151,7 @@ int __init amd_iommu_init_dma_ops(void)
        gart_iommu_aperture = 0;
 #endif
 
+       /* Make the driver finally visible to the drivers */
        dma_ops = &amd_iommu_dma_ops;
 
        return 0;
index 2a13e430437dc5f1e05793aa995df4befcbc8938..c9d8ff2eb130b3ed384bc525ef13a5c4784161d7 100644 (file)
 #include <asm/pci-direct.h>
 #include <asm/amd_iommu_types.h>
 #include <asm/amd_iommu.h>
-#include <asm/gart.h>
+#include <asm/iommu.h>
 
 /*
  * definitions for the ACPI scanning code
  */
-#define UPDATE_LAST_BDF(x) do {\
-       if ((x) > amd_iommu_last_bdf) \
-               amd_iommu_last_bdf = (x); \
-       } while (0);
-
-#define DEVID(bus, devfn) (((bus) << 8) | (devfn))
 #define PCI_BUS(x) (((x) >> 8) & 0xff)
 #define IVRS_HEADER_LENGTH 48
-#define TBL_SIZE(x) (1 << (PAGE_SHIFT + get_order(amd_iommu_last_bdf * (x))))
 
 #define ACPI_IVHD_TYPE                  0x10
 #define ACPI_IVMD_TYPE_ALL              0x20
 #define ACPI_DEVFLAG_LINT1              0x80
 #define ACPI_DEVFLAG_ATSDIS             0x10000000
 
+/*
+ * ACPI table definitions
+ *
+ * These data structures are laid over the table to parse the important values
+ * out of it.
+ */
+
+/*
+ * structure describing one IOMMU in the ACPI table. Typically followed by one
+ * or more ivhd_entrys.
+ */
 struct ivhd_header {
        u8 type;
        u8 flags;
@@ -83,6 +87,10 @@ struct ivhd_header {
        u32 reserved;
 } __attribute__((packed));
 
+/*
+ * A device entry describing which devices a specific IOMMU translates and
+ * which requestor ids they use.
+ */
 struct ivhd_entry {
        u8 type;
        u16 devid;
@@ -90,6 +98,10 @@ struct ivhd_entry {
        u32 ext;
 } __attribute__((packed));
 
+/*
+ * An AMD IOMMU memory definition structure. It defines things like exclusion
+ * ranges for devices and regions that should be unity mapped.
+ */
 struct ivmd_header {
        u8 type;
        u8 flags;
@@ -103,22 +115,80 @@ struct ivmd_header {
 
 static int __initdata amd_iommu_detected;
 
-u16 amd_iommu_last_bdf;
-struct list_head amd_iommu_unity_map;
-unsigned amd_iommu_aperture_order = 26;
-int amd_iommu_isolate;
+u16 amd_iommu_last_bdf;                        /* largest PCI device id we have
+                                          to handle */
+LIST_HEAD(amd_iommu_unity_map);                /* a list of required unity mappings
+                                          we find in ACPI */
+unsigned amd_iommu_aperture_order = 26; /* size of aperture in power of 2 */
+int amd_iommu_isolate;                 /* if 1, device isolation is enabled */
+
+LIST_HEAD(amd_iommu_list);             /* list of all AMD IOMMUs in the
+                                          system */
 
-struct list_head amd_iommu_list;
+/*
+ * Pointer to the device table which is shared by all AMD IOMMUs
+ * it is indexed by the PCI device id or the HT unit id and contains
+ * information about the domain the device belongs to as well as the
+ * page table root pointer.
+ */
 struct dev_table_entry *amd_iommu_dev_table;
+
+/*
+ * The alias table is a driver specific data structure which contains the
+ * mappings of the PCI device ids to the actual requestor ids on the IOMMU.
+ * More than one device can share the same requestor id.
+ */
 u16 *amd_iommu_alias_table;
+
+/*
+ * The rlookup table is used to find the IOMMU which is responsible
+ * for a specific device. It is also indexed by the PCI device id.
+ */
 struct amd_iommu **amd_iommu_rlookup_table;
+
+/*
+ * The pd table (protection domain table) is used to find the protection domain
+ * data structure a device belongs to. Indexed with the PCI device id too.
+ */
 struct protection_domain **amd_iommu_pd_table;
+
+/*
+ * AMD IOMMU allows up to 2^16 differend protection domains. This is a bitmap
+ * to know which ones are already in use.
+ */
 unsigned long *amd_iommu_pd_alloc_bitmap;
 
-static u32 dev_table_size;
-static u32 alias_table_size;
-static u32 rlookup_table_size;
+static u32 dev_table_size;     /* size of the device table */
+static u32 alias_table_size;   /* size of the alias table */
+static u32 rlookup_table_size; /* size if the rlookup table */
 
+static inline void update_last_devid(u16 devid)
+{
+       if (devid > amd_iommu_last_bdf)
+               amd_iommu_last_bdf = devid;
+}
+
+static inline unsigned long tbl_size(int entry_size)
+{
+       unsigned shift = PAGE_SHIFT +
+                        get_order(amd_iommu_last_bdf * entry_size);
+
+       return 1UL << shift;
+}
+
+/****************************************************************************
+ *
+ * AMD IOMMU MMIO register space handling functions
+ *
+ * These functions are used to program the IOMMU device registers in
+ * MMIO space required for that driver.
+ *
+ ****************************************************************************/
+
+/*
+ * This function set the exclusion range in the IOMMU. DMA accesses to the
+ * exclusion range are passed through untranslated
+ */
 static void __init iommu_set_exclusion_range(struct amd_iommu *iommu)
 {
        u64 start = iommu->exclusion_start & PAGE_MASK;
@@ -137,6 +207,7 @@ static void __init iommu_set_exclusion_range(struct amd_iommu *iommu)
                        &entry, sizeof(entry));
 }
 
+/* Programs the physical address of the device table into the IOMMU hardware */
 static void __init iommu_set_device_table(struct amd_iommu *iommu)
 {
        u32 entry;
@@ -149,6 +220,7 @@ static void __init iommu_set_device_table(struct amd_iommu *iommu)
                        &entry, sizeof(entry));
 }
 
+/* Generic functions to enable/disable certain features of the IOMMU. */
 static void __init iommu_feature_enable(struct amd_iommu *iommu, u8 bit)
 {
        u32 ctrl;
@@ -167,6 +239,7 @@ static void __init iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
        writel(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
 }
 
+/* Function to enable the hardware */
 void __init iommu_enable(struct amd_iommu *iommu)
 {
        printk(KERN_INFO "AMD IOMMU: Enabling IOMMU at ");
@@ -176,6 +249,10 @@ void __init iommu_enable(struct amd_iommu *iommu)
        iommu_feature_enable(iommu, CONTROL_IOMMU_EN);
 }
 
+/*
+ * mapping and unmapping functions for the IOMMU MMIO space. Each AMD IOMMU in
+ * the system has one.
+ */
 static u8 * __init iommu_map_mmio_space(u64 address)
 {
        u8 *ret;
@@ -199,16 +276,33 @@ static void __init iommu_unmap_mmio_space(struct amd_iommu *iommu)
        release_mem_region(iommu->mmio_phys, MMIO_REGION_LENGTH);
 }
 
+/****************************************************************************
+ *
+ * The functions below belong to the first pass of AMD IOMMU ACPI table
+ * parsing. In this pass we try to find out the highest device id this
+ * code has to handle. Upon this information the size of the shared data
+ * structures is determined later.
+ *
+ ****************************************************************************/
+
+/*
+ * This function reads the last device id the IOMMU has to handle from the PCI
+ * capability header for this IOMMU
+ */
 static int __init find_last_devid_on_pci(int bus, int dev, int fn, int cap_ptr)
 {
        u32 cap;
 
        cap = read_pci_config(bus, dev, fn, cap_ptr+MMIO_RANGE_OFFSET);
-       UPDATE_LAST_BDF(DEVID(MMIO_GET_BUS(cap), MMIO_GET_LD(cap)));
+       update_last_devid(calc_devid(MMIO_GET_BUS(cap), MMIO_GET_LD(cap)));
 
        return 0;
 }
 
+/*
+ * After reading the highest device id from the IOMMU PCI capability header
+ * this function looks if there is a higher device id defined in the ACPI table
+ */
 static int __init find_last_devid_from_ivhd(struct ivhd_header *h)
 {
        u8 *p = (void *)h, *end = (void *)h;
@@ -229,7 +323,8 @@ static int __init find_last_devid_from_ivhd(struct ivhd_header *h)
                case IVHD_DEV_RANGE_END:
                case IVHD_DEV_ALIAS:
                case IVHD_DEV_EXT_SELECT:
-                       UPDATE_LAST_BDF(dev->devid);
+                       /* all the above subfield types refer to device ids */
+                       update_last_devid(dev->devid);
                        break;
                default:
                        break;
@@ -242,6 +337,11 @@ static int __init find_last_devid_from_ivhd(struct ivhd_header *h)
        return 0;
 }
 
+/*
+ * Iterate over all IVHD entries in the ACPI table and find the highest device
+ * id which we need to handle. This is the first of three functions which parse
+ * the ACPI table. So we check the checksum here.
+ */
 static int __init find_last_devid_acpi(struct acpi_table_header *table)
 {
        int i;
@@ -277,19 +377,31 @@ static int __init find_last_devid_acpi(struct acpi_table_header *table)
        return 0;
 }
 
+/****************************************************************************
+ *
+ * The following functions belong the the code path which parses the ACPI table
+ * the second time. In this ACPI parsing iteration we allocate IOMMU specific
+ * data structures, initialize the device/alias/rlookup table and also
+ * basically initialize the hardware.
+ *
+ ****************************************************************************/
+
+/*
+ * Allocates the command buffer. This buffer is per AMD IOMMU. We can
+ * write commands to that buffer later and the IOMMU will execute them
+ * asynchronously
+ */
 static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)
 {
-       u8 *cmd_buf = (u8 *)__get_free_pages(GFP_KERNEL,
+       u8 *cmd_buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
                        get_order(CMD_BUFFER_SIZE));
-       u64 entry = 0;
+       u64 entry;
 
        if (cmd_buf == NULL)
                return NULL;
 
        iommu->cmd_buf_size = CMD_BUFFER_SIZE;
 
-       memset(cmd_buf, 0, CMD_BUFFER_SIZE);
-
        entry = (u64)virt_to_phys(cmd_buf);
        entry |= MMIO_CMD_SIZE_512;
        memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET,
@@ -302,11 +414,10 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)
 
 static void __init free_command_buffer(struct amd_iommu *iommu)
 {
-       if (iommu->cmd_buf)
-               free_pages((unsigned long)iommu->cmd_buf,
-                               get_order(CMD_BUFFER_SIZE));
+       free_pages((unsigned long)iommu->cmd_buf, get_order(CMD_BUFFER_SIZE));
 }
 
+/* sets a specific bit in the device table entry. */
 static void set_dev_entry_bit(u16 devid, u8 bit)
 {
        int i = (bit >> 5) & 0x07;
@@ -315,7 +426,18 @@ static void set_dev_entry_bit(u16 devid, u8 bit)
        amd_iommu_dev_table[devid].data[i] |= (1 << _bit);
 }
 
-static void __init set_dev_entry_from_acpi(u16 devid, u32 flags, u32 ext_flags)
+/* Writes the specific IOMMU for a device into the rlookup table */
+static void __init set_iommu_for_device(struct amd_iommu *iommu, u16 devid)
+{
+       amd_iommu_rlookup_table[devid] = iommu;
+}
+
+/*
+ * This function takes the device specific flags read from the ACPI
+ * table and sets up the device table entry with that information
+ */
+static void __init set_dev_entry_from_acpi(struct amd_iommu *iommu,
+                                          u16 devid, u32 flags, u32 ext_flags)
 {
        if (flags & ACPI_DEVFLAG_INITPASS)
                set_dev_entry_bit(devid, DEV_ENTRY_INIT_PASS);
@@ -331,13 +453,14 @@ static void __init set_dev_entry_from_acpi(u16 devid, u32 flags, u32 ext_flags)
                set_dev_entry_bit(devid, DEV_ENTRY_LINT0_PASS);
        if (flags & ACPI_DEVFLAG_LINT1)
                set_dev_entry_bit(devid, DEV_ENTRY_LINT1_PASS);
-}
 
-static void __init set_iommu_for_device(struct amd_iommu *iommu, u16 devid)
-{
-       amd_iommu_rlookup_table[devid] = iommu;
+       set_iommu_for_device(iommu, devid);
 }
 
+/*
+ * Reads the device exclusion range from ACPI and initialize IOMMU with
+ * it
+ */
 static void __init set_device_exclusion_range(u16 devid, struct ivmd_header *m)
 {
        struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
@@ -346,12 +469,22 @@ static void __init set_device_exclusion_range(u16 devid, struct ivmd_header *m)
                return;
 
        if (iommu) {
+               /*
+                * We only can configure exclusion ranges per IOMMU, not
+                * per device. But we can enable the exclusion range per
+                * device. This is done here
+                */
                set_dev_entry_bit(m->devid, DEV_ENTRY_EX);
                iommu->exclusion_start = m->range_start;
                iommu->exclusion_length = m->range_length;
        }
 }
 
+/*
+ * This function reads some important data from the IOMMU PCI space and
+ * initializes the driver data structure with it. It reads the hardware
+ * capabilities and the first/last device entries
+ */
 static void __init init_iommu_from_pci(struct amd_iommu *iommu)
 {
        int bus = PCI_BUS(iommu->devid);
@@ -363,10 +496,16 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu)
        iommu->cap = read_pci_config(bus, dev, fn, cap_ptr+MMIO_CAP_HDR_OFFSET);
 
        range = read_pci_config(bus, dev, fn, cap_ptr+MMIO_RANGE_OFFSET);
-       iommu->first_device = DEVID(MMIO_GET_BUS(range), MMIO_GET_FD(range));
-       iommu->last_device = DEVID(MMIO_GET_BUS(range), MMIO_GET_LD(range));
+       iommu->first_device = calc_devid(MMIO_GET_BUS(range),
+                                        MMIO_GET_FD(range));
+       iommu->last_device = calc_devid(MMIO_GET_BUS(range),
+                                       MMIO_GET_LD(range));
 }
 
+/*
+ * Takes a pointer to an AMD IOMMU entry in the ACPI table and
+ * initializes the hardware and our data structures with it.
+ */
 static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
                                        struct ivhd_header *h)
 {
@@ -374,7 +513,7 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
        u8 *end = p, flags = 0;
        u16 dev_i, devid = 0, devid_start = 0, devid_to = 0;
        u32 ext_flags = 0;
-       bool alias = 0;
+       bool alias = false;
        struct ivhd_entry *e;
 
        /*
@@ -414,22 +553,23 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
                case IVHD_DEV_ALL:
                        for (dev_i = iommu->first_device;
                                        dev_i <= iommu->last_device; ++dev_i)
-                               set_dev_entry_from_acpi(dev_i, e->flags, 0);
+                               set_dev_entry_from_acpi(iommu, dev_i,
+                                                       e->flags, 0);
                        break;
                case IVHD_DEV_SELECT:
                        devid = e->devid;
-                       set_dev_entry_from_acpi(devid, e->flags, 0);
+                       set_dev_entry_from_acpi(iommu, devid, e->flags, 0);
                        break;
                case IVHD_DEV_SELECT_RANGE_START:
                        devid_start = e->devid;
                        flags = e->flags;
                        ext_flags = 0;
-                       alias = 0;
+                       alias = false;
                        break;
                case IVHD_DEV_ALIAS:
                        devid = e->devid;
                        devid_to = e->ext >> 8;
-                       set_dev_entry_from_acpi(devid, e->flags, 0);
+                       set_dev_entry_from_acpi(iommu, devid, e->flags, 0);
                        amd_iommu_alias_table[devid] = devid_to;
                        break;
                case IVHD_DEV_ALIAS_RANGE:
@@ -437,24 +577,25 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
                        flags = e->flags;
                        devid_to = e->ext >> 8;
                        ext_flags = 0;
-                       alias = 1;
+                       alias = true;
                        break;
                case IVHD_DEV_EXT_SELECT:
                        devid = e->devid;
-                       set_dev_entry_from_acpi(devid, e->flags, e->ext);
+                       set_dev_entry_from_acpi(iommu, devid, e->flags,
+                                               e->ext);
                        break;
                case IVHD_DEV_EXT_SELECT_RANGE:
                        devid_start = e->devid;
                        flags = e->flags;
                        ext_flags = e->ext;
-                       alias = 0;
+                       alias = false;
                        break;
                case IVHD_DEV_RANGE_END:
                        devid = e->devid;
                        for (dev_i = devid_start; dev_i <= devid; ++dev_i) {
                                if (alias)
                                        amd_iommu_alias_table[dev_i] = devid_to;
-                               set_dev_entry_from_acpi(
+                               set_dev_entry_from_acpi(iommu,
                                                amd_iommu_alias_table[dev_i],
                                                flags, ext_flags);
                        }
@@ -467,6 +608,7 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
        }
 }
 
+/* Initializes the device->iommu mapping for the driver */
 static int __init init_iommu_devices(struct amd_iommu *iommu)
 {
        u16 i;
@@ -494,6 +636,11 @@ static void __init free_iommu_all(void)
        }
 }
 
+/*
+ * This function clues the initialization function for one IOMMU
+ * together and also allocates the command buffer and programs the
+ * hardware. It does NOT enable the IOMMU. This is done afterwards.
+ */
 static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
 {
        spin_lock_init(&iommu->lock);
@@ -521,6 +668,10 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
        return 0;
 }
 
+/*
+ * Iterates over all IOMMU entries in the ACPI table, allocates the
+ * IOMMU structure and initializes it with init_iommu_one()
+ */
 static int __init init_iommu_all(struct acpi_table_header *table)
 {
        u8 *p = (u8 *)table, *end = (u8 *)table;
@@ -528,8 +679,6 @@ static int __init init_iommu_all(struct acpi_table_header *table)
        struct amd_iommu *iommu;
        int ret;
 
-       INIT_LIST_HEAD(&amd_iommu_list);
-
        end += table->length;
        p += IVRS_HEADER_LENGTH;
 
@@ -555,6 +704,14 @@ static int __init init_iommu_all(struct acpi_table_header *table)
        return 0;
 }
 
+/****************************************************************************
+ *
+ * The next functions belong to the third pass of parsing the ACPI
+ * table. In this last pass the memory mapping requirements are
+ * gathered (like exclusion and unity mapping reanges).
+ *
+ ****************************************************************************/
+
 static void __init free_unity_maps(void)
 {
        struct unity_map_entry *entry, *next;
@@ -565,6 +722,7 @@ static void __init free_unity_maps(void)
        }
 }
 
+/* called when we find an exclusion range definition in ACPI */
 static int __init init_exclusion_range(struct ivmd_header *m)
 {
        int i;
@@ -588,6 +746,7 @@ static int __init init_exclusion_range(struct ivmd_header *m)
        return 0;
 }
 
+/* called for unity map ACPI definition */
 static int __init init_unity_map_range(struct ivmd_header *m)
 {
        struct unity_map_entry *e = 0;
@@ -619,13 +778,12 @@ static int __init init_unity_map_range(struct ivmd_header *m)
        return 0;
 }
 
+/* iterates over all memory definitions we find in the ACPI table */
 static int __init init_memory_definitions(struct acpi_table_header *table)
 {
        u8 *p = (u8 *)table, *end = (u8 *)table;
        struct ivmd_header *m;
 
-       INIT_LIST_HEAD(&amd_iommu_unity_map);
-
        end += table->length;
        p += IVRS_HEADER_LENGTH;
 
@@ -642,6 +800,10 @@ static int __init init_memory_definitions(struct acpi_table_header *table)
        return 0;
 }
 
+/*
+ * This function finally enables all IOMMUs found in the system after
+ * they have been initialized
+ */
 static void __init enable_iommus(void)
 {
        struct amd_iommu *iommu;
@@ -678,6 +840,34 @@ static struct sys_device device_amd_iommu = {
        .cls = &amd_iommu_sysdev_class,
 };
 
+/*
+ * This is the core init function for AMD IOMMU hardware in the system.
+ * This function is called from the generic x86 DMA layer initialization
+ * code.
+ *
+ * This function basically parses the ACPI table for AMD IOMMU (IVRS)
+ * three times:
+ *
+ *     1 pass) Find the highest PCI device id the driver has to handle.
+ *             Upon this information the size of the data structures is
+ *             determined that needs to be allocated.
+ *
+ *     2 pass) Initialize the data structures just allocated with the
+ *             information in the ACPI table about available AMD IOMMUs
+ *             in the system. It also maps the PCI devices in the
+ *             system to specific IOMMUs
+ *
+ *     3 pass) After the basic data structures are allocated and
+ *             initialized we update them with information about memory
+ *             remapping requirements parsed out of the ACPI table in
+ *             this last pass.
+ *
+ * After that the hardware is initialized and ready to go. In the last
+ * step we do some Linux specific things like registering the driver in
+ * the dma_ops interface and initializing the suspend/resume support
+ * functions. Finally it prints some information about AMD IOMMUs and
+ * the driver state and enables the hardware.
+ */
 int __init amd_iommu_init(void)
 {
        int i, ret = 0;
@@ -699,14 +889,14 @@ int __init amd_iommu_init(void)
        if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0)
                return -ENODEV;
 
-       dev_table_size     = TBL_SIZE(DEV_TABLE_ENTRY_SIZE);
-       alias_table_size   = TBL_SIZE(ALIAS_TABLE_ENTRY_SIZE);
-       rlookup_table_size = TBL_SIZE(RLOOKUP_TABLE_ENTRY_SIZE);
+       dev_table_size     = tbl_size(DEV_TABLE_ENTRY_SIZE);
+       alias_table_size   = tbl_size(ALIAS_TABLE_ENTRY_SIZE);
+       rlookup_table_size = tbl_size(RLOOKUP_TABLE_ENTRY_SIZE);
 
        ret = -ENOMEM;
 
        /* Device table - directly used by all IOMMUs */
-       amd_iommu_dev_table = (void *)__get_free_pages(GFP_KERNEL,
+       amd_iommu_dev_table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
                                      get_order(dev_table_size));
        if (amd_iommu_dev_table == NULL)
                goto out;
@@ -730,27 +920,23 @@ int __init amd_iommu_init(void)
         * Protection Domain table - maps devices to protection domains
         * This table has the same size as the rlookup_table
         */
-       amd_iommu_pd_table = (void *)__get_free_pages(GFP_KERNEL,
+       amd_iommu_pd_table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
                                     get_order(rlookup_table_size));
        if (amd_iommu_pd_table == NULL)
                goto free;
 
-       amd_iommu_pd_alloc_bitmap = (void *)__get_free_pages(GFP_KERNEL,
+       amd_iommu_pd_alloc_bitmap = (void *)__get_free_pages(
+                                           GFP_KERNEL | __GFP_ZERO,
                                            get_order(MAX_DOMAIN_ID/8));
        if (amd_iommu_pd_alloc_bitmap == NULL)
                goto free;
 
        /*
-        * memory is allocated now; initialize the device table with all zeroes
-        * and let all alias entries point to itself
+        * let all alias entries point to itself
         */
-       memset(amd_iommu_dev_table, 0, dev_table_size);
        for (i = 0; i < amd_iommu_last_bdf; ++i)
                amd_iommu_alias_table[i] = i;
 
-       memset(amd_iommu_pd_table, 0, rlookup_table_size);
-       memset(amd_iommu_pd_alloc_bitmap, 0, MAX_DOMAIN_ID / 8);
-
        /*
         * never allocate domain 0 because its used as the non-allocated and
         * error value placeholder
@@ -795,24 +981,19 @@ out:
        return ret;
 
 free:
-       if (amd_iommu_pd_alloc_bitmap)
-               free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, 1);
+       free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, 1);
 
-       if (amd_iommu_pd_table)
-               free_pages((unsigned long)amd_iommu_pd_table,
-                               get_order(rlookup_table_size));
+       free_pages((unsigned long)amd_iommu_pd_table,
+                  get_order(rlookup_table_size));
 
-       if (amd_iommu_rlookup_table)
-               free_pages((unsigned long)amd_iommu_rlookup_table,
-                               get_order(rlookup_table_size));
+       free_pages((unsigned long)amd_iommu_rlookup_table,
+                  get_order(rlookup_table_size));
 
-       if (amd_iommu_alias_table)
-               free_pages((unsigned long)amd_iommu_alias_table,
-                               get_order(alias_table_size));
+       free_pages((unsigned long)amd_iommu_alias_table,
+                  get_order(alias_table_size));
 
-       if (amd_iommu_dev_table)
-               free_pages((unsigned long)amd_iommu_dev_table,
-                               get_order(dev_table_size));
+       free_pages((unsigned long)amd_iommu_dev_table,
+                  get_order(dev_table_size));
 
        free_iommu_all();
 
@@ -821,6 +1002,13 @@ free:
        goto out;
 }
 
+/****************************************************************************
+ *
+ * Early detect code. This code runs at IOMMU detection time in the DMA
+ * layer. It just looks if there is an IVRS ACPI table to detect AMD
+ * IOMMUs
+ *
+ ****************************************************************************/
 static int __init early_amd_iommu_detect(struct acpi_table_header *table)
 {
        return 0;
@@ -828,7 +1016,7 @@ static int __init early_amd_iommu_detect(struct acpi_table_header *table)
 
 void __init amd_iommu_detect(void)
 {
-       if (swiotlb || no_iommu || iommu_detected)
+       if (swiotlb || no_iommu || (iommu_detected && !gart_iommu_aperture))
                return;
 
        if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) {
@@ -841,6 +1029,13 @@ void __init amd_iommu_detect(void)
        }
 }
 
+/****************************************************************************
+ *
+ * Parsing functions for the AMD IOMMU specific kernel command line
+ * options.
+ *
+ ****************************************************************************/
+
 static int __init parse_amd_iommu_options(char *str)
 {
        for (; *str; ++str) {
@@ -853,20 +1048,10 @@ static int __init parse_amd_iommu_options(char *str)
 
 static int __init parse_amd_iommu_size_options(char *str)
 {
-       for (; *str; ++str) {
-               if (strcmp(str, "32M") == 0)
-                       amd_iommu_aperture_order = 25;
-               if (strcmp(str, "64M") == 0)
-                       amd_iommu_aperture_order = 26;
-               if (strcmp(str, "128M") == 0)
-                       amd_iommu_aperture_order = 27;
-               if (strcmp(str, "256M") == 0)
-                       amd_iommu_aperture_order = 28;
-               if (strcmp(str, "512M") == 0)
-                       amd_iommu_aperture_order = 29;
-               if (strcmp(str, "1G") == 0)
-                       amd_iommu_aperture_order = 30;
-       }
+       unsigned order = PAGE_SHIFT + get_order(memparse(str, &str));
+
+       if ((order > 24) && (order < 31))
+               amd_iommu_aperture_order = order;
 
        return 1;
 }
index 9f907806c1a53d58f9be603bb18bdcb60f14c6c2..44e21826db1145a00659c89c5c45232ff3e70d2a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/suspend.h>
 #include <asm/e820.h>
 #include <asm/io.h>
+#include <asm/iommu.h>
 #include <asm/gart.h>
 #include <asm/pci-direct.h>
 #include <asm/dma.h>
index a437d027f20b6d8d7ba3dc88400220e796afe41e..d6c8983583713d747790587861318a5fb58eb342 100644 (file)
@@ -75,7 +75,7 @@ char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE};
 /*
  * Debug level, exported for io_apic.c
  */
-int apic_verbosity;
+unsigned int apic_verbosity;
 
 int pic_mode;
 
@@ -177,7 +177,7 @@ void __cpuinit enable_NMI_through_LVT0(void)
        /* Level triggered for 82489DX */
        if (!lapic_is_integrated())
                v |= APIC_LVT_LEVEL_TRIGGER;
-       apic_write_around(APIC_LVT0, v);
+       apic_write(APIC_LVT0, v);
 }
 
 /**
@@ -212,9 +212,6 @@ int lapic_get_maxlvt(void)
  * this function twice on the boot CPU, once with a bogus timeout
  * value, second time for real. The other (noncalibrating) CPUs
  * call this function only once, with the real, calibrated value.
- *
- * We do reads before writes even if unnecessary, to get around the
- * P5 APIC double write bug.
  */
 static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
 {
@@ -229,18 +226,18 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
        if (!irqen)
                lvtt_value |= APIC_LVT_MASKED;
 
-       apic_write_around(APIC_LVTT, lvtt_value);
+       apic_write(APIC_LVTT, lvtt_value);
 
        /*
         * Divide PICLK by 16
         */
        tmp_value = apic_read(APIC_TDCR);
-       apic_write_around(APIC_TDCR, (tmp_value
-                               & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE))
-                               | APIC_TDR_DIV_16);
+       apic_write(APIC_TDCR,
+                  (tmp_value & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) |
+                  APIC_TDR_DIV_16);
 
        if (!oneshot)
-               apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR);
+               apic_write(APIC_TMICT, clocks / APIC_DIVISOR);
 }
 
 /*
@@ -249,7 +246,7 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
 static int lapic_next_event(unsigned long delta,
                            struct clock_event_device *evt)
 {
-       apic_write_around(APIC_TMICT, delta);
+       apic_write(APIC_TMICT, delta);
        return 0;
 }
 
@@ -278,7 +275,7 @@ static void lapic_timer_setup(enum clock_event_mode mode,
        case CLOCK_EVT_MODE_SHUTDOWN:
                v = apic_read(APIC_LVTT);
                v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
-               apic_write_around(APIC_LVTT, v);
+               apic_write(APIC_LVTT, v);
                break;
        case CLOCK_EVT_MODE_RESUME:
                /* Nothing to do here */
@@ -372,12 +369,7 @@ static void __init lapic_cal_handler(struct clock_event_device *dev)
        }
 }
 
-/*
- * Setup the boot APIC
- *
- * Calibrate and verify the result.
- */
-void __init setup_boot_APIC_clock(void)
+static int __init calibrate_APIC_clock(void)
 {
        struct clock_event_device *levt = &__get_cpu_var(lapic_events);
        const long pm_100ms = PMTMR_TICKS_PER_SEC/10;
@@ -387,24 +379,6 @@ void __init setup_boot_APIC_clock(void)
        long delta, deltapm;
        int pm_referenced = 0;
 
-       /*
-        * The local apic timer can be disabled via the kernel
-        * commandline or from the CPU detection code. Register the lapic
-        * timer as a dummy clock event source on SMP systems, so the
-        * broadcast mechanism is used. On UP systems simply ignore it.
-        */
-       if (local_apic_timer_disabled) {
-               /* No broadcast on UP ! */
-               if (num_possible_cpus() > 1) {
-                       lapic_clockevent.mult = 1;
-                       setup_APIC_timer();
-               }
-               return;
-       }
-
-       apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
-                   "calibrating APIC timer ...\n");
-
        local_irq_disable();
 
        /* Replace the global interrupt handler */
@@ -489,8 +463,6 @@ void __init setup_boot_APIC_clock(void)
                    calibration_result / (1000000 / HZ),
                    calibration_result % (1000000 / HZ));
 
-       local_apic_timer_verify_ok = 1;
-
        /*
         * Do a sanity check on the APIC calibration result
         */
@@ -498,12 +470,11 @@ void __init setup_boot_APIC_clock(void)
                local_irq_enable();
                printk(KERN_WARNING
                       "APIC frequency too slow, disabling apic timer\n");
-               /* No broadcast on UP ! */
-               if (num_possible_cpus() > 1)
-                       setup_APIC_timer();
-               return;
+               return -1;
        }
 
+       local_apic_timer_verify_ok = 1;
+
        /* We trust the pm timer based calibration */
        if (!pm_referenced) {
                apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
@@ -543,22 +514,55 @@ void __init setup_boot_APIC_clock(void)
        if (!local_apic_timer_verify_ok) {
                printk(KERN_WARNING
                       "APIC timer disabled due to verification failure.\n");
+                       return -1;
+       }
+
+       return 0;
+}
+
+/*
+ * Setup the boot APIC
+ *
+ * Calibrate and verify the result.
+ */
+void __init setup_boot_APIC_clock(void)
+{
+       /*
+        * The local apic timer can be disabled via the kernel
+        * commandline or from the CPU detection code. Register the lapic
+        * timer as a dummy clock event source on SMP systems, so the
+        * broadcast mechanism is used. On UP systems simply ignore it.
+        */
+       if (local_apic_timer_disabled) {
                /* No broadcast on UP ! */
-               if (num_possible_cpus() == 1)
-                       return;
-       } else {
-               /*
-                * If nmi_watchdog is set to IO_APIC, we need the
-                * PIT/HPET going.  Otherwise register lapic as a dummy
-                * device.
-                */
-               if (nmi_watchdog != NMI_IO_APIC)
-                       lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
-               else
-                       printk(KERN_WARNING "APIC timer registered as dummy,"
-                               " due to nmi_watchdog=%d!\n", nmi_watchdog);
+               if (num_possible_cpus() > 1) {
+                       lapic_clockevent.mult = 1;
+                       setup_APIC_timer();
+               }
+               return;
        }
 
+       apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
+                   "calibrating APIC timer ...\n");
+
+       if (calibrate_APIC_clock()) {
+               /* No broadcast on UP ! */
+               if (num_possible_cpus() > 1)
+                       setup_APIC_timer();
+               return;
+       }
+
+       /*
+        * If nmi_watchdog is set to IO_APIC, we need the
+        * PIT/HPET going.  Otherwise register lapic as a dummy
+        * device.
+        */
+       if (nmi_watchdog != NMI_IO_APIC)
+               lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
+       else
+               printk(KERN_WARNING "APIC timer registered as dummy,"
+                       " due to nmi_watchdog=%d!\n", nmi_watchdog);
+
        /* Setup the lapic or request the broadcast */
        setup_APIC_timer();
 }
@@ -693,44 +697,44 @@ void clear_local_APIC(void)
         */
        if (maxlvt >= 3) {
                v = ERROR_APIC_VECTOR; /* any non-zero vector will do */
-               apic_write_around(APIC_LVTERR, v | APIC_LVT_MASKED);
+               apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
        }
        /*
         * Careful: we have to set masks only first to deassert
         * any level-triggered sources.
         */
        v = apic_read(APIC_LVTT);
-       apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED);
+       apic_write(APIC_LVTT, v | APIC_LVT_MASKED);
        v = apic_read(APIC_LVT0);
-       apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
+       apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
        v = apic_read(APIC_LVT1);
-       apic_write_around(APIC_LVT1, v | APIC_LVT_MASKED);
+       apic_write(APIC_LVT1, v | APIC_LVT_MASKED);
        if (maxlvt >= 4) {
                v = apic_read(APIC_LVTPC);
-               apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED);
+               apic_write(APIC_LVTPC, v | APIC_LVT_MASKED);
        }
 
        /* lets not touch this if we didn't frob it */
 #ifdef CONFIG_X86_MCE_P4THERMAL
        if (maxlvt >= 5) {
                v = apic_read(APIC_LVTTHMR);
-               apic_write_around(APIC_LVTTHMR, v | APIC_LVT_MASKED);
+               apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED);
        }
 #endif
        /*
         * Clean APIC state for other OSs:
         */
-       apic_write_around(APIC_LVTT, APIC_LVT_MASKED);
-       apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
-       apic_write_around(APIC_LVT1, APIC_LVT_MASKED);
+       apic_write(APIC_LVTT, APIC_LVT_MASKED);
+       apic_write(APIC_LVT0, APIC_LVT_MASKED);
+       apic_write(APIC_LVT1, APIC_LVT_MASKED);
        if (maxlvt >= 3)
-               apic_write_around(APIC_LVTERR, APIC_LVT_MASKED);
+               apic_write(APIC_LVTERR, APIC_LVT_MASKED);
        if (maxlvt >= 4)
-               apic_write_around(APIC_LVTPC, APIC_LVT_MASKED);
+               apic_write(APIC_LVTPC, APIC_LVT_MASKED);
 
 #ifdef CONFIG_X86_MCE_P4THERMAL
        if (maxlvt >= 5)
-               apic_write_around(APIC_LVTTHMR, APIC_LVT_MASKED);
+               apic_write(APIC_LVTTHMR, APIC_LVT_MASKED);
 #endif
        /* Integrated APIC (!82489DX) ? */
        if (lapic_is_integrated()) {
@@ -756,7 +760,7 @@ void disable_local_APIC(void)
         */
        value = apic_read(APIC_SPIV);
        value &= ~APIC_SPIV_APIC_ENABLED;
-       apic_write_around(APIC_SPIV, value);
+       apic_write(APIC_SPIV, value);
 
        /*
         * When LAPIC was disabled by the BIOS and enabled by the kernel,
@@ -865,8 +869,8 @@ void __init sync_Arb_IDs(void)
        apic_wait_icr_idle();
 
        apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n");
-       apic_write_around(APIC_ICR, APIC_DEST_ALLINC | APIC_INT_LEVELTRIG
-                               | APIC_DM_INIT);
+       apic_write(APIC_ICR,
+                  APIC_DEST_ALLINC | APIC_INT_LEVELTRIG | APIC_DM_INIT);
 }
 
 /*
@@ -902,16 +906,16 @@ void __init init_bsp_APIC(void)
        else
                value |= APIC_SPIV_FOCUS_DISABLED;
        value |= SPURIOUS_APIC_VECTOR;
-       apic_write_around(APIC_SPIV, value);
+       apic_write(APIC_SPIV, value);
 
        /*
         * Set up the virtual wire mode.
         */
-       apic_write_around(APIC_LVT0, APIC_DM_EXTINT);
+       apic_write(APIC_LVT0, APIC_DM_EXTINT);
        value = APIC_DM_NMI;
        if (!lapic_is_integrated())             /* 82489DX */
                value |= APIC_LVT_LEVEL_TRIGGER;
-       apic_write_around(APIC_LVT1, value);
+       apic_write(APIC_LVT1, value);
 }
 
 static void __cpuinit lapic_setup_esr(void)
@@ -926,7 +930,7 @@ static void __cpuinit lapic_setup_esr(void)
 
                /* enables sending errors */
                value = ERROR_APIC_VECTOR;
-               apic_write_around(APIC_LVTERR, value);
+               apic_write(APIC_LVTERR, value);
                /*
                 * spec says clear errors after enabling vector.
                 */
@@ -989,7 +993,7 @@ void __cpuinit setup_local_APIC(void)
         */
        value = apic_read(APIC_TASKPRI);
        value &= ~APIC_TPRI_MASK;
-       apic_write_around(APIC_TASKPRI, value);
+       apic_write(APIC_TASKPRI, value);
 
        /*
         * After a crash, we no longer service the interrupts and a pending
@@ -1047,7 +1051,7 @@ void __cpuinit setup_local_APIC(void)
         * Set spurious IRQ vector
         */
        value |= SPURIOUS_APIC_VECTOR;
-       apic_write_around(APIC_SPIV, value);
+       apic_write(APIC_SPIV, value);
 
        /*
         * Set up LVT0, LVT1:
@@ -1069,7 +1073,7 @@ void __cpuinit setup_local_APIC(void)
                apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
                                smp_processor_id());
        }
-       apic_write_around(APIC_LVT0, value);
+       apic_write(APIC_LVT0, value);
 
        /*
         * only the BP should see the LINT1 NMI signal, obviously.
@@ -1080,7 +1084,7 @@ void __cpuinit setup_local_APIC(void)
                value = APIC_DM_NMI | APIC_LVT_MASKED;
        if (!integrated)                /* 82489DX */
                value |= APIC_LVT_LEVEL_TRIGGER;
-       apic_write_around(APIC_LVT1, value);
+       apic_write(APIC_LVT1, value);
 }
 
 void __cpuinit end_local_APIC_setup(void)
@@ -1091,7 +1095,7 @@ void __cpuinit end_local_APIC_setup(void)
        /* Disable the local apic timer */
        value = apic_read(APIC_LVTT);
        value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
-       apic_write_around(APIC_LVTT, value);
+       apic_write(APIC_LVTT, value);
 
        setup_apic_nmi_watchdog(NULL);
        apic_pm_activate();
@@ -1214,9 +1218,6 @@ int apic_version[MAX_APICS];
 
 int __init APIC_init_uniprocessor(void)
 {
-       if (disable_apic)
-               clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
-
        if (!smp_found_config && !cpu_has_apic)
                return -1;
 
@@ -1419,7 +1420,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
                value &= ~APIC_VECTOR_MASK;
                value |= APIC_SPIV_APIC_ENABLED;
                value |= 0xf;
-               apic_write_around(APIC_SPIV, value);
+               apic_write(APIC_SPIV, value);
 
                if (!virt_wire_setup) {
                        /*
@@ -1432,10 +1433,10 @@ void disconnect_bsp_APIC(int virt_wire_setup)
                                APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
                        value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
                        value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
-                       apic_write_around(APIC_LVT0, value);
+                       apic_write(APIC_LVT0, value);
                } else {
                        /* Disable LVT0 */
-                       apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
+                       apic_write(APIC_LVT0, APIC_LVT_MASKED);
                }
 
                /*
@@ -1449,7 +1450,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
                        APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
                value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
                value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
-               apic_write_around(APIC_LVT1, value);
+               apic_write(APIC_LVT1, value);
        }
 }
 
@@ -1700,7 +1701,7 @@ early_param("lapic", parse_lapic);
 static int __init parse_nolapic(char *arg)
 {
        disable_apic = 1;
-       clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
+       setup_clear_cpu_cap(X86_FEATURE_APIC);
        return 0;
 }
 early_param("nolapic", parse_nolapic);
index 1e3d32e27c14c23a8d48d1dc6bcf8b30faeefae7..7f1f030da7ee4c048990eecf9dc00229472028ca 100644 (file)
@@ -54,7 +54,7 @@ EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
 /*
  * Debug level, exported for io_apic.c
  */
-int apic_verbosity;
+unsigned int apic_verbosity;
 
 /* Have we found an MP table */
 int smp_found_config;
@@ -314,7 +314,7 @@ static void setup_APIC_timer(void)
 
 #define TICK_COUNT 100000000
 
-static void __init calibrate_APIC_clock(void)
+static int __init calibrate_APIC_clock(void)
 {
        unsigned apic, apic_start;
        unsigned long tsc, tsc_start;
@@ -368,6 +368,17 @@ static void __init calibrate_APIC_clock(void)
                clockevent_delta2ns(0xF, &lapic_clockevent);
 
        calibration_result = result / HZ;
+
+       /*
+        * Do a sanity check on the APIC calibration result
+        */
+       if (calibration_result < (1000000 / HZ)) {
+               printk(KERN_WARNING
+                       "APIC frequency too slow, disabling apic timer\n");
+               return -1;
+       }
+
+       return 0;
 }
 
 /*
@@ -394,14 +405,7 @@ void __init setup_boot_APIC_clock(void)
        }
 
        printk(KERN_INFO "Using local APIC timer interrupts.\n");
-       calibrate_APIC_clock();
-
-       /*
-        * Do a sanity check on the APIC calibration result
-        */
-       if (calibration_result < (1000000 / HZ)) {
-               printk(KERN_WARNING
-                      "APIC frequency too slow, disabling apic timer\n");
+       if (calibrate_APIC_clock()) {
                /* No broadcast on UP ! */
                if (num_possible_cpus() > 1)
                        setup_APIC_timer();
@@ -1337,7 +1341,7 @@ early_param("apic", apic_set_verbosity);
 static __init int setup_disableapic(char *str)
 {
        disable_apic = 1;
-       clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
+       setup_clear_cpu_cap(X86_FEATURE_APIC);
        return 0;
 }
 early_param("disableapic", setup_disableapic);
index bacf5deeec2d13a16a675e2b6bc44e8f53ed232c..aa89387006fe3a730b9b7eba9b7b55cc3c1beb4d 100644 (file)
@@ -18,6 +18,8 @@
 #include <asm/ia32.h>
 #include <asm/bootparam.h>
 
+#include <xen/interface/xen.h>
+
 #define __NO_STUBS 1
 #undef __SYSCALL
 #undef _ASM_X86_64_UNISTD_H_
@@ -131,5 +133,14 @@ int main(void)
        OFFSET(BP_loadflags, boot_params, hdr.loadflags);
        OFFSET(BP_hardware_subarch, boot_params, hdr.hardware_subarch);
        OFFSET(BP_version, boot_params, hdr.version);
+
+       BLANK();
+       DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
+#ifdef CONFIG_XEN
+       BLANK();
+       OFFSET(XEN_vcpu_info_mask, vcpu_info, evtchn_upcall_mask);
+       OFFSET(XEN_vcpu_info_pending, vcpu_info, evtchn_upcall_pending);
+#undef ENTRY
+#endif
        return 0;
 }
diff --git a/arch/x86/kernel/bios_uv.c b/arch/x86/kernel/bios_uv.c
new file mode 100644 (file)
index 0000000..c639bd5
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * BIOS run time interface routines.
+ *
+ *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <asm/uv/bios.h>
+
+const char *
+x86_bios_strerror(long status)
+{
+       const char *str;
+       switch (status) {
+       case  0: str = "Call completed without error"; break;
+       case -1: str = "Not implemented"; break;
+       case -2: str = "Invalid argument"; break;
+       case -3: str = "Call completed with error"; break;
+       default: str = "Unknown BIOS status code"; break;
+       }
+       return str;
+}
+
+long
+x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
+                  unsigned long *drift_info)
+{
+       struct uv_bios_retval isrv;
+
+       BIOS_CALL(isrv, BIOS_FREQ_BASE, which, 0, 0, 0, 0, 0, 0);
+       *ticks_per_second = isrv.v0;
+       *drift_info = isrv.v1;
+       return isrv.status;
+}
+EXPORT_SYMBOL_GPL(x86_bios_freq_base);
index 81a07ca65d4487d7f3133619210d287238ac411c..cae9cabc3031f1e3a2a3d6f8085d20b557026ac3 100644 (file)
@@ -24,8 +24,6 @@
 extern void vide(void);
 __asm__(".align 4\nvide: ret");
 
-int force_mwait __cpuinitdata;
-
 static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
 {
        if (cpuid_eax(0x80000000) >= 0x80000007) {
index 7c36fb8a28d46455c2a51b8adabc8511e1f9386c..d1692b2a41ffac4bf6b9423d38af42741a847b36 100644 (file)
@@ -115,6 +115,8 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
        /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */
        if (c->x86_power & (1<<8))
                set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
+
+       set_cpu_cap(c, X86_FEATURE_SYSCALL32);
 }
 
 static void __cpuinit init_amd(struct cpuinfo_x86 *c)
index 1b1c56bb338f7de23f8ee65f4e53f155c0cc294c..c9b58a806e852d3d4a2ff96e0f48c0e737cff80f 100644 (file)
@@ -131,13 +131,7 @@ static void __init check_popad(void)
  *   (for due to lack of "invlpg" and working WP on a i386)
  * - In order to run on anything without a TSC, we need to be
  *   compiled for a i486.
- * - In order to support the local APIC on a buggy Pentium machine,
- *   we need to be compiled with CONFIG_X86_GOOD_APIC disabled,
- *   which happens implicitly if compiled for a Pentium or lower
- *   (unless an advanced selection of CPU features is used) as an
- *   otherwise config implies a properly working local APIC without
- *   the need to do extra reads from the APIC.
-*/
+ */
 
 static void __init check_config(void)
 {
@@ -151,21 +145,6 @@ static void __init check_config(void)
        if (boot_cpu_data.x86 == 3)
                panic("Kernel requires i486+ for 'invlpg' and other features");
 #endif
-
-/*
- * If we were told we had a good local APIC, check for buggy Pentia,
- * i.e. all B steppings and the C2 stepping of P54C when using their
- * integrated APIC (see 11AP erratum in "Pentium Processor
- * Specification Update").
- */
-#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_GOOD_APIC)
-       if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL
-           && cpu_has_apic
-           && boot_cpu_data.x86 == 5
-           && boot_cpu_data.x86_model == 2
-           && (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11))
-               panic("Kernel compiled for PMMX+, assumes a local APIC without the read-before-write bug!");
-#endif
 }
 
 
index 7b8cc72feb40e3ed8bfd02437fe3b6324b024f67..dd6e3f15017eb87b04885fd5164681bbdd9a3073 100644 (file)
@@ -7,15 +7,13 @@
 #include <linux/module.h>
 #include <linux/kgdb.h>
 #include <linux/topology.h>
-#include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/smp.h>
-#include <linux/module.h>
 #include <linux/percpu.h>
-#include <asm/processor.h>
 #include <asm/i387.h>
 #include <asm/msr.h>
 #include <asm/io.h>
+#include <asm/linkage.h>
 #include <asm/mmu_context.h>
 #include <asm/mtrr.h>
 #include <asm/mce.h>
@@ -305,7 +303,6 @@ static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
                        c->x86_capability[2] = cpuid_edx(0x80860001);
        }
 
-       c->extended_cpuid_level = cpuid_eax(0x80000000);
        if (c->extended_cpuid_level >= 0x80000007)
                c->x86_power = cpuid_edx(0x80000007);
 
@@ -316,18 +313,11 @@ static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
                c->x86_phys_bits = eax & 0xff;
        }
 
-       /* Assume all 64-bit CPUs support 32-bit syscall */
-       set_cpu_cap(c, X86_FEATURE_SYSCALL32);
-
        if (c->x86_vendor != X86_VENDOR_UNKNOWN &&
            cpu_devs[c->x86_vendor]->c_early_init)
                cpu_devs[c->x86_vendor]->c_early_init(c);
 
        validate_pat_support(c);
-
-       /* early_param could clear that, but recall get it set again */
-       if (disable_apic)
-               clear_cpu_cap(c, X86_FEATURE_APIC);
 }
 
 /*
@@ -517,8 +507,7 @@ void pda_init(int cpu)
 }
 
 char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ +
-                          DEBUG_STKSZ]
-__attribute__((section(".bss.page_aligned")));
+                          DEBUG_STKSZ] __page_aligned_bss;
 
 extern asmlinkage void ignore_sysret(void);
 
index f8a63b3664e3ac649de72783db4ed7d388a70a94..35fb4eaf6e1cfe9b83f1ddc37b08416e7a097de5 100644 (file)
@@ -1,5 +1,4 @@
 /*
- *  $Id: powernow-k7.h,v 1.2 2003/02/10 18:26:01 davej Exp $
  *  (C) 2003 Dave Jones.
  *
  *  Licensed under the terms of the GNU GPL License version 2.
index 70609efdf1da3ae7fea3a311ffbb1639e3f5675e..b75f2569b8f8ba1940d55ce3616f25a91c7c6d75 100644 (file)
@@ -227,6 +227,16 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
        if (cpu_has_bts)
                ds_init_intel(c);
 
+       /*
+        * See if we have a good local APIC by checking for buggy Pentia,
+        * i.e. all B steppings and the C2 stepping of P54C when using their
+        * integrated APIC (see 11AP erratum in "Pentium Processor
+        * Specification Update").
+        */
+       if (cpu_has_apic && (c->x86<<8 | c->x86_model<<4) == 0x520 &&
+           (c->x86_mask < 0x6 || c->x86_mask == 0xb))
+               set_cpu_cap(c, X86_FEATURE_11AP);
+
 #ifdef CONFIG_X86_NUMAQ
        numaq_tsc_disable();
 #endif
index e4b8d189d7edacf0ac60d2dd636ad54100ce7fdc..650d40f7912bea81023dc7f9698b8b10ced4d6fa 100644 (file)
@@ -781,15 +781,14 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
                        }
                        kobject_put(per_cpu(cache_kobject, cpu));
                        cpuid4_cache_sysfs_exit(cpu);
-                       break;
+                       return retval;
                }
                kobject_uevent(&(this_object->kobj), KOBJ_ADD);
        }
-       if (!retval)
-               cpu_set(cpu, cache_dev_map);
+       cpu_set(cpu, cache_dev_map);
 
        kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
-       return retval;
+       return 0;
 }
 
 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
index 2fe06ab5c547ddfe9a07ec77c519688dfd13345d..65a339678ece817b3b27fa56afb5ee97aae8d027 100644 (file)
@@ -762,10 +762,14 @@ DEFINE_PER_CPU(struct sys_device, device_mce);
 
 /* Why are there no generic functions for this? */
 #define ACCESSOR(name, var, start) \
-       static ssize_t show_ ## name(struct sys_device *s, char *buf) { \
+       static ssize_t show_ ## name(struct sys_device *s,              \
+                                    struct sysdev_attribute *attr,     \
+                                    char *buf) {                       \
                return sprintf(buf, "%lx\n", (unsigned long)var);       \
        }                                                               \
-       static ssize_t set_ ## name(struct sys_device *s,const char *buf,size_t siz) { \
+       static ssize_t set_ ## name(struct sys_device *s,               \
+                                   struct sysdev_attribute *attr,      \
+                                   const char *buf, size_t siz) {      \
                char *end;                                              \
                unsigned long new = simple_strtoul(buf, &end, 0);       \
                if (end == buf) return -EINVAL;                         \
@@ -786,14 +790,16 @@ ACCESSOR(bank3ctl,bank[3],mce_restart())
 ACCESSOR(bank4ctl,bank[4],mce_restart())
 ACCESSOR(bank5ctl,bank[5],mce_restart())
 
-static ssize_t show_trigger(struct sys_device *s, char *buf)
+static ssize_t show_trigger(struct sys_device *s, struct sysdev_attribute *attr,
+                               char *buf)
 {
        strcpy(buf, trigger);
        strcat(buf, "\n");
        return strlen(trigger) + 1;
 }
 
-static ssize_t set_trigger(struct sys_device *s,const char *buf,size_t siz)
+static ssize_t set_trigger(struct sys_device *s, struct sysdev_attribute *attr,
+                               const char *buf,size_t siz)
 {
        char *p;
        int len;
@@ -806,12 +812,12 @@ static ssize_t set_trigger(struct sys_device *s,const char *buf,size_t siz)
 }
 
 static SYSDEV_ATTR(trigger, 0644, show_trigger, set_trigger);
-ACCESSOR(tolerant,tolerant,)
+static SYSDEV_INT_ATTR(tolerant, 0644, tolerant);
 ACCESSOR(check_interval,check_interval,mce_restart())
 static struct sysdev_attribute *mce_attributes[] = {
        &attr_bank0ctl, &attr_bank1ctl, &attr_bank2ctl,
        &attr_bank3ctl, &attr_bank4ctl, &attr_bank5ctl,
-       &attr_tolerant, &attr_check_interval, &attr_trigger,
+       &attr_tolerant.attr, &attr_check_interval, &attr_trigger,
        NULL
 };
 
index eef001ad3bdee23a5a5585ce75dd7be4378f40ff..9b60fce09f758d5af0520bccb61445a99aaad693 100644 (file)
@@ -102,7 +102,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c)
        /* The temperature transition interrupt handler setup */
        h = THERMAL_APIC_VECTOR;                /* our delivery vector */
        h |= (APIC_DM_FIXED | APIC_LVT_MASKED); /* we'll mask till we're ready */
-       apic_write_around(APIC_LVTTHMR, h);
+       apic_write(APIC_LVTTHMR, h);
 
        rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
        wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03 , h);
@@ -114,7 +114,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c)
        wrmsr(MSR_IA32_MISC_ENABLE, l | (1<<3), h);
 
        l = apic_read(APIC_LVTTHMR);
-       apic_write_around(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
+       apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
        printk(KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu);
 
        /* enable thermal throttle processing */
index 1f4cc48c14c633be4e0a1ca62b1502616337b048..d5ae2243f0b959bf26839c476850faec8a6a4476 100644 (file)
@@ -35,6 +35,7 @@ atomic_t therm_throt_en = ATOMIC_INIT(0);
 
 #define define_therm_throt_sysdev_show_func(name)                            \
 static ssize_t therm_throt_sysdev_show_##name(struct sys_device *dev,        \
+                                       struct sysdev_attribute *attr,       \
                                               char *buf)                     \
 {                                                                            \
        unsigned int cpu = dev->id;                                          \
index 6d4bdc02388a2abf86eed64b2d596138f96225c4..de7439f82b9230d7a65fa8a12af027bc7a578660 100644 (file)
@@ -250,7 +250,7 @@ static void write_watchdog_counter(unsigned int perfctr_msr,
 
        do_div(count, nmi_hz);
        if(descr)
-               Dprintk("setting %s to -0x%08Lx\n", descr, count);
+               pr_debug("setting %s to -0x%08Lx\n", descr, count);
        wrmsrl(perfctr_msr, 0 - count);
 }
 
@@ -261,7 +261,7 @@ static void write_watchdog_counter32(unsigned int perfctr_msr,
 
        do_div(count, nmi_hz);
        if(descr)
-               Dprintk("setting %s to -0x%08Lx\n", descr, count);
+               pr_debug("setting %s to -0x%08Lx\n", descr, count);
        wrmsr(perfctr_msr, (u32)(-count), 0);
 }
 
index 2de5fa2bbf77061c31d686035e0d48ca266c49cf..14b11b3be31ca64d600cb7281edb93f5228809b9 100644 (file)
@@ -141,8 +141,8 @@ static __cpuinit int cpuid_device_create(int cpu)
 {
        struct device *dev;
 
-       dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu),
-                           "cpu%d", cpu);
+       dev = device_create_drvdata(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu),
+                                   NULL, "cpu%d", cpu);
        return IS_ERR(dev) ? PTR_ERR(dev) : 0;
 }
 
index 28c29180b3807e94f14b38a090ebb8d6deb0e9de..9af89078f7bb0cb2b6ce7ed958c9483b24d4402e 100644 (file)
@@ -877,7 +877,8 @@ void __init early_res_to_bootmem(u64 start, u64 end)
        for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++)
                count++;
 
-       printk(KERN_INFO "(%d early reservations) ==> bootmem\n", count);
+       printk(KERN_INFO "(%d early reservations) ==> bootmem [%010llx - %010llx]\n",
+                        count, start, end);
        for (i = 0; i < count; i++) {
                struct early_res *r = &early_res[i];
                printk(KERN_INFO "  #%d [%010llx - %010llx] %16s", i,
@@ -1298,11 +1299,6 @@ void __init e820_reserve_resources(void)
        }
 }
 
-/*
- * Non-standard memory setup can be specified via this quirk:
- */
-char * (*arch_memory_setup_quirk)(void);
-
 char *__init default_machine_specific_memory_setup(void)
 {
        char *who = "BIOS-e820";
@@ -1343,8 +1339,8 @@ char *__init default_machine_specific_memory_setup(void)
 
 char *__init __attribute__((weak)) machine_specific_memory_setup(void)
 {
-       if (arch_memory_setup_quirk) {
-               char *who = arch_memory_setup_quirk();
+       if (x86_quirks->arch_memory_setup) {
+               char *who = x86_quirks->arch_memory_setup();
 
                if (who)
                        return who;
@@ -1367,24 +1363,3 @@ void __init setup_memory_map(void)
        printk(KERN_INFO "BIOS-provided physical RAM map:\n");
        e820_print_map(who);
 }
-
-#ifdef CONFIG_X86_64
-int __init arch_get_ram_range(int slot, u64 *addr, u64 *size)
-{
-       int i;
-
-       if (slot < 0 || slot >= e820.nr_map)
-               return -1;
-       for (i = slot; i < e820.nr_map; i++) {
-               if (e820.map[i].type != E820_RAM)
-                       continue;
-               break;
-       }
-       if (i == e820.nr_map || e820.map[i].addr > (max_pfn << PAGE_SHIFT))
-               return -1;
-       *addr = e820.map[i].addr;
-       *size = min_t(u64, e820.map[i].size + e820.map[i].addr,
-               max_pfn << PAGE_SHIFT) - *addr;
-       return i + 1;
-}
-#endif
index a0e11c0cc872f03b1ca9b85fd9521f19fa8a3269..4353cf5e6fac8b4d329e18def887dadd3f55bbb8 100644 (file)
 #include <asm/dma.h>
 #include <asm/io_apic.h>
 #include <asm/apic.h>
-
-#ifdef CONFIG_GART_IOMMU
-#include <asm/gart.h>
-#endif
+#include <asm/iommu.h>
 
 static void __init fix_hypertransport_config(int num, int slot, int func)
 {
index 6bc07f0f1202eeb1eaac0b55064acad7f355371a..cdfd94cc6b14e4fd1c06c058904e13c2f6575810 100644 (file)
@@ -332,7 +332,7 @@ sysenter_past_esp:
        GET_THREAD_INFO(%ebp)
 
        /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
-       testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
+       testw $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
        jnz syscall_trace_entry
        cmpl $(nr_syscalls), %eax
        jae syscall_badsys
@@ -370,7 +370,7 @@ ENTRY(system_call)
        GET_THREAD_INFO(%ebp)
                                        # system call tracing in operation / emulation
        /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
-       testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
+       testw $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
        jnz syscall_trace_entry
        cmpl $(nr_syscalls), %eax
        jae syscall_badsys
@@ -383,10 +383,6 @@ syscall_exit:
                                        # setting need_resched or sigpending
                                        # between sampling and the iret
        TRACE_IRQS_OFF
-       testl $X86_EFLAGS_TF,PT_EFLAGS(%esp)    # If tracing set singlestep flag on exit
-       jz no_singlestep
-       orl $_TIF_SINGLESTEP,TI_flags(%ebp)
-no_singlestep:
        movl TI_flags(%ebp), %ecx
        testw $_TIF_ALLWORK_MASK, %cx   # current->work
        jne syscall_exit_work
@@ -514,12 +510,8 @@ END(work_pending)
 syscall_trace_entry:
        movl $-ENOSYS,PT_EAX(%esp)
        movl %esp, %eax
-       xorl %edx,%edx
-       call do_syscall_trace
-       cmpl $0, %eax
-       jne resume_userspace            # ret != 0 -> running under PTRACE_SYSEMU,
-                                       # so must skip actual syscall
-       movl PT_ORIG_EAX(%esp), %eax
+       call syscall_trace_enter
+       /* What it returned is what we'll actually use.  */
        cmpl $(nr_syscalls), %eax
        jnae syscall_call
        jmp syscall_exit
@@ -528,14 +520,13 @@ END(syscall_trace_entry)
        # perform syscall exit tracing
        ALIGN
 syscall_exit_work:
-       testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
+       testb $_TIF_WORK_SYSCALL_EXIT, %cl
        jz work_pending
        TRACE_IRQS_ON
-       ENABLE_INTERRUPTS(CLBR_ANY)     # could let do_syscall_trace() call
+       ENABLE_INTERRUPTS(CLBR_ANY)     # could let syscall_trace_leave() call
                                        # schedule() instead
        movl %esp, %eax
-       movl $1, %edx
-       call do_syscall_trace
+       call syscall_trace_leave
        jmp resume_userspace
 END(syscall_exit_work)
        CFI_ENDPROC
@@ -1024,6 +1015,7 @@ ENDPROC(kernel_thread_helper)
 ENTRY(xen_sysenter_target)
        RING0_INT_FRAME
        addl $5*4, %esp         /* remove xen-provided frame */
+       CFI_ADJUST_CFA_OFFSET -5*4
        jmp sysenter_past_esp
        CFI_ENDPROC
 
index ae63e584c340cbafd342af95e18bce946b474525..8410e26f418337d7fc37d77dba6a1f0e60e7f525 100644 (file)
@@ -349,8 +349,7 @@ ENTRY(system_call_after_swapgs)
        movq  %rcx,RIP-ARGOFFSET(%rsp)
        CFI_REL_OFFSET rip,RIP-ARGOFFSET
        GET_THREAD_INFO(%rcx)
-       testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP), \
-               TI_flags(%rcx)
+       testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%rcx)
        jnz tracesys
        cmpq $__NR_syscall_max,%rax
        ja badsys
@@ -430,7 +429,12 @@ tracesys:
        FIXUP_TOP_OF_STACK %rdi
        movq %rsp,%rdi
        call syscall_trace_enter
-       LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
+       /*
+        * Reload arg registers from stack in case ptrace changed them.
+        * We don't reload %rax because syscall_trace_enter() returned
+        * the value it wants us to use in the table lookup.
+        */
+       LOAD_ARGS ARGOFFSET, 1
        RESTORE_REST
        cmpq $__NR_syscall_max,%rax
        ja   int_ret_from_sys_call      /* RAX(%rsp) set to -ENOSYS above */
@@ -483,7 +487,7 @@ int_very_careful:
        ENABLE_INTERRUPTS(CLBR_NONE)
        SAVE_REST
        /* Check for syscall exit trace */      
-       testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edx
+       testl $_TIF_WORK_SYSCALL_EXIT,%edx
        jz int_signal
        pushq %rdi
        CFI_ADJUST_CFA_OFFSET 8
@@ -491,7 +495,7 @@ int_very_careful:
        call syscall_trace_leave
        popq %rdi
        CFI_ADJUST_CFA_OFFSET -8
-       andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi
+       andl $~(_TIF_WORK_SYSCALL_EXIT|_TIF_SYSCALL_EMU),%edi
        jmp int_restore_rest
        
 int_signal:
@@ -1189,6 +1193,7 @@ END(device_not_available)
        /* runs on exception stack */
 KPROBE_ENTRY(debug)
        INTR_FRAME
+       PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq $0
        CFI_ADJUST_CFA_OFFSET 8         
        paranoidentry do_debug, DEBUG_STACK
@@ -1198,6 +1203,7 @@ KPROBE_END(debug)
        /* runs on exception stack */   
 KPROBE_ENTRY(nmi)
        INTR_FRAME
+       PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq $-1
        CFI_ADJUST_CFA_OFFSET 8
        paranoidentry do_nmi, 0, 0
@@ -1211,6 +1217,7 @@ KPROBE_END(nmi)
 
 KPROBE_ENTRY(int3)
        INTR_FRAME
+       PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq $0
        CFI_ADJUST_CFA_OFFSET 8
        paranoidentry do_int3, DEBUG_STACK
@@ -1237,6 +1244,7 @@ END(coprocessor_segment_overrun)
        /* runs on exception stack */
 ENTRY(double_fault)
        XCPT_FRAME
+       PARAVIRT_ADJUST_EXCEPTION_FRAME
        paranoidentry do_double_fault
        jmp paranoid_exit1
        CFI_ENDPROC
@@ -1253,6 +1261,7 @@ END(segment_not_present)
        /* runs on exception stack */
 ENTRY(stack_segment)
        XCPT_FRAME
+       PARAVIRT_ADJUST_EXCEPTION_FRAME
        paranoidentry do_stack_segment
        jmp paranoid_exit1
        CFI_ENDPROC
@@ -1278,6 +1287,7 @@ END(spurious_interrupt_bug)
        /* runs on exception stack */
 ENTRY(machine_check)
        INTR_FRAME
+       PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq $0
        CFI_ADJUST_CFA_OFFSET 8 
        paranoidentry do_machine_check
@@ -1312,3 +1322,103 @@ KPROBE_ENTRY(ignore_sysret)
        sysret
        CFI_ENDPROC
 ENDPROC(ignore_sysret)
+
+#ifdef CONFIG_XEN
+ENTRY(xen_hypervisor_callback)
+       zeroentry xen_do_hypervisor_callback
+END(xen_hypervisor_callback)
+
+/*
+# A note on the "critical region" in our callback handler.
+# We want to avoid stacking callback handlers due to events occurring
+# during handling of the last event. To do this, we keep events disabled
+# until we've done all processing. HOWEVER, we must enable events before
+# popping the stack frame (can't be done atomically) and so it would still
+# be possible to get enough handler activations to overflow the stack.
+# Although unlikely, bugs of that kind are hard to track down, so we'd
+# like to avoid the possibility.
+# So, on entry to the handler we detect whether we interrupted an
+# existing activation in its critical region -- if so, we pop the current
+# activation and restart the handler using the previous one.
+*/
+ENTRY(xen_do_hypervisor_callback)   # do_hypervisor_callback(struct *pt_regs)
+       CFI_STARTPROC
+/* Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will
+   see the correct pointer to the pt_regs */
+       movq %rdi, %rsp            # we don't return, adjust the stack frame
+       CFI_ENDPROC
+       CFI_DEFAULT_STACK
+11:    incl %gs:pda_irqcount
+       movq %rsp,%rbp
+       CFI_DEF_CFA_REGISTER rbp
+       cmovzq %gs:pda_irqstackptr,%rsp
+       pushq %rbp                      # backlink for old unwinder
+       call xen_evtchn_do_upcall
+       popq %rsp
+       CFI_DEF_CFA_REGISTER rsp
+       decl %gs:pda_irqcount
+       jmp  error_exit
+       CFI_ENDPROC
+END(do_hypervisor_callback)
+
+/*
+# Hypervisor uses this for application faults while it executes.
+# We get here for two reasons:
+#  1. Fault while reloading DS, ES, FS or GS
+#  2. Fault while executing IRET
+# Category 1 we do not need to fix up as Xen has already reloaded all segment
+# registers that could be reloaded and zeroed the others.
+# Category 2 we fix up by killing the current process. We cannot use the
+# normal Linux return path in this case because if we use the IRET hypercall
+# to pop the stack frame we end up in an infinite loop of failsafe callbacks.
+# We distinguish between categories by comparing each saved segment register
+# with its current contents: any discrepancy means we in category 1.
+*/
+ENTRY(xen_failsafe_callback)
+       framesz = (RIP-0x30)    /* workaround buggy gas */
+       _frame framesz
+       CFI_REL_OFFSET rcx, 0
+       CFI_REL_OFFSET r11, 8
+       movw %ds,%cx
+       cmpw %cx,0x10(%rsp)
+       CFI_REMEMBER_STATE
+       jne 1f
+       movw %es,%cx
+       cmpw %cx,0x18(%rsp)
+       jne 1f
+       movw %fs,%cx
+       cmpw %cx,0x20(%rsp)
+       jne 1f
+       movw %gs,%cx
+       cmpw %cx,0x28(%rsp)
+       jne 1f
+       /* All segments match their saved values => Category 2 (Bad IRET). */
+       movq (%rsp),%rcx
+       CFI_RESTORE rcx
+       movq 8(%rsp),%r11
+       CFI_RESTORE r11
+       addq $0x30,%rsp
+       CFI_ADJUST_CFA_OFFSET -0x30
+       pushq $0
+       CFI_ADJUST_CFA_OFFSET 8
+       pushq %r11
+       CFI_ADJUST_CFA_OFFSET 8
+       pushq %rcx
+       CFI_ADJUST_CFA_OFFSET 8
+       jmp general_protection
+       CFI_RESTORE_STATE
+1:     /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */
+       movq (%rsp),%rcx
+       CFI_RESTORE rcx
+       movq 8(%rsp),%r11
+       CFI_RESTORE r11
+       addq $0x30,%rsp
+       CFI_ADJUST_CFA_OFFSET -0x30
+       pushq $0
+       CFI_ADJUST_CFA_OFFSET 8
+       SAVE_ALL
+       jmp error_exit
+       CFI_ENDPROC
+END(xen_failsafe_callback)
+
+#endif /* CONFIG_XEN */
index 3e5d7b8698f91b70f6de1c63c674288bcf4b3b3c..2cfcbded888a0b91eece817e0eb3f49e865154fd 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/pgtable.h>
 #include <asm/uv/uv_mmrs.h>
 #include <asm/uv/uv_hub.h>
+#include <asm/uv/bios.h>
 
 DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
 EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);
@@ -40,6 +41,9 @@ EXPORT_SYMBOL_GPL(uv_cpu_to_blade);
 short uv_possible_blades;
 EXPORT_SYMBOL_GPL(uv_possible_blades);
 
+unsigned long sn_rtc_cycles_per_second;
+EXPORT_SYMBOL(sn_rtc_cycles_per_second);
+
 /* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
 
 static cpumask_t uv_target_cpus(void)
@@ -272,6 +276,23 @@ static __init void map_mmioh_high(int max_pnode)
                map_high("MMIOH", mmioh.s.base, shift, map_uc);
 }
 
+static __init void uv_rtc_init(void)
+{
+       long status, ticks_per_sec, drift;
+
+       status =
+           x86_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
+                                       &drift);
+       if (status != 0 || ticks_per_sec < 100000) {
+               printk(KERN_WARNING
+                       "unable to determine platform RTC clock frequency, "
+                       "guessing.\n");
+               /* BIOS gives wrong value for clock freq. so guess */
+               sn_rtc_cycles_per_second = 1000000000000UL / 30000UL;
+       } else
+               sn_rtc_cycles_per_second = ticks_per_sec;
+}
+
 static __init void uv_system_init(void)
 {
        union uvh_si_addr_map_config_u m_n_config;
@@ -326,6 +347,8 @@ static __init void uv_system_init(void)
        gnode_upper = (((unsigned long)node_id.s.node_id) &
                       ~((1 << n_val) - 1)) << m_val;
 
+       uv_rtc_init();
+
        for_each_present_cpu(cpu) {
                nid = cpu_to_node(cpu);
                pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu));
index c9781982914693cbb6ba98bf7cea94b1a291c8a5..1b318e903bf63f14bd4f514ad8fd5916289bb979 100644 (file)
@@ -39,6 +39,13 @@ static struct x8664_pda *__cpu_pda[NR_CPUS] __initdata;
 static struct x8664_pda *__cpu_pda[NR_CPUS] __read_mostly;
 #endif
 
+void __init x86_64_init_pda(void)
+{
+       _cpu_pda = __cpu_pda;
+       cpu_pda(0) = &_boot_cpu_pda;
+       pda_init(0);
+}
+
 static void __init zap_identity_mappings(void)
 {
        pgd_t *pgd = pgd_offset_k(0UL);
@@ -102,9 +109,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
 
        early_printk("Kernel alive\n");
 
-       _cpu_pda = __cpu_pda;
-       cpu_pda(0) = &_boot_cpu_pda;
-       pda_init(0);
+       x86_64_init_pda();
 
        early_printk("Kernel really alive\n");
 
index b07ac7b217cb161e2b4f35b1edf4677fe32f0d64..db3280afe886f1b97a9f2c383afc4ac80993a060 100644 (file)
@@ -407,6 +407,7 @@ ENTRY(phys_base)
        /* This must match the first entry in level2_kernel_pgt */
        .quad   0x0000000000000000
 
+#include "../../x86/xen/xen-head.S"
        
        .section .bss, "aw", @nobits
        .align L1_CACHE_BYTES
index 558abf4c796afa0d7dd7ad2622e3bd42f28e8d39..de9aa0e3a9c51e10df0e85403529e3aa285ad395 100644 (file)
@@ -756,7 +756,7 @@ void send_IPI_self(int vector)
        /*
         * Send the IPI. The write to APIC_ICR fires this off.
         */
-       apic_write_around(APIC_ICR, cfg);
+       apic_write(APIC_ICR, cfg);
 }
 #endif /* !CONFIG_SMP */
 
@@ -2030,7 +2030,7 @@ static void mask_lapic_irq(unsigned int irq)
        unsigned long v;
 
        v = apic_read(APIC_LVT0);
-       apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
+       apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
 }
 
 static void unmask_lapic_irq(unsigned int irq)
@@ -2038,7 +2038,7 @@ static void unmask_lapic_irq(unsigned int irq)
        unsigned long v;
 
        v = apic_read(APIC_LVT0);
-       apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED);
+       apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
 }
 
 static struct irq_chip lapic_chip __read_mostly = {
@@ -2168,7 +2168,7 @@ static inline void __init check_timer(void)
         * The AEOI mode will finish them in the 8259A
         * automatically.
         */
-       apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
+       apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
        init_8259A(1);
        timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
 
@@ -2177,8 +2177,9 @@ static inline void __init check_timer(void)
        pin2  = ioapic_i8259.pin;
        apic2 = ioapic_i8259.apic;
 
-       printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
-               vector, apic1, pin1, apic2, pin2);
+       apic_printk(APIC_QUIET, KERN_INFO "..TIMER: vector=0x%02X "
+                   "apic1=%d pin1=%d apic2=%d pin2=%d\n",
+                   vector, apic1, pin1, apic2, pin2);
 
        /*
         * Some BIOS writers are clueless and report the ExtINTA
@@ -2216,12 +2217,13 @@ static inline void __init check_timer(void)
                }
                clear_IO_APIC_pin(apic1, pin1);
                if (!no_pin1)
-                       printk(KERN_ERR "..MP-BIOS bug: "
-                              "8254 timer not connected to IO-APIC\n");
+                       apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
+                                   "8254 timer not connected to IO-APIC\n");
 
-               printk(KERN_INFO "...trying to set up timer (IRQ0) "
-                      "through the 8259A ... ");
-               printk("\n..... (found pin %d) ...", pin2);
+               apic_printk(APIC_QUIET, KERN_INFO "...trying to set up timer "
+                           "(IRQ0) through the 8259A ...\n");
+               apic_printk(APIC_QUIET, KERN_INFO
+                           "..... (found apic %d pin %d) ...\n", apic2, pin2);
                /*
                 * legacy devices should be connected to IO APIC #0
                 */
@@ -2230,7 +2232,7 @@ static inline void __init check_timer(void)
                unmask_IO_APIC_irq(0);
                enable_8259A_irq(0);
                if (timer_irq_works()) {
-                       printk("works.\n");
+                       apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
                        timer_through_8259 = 1;
                        if (nmi_watchdog == NMI_IO_APIC) {
                                disable_8259A_irq(0);
@@ -2244,44 +2246,47 @@ static inline void __init check_timer(void)
                 */
                disable_8259A_irq(0);
                clear_IO_APIC_pin(apic2, pin2);
-               printk(" failed.\n");
+               apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
        }
 
        if (nmi_watchdog == NMI_IO_APIC) {
-               printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
+               apic_printk(APIC_QUIET, KERN_WARNING "timer doesn't work "
+                           "through the IO-APIC - disabling NMI Watchdog!\n");
                nmi_watchdog = NMI_NONE;
        }
        timer_ack = 0;
 
-       printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
+       apic_printk(APIC_QUIET, KERN_INFO
+                   "...trying to set up timer as Virtual Wire IRQ...\n");
 
        lapic_register_intr(0, vector);
-       apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector);   /* Fixed mode */
+       apic_write(APIC_LVT0, APIC_DM_FIXED | vector);  /* Fixed mode */
        enable_8259A_irq(0);
 
        if (timer_irq_works()) {
-               printk(" works.\n");
+               apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
                goto out;
        }
        disable_8259A_irq(0);
-       apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
-       printk(" failed.\n");
+       apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
+       apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
 
-       printk(KERN_INFO "...trying to set up timer as ExtINT IRQ...");
+       apic_printk(APIC_QUIET, KERN_INFO
+                   "...trying to set up timer as ExtINT IRQ...\n");
 
        init_8259A(0);
        make_8259A_irq(0);
-       apic_write_around(APIC_LVT0, APIC_DM_EXTINT);
+       apic_write(APIC_LVT0, APIC_DM_EXTINT);
 
        unlock_ExtINT_logic();
 
        if (timer_irq_works()) {
-               printk(" works.\n");
+               apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
                goto out;
        }
-       printk(" failed :(.\n");
+       apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
        panic("IO-APIC + timer doesn't work!  Boot with apic=debug and send a "
-               "report.  Then try booting with the 'noapic' option");
+               "report.  Then try booting with the 'noapic' option.\n");
 out:
        local_irq_restore(flags);
 }
index a85db790754bf56a5b8af635802d652176737dac..8269434d170765a6466eb7039e2b849d8b0b5b18 100644 (file)
@@ -45,6 +45,7 @@
 #include <asm/proto.h>
 #include <asm/acpi.h>
 #include <asm/dma.h>
+#include <asm/i8259.h>
 #include <asm/nmi.h>
 #include <asm/msidef.h>
 #include <asm/hypertransport.h>
@@ -1694,8 +1695,9 @@ static inline void __init check_timer(void)
        pin2  = ioapic_i8259.pin;
        apic2 = ioapic_i8259.apic;
 
-       apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
-               cfg->vector, apic1, pin1, apic2, pin2);
+       apic_printk(APIC_QUIET, KERN_INFO "..TIMER: vector=0x%02X "
+                   "apic1=%d pin1=%d apic2=%d pin2=%d\n",
+                   cfg->vector, apic1, pin1, apic2, pin2);
 
        /*
         * Some BIOS writers are clueless and report the ExtINTA
@@ -1733,14 +1735,13 @@ static inline void __init check_timer(void)
                }
                clear_IO_APIC_pin(apic1, pin1);
                if (!no_pin1)
-                       apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: "
+                       apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
                                    "8254 timer not connected to IO-APIC\n");
 
-               apic_printk(APIC_VERBOSE,KERN_INFO
-                       "...trying to set up timer (IRQ0) "
-                       "through the 8259A ... ");
-               apic_printk(APIC_VERBOSE,"\n..... (found apic %d pin %d) ...",
-                       apic2, pin2);
+               apic_printk(APIC_QUIET, KERN_INFO "...trying to set up timer "
+                           "(IRQ0) through the 8259A ...\n");
+               apic_printk(APIC_QUIET, KERN_INFO
+                           "..... (found apic %d pin %d) ...\n", apic2, pin2);
                /*
                 * legacy devices should be connected to IO APIC #0
                 */
@@ -1749,7 +1750,7 @@ static inline void __init check_timer(void)
                unmask_IO_APIC_irq(0);
                enable_8259A_irq(0);
                if (timer_irq_works()) {
-                       apic_printk(APIC_VERBOSE," works.\n");
+                       apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
                        timer_through_8259 = 1;
                        if (nmi_watchdog == NMI_IO_APIC) {
                                disable_8259A_irq(0);
@@ -1763,29 +1764,32 @@ static inline void __init check_timer(void)
                 */
                disable_8259A_irq(0);
                clear_IO_APIC_pin(apic2, pin2);
-               apic_printk(APIC_VERBOSE," failed.\n");
+               apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
        }
 
        if (nmi_watchdog == NMI_IO_APIC) {
-               printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
+               apic_printk(APIC_QUIET, KERN_WARNING "timer doesn't work "
+                           "through the IO-APIC - disabling NMI Watchdog!\n");
                nmi_watchdog = NMI_NONE;
        }
 
-       apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
+       apic_printk(APIC_QUIET, KERN_INFO
+                   "...trying to set up timer as Virtual Wire IRQ...\n");
 
        lapic_register_intr(0);
        apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector);     /* Fixed mode */
        enable_8259A_irq(0);
 
        if (timer_irq_works()) {
-               apic_printk(APIC_VERBOSE," works.\n");
+               apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
                goto out;
        }
        disable_8259A_irq(0);
        apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
-       apic_printk(APIC_VERBOSE," failed.\n");
+       apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
 
-       apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as ExtINT IRQ...");
+       apic_printk(APIC_QUIET, KERN_INFO
+                   "...trying to set up timer as ExtINT IRQ...\n");
 
        init_8259A(0);
        make_8259A_irq(0);
@@ -1794,11 +1798,12 @@ static inline void __init check_timer(void)
        unlock_ExtINT_logic();
 
        if (timer_irq_works()) {
-               apic_printk(APIC_VERBOSE," works.\n");
+               apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
                goto out;
        }
-       apic_printk(APIC_VERBOSE," failed :(.\n");
-       panic("IO-APIC + timer doesn't work! Try using the 'noapic' kernel parameter\n");
+       apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
+       panic("IO-APIC + timer doesn't work!  Boot with apic=debug and send a "
+               "report.  Then try booting with the 'noapic' option.\n");
 out:
        local_irq_restore(flags);
 }
index 5921e5f0a64027745fa2ac3e5f695ceaca9ddeae..1c3a66a67f83d3bb6d7eec2d5e4cfb1560660720 100644 (file)
@@ -103,6 +103,9 @@ void __init io_delay_init(void)
 
 static int __init io_delay_param(char *s)
 {
+       if (!s)
+               return -EINVAL;
+
        if (!strcmp(s, "0x80"))
                io_delay_type = CONFIG_IO_DELAY_TYPE_0X80;
        else if (!strcmp(s, "0xed"))
index 9d98cda39ad9ea006729b999daec04c0e1e32d72..3f7537b669d312e08a6d92e92787feb0ae903549 100644 (file)
@@ -70,7 +70,7 @@ void __send_IPI_shortcut(unsigned int shortcut, int vector)
        /*
         * Send the IPI. The write to APIC_ICR fires this off.
         */
-       apic_write_around(APIC_ICR, cfg);
+       apic_write(APIC_ICR, cfg);
 }
 
 void send_IPI_self(int vector)
@@ -98,7 +98,7 @@ static inline void __send_IPI_dest_field(unsigned long mask, int vector)
         * prepare target chip field
         */
        cfg = __prepare_ICR2(mask);
-       apic_write_around(APIC_ICR2, cfg);
+       apic_write(APIC_ICR2, cfg);
 
        /*
         * program the ICR
@@ -108,7 +108,7 @@ static inline void __send_IPI_dest_field(unsigned long mask, int vector)
        /*
         * Send the IPI. The write to APIC_ICR fires this off.
         */
-       apic_write_around(APIC_ICR, cfg);
+       apic_write(APIC_ICR, cfg);
 }
 
 /*
index 47a6f6f124789a32179172920e4f6a436700ec50..1cf8c1fcc0889c5a066ddb2b7e150ece69dc1729 100644 (file)
@@ -83,11 +83,8 @@ union irq_ctx {
 static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
 static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
 
-static char softirq_stack[NR_CPUS * THREAD_SIZE]
-               __attribute__((__section__(".bss.page_aligned")));
-
-static char hardirq_stack[NR_CPUS * THREAD_SIZE]
-               __attribute__((__section__(".bss.page_aligned")));
+static char softirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss;
+static char hardirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss;
 
 static void call_on_stack(void *func, void *stack)
 {
index c03205991718b30da8adfed31d915f7f325b2aa0..f2d43bc7551488a61390c27cd429a9721fefbc26 100644 (file)
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 
 #include <asm/setup.h>
 
+struct dentry *arch_debugfs_dir;
+EXPORT_SYMBOL(arch_debugfs_dir);
+
 #ifdef CONFIG_DEBUG_BOOT_PARAMS
 struct setup_data_node {
        u64 paddr;
@@ -209,6 +213,10 @@ static int __init arch_kdebugfs_init(void)
 {
        int error = 0;
 
+       arch_debugfs_dir = debugfs_create_dir("x86", NULL);
+       if (!arch_debugfs_dir)
+               return -ENOMEM;
+
 #ifdef CONFIG_DEBUG_BOOT_PARAMS
        error = boot_params_kdebugfs_init();
 #endif
index b8c6743a13daddad0446d686d3f36436b3ac7531..43c019f85f0db749425e451957bd2279cee47b80 100644 (file)
@@ -860,7 +860,6 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
 
        resume_execution(cur, regs, kcb);
        regs->flags |= kcb->kprobe_saved_flags;
-       trace_hardirqs_fixup_flags(regs->flags);
 
        if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
                kcb->kprobe_status = KPROBE_HIT_SSDONE;
index 58520169e35dbbdfd7613a4648100197fbca7140..6994c751590ec14ea31b7418bfd4659722466b2e 100644 (file)
@@ -648,7 +648,9 @@ static void microcode_fini_cpu(int cpu)
        mutex_unlock(&microcode_mutex);
 }
 
-static ssize_t reload_store(struct sys_device *dev, const char *buf, size_t sz)
+static ssize_t reload_store(struct sys_device *dev,
+                           struct sysdev_attribute *attr,
+                           const char *buf, size_t sz)
 {
        struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
        char *end;
@@ -679,14 +681,16 @@ static ssize_t reload_store(struct sys_device *dev, const char *buf, size_t sz)
        return sz;
 }
 
-static ssize_t version_show(struct sys_device *dev, char *buf)
+static ssize_t version_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
 
        return sprintf(buf, "0x%x\n", uci->rev);
 }
 
-static ssize_t pf_show(struct sys_device *dev, char *buf)
+static ssize_t pf_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
 
index a888e67f5874dad3415220cc9fd0c9f962c4661c..0e867676b5a57ebd14b063bf71cdac852e2b4089 100644 (file)
@@ -150,7 +150,8 @@ int module_finalize(const Elf_Ehdr *hdr,
                     const Elf_Shdr *sechdrs,
                     struct module *me)
 {
-       const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL;
+       const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL,
+               *para = NULL;
        char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
 
        for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
@@ -160,6 +161,8 @@ int module_finalize(const Elf_Ehdr *hdr,
                        alt = s;
                if (!strcmp(".smp_locks", secstrings + s->sh_name))
                        locks= s;
+               if (!strcmp(".parainstructions", secstrings + s->sh_name))
+                       para = s;
        }
 
        if (alt) {
@@ -175,6 +178,11 @@ int module_finalize(const Elf_Ehdr *hdr,
                                            tseg, tseg + text->sh_size);
        }
 
+       if (para) {
+               void *pseg = (void *)para->sh_addr;
+               apply_paravirt(pseg, pseg + para->sh_size);
+       }
+
        return module_bug_finalize(hdr, sechdrs, me);
 }
 
index 3b25e49380c6eed8ff660d409afb2deda8c428cd..6ae005ccaed83bc46a6666f1d65b80baf7737f8d 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/bios_ebda.h>
 #include <asm/e820.h>
 #include <asm/trampoline.h>
+#include <asm/setup.h>
 
 #include <mach_apic.h>
 #ifdef CONFIG_X86_32
@@ -48,76 +49,6 @@ static int __init mpf_checksum(unsigned char *mp, int len)
        return sum & 0xFF;
 }
 
-#ifdef CONFIG_X86_NUMAQ
-int found_numaq;
-/*
- * Have to match translation table entries to main table entries by counter
- * hence the mpc_record variable .... can't see a less disgusting way of
- * doing this ....
- */
-struct mpc_config_translation {
-       unsigned char mpc_type;
-       unsigned char trans_len;
-       unsigned char trans_type;
-       unsigned char trans_quad;
-       unsigned char trans_global;
-       unsigned char trans_local;
-       unsigned short trans_reserved;
-};
-
-
-static int mpc_record;
-static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY]
-    __cpuinitdata;
-
-static inline int generate_logical_apicid(int quad, int phys_apicid)
-{
-       return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
-}
-
-
-static inline int mpc_apic_id(struct mpc_config_processor *m,
-                       struct mpc_config_translation *translation_record)
-{
-       int quad = translation_record->trans_quad;
-       int logical_apicid = generate_logical_apicid(quad, m->mpc_apicid);
-
-       printk(KERN_DEBUG "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
-              m->mpc_apicid,
-              (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
-              (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
-              m->mpc_apicver, quad, logical_apicid);
-       return logical_apicid;
-}
-
-int mp_bus_id_to_node[MAX_MP_BUSSES];
-
-int mp_bus_id_to_local[MAX_MP_BUSSES];
-
-static void mpc_oem_bus_info(struct mpc_config_bus *m, char *name,
-       struct mpc_config_translation *translation)
-{
-       int quad = translation->trans_quad;
-       int local = translation->trans_local;
-
-       mp_bus_id_to_node[m->mpc_busid] = quad;
-       mp_bus_id_to_local[m->mpc_busid] = local;
-       printk(KERN_INFO "Bus #%d is %s (node %d)\n",
-              m->mpc_busid, name, quad);
-}
-
-int quad_local_to_mp_bus_id [NR_CPUS/4][4];
-static void mpc_oem_pci_bus(struct mpc_config_bus *m,
-       struct mpc_config_translation *translation)
-{
-       int quad = translation->trans_quad;
-       int local = translation->trans_local;
-
-       quad_local_to_mp_bus_id[quad][local] = m->mpc_busid;
-}
-
-#endif
-
 static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
 {
        int apicid;
@@ -127,14 +58,12 @@ static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
                disabled_cpus++;
                return;
        }
-#ifdef CONFIG_X86_NUMAQ
-       if (found_numaq)
-               apicid = mpc_apic_id(m, translation_table[mpc_record]);
+
+       if (x86_quirks->mpc_apic_id)
+               apicid = x86_quirks->mpc_apic_id(m);
        else
                apicid = m->mpc_apicid;
-#else
-       apicid = m->mpc_apicid;
-#endif
+
        if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
                bootup_cpu = " (Bootup-CPU)";
                boot_cpu_physical_apicid = m->mpc_apicid;
@@ -151,12 +80,10 @@ static void __init MP_bus_info(struct mpc_config_bus *m)
        memcpy(str, m->mpc_bustype, 6);
        str[6] = 0;
 
-#ifdef CONFIG_X86_NUMAQ
-       if (found_numaq)
-               mpc_oem_bus_info(m, str, translation_table[mpc_record]);
-#else
-       printk(KERN_INFO "Bus #%d is %s\n", m->mpc_busid, str);
-#endif
+       if (x86_quirks->mpc_oem_bus_info)
+               x86_quirks->mpc_oem_bus_info(m, str);
+       else
+               printk(KERN_INFO "Bus #%d is %s\n", m->mpc_busid, str);
 
 #if MAX_MP_BUSSES < 256
        if (m->mpc_busid >= MAX_MP_BUSSES) {
@@ -173,10 +100,9 @@ static void __init MP_bus_info(struct mpc_config_bus *m)
                mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
 #endif
        } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) {
-#ifdef CONFIG_X86_NUMAQ
-               if (found_numaq)
-                       mpc_oem_pci_bus(m, translation_table[mpc_record]);
-#endif
+               if (x86_quirks->mpc_oem_pci_bus)
+                       x86_quirks->mpc_oem_pci_bus(m);
+
                clear_bit(m->mpc_busid, mp_bus_not_pci);
 #if defined(CONFIG_EISA) || defined (CONFIG_MCA)
                mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
@@ -316,83 +242,6 @@ static void __init MP_lintsrc_info(struct mpc_config_lintsrc *m)
                m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint);
 }
 
-#ifdef CONFIG_X86_NUMAQ
-static void __init MP_translation_info(struct mpc_config_translation *m)
-{
-       printk(KERN_INFO
-              "Translation: record %d, type %d, quad %d, global %d, local %d\n",
-              mpc_record, m->trans_type, m->trans_quad, m->trans_global,
-              m->trans_local);
-
-       if (mpc_record >= MAX_MPC_ENTRY)
-               printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
-       else
-               translation_table[mpc_record] = m;      /* stash this for later */
-       if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
-               node_set_online(m->trans_quad);
-}
-
-/*
- * Read/parse the MPC oem tables
- */
-
-static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable,
-                                   unsigned short oemsize)
-{
-       int count = sizeof(*oemtable);  /* the header size */
-       unsigned char *oemptr = ((unsigned char *)oemtable) + count;
-
-       mpc_record = 0;
-       printk(KERN_INFO "Found an OEM MPC table at %8p - parsing it ... \n",
-              oemtable);
-       if (memcmp(oemtable->oem_signature, MPC_OEM_SIGNATURE, 4)) {
-               printk(KERN_WARNING
-                      "SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
-                      oemtable->oem_signature[0], oemtable->oem_signature[1],
-                      oemtable->oem_signature[2], oemtable->oem_signature[3]);
-               return;
-       }
-       if (mpf_checksum((unsigned char *)oemtable, oemtable->oem_length)) {
-               printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
-               return;
-       }
-       while (count < oemtable->oem_length) {
-               switch (*oemptr) {
-               case MP_TRANSLATION:
-                       {
-                               struct mpc_config_translation *m =
-                                   (struct mpc_config_translation *)oemptr;
-                               MP_translation_info(m);
-                               oemptr += sizeof(*m);
-                               count += sizeof(*m);
-                               ++mpc_record;
-                               break;
-                       }
-               default:
-                       {
-                               printk(KERN_WARNING
-                                      "Unrecognised OEM table entry type! - %d\n",
-                                      (int)*oemptr);
-                               return;
-                       }
-               }
-       }
-}
-
-void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem,
-                                char *productid)
-{
-       if (strncmp(oem, "IBM NUMA", 8))
-               printk("Warning!  Not a NUMA-Q system!\n");
-       else
-               found_numaq = 1;
-
-       if (mpc->mpc_oemptr)
-               smp_read_mpc_oem((struct mp_config_oemtable *)mpc->mpc_oemptr,
-                                mpc->mpc_oemsize);
-}
-#endif /* CONFIG_X86_NUMAQ */
-
 /*
  * Read/parse the MPC
  */
@@ -457,7 +306,6 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
        } else
                mps_oem_check(mpc, oem, str);
 #endif
-
        /* save the local APIC address, it might be non-default */
        if (!acpi_lapic)
                mp_lapic_addr = mpc->mpc_lapic;
@@ -465,12 +313,17 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
        if (early)
                return 1;
 
+       if (mpc->mpc_oemptr && x86_quirks->smp_read_mpc_oem) {
+               struct mp_config_oemtable *oem_table = (struct mp_config_oemtable *)(unsigned long)mpc->mpc_oemptr;
+               x86_quirks->smp_read_mpc_oem(oem_table, mpc->mpc_oemsize);
+       }
+
        /*
         *      Now process the configuration blocks.
         */
-#ifdef CONFIG_X86_NUMAQ
-       mpc_record = 0;
-#endif
+       if (x86_quirks->mpc_record)
+               *x86_quirks->mpc_record = 0;
+
        while (count < mpc->mpc_length) {
                switch (*mpt) {
                case MP_PROCESSOR:
@@ -536,9 +389,8 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
                        count = mpc->mpc_length;
                        break;
                }
-#ifdef CONFIG_X86_NUMAQ
-               ++mpc_record;
-#endif
+               if (x86_quirks->mpc_record)
+                       (*x86_quirks->mpc_record)++;
        }
 
 #ifdef CONFIG_X86_GENERICARCH
@@ -725,12 +577,6 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
 
 static struct intel_mp_floating *mpf_found;
 
-/*
- * Machine specific quirk for finding the SMP config before other setup
- * activities destroy the table:
- */
-int (*mach_get_smp_config_quirk)(unsigned int early);
-
 /*
  * Scan the memory blocks for an SMP configuration block.
  */
@@ -738,8 +584,8 @@ static void __init __get_smp_config(unsigned int early)
 {
        struct intel_mp_floating *mpf = mpf_found;
 
-       if (mach_get_smp_config_quirk) {
-               if (mach_get_smp_config_quirk(early))
+       if (x86_quirks->mach_get_smp_config) {
+               if (x86_quirks->mach_get_smp_config(early))
                        return;
        }
        if (acpi_lapic && early)
@@ -899,14 +745,12 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
        return 0;
 }
 
-int (*mach_find_smp_config_quirk)(unsigned int reserve);
-
 static void __init __find_smp_config(unsigned int reserve)
 {
        unsigned int address;
 
-       if (mach_find_smp_config_quirk) {
-               if (mach_find_smp_config_quirk(reserve))
+       if (x86_quirks->mach_find_smp_config) {
+               if (x86_quirks->mach_find_smp_config(reserve))
                        return;
        }
        /*
index a153b3905f60591cb6fb627cad9dcc6e529e25cb..9fd8095524474aa7ef0a999c2746c92c8a166565 100644 (file)
@@ -149,8 +149,8 @@ static int __cpuinit msr_device_create(int cpu)
 {
        struct device *dev;
 
-       dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu),
-                           "msr%d", cpu);
+       dev = device_create_drvdata(msr_class, NULL, MKDEV(MSR_MAJOR, cpu),
+                                   NULL, "msr%d", cpu);
        return IS_ERR(dev) ? PTR_ERR(dev) : 0;
 }
 
index ec024b3baad0764821c036d0aa2552397f76f017..ac6d51222e7d3562abb1e7b5e8bd4a16a1c1c1f4 100644 (file)
@@ -263,7 +263,7 @@ late_initcall(init_lapic_nmi_sysfs);
 
 static void __acpi_nmi_enable(void *__unused)
 {
-       apic_write_around(APIC_LVT0, APIC_DM_NMI);
+       apic_write(APIC_LVT0, APIC_DM_NMI);
 }
 
 /*
@@ -277,7 +277,7 @@ void acpi_nmi_enable(void)
 
 static void __acpi_nmi_disable(void *__unused)
 {
-       apic_write_around(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED);
+       apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED);
 }
 
 /*
@@ -448,6 +448,13 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason)
 
 #ifdef CONFIG_SYSCTL
 
+static int __init setup_unknown_nmi_panic(char *str)
+{
+       unknown_nmi_panic = 1;
+       return 1;
+}
+__setup("unknown_nmi_panic", setup_unknown_nmi_panic);
+
 static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
 {
        unsigned char reason = get_nmi_reason();
index a23e8233b9ac59b8afbb0634be2a0c318defd652..b8c45610b20a89a6f52f9b266d68de042d688168 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/processor.h>
 #include <asm/mpspec.h>
 #include <asm/e820.h>
+#include <asm/setup.h>
 
 #define        MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT))
 
@@ -71,6 +72,188 @@ static void __init smp_dump_qct(void)
        }
 }
 
+
+void __init numaq_tsc_disable(void)
+{
+       if (!found_numaq)
+               return;
+
+       if (num_online_nodes() > 1) {
+               printk(KERN_DEBUG "NUMAQ: disabling TSC\n");
+               setup_clear_cpu_cap(X86_FEATURE_TSC);
+       }
+}
+
+static int __init numaq_pre_time_init(void)
+{
+       numaq_tsc_disable();
+       return 0;
+}
+
+int found_numaq;
+/*
+ * Have to match translation table entries to main table entries by counter
+ * hence the mpc_record variable .... can't see a less disgusting way of
+ * doing this ....
+ */
+struct mpc_config_translation {
+       unsigned char mpc_type;
+       unsigned char trans_len;
+       unsigned char trans_type;
+       unsigned char trans_quad;
+       unsigned char trans_global;
+       unsigned char trans_local;
+       unsigned short trans_reserved;
+};
+
+/* x86_quirks member */
+static int mpc_record;
+static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY]
+    __cpuinitdata;
+
+static inline int generate_logical_apicid(int quad, int phys_apicid)
+{
+       return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
+}
+
+/* x86_quirks member */
+static int mpc_apic_id(struct mpc_config_processor *m)
+{
+       int quad = translation_table[mpc_record]->trans_quad;
+       int logical_apicid = generate_logical_apicid(quad, m->mpc_apicid);
+
+       printk(KERN_DEBUG "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
+              m->mpc_apicid,
+              (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
+              (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
+              m->mpc_apicver, quad, logical_apicid);
+       return logical_apicid;
+}
+
+int mp_bus_id_to_node[MAX_MP_BUSSES];
+
+int mp_bus_id_to_local[MAX_MP_BUSSES];
+
+/* x86_quirks member */
+static void mpc_oem_bus_info(struct mpc_config_bus *m, char *name)
+{
+       int quad = translation_table[mpc_record]->trans_quad;
+       int local = translation_table[mpc_record]->trans_local;
+
+       mp_bus_id_to_node[m->mpc_busid] = quad;
+       mp_bus_id_to_local[m->mpc_busid] = local;
+       printk(KERN_INFO "Bus #%d is %s (node %d)\n",
+              m->mpc_busid, name, quad);
+}
+
+int quad_local_to_mp_bus_id [NR_CPUS/4][4];
+
+/* x86_quirks member */
+static void mpc_oem_pci_bus(struct mpc_config_bus *m)
+{
+       int quad = translation_table[mpc_record]->trans_quad;
+       int local = translation_table[mpc_record]->trans_local;
+
+       quad_local_to_mp_bus_id[quad][local] = m->mpc_busid;
+}
+
+static void __init MP_translation_info(struct mpc_config_translation *m)
+{
+       printk(KERN_INFO
+              "Translation: record %d, type %d, quad %d, global %d, local %d\n",
+              mpc_record, m->trans_type, m->trans_quad, m->trans_global,
+              m->trans_local);
+
+       if (mpc_record >= MAX_MPC_ENTRY)
+               printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
+       else
+               translation_table[mpc_record] = m;      /* stash this for later */
+       if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
+               node_set_online(m->trans_quad);
+}
+
+static int __init mpf_checksum(unsigned char *mp, int len)
+{
+       int sum = 0;
+
+       while (len--)
+               sum += *mp++;
+
+       return sum & 0xFF;
+}
+
+/*
+ * Read/parse the MPC oem tables
+ */
+
+static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable,
+                                   unsigned short oemsize)
+{
+       int count = sizeof(*oemtable);  /* the header size */
+       unsigned char *oemptr = ((unsigned char *)oemtable) + count;
+
+       mpc_record = 0;
+       printk(KERN_INFO "Found an OEM MPC table at %8p - parsing it ... \n",
+              oemtable);
+       if (memcmp(oemtable->oem_signature, MPC_OEM_SIGNATURE, 4)) {
+               printk(KERN_WARNING
+                      "SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
+                      oemtable->oem_signature[0], oemtable->oem_signature[1],
+                      oemtable->oem_signature[2], oemtable->oem_signature[3]);
+               return;
+       }
+       if (mpf_checksum((unsigned char *)oemtable, oemtable->oem_length)) {
+               printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
+               return;
+       }
+       while (count < oemtable->oem_length) {
+               switch (*oemptr) {
+               case MP_TRANSLATION:
+                       {
+                               struct mpc_config_translation *m =
+                                   (struct mpc_config_translation *)oemptr;
+                               MP_translation_info(m);
+                               oemptr += sizeof(*m);
+                               count += sizeof(*m);
+                               ++mpc_record;
+                               break;
+                       }
+               default:
+                       {
+                               printk(KERN_WARNING
+                                      "Unrecognised OEM table entry type! - %d\n",
+                                      (int)*oemptr);
+                               return;
+                       }
+               }
+       }
+}
+
+static struct x86_quirks numaq_x86_quirks __initdata = {
+       .arch_pre_time_init     = numaq_pre_time_init,
+       .arch_time_init         = NULL,
+       .arch_pre_intr_init     = NULL,
+       .arch_memory_setup      = NULL,
+       .arch_intr_init         = NULL,
+       .arch_trap_init         = NULL,
+       .mach_get_smp_config    = NULL,
+       .mach_find_smp_config   = NULL,
+       .mpc_record             = &mpc_record,
+       .mpc_apic_id            = mpc_apic_id,
+       .mpc_oem_bus_info       = mpc_oem_bus_info,
+       .mpc_oem_pci_bus        = mpc_oem_pci_bus,
+       .smp_read_mpc_oem       = smp_read_mpc_oem,
+};
+
+void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem,
+                                char *productid)
+{
+       if (strncmp(oem, "IBM NUMA", 8))
+               printk("Warning!  Not a NUMA-Q system!\n");
+       else
+               found_numaq = 1;
+}
+
 static __init void early_check_numaq(void)
 {
        /*
@@ -82,6 +265,9 @@ static __init void early_check_numaq(void)
         */
        if (smp_found_config)
                early_get_smp_config();
+
+       if (found_numaq)
+               x86_quirks = &numaq_x86_quirks;
 }
 
 int __init get_memcfg_numaq(void)
@@ -92,14 +278,3 @@ int __init get_memcfg_numaq(void)
        smp_dump_qct();
        return 1;
 }
-
-void __init numaq_tsc_disable(void)
-{
-       if (!found_numaq)
-               return;
-
-       if (num_online_nodes() > 1) {
-               printk(KERN_DEBUG "NUMAQ: disabling TSC\n");
-               setup_clear_cpu_cap(X86_FEATURE_TSC);
-       }
-}
index e0f571d58c19c0bfa4eeee39d89972ed2239f55f..94da4d52d798e8490f21c59c777df72d6bba86d5 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/desc.h>
 #include <asm/setup.h>
 #include <asm/arch_hooks.h>
+#include <asm/pgtable.h>
 #include <asm/time.h>
 #include <asm/pgalloc.h>
 #include <asm/irq.h>
@@ -123,6 +124,7 @@ static void *get_call_destination(u8 type)
                .pv_irq_ops = pv_irq_ops,
                .pv_apic_ops = pv_apic_ops,
                .pv_mmu_ops = pv_mmu_ops,
+               .pv_lock_ops = pv_lock_ops,
        };
        return *((void **)&tmpl + type);
 }
@@ -266,6 +268,17 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
        return __get_cpu_var(paravirt_lazy_mode);
 }
 
+void __init paravirt_use_bytelocks(void)
+{
+#ifdef CONFIG_SMP
+       pv_lock_ops.spin_is_locked = __byte_spin_is_locked;
+       pv_lock_ops.spin_is_contended = __byte_spin_is_contended;
+       pv_lock_ops.spin_lock = __byte_spin_lock;
+       pv_lock_ops.spin_trylock = __byte_spin_trylock;
+       pv_lock_ops.spin_unlock = __byte_spin_unlock;
+#endif
+}
+
 struct pv_info pv_info = {
        .name = "bare hardware",
        .paravirt_enabled = 0,
@@ -361,7 +374,6 @@ struct pv_cpu_ops pv_cpu_ops = {
 struct pv_apic_ops pv_apic_ops = {
 #ifdef CONFIG_X86_LOCAL_APIC
        .apic_write = native_apic_write,
-       .apic_write_atomic = native_apic_write_atomic,
        .apic_read = native_apic_read,
        .setup_boot_clock = setup_boot_APIC_clock,
        .setup_secondary_clock = setup_secondary_APIC_clock,
@@ -373,6 +385,9 @@ struct pv_mmu_ops pv_mmu_ops = {
 #ifndef CONFIG_X86_64
        .pagetable_setup_start = native_pagetable_setup_start,
        .pagetable_setup_done = native_pagetable_setup_done,
+#else
+       .pagetable_setup_start = paravirt_nop,
+       .pagetable_setup_done = paravirt_nop,
 #endif
 
        .read_cr2 = native_read_cr2,
@@ -428,7 +443,7 @@ struct pv_mmu_ops pv_mmu_ops = {
 #endif /* PAGETABLE_LEVELS >= 3 */
 
        .pte_val = native_pte_val,
-       .pte_flags = native_pte_val,
+       .pte_flags = native_pte_flags,
        .pgd_val = native_pgd_val,
 
        .make_pte = native_make_pte,
@@ -446,6 +461,18 @@ struct pv_mmu_ops pv_mmu_ops = {
        .set_fixmap = native_set_fixmap,
 };
 
+struct pv_lock_ops pv_lock_ops = {
+#ifdef CONFIG_SMP
+       .spin_is_locked = __ticket_spin_is_locked,
+       .spin_is_contended = __ticket_spin_is_contended,
+
+       .spin_lock = __ticket_spin_lock,
+       .spin_trylock = __ticket_spin_trylock,
+       .spin_unlock = __ticket_spin_unlock,
+#endif
+};
+EXPORT_SYMBOL_GPL(pv_lock_ops);
+
 EXPORT_SYMBOL_GPL(pv_time_ops);
 EXPORT_SYMBOL    (pv_cpu_ops);
 EXPORT_SYMBOL    (pv_mmu_ops);
index 6959b5c45df4546f28c2ef962fdc197d7afbfe3a..151f2d171f7c7386b7a14f574d4c7f34edfab0f3 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/delay.h>
 #include <linux/scatterlist.h>
 #include <linux/iommu-helper.h>
-#include <asm/gart.h>
+#include <asm/iommu.h>
 #include <asm/calgary.h>
 #include <asm/tce.h>
 #include <asm/pci-direct.h>
index 8467ec2320f178584afb402cfb2b48859a3eb48e..cbecb05551bbcefeb68e6048bd1dd5aeab5376f7 100644 (file)
@@ -5,12 +5,11 @@
 
 #include <asm/proto.h>
 #include <asm/dma.h>
-#include <asm/gart.h>
+#include <asm/iommu.h>
 #include <asm/calgary.h>
 #include <asm/amd_iommu.h>
 
-int forbid_dac __read_mostly;
-EXPORT_SYMBOL(forbid_dac);
+static int forbid_dac __read_mostly;
 
 const struct dma_mapping_ops *dma_ops;
 EXPORT_SYMBOL(dma_ops);
@@ -114,21 +113,15 @@ void __init pci_iommu_alloc(void)
         * The order of these functions is important for
         * fall-back/fail-over reasons
         */
-#ifdef CONFIG_GART_IOMMU
        gart_iommu_hole_init();
-#endif
 
-#ifdef CONFIG_CALGARY_IOMMU
        detect_calgary();
-#endif
 
        detect_intel_iommu();
 
        amd_iommu_detect();
 
-#ifdef CONFIG_SWIOTLB
        pci_swiotlb_init();
-#endif
 }
 #endif
 
@@ -184,9 +177,7 @@ static __init int iommu_setup(char *p)
                        swiotlb = 1;
 #endif
 
-#ifdef CONFIG_GART_IOMMU
                gart_parse_options(p);
-#endif
 
 #ifdef CONFIG_CALGARY_IOMMU
                if (!strncmp(p, "calgary", 7))
@@ -323,8 +314,7 @@ int dma_supported(struct device *dev, u64 mask)
 {
 #ifdef CONFIG_PCI
        if (mask > 0xffffffff && forbid_dac > 0) {
-               printk(KERN_INFO "PCI: Disallowing DAC for device %s\n",
-                                dev->bus_id);
+               dev_info(dev, "PCI: Disallowing DAC for device\n");
                return 0;
        }
 #endif
@@ -351,8 +341,7 @@ int dma_supported(struct device *dev, u64 mask)
           type. Normally this doesn't make any difference, but gives
           more gentle handling of IOMMU overflow. */
        if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) {
-               printk(KERN_INFO "%s: Force SAC with mask %Lx\n",
-                                dev->bus_id, mask);
+               dev_info(dev, "Force SAC with mask %Lx\n", mask);
                return 0;
        }
 
@@ -500,17 +489,13 @@ EXPORT_SYMBOL(dma_free_coherent);
 
 static int __init pci_iommu_init(void)
 {
-#ifdef CONFIG_CALGARY_IOMMU
        calgary_iommu_init();
-#endif
 
        intel_iommu_init();
 
        amd_iommu_init();
 
-#ifdef CONFIG_GART_IOMMU
        gart_iommu_init();
-#endif
 
        no_iommu_init();
        return 0;
index c3fe78406d1897b40e380f0528cf4db832d0a191..df5f142657d27352a9e3c1bbd911fd89f677c1fa 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/mtrr.h>
 #include <asm/pgtable.h>
 #include <asm/proto.h>
+#include <asm/iommu.h>
 #include <asm/gart.h>
 #include <asm/cacheflush.h>
 #include <asm/swiotlb.h>
@@ -197,9 +198,7 @@ static void iommu_full(struct device *dev, size_t size, int dir)
         * out. Hopefully no network devices use single mappings that big.
         */
 
-       printk(KERN_ERR
-               "PCI-DMA: Out of IOMMU space for %lu bytes at device %s\n",
-               size, dev->bus_id);
+       dev_err(dev, "PCI-DMA: Out of IOMMU space for %lu bytes\n", size);
 
        if (size > PAGE_SIZE*EMERGENCY_PAGES) {
                if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
index aec43d56f49c57cedffaefad7205fbbfe9b984c2..792b9179eff315ecf3ae26e7e1635073e1a42c26 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/scatterlist.h>
 
-#include <asm/gart.h>
+#include <asm/iommu.h>
 #include <asm/processor.h>
 #include <asm/dma.h>
 
index 82299cd1d04d452fea6ba6069fb3297a8824f7de..20df839b9c2012c12fa082c7b42ada6e63879a87 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
 
-#include <asm/gart.h>
+#include <asm/iommu.h>
 #include <asm/swiotlb.h>
 #include <asm/dma.h>
 
index 4d629c62f4f8fbb993a49c0d5f12d7e88bbd94b5..7fc4d5b0a6a0f99a4d1d9c4df685a5a4d3a135bb 100644 (file)
@@ -15,6 +15,7 @@ unsigned long idle_nomwait;
 EXPORT_SYMBOL(idle_nomwait);
 
 struct kmem_cache *task_xstate_cachep;
+static int force_mwait __cpuinitdata;
 
 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 {
@@ -199,6 +200,7 @@ static void poll_idle(void)
  *
  * idle=mwait overrides this decision and forces the usage of mwait.
  */
+static int __cpuinitdata force_mwait;
 
 #define MWAIT_INFO                     0x05
 #define MWAIT_ECX_EXTENDED_INFO                0x01
@@ -326,6 +328,9 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
 
 static int __init idle_setup(char *str)
 {
+       if (!str)
+               return -EINVAL;
+
        if (!strcmp(str, "poll")) {
                printk("using polling idle threads.\n");
                pm_idle = poll_idle;
index a8e53626ac9aaf5fc8290908aaf42552556a1b11..e8a8e1b998176fba76076a6a9b0c9d432f6f3922 100644 (file)
@@ -537,8 +537,8 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
 struct task_struct *
 __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 {
-       struct thread_struct *prev = &prev_p->thread,
-                                *next = &next_p->thread;
+       struct thread_struct *prev = &prev_p->thread;
+       struct thread_struct *next = &next_p->thread;
        int cpu = smp_processor_id();
        struct tss_struct *tss = &per_cpu(init_tss, cpu);
        unsigned fsindex, gsindex;
@@ -586,35 +586,34 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
        /* 
         * Switch FS and GS.
+        *
+        * Segment register != 0 always requires a reload.  Also
+        * reload when it has changed.  When prev process used 64bit
+        * base always reload to avoid an information leak.
         */
-       { 
-               /* segment register != 0 always requires a reload. 
-                  also reload when it has changed. 
-                  when prev process used 64bit base always reload
-                  to avoid an information leak. */
-               if (unlikely(fsindex | next->fsindex | prev->fs)) {
-                       loadsegment(fs, next->fsindex);
-                       /* check if the user used a selector != 0
-                        * if yes clear 64bit base, since overloaded base
-                         * is always mapped to the Null selector
-                         */
-                       if (fsindex)
+       if (unlikely(fsindex | next->fsindex | prev->fs)) {
+               loadsegment(fs, next->fsindex);
+               /* 
+                * Check if the user used a selector != 0; if yes
+                *  clear 64bit base, since overloaded base is always
+                *  mapped to the Null selector
+                */
+               if (fsindex)
                        prev->fs = 0;                           
-               }
-               /* when next process has a 64bit base use it */
-               if (next->fs) 
-                       wrmsrl(MSR_FS_BASE, next->fs); 
-               prev->fsindex = fsindex;
-
-               if (unlikely(gsindex | next->gsindex | prev->gs)) {
-                       load_gs_index(next->gsindex);
-                       if (gsindex)
+       }
+       /* when next process has a 64bit base use it */
+       if (next->fs)
+               wrmsrl(MSR_FS_BASE, next->fs);
+       prev->fsindex = fsindex;
+
+       if (unlikely(gsindex | next->gsindex | prev->gs)) {
+               load_gs_index(next->gsindex);
+               if (gsindex)
                        prev->gs = 0;                           
-               }
-               if (next->gs)
-                       wrmsrl(MSR_KERNEL_GS_BASE, next->gs); 
-               prev->gsindex = gsindex;
        }
+       if (next->gs)
+               wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
+       prev->gsindex = gsindex;
 
        /* Must be after DS reload */
        unlazy_fpu(prev_p);
@@ -627,7 +626,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        write_pda(pcurrent, next_p); 
 
        write_pda(kernelstack,
-       (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
+                 (unsigned long)task_stack_page(next_p) +
+                 THREAD_SIZE - PDA_STACKOFFSET);
 #ifdef CONFIG_CC_STACKPROTECTOR
        write_pda(stack_canary, next_p->stack_canary);
        /*
index 77040b6070e18c00ce71f788efa0d40d5a156229..e37dccce85db5e15922602b833a3821b78ca4ffd 100644 (file)
@@ -1357,8 +1357,6 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
 #endif
 }
 
-#ifdef CONFIG_X86_32
-
 void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
 {
        struct siginfo info;
@@ -1377,89 +1375,10 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
        force_sig_info(SIGTRAP, &info, tsk);
 }
 
-/* notification of system call entry/exit
- * - triggered by current->work.syscall_trace
- */
-int do_syscall_trace(struct pt_regs *regs, int entryexit)
-{
-       int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU);
-       /*
-        * With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP for syscall
-        * interception
-        */
-       int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP);
-       int ret = 0;
-
-       /* do the secure computing check first */
-       if (!entryexit)
-               secure_computing(regs->orig_ax);
-
-       if (unlikely(current->audit_context)) {
-               if (entryexit)
-                       audit_syscall_exit(AUDITSC_RESULT(regs->ax),
-                                               regs->ax);
-               /* Debug traps, when using PTRACE_SINGLESTEP, must be sent only
-                * on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is
-                * not used, entry.S will call us only on syscall exit, not
-                * entry; so when TIF_SYSCALL_AUDIT is used we must avoid
-                * calling send_sigtrap() on syscall entry.
-                *
-                * Note that when PTRACE_SYSEMU_SINGLESTEP is used,
-                * is_singlestep is false, despite his name, so we will still do
-                * the correct thing.
-                */
-               else if (is_singlestep)
-                       goto out;
-       }
-
-       if (!(current->ptrace & PT_PTRACED))
-               goto out;
-
-       /* If a process stops on the 1st tracepoint with SYSCALL_TRACE
-        * and then is resumed with SYSEMU_SINGLESTEP, it will come in
-        * here. We have to check this and return */
-       if (is_sysemu && entryexit)
-               return 0;
-
-       /* Fake a debug trap */
-       if (is_singlestep)
-               send_sigtrap(current, regs, 0);
-
-       if (!test_thread_flag(TIF_SYSCALL_TRACE) && !is_sysemu)
-               goto out;
-
-       /* the 0x80 provides a way for the tracing parent to distinguish
-          between a syscall stop and SIGTRAP delivery */
-       /* Note that the debugger could change the result of test_thread_flag!*/
-       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80:0));
-
-       /*
-        * this isn't the same as continuing with a signal, but it will do
-        * for normal use.  strace only continues with a signal if the
-        * stopping signal is not SIGTRAP.  -brl
-        */
-       if (current->exit_code) {
-               send_sig(current->exit_code, current, 1);
-               current->exit_code = 0;
-       }
-       ret = is_sysemu;
-out:
-       if (unlikely(current->audit_context) && !entryexit)
-               audit_syscall_entry(AUDIT_ARCH_I386, regs->orig_ax,
-                                   regs->bx, regs->cx, regs->dx, regs->si);
-       if (ret == 0)
-               return 0;
-
-       regs->orig_ax = -1; /* force skip of syscall restarting */
-       if (unlikely(current->audit_context))
-               audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
-       return 1;
-}
-
-#else  /* CONFIG_X86_64 */
-
 static void syscall_trace(struct pt_regs *regs)
 {
+       if (!(current->ptrace & PT_PTRACED))
+               return;
 
 #if 0
        printk("trace %s ip %lx sp %lx ax %d origrax %d caller %lx tiflags %x ptrace %x\n",
@@ -1481,39 +1400,81 @@ static void syscall_trace(struct pt_regs *regs)
        }
 }
 
-asmlinkage void syscall_trace_enter(struct pt_regs *regs)
+#ifdef CONFIG_X86_32
+# define IS_IA32       1
+#elif defined CONFIG_IA32_EMULATION
+# define IS_IA32       test_thread_flag(TIF_IA32)
+#else
+# define IS_IA32       0
+#endif
+
+/*
+ * We must return the syscall number to actually look up in the table.
+ * This can be -1L to skip running any syscall at all.
+ */
+asmregparm long syscall_trace_enter(struct pt_regs *regs)
 {
+       long ret = 0;
+
+       /*
+        * If we stepped into a sysenter/syscall insn, it trapped in
+        * kernel mode; do_debug() cleared TF and set TIF_SINGLESTEP.
+        * If user-mode had set TF itself, then it's still clear from
+        * do_debug() and we need to set it again to restore the user
+        * state.  If we entered on the slow path, TF was already set.
+        */
+       if (test_thread_flag(TIF_SINGLESTEP))
+               regs->flags |= X86_EFLAGS_TF;
+
        /* do the secure computing check first */
        secure_computing(regs->orig_ax);
 
-       if (test_thread_flag(TIF_SYSCALL_TRACE)
-           && (current->ptrace & PT_PTRACED))
+       if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
+               ret = -1L;
+
+       if (ret || test_thread_flag(TIF_SYSCALL_TRACE))
                syscall_trace(regs);
 
        if (unlikely(current->audit_context)) {
-               if (test_thread_flag(TIF_IA32)) {
+               if (IS_IA32)
                        audit_syscall_entry(AUDIT_ARCH_I386,
                                            regs->orig_ax,
                                            regs->bx, regs->cx,
                                            regs->dx, regs->si);
-               } else {
+#ifdef CONFIG_X86_64
+               else
                        audit_syscall_entry(AUDIT_ARCH_X86_64,
                                            regs->orig_ax,
                                            regs->di, regs->si,
                                            regs->dx, regs->r10);
-               }
+#endif
        }
+
+       return ret ?: regs->orig_ax;
 }
 
-asmlinkage void syscall_trace_leave(struct pt_regs *regs)
+asmregparm void syscall_trace_leave(struct pt_regs *regs)
 {
        if (unlikely(current->audit_context))
                audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
 
-       if ((test_thread_flag(TIF_SYSCALL_TRACE)
-            || test_thread_flag(TIF_SINGLESTEP))
-           && (current->ptrace & PT_PTRACED))
+       if (test_thread_flag(TIF_SYSCALL_TRACE))
                syscall_trace(regs);
-}
 
-#endif /* CONFIG_X86_32 */
+       /*
+        * If TIF_SYSCALL_EMU is set, we only get here because of
+        * TIF_SINGLESTEP (i.e. this is PTRACE_SYSEMU_SINGLESTEP).
+        * We already reported this syscall instruction in
+        * syscall_trace_enter(), so don't do any more now.
+        */
+       if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
+               return;
+
+       /*
+        * If we are single-stepping, synthesize a trap to follow the
+        * system call instruction.
+        */
+       if (test_thread_flag(TIF_SINGLESTEP) &&
+           (current->ptrace & PT_PTRACED))
+               send_sigtrap(current, regs, 0);
+}
index 214bbdfc851e274bd616fa1a981920ee61f76179..06a9f643817ee0310d1dce58da6a86f30b5c23cd 100644 (file)
@@ -177,6 +177,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"),
                },
        },
+       {       /* Handle problems with rebooting on Dell T5400's */
+               .callback = set_bios_reboot,
+               .ident = "Dell Precision T5400",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation T5400"),
+               },
+       },
        {       /* Handle problems with rebooting on HP laptops */
                .callback = set_bios_reboot,
                .ident = "HP Compaq Laptop",
index 531b55b8e81a1de1827eac5691d5f8aef1d8d10c..b4aacb9f52e3e29295acd3e8920df9306a8e8308 100644 (file)
 #include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/delay.h>
-#include <linux/highmem.h>
 
 #include <linux/kallsyms.h>
-#include <linux/edd.h>
-#include <linux/iscsi_ibft.h>
-#include <linux/kexec.h>
 #include <linux/cpufreq.h>
 #include <linux/dma-mapping.h>
 #include <linux/ctype.h>
@@ -96,7 +92,7 @@
 #include <asm/smp.h>
 #include <asm/desc.h>
 #include <asm/dma.h>
-#include <asm/gart.h>
+#include <asm/iommu.h>
 #include <asm/mmu_context.h>
 #include <asm/proto.h>
 
 #include <asm/paravirt.h>
 
 #include <asm/percpu.h>
-#include <asm/sections.h>
 #include <asm/topology.h>
 #include <asm/apicdef.h>
 #ifdef CONFIG_X86_64
@@ -579,6 +574,10 @@ static int __init setup_elfcorehdr(char *arg)
 early_param("elfcorehdr", setup_elfcorehdr);
 #endif
 
+static struct x86_quirks default_x86_quirks __initdata;
+
+struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
+
 /*
  * Determine if we were loaded by an EFI loader.  If so, then we have also been
  * passed the efi memmap, systab, etc., so we should use these data structures
@@ -681,7 +680,7 @@ void __init setup_arch(char **cmdline_p)
 #ifdef CONFIG_X86_LOCAL_APIC
                disable_apic = 1;
 #endif
-               clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
+               setup_clear_cpu_cap(X86_FEATURE_APIC);
        }
 
 #ifdef CONFIG_PCI
@@ -824,7 +823,10 @@ void __init setup_arch(char **cmdline_p)
        vmi_init();
 #endif
 
+       paravirt_pagetable_setup_start(swapper_pg_dir);
        paging_init();
+       paravirt_pagetable_setup_done(swapper_pg_dir);
+       paravirt_post_allocator_init();
 
 #ifdef CONFIG_X86_64
        map_vsyscall();
@@ -854,14 +856,6 @@ void __init setup_arch(char **cmdline_p)
        init_cpu_to_node();
 #endif
 
-#ifdef CONFIG_X86_NUMAQ
-       /*
-        * need to check online nodes num, call it
-        * here before time_init/tsc_init
-        */
-       numaq_tsc_disable();
-#endif
-
        init_apic_mappings();
        ioapic_init_mappings();
 
index cac68430d31f3bd3f4ddbfec4073d20ea509030f..f7745f94c0061236b8b224afd44d3a19eb63f3d1 100644 (file)
@@ -227,8 +227,8 @@ static void __init setup_node_to_cpumask_map(void)
        /* allocate the map */
        map = alloc_bootmem_low(nr_node_ids * sizeof(cpumask_t));
 
-       Dprintk(KERN_DEBUG "Node to cpumask map at %p for %d nodes\n",
-               map, nr_node_ids);
+       pr_debug(KERN_DEBUG "Node to cpumask map at %p for %d nodes\n",
+                map, nr_node_ids);
 
        /* node_to_cpumask() will now work */
        node_to_cpumask_map = map;
@@ -248,7 +248,7 @@ void __cpuinit numa_set_node(int cpu, int node)
                per_cpu(x86_cpu_to_node_map, cpu) = node;
 
        else
-               Dprintk(KERN_INFO "Setting node for non-present cpu %d\n", cpu);
+               pr_debug("Setting node for non-present cpu %d\n", cpu);
 }
 
 void __cpuinit numa_clear_node(int cpu)
index d92373630963f980fb5471a0d96d903b5d4b18bf..07faaa5109cb78003c4b2e5bbbad15da7136ca34 100644 (file)
@@ -212,7 +212,7 @@ asmlinkage unsigned long sys_sigreturn(unsigned long __unused)
 
 badframe:
        if (show_unhandled_signals && printk_ratelimit()) {
-               printk(KERN_INFO "%s%s[%d] bad frame in sigreturn frame:"
+               printk("%s%s[%d] bad frame in sigreturn frame:"
                        "%p ip:%lx sp:%lx oeax:%lx",
                    task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
                    current->comm, task_pid_nr(current), frame, regs->ip,
@@ -657,12 +657,6 @@ static void do_signal(struct pt_regs *regs)
 void
 do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
 {
-       /* Pending single-step? */
-       if (thread_info_flags & _TIF_SINGLESTEP) {
-               regs->flags |= X86_EFLAGS_TF;
-               clear_thread_flag(TIF_SINGLESTEP);
-       }
-
        /* deal with pending signal delivery */
        if (thread_info_flags & _TIF_SIGPENDING)
                do_signal(regs);
index e53b267662e712681d99b4b5ae6014af9bf790c1..bf87684474f18497e2326d497217ae45b4888df5 100644 (file)
@@ -487,12 +487,6 @@ static void do_signal(struct pt_regs *regs)
 void do_notify_resume(struct pt_regs *regs, void *unused,
                      __u32 thread_info_flags)
 {
-       /* Pending single-step? */
-       if (thread_info_flags & _TIF_SINGLESTEP) {
-               regs->flags |= X86_EFLAGS_TF;
-               clear_thread_flag(TIF_SINGLESTEP);
-       }
-
 #ifdef CONFIG_X86_MCE
        /* notify userspace of pending MCEs */
        if (thread_info_flags & _TIF_MCE_NOTIFY)
index 09b98cd6332cd8ef2a742de580eece1b2ba51952..332512767f4f0600d15ed473391528b20c4a5a72 100644 (file)
@@ -216,7 +216,7 @@ static void __cpuinit smp_callin(void)
                panic("%s: phys CPU#%d, CPU#%d already present??\n", __func__,
                                        phys_id, cpuid);
        }
-       Dprintk("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpuid, phys_id);
+       pr_debug("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpuid, phys_id);
 
        /*
         * STARTUP IPIs are fragile beasts as they might sometimes
@@ -251,7 +251,7 @@ static void __cpuinit smp_callin(void)
         * boards)
         */
 
-       Dprintk("CALLIN, before setup_local_APIC().\n");
+       pr_debug("CALLIN, before setup_local_APIC().\n");
        smp_callin_clear_local_apic();
        setup_local_APIC();
        end_local_APIC_setup();
@@ -266,7 +266,7 @@ static void __cpuinit smp_callin(void)
        local_irq_enable();
        calibrate_delay();
        local_irq_disable();
-       Dprintk("Stack at about %p\n", &cpuid);
+       pr_debug("Stack at about %p\n", &cpuid);
 
        /*
         * Save our processor parameters
@@ -513,7 +513,7 @@ static void impress_friends(void)
        /*
         * Allow the user to impress friends.
         */
-       Dprintk("Before bogomips.\n");
+       pr_debug("Before bogomips.\n");
        for_each_possible_cpu(cpu)
                if (cpu_isset(cpu, cpu_callout_map))
                        bogosum += cpu_data(cpu).loops_per_jiffy;
@@ -523,7 +523,7 @@ static void impress_friends(void)
                bogosum/(500000/HZ),
                (bogosum/(5000/HZ))%100);
 
-       Dprintk("Before bogocount - setting activated=1.\n");
+       pr_debug("Before bogocount - setting activated=1.\n");
 }
 
 static inline void __inquire_remote_apic(int apicid)
@@ -546,8 +546,8 @@ static inline void __inquire_remote_apic(int apicid)
                        printk(KERN_CONT
                               "a previous APIC delivery may have failed\n");
 
-               apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
-               apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]);
+               apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
+               apic_write(APIC_ICR, APIC_DM_REMRD | regs[i]);
 
                timeout = 0;
                do {
@@ -579,29 +579,24 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip)
        int maxlvt;
 
        /* Target chip */
-       apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(logical_apicid));
+       apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(logical_apicid));
 
        /* Boot on the stack */
        /* Kick the second */
-       apic_write_around(APIC_ICR, APIC_DM_NMI | APIC_DEST_LOGICAL);
+       apic_write(APIC_ICR, APIC_DM_NMI | APIC_DEST_LOGICAL);
 
-       Dprintk("Waiting for send to finish...\n");
+       pr_debug("Waiting for send to finish...\n");
        send_status = safe_apic_wait_icr_idle();
 
        /*
         * Give the other CPU some time to accept the IPI.
         */
        udelay(200);
-       /*
-        * Due to the Pentium erratum 3AP.
-        */
        maxlvt = lapic_get_maxlvt();
-       if (maxlvt > 3) {
-               apic_read_around(APIC_SPIV);
+       if (maxlvt > 3)                 /* Due to the Pentium erratum 3AP.  */
                apic_write(APIC_ESR, 0);
-       }
        accept_status = (apic_read(APIC_ESR) & 0xEF);
-       Dprintk("NMI sent.\n");
+       pr_debug("NMI sent.\n");
 
        if (send_status)
                printk(KERN_ERR "APIC never delivered???\n");
@@ -625,42 +620,44 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
                return send_status;
        }
 
+       maxlvt = lapic_get_maxlvt();
+
        /*
         * Be paranoid about clearing APIC errors.
         */
        if (APIC_INTEGRATED(apic_version[phys_apicid])) {
-               apic_read_around(APIC_SPIV);
-               apic_write(APIC_ESR, 0);
+               if (maxlvt > 3)         /* Due to the Pentium erratum 3AP.  */
+                       apic_write(APIC_ESR, 0);
                apic_read(APIC_ESR);
        }
 
-       Dprintk("Asserting INIT.\n");
+       pr_debug("Asserting INIT.\n");
 
        /*
         * Turn INIT on target chip
         */
-       apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
+       apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
 
        /*
         * Send IPI
         */
-       apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT
-                               | APIC_DM_INIT);
+       apic_write(APIC_ICR,
+                  APIC_INT_LEVELTRIG | APIC_INT_ASSERT | APIC_DM_INIT);
 
-       Dprintk("Waiting for send to finish...\n");
+       pr_debug("Waiting for send to finish...\n");
        send_status = safe_apic_wait_icr_idle();
 
        mdelay(10);
 
-       Dprintk("Deasserting INIT.\n");
+       pr_debug("Deasserting INIT.\n");
 
        /* Target chip */
-       apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
+       apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
 
        /* Send IPI */
-       apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
+       apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
 
-       Dprintk("Waiting for send to finish...\n");
+       pr_debug("Waiting for send to finish...\n");
        send_status = safe_apic_wait_icr_idle();
 
        mb();
@@ -687,55 +684,47 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
        /*
         * Run STARTUP IPI loop.
         */
-       Dprintk("#startup loops: %d.\n", num_starts);
-
-       maxlvt = lapic_get_maxlvt();
+       pr_debug("#startup loops: %d.\n", num_starts);
 
        for (j = 1; j <= num_starts; j++) {
-               Dprintk("Sending STARTUP #%d.\n", j);
-               apic_read_around(APIC_SPIV);
-               apic_write(APIC_ESR, 0);
+               pr_debug("Sending STARTUP #%d.\n", j);
+               if (maxlvt > 3)         /* Due to the Pentium erratum 3AP.  */
+                       apic_write(APIC_ESR, 0);
                apic_read(APIC_ESR);
-               Dprintk("After apic_write.\n");
+               pr_debug("After apic_write.\n");
 
                /*
                 * STARTUP IPI
                 */
 
                /* Target chip */
-               apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
+               apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
 
                /* Boot on the stack */
                /* Kick the second */
-               apic_write_around(APIC_ICR, APIC_DM_STARTUP
-                                       | (start_eip >> 12));
+               apic_write(APIC_ICR, APIC_DM_STARTUP | (start_eip >> 12));
 
                /*
                 * Give the other CPU some time to accept the IPI.
                 */
                udelay(300);
 
-               Dprintk("Startup point 1.\n");
+               pr_debug("Startup point 1.\n");
 
-               Dprintk("Waiting for send to finish...\n");
+               pr_debug("Waiting for send to finish...\n");
                send_status = safe_apic_wait_icr_idle();
 
                /*
                 * Give the other CPU some time to accept the IPI.
                 */
                udelay(200);
-               /*
-                * Due to the Pentium erratum 3AP.
-                */
-               if (maxlvt > 3) {
-                       apic_read_around(APIC_SPIV);
+               if (maxlvt > 3)         /* Due to the Pentium erratum 3AP.  */
                        apic_write(APIC_ESR, 0);
-               }
                accept_status = (apic_read(APIC_ESR) & 0xEF);
                if (send_status || accept_status)
                        break;
        }
-       Dprintk("After Startup.\n");
+       pr_debug("After Startup.\n");
 
        if (send_status)
                printk(KERN_ERR "APIC never delivered???\n");
@@ -768,7 +757,7 @@ static void __cpuinit do_fork_idle(struct work_struct *work)
  *
  * Must be called after the _cpu_pda pointer table is initialized.
  */
-static int __cpuinit get_local_pda(int cpu)
+int __cpuinit get_local_pda(int cpu)
 {
        struct x8664_pda *oldpda, *newpda;
        unsigned long size = sizeof(struct x8664_pda);
@@ -886,7 +875,7 @@ do_rest:
 
        if (get_uv_system_type() != UV_NON_UNIQUE_APIC) {
 
-               Dprintk("Setting warm reset code and vector.\n");
+               pr_debug("Setting warm reset code and vector.\n");
 
                store_NMI_vector(&nmi_high, &nmi_low);
 
@@ -907,9 +896,9 @@ do_rest:
                /*
                 * allow APs to start initializing.
                 */
-               Dprintk("Before Callout %d.\n", cpu);
+               pr_debug("Before Callout %d.\n", cpu);
                cpu_set(cpu, cpu_callout_map);
-               Dprintk("After Callout %d.\n", cpu);
+               pr_debug("After Callout %d.\n", cpu);
 
                /*
                 * Wait 5s total for a response
@@ -922,10 +911,10 @@ do_rest:
 
                if (cpu_isset(cpu, cpu_callin_map)) {
                        /* number CPUs logically, starting from 1 (BSP is 0) */
-                       Dprintk("OK.\n");
+                       pr_debug("OK.\n");
                        printk(KERN_INFO "CPU%d: ", cpu);
                        print_cpu_info(&cpu_data(cpu));
-                       Dprintk("CPU has booted.\n");
+                       pr_debug("CPU has booted.\n");
                } else {
                        boot_error = 1;
                        if (*((volatile unsigned char *)trampoline_base)
@@ -970,7 +959,7 @@ int __cpuinit native_cpu_up(unsigned int cpu)
 
        WARN_ON(irqs_disabled());
 
-       Dprintk("++++++++++++++++++++=_---CPU UP  %u\n", cpu);
+       pr_debug("++++++++++++++++++++=_---CPU UP  %u\n", cpu);
 
        if (apicid == BAD_APICID || apicid == boot_cpu_physical_apicid ||
            !physid_isset(apicid, phys_cpu_present_map)) {
@@ -982,7 +971,7 @@ int __cpuinit native_cpu_up(unsigned int cpu)
         * Already booted CPU?
         */
        if (cpu_isset(cpu, cpu_callin_map)) {
-               Dprintk("do_boot_cpu %d Already started\n", cpu);
+               pr_debug("do_boot_cpu %d Already started\n", cpu);
                return -ENOSYS;
        }
 
@@ -1009,7 +998,7 @@ int __cpuinit native_cpu_up(unsigned int cpu)
        err = do_boot_cpu(apicid, cpu);
 #endif
        if (err) {
-               Dprintk("do_boot_cpu failed %d\n", err);
+               pr_debug("do_boot_cpu failed %d\n", err);
                return -EIO;
        }
 
@@ -1213,7 +1202,7 @@ void __init native_smp_prepare_boot_cpu(void)
 
 void __init native_smp_cpus_done(unsigned int max_cpus)
 {
-       Dprintk("Boot done.\n");
+       pr_debug("Boot done.\n");
 
        impress_friends();
        smp_checks();
@@ -1311,7 +1300,7 @@ static void __ref remove_cpu_from_maps(int cpu)
        cpu_clear(cpu, cpu_callout_map);
        cpu_clear(cpu, cpu_callin_map);
        /* was set by cpu_init() */
-       clear_bit(cpu, (unsigned long *)&cpu_initialized);
+       cpu_clear(cpu, cpu_initialized);
        numa_remove_cpu(cpu);
 }
 
@@ -1390,7 +1379,8 @@ static int __init parse_maxcpus(char *arg)
 {
        extern unsigned int maxcpus;
 
-       maxcpus = simple_strtoul(arg, NULL, 0);
+       if (arg)
+               maxcpus = simple_strtoul(arg, NULL, 0);
        return 0;
 }
 early_param("maxcpus", parse_maxcpus);
diff --git a/arch/x86/kernel/smpcommon_32.c b/arch/x86/kernel/smpcommon_32.c
deleted file mode 100644 (file)
index 8b13789..0000000
+++ /dev/null
@@ -1 +0,0 @@
-
index 92c20fee6781b5f5d419335e68eee8361b7f960d..e8b9863ef8c4f8d09f10344d868450711add7ee5 100644 (file)
@@ -105,6 +105,20 @@ static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs)
 static int enable_single_step(struct task_struct *child)
 {
        struct pt_regs *regs = task_pt_regs(child);
+       unsigned long oflags;
+
+       /*
+        * If we stepped into a sysenter/syscall insn, it trapped in
+        * kernel mode; do_debug() cleared TF and set TIF_SINGLESTEP.
+        * If user-mode had set TF itself, then it's still clear from
+        * do_debug() and we need to set it again to restore the user
+        * state so we don't wrongly set TIF_FORCED_TF below.
+        * If enable_single_step() was used last and that is what
+        * set TIF_SINGLESTEP, then both TF and TIF_FORCED_TF are
+        * already set and our bookkeeping is fine.
+        */
+       if (unlikely(test_tsk_thread_flag(child, TIF_SINGLESTEP)))
+               regs->flags |= X86_EFLAGS_TF;
 
        /*
         * Always set TIF_SINGLESTEP - this guarantees that
@@ -113,11 +127,7 @@ static int enable_single_step(struct task_struct *child)
         */
        set_tsk_thread_flag(child, TIF_SINGLESTEP);
 
-       /*
-        * If TF was already set, don't do anything else
-        */
-       if (regs->flags & X86_EFLAGS_TF)
-               return 0;
+       oflags = regs->flags;
 
        /* Set TF on the kernel stack.. */
        regs->flags |= X86_EFLAGS_TF;
@@ -126,9 +136,22 @@ static int enable_single_step(struct task_struct *child)
         * ..but if TF is changed by the instruction we will trace,
         * don't mark it as being "us" that set it, so that we
         * won't clear it by hand later.
+        *
+        * Note that if we don't actually execute the popf because
+        * of a signal arriving right now or suchlike, we will lose
+        * track of the fact that it really was "us" that set it.
         */
-       if (is_setting_trap_flag(child, regs))
+       if (is_setting_trap_flag(child, regs)) {
+               clear_tsk_thread_flag(child, TIF_FORCED_TF);
                return 0;
+       }
+
+       /*
+        * If TF was already set, check whether it was us who set it.
+        * If not, we should never attempt a block step.
+        */
+       if (oflags & X86_EFLAGS_TF)
+               return test_tsk_thread_flag(child, TIF_FORCED_TF);
 
        set_tsk_thread_flag(child, TIF_FORCED_TF);
 
index 059ca6ee59b4f1bbc9d0eafe4c1f2b3977f17e79..ffe3c664afc0aae1318c1b26ab272f858d87812b 100644 (file)
@@ -129,6 +129,7 @@ void __init hpet_time_init(void)
  */
 void __init time_init(void)
 {
+       pre_time_init_hook();
        tsc_init();
        late_time_init = choose_time_init();
 }
index 8a768973c4f01bdf4b9317d0b23800a233608db9..03df8e45e5a1562e6d63f149a6189eb7964e7335 100644 (file)
@@ -58,6 +58,7 @@
 #include <asm/nmi.h>
 #include <asm/smp.h>
 #include <asm/io.h>
+#include <asm/traps.h>
 
 #include "mach_traps.h"
 
@@ -77,26 +78,6 @@ char ignore_fpu_irq;
 gate_desc idt_table[256]
        __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
 
-asmlinkage void divide_error(void);
-asmlinkage void debug(void);
-asmlinkage void nmi(void);
-asmlinkage void int3(void);
-asmlinkage void overflow(void);
-asmlinkage void bounds(void);
-asmlinkage void invalid_op(void);
-asmlinkage void device_not_available(void);
-asmlinkage void coprocessor_segment_overrun(void);
-asmlinkage void invalid_TSS(void);
-asmlinkage void segment_not_present(void);
-asmlinkage void stack_segment(void);
-asmlinkage void general_protection(void);
-asmlinkage void page_fault(void);
-asmlinkage void coprocessor_error(void);
-asmlinkage void simd_coprocessor_error(void);
-asmlinkage void alignment_check(void);
-asmlinkage void spurious_interrupt_bug(void);
-asmlinkage void machine_check(void);
-
 int panic_on_unrecovered_nmi;
 int kstack_depth_to_print = 24;
 static unsigned int code_bytes = 64;
@@ -256,7 +237,7 @@ static const struct stacktrace_ops print_trace_ops = {
 
 static void
 show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
-                  unsigned long *stack, unsigned long bp, char *log_lvl)
+               unsigned long *stack, unsigned long bp, char *log_lvl)
 {
        dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
        printk("%s =======================\n", log_lvl);
@@ -383,6 +364,54 @@ int is_valid_bugaddr(unsigned long ip)
        return ud2 == 0x0b0f;
 }
 
+static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
+static int die_owner = -1;
+static unsigned int die_nest_count;
+
+unsigned __kprobes long oops_begin(void)
+{
+       unsigned long flags;
+
+       oops_enter();
+
+       if (die_owner != raw_smp_processor_id()) {
+               console_verbose();
+               raw_local_irq_save(flags);
+               __raw_spin_lock(&die_lock);
+               die_owner = smp_processor_id();
+               die_nest_count = 0;
+               bust_spinlocks(1);
+       } else {
+               raw_local_irq_save(flags);
+       }
+       die_nest_count++;
+       return flags;
+}
+
+void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
+{
+       bust_spinlocks(0);
+       die_owner = -1;
+       add_taint(TAINT_DIE);
+       __raw_spin_unlock(&die_lock);
+       raw_local_irq_restore(flags);
+
+       if (!regs)
+               return;
+
+       if (kexec_should_crash(current))
+               crash_kexec(regs);
+
+       if (in_interrupt())
+               panic("Fatal exception in interrupt");
+
+       if (panic_on_oops)
+               panic("Fatal exception");
+
+       oops_exit();
+       do_exit(signr);
+}
+
 int __kprobes __die(const char *str, struct pt_regs *regs, long err)
 {
        unsigned short ss;
@@ -423,31 +452,9 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
  */
 void die(const char *str, struct pt_regs *regs, long err)
 {
-       static struct {
-               raw_spinlock_t lock;
-               u32 lock_owner;
-               int lock_owner_depth;
-       } die = {
-               .lock =                 __RAW_SPIN_LOCK_UNLOCKED,
-               .lock_owner =           -1,
-               .lock_owner_depth =     0
-       };
-       unsigned long flags;
-
-       oops_enter();
-
-       if (die.lock_owner != raw_smp_processor_id()) {
-               console_verbose();
-               raw_local_irq_save(flags);
-               __raw_spin_lock(&die.lock);
-               die.lock_owner = smp_processor_id();
-               die.lock_owner_depth = 0;
-               bust_spinlocks(1);
-       } else {
-               raw_local_irq_save(flags);
-       }
+       unsigned long flags = oops_begin();
 
-       if (++die.lock_owner_depth < 3) {
+       if (die_nest_count < 3) {
                report_bug(regs->ip, regs);
 
                if (__die(str, regs, err))
@@ -456,26 +463,7 @@ void die(const char *str, struct pt_regs *regs, long err)
                printk(KERN_EMERG "Recursive die() failure, output suppressed\n");
        }
 
-       bust_spinlocks(0);
-       die.lock_owner = -1;
-       add_taint(TAINT_DIE);
-       __raw_spin_unlock(&die.lock);
-       raw_local_irq_restore(flags);
-
-       if (!regs)
-               return;
-
-       if (kexec_should_crash(current))
-               crash_kexec(regs);
-
-       if (in_interrupt())
-               panic("Fatal exception in interrupt");
-
-       if (panic_on_oops)
-               panic("Fatal exception");
-
-       oops_exit();
-       do_exit(SIGSEGV);
+       oops_end(flags, regs, SIGSEGV);
 }
 
 static inline void
index 2696a683778204e2f1b417ab4929f27f657836bf..3f18d73f420c414d809a1046dd5676b992e8676e 100644 (file)
 #include <asm/pgalloc.h>
 #include <asm/proto.h>
 #include <asm/pda.h>
+#include <asm/traps.h>
 
 #include <mach_traps.h>
 
-asmlinkage void divide_error(void);
-asmlinkage void debug(void);
-asmlinkage void nmi(void);
-asmlinkage void int3(void);
-asmlinkage void overflow(void);
-asmlinkage void bounds(void);
-asmlinkage void invalid_op(void);
-asmlinkage void device_not_available(void);
-asmlinkage void double_fault(void);
-asmlinkage void coprocessor_segment_overrun(void);
-asmlinkage void invalid_TSS(void);
-asmlinkage void segment_not_present(void);
-asmlinkage void stack_segment(void);
-asmlinkage void general_protection(void);
-asmlinkage void page_fault(void);
-asmlinkage void coprocessor_error(void);
-asmlinkage void simd_coprocessor_error(void);
-asmlinkage void alignment_check(void);
-asmlinkage void spurious_interrupt_bug(void);
-asmlinkage void machine_check(void);
-
 int panic_on_unrecovered_nmi;
 int kstack_depth_to_print = 12;
 static unsigned int code_bytes = 64;
@@ -355,17 +335,24 @@ static const struct stacktrace_ops print_trace_ops = {
        .address = print_trace_address,
 };
 
-void show_trace(struct task_struct *task, struct pt_regs *regs,
-               unsigned long *stack, unsigned long bp)
+static void
+show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
+               unsigned long *stack, unsigned long bp, char *log_lvl)
 {
        printk("\nCall Trace:\n");
-       dump_trace(task, regs, stack, bp, &print_trace_ops, NULL);
+       dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
        printk("\n");
 }
 
+void show_trace(struct task_struct *task, struct pt_regs *regs,
+               unsigned long *stack, unsigned long bp)
+{
+       show_trace_log_lvl(task, regs, stack, bp, "");
+}
+
 static void
-_show_stack(struct task_struct *task, struct pt_regs *regs,
-               unsigned long *sp, unsigned long bp)
+show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
+               unsigned long *sp, unsigned long bp, char *log_lvl)
 {
        unsigned long *stack;
        int i;
@@ -399,12 +386,12 @@ _show_stack(struct task_struct *task, struct pt_regs *regs,
                printk(" %016lx", *stack++);
                touch_nmi_watchdog();
        }
-       show_trace(task, regs, sp, bp);
+       show_trace_log_lvl(task, regs, sp, bp, log_lvl);
 }
 
 void show_stack(struct task_struct *task, unsigned long *sp)
 {
-       _show_stack(task, NULL, sp, 0);
+       show_stack_log_lvl(task, NULL, sp, 0, "");
 }
 
 /*
@@ -454,7 +441,8 @@ void show_registers(struct pt_regs *regs)
                u8 *ip;
 
                printk("Stack: ");
-               _show_stack(NULL, regs, (unsigned long *)sp, regs->bp);
+               show_stack_log_lvl(NULL, regs, (unsigned long *)sp,
+                               regs->bp, "");
                printk("\n");
 
                printk(KERN_EMERG "Code: ");
@@ -518,7 +506,7 @@ unsigned __kprobes long oops_begin(void)
 }
 
 void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
-{ 
+{
        die_owner = -1;
        bust_spinlocks(0);
        die_nest_count--;
index e94bdb6add1d335b273eb5613962d686ffc08198..41e01b145c4800c514e07f456a126a0a0b5104e7 100644 (file)
@@ -73,7 +73,7 @@ int is_visws_box(void)
        return visws_board_type >= 0;
 }
 
-static int __init visws_time_init_quirk(void)
+static int __init visws_time_init(void)
 {
        printk(KERN_INFO "Starting Cobalt Timer system clock\n");
 
@@ -93,7 +93,7 @@ static int __init visws_time_init_quirk(void)
        return 0;
 }
 
-static int __init visws_pre_intr_init_quirk(void)
+static int __init visws_pre_intr_init(void)
 {
        init_VISWS_APIC_irqs();
 
@@ -114,7 +114,7 @@ EXPORT_SYMBOL(sgivwfb_mem_size);
 
 long long mem_size __initdata = 0;
 
-static char * __init visws_memory_setup_quirk(void)
+static char * __init visws_memory_setup(void)
 {
        long long gfx_mem_size = 8 * MB;
 
@@ -176,7 +176,7 @@ static void visws_machine_power_off(void)
        outl(PIIX_SPECIAL_STOP, 0xCFC);
 }
 
-static int __init visws_get_smp_config_quirk(unsigned int early)
+static int __init visws_get_smp_config(unsigned int early)
 {
        /*
         * Prevent MP-table parsing by the generic code:
@@ -192,7 +192,7 @@ extern unsigned int __cpuinitdata maxcpus;
  * No problem for Linux.
  */
 
-static void __init MP_processor_info (struct mpc_config_processor *m)
+static void __init MP_processor_info(struct mpc_config_processor *m)
 {
        int ver, logical_apicid;
        physid_mask_t apic_cpus;
@@ -232,7 +232,7 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
        apic_version[m->mpc_apicid] = ver;
 }
 
-int __init visws_find_smp_config_quirk(unsigned int reserve)
+static int __init visws_find_smp_config(unsigned int reserve)
 {
        struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS);
        unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS));
@@ -258,7 +258,17 @@ int __init visws_find_smp_config_quirk(unsigned int reserve)
        return 1;
 }
 
-extern int visws_trap_init_quirk(void);
+static int visws_trap_init(void);
+
+static struct x86_quirks visws_x86_quirks __initdata = {
+       .arch_time_init         = visws_time_init,
+       .arch_pre_intr_init     = visws_pre_intr_init,
+       .arch_memory_setup      = visws_memory_setup,
+       .arch_intr_init         = NULL,
+       .arch_trap_init         = visws_trap_init,
+       .mach_get_smp_config    = visws_get_smp_config,
+       .mach_find_smp_config   = visws_find_smp_config,
+};
 
 void __init visws_early_detect(void)
 {
@@ -272,16 +282,10 @@ void __init visws_early_detect(void)
 
        /*
         * Install special quirks for timer, interrupt and memory setup:
-        */
-       arch_time_init_quirk            = visws_time_init_quirk;
-       arch_pre_intr_init_quirk        = visws_pre_intr_init_quirk;
-       arch_memory_setup_quirk         = visws_memory_setup_quirk;
-
-       /*
         * Fall back to generic behavior for traps:
+        * Override generic MP-table parsing:
         */
-       arch_intr_init_quirk            = NULL;
-       arch_trap_init_quirk            = visws_trap_init_quirk;
+       x86_quirks = &visws_x86_quirks;
 
        /*
         * Install reboot quirks:
@@ -294,12 +298,6 @@ void __init visws_early_detect(void)
         */
        no_broadcast = 0;
 
-       /*
-        * Override generic MP-table parsing:
-        */
-       mach_get_smp_config_quirk       = visws_get_smp_config_quirk;
-       mach_find_smp_config_quirk      = visws_find_smp_config_quirk;
-
 #ifdef CONFIG_X86_IO_APIC
        /*
         * Turn off IO-APIC detection and initialization:
@@ -426,7 +424,7 @@ static __init void cobalt_init(void)
                co_apic_read(CO_APIC_ID));
 }
 
-int __init visws_trap_init_quirk(void)
+static int __init visws_trap_init(void)
 {
        lithium_init();
        cobalt_init();
index b15346092b7b72aa66e75621f4e31f72698ccbce..0a1b1a9d922df7f4380a40d4b210330dbc8db17a 100644 (file)
@@ -906,7 +906,6 @@ static inline int __init activate_vmi(void)
 #ifdef CONFIG_X86_LOCAL_APIC
        para_fill(pv_apic_ops.apic_read, APICRead);
        para_fill(pv_apic_ops.apic_write, APICWrite);
-       para_fill(pv_apic_ops.apic_write_atomic, APICWrite);
 #endif
 
        /*
index 50dad44fb54234e2725c833fafd15b59b3db0283..0313a5eec4125620016299cca616400821f7bd41 100644 (file)
@@ -991,7 +991,6 @@ __init void lguest_init(void)
 #ifdef CONFIG_X86_LOCAL_APIC
        /* apic read/write intercepts */
        pv_apic_ops.apic_write = lguest_apic_write;
-       pv_apic_ops.apic_write_atomic = lguest_apic_write;
        pv_apic_ops.apic_read = lguest_apic_read;
 #endif
 
index 48278fa7d3dee05eeaf2ccfa9bb8c726f6dd2f84..3d317836be9ed9e1739e92461d0912dc37c65ffb 100644 (file)
 #include <asm/e820.h>
 #include <asm/setup.h>
 
-/*
- * Any quirks to be performed to initialize timers/irqs/etc?
- */
-int (*arch_time_init_quirk)(void);
-int (*arch_pre_intr_init_quirk)(void);
-int (*arch_intr_init_quirk)(void);
-int (*arch_trap_init_quirk)(void);
-
 #ifdef CONFIG_HOTPLUG_CPU
 #define DEFAULT_SEND_IPI       (1)
 #else
@@ -37,8 +29,8 @@ int no_broadcast=DEFAULT_SEND_IPI;
  **/
 void __init pre_intr_init_hook(void)
 {
-       if (arch_pre_intr_init_quirk) {
-               if (arch_pre_intr_init_quirk())
+       if (x86_quirks->arch_pre_intr_init) {
+               if (x86_quirks->arch_pre_intr_init())
                        return;
        }
        init_ISA_irqs();
@@ -64,8 +56,8 @@ static struct irqaction irq2 = {
  **/
 void __init intr_init_hook(void)
 {
-       if (arch_intr_init_quirk) {
-               if (arch_intr_init_quirk())
+       if (x86_quirks->arch_intr_init) {
+               if (x86_quirks->arch_intr_init())
                        return;
        }
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -97,8 +89,8 @@ void __init pre_setup_arch_hook(void)
  **/
 void __init trap_init_hook(void)
 {
-       if (arch_trap_init_quirk) {
-               if (arch_trap_init_quirk())
+       if (x86_quirks->arch_trap_init) {
+               if (x86_quirks->arch_trap_init())
                        return;
        }
 }
@@ -110,6 +102,16 @@ static struct irqaction irq0  = {
        .name = "timer"
 };
 
+/**
+ * pre_time_init_hook - do any specific initialisations before.
+ *
+ **/
+void __init pre_time_init_hook(void)
+{
+       if (x86_quirks->arch_pre_time_init)
+               x86_quirks->arch_pre_time_init();
+}
+
 /**
  * time_init_hook - do any specific initialisations for the system timer.
  *
@@ -119,13 +121,13 @@ static struct irqaction irq0  = {
  **/
 void __init time_init_hook(void)
 {
-       if (arch_time_init_quirk) {
+       if (x86_quirks->arch_time_init) {
                /*
                 * A nonzero return code does not mean failure, it means
                 * that the architecture quirk does not want any
                 * generic (timer) setup to be performed after this:
                 */
-               if (arch_time_init_quirk())
+               if (x86_quirks->arch_time_init())
                        return;
        }
 
index 4354ce804889920f7560361cf79c2876cf7417b9..50189af14b859c67da06815b06a44c50ce07e4d8 100644 (file)
@@ -130,10 +130,10 @@ parse_unisys_oem (char *oemptr)
                        mip_addr = val;
                        mip = (struct mip_reg *)val;
                        mip_reg = __va(mip);
-                       Dprintk("es7000_mipcfg: host_reg = 0x%lx \n",
-                               (unsigned long)host_reg);
-                       Dprintk("es7000_mipcfg: mip_reg = 0x%lx \n",
-                               (unsigned long)mip_reg);
+                       pr_debug("es7000_mipcfg: host_reg = 0x%lx \n",
+                                (unsigned long)host_reg);
+                       pr_debug("es7000_mipcfg: mip_reg = 0x%lx \n",
+                                (unsigned long)mip_reg);
                        success++;
                        break;
                case MIP_PSAI_REG:
index 9873716e9f764bcd7c5bc0f369a0269efdffb35a..1fbb844c3d7afdc0b35723d96ba6578c09584de1 100644 (file)
@@ -21,3 +21,4 @@ obj-$(CONFIG_K8_NUMA)         += k8topology_64.o
 endif
 obj-$(CONFIG_ACPI_NUMA)                += srat_$(BITS).o
 
+obj-$(CONFIG_MEMTEST)          += memtest.o
index 0bb0caed8971878152ed52d26dce836637bf82f7..a20d1fa64b4ea28f22d6c202905a71e78ce744b0 100644 (file)
@@ -148,8 +148,8 @@ static void note_page(struct seq_file *m, struct pg_state *st,
         * we have now. "break" is either changing perms, levels or
         * address space marker.
         */
-       prot = pgprot_val(new_prot) & ~(PTE_MASK);
-       cur = pgprot_val(st->current_prot) & ~(PTE_MASK);
+       prot = pgprot_val(new_prot) & ~(PTE_PFN_MASK);
+       cur = pgprot_val(st->current_prot) & ~(PTE_PFN_MASK);
 
        if (!st->level) {
                /* First entry */
@@ -221,7 +221,7 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st, pud_t addr,
        for (i = 0; i < PTRS_PER_PMD; i++) {
                st->current_address = normalize_addr(P + i * PMD_LEVEL_MULT);
                if (!pmd_none(*start)) {
-                       pgprotval_t prot = pmd_val(*start) & ~PTE_MASK;
+                       pgprotval_t prot = pmd_val(*start) & PTE_FLAGS_MASK;
 
                        if (pmd_large(*start) || !pmd_present(*start))
                                note_page(m, st, __pgprot(prot), 3);
@@ -253,7 +253,7 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t addr,
        for (i = 0; i < PTRS_PER_PUD; i++) {
                st->current_address = normalize_addr(P + i * PUD_LEVEL_MULT);
                if (!pud_none(*start)) {
-                       pgprotval_t prot = pud_val(*start) & ~PTE_MASK;
+                       pgprotval_t prot = pud_val(*start) & PTE_FLAGS_MASK;
 
                        if (pud_large(*start) || !pud_present(*start))
                                note_page(m, st, __pgprot(prot), 2);
@@ -288,7 +288,7 @@ static void walk_pgd_level(struct seq_file *m)
        for (i = 0; i < PTRS_PER_PGD; i++) {
                st.current_address = normalize_addr(i * PGD_LEVEL_MULT);
                if (!pgd_none(*start)) {
-                       pgprotval_t prot = pgd_val(*start) & ~PTE_MASK;
+                       pgprotval_t prot = pgd_val(*start) & PTE_FLAGS_MASK;
 
                        if (pgd_large(*start) || !pgd_present(*start))
                                note_page(m, &st, __pgprot(prot), 1);
index 9689a5138e6472e33c6d0862b3ae56194ffcedb4..d37f29376b0ce455ae3907051a58779f4b995a25 100644 (file)
@@ -844,6 +844,9 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
                reserve_early(table_start << PAGE_SHIFT,
                                 table_end << PAGE_SHIFT, "PGTABLE");
 
+       if (!after_init_bootmem)
+               early_memtest(start, end);
+
        return end >> PAGE_SHIFT;
 }
 
@@ -868,8 +871,6 @@ void __init paging_init(void)
         */
        sparse_init();
        zone_sizes_init();
-
-       paravirt_post_allocator_init();
 }
 
 /*
index 306049edd55322a3c5aec4c7acdf3e38e224eda6..ec37121f67092b8c996b9b99e104d17e642dc650 100644 (file)
@@ -517,118 +517,6 @@ static void __init init_gbpages(void)
                direct_gbpages = 0;
 }
 
-#ifdef CONFIG_MEMTEST
-
-static void __init memtest(unsigned long start_phys, unsigned long size,
-                                unsigned pattern)
-{
-       unsigned long i;
-       unsigned long *start;
-       unsigned long start_bad;
-       unsigned long last_bad;
-       unsigned long val;
-       unsigned long start_phys_aligned;
-       unsigned long count;
-       unsigned long incr;
-
-       switch (pattern) {
-       case 0:
-               val = 0UL;
-               break;
-       case 1:
-               val = -1UL;
-               break;
-       case 2:
-               val = 0x5555555555555555UL;
-               break;
-       case 3:
-               val = 0xaaaaaaaaaaaaaaaaUL;
-               break;
-       default:
-               return;
-       }
-
-       incr = sizeof(unsigned long);
-       start_phys_aligned = ALIGN(start_phys, incr);
-       count = (size - (start_phys_aligned - start_phys))/incr;
-       start = __va(start_phys_aligned);
-       start_bad = 0;
-       last_bad = 0;
-
-       for (i = 0; i < count; i++)
-               start[i] = val;
-       for (i = 0; i < count; i++, start++, start_phys_aligned += incr) {
-               if (*start != val) {
-                       if (start_phys_aligned == last_bad + incr) {
-                               last_bad += incr;
-                       } else {
-                               if (start_bad) {
-                                       printk(KERN_CONT "\n  %016lx bad mem addr %016lx - %016lx reserved",
-                                               val, start_bad, last_bad + incr);
-                                       reserve_early(start_bad, last_bad - start_bad, "BAD RAM");
-                               }
-                               start_bad = last_bad = start_phys_aligned;
-                       }
-               }
-       }
-       if (start_bad) {
-               printk(KERN_CONT "\n  %016lx bad mem addr %016lx - %016lx reserved",
-                       val, start_bad, last_bad + incr);
-               reserve_early(start_bad, last_bad - start_bad, "BAD RAM");
-       }
-
-}
-
-/* default is disabled */
-static int memtest_pattern __initdata;
-
-static int __init parse_memtest(char *arg)
-{
-       if (arg)
-               memtest_pattern = simple_strtoul(arg, NULL, 0);
-       return 0;
-}
-
-early_param("memtest", parse_memtest);
-
-static void __init early_memtest(unsigned long start, unsigned long end)
-{
-       u64 t_start, t_size;
-       unsigned pattern;
-
-       if (!memtest_pattern)
-               return;
-
-       printk(KERN_INFO "early_memtest: pattern num %d", memtest_pattern);
-       for (pattern = 0; pattern < memtest_pattern; pattern++) {
-               t_start = start;
-               t_size = 0;
-               while (t_start < end) {
-                       t_start = find_e820_area_size(t_start, &t_size, 1);
-
-                       /* done ? */
-                       if (t_start >= end)
-                               break;
-                       if (t_start + t_size > end)
-                               t_size = end - t_start;
-
-                       printk(KERN_CONT "\n  %016llx - %016llx pattern %d",
-                               (unsigned long long)t_start,
-                               (unsigned long long)t_start + t_size, pattern);
-
-                       memtest(t_start, t_size, pattern);
-
-                       t_start += t_size;
-               }
-       }
-       printk(KERN_CONT "\n");
-}
-#else
-static void __init early_memtest(unsigned long start, unsigned long end)
-{
-}
-#endif
-
 static unsigned long __init kernel_physical_mapping_init(unsigned long start,
                                                unsigned long end,
                                                unsigned long page_size_mask)
diff --git a/arch/x86/mm/memtest.c b/arch/x86/mm/memtest.c
new file mode 100644 (file)
index 0000000..672e17f
--- /dev/null
@@ -0,0 +1,123 @@
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/pfn.h>
+
+#include <asm/e820.h>
+
+static void __init memtest(unsigned long start_phys, unsigned long size,
+                                unsigned pattern)
+{
+       unsigned long i;
+       unsigned long *start;
+       unsigned long start_bad;
+       unsigned long last_bad;
+       unsigned long val;
+       unsigned long start_phys_aligned;
+       unsigned long count;
+       unsigned long incr;
+
+       switch (pattern) {
+       case 0:
+               val = 0UL;
+               break;
+       case 1:
+               val = -1UL;
+               break;
+       case 2:
+#ifdef CONFIG_X86_64
+               val = 0x5555555555555555UL;
+#else
+               val = 0x55555555UL;
+#endif
+               break;
+       case 3:
+#ifdef CONFIG_X86_64
+               val = 0xaaaaaaaaaaaaaaaaUL;
+#else
+               val = 0xaaaaaaaaUL;
+#endif
+               break;
+       default:
+               return;
+       }
+
+       incr = sizeof(unsigned long);
+       start_phys_aligned = ALIGN(start_phys, incr);
+       count = (size - (start_phys_aligned - start_phys))/incr;
+       start = __va(start_phys_aligned);
+       start_bad = 0;
+       last_bad = 0;
+
+       for (i = 0; i < count; i++)
+               start[i] = val;
+       for (i = 0; i < count; i++, start++, start_phys_aligned += incr) {
+               if (*start != val) {
+                       if (start_phys_aligned == last_bad + incr) {
+                               last_bad += incr;
+                       } else {
+                               if (start_bad) {
+                                       printk(KERN_CONT "\n  %010lx bad mem addr %010lx - %010lx reserved",
+                                               val, start_bad, last_bad + incr);
+                                       reserve_early(start_bad, last_bad - start_bad, "BAD RAM");
+                               }
+                               start_bad = last_bad = start_phys_aligned;
+                       }
+               }
+       }
+       if (start_bad) {
+               printk(KERN_CONT "\n  %016lx bad mem addr %010lx - %010lx reserved",
+                       val, start_bad, last_bad + incr);
+               reserve_early(start_bad, last_bad - start_bad, "BAD RAM");
+       }
+
+}
+
+/* default is disabled */
+static int memtest_pattern __initdata;
+
+static int __init parse_memtest(char *arg)
+{
+       if (arg)
+               memtest_pattern = simple_strtoul(arg, NULL, 0);
+       return 0;
+}
+
+early_param("memtest", parse_memtest);
+
+void __init early_memtest(unsigned long start, unsigned long end)
+{
+       u64 t_start, t_size;
+       unsigned pattern;
+
+       if (!memtest_pattern)
+               return;
+
+       printk(KERN_INFO "early_memtest: pattern num %d", memtest_pattern);
+       for (pattern = 0; pattern < memtest_pattern; pattern++) {
+               t_start = start;
+               t_size = 0;
+               while (t_start < end) {
+                       t_start = find_e820_area_size(t_start, &t_size, 1);
+
+                       /* done ? */
+                       if (t_start >= end)
+                               break;
+                       if (t_start + t_size > end)
+                               t_size = end - t_start;
+
+                       printk(KERN_CONT "\n  %010llx - %010llx pattern %d",
+                               (unsigned long long)t_start,
+                               (unsigned long long)t_start + t_size, pattern);
+
+                       memtest(t_start, t_size, pattern);
+
+                       t_start += t_size;
+               }
+       }
+       printk(KERN_CONT "\n");
+}
index b432d57817737ab777ec223bfdaf3e2442f49490..9782f42dd319801ebe870f5b1d75cc8480df0143 100644 (file)
 #include <asm/acpi.h>
 #include <asm/k8.h>
 
-#ifndef Dprintk
-#define Dprintk(x...)
-#endif
-
 struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
 EXPORT_SYMBOL(node_data);
 
index d4585077977a0bd1c6c7234b09051d671851a6aa..2fe30916d4b66aba6ea1121a9d5bfadb60f1c82f 100644 (file)
@@ -12,6 +12,8 @@
 #include <linux/gfp.h>
 #include <linux/fs.h>
 #include <linux/bootmem.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 
 #include <asm/msr.h>
 #include <asm/tlbflush.h>
@@ -373,8 +375,8 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
        return vma_prot;
 }
 
-#ifdef CONFIG_NONPROMISC_DEVMEM
-/* This check is done in drivers/char/mem.c in case of NONPROMISC_DEVMEM*/
+#ifdef CONFIG_STRICT_DEVMEM
+/* This check is done in drivers/char/mem.c in case of STRICT_DEVMEM*/
 static inline int range_is_allowed(unsigned long pfn, unsigned long size)
 {
        return 1;
@@ -398,7 +400,7 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
        }
        return 1;
 }
-#endif /* CONFIG_NONPROMISC_DEVMEM */
+#endif /* CONFIG_STRICT_DEVMEM */
 
 int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
                                unsigned long size, pgprot_t *vma_prot)
@@ -489,3 +491,89 @@ void unmap_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
 
        free_memtype(addr, addr + size);
 }
+
+#if defined(CONFIG_DEBUG_FS)
+
+/* get Nth element of the linked list */
+static struct memtype *memtype_get_idx(loff_t pos)
+{
+       struct memtype *list_node, *print_entry;
+       int i = 1;
+
+       print_entry  = kmalloc(sizeof(struct memtype), GFP_KERNEL);
+       if (!print_entry)
+               return NULL;
+
+       spin_lock(&memtype_lock);
+       list_for_each_entry(list_node, &memtype_list, nd) {
+               if (pos == i) {
+                       *print_entry = *list_node;
+                       spin_unlock(&memtype_lock);
+                       return print_entry;
+               }
+               ++i;
+       }
+       spin_unlock(&memtype_lock);
+       kfree(print_entry);
+       return NULL;
+}
+
+static void *memtype_seq_start(struct seq_file *seq, loff_t *pos)
+{
+       if (*pos == 0) {
+               ++*pos;
+               seq_printf(seq, "PAT memtype list:\n");
+       }
+
+       return memtype_get_idx(*pos);
+}
+
+static void *memtype_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       ++*pos;
+       return memtype_get_idx(*pos);
+}
+
+static void memtype_seq_stop(struct seq_file *seq, void *v)
+{
+}
+
+static int memtype_seq_show(struct seq_file *seq, void *v)
+{
+       struct memtype *print_entry = (struct memtype *)v;
+
+       seq_printf(seq, "%s @ 0x%Lx-0x%Lx\n", cattr_name(print_entry->type),
+                       print_entry->start, print_entry->end);
+       kfree(print_entry);
+       return 0;
+}
+
+static struct seq_operations memtype_seq_ops = {
+       .start = memtype_seq_start,
+       .next  = memtype_seq_next,
+       .stop  = memtype_seq_stop,
+       .show  = memtype_seq_show,
+};
+
+static int memtype_seq_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &memtype_seq_ops);
+}
+
+static const struct file_operations memtype_fops = {
+       .open    = memtype_seq_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = seq_release,
+};
+
+static int __init pat_memtype_list_init(void)
+{
+       debugfs_create_file("pat_memtype_list", S_IRUSR, arch_debugfs_dir,
+                               NULL, &memtype_fops);
+       return 0;
+}
+
+late_initcall(pat_memtype_list_init);
+
+#endif /* CONFIG_DEBUG_FS */
index e515e8db842a0aa4a78ffe617abc7df08b110659..d49202e740eaf5a224897e4991c9eec951657918 100644 (file)
@@ -5,13 +5,13 @@ obj-$(CONFIG_PCI_MMCONFIG)    += mmconfig_$(BITS).o direct.o mmconfig-shared.o
 obj-$(CONFIG_PCI_DIRECT)       += direct.o
 obj-$(CONFIG_PCI_OLPC)         += olpc.o
 
-pci-y                          := fixup.o
-pci-$(CONFIG_ACPI)             += acpi.o
-pci-y                          += legacy.o irq.o
+obj-y                          += fixup.o
+obj-$(CONFIG_ACPI)             += acpi.o
+obj-y                          += legacy.o irq.o
 
-pci-$(CONFIG_X86_VISWS)                += visws.o
+obj-$(CONFIG_X86_VISWS)                += visws.o
 
-pci-$(CONFIG_X86_NUMAQ)                += numa.o
+obj-$(CONFIG_X86_NUMAQ)                += numaq_32.o
 
-obj-y                          += $(pci-y) common.o early.o
+obj-y                          += common.o early.o
 obj-y                          += amd_bus.o
index 858dbe3399f9f79d5b318bef2767ffcb37153960..86631ccbc25a6f7e9975f0c3f4999e6d022d84b6 100644 (file)
@@ -7,15 +7,13 @@
 /* Direct PCI access. This is used for PCI accesses in early boot before
    the PCI subsystem works. */
 
-#define PDprintk(x...)
-
 u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
 {
        u32 v;
        outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
        v = inl(0xcfc);
        if (v != 0xffffffff)
-               PDprintk("%x reading 4 from %x: %x\n", slot, offset, v);
+               pr_debug("%x reading 4 from %x: %x\n", slot, offset, v);
        return v;
 }
 
@@ -24,7 +22,7 @@ u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset)
        u8 v;
        outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
        v = inb(0xcfc + (offset&3));
-       PDprintk("%x reading 1 from %x: %x\n", slot, offset, v);
+       pr_debug("%x reading 1 from %x: %x\n", slot, offset, v);
        return v;
 }
 
@@ -33,28 +31,28 @@ u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset)
        u16 v;
        outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
        v = inw(0xcfc + (offset&2));
-       PDprintk("%x reading 2 from %x: %x\n", slot, offset, v);
+       pr_debug("%x reading 2 from %x: %x\n", slot, offset, v);
        return v;
 }
 
 void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset,
                                    u32 val)
 {
-       PDprintk("%x writing to %x: %x\n", slot, offset, val);
+       pr_debug("%x writing to %x: %x\n", slot, offset, val);
        outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
        outl(val, 0xcfc);
 }
 
 void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val)
 {
-       PDprintk("%x writing to %x: %x\n", slot, offset, val);
+       pr_debug("%x writing to %x: %x\n", slot, offset, val);
        outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
        outb(val, 0xcfc + (offset&3));
 }
 
 void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val)
 {
-       PDprintk("%x writing to %x: %x\n", slot, offset, val);
+       pr_debug("%x writing to %x: %x\n", slot, offset, val);
        outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
        outw(val, 0xcfc + (offset&2));
 }
@@ -71,7 +69,7 @@ void early_dump_pci_device(u8 bus, u8 slot, u8 func)
        int j;
        u32 val;
 
-       printk("PCI: %02x:%02x:%02x", bus, slot, func);
+       printk(KERN_INFO "PCI: %02x:%02x:%02x", bus, slot, func);
 
        for (i = 0; i < 256; i += 4) {
                if (!(i & 0x0f))
index 132876cc6fca3e9d42cd836b2378ee26b4cdf7c7..ec9ce35e44d6afe51b2c63bafbe9d5e3053d68c4 100644 (file)
@@ -57,14 +57,17 @@ static int __init pci_legacy_init(void)
 
 int __init pci_subsys_init(void)
 {
+#ifdef CONFIG_X86_NUMAQ
+       pci_numaq_init();
+#endif
 #ifdef CONFIG_ACPI
        pci_acpi_init();
+#endif
+#ifdef CONFIG_X86_VISWS
+       pci_visws_init();
 #endif
        pci_legacy_init();
        pcibios_irq_init();
-#ifdef CONFIG_X86_NUMAQ
-       pci_numa_init();
-#endif
        pcibios_init();
 
        return 0;
similarity index 97%
rename from arch/x86/pci/numa.c
rename to arch/x86/pci/numaq_32.c
index 8b5ca1966731a6fd5bd2642696367e99fc12e1f6..f4b16dc11dad17371056924331653ac48a224838 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * numa.c - Low-level PCI access for NUMA-Q machines
+ * numaq_32.c - Low-level PCI access for NUMA-Q machines
  */
 
 #include <linux/pci.h>
@@ -151,7 +151,7 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx);
 
-int __init pci_numa_init(void)
+int __init pci_numaq_init(void)
 {
        int quad;
 
index 3e25deb821ac9152feb484db2414565c541f18de..15b9cf6be729c0c7cddee3ff54d1ce9809f32d58 100644 (file)
@@ -108,7 +108,8 @@ extern void __init dmi_check_skip_isa_align(void);
 /* some common used subsys_initcalls */
 extern int __init pci_acpi_init(void);
 extern int __init pcibios_irq_init(void);
-extern int __init pci_numa_init(void);
+extern int __init pci_visws_init(void);
+extern int __init pci_numaq_init(void);
 extern int __init pcibios_init(void);
 
 /* pci-mmconfig.c */
index 1a7bed492bb15647b2f1ce0df3740cd074094781..42f4cb19facab8a47b70c85fcfd819cb086ade3b 100644 (file)
@@ -86,8 +86,14 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
        pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
 }
 
-static int __init pci_visws_init(void)
+int __init pci_visws_init(void)
 {
+       if (!is_visws_box())
+               return -1;
+
+       pcibios_enable_irq = &pci_visws_enable_irq;
+       pcibios_disable_irq = &pci_visws_disable_irq;
+
        /* The VISWS supports configuration access type 1 only */
        pci_probe = (pci_probe | PCI_PROBE_CONF1) &
                    ~(PCI_PROBE_BIOS | PCI_PROBE_CONF2);
@@ -105,18 +111,3 @@ static int __init pci_visws_init(void)
        pcibios_resource_survey();
        return 0;
 }
-
-static __init int pci_subsys_init(void)
-{
-       if (!is_visws_box())
-               return -1;
-
-       pcibios_enable_irq = &pci_visws_enable_irq;
-       pcibios_disable_irq = &pci_visws_disable_irq;
-
-       pci_visws_init();
-       pcibios_init();
-
-       return 0;
-}
-subsys_initcall(pci_subsys_init);
index b7ad9f89d21f8898dbf792de05b0dddd21f3a803..4d6ef0a336d6d3499580b32958d59c93639bc647 100644 (file)
@@ -62,7 +62,7 @@ $(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE
 # Build multiple 32-bit vDSO images to choose from at boot time.
 #
 obj-$(VDSO32-y)                        += vdso32-syms.lds
-vdso32.so-$(CONFIG_X86_32)     += int80
+vdso32.so-$(VDSO32-y)          += int80
 vdso32.so-$(CONFIG_COMPAT)     += syscall
 vdso32.so-$(VDSO32-y)          += sysenter
 
index 0bce5429a51546de1fab7f0acd29e921d38a9870..513f330c58326b2126e6cfe4c78214eaa77226e8 100644 (file)
@@ -193,17 +193,12 @@ static __init void relocate_vdso(Elf32_Ehdr *ehdr)
        }
 }
 
-/*
- * These symbols are defined by vdso32.S to mark the bounds
- * of the ELF DSO images included therein.
- */
-extern const char vdso32_default_start, vdso32_default_end;
-extern const char vdso32_sysenter_start, vdso32_sysenter_end;
 static struct page *vdso32_pages[1];
 
 #ifdef CONFIG_X86_64
 
 #define        vdso32_sysenter()       (boot_cpu_has(X86_FEATURE_SYSENTER32))
+#define        vdso32_syscall()        (boot_cpu_has(X86_FEATURE_SYSCALL32))
 
 /* May not be __init: called during resume */
 void syscall32_cpu_init(void)
@@ -226,6 +221,7 @@ static inline void map_compat_vdso(int map)
 #else  /* CONFIG_X86_32 */
 
 #define vdso32_sysenter()      (boot_cpu_has(X86_FEATURE_SEP))
+#define vdso32_syscall()       (0)
 
 void enable_sep_cpu(void)
 {
@@ -296,12 +292,15 @@ int __init sysenter_setup(void)
        gate_vma_init();
 #endif
 
-       if (!vdso32_sysenter()) {
-               vsyscall = &vdso32_default_start;
-               vsyscall_len = &vdso32_default_end - &vdso32_default_start;
-       } else {
+       if (vdso32_syscall()) {
+               vsyscall = &vdso32_syscall_start;
+               vsyscall_len = &vdso32_syscall_end - &vdso32_syscall_start;
+       } else if (vdso32_sysenter()){
                vsyscall = &vdso32_sysenter_start;
                vsyscall_len = &vdso32_sysenter_end - &vdso32_sysenter_start;
+       } else {
+               vsyscall = &vdso32_int80_start;
+               vsyscall_len = &vdso32_int80_end - &vdso32_int80_start;
        }
 
        memcpy(syscall_page, vsyscall, vsyscall_len);
index 1e36f72cab865e450cc3f17a9fdf53a7da485a14..2ce5f82c333b15c255b621e63d7bc57b7278b361 100644 (file)
@@ -2,14 +2,17 @@
 
 __INITDATA
 
-       .globl vdso32_default_start, vdso32_default_end
-vdso32_default_start:
-#ifdef CONFIG_X86_32
+       .globl vdso32_int80_start, vdso32_int80_end
+vdso32_int80_start:
        .incbin "arch/x86/vdso/vdso32-int80.so"
-#else
+vdso32_int80_end:
+
+       .globl vdso32_syscall_start, vdso32_syscall_end
+vdso32_syscall_start:
+#ifdef CONFIG_COMPAT
        .incbin "arch/x86/vdso/vdso32-syscall.so"
 #endif
-vdso32_default_end:
+vdso32_syscall_end:
 
        .globl vdso32_sysenter_start, vdso32_sysenter_end
 vdso32_sysenter_start:
index 19a6cfaf5db9c2ff89e60ff7c8fa3f4485d9a14b..257ba4a10abf0740ee908d2ff1369c77d7d31b50 100644 (file)
@@ -21,7 +21,8 @@ unsigned int __read_mostly vdso_enabled = 1;
 extern char vdso_start[], vdso_end[];
 extern unsigned short vdso_sync_cpuid;
 
-struct page **vdso_pages;
+static struct page **vdso_pages;
+static unsigned vdso_size;
 
 static inline void *var_ref(void *p, char *name)
 {
@@ -38,6 +39,7 @@ static int __init init_vdso_vars(void)
        int i;
        char *vbase;
 
+       vdso_size = npages << PAGE_SHIFT;
        vdso_pages = kmalloc(sizeof(struct page *) * npages, GFP_KERNEL);
        if (!vdso_pages)
                goto oom;
@@ -101,20 +103,19 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
        struct mm_struct *mm = current->mm;
        unsigned long addr;
        int ret;
-       unsigned len = round_up(vdso_end - vdso_start, PAGE_SIZE);
 
        if (!vdso_enabled)
                return 0;
 
        down_write(&mm->mmap_sem);
-       addr = vdso_addr(mm->start_stack, len);
-       addr = get_unmapped_area(NULL, addr, len, 0, 0);
+       addr = vdso_addr(mm->start_stack, vdso_size);
+       addr = get_unmapped_area(NULL, addr, vdso_size, 0, 0);
        if (IS_ERR_VALUE(addr)) {
                ret = addr;
                goto up_fail;
        }
 
-       ret = install_special_mapping(mm, addr, len,
+       ret = install_special_mapping(mm, addr, vdso_size,
                                      VM_READ|VM_EXEC|
                                      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
                                      VM_ALWAYSDUMP,
index c2cc9958087109f9e8e8aa749c0e0b8d693612cd..3815e425f4702f11a1693ba3a43a49e9dabc05bb 100644 (file)
@@ -6,8 +6,8 @@ config XEN
        bool "Xen guest support"
        select PARAVIRT
        select PARAVIRT_CLOCK
-       depends on X86_32
-       depends on X86_CMPXCHG && X86_TSC && X86_PAE && !(X86_VISWS || X86_VOYAGER)
+       depends on X86_64 || (X86_32 && X86_PAE && !(X86_VISWS || X86_VOYAGER))
+       depends on X86_CMPXCHG && X86_TSC
        help
          This is the Linux Xen port.  Enabling this will allow the
          kernel to boot in a paravirtualized environment under the
@@ -15,10 +15,16 @@ config XEN
 
 config XEN_MAX_DOMAIN_MEMORY
        int "Maximum allowed size of a domain in gigabytes"
-       default 8
+       default 8 if X86_32
+       default 32 if X86_64
        depends on XEN
        help
          The pseudo-physical to machine address array is sized
          according to the maximum possible memory size of a Xen
          domain.  This array uses 1 page per gigabyte, so there's no
-         need to be too stingy here.
\ No newline at end of file
+         need to be too stingy here.
+
+config XEN_SAVE_RESTORE
+       bool
+       depends on PM
+       default y
\ No newline at end of file
index 2ba2d1649131a1b0151911179679b599a98b9272..59c1e539aed28b9d2c8395671be4a459097df7e7 100644 (file)
@@ -1,4 +1,4 @@
 obj-y          := enlighten.o setup.o multicalls.o mmu.o \
-                       time.o xen-asm.o grant-table.o suspend.o
+                       time.o xen-asm_$(BITS).o grant-table.o suspend.o
 
 obj-$(CONFIG_SMP)      += smp.o
index bb508456ef523e1fa50f77a2993bf481b06f03f0..9ff6e3cbf08feaf41c36d9a48c46ae45a105174e 100644 (file)
@@ -33,6 +33,7 @@
 #include <xen/interface/sched.h>
 #include <xen/features.h>
 #include <xen/page.h>
+#include <xen/hvc-console.h>
 
 #include <asm/paravirt.h>
 #include <asm/page.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/fixmap.h>
 #include <asm/processor.h>
+#include <asm/msr-index.h>
 #include <asm/setup.h>
 #include <asm/desc.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/reboot.h>
-#include <asm/pgalloc.h>
 
 #include "xen-ops.h"
 #include "mmu.h"
@@ -56,6 +57,18 @@ EXPORT_SYMBOL_GPL(hypercall_page);
 DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
 DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
 
+/*
+ * Identity map, in addition to plain kernel map.  This needs to be
+ * large enough to allocate page table pages to allocate the rest.
+ * Each page can map 2MB.
+ */
+static pte_t level1_ident_pgt[PTRS_PER_PTE * 4] __page_aligned_bss;
+
+#ifdef CONFIG_X86_64
+/* l3 pud for userspace vsyscall mapping */
+static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss;
+#endif /* CONFIG_X86_64 */
+
 /*
  * Note about cr3 (pagetable base) values:
  *
@@ -167,10 +180,14 @@ void xen_vcpu_restore(void)
 
 static void __init xen_banner(void)
 {
+       unsigned version = HYPERVISOR_xen_version(XENVER_version, NULL);
+       struct xen_extraversion extra;
+       HYPERVISOR_xen_version(XENVER_extraversion, &extra);
+
        printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
               pv_info.name);
-       printk(KERN_INFO "Hypervisor signature: %s%s\n",
-              xen_start_info->magic,
+       printk(KERN_INFO "Xen version: %d.%d%s%s\n",
+              version >> 16, version & 0xffff, extra.extraversion,
               xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : "");
 }
 
@@ -363,14 +380,6 @@ static void load_TLS_descriptor(struct thread_struct *t,
 
 static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
 {
-       xen_mc_batch();
-
-       load_TLS_descriptor(t, cpu, 0);
-       load_TLS_descriptor(t, cpu, 1);
-       load_TLS_descriptor(t, cpu, 2);
-
-       xen_mc_issue(PARAVIRT_LAZY_CPU);
-
        /*
         * XXX sleazy hack: If we're being called in a lazy-cpu zone,
         * it means we're in a context switch, and %gs has just been
@@ -379,10 +388,39 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
         * Either way, it has been saved, and the new value will get
         * loaded properly.  This will go away as soon as Xen has been
         * modified to not save/restore %gs for normal hypercalls.
+        *
+        * On x86_64, this hack is not used for %gs, because gs points
+        * to KERNEL_GS_BASE (and uses it for PDA references), so we
+        * must not zero %gs on x86_64
+        *
+        * For x86_64, we need to zero %fs, otherwise we may get an
+        * exception between the new %fs descriptor being loaded and
+        * %fs being effectively cleared at __switch_to().
         */
-       if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)
+       if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) {
+#ifdef CONFIG_X86_32
                loadsegment(gs, 0);
+#else
+               loadsegment(fs, 0);
+#endif
+       }
+
+       xen_mc_batch();
+
+       load_TLS_descriptor(t, cpu, 0);
+       load_TLS_descriptor(t, cpu, 1);
+       load_TLS_descriptor(t, cpu, 2);
+
+       xen_mc_issue(PARAVIRT_LAZY_CPU);
+}
+
+#ifdef CONFIG_X86_64
+static void xen_load_gs_index(unsigned int idx)
+{
+       if (HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, idx))
+               BUG();
 }
+#endif
 
 static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum,
                                const void *ptr)
@@ -400,23 +438,18 @@ static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum,
        preempt_enable();
 }
 
-static int cvt_gate_to_trap(int vector, u32 low, u32 high,
+static int cvt_gate_to_trap(int vector, const gate_desc *val,
                            struct trap_info *info)
 {
-       u8 type, dpl;
-
-       type = (high >> 8) & 0x1f;
-       dpl = (high >> 13) & 3;
-
-       if (type != 0xf && type != 0xe)
+       if (val->type != 0xf && val->type != 0xe)
                return 0;
 
        info->vector = vector;
-       info->address = (high & 0xffff0000) | (low & 0x0000ffff);
-       info->cs = low >> 16;
-       info->flags = dpl;
+       info->address = gate_offset(*val);
+       info->cs = gate_segment(*val);
+       info->flags = val->dpl;
        /* interrupt gates clear IF */
-       if (type == 0xe)
+       if (val->type == 0xe)
                info->flags |= 4;
 
        return 1;
@@ -443,11 +476,10 @@ static void xen_write_idt_entry(gate_desc *dt, int entrynum, const gate_desc *g)
 
        if (p >= start && (p + 8) <= end) {
                struct trap_info info[2];
-               u32 *desc = (u32 *)g;
 
                info[1].address = 0;
 
-               if (cvt_gate_to_trap(entrynum, desc[0], desc[1], &info[0]))
+               if (cvt_gate_to_trap(entrynum, g, &info[0]))
                        if (HYPERVISOR_set_trap_table(info))
                                BUG();
        }
@@ -460,13 +492,13 @@ static void xen_convert_trap_info(const struct desc_ptr *desc,
 {
        unsigned in, out, count;
 
-       count = (desc->size+1) / 8;
+       count = (desc->size+1) / sizeof(gate_desc);
        BUG_ON(count > 256);
 
        for (in = out = 0; in < count; in++) {
-               const u32 *entry = (u32 *)(desc->address + in * 8);
+               gate_desc *entry = (gate_desc*)(desc->address) + in;
 
-               if (cvt_gate_to_trap(in, entry[0], entry[1], &traps[out]))
+               if (cvt_gate_to_trap(in, entry, &traps[out]))
                        out++;
        }
        traps[out].address = 0;
@@ -695,33 +727,89 @@ static void set_current_cr3(void *v)
        x86_write_percpu(xen_current_cr3, (unsigned long)v);
 }
 
-static void xen_write_cr3(unsigned long cr3)
+static void __xen_write_cr3(bool kernel, unsigned long cr3)
 {
        struct mmuext_op *op;
        struct multicall_space mcs;
-       unsigned long mfn = pfn_to_mfn(PFN_DOWN(cr3));
+       unsigned long mfn;
 
-       BUG_ON(preemptible());
+       if (cr3)
+               mfn = pfn_to_mfn(PFN_DOWN(cr3));
+       else
+               mfn = 0;
 
-       mcs = xen_mc_entry(sizeof(*op));  /* disables interrupts */
+       WARN_ON(mfn == 0 && kernel);
 
-       /* Update while interrupts are disabled, so its atomic with
-          respect to ipis */
-       x86_write_percpu(xen_cr3, cr3);
+       mcs = __xen_mc_entry(sizeof(*op));
 
        op = mcs.args;
-       op->cmd = MMUEXT_NEW_BASEPTR;
+       op->cmd = kernel ? MMUEXT_NEW_BASEPTR : MMUEXT_NEW_USER_BASEPTR;
        op->arg1.mfn = mfn;
 
        MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
 
-       /* Update xen_update_cr3 once the batch has actually
-          been submitted. */
-       xen_mc_callback(set_current_cr3, (void *)cr3);
+       if (kernel) {
+               x86_write_percpu(xen_cr3, cr3);
+
+               /* Update xen_current_cr3 once the batch has actually
+                  been submitted. */
+               xen_mc_callback(set_current_cr3, (void *)cr3);
+       }
+}
+
+static void xen_write_cr3(unsigned long cr3)
+{
+       BUG_ON(preemptible());
+
+       xen_mc_batch();  /* disables interrupts */
+
+       /* Update while interrupts are disabled, so its atomic with
+          respect to ipis */
+       x86_write_percpu(xen_cr3, cr3);
+
+       __xen_write_cr3(true, cr3);
+
+#ifdef CONFIG_X86_64
+       {
+               pgd_t *user_pgd = xen_get_user_pgd(__va(cr3));
+               if (user_pgd)
+                       __xen_write_cr3(false, __pa(user_pgd));
+               else
+                       __xen_write_cr3(false, 0);
+       }
+#endif
 
        xen_mc_issue(PARAVIRT_LAZY_CPU);  /* interrupts restored */
 }
 
+static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
+{
+       int ret;
+
+       ret = 0;
+
+       switch(msr) {
+#ifdef CONFIG_X86_64
+               unsigned which;
+               u64 base;
+
+       case MSR_FS_BASE:               which = SEGBASE_FS; goto set;
+       case MSR_KERNEL_GS_BASE:        which = SEGBASE_GS_USER; goto set;
+       case MSR_GS_BASE:               which = SEGBASE_GS_KERNEL; goto set;
+
+       set:
+               base = ((u64)high << 32) | low;
+               if (HYPERVISOR_set_segment_base(which, base) != 0)
+                       ret = -EFAULT;
+               break;
+#endif
+       default:
+               ret = native_write_msr_safe(msr, low, high);
+       }
+
+       return ret;
+}
+
 /* Early in boot, while setting up the initial pagetable, assume
    everything is pinned. */
 static __init void xen_alloc_pte_init(struct mm_struct *mm, u32 pfn)
@@ -778,6 +866,48 @@ static void xen_alloc_pmd(struct mm_struct *mm, u32 pfn)
        xen_alloc_ptpage(mm, pfn, PT_PMD);
 }
 
+static int xen_pgd_alloc(struct mm_struct *mm)
+{
+       pgd_t *pgd = mm->pgd;
+       int ret = 0;
+
+       BUG_ON(PagePinned(virt_to_page(pgd)));
+
+#ifdef CONFIG_X86_64
+       {
+               struct page *page = virt_to_page(pgd);
+               pgd_t *user_pgd;
+
+               BUG_ON(page->private != 0);
+
+               ret = -ENOMEM;
+
+               user_pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
+               page->private = (unsigned long)user_pgd;
+
+               if (user_pgd != NULL) {
+                       user_pgd[pgd_index(VSYSCALL_START)] =
+                               __pgd(__pa(level3_user_vsyscall) | _PAGE_TABLE);
+                       ret = 0;
+               }
+
+               BUG_ON(PagePinned(virt_to_page(xen_get_user_pgd(pgd))));
+       }
+#endif
+
+       return ret;
+}
+
+static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+#ifdef CONFIG_X86_64
+       pgd_t *user_pgd = xen_get_user_pgd(pgd);
+
+       if (user_pgd)
+               free_page((unsigned long)user_pgd);
+#endif
+}
+
 /* This should never happen until we're OK to use struct page */
 static void xen_release_ptpage(u32 pfn, unsigned level)
 {
@@ -803,6 +933,18 @@ static void xen_release_pmd(u32 pfn)
        xen_release_ptpage(pfn, PT_PMD);
 }
 
+#if PAGETABLE_LEVELS == 4
+static void xen_alloc_pud(struct mm_struct *mm, u32 pfn)
+{
+       xen_alloc_ptpage(mm, pfn, PT_PUD);
+}
+
+static void xen_release_pud(u32 pfn)
+{
+       xen_release_ptpage(pfn, PT_PUD);
+}
+#endif
+
 #ifdef CONFIG_HIGHPTE
 static void *xen_kmap_atomic_pte(struct page *page, enum km_type type)
 {
@@ -841,68 +983,16 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
 
 static __init void xen_pagetable_setup_start(pgd_t *base)
 {
-       pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base;
-       int i;
-
-       /* special set_pte for pagetable initialization */
-       pv_mmu_ops.set_pte = xen_set_pte_init;
-
-       init_mm.pgd = base;
-       /*
-        * copy top-level of Xen-supplied pagetable into place.  This
-        * is a stand-in while we copy the pmd pages.
-        */
-       memcpy(base, xen_pgd, PTRS_PER_PGD * sizeof(pgd_t));
-
-       /*
-        * For PAE, need to allocate new pmds, rather than
-        * share Xen's, since Xen doesn't like pmd's being
-        * shared between address spaces.
-        */
-       for (i = 0; i < PTRS_PER_PGD; i++) {
-               if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) {
-                       pmd_t *pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
-
-                       memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]),
-                              PAGE_SIZE);
-
-                       make_lowmem_page_readonly(pmd);
-
-                       set_pgd(&base[i], __pgd(1 + __pa(pmd)));
-               } else
-                       pgd_clear(&base[i]);
-       }
-
-       /* make sure zero_page is mapped RO so we can use it in pagetables */
-       make_lowmem_page_readonly(empty_zero_page);
-       make_lowmem_page_readonly(base);
-       /*
-        * Switch to new pagetable.  This is done before
-        * pagetable_init has done anything so that the new pages
-        * added to the table can be prepared properly for Xen.
-        */
-       xen_write_cr3(__pa(base));
-
-       /* Unpin initial Xen pagetable */
-       pin_pagetable_pfn(MMUEXT_UNPIN_TABLE,
-                         PFN_DOWN(__pa(xen_start_info->pt_base)));
 }
 
 void xen_setup_shared_info(void)
 {
        if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-               unsigned long addr = fix_to_virt(FIX_PARAVIRT_BOOTMAP);
-
-               /*
-                * Create a mapping for the shared info page.
-                * Should be set_fixmap(), but shared_info is a machine
-                * address with no corresponding pseudo-phys address.
-                */
-               set_pte_mfn(addr,
-                           PFN_DOWN(xen_start_info->shared_info),
-                           PAGE_KERNEL);
-
-               HYPERVISOR_shared_info = (struct shared_info *)addr;
+               set_fixmap(FIX_PARAVIRT_BOOTMAP,
+                          xen_start_info->shared_info);
+
+               HYPERVISOR_shared_info =
+                       (struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP);
        } else
                HYPERVISOR_shared_info =
                        (struct shared_info *)__va(xen_start_info->shared_info);
@@ -917,26 +1007,32 @@ void xen_setup_shared_info(void)
 
 static __init void xen_pagetable_setup_done(pgd_t *base)
 {
-       /* This will work as long as patching hasn't happened yet
-          (which it hasn't) */
-       pv_mmu_ops.alloc_pte = xen_alloc_pte;
-       pv_mmu_ops.alloc_pmd = xen_alloc_pmd;
-       pv_mmu_ops.release_pte = xen_release_pte;
-       pv_mmu_ops.release_pmd = xen_release_pmd;
-       pv_mmu_ops.set_pte = xen_set_pte;
-
        xen_setup_shared_info();
-
-       /* Actually pin the pagetable down, but we can't set PG_pinned
-          yet because the page structures don't exist yet. */
-       pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(base)));
 }
 
 static __init void xen_post_allocator_init(void)
 {
+       pv_mmu_ops.set_pte = xen_set_pte;
        pv_mmu_ops.set_pmd = xen_set_pmd;
        pv_mmu_ops.set_pud = xen_set_pud;
+#if PAGETABLE_LEVELS == 4
+       pv_mmu_ops.set_pgd = xen_set_pgd;
+#endif
+
+       /* This will work as long as patching hasn't happened yet
+          (which it hasn't) */
+       pv_mmu_ops.alloc_pte = xen_alloc_pte;
+       pv_mmu_ops.alloc_pmd = xen_alloc_pmd;
+       pv_mmu_ops.release_pte = xen_release_pte;
+       pv_mmu_ops.release_pmd = xen_release_pmd;
+#if PAGETABLE_LEVELS == 4
+       pv_mmu_ops.alloc_pud = xen_alloc_pud;
+       pv_mmu_ops.release_pud = xen_release_pud;
+#endif
 
+#ifdef CONFIG_X86_64
+       SetPagePinned(virt_to_page(level3_user_vsyscall));
+#endif
        xen_mark_init_mm_pinned();
 }
 
@@ -950,6 +1046,7 @@ void xen_setup_vcpu_info_placement(void)
 
        /* xen_vcpu_setup managed to place the vcpu_info within the
           percpu area for all cpus, so make use of it */
+#ifdef CONFIG_X86_32
        if (have_vcpu_info_placement) {
                printk(KERN_INFO "Xen: using vcpu_info placement\n");
 
@@ -959,6 +1056,7 @@ void xen_setup_vcpu_info_placement(void)
                pv_irq_ops.irq_enable = xen_irq_enable_direct;
                pv_mmu_ops.read_cr2 = xen_read_cr2_direct;
        }
+#endif
 }
 
 static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
@@ -979,10 +1077,12 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
        goto patch_site
 
        switch (type) {
+#ifdef CONFIG_X86_32
                SITE(pv_irq_ops, irq_enable);
                SITE(pv_irq_ops, irq_disable);
                SITE(pv_irq_ops, save_fl);
                SITE(pv_irq_ops, restore_fl);
+#endif /* CONFIG_X86_32 */
 #undef SITE
 
        patch_site:
@@ -1025,8 +1125,15 @@ static void xen_set_fixmap(unsigned idx, unsigned long phys, pgprot_t prot)
 #ifdef CONFIG_X86_F00F_BUG
        case FIX_F00F_IDT:
 #endif
+#ifdef CONFIG_X86_32
        case FIX_WP_TEST:
        case FIX_VDSO:
+# ifdef CONFIG_HIGHMEM
+       case FIX_KMAP_BEGIN ... FIX_KMAP_END:
+# endif
+#else
+       case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE:
+#endif
 #ifdef CONFIG_X86_LOCAL_APIC
        case FIX_APIC_BASE:     /* maps dummy local APIC */
 #endif
@@ -1039,6 +1146,15 @@ static void xen_set_fixmap(unsigned idx, unsigned long phys, pgprot_t prot)
        }
 
        __native_set_fixmap(idx, pte);
+
+#ifdef CONFIG_X86_64
+       /* Replicate changes to map the vsyscall page into the user
+          pagetable vsyscall mapping. */
+       if (idx >= VSYSCALL_LAST_PAGE && idx <= VSYSCALL_FIRST_PAGE) {
+               unsigned long vaddr = __fix_to_virt(idx);
+               set_pte_vaddr_pud(level3_user_vsyscall, vaddr, pte);
+       }
+#endif
 }
 
 static const struct pv_info xen_info __initdata = {
@@ -1084,18 +1200,25 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
        .wbinvd = native_wbinvd,
 
        .read_msr = native_read_msr_safe,
-       .write_msr = native_write_msr_safe,
+       .write_msr = xen_write_msr_safe,
        .read_tsc = native_read_tsc,
        .read_pmc = native_read_pmc,
 
        .iret = xen_iret,
        .irq_enable_sysexit = xen_sysexit,
+#ifdef CONFIG_X86_64
+       .usergs_sysret32 = xen_sysret32,
+       .usergs_sysret64 = xen_sysret64,
+#endif
 
        .load_tr_desc = paravirt_nop,
        .set_ldt = xen_set_ldt,
        .load_gdt = xen_load_gdt,
        .load_idt = xen_load_idt,
        .load_tls = xen_load_tls,
+#ifdef CONFIG_X86_64
+       .load_gs_index = xen_load_gs_index,
+#endif
 
        .store_gdt = native_store_gdt,
        .store_idt = native_store_idt,
@@ -1109,14 +1232,34 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
        .set_iopl_mask = xen_set_iopl_mask,
        .io_delay = xen_io_delay,
 
+       /* Xen takes care of %gs when switching to usermode for us */
+       .swapgs = paravirt_nop,
+
        .lazy_mode = {
                .enter = paravirt_enter_lazy_cpu,
                .leave = xen_leave_lazy,
        },
 };
 
+static void __init __xen_init_IRQ(void)
+{
+#ifdef CONFIG_X86_64
+       int i;
+
+       /* Create identity vector->irq map */
+       for(i = 0; i < NR_VECTORS; i++) {
+               int cpu;
+
+               for_each_possible_cpu(cpu)
+                       per_cpu(vector_irq, cpu)[i] = i;
+       }
+#endif /* CONFIG_X86_64 */
+
+       xen_init_IRQ();
+}
+
 static const struct pv_irq_ops xen_irq_ops __initdata = {
-       .init_IRQ = xen_init_IRQ,
+       .init_IRQ = __xen_init_IRQ,
        .save_fl = xen_save_fl,
        .restore_fl = xen_restore_fl,
        .irq_disable = xen_irq_disable,
@@ -1124,14 +1267,13 @@ static const struct pv_irq_ops xen_irq_ops __initdata = {
        .safe_halt = xen_safe_halt,
        .halt = xen_halt,
 #ifdef CONFIG_X86_64
-       .adjust_exception_frame = paravirt_nop,
+       .adjust_exception_frame = xen_adjust_exception_frame,
 #endif
 };
 
 static const struct pv_apic_ops xen_apic_ops __initdata = {
 #ifdef CONFIG_X86_LOCAL_APIC
        .apic_write = xen_apic_write,
-       .apic_write_atomic = xen_apic_write,
        .apic_read = xen_apic_read,
        .setup_boot_clock = paravirt_nop,
        .setup_secondary_clock = paravirt_nop,
@@ -1157,8 +1299,8 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
        .pte_update = paravirt_nop,
        .pte_update_defer = paravirt_nop,
 
-       .pgd_alloc = __paravirt_pgd_alloc,
-       .pgd_free = paravirt_nop,
+       .pgd_alloc = xen_pgd_alloc,
+       .pgd_free = xen_pgd_free,
 
        .alloc_pte = xen_alloc_pte_init,
        .release_pte = xen_release_pte_init,
@@ -1170,7 +1312,11 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
        .kmap_atomic_pte = xen_kmap_atomic_pte,
 #endif
 
-       .set_pte = NULL,        /* see xen_pagetable_setup_* */
+#ifdef CONFIG_X86_64
+       .set_pte = xen_set_pte,
+#else
+       .set_pte = xen_set_pte_init,
+#endif
        .set_pte_at = xen_set_pte_at,
        .set_pmd = xen_set_pmd_hyper,
 
@@ -1184,15 +1330,26 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
        .make_pte = xen_make_pte,
        .make_pgd = xen_make_pgd,
 
+#ifdef CONFIG_X86_PAE
        .set_pte_atomic = xen_set_pte_atomic,
        .set_pte_present = xen_set_pte_at,
-       .set_pud = xen_set_pud_hyper,
        .pte_clear = xen_pte_clear,
        .pmd_clear = xen_pmd_clear,
+#endif /* CONFIG_X86_PAE */
+       .set_pud = xen_set_pud_hyper,
 
        .make_pmd = xen_make_pmd,
        .pmd_val = xen_pmd_val,
 
+#if PAGETABLE_LEVELS == 4
+       .pud_val = xen_pud_val,
+       .make_pud = xen_make_pud,
+       .set_pgd = xen_set_pgd_hyper,
+
+       .alloc_pud = xen_alloc_pte_init,
+       .release_pud = xen_release_pte_init,
+#endif /* PAGETABLE_LEVELS == 4 */
+
        .activate_mm = xen_activate_mm,
        .dup_mmap = xen_dup_mmap,
        .exit_mmap = xen_exit_mmap,
@@ -1205,21 +1362,6 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
        .set_fixmap = xen_set_fixmap,
 };
 
-#ifdef CONFIG_SMP
-static const struct smp_ops xen_smp_ops __initdata = {
-       .smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu,
-       .smp_prepare_cpus = xen_smp_prepare_cpus,
-       .cpu_up = xen_cpu_up,
-       .smp_cpus_done = xen_smp_cpus_done,
-
-       .smp_send_stop = xen_smp_send_stop,
-       .smp_send_reschedule = xen_smp_send_reschedule,
-
-       .send_call_func_ipi = xen_smp_send_call_function_ipi,
-       .send_call_func_single_ipi = xen_smp_send_call_function_single_ipi,
-};
-#endif /* CONFIG_SMP */
-
 static void xen_reboot(int reason)
 {
        struct sched_shutdown r = { .reason = reason };
@@ -1264,6 +1406,7 @@ static const struct machine_ops __initdata xen_machine_ops = {
 
 static void __init xen_reserve_top(void)
 {
+#ifdef CONFIG_X86_32
        unsigned long top = HYPERVISOR_VIRT_START;
        struct xen_platform_parameters pp;
 
@@ -1271,8 +1414,248 @@ static void __init xen_reserve_top(void)
                top = pp.virt_start;
 
        reserve_top_address(-top + 2 * PAGE_SIZE);
+#endif /* CONFIG_X86_32 */
+}
+
+/*
+ * Like __va(), but returns address in the kernel mapping (which is
+ * all we have until the physical memory mapping has been set up.
+ */
+static void *__ka(phys_addr_t paddr)
+{
+#ifdef CONFIG_X86_64
+       return (void *)(paddr + __START_KERNEL_map);
+#else
+       return __va(paddr);
+#endif
 }
 
+/* Convert a machine address to physical address */
+static unsigned long m2p(phys_addr_t maddr)
+{
+       phys_addr_t paddr;
+
+       maddr &= PTE_PFN_MASK;
+       paddr = mfn_to_pfn(maddr >> PAGE_SHIFT) << PAGE_SHIFT;
+
+       return paddr;
+}
+
+/* Convert a machine address to kernel virtual */
+static void *m2v(phys_addr_t maddr)
+{
+       return __ka(m2p(maddr));
+}
+
+#ifdef CONFIG_X86_64
+static void walk(pgd_t *pgd, unsigned long addr)
+{
+       unsigned l4idx = pgd_index(addr);
+       unsigned l3idx = pud_index(addr);
+       unsigned l2idx = pmd_index(addr);
+       unsigned l1idx = pte_index(addr);
+       pgd_t l4;
+       pud_t l3;
+       pmd_t l2;
+       pte_t l1;
+
+       xen_raw_printk("walk %p, %lx -> %d %d %d %d\n",
+                      pgd, addr, l4idx, l3idx, l2idx, l1idx);
+
+       l4 = pgd[l4idx];
+       xen_raw_printk("  l4: %016lx\n", l4.pgd);
+       xen_raw_printk("      %016lx\n", pgd_val(l4));
+
+       l3 = ((pud_t *)(m2v(l4.pgd)))[l3idx];
+       xen_raw_printk("  l3: %016lx\n", l3.pud);
+       xen_raw_printk("      %016lx\n", pud_val(l3));
+
+       l2 = ((pmd_t *)(m2v(l3.pud)))[l2idx];
+       xen_raw_printk("  l2: %016lx\n", l2.pmd);
+       xen_raw_printk("      %016lx\n", pmd_val(l2));
+
+       l1 = ((pte_t *)(m2v(l2.pmd)))[l1idx];
+       xen_raw_printk("  l1: %016lx\n", l1.pte);
+       xen_raw_printk("      %016lx\n", pte_val(l1));
+}
+#endif
+
+static void set_page_prot(void *addr, pgprot_t prot)
+{
+       unsigned long pfn = __pa(addr) >> PAGE_SHIFT;
+       pte_t pte = pfn_pte(pfn, prot);
+
+       xen_raw_printk("addr=%p pfn=%lx mfn=%lx prot=%016llx pte=%016llx\n",
+                      addr, pfn, get_phys_to_machine(pfn),
+                      pgprot_val(prot), pte.pte);
+
+       if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, 0))
+               BUG();
+}
+
+static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
+{
+       unsigned pmdidx, pteidx;
+       unsigned ident_pte;
+       unsigned long pfn;
+
+       ident_pte = 0;
+       pfn = 0;
+       for(pmdidx = 0; pmdidx < PTRS_PER_PMD && pfn < max_pfn; pmdidx++) {
+               pte_t *pte_page;
+
+               /* Reuse or allocate a page of ptes */
+               if (pmd_present(pmd[pmdidx]))
+                       pte_page = m2v(pmd[pmdidx].pmd);
+               else {
+                       /* Check for free pte pages */
+                       if (ident_pte == ARRAY_SIZE(level1_ident_pgt))
+                               break;
+
+                       pte_page = &level1_ident_pgt[ident_pte];
+                       ident_pte += PTRS_PER_PTE;
+
+                       pmd[pmdidx] = __pmd(__pa(pte_page) | _PAGE_TABLE);
+               }
+
+               /* Install mappings */
+               for(pteidx = 0; pteidx < PTRS_PER_PTE; pteidx++, pfn++) {
+                       pte_t pte;
+
+                       if (pfn > max_pfn_mapped)
+                               max_pfn_mapped = pfn;
+
+                       if (!pte_none(pte_page[pteidx]))
+                               continue;
+
+                       pte = pfn_pte(pfn, PAGE_KERNEL_EXEC);
+                       pte_page[pteidx] = pte;
+               }
+       }
+
+       for(pteidx = 0; pteidx < ident_pte; pteidx += PTRS_PER_PTE)
+               set_page_prot(&level1_ident_pgt[pteidx], PAGE_KERNEL_RO);
+
+       set_page_prot(pmd, PAGE_KERNEL_RO);
+}
+
+#ifdef CONFIG_X86_64
+static void convert_pfn_mfn(void *v)
+{
+       pte_t *pte = v;
+       int i;
+
+       /* All levels are converted the same way, so just treat them
+          as ptes. */
+       for(i = 0; i < PTRS_PER_PTE; i++)
+               pte[i] = xen_make_pte(pte[i].pte);
+}
+
+/*
+ * Set up the inital kernel pagetable.
+ *
+ * We can construct this by grafting the Xen provided pagetable into
+ * head_64.S's preconstructed pagetables.  We copy the Xen L2's into
+ * level2_ident_pgt, level2_kernel_pgt and level2_fixmap_pgt.  This
+ * means that only the kernel has a physical mapping to start with -
+ * but that's enough to get __va working.  We need to fill in the rest
+ * of the physical mapping once some sort of allocator has been set
+ * up.
+ */
+static __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
+{
+       pud_t *l3;
+       pmd_t *l2;
+
+       /* Zap identity mapping */
+       init_level4_pgt[0] = __pgd(0);
+
+       /* Pre-constructed entries are in pfn, so convert to mfn */
+       convert_pfn_mfn(init_level4_pgt);
+       convert_pfn_mfn(level3_ident_pgt);
+       convert_pfn_mfn(level3_kernel_pgt);
+
+       l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
+       l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
+
+       memcpy(level2_ident_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD);
+       memcpy(level2_kernel_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD);
+
+       l3 = m2v(pgd[pgd_index(__START_KERNEL_map + PMD_SIZE)].pgd);
+       l2 = m2v(l3[pud_index(__START_KERNEL_map + PMD_SIZE)].pud);
+       memcpy(level2_fixmap_pgt, l2, sizeof(pmd_t) * PTRS_PER_PMD);
+
+       /* Set up identity map */
+       xen_map_identity_early(level2_ident_pgt, max_pfn);
+
+       /* Make pagetable pieces RO */
+       set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
+       set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
+       set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
+       set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
+       set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
+       set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
+
+       /* Pin down new L4 */
+       pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
+                         PFN_DOWN(__pa_symbol(init_level4_pgt)));
+
+       /* Unpin Xen-provided one */
+       pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
+
+       /* Switch over */
+       pgd = init_level4_pgt;
+
+       /*
+        * At this stage there can be no user pgd, and no page
+        * structure to attach it to, so make sure we just set kernel
+        * pgd.
+        */
+       xen_mc_batch();
+       __xen_write_cr3(true, __pa(pgd));
+       xen_mc_issue(PARAVIRT_LAZY_CPU);
+
+       reserve_early(__pa(xen_start_info->pt_base),
+                     __pa(xen_start_info->pt_base +
+                          xen_start_info->nr_pt_frames * PAGE_SIZE),
+                     "XEN PAGETABLES");
+
+       return pgd;
+}
+#else  /* !CONFIG_X86_64 */
+static pmd_t level2_kernel_pgt[PTRS_PER_PMD] __page_aligned_bss;
+
+static __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
+{
+       pmd_t *kernel_pmd;
+
+       init_pg_tables_start = __pa(pgd);
+       init_pg_tables_end = __pa(pgd) + xen_start_info->nr_pt_frames*PAGE_SIZE;
+       max_pfn_mapped = PFN_DOWN(init_pg_tables_end + 512*1024);
+
+       kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd);
+       memcpy(level2_kernel_pgt, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD);
+
+       xen_map_identity_early(level2_kernel_pgt, max_pfn);
+
+       memcpy(swapper_pg_dir, pgd, sizeof(pgd_t) * PTRS_PER_PGD);
+       set_pgd(&swapper_pg_dir[KERNEL_PGD_BOUNDARY],
+                       __pgd(__pa(level2_kernel_pgt) | _PAGE_PRESENT));
+
+       set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
+       set_page_prot(swapper_pg_dir, PAGE_KERNEL_RO);
+       set_page_prot(empty_zero_page, PAGE_KERNEL_RO);
+
+       pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
+
+       xen_write_cr3(__pa(swapper_pg_dir));
+
+       pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(swapper_pg_dir)));
+
+       return swapper_pg_dir;
+}
+#endif /* CONFIG_X86_64 */
+
 /* First C function to be called on Xen boot */
 asmlinkage void __init xen_start_kernel(void)
 {
@@ -1301,53 +1684,56 @@ asmlinkage void __init xen_start_kernel(void)
 
        machine_ops = xen_machine_ops;
 
-#ifdef CONFIG_SMP
-       smp_ops = xen_smp_ops;
+#ifdef CONFIG_X86_64
+       /* Disable until direct per-cpu data access. */
+       have_vcpu_info_placement = 0;
+       x86_64_init_pda();
 #endif
 
+       xen_smp_init();
+
        /* Get mfn list */
        if (!xen_feature(XENFEAT_auto_translated_physmap))
                xen_build_dynamic_phys_to_machine();
 
        pgd = (pgd_t *)xen_start_info->pt_base;
 
-       init_pg_tables_start = __pa(pgd);
-       init_pg_tables_end = __pa(pgd) + xen_start_info->nr_pt_frames*PAGE_SIZE;
-       max_pfn_mapped = (init_pg_tables_end + 512*1024) >> PAGE_SHIFT;
-
-       init_mm.pgd = pgd; /* use the Xen pagetables to start */
-
-       /* keep using Xen gdt for now; no urgent need to change it */
-
-       x86_write_percpu(xen_cr3, __pa(pgd));
-       x86_write_percpu(xen_current_cr3, __pa(pgd));
+       /* Prevent unwanted bits from being set in PTEs. */
+       __supported_pte_mask &= ~_PAGE_GLOBAL;
+       if (!is_initial_xendomain())
+               __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
 
        /* Don't do the full vcpu_info placement stuff until we have a
           possible map and a non-dummy shared_info. */
        per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
 
+       xen_raw_console_write("mapping kernel into physical memory\n");
+       pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages);
+
+       init_mm.pgd = pgd;
+
+       /* keep using Xen gdt for now; no urgent need to change it */
+
        pv_info.kernel_rpl = 1;
        if (xen_feature(XENFEAT_supervisor_mode_kernel))
                pv_info.kernel_rpl = 0;
 
-       /* Prevent unwanted bits from being set in PTEs. */
-       __supported_pte_mask &= ~_PAGE_GLOBAL;
-       if (!is_initial_xendomain())
-               __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
-
        /* set the limit of our address space */
        xen_reserve_top();
 
+#ifdef CONFIG_X86_32
        /* set up basic CPUID stuff */
        cpu_detect(&new_cpu_data);
        new_cpu_data.hard_math = 1;
        new_cpu_data.x86_capability[0] = cpuid_edx(1);
+#endif
 
        /* Poke various useful things into boot_params */
        boot_params.hdr.type_of_loader = (9 << 4) | 0;
        boot_params.hdr.ramdisk_image = xen_start_info->mod_start
                ? __pa(xen_start_info->mod_start) : 0;
        boot_params.hdr.ramdisk_size = xen_start_info->mod_len;
+       boot_params.hdr.cmd_line_ptr = __pa(xen_start_info->cmd_line);
 
        if (!is_initial_xendomain()) {
                add_preferred_console("xenboot", 0, NULL);
@@ -1355,6 +1741,21 @@ asmlinkage void __init xen_start_kernel(void)
                add_preferred_console("hvc", 0, NULL);
        }
 
+       xen_raw_console_write("about to get started...\n");
+
+#if 0
+       xen_raw_printk("&boot_params=%p __pa(&boot_params)=%lx __va(__pa(&boot_params))=%lx\n",
+                      &boot_params, __pa_symbol(&boot_params),
+                      __va(__pa_symbol(&boot_params)));
+
+       walk(pgd, &boot_params);
+       walk(pgd, __va(__pa(&boot_params)));
+#endif
+
        /* Start the world */
+#ifdef CONFIG_X86_32
        i386_start_kernel();
+#else
+       x86_64_start_reservations((char *)__pa_symbol(&boot_params));
+#endif
 }
index ff0aa74afaa1ae01ce1a3bd45a907af1cd04e3ea..aa37469da69691cba0eca23089a517dcab26351a 100644 (file)
 
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
+#include <asm/fixmap.h>
 #include <asm/mmu_context.h>
 #include <asm/paravirt.h>
+#include <asm/linkage.h>
 
 #include <asm/xen/hypercall.h>
 #include <asm/xen/hypervisor.h>
 #include "multicalls.h"
 #include "mmu.h"
 
+/*
+ * Just beyond the highest usermode address.  STACK_TOP_MAX has a
+ * redzone above it, so round it up to a PGD boundary.
+ */
+#define USER_LIMIT     ((STACK_TOP_MAX + PGDIR_SIZE - 1) & PGDIR_MASK)
+
+
 #define P2M_ENTRIES_PER_PAGE   (PAGE_SIZE / sizeof(unsigned long))
 #define TOP_ENTRIES            (MAX_DOMAIN_PAGES / P2M_ENTRIES_PER_PAGE)
 
 /* Placeholder for holes in the address space */
-static unsigned long p2m_missing[P2M_ENTRIES_PER_PAGE]
-       __attribute__((section(".data.page_aligned"))) =
+static unsigned long p2m_missing[P2M_ENTRIES_PER_PAGE] __page_aligned_data =
                { [ 0 ... P2M_ENTRIES_PER_PAGE-1 ] = ~0UL };
 
  /* Array of pointers to pages containing p2m entries */
-static unsigned long *p2m_top[TOP_ENTRIES]
-       __attribute__((section(".data.page_aligned"))) =
+static unsigned long *p2m_top[TOP_ENTRIES] __page_aligned_data =
                { [ 0 ... TOP_ENTRIES - 1] = &p2m_missing[0] };
 
 /* Arrays of p2m arrays expressed in mfns used for save/restore */
-static unsigned long p2m_top_mfn[TOP_ENTRIES]
-       __attribute__((section(".bss.page_aligned")));
+static unsigned long p2m_top_mfn[TOP_ENTRIES] __page_aligned_bss;
 
-static unsigned long p2m_top_mfn_list[
-                       PAGE_ALIGN(TOP_ENTRIES / P2M_ENTRIES_PER_PAGE)]
-       __attribute__((section(".bss.page_aligned")));
+static unsigned long p2m_top_mfn_list[TOP_ENTRIES / P2M_ENTRIES_PER_PAGE]
+       __page_aligned_bss;
 
 static inline unsigned p2m_top_index(unsigned long pfn)
 {
@@ -181,15 +186,16 @@ void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
        p2m_top[topidx][idx] = mfn;
 }
 
-xmaddr_t arbitrary_virt_to_machine(unsigned long address)
+xmaddr_t arbitrary_virt_to_machine(void *vaddr)
 {
+       unsigned long address = (unsigned long)vaddr;
        unsigned int level;
        pte_t *pte = lookup_address(address, &level);
        unsigned offset = address & ~PAGE_MASK;
 
        BUG_ON(pte == NULL);
 
-       return XMADDR((pte_mfn(*pte) << PAGE_SHIFT) + offset);
+       return XMADDR(((phys_addr_t)pte_mfn(*pte) << PAGE_SHIFT) + offset);
 }
 
 void make_lowmem_page_readonly(void *vaddr)
@@ -256,7 +262,8 @@ void xen_set_pmd_hyper(pmd_t *ptr, pmd_t val)
 
        xen_mc_batch();
 
-       u.ptr = virt_to_machine(ptr).maddr;
+       /* ptr may be ioremapped for 64-bit pagetable setup */
+       u.ptr = arbitrary_virt_to_machine(ptr).maddr;
        u.val = pmd_val_ma(val);
        extend_mmu_update(&u);
 
@@ -283,35 +290,7 @@ void xen_set_pmd(pmd_t *ptr, pmd_t val)
  */
 void set_pte_mfn(unsigned long vaddr, unsigned long mfn, pgprot_t flags)
 {
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *pte;
-
-       pgd = swapper_pg_dir + pgd_index(vaddr);
-       if (pgd_none(*pgd)) {
-               BUG();
-               return;
-       }
-       pud = pud_offset(pgd, vaddr);
-       if (pud_none(*pud)) {
-               BUG();
-               return;
-       }
-       pmd = pmd_offset(pud, vaddr);
-       if (pmd_none(*pmd)) {
-               BUG();
-               return;
-       }
-       pte = pte_offset_kernel(pmd, vaddr);
-       /* <mfn,flags> stored as-is, to permit clearing entries */
-       xen_set_pte(pte, mfn_pte(mfn, flags));
-
-       /*
-        * It's enough to flush this one mapping.
-        * (PGE mappings get flushed as well)
-        */
-       __flush_tlb_one(vaddr);
+       set_pte_vaddr(vaddr, mfn_pte(mfn, flags));
 }
 
 void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
@@ -364,8 +343,8 @@ void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
 static pteval_t pte_mfn_to_pfn(pteval_t val)
 {
        if (val & _PAGE_PRESENT) {
-               unsigned long mfn = (val & PTE_MASK) >> PAGE_SHIFT;
-               pteval_t flags = val & ~PTE_MASK;
+               unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT;
+               pteval_t flags = val & PTE_FLAGS_MASK;
                val = ((pteval_t)mfn_to_pfn(mfn) << PAGE_SHIFT) | flags;
        }
 
@@ -375,8 +354,8 @@ static pteval_t pte_mfn_to_pfn(pteval_t val)
 static pteval_t pte_pfn_to_mfn(pteval_t val)
 {
        if (val & _PAGE_PRESENT) {
-               unsigned long pfn = (val & PTE_MASK) >> PAGE_SHIFT;
-               pteval_t flags = val & ~PTE_MASK;
+               unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT;
+               pteval_t flags = val & PTE_FLAGS_MASK;
                val = ((pteval_t)pfn_to_mfn(pfn) << PAGE_SHIFT) | flags;
        }
 
@@ -418,7 +397,8 @@ void xen_set_pud_hyper(pud_t *ptr, pud_t val)
 
        xen_mc_batch();
 
-       u.ptr = virt_to_machine(ptr).maddr;
+       /* ptr may be ioremapped for 64-bit pagetable setup */
+       u.ptr = arbitrary_virt_to_machine(ptr).maddr;
        u.val = pud_val_ma(val);
        extend_mmu_update(&u);
 
@@ -441,14 +421,19 @@ void xen_set_pud(pud_t *ptr, pud_t val)
 
 void xen_set_pte(pte_t *ptep, pte_t pte)
 {
+#ifdef CONFIG_X86_PAE
        ptep->pte_high = pte.pte_high;
        smp_wmb();
        ptep->pte_low = pte.pte_low;
+#else
+       *ptep = pte;
+#endif
 }
 
+#ifdef CONFIG_X86_PAE
 void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
 {
-       set_64bit((u64 *)ptep, pte_val_ma(pte));
+       set_64bit((u64 *)ptep, native_pte_val(pte));
 }
 
 void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
@@ -462,6 +447,7 @@ void xen_pmd_clear(pmd_t *pmdp)
 {
        set_pmd(pmdp, __pmd(0));
 }
+#endif /* CONFIG_X86_PAE */
 
 pmd_t xen_make_pmd(pmdval_t pmd)
 {
@@ -469,78 +455,189 @@ pmd_t xen_make_pmd(pmdval_t pmd)
        return native_make_pmd(pmd);
 }
 
+#if PAGETABLE_LEVELS == 4
+pudval_t xen_pud_val(pud_t pud)
+{
+       return pte_mfn_to_pfn(pud.pud);
+}
+
+pud_t xen_make_pud(pudval_t pud)
+{
+       pud = pte_pfn_to_mfn(pud);
+
+       return native_make_pud(pud);
+}
+
+pgd_t *xen_get_user_pgd(pgd_t *pgd)
+{
+       pgd_t *pgd_page = (pgd_t *)(((unsigned long)pgd) & PAGE_MASK);
+       unsigned offset = pgd - pgd_page;
+       pgd_t *user_ptr = NULL;
+
+       if (offset < pgd_index(USER_LIMIT)) {
+               struct page *page = virt_to_page(pgd_page);
+               user_ptr = (pgd_t *)page->private;
+               if (user_ptr)
+                       user_ptr += offset;
+       }
+
+       return user_ptr;
+}
+
+static void __xen_set_pgd_hyper(pgd_t *ptr, pgd_t val)
+{
+       struct mmu_update u;
+
+       u.ptr = virt_to_machine(ptr).maddr;
+       u.val = pgd_val_ma(val);
+       extend_mmu_update(&u);
+}
+
+/*
+ * Raw hypercall-based set_pgd, intended for in early boot before
+ * there's a page structure.  This implies:
+ *  1. The only existing pagetable is the kernel's
+ *  2. It is always pinned
+ *  3. It has no user pagetable attached to it
+ */
+void __init xen_set_pgd_hyper(pgd_t *ptr, pgd_t val)
+{
+       preempt_disable();
+
+       xen_mc_batch();
+
+       __xen_set_pgd_hyper(ptr, val);
+
+       xen_mc_issue(PARAVIRT_LAZY_MMU);
+
+       preempt_enable();
+}
+
+void xen_set_pgd(pgd_t *ptr, pgd_t val)
+{
+       pgd_t *user_ptr = xen_get_user_pgd(ptr);
+
+       /* If page is not pinned, we can just update the entry
+          directly */
+       if (!page_pinned(ptr)) {
+               *ptr = val;
+               if (user_ptr) {
+                       WARN_ON(page_pinned(user_ptr));
+                       *user_ptr = val;
+               }
+               return;
+       }
+
+       /* If it's pinned, then we can at least batch the kernel and
+          user updates together. */
+       xen_mc_batch();
+
+       __xen_set_pgd_hyper(ptr, val);
+       if (user_ptr)
+               __xen_set_pgd_hyper(user_ptr, val);
+
+       xen_mc_issue(PARAVIRT_LAZY_MMU);
+}
+#endif /* PAGETABLE_LEVELS == 4 */
+
 /*
-  (Yet another) pagetable walker.  This one is intended for pinning a
-  pagetable.  This means that it walks a pagetable and calls the
-  callback function on each page it finds making up the page table,
-  at every level.  It walks the entire pagetable, but it only bothers
-  pinning pte pages which are below pte_limit.  In the normal case
-  this will be TASK_SIZE, but at boot we need to pin up to
-  FIXADDR_TOP.  But the important bit is that we don't pin beyond
-  there, because then we start getting into Xen's ptes.
-*/
-static int pgd_walk(pgd_t *pgd_base, int (*func)(struct page *, enum pt_level),
+ * (Yet another) pagetable walker.  This one is intended for pinning a
+ * pagetable.  This means that it walks a pagetable and calls the
+ * callback function on each page it finds making up the page table,
+ * at every level.  It walks the entire pagetable, but it only bothers
+ * pinning pte pages which are below limit.  In the normal case this
+ * will be STACK_TOP_MAX, but at boot we need to pin up to
+ * FIXADDR_TOP.
+ *
+ * For 32-bit the important bit is that we don't pin beyond there,
+ * because then we start getting into Xen's ptes.
+ *
+ * For 64-bit, we must skip the Xen hole in the middle of the address
+ * space, just after the big x86-64 virtual hole.
+ */
+static int pgd_walk(pgd_t *pgd, int (*func)(struct page *, enum pt_level),
                    unsigned long limit)
 {
-       pgd_t *pgd = pgd_base;
        int flush = 0;
-       unsigned long addr = 0;
-       unsigned long pgd_next;
+       unsigned hole_low, hole_high;
+       unsigned pgdidx_limit, pudidx_limit, pmdidx_limit;
+       unsigned pgdidx, pudidx, pmdidx;
 
-       BUG_ON(limit > FIXADDR_TOP);
+       /* The limit is the last byte to be touched */
+       limit--;
+       BUG_ON(limit >= FIXADDR_TOP);
 
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return 0;
 
-       for (; addr != FIXADDR_TOP; pgd++, addr = pgd_next) {
+       /*
+        * 64-bit has a great big hole in the middle of the address
+        * space, which contains the Xen mappings.  On 32-bit these
+        * will end up making a zero-sized hole and so is a no-op.
+        */
+       hole_low = pgd_index(USER_LIMIT);
+       hole_high = pgd_index(PAGE_OFFSET);
+
+       pgdidx_limit = pgd_index(limit);
+#if PTRS_PER_PUD > 1
+       pudidx_limit = pud_index(limit);
+#else
+       pudidx_limit = 0;
+#endif
+#if PTRS_PER_PMD > 1
+       pmdidx_limit = pmd_index(limit);
+#else
+       pmdidx_limit = 0;
+#endif
+
+       flush |= (*func)(virt_to_page(pgd), PT_PGD);
+
+       for (pgdidx = 0; pgdidx <= pgdidx_limit; pgdidx++) {
                pud_t *pud;
-               unsigned long pud_limit, pud_next;
 
-               pgd_next = pud_limit = pgd_addr_end(addr, FIXADDR_TOP);
+               if (pgdidx >= hole_low && pgdidx < hole_high)
+                       continue;
 
-               if (!pgd_val(*pgd))
+               if (!pgd_val(pgd[pgdidx]))
                        continue;
 
-               pud = pud_offset(pgd, 0);
+               pud = pud_offset(&pgd[pgdidx], 0);
 
                if (PTRS_PER_PUD > 1) /* not folded */
                        flush |= (*func)(virt_to_page(pud), PT_PUD);
 
-               for (; addr != pud_limit; pud++, addr = pud_next) {
+               for (pudidx = 0; pudidx < PTRS_PER_PUD; pudidx++) {
                        pmd_t *pmd;
-                       unsigned long pmd_limit;
 
-                       pud_next = pud_addr_end(addr, pud_limit);
-
-                       if (pud_next < limit)
-                               pmd_limit = pud_next;
-                       else
-                               pmd_limit = limit;
+                       if (pgdidx == pgdidx_limit &&
+                           pudidx > pudidx_limit)
+                               goto out;
 
-                       if (pud_none(*pud))
+                       if (pud_none(pud[pudidx]))
                                continue;
 
-                       pmd = pmd_offset(pud, 0);
+                       pmd = pmd_offset(&pud[pudidx], 0);
 
                        if (PTRS_PER_PMD > 1) /* not folded */
                                flush |= (*func)(virt_to_page(pmd), PT_PMD);
 
-                       for (; addr != pmd_limit; pmd++) {
-                               addr += (PAGE_SIZE * PTRS_PER_PTE);
-                               if ((pmd_limit-1) < (addr-1)) {
-                                       addr = pmd_limit;
-                                       break;
-                               }
+                       for (pmdidx = 0; pmdidx < PTRS_PER_PMD; pmdidx++) {
+                               struct page *pte;
+
+                               if (pgdidx == pgdidx_limit &&
+                                   pudidx == pudidx_limit &&
+                                   pmdidx > pmdidx_limit)
+                                       goto out;
 
-                               if (pmd_none(*pmd))
+                               if (pmd_none(pmd[pmdidx]))
                                        continue;
 
-                               flush |= (*func)(pmd_page(*pmd), PT_PTE);
+                               pte = pmd_page(pmd[pmdidx]);
+                               flush |= (*func)(pte, PT_PTE);
                        }
                }
        }
-
-       flush |= (*func)(virt_to_page(pgd_base), PT_PGD);
+out:
 
        return flush;
 }
@@ -622,14 +719,31 @@ void xen_pgd_pin(pgd_t *pgd)
 {
        xen_mc_batch();
 
-       if (pgd_walk(pgd, pin_page, TASK_SIZE)) {
+       if (pgd_walk(pgd, pin_page, USER_LIMIT)) {
                /* re-enable interrupts for kmap_flush_unused */
                xen_mc_issue(0);
                kmap_flush_unused();
                xen_mc_batch();
        }
 
+#ifdef CONFIG_X86_64
+       {
+               pgd_t *user_pgd = xen_get_user_pgd(pgd);
+
+               xen_do_pin(MMUEXT_PIN_L4_TABLE, PFN_DOWN(__pa(pgd)));
+
+               if (user_pgd) {
+                       pin_page(virt_to_page(user_pgd), PT_PGD);
+                       xen_do_pin(MMUEXT_PIN_L4_TABLE, PFN_DOWN(__pa(user_pgd)));
+               }
+       }
+#else /* CONFIG_X86_32 */
+#ifdef CONFIG_X86_PAE
+       /* Need to make sure unshared kernel PMD is pinnable */
+       pin_page(virt_to_page(pgd_page(pgd[pgd_index(TASK_SIZE)])), PT_PMD);
+#endif
        xen_do_pin(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(pgd)));
+#endif /* CONFIG_X86_64 */
        xen_mc_issue(0);
 }
 
@@ -656,9 +770,11 @@ void xen_mm_pin_all(void)
        spin_unlock_irqrestore(&pgd_lock, flags);
 }
 
-/* The init_mm pagetable is really pinned as soon as its created, but
-   that's before we have page structures to store the bits.  So do all
-   the book-keeping now. */
+/*
+ * The init_mm pagetable is really pinned as soon as its created, but
+ * that's before we have page structures to store the bits.  So do all
+ * the book-keeping now.
+ */
 static __init int mark_pinned(struct page *page, enum pt_level level)
 {
        SetPagePinned(page);
@@ -708,7 +824,23 @@ static void xen_pgd_unpin(pgd_t *pgd)
 
        xen_do_pin(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
 
-       pgd_walk(pgd, unpin_page, TASK_SIZE);
+#ifdef CONFIG_X86_64
+       {
+               pgd_t *user_pgd = xen_get_user_pgd(pgd);
+
+               if (user_pgd) {
+                       xen_do_pin(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(user_pgd)));
+                       unpin_page(virt_to_page(user_pgd), PT_PGD);
+               }
+       }
+#endif
+
+#ifdef CONFIG_X86_PAE
+       /* Need to make sure unshared kernel PMD is unpinned */
+       pin_page(virt_to_page(pgd_page(pgd[pgd_index(TASK_SIZE)])), PT_PMD);
+#endif
+
+       pgd_walk(pgd, unpin_page, USER_LIMIT);
 
        xen_mc_issue(0);
 }
@@ -727,7 +859,6 @@ void xen_mm_unpin_all(void)
        list_for_each_entry(page, &pgd_list, lru) {
                if (PageSavePinned(page)) {
                        BUG_ON(!PagePinned(page));
-                       printk("unpinning pinned %p\n", page_address(page));
                        xen_pgd_unpin((pgd_t *)page_address(page));
                        ClearPageSavePinned(page);
                }
@@ -757,8 +888,15 @@ void xen_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
 static void drop_other_mm_ref(void *info)
 {
        struct mm_struct *mm = info;
+       struct mm_struct *active_mm;
+
+#ifdef CONFIG_X86_64
+       active_mm = read_pda(active_mm);
+#else
+       active_mm = __get_cpu_var(cpu_tlbstate).active_mm;
+#endif
 
-       if (__get_cpu_var(cpu_tlbstate).active_mm == mm)
+       if (active_mm == mm)
                leave_mm(smp_processor_id());
 
        /* If this cpu still has a stale cr3 reference, then make sure
index 297bf9f5b8bc3c5a709ff811078c874ffe9b2bab..0f59bd03f9e31f9ac8316e452b21729b0d4de9cb 100644 (file)
@@ -10,18 +10,6 @@ enum pt_level {
        PT_PTE
 };
 
-/*
- * Page-directory addresses above 4GB do not fit into architectural %cr3.
- * When accessing %cr3, or equivalent field in vcpu_guest_context, guests
- * must use the following accessor macros to pack/unpack valid MFNs.
- *
- * Note that Xen is using the fact that the pagetable base is always
- * page-aligned, and putting the 12 MSB of the address into the 12 LSB
- * of cr3.
- */
-#define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20))
-#define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20))
-
 
 void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
 
@@ -44,13 +32,26 @@ pgd_t xen_make_pgd(pgdval_t);
 void xen_set_pte(pte_t *ptep, pte_t pteval);
 void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
                    pte_t *ptep, pte_t pteval);
+
+#ifdef CONFIG_X86_PAE
 void xen_set_pte_atomic(pte_t *ptep, pte_t pte);
+void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+void xen_pmd_clear(pmd_t *pmdp);
+#endif /* CONFIG_X86_PAE */
+
 void xen_set_pmd(pmd_t *pmdp, pmd_t pmdval);
 void xen_set_pud(pud_t *ptr, pud_t val);
 void xen_set_pmd_hyper(pmd_t *pmdp, pmd_t pmdval);
 void xen_set_pud_hyper(pud_t *ptr, pud_t val);
-void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
-void xen_pmd_clear(pmd_t *pmdp);
+
+#if PAGETABLE_LEVELS == 4
+pudval_t xen_pud_val(pud_t pud);
+pud_t xen_make_pud(pudval_t pudval);
+void xen_set_pgd(pgd_t *pgdp, pgd_t pgd);
+void xen_set_pgd_hyper(pgd_t *pgdp, pgd_t pgd);
+#endif
+
+pgd_t *xen_get_user_pgd(pgd_t *pgd);
 
 pte_t xen_ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
 void  xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
index 3c63c4da7ed19cbe4ae43234fe6f6068eb638a79..9efd1c6c9776c5f9e8973026dd03b111c6e9e585 100644 (file)
@@ -76,6 +76,7 @@ void xen_mc_flush(void)
                if (ret) {
                        printk(KERN_ERR "%d multicall(s) failed: cpu %d\n",
                               ret, smp_processor_id());
+                       dump_stack();
                        for (i = 0; i < b->mcidx; i++) {
                                printk("  call %2d/%d: op=%lu arg=[%lx] result=%ld\n",
                                       i+1, b->mcidx,
index e0a39595bde3b342c8364a4306f3b8ea61d88def..b6acc3a0af46d0adeb44a99a8b8d78e1ef8c5140 100644 (file)
@@ -83,30 +83,72 @@ static void xen_idle(void)
 
 /*
  * Set the bit indicating "nosegneg" library variants should be used.
+ * We only need to bother in pure 32-bit mode; compat 32-bit processes
+ * can have un-truncated segments, so wrapping around is allowed.
  */
 static void __init fiddle_vdso(void)
 {
-       extern const char vdso32_default_start;
-       u32 *mask = VDSO32_SYMBOL(&vdso32_default_start, NOTE_MASK);
+#ifdef CONFIG_X86_32
+       u32 *mask;
+       mask = VDSO32_SYMBOL(&vdso32_int80_start, NOTE_MASK);
        *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT;
+       mask = VDSO32_SYMBOL(&vdso32_sysenter_start, NOTE_MASK);
+       *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT;
+#endif
 }
 
-void xen_enable_sysenter(void)
+static __cpuinit int register_callback(unsigned type, const void *func)
 {
-       int cpu = smp_processor_id();
-       extern void xen_sysenter_target(void);
-       /* Mask events on entry, even though they get enabled immediately */
-       static struct callback_register sysenter = {
-               .type = CALLBACKTYPE_sysenter,
-               .address = { __KERNEL_CS, (unsigned long)xen_sysenter_target },
+       struct callback_register callback = {
+               .type = type,
+               .address = XEN_CALLBACK(__KERNEL_CS, func),
                .flags = CALLBACKF_mask_events,
        };
 
-       if (!boot_cpu_has(X86_FEATURE_SEP) ||
-           HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) != 0) {
-               clear_cpu_cap(&cpu_data(cpu), X86_FEATURE_SEP);
-               clear_cpu_cap(&boot_cpu_data, X86_FEATURE_SEP);
+       return HYPERVISOR_callback_op(CALLBACKOP_register, &callback);
+}
+
+void __cpuinit xen_enable_sysenter(void)
+{
+       extern void xen_sysenter_target(void);
+       int ret;
+       unsigned sysenter_feature;
+
+#ifdef CONFIG_X86_32
+       sysenter_feature = X86_FEATURE_SEP;
+#else
+       sysenter_feature = X86_FEATURE_SYSENTER32;
+#endif
+
+       if (!boot_cpu_has(sysenter_feature))
+               return;
+
+       ret = register_callback(CALLBACKTYPE_sysenter, xen_sysenter_target);
+       if(ret != 0)
+               setup_clear_cpu_cap(sysenter_feature);
+}
+
+void __cpuinit xen_enable_syscall(void)
+{
+#ifdef CONFIG_X86_64
+       int ret;
+       extern void xen_syscall_target(void);
+       extern void xen_syscall32_target(void);
+
+       ret = register_callback(CALLBACKTYPE_syscall, xen_syscall_target);
+       if (ret != 0) {
+               printk(KERN_ERR "Failed to set syscall callback: %d\n", ret);
+               /* Pretty fatal; 64-bit userspace has no other
+                  mechanism for syscalls. */
        }
+
+       if (boot_cpu_has(X86_FEATURE_SYSCALL32)) {
+               ret = register_callback(CALLBACKTYPE_syscall32,
+                                       xen_syscall32_target);
+               if (ret != 0)
+                       setup_clear_cpu_cap(X86_FEATURE_SYSCALL32);
+       }
+#endif /* CONFIG_X86_64 */
 }
 
 void __init xen_arch_setup(void)
@@ -120,10 +162,12 @@ void __init xen_arch_setup(void)
        if (!xen_feature(XENFEAT_auto_translated_physmap))
                HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_pae_extended_cr3);
 
-       HYPERVISOR_set_callbacks(__KERNEL_CS, (unsigned long)xen_hypervisor_callback,
-                                __KERNEL_CS, (unsigned long)xen_failsafe_callback);
+       if (register_callback(CALLBACKTYPE_event, xen_hypervisor_callback) ||
+           register_callback(CALLBACKTYPE_failsafe, xen_failsafe_callback))
+               BUG();
 
        xen_enable_sysenter();
+       xen_enable_syscall();
 
        set_iopl.iopl = 1;
        rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
@@ -143,11 +187,6 @@ void __init xen_arch_setup(void)
 
        pm_idle = xen_idle;
 
-#ifdef CONFIG_SMP
-       /* fill cpus_possible with all available cpus */
-       xen_fill_possible_map();
-#endif
-
        paravirt_disable_iospace();
 
        fiddle_vdso();
index 463adecc5cba4a26270dc0479b8068797dd716f4..d8faf79a0a1da22b57d4f39ee58abc1ca9b908d7 100644 (file)
@@ -15,6 +15,7 @@
  * This does not handle HOTPLUG_CPU yet.
  */
 #include <linux/sched.h>
+#include <linux/kernel_stat.h>
 #include <linux/err.h>
 #include <linux/smp.h>
 
@@ -35,6 +36,8 @@
 #include "xen-ops.h"
 #include "mmu.h"
 
+static void __cpuinit xen_init_lock_cpu(int cpu);
+
 cpumask_t xen_cpu_initialized_map;
 
 static DEFINE_PER_CPU(int, resched_irq);
@@ -66,13 +69,22 @@ static __cpuinit void cpu_bringup_and_idle(void)
        int cpu = smp_processor_id();
 
        cpu_init();
+       preempt_disable();
+
        xen_enable_sysenter();
+       xen_enable_syscall();
 
-       preempt_disable();
-       per_cpu(cpu_state, cpu) = CPU_ONLINE;
+       cpu = smp_processor_id();
+       smp_store_cpu_info(cpu);
+       cpu_data(cpu).x86_max_cores = 1;
+       set_cpu_sibling_map(cpu);
 
        xen_setup_cpu_clockevents();
 
+       cpu_set(cpu, cpu_online_map);
+       x86_write_percpu(cpu_state, CPU_ONLINE);
+       wmb();
+
        /* We can take interrupts now: we're officially "up". */
        local_irq_enable();
 
@@ -141,56 +153,39 @@ static int xen_smp_intr_init(unsigned int cpu)
        return rc;
 }
 
-void __init xen_fill_possible_map(void)
+static void __init xen_fill_possible_map(void)
 {
        int i, rc;
 
        for (i = 0; i < NR_CPUS; i++) {
                rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
-               if (rc >= 0)
+               if (rc >= 0) {
+                       num_processors++;
                        cpu_set(i, cpu_possible_map);
+               }
        }
 }
 
-void __init xen_smp_prepare_boot_cpu(void)
+static void __init xen_smp_prepare_boot_cpu(void)
 {
-       int cpu;
-
        BUG_ON(smp_processor_id() != 0);
        native_smp_prepare_boot_cpu();
 
        /* We've switched to the "real" per-cpu gdt, so make sure the
           old memory can be recycled */
-       make_lowmem_page_readwrite(&per_cpu__gdt_page);
-
-       for_each_possible_cpu(cpu) {
-               cpus_clear(per_cpu(cpu_sibling_map, cpu));
-               /*
-                * cpu_core_map lives in a per cpu area that is cleared
-                * when the per cpu array is allocated.
-                *
-                * cpus_clear(per_cpu(cpu_core_map, cpu));
-                */
-       }
+       make_lowmem_page_readwrite(&per_cpu_var(gdt_page));
 
        xen_setup_vcpu_info_placement();
 }
 
-void __init xen_smp_prepare_cpus(unsigned int max_cpus)
+static void __init xen_smp_prepare_cpus(unsigned int max_cpus)
 {
        unsigned cpu;
 
-       for_each_possible_cpu(cpu) {
-               cpus_clear(per_cpu(cpu_sibling_map, cpu));
-               /*
-                * cpu_core_ map will be zeroed when the per
-                * cpu area is allocated.
-                *
-                * cpus_clear(per_cpu(cpu_core_map, cpu));
-                */
-       }
+       xen_init_lock_cpu(0);
 
        smp_store_cpu_info(0);
+       cpu_data(0).x86_max_cores = 1;
        set_cpu_sibling_map(0);
 
        if (xen_smp_intr_init(0))
@@ -225,7 +220,7 @@ static __cpuinit int
 cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 {
        struct vcpu_guest_context *ctxt;
-       struct gdt_page *gdt = &per_cpu(gdt_page, cpu);
+       struct desc_struct *gdt;
 
        if (cpu_test_and_set(cpu, xen_cpu_initialized_map))
                return 0;
@@ -234,12 +229,15 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
        if (ctxt == NULL)
                return -ENOMEM;
 
+       gdt = get_cpu_gdt_table(cpu);
+
        ctxt->flags = VGCF_IN_KERNEL;
        ctxt->user_regs.ds = __USER_DS;
        ctxt->user_regs.es = __USER_DS;
-       ctxt->user_regs.fs = __KERNEL_PERCPU;
-       ctxt->user_regs.gs = 0;
        ctxt->user_regs.ss = __KERNEL_DS;
+#ifdef CONFIG_X86_32
+       ctxt->user_regs.fs = __KERNEL_PERCPU;
+#endif
        ctxt->user_regs.eip = (unsigned long)cpu_bringup_and_idle;
        ctxt->user_regs.eflags = 0x1000; /* IOPL_RING1 */
 
@@ -249,11 +247,11 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 
        ctxt->ldt_ents = 0;
 
-       BUG_ON((unsigned long)gdt->gdt & ~PAGE_MASK);
-       make_lowmem_page_readonly(gdt->gdt);
+       BUG_ON((unsigned long)gdt & ~PAGE_MASK);
+       make_lowmem_page_readonly(gdt);
 
-       ctxt->gdt_frames[0] = virt_to_mfn(gdt->gdt);
-       ctxt->gdt_ents      = ARRAY_SIZE(gdt->gdt);
+       ctxt->gdt_frames[0] = virt_to_mfn(gdt);
+       ctxt->gdt_ents      = GDT_ENTRIES;
 
        ctxt->user_regs.cs = __KERNEL_CS;
        ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs);
@@ -261,9 +259,11 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
        ctxt->kernel_ss = __KERNEL_DS;
        ctxt->kernel_sp = idle->thread.sp0;
 
+#ifdef CONFIG_X86_32
        ctxt->event_callback_cs     = __KERNEL_CS;
-       ctxt->event_callback_eip    = (unsigned long)xen_hypervisor_callback;
        ctxt->failsafe_callback_cs  = __KERNEL_CS;
+#endif
+       ctxt->event_callback_eip    = (unsigned long)xen_hypervisor_callback;
        ctxt->failsafe_callback_eip = (unsigned long)xen_failsafe_callback;
 
        per_cpu(xen_cr3, cpu) = __pa(swapper_pg_dir);
@@ -276,7 +276,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
        return 0;
 }
 
-int __cpuinit xen_cpu_up(unsigned int cpu)
+static int __cpuinit xen_cpu_up(unsigned int cpu)
 {
        struct task_struct *idle = idle_task(cpu);
        int rc;
@@ -287,10 +287,28 @@ int __cpuinit xen_cpu_up(unsigned int cpu)
                return rc;
 #endif
 
+#ifdef CONFIG_X86_64
+       /* Allocate node local memory for AP pdas */
+       WARN_ON(cpu == 0);
+       if (cpu > 0) {
+               rc = get_local_pda(cpu);
+               if (rc)
+                       return rc;
+       }
+#endif
+
+#ifdef CONFIG_X86_32
        init_gdt(cpu);
        per_cpu(current_task, cpu) = idle;
        irq_ctx_init(cpu);
+#else
+       cpu_pda(cpu)->pcurrent = idle;
+       clear_tsk_thread_flag(idle, TIF_FORK);
+#endif
        xen_setup_timer(cpu);
+       xen_init_lock_cpu(cpu);
+
+       per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 
        /* make sure interrupts start blocked */
        per_cpu(xen_vcpu, cpu)->evtchn_upcall_mask = 1;
@@ -306,20 +324,18 @@ int __cpuinit xen_cpu_up(unsigned int cpu)
        if (rc)
                return rc;
 
-       smp_store_cpu_info(cpu);
-       set_cpu_sibling_map(cpu);
-       /* This must be done before setting cpu_online_map */
-       wmb();
-
-       cpu_set(cpu, cpu_online_map);
-
        rc = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
        BUG_ON(rc);
 
+       while(per_cpu(cpu_state, cpu) != CPU_ONLINE) {
+               HYPERVISOR_sched_op(SCHEDOP_yield, 0);
+               barrier();
+       }
+
        return 0;
 }
 
-void xen_smp_cpus_done(unsigned int max_cpus)
+static void xen_smp_cpus_done(unsigned int max_cpus)
 {
 }
 
@@ -335,12 +351,12 @@ static void stop_self(void *v)
        BUG();
 }
 
-void xen_smp_send_stop(void)
+static void xen_smp_send_stop(void)
 {
        smp_call_function(stop_self, NULL, 0);
 }
 
-void xen_smp_send_reschedule(int cpu)
+static void xen_smp_send_reschedule(int cpu)
 {
        xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR);
 }
@@ -355,7 +371,7 @@ static void xen_send_IPI_mask(cpumask_t mask, enum ipi_vector vector)
                xen_send_IPI_one(cpu, vector);
 }
 
-void xen_smp_send_call_function_ipi(cpumask_t mask)
+static void xen_smp_send_call_function_ipi(cpumask_t mask)
 {
        int cpu;
 
@@ -370,7 +386,7 @@ void xen_smp_send_call_function_ipi(cpumask_t mask)
        }
 }
 
-void xen_smp_send_call_function_single_ipi(int cpu)
+static void xen_smp_send_call_function_single_ipi(int cpu)
 {
        xen_send_IPI_mask(cpumask_of_cpu(cpu), XEN_CALL_FUNCTION_SINGLE_VECTOR);
 }
@@ -379,7 +395,11 @@ static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id)
 {
        irq_enter();
        generic_smp_call_function_interrupt();
+#ifdef CONFIG_X86_32
        __get_cpu_var(irq_stat).irq_call_count++;
+#else
+       add_pda(irq_call_count, 1);
+#endif
        irq_exit();
 
        return IRQ_HANDLED;
@@ -389,8 +409,196 @@ static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id)
 {
        irq_enter();
        generic_smp_call_function_single_interrupt();
+#ifdef CONFIG_X86_32
        __get_cpu_var(irq_stat).irq_call_count++;
+#else
+       add_pda(irq_call_count, 1);
+#endif
        irq_exit();
 
        return IRQ_HANDLED;
 }
+
+struct xen_spinlock {
+       unsigned char lock;             /* 0 -> free; 1 -> locked */
+       unsigned short spinners;        /* count of waiting cpus */
+};
+
+static int xen_spin_is_locked(struct raw_spinlock *lock)
+{
+       struct xen_spinlock *xl = (struct xen_spinlock *)lock;
+
+       return xl->lock != 0;
+}
+
+static int xen_spin_is_contended(struct raw_spinlock *lock)
+{
+       struct xen_spinlock *xl = (struct xen_spinlock *)lock;
+
+       /* Not strictly true; this is only the count of contended
+          lock-takers entering the slow path. */
+       return xl->spinners != 0;
+}
+
+static int xen_spin_trylock(struct raw_spinlock *lock)
+{
+       struct xen_spinlock *xl = (struct xen_spinlock *)lock;
+       u8 old = 1;
+
+       asm("xchgb %b0,%1"
+           : "+q" (old), "+m" (xl->lock) : : "memory");
+
+       return old == 0;
+}
+
+static DEFINE_PER_CPU(int, lock_kicker_irq) = -1;
+static DEFINE_PER_CPU(struct xen_spinlock *, lock_spinners);
+
+static inline void spinning_lock(struct xen_spinlock *xl)
+{
+       __get_cpu_var(lock_spinners) = xl;
+       wmb();                  /* set lock of interest before count */
+       asm(LOCK_PREFIX " incw %0"
+           : "+m" (xl->spinners) : : "memory");
+}
+
+static inline void unspinning_lock(struct xen_spinlock *xl)
+{
+       asm(LOCK_PREFIX " decw %0"
+           : "+m" (xl->spinners) : : "memory");
+       wmb();                  /* decrement count before clearing lock */
+       __get_cpu_var(lock_spinners) = NULL;
+}
+
+static noinline int xen_spin_lock_slow(struct raw_spinlock *lock)
+{
+       struct xen_spinlock *xl = (struct xen_spinlock *)lock;
+       int irq = __get_cpu_var(lock_kicker_irq);
+       int ret;
+
+       /* If kicker interrupts not initialized yet, just spin */
+       if (irq == -1)
+               return 0;
+
+       /* announce we're spinning */
+       spinning_lock(xl);
+
+       /* clear pending */
+       xen_clear_irq_pending(irq);
+
+       /* check again make sure it didn't become free while
+          we weren't looking  */
+       ret = xen_spin_trylock(lock);
+       if (ret)
+               goto out;
+
+       /* block until irq becomes pending */
+       xen_poll_irq(irq);
+       kstat_this_cpu.irqs[irq]++;
+
+out:
+       unspinning_lock(xl);
+       return ret;
+}
+
+static void xen_spin_lock(struct raw_spinlock *lock)
+{
+       struct xen_spinlock *xl = (struct xen_spinlock *)lock;
+       int timeout;
+       u8 oldval;
+
+       do {
+               timeout = 1 << 10;
+
+               asm("1: xchgb %1,%0\n"
+                   "   testb %1,%1\n"
+                   "   jz 3f\n"
+                   "2: rep;nop\n"
+                   "   cmpb $0,%0\n"
+                   "   je 1b\n"
+                   "   dec %2\n"
+                   "   jnz 2b\n"
+                   "3:\n"
+                   : "+m" (xl->lock), "=q" (oldval), "+r" (timeout)
+                   : "1" (1)
+                   : "memory");
+
+       } while (unlikely(oldval != 0 && !xen_spin_lock_slow(lock)));
+}
+
+static noinline void xen_spin_unlock_slow(struct xen_spinlock *xl)
+{
+       int cpu;
+
+       for_each_online_cpu(cpu) {
+               /* XXX should mix up next cpu selection */
+               if (per_cpu(lock_spinners, cpu) == xl) {
+                       xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR);
+                       break;
+               }
+       }
+}
+
+static void xen_spin_unlock(struct raw_spinlock *lock)
+{
+       struct xen_spinlock *xl = (struct xen_spinlock *)lock;
+
+       smp_wmb();              /* make sure no writes get moved after unlock */
+       xl->lock = 0;           /* release lock */
+
+       /* make sure unlock happens before kick */
+       barrier();
+
+       if (unlikely(xl->spinners))
+               xen_spin_unlock_slow(xl);
+}
+
+static __cpuinit void xen_init_lock_cpu(int cpu)
+{
+       int irq;
+       const char *name;
+
+       name = kasprintf(GFP_KERNEL, "spinlock%d", cpu);
+       irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR,
+                                    cpu,
+                                    xen_reschedule_interrupt,
+                                    IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING,
+                                    name,
+                                    NULL);
+
+       if (irq >= 0) {
+               disable_irq(irq); /* make sure it's never delivered */
+               per_cpu(lock_kicker_irq, cpu) = irq;
+       }
+
+       printk("cpu %d spinlock event irq %d\n", cpu, irq);
+}
+
+static void __init xen_init_spinlocks(void)
+{
+       pv_lock_ops.spin_is_locked = xen_spin_is_locked;
+       pv_lock_ops.spin_is_contended = xen_spin_is_contended;
+       pv_lock_ops.spin_lock = xen_spin_lock;
+       pv_lock_ops.spin_trylock = xen_spin_trylock;
+       pv_lock_ops.spin_unlock = xen_spin_unlock;
+}
+
+static const struct smp_ops xen_smp_ops __initdata = {
+       .smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu,
+       .smp_prepare_cpus = xen_smp_prepare_cpus,
+       .cpu_up = xen_cpu_up,
+       .smp_cpus_done = xen_smp_cpus_done,
+
+       .smp_send_stop = xen_smp_send_stop,
+       .smp_send_reschedule = xen_smp_send_reschedule,
+
+       .send_call_func_ipi = xen_smp_send_call_function_ipi,
+       .send_call_func_single_ipi = xen_smp_send_call_function_single_ipi,
+};
+
+void __init xen_smp_init(void)
+{
+       smp_ops = xen_smp_ops;
+       xen_fill_possible_map();
+       xen_init_spinlocks();
+}
index 251669a932d4c440f39cc361374ddf59816d0676..2a234db5949beb39e21e5fa09089c3740d802940 100644 (file)
@@ -38,8 +38,11 @@ void xen_post_suspend(int suspend_cancelled)
                xen_cpu_initialized_map = cpu_online_map;
 #endif
                xen_vcpu_restore();
-               xen_timer_resume();
        }
 
 }
 
+void xen_arch_resume(void)
+{
+       /* nothing */
+}
diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S
new file mode 100644 (file)
index 0000000..4038cbf
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+       Asm versions of Xen pv-ops, suitable for either direct use or inlining.
+       The inline versions are the same as the direct-use versions, with the
+       pre- and post-amble chopped off.
+
+       This code is encoded for size rather than absolute efficiency,
+       with a view to being able to inline as much as possible.
+
+       We only bother with direct forms (ie, vcpu in pda) of the operations
+       here; the indirect forms are better handled in C, since they're
+       generally too large to inline anyway.
+ */
+
+#include <linux/linkage.h>
+
+#include <asm/asm-offsets.h>
+#include <asm/processor-flags.h>
+#include <asm/errno.h>
+#include <asm/segment.h>
+
+#include <xen/interface/xen.h>
+
+#define RELOC(x, v)    .globl x##_reloc; x##_reloc=v
+#define ENDPATCH(x)    .globl x##_end; x##_end=.
+
+/* Pseudo-flag used for virtual NMI, which we don't implement yet */
+#define XEN_EFLAGS_NMI 0x80000000
+
+#if 0
+#include <asm/percpu.h>
+
+/*
+       Enable events.  This clears the event mask and tests the pending
+       event status with one and operation.  If there are pending
+       events, then enter the hypervisor to get them handled.
+ */
+ENTRY(xen_irq_enable_direct)
+       /* Unmask events */
+       movb $0, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)
+
+       /* Preempt here doesn't matter because that will deal with
+          any pending interrupts.  The pending check may end up being
+          run on the wrong CPU, but that doesn't hurt. */
+
+       /* Test for pending */
+       testb $0xff, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_pending)
+       jz 1f
+
+2:     call check_events
+1:
+ENDPATCH(xen_irq_enable_direct)
+       ret
+       ENDPROC(xen_irq_enable_direct)
+       RELOC(xen_irq_enable_direct, 2b+1)
+
+/*
+       Disabling events is simply a matter of making the event mask
+       non-zero.
+ */
+ENTRY(xen_irq_disable_direct)
+       movb $1, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)
+ENDPATCH(xen_irq_disable_direct)
+       ret
+       ENDPROC(xen_irq_disable_direct)
+       RELOC(xen_irq_disable_direct, 0)
+
+/*
+       (xen_)save_fl is used to get the current interrupt enable status.
+       Callers expect the status to be in X86_EFLAGS_IF, and other bits
+       may be set in the return value.  We take advantage of this by
+       making sure that X86_EFLAGS_IF has the right value (and other bits
+       in that byte are 0), but other bits in the return value are
+       undefined.  We need to toggle the state of the bit, because
+       Xen and x86 use opposite senses (mask vs enable).
+ */
+ENTRY(xen_save_fl_direct)
+       testb $0xff, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)
+       setz %ah
+       addb %ah,%ah
+ENDPATCH(xen_save_fl_direct)
+       ret
+       ENDPROC(xen_save_fl_direct)
+       RELOC(xen_save_fl_direct, 0)
+
+/*
+       In principle the caller should be passing us a value return
+       from xen_save_fl_direct, but for robustness sake we test only
+       the X86_EFLAGS_IF flag rather than the whole byte. After
+       setting the interrupt mask state, it checks for unmasked
+       pending events and enters the hypervisor to get them delivered
+       if so.
+ */
+ENTRY(xen_restore_fl_direct)
+       testb $X86_EFLAGS_IF>>8, %ah
+       setz PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)
+       /* Preempt here doesn't matter because that will deal with
+          any pending interrupts.  The pending check may end up being
+          run on the wrong CPU, but that doesn't hurt. */
+
+       /* check for unmasked and pending */
+       cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_pending)
+       jz 1f
+2:     call check_events
+1:
+ENDPATCH(xen_restore_fl_direct)
+       ret
+       ENDPROC(xen_restore_fl_direct)
+       RELOC(xen_restore_fl_direct, 2b+1)
+
+
+/*
+       Force an event check by making a hypercall,
+       but preserve regs before making the call.
+ */
+check_events:
+       push %rax
+       push %rcx
+       push %rdx
+       push %rsi
+       push %rdi
+       push %r8
+       push %r9
+       push %r10
+       push %r11
+       call force_evtchn_callback
+       pop %r11
+       pop %r10
+       pop %r9
+       pop %r8
+       pop %rdi
+       pop %rsi
+       pop %rdx
+       pop %rcx
+       pop %rax
+       ret
+#endif
+
+ENTRY(xen_adjust_exception_frame)
+       mov 8+0(%rsp),%rcx
+       mov 8+8(%rsp),%r11
+       ret $16
+
+hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32
+/*
+       Xen64 iret frame:
+
+       ss
+       rsp
+       rflags
+       cs
+       rip             <-- standard iret frame
+
+       flags
+
+       rcx             }
+       r11             }<-- pushed by hypercall page
+rsp -> rax             }
+ */
+ENTRY(xen_iret)
+       pushq $0
+1:     jmp hypercall_iret
+ENDPATCH(xen_iret)
+RELOC(xen_iret, 1b+1)
+
+/*
+       sysexit is not used for 64-bit processes, so it's
+       only ever used to return to 32-bit compat userspace.
+ */
+ENTRY(xen_sysexit)
+       pushq $__USER32_DS
+       pushq %rcx
+       pushq $X86_EFLAGS_IF
+       pushq $__USER32_CS
+       pushq %rdx
+
+       pushq $VGCF_in_syscall
+1:     jmp hypercall_iret
+ENDPATCH(xen_sysexit)
+RELOC(xen_sysexit, 1b+1)
+
+ENTRY(xen_sysret64)
+       /* We're already on the usermode stack at this point, but still
+          with the kernel gs, so we can easily switch back */
+       movq %rsp, %gs:pda_oldrsp
+       movq %gs:pda_kernelstack,%rsp
+
+       pushq $__USER_DS
+       pushq %gs:pda_oldrsp
+       pushq %r11
+       pushq $__USER_CS
+       pushq %rcx
+
+       pushq $VGCF_in_syscall
+1:     jmp hypercall_iret
+ENDPATCH(xen_sysret64)
+RELOC(xen_sysret64, 1b+1)
+
+ENTRY(xen_sysret32)
+       /* We're already on the usermode stack at this point, but still
+          with the kernel gs, so we can easily switch back */
+       movq %rsp, %gs:pda_oldrsp
+       movq %gs:pda_kernelstack, %rsp
+
+       pushq $__USER32_DS
+       pushq %gs:pda_oldrsp
+       pushq %r11
+       pushq $__USER32_CS
+       pushq %rcx
+
+       pushq $VGCF_in_syscall
+1:     jmp hypercall_iret
+ENDPATCH(xen_sysret32)
+RELOC(xen_sysret32, 1b+1)
+
+/*
+       Xen handles syscall callbacks much like ordinary exceptions,
+       which means we have:
+        - kernel gs
+        - kernel rsp
+        - an iret-like stack frame on the stack (including rcx and r11):
+               ss
+               rsp
+               rflags
+               cs
+               rip
+               r11
+       rsp->   rcx
+
+       In all the entrypoints, we undo all that to make it look
+       like a CPU-generated syscall/sysenter and jump to the normal
+       entrypoint.
+ */
+
+.macro undo_xen_syscall
+       mov 0*8(%rsp),%rcx
+       mov 1*8(%rsp),%r11
+       mov 5*8(%rsp),%rsp
+.endm
+
+/* Normal 64-bit system call target */
+ENTRY(xen_syscall_target)
+       undo_xen_syscall
+       jmp system_call_after_swapgs
+ENDPROC(xen_syscall_target)
+
+#ifdef CONFIG_IA32_EMULATION
+
+/* 32-bit compat syscall target */
+ENTRY(xen_syscall32_target)
+       undo_xen_syscall
+       jmp ia32_cstar_target
+ENDPROC(xen_syscall32_target)
+
+/* 32-bit compat sysenter target */
+ENTRY(xen_sysenter_target)
+       undo_xen_syscall
+       jmp ia32_sysenter_target
+ENDPROC(xen_sysenter_target)
+
+#else /* !CONFIG_IA32_EMULATION */
+
+ENTRY(xen_syscall32_target)
+ENTRY(xen_sysenter_target)
+       lea 16(%rsp), %rsp      /* strip %rcx,%r11 */
+       mov $-ENOSYS, %rax
+       pushq $VGCF_in_syscall
+       jmp hypercall_iret
+ENDPROC(xen_syscall32_target)
+ENDPROC(xen_sysenter_target)
+
+#endif /* CONFIG_IA32_EMULATION */
index 7c0cf6320a0aa0ed55d56b5c627856dcb579d377..63d49a523ed307f9407e805ca507bf293ad0dfca 100644 (file)
@@ -5,15 +5,24 @@
 
 #include <linux/elfnote.h>
 #include <linux/init.h>
+
 #include <asm/boot.h>
+#include <asm/asm.h>
+#include <asm/page.h>
+
 #include <xen/interface/elfnote.h>
 #include <asm/xen/interface.h>
 
        __INIT
 ENTRY(startup_xen)
-       movl %esi,xen_start_info
        cld
-       movl $(init_thread_union+THREAD_SIZE),%esp
+#ifdef CONFIG_X86_32
+       mov %esi,xen_start_info
+       mov $init_thread_union+THREAD_SIZE,%esp
+#else
+       mov %rsi,xen_start_info
+       mov $init_thread_union+THREAD_SIZE,%rsp
+#endif
        jmp xen_start_kernel
 
        __FINIT
@@ -21,21 +30,26 @@ ENTRY(startup_xen)
 .pushsection .text
        .align PAGE_SIZE_asm
 ENTRY(hypercall_page)
-       .skip 0x1000
+       .skip PAGE_SIZE_asm
 .popsection
 
        ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
        ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz "2.6")
        ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz "xen-3.0")
-       ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      .long  __PAGE_OFFSET)
-       ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .long  startup_xen)
-       ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long  hypercall_page)
+#ifdef CONFIG_X86_32
+       ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      _ASM_PTR __PAGE_OFFSET)
+#else
+       ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      _ASM_PTR __START_KERNEL_map)
+#endif
+       ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          _ASM_PTR startup_xen)
+       ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _ASM_PTR hypercall_page)
        ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .asciz "!writable_page_tables|pae_pgdir_above_4gb")
        ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz "yes")
        ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz "generic")
        ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,
                .quad _PAGE_PRESENT; .quad _PAGE_PRESENT)
        ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long 1)
-       ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW,   .long __HYPERVISOR_VIRT_START)
+       ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW,   _ASM_PTR __HYPERVISOR_VIRT_START)
+       ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET,   _ASM_PTR 0)
 
 #endif /*CONFIG_XEN */
index 6f4b1045c1c20768015d1fc7987f9ee3a73b4475..dd3c23152a2e618f733192c86aac1ad04de61ed9 100644 (file)
@@ -26,6 +26,7 @@ char * __init xen_memory_setup(void);
 void __init xen_arch_setup(void);
 void __init xen_init_IRQ(void);
 void xen_enable_sysenter(void);
+void xen_enable_syscall(void);
 void xen_vcpu_restore(void);
 
 void __init xen_build_dynamic_phys_to_machine(void);
@@ -37,7 +38,6 @@ 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 xen_timer_resume(void);
 
 irqreturn_t xen_debug_interrupt(int irq, void *dev_id);
 
@@ -45,20 +45,15 @@ bool xen_vcpu_stolen(int vcpu);
 
 void xen_mark_init_mm_pinned(void);
 
-void __init xen_fill_possible_map(void);
-
 void __init xen_setup_vcpu_info_placement(void);
-void xen_smp_prepare_boot_cpu(void);
-void xen_smp_prepare_cpus(unsigned int max_cpus);
-int xen_cpu_up(unsigned int cpu);
-void xen_smp_cpus_done(unsigned int max_cpus);
 
-void xen_smp_send_stop(void);
-void xen_smp_send_reschedule(int cpu);
-void xen_smp_send_call_function_ipi(cpumask_t mask);
-void xen_smp_send_call_function_single_ipi(int cpu);
+#ifdef CONFIG_SMP
+void xen_smp_init(void);
 
 extern cpumask_t xen_cpu_initialized_map;
+#else
+static inline void xen_smp_init(void) {}
+#endif
 
 
 /* Declare an asm function, along with symbols needed to make it
@@ -73,7 +68,11 @@ DECL_ASM(void, xen_irq_disable_direct, void);
 DECL_ASM(unsigned long, xen_save_fl_direct, void);
 DECL_ASM(void, xen_restore_fl_direct, unsigned long);
 
+/* These are not functions, and cannot be called normally */
 void xen_iret(void);
 void xen_sysexit(void);
+void xen_sysret32(void);
+void xen_sysret64(void);
+void xen_adjust_exception_frame(void);
 
 #endif /* XEN_OPS_H */
index 9fc8551a1cf685c53fce6564a004d40642bf3acc..02e417d3d8e95815713b1420146b069112da6b99 100644 (file)
@@ -194,8 +194,8 @@ config HOTPLUG
        plugged into slots found on all modern laptop computers.  Another
        example, used on modern desktops as well as laptops, is USB.
 
-       Enable HOTPLUG and KMOD, and build a modular kernel.  Get agent
-       software (at <http://linux-hotplug.sourceforge.net/>) and install it.
+       Enable HOTPLUG and build a modular kernel.  Get agent software
+       (from <http://linux-hotplug.sourceforge.net/>) and install it.
        Then your kernel will automatically call out to a user mode "policy
        agent" (/sbin/hotplug) to load modules and set up software needed
        to use devices as you hotplug them.
index 5fb9b0bdbe85b60776eb60bd6486f8f86c629587..5a68b09a69bac112758f83f855ee1a94df785df9 100644 (file)
@@ -1044,7 +1044,8 @@ int bsg_register_queue(struct request_queue *q, struct device *parent,
        bcd->release = release;
        kref_init(&bcd->ref);
        dev = MKDEV(bsg_major, bcd->minor);
-       class_dev = device_create(bsg_class, parent, dev, "%s", devname);
+       class_dev = device_create_drvdata(bsg_class, parent, dev, NULL,
+                                         "%s", devname);
        if (IS_ERR(class_dev)) {
                ret = PTR_ERR(class_dev);
                goto put_dev;
index 9074f384b0970535c9048432065ef043ff231923..c13cc77291af7d1c26378051f7fa1b9770d0f81d 100644 (file)
@@ -183,6 +183,7 @@ static int exact_lock(dev_t devt, void *data)
 void add_disk(struct gendisk *disk)
 {
        struct backing_dev_info *bdi;
+       int retval;
 
        disk->flags |= GENHD_FL_UP;
        blk_register_region(MKDEV(disk->major, disk->first_minor),
@@ -193,7 +194,8 @@ void add_disk(struct gendisk *disk)
 
        bdi = &disk->queue->backing_dev_info;
        bdi_register_dev(bdi, MKDEV(disk->major, disk->first_minor));
-       sysfs_create_link(&disk->dev.kobj, &bdi->dev->kobj, "bdi");
+       retval = sysfs_create_link(&disk->dev.kobj, &bdi->dev->kobj, "bdi");
+       WARN_ON(retval);
 }
 
 EXPORT_SYMBOL(add_disk);
@@ -225,89 +227,111 @@ struct gendisk *get_gendisk(dev_t devt, int *part)
 }
 
 /*
- * print a full list of all partitions - intended for places where the root
- * filesystem can't be mounted and thus to give the victim some idea of what
- * went wrong
+ * print a partitions - intended for places where the root filesystem can't be
+ * mounted and thus to give the victim some idea of what went wrong
  */
-void __init printk_all_partitions(void)
+static int printk_partition(struct device *dev, void *data)
 {
-       struct device *dev;
        struct gendisk *sgp;
        char buf[BDEVNAME_SIZE];
        int n;
 
-       mutex_lock(&block_class_lock);
-       /* For each block device... */
-       list_for_each_entry(dev, &block_class.devices, node) {
-               if (dev->type != &disk_type)
-                       continue;
-               sgp = dev_to_disk(dev);
-               /*
-                * Don't show empty devices or things that have been surpressed
-                */
-               if (get_capacity(sgp) == 0 ||
-                   (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO))
-                       continue;
+       if (dev->type != &disk_type)
+               goto exit;
 
-               /*
-                * Note, unlike /proc/partitions, I am showing the numbers in
-                * hex - the same format as the root= option takes.
-                */
-               printk("%02x%02x %10llu %s",
-                       sgp->major, sgp->first_minor,
-                       (unsigned long long)get_capacity(sgp) >> 1,
-                       disk_name(sgp, 0, buf));
-               if (sgp->driverfs_dev != NULL &&
-                   sgp->driverfs_dev->driver != NULL)
-                       printk(" driver: %s\n",
-                               sgp->driverfs_dev->driver->name);
-               else
-                       printk(" (driver?)\n");
-
-               /* now show the partitions */
-               for (n = 0; n < sgp->minors - 1; ++n) {
-                       if (sgp->part[n] == NULL)
-                               continue;
-                       if (sgp->part[n]->nr_sects == 0)
-                               continue;
-                       printk("  %02x%02x %10llu %s\n",
-                               sgp->major, n + 1 + sgp->first_minor,
-                               (unsigned long long)sgp->part[n]->nr_sects >> 1,
-                               disk_name(sgp, n + 1, buf));
-               }
+       sgp = dev_to_disk(dev);
+       /*
+        * Don't show empty devices or things that have been surpressed
+        */
+       if (get_capacity(sgp) == 0 ||
+           (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO))
+               goto exit;
+
+       /*
+        * Note, unlike /proc/partitions, I am showing the numbers in
+        * hex - the same format as the root= option takes.
+        */
+       printk("%02x%02x %10llu %s",
+               sgp->major, sgp->first_minor,
+               (unsigned long long)get_capacity(sgp) >> 1,
+               disk_name(sgp, 0, buf));
+       if (sgp->driverfs_dev != NULL &&
+           sgp->driverfs_dev->driver != NULL)
+               printk(" driver: %s\n",
+                       sgp->driverfs_dev->driver->name);
+       else
+               printk(" (driver?)\n");
+
+       /* now show the partitions */
+       for (n = 0; n < sgp->minors - 1; ++n) {
+               if (sgp->part[n] == NULL)
+                       goto exit;
+               if (sgp->part[n]->nr_sects == 0)
+                       goto exit;
+               printk("  %02x%02x %10llu %s\n",
+                       sgp->major, n + 1 + sgp->first_minor,
+                       (unsigned long long)sgp->part[n]->nr_sects >> 1,
+                       disk_name(sgp, n + 1, buf));
        }
+exit:
+       return 0;
+}
 
+/*
+ * print a full list of all partitions - intended for places where the root
+ * filesystem can't be mounted and thus to give the victim some idea of what
+ * went wrong
+ */
+void __init printk_all_partitions(void)
+{
+       mutex_lock(&block_class_lock);
+       class_for_each_device(&block_class, NULL, NULL, printk_partition);
        mutex_unlock(&block_class_lock);
 }
 
 #ifdef CONFIG_PROC_FS
 /* iterator */
+static int find_start(struct device *dev, void *data)
+{
+       loff_t k = *(loff_t *)data;
+
+       if (dev->type != &disk_type)
+               return 0;
+       if (!k--)
+               return 1;
+       return 0;
+}
+
 static void *part_start(struct seq_file *part, loff_t *pos)
 {
-       loff_t k = *pos;
        struct device *dev;
+       loff_t n = *pos;
+
+       if (!n)
+               seq_puts(part, "major minor  #blocks  name\n\n");
 
        mutex_lock(&block_class_lock);
-       list_for_each_entry(dev, &block_class.devices, node) {
-               if (dev->type != &disk_type)
-                       continue;
-               if (!k--)
-                       return dev_to_disk(dev);
-       }
+       dev = class_find_device(&block_class, NULL, (void *)pos, find_start);
+       if (dev)
+               return dev_to_disk(dev);
        return NULL;
 }
 
+static int find_next(struct device *dev, void *data)
+{
+       if (dev->type == &disk_type)
+               return 1;
+       return 0;
+}
+
 static void *part_next(struct seq_file *part, void *v, loff_t *pos)
 {
        struct gendisk *gp = v;
        struct device *dev;
        ++*pos;
-       list_for_each_entry(dev, &gp->dev.node, node) {
-               if (&dev->node == &block_class.devices)
-                       return NULL;
-               if (dev->type == &disk_type)
-                       return dev_to_disk(dev);
-       }
+       dev = class_find_device(&block_class, &gp->dev, NULL, find_next);
+       if (dev)
+               return dev_to_disk(dev);
        return NULL;
 }
 
@@ -322,9 +346,6 @@ static int show_partition(struct seq_file *part, void *v)
        int n;
        char buf[BDEVNAME_SIZE];
 
-       if (&sgp->dev.node == block_class.devices.next)
-               seq_puts(part, "major minor  #blocks  name\n\n");
-
        /* Don't show non-partitionable removeable devices or empty devices */
        if (!get_capacity(sgp) ||
                        (sgp->minors == 1 && (sgp->flags & GENHD_FL_REMOVABLE)))
@@ -370,7 +391,10 @@ static struct kobject *base_probe(dev_t devt, int *part, void *data)
 
 static int __init genhd_device_init(void)
 {
-       int error = class_register(&block_class);
+       int error;
+
+       block_class.dev_kobj = sysfs_dev_block_kobj;
+       error = class_register(&block_class);
        if (unlikely(error))
                return error;
        bdev_map = kobj_map_init(base_probe, &block_class_lock);
@@ -532,6 +556,7 @@ static struct device_type disk_type = {
        .release        = disk_release,
 };
 
+#ifdef CONFIG_PROC_FS
 /*
  * aggregate disk stat collector.  Uses the same stats that the sysfs
  * entries do, above, but makes them available through one seq_file.
@@ -542,16 +567,12 @@ static struct device_type disk_type = {
 
 static void *diskstats_start(struct seq_file *part, loff_t *pos)
 {
-       loff_t k = *pos;
        struct device *dev;
 
        mutex_lock(&block_class_lock);
-       list_for_each_entry(dev, &block_class.devices, node) {
-               if (dev->type != &disk_type)
-                       continue;
-               if (!k--)
-                       return dev_to_disk(dev);
-       }
+       dev = class_find_device(&block_class, NULL, (void *)pos, find_start);
+       if (dev)
+               return dev_to_disk(dev);
        return NULL;
 }
 
@@ -561,12 +582,9 @@ static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos)
        struct device *dev;
 
        ++*pos;
-       list_for_each_entry(dev, &gp->dev.node, node) {
-               if (&dev->node == &block_class.devices)
-                       return NULL;
-               if (dev->type == &disk_type)
-                       return dev_to_disk(dev);
-       }
+       dev = class_find_device(&block_class, &gp->dev, NULL, find_next);
+       if (dev)
+               return dev_to_disk(dev);
        return NULL;
 }
 
@@ -641,6 +659,7 @@ const struct seq_operations diskstats_op = {
        .stop   = diskstats_stop,
        .show   = diskstats_show
 };
+#endif /* CONFIG_PROC_FS */
 
 static void media_change_notify_thread(struct work_struct *work)
 {
@@ -665,24 +684,38 @@ void genhd_media_change_notify(struct gendisk *disk)
 EXPORT_SYMBOL_GPL(genhd_media_change_notify);
 #endif  /*  0  */
 
+struct find_block {
+       const char *name;
+       int part;
+};
+
+static int match_id(struct device *dev, void *data)
+{
+       struct find_block *find = data;
+
+       if (dev->type != &disk_type)
+               return 0;
+       if (strcmp(dev->bus_id, find->name) == 0) {
+               struct gendisk *disk = dev_to_disk(dev);
+               if (find->part < disk->minors)
+                       return 1;
+       }
+       return 0;
+}
+
 dev_t blk_lookup_devt(const char *name, int part)
 {
        struct device *dev;
        dev_t devt = MKDEV(0, 0);
+       struct find_block find;
 
        mutex_lock(&block_class_lock);
-       list_for_each_entry(dev, &block_class.devices, node) {
-               if (dev->type != &disk_type)
-                       continue;
-               if (strcmp(dev->bus_id, name) == 0) {
-                       struct gendisk *disk = dev_to_disk(dev);
-
-                       if (part < disk->minors)
-                               devt = MKDEV(MAJOR(dev->devt),
-                                            MINOR(dev->devt) + part);
-                       break;
-               }
-       }
+       find.name = name;
+       find.part = part;
+       dev = class_find_device(&block_class, NULL, (void *)&find, match_id);
+       if (dev)
+               devt = MKDEV(MAJOR(dev->devt),
+                            MINOR(dev->devt) + part);
        mutex_unlock(&block_class_lock);
 
        return devt;
index a5eda80e84277806b4cbb49c32d55dad233df381..ddccfb01c416b9a636324ee273244b147c644a16 100644 (file)
@@ -73,15 +73,7 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
                pr_debug("%s: (sync) len: %zu\n", __func__, len);
 
                /* wait for any prerequisite operations */
-               if (depend_tx) {
-                       /* if ack is already set then we cannot be sure
-                        * we are referring to the correct operation
-                        */
-                       BUG_ON(async_tx_test_ack(depend_tx));
-                       if (dma_wait_for_async_tx(depend_tx) == DMA_ERROR)
-                               panic("%s: DMA_ERROR waiting for depend_tx\n",
-                                       __func__);
-               }
+               async_tx_quiesce(&depend_tx);
 
                dest_buf = kmap_atomic(dest, KM_USER0) + dest_offset;
                src_buf = kmap_atomic(src, KM_USER1) + src_offset;
@@ -91,7 +83,7 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
                kunmap_atomic(dest_buf, KM_USER0);
                kunmap_atomic(src_buf, KM_USER1);
 
-               async_tx_sync_epilog(flags, depend_tx, cb_fn, cb_param);
+               async_tx_sync_epilog(cb_fn, cb_param);
        }
 
        return tx;
index f5ff3906b035d52d5c6b28949ca6470b46d60f88..5b5eb99bb244311bb1456c62080249d812967be4 100644 (file)
@@ -72,19 +72,11 @@ async_memset(struct page *dest, int val, unsigned int offset,
                dest_buf = (void *) (((char *) page_address(dest)) + offset);
 
                /* wait for any prerequisite operations */
-               if (depend_tx) {
-                       /* if ack is already set then we cannot be sure
-                        * we are referring to the correct operation
-                        */
-                       BUG_ON(depend_tx->ack);
-                       if (dma_wait_for_async_tx(depend_tx) == DMA_ERROR)
-                               panic("%s: DMA_ERROR waiting for depend_tx\n",
-                                       __func__);
-               }
+               async_tx_quiesce(&depend_tx);
 
                memset(dest_buf, val, len);
 
-               async_tx_sync_epilog(flags, depend_tx, cb_fn, cb_param);
+               async_tx_sync_epilog(cb_fn, cb_param);
        }
 
        return tx;
index 095c798d31700746d8bd6769e3f5f8d015d7e264..85eaf7b1c53153ef07bdc33efa3a9d9c6cdff839 100644 (file)
@@ -295,7 +295,7 @@ dma_channel_add_remove(struct dma_client *client,
        case DMA_RESOURCE_REMOVED:
                found = 0;
                spin_lock_irqsave(&async_tx_lock, flags);
-               list_for_each_entry_rcu(ref, &async_tx_master_list, node)
+               list_for_each_entry(ref, &async_tx_master_list, node)
                        if (ref->chan == chan) {
                                /* permit backing devices to go away */
                                dma_chan_put(ref->chan);
@@ -608,23 +608,34 @@ async_trigger_callback(enum async_tx_flags flags,
                pr_debug("%s: (sync)\n", __func__);
 
                /* wait for any prerequisite operations */
-               if (depend_tx) {
-                       /* if ack is already set then we cannot be sure
-                        * we are referring to the correct operation
-                        */
-                       BUG_ON(async_tx_test_ack(depend_tx));
-                       if (dma_wait_for_async_tx(depend_tx) == DMA_ERROR)
-                               panic("%s: DMA_ERROR waiting for depend_tx\n",
-                                       __func__);
-               }
+               async_tx_quiesce(&depend_tx);
 
-               async_tx_sync_epilog(flags, depend_tx, cb_fn, cb_param);
+               async_tx_sync_epilog(cb_fn, cb_param);
        }
 
        return tx;
 }
 EXPORT_SYMBOL_GPL(async_trigger_callback);
 
+/**
+ * async_tx_quiesce - ensure tx is complete and freeable upon return
+ * @tx - transaction to quiesce
+ */
+void async_tx_quiesce(struct dma_async_tx_descriptor **tx)
+{
+       if (*tx) {
+               /* if ack is already set then we cannot be sure
+                * we are referring to the correct operation
+                */
+               BUG_ON(async_tx_test_ack(*tx));
+               if (dma_wait_for_async_tx(*tx) == DMA_ERROR)
+                       panic("DMA_ERROR waiting for transaction\n");
+               async_tx_ack(*tx);
+               *tx = NULL;
+       }
+}
+EXPORT_SYMBOL_GPL(async_tx_quiesce);
+
 module_init(async_tx_init);
 module_exit(async_tx_exit);
 
index 3a0dddca5a1097e473d103a15797547da66e7bf1..65974c6d3d7a78dbc40e9437b416d5990e04e9a2 100644 (file)
  *     when CONFIG_DMA_ENGINE=n
  */
 static __always_inline struct dma_async_tx_descriptor *
-do_async_xor(struct dma_device *device,
-       struct dma_chan *chan, struct page *dest, struct page **src_list,
-       unsigned int offset, unsigned int src_cnt, size_t len,
-       enum async_tx_flags flags, struct dma_async_tx_descriptor *depend_tx,
-       dma_async_tx_callback cb_fn, void *cb_param)
+do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list,
+            unsigned int offset, int src_cnt, size_t len,
+            enum async_tx_flags flags,
+            struct dma_async_tx_descriptor *depend_tx,
+            dma_async_tx_callback cb_fn, void *cb_param)
 {
-       dma_addr_t dma_dest;
+       struct dma_device *dma = chan->device;
        dma_addr_t *dma_src = (dma_addr_t *) src_list;
-       struct dma_async_tx_descriptor *tx;
+       struct dma_async_tx_descriptor *tx = NULL;
+       int src_off = 0;
        int i;
-       unsigned long dma_prep_flags = cb_fn ? DMA_PREP_INTERRUPT : 0;
-
-       pr_debug("%s: len: %zu\n", __func__, len);
-
-       dma_dest = dma_map_page(device->dev, dest, offset, len,
-                               DMA_FROM_DEVICE);
+       dma_async_tx_callback _cb_fn;
+       void *_cb_param;
+       enum async_tx_flags async_flags;
+       enum dma_ctrl_flags dma_flags;
+       int xor_src_cnt;
+       dma_addr_t dma_dest;
 
+       dma_dest = dma_map_page(dma->dev, dest, offset, len, DMA_FROM_DEVICE);
        for (i = 0; i < src_cnt; i++)
-               dma_src[i] = dma_map_page(device->dev, src_list[i], offset,
+               dma_src[i] = dma_map_page(dma->dev, src_list[i], offset,
                                          len, DMA_TO_DEVICE);
 
-       /* Since we have clobbered the src_list we are committed
-        * to doing this asynchronously.  Drivers force forward progress
-        * in case they can not provide a descriptor
-        */
-       tx = device->device_prep_dma_xor(chan, dma_dest, dma_src, src_cnt, len,
-                                        dma_prep_flags);
-       if (!tx) {
-               if (depend_tx)
-                       dma_wait_for_async_tx(depend_tx);
-
-               while (!tx)
-                       tx = device->device_prep_dma_xor(chan, dma_dest,
-                                                        dma_src, src_cnt, len,
-                                                        dma_prep_flags);
-       }
+       while (src_cnt) {
+               async_flags = flags;
+               dma_flags = 0;
+               xor_src_cnt = min(src_cnt, dma->max_xor);
+               /* if we are submitting additional xors, leave the chain open,
+                * clear the callback parameters, and leave the destination
+                * buffer mapped
+                */
+               if (src_cnt > xor_src_cnt) {
+                       async_flags &= ~ASYNC_TX_ACK;
+                       dma_flags = DMA_COMPL_SKIP_DEST_UNMAP;
+                       _cb_fn = NULL;
+                       _cb_param = NULL;
+               } else {
+                       _cb_fn = cb_fn;
+                       _cb_param = cb_param;
+               }
+               if (_cb_fn)
+                       dma_flags |= DMA_PREP_INTERRUPT;
 
-       async_tx_submit(chan, tx, flags, depend_tx, cb_fn, cb_param);
+               /* Since we have clobbered the src_list we are committed
+                * to doing this asynchronously.  Drivers force forward progress
+                * in case they can not provide a descriptor
+                */
+               tx = dma->device_prep_dma_xor(chan, dma_dest, &dma_src[src_off],
+                                             xor_src_cnt, len, dma_flags);
+
+               if (unlikely(!tx))
+                       async_tx_quiesce(&depend_tx);
+
+               /* spin wait for the preceeding transactions to complete */
+               while (unlikely(!tx)) {
+                       dma_async_issue_pending(chan);
+                       tx = dma->device_prep_dma_xor(chan, dma_dest,
+                                                     &dma_src[src_off],
+                                                     xor_src_cnt, len,
+                                                     dma_flags);
+               }
+
+               async_tx_submit(chan, tx, async_flags, depend_tx, _cb_fn,
+                               _cb_param);
+
+               depend_tx = tx;
+               flags |= ASYNC_TX_DEP_ACK;
+
+               if (src_cnt > xor_src_cnt) {
+                       /* drop completed sources */
+                       src_cnt -= xor_src_cnt;
+                       src_off += xor_src_cnt;
+
+                       /* use the intermediate result a source */
+                       dma_src[--src_off] = dma_dest;
+                       src_cnt++;
+               } else
+                       break;
+       }
 
        return tx;
 }
 
 static void
 do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset,
-       unsigned int src_cnt, size_t len, enum async_tx_flags flags,
-       struct dma_async_tx_descriptor *depend_tx,
-       dma_async_tx_callback cb_fn, void *cb_param)
+           int src_cnt, size_t len, enum async_tx_flags flags,
+           dma_async_tx_callback cb_fn, void *cb_param)
 {
-       void *_dest;
        int i;
-
-       pr_debug("%s: len: %zu\n", __func__, len);
+       int xor_src_cnt;
+       int src_off = 0;
+       void *dest_buf;
+       void **srcs = (void **) src_list;
 
        /* reuse the 'src_list' array to convert to buffer pointers */
        for (i = 0; i < src_cnt; i++)
-               src_list[i] = (struct page *)
-                       (page_address(src_list[i]) + offset);
+               srcs[i] = page_address(src_list[i]) + offset;
 
        /* set destination address */
-       _dest = page_address(dest) + offset;
+       dest_buf = page_address(dest) + offset;
 
        if (flags & ASYNC_TX_XOR_ZERO_DST)
-               memset(_dest, 0, len);
+               memset(dest_buf, 0, len);
 
-       xor_blocks(src_cnt, len, _dest,
-               (void **) src_list);
+       while (src_cnt > 0) {
+               /* process up to 'MAX_XOR_BLOCKS' sources */
+               xor_src_cnt = min(src_cnt, MAX_XOR_BLOCKS);
+               xor_blocks(xor_src_cnt, len, dest_buf, &srcs[src_off]);
 
-       async_tx_sync_epilog(flags, depend_tx, cb_fn, cb_param);
+               /* drop completed sources */
+               src_cnt -= xor_src_cnt;
+               src_off += xor_src_cnt;
+       }
+
+       async_tx_sync_epilog(cb_fn, cb_param);
 }
 
 /**
@@ -132,106 +179,34 @@ async_xor(struct page *dest, struct page **src_list, unsigned int offset,
        struct dma_chan *chan = async_tx_find_channel(depend_tx, DMA_XOR,
                                                      &dest, 1, src_list,
                                                      src_cnt, len);
-       struct dma_device *device = chan ? chan->device : NULL;
-       struct dma_async_tx_descriptor *tx = NULL;
-       dma_async_tx_callback _cb_fn;
-       void *_cb_param;
-       unsigned long local_flags;
-       int xor_src_cnt;
-       int i = 0, src_off = 0;
-
        BUG_ON(src_cnt <= 1);
 
-       while (src_cnt) {
-               local_flags = flags;
-               if (device) { /* run the xor asynchronously */
-                       xor_src_cnt = min(src_cnt, device->max_xor);
-                       /* if we are submitting additional xors
-                        * only set the callback on the last transaction
-                        */
-                       if (src_cnt > xor_src_cnt) {
-                               local_flags &= ~ASYNC_TX_ACK;
-                               _cb_fn = NULL;
-                               _cb_param = NULL;
-                       } else {
-                               _cb_fn = cb_fn;
-                               _cb_param = cb_param;
-                       }
-
-                       tx = do_async_xor(device, chan, dest,
-                                         &src_list[src_off], offset,
-                                         xor_src_cnt, len, local_flags,
-                                         depend_tx, _cb_fn, _cb_param);
-               } else { /* run the xor synchronously */
-                       /* in the sync case the dest is an implied source
-                        * (assumes the dest is at the src_off index)
-                        */
-                       if (flags & ASYNC_TX_XOR_DROP_DST) {
-                               src_cnt--;
-                               src_off++;
-                       }
-
-                       /* process up to 'MAX_XOR_BLOCKS' sources */
-                       xor_src_cnt = min(src_cnt, MAX_XOR_BLOCKS);
-
-                       /* if we are submitting additional xors
-                        * only set the callback on the last transaction
-                        */
-                       if (src_cnt > xor_src_cnt) {
-                               local_flags &= ~ASYNC_TX_ACK;
-                               _cb_fn = NULL;
-                               _cb_param = NULL;
-                       } else {
-                               _cb_fn = cb_fn;
-                               _cb_param = cb_param;
-                       }
-
-                       /* wait for any prerequisite operations */
-                       if (depend_tx) {
-                               /* if ack is already set then we cannot be sure
-                                * we are referring to the correct operation
-                                */
-                               BUG_ON(async_tx_test_ack(depend_tx));
-                               if (dma_wait_for_async_tx(depend_tx) ==
-                                       DMA_ERROR)
-                                       panic("%s: DMA_ERROR waiting for "
-                                               "depend_tx\n",
-                                               __func__);
-                       }
-
-                       do_sync_xor(dest, &src_list[src_off], offset,
-                               xor_src_cnt, len, local_flags, depend_tx,
-                               _cb_fn, _cb_param);
-               }
+       if (chan) {
+               /* run the xor asynchronously */
+               pr_debug("%s (async): len: %zu\n", __func__, len);
 
-               /* the previous tx is hidden from the client,
-                * so ack it
-                */
-               if (i && depend_tx)
-                       async_tx_ack(depend_tx);
+               return do_async_xor(chan, dest, src_list, offset, src_cnt, len,
+                                   flags, depend_tx, cb_fn, cb_param);
+       } else {
+               /* run the xor synchronously */
+               pr_debug("%s (sync): len: %zu\n", __func__, len);
 
-               depend_tx = tx;
+               /* in the sync case the dest is an implied source
+                * (assumes the dest is the first source)
+                */
+               if (flags & ASYNC_TX_XOR_DROP_DST) {
+                       src_cnt--;
+                       src_list++;
+               }
 
-               if (src_cnt > xor_src_cnt) {
-                       /* drop completed sources */
-                       src_cnt -= xor_src_cnt;
-                       src_off += xor_src_cnt;
+               /* wait for any prerequisite operations */
+               async_tx_quiesce(&depend_tx);
 
-                       /* unconditionally preserve the destination */
-                       flags &= ~ASYNC_TX_XOR_ZERO_DST;
+               do_sync_xor(dest, src_list, offset, src_cnt, len,
+                           flags, cb_fn, cb_param);
 
-                       /* use the intermediate result a source, but remember
-                        * it's dropped, because it's implied, in the sync case
-                        */
-                       src_list[--src_off] = dest;
-                       src_cnt++;
-                       flags |= ASYNC_TX_XOR_DROP_DST;
-               } else
-                       src_cnt = 0;
-               i++;
+               return NULL;
        }
-
-       return tx;
 }
 EXPORT_SYMBOL_GPL(async_xor);
 
@@ -285,11 +260,11 @@ async_xor_zero_sum(struct page *dest, struct page **src_list,
                tx = device->device_prep_dma_zero_sum(chan, dma_src, src_cnt,
                                                      len, result,
                                                      dma_prep_flags);
-               if (!tx) {
-                       if (depend_tx)
-                               dma_wait_for_async_tx(depend_tx);
+               if (unlikely(!tx)) {
+                       async_tx_quiesce(&depend_tx);
 
                        while (!tx)
+                               dma_async_issue_pending(chan);
                                tx = device->device_prep_dma_zero_sum(chan,
                                        dma_src, src_cnt, len, result,
                                        dma_prep_flags);
@@ -307,18 +282,11 @@ async_xor_zero_sum(struct page *dest, struct page **src_list,
                tx = async_xor(dest, src_list, offset, src_cnt, len, xor_flags,
                        depend_tx, NULL, NULL);
 
-               if (tx) {
-                       if (dma_wait_for_async_tx(tx) == DMA_ERROR)
-                               panic("%s: DMA_ERROR waiting for tx\n",
-                                       __func__);
-                       async_tx_ack(tx);
-               }
+               async_tx_quiesce(&tx);
 
                *result = page_is_zero(dest, offset, len) ? 0 : 1;
 
-               tx = NULL;
-
-               async_tx_sync_epilog(flags, depend_tx, cb_fn, cb_param);
+               async_tx_sync_epilog(cb_fn, cb_param);
        }
 
        return tx;
index 55c17afbe669c86cc6da590994a143fe6d543e77..2655bc1b4eebc7cbb02a16afc715e703dd0e3499 100644 (file)
@@ -263,22 +263,22 @@ static int acpi_fan_add(struct acpi_device *device)
                goto end;
        }
 
-       printk(KERN_INFO PREFIX
-               "%s is registered as cooling_device%d\n",
-               device->dev.bus_id, cdev->id);
+       dev_info(&device->dev, "registered as cooling_device%d\n", cdev->id);
 
        acpi_driver_data(device) = cdev;
        result = sysfs_create_link(&device->dev.kobj,
                                   &cdev->device.kobj,
                                   "thermal_cooling");
        if (result)
-               printk(KERN_ERR PREFIX "Create sysfs link\n");
+               dev_err(&device->dev, "Failed to create sysfs link "
+                       "'thermal_cooling'\n");
 
        result = sysfs_create_link(&cdev->device.kobj,
                                   &device->dev.kobj,
                                   "device");
        if (result)
-               printk(KERN_ERR PREFIX "Create sysfs link\n");
+               dev_err(&device->dev, "Failed to create sysfs link "
+                       "'device'\n");
 
        result = acpi_fan_add_fs(device);
        if (result)
index 2f173e83f8a76bf0291f93689fe075d3fb4e7edf..084109507c9f5101a1cdcf678db34005984a2855 100644 (file)
@@ -146,8 +146,7 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
        acpi_status status;
 
        if (dev->archdata.acpi_handle) {
-               printk(KERN_WARNING PREFIX
-                      "Drivers changed 'acpi_handle' for %s\n", dev->bus_id);
+               dev_warn(dev, "Drivers changed 'acpi_handle'\n");
                return -EINVAL;
        }
        get_device(dev);
@@ -195,8 +194,7 @@ static int acpi_unbind_one(struct device *dev)
                /* acpi_bind_one increase refcnt by one */
                put_device(dev);
        } else {
-               printk(KERN_ERR PREFIX
-                      "Oops, 'acpi_handle' corrupt for %s\n", dev->bus_id);
+               dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
        }
        return 0;
 }
index ec0f2d581ece851d67e98f51f4107552f9146f50..e36422a7122c7e974ce9728fce8b97b21e8fe49a 100644 (file)
@@ -714,9 +714,8 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
                goto end;
        }
 
-       printk(KERN_INFO PREFIX
-               "%s is registered as cooling_device%d\n",
-               device->dev.bus_id, pr->cdev->id);
+       dev_info(&device->dev, "registered as cooling_device%d\n",
+                pr->cdev->id);
 
        result = sysfs_create_link(&device->dev.kobj,
                                   &pr->cdev->device.kobj,
index f3132aa47a69d7b0656d9fe4fa40e9c5a9f8edcf..f6f52c1a2abad88cecc73a41ea65c4bddfafc0ae 100644 (file)
@@ -471,7 +471,7 @@ static int acpi_device_register(struct acpi_device *device,
        device->dev.release = &acpi_device_release;
        result = device_add(&device->dev);
        if(result) {
-               printk(KERN_ERR PREFIX "Error adding device %s", device->dev.bus_id);
+               dev_err(&device->dev, "Error adding device\n");
                goto end;
        }
 
index 84c795fb9b1ebef3a787907ba372cc368923a6c2..30a3413379334e9ee24071f8d704dc3156bc118c 100644 (file)
@@ -1179,8 +1179,8 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
 
        tz->tz_enabled = 1;
 
-       printk(KERN_INFO PREFIX "%s is registered as thermal_zone%d\n",
-                       tz->device->dev.bus_id, tz->thermal_zone->id);
+       dev_info(&tz->device->dev, "registered as thermal_zone%d\n",
+                tz->thermal_zone->id);
        return 0;
 }
 
index 64c889331f3bd97be35ca4eeb0153e50aae74111..37b9e16710d60596442c780e683d24441e797a61 100644 (file)
@@ -762,9 +762,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
                if (IS_ERR(device->cdev))
                        return;
 
-               printk(KERN_INFO PREFIX
-                       "%s is registered as cooling_device%d\n",
-                       device->dev->dev.bus_id, device->cdev->id);
+               dev_info(&device->dev->dev, "registered as cooling_device%d\n",
+                        device->cdev->id);
                result = sysfs_create_link(&device->dev->dev.kobj,
                                &device->cdev->device.kobj,
                                "thermal_cooling");
index d47482fa1d212644a5e152b8d8c033e40c9a8626..6318f6b573608f345129234abf85c2629f6df4a1 100644 (file)
@@ -27,8 +27,9 @@ config PREVENT_FIRMWARE_BUILD
          If unsure say Y here.
 
 config FW_LOADER
-       tristate "Userspace firmware loading support"
+       tristate "Userspace firmware loading support" if EMBEDDED
        depends on HOTPLUG
+       default y
        ---help---
          This option is provided for the case where no in-kernel-tree modules
          require userspace firmware loading support, but a module built outside
index 2c9ae43e221933607e81f32b26c40f7156447dc5..31dc0cd84afa2474c8f3a4a511e07c30ef1febe6 100644 (file)
@@ -36,6 +36,33 @@ struct driver_private {
 };
 #define to_driver(obj) container_of(obj, struct driver_private, kobj)
 
+
+/**
+ * struct class_private - structure to hold the private to the driver core portions of the class structure.
+ *
+ * @class_subsys - the struct kset that defines this class.  This is the main kobject
+ * @class_devices - list of devices associated with this class
+ * @class_interfaces - list of class_interfaces associated with this class
+ * @class_dirs - "glue" directory for virtual devices associated with this class
+ * @class_mutex - mutex to protect the children, devices, and interfaces lists.
+ * @class - pointer back to the struct class that this structure is associated
+ * with.
+ *
+ * This structure is the one that is the actual kobject allowing struct
+ * class to be statically allocated safely.  Nothing outside of the driver
+ * core should ever touch these fields.
+ */
+struct class_private {
+       struct kset class_subsys;
+       struct list_head class_devices;
+       struct list_head class_interfaces;
+       struct kset class_dirs;
+       struct mutex class_mutex;
+       struct class *class;
+};
+#define to_class(obj)  \
+       container_of(obj, struct class_private, class_subsys.kobj)
+
 /* initialisation functions */
 extern int devices_init(void);
 extern int buses_init(void);
index e085af0ff94fb93007e7dce12f98443e4c5daa6d..839d27cecb36c8acb3bf8e9e4880ba720e6fe53b 100644 (file)
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/genhd.h>
+#include <linux/mutex.h>
 #include "base.h"
 
 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
-#define to_class(obj) container_of(obj, struct class, subsys.kobj)
 
 static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr,
                               char *buf)
 {
        struct class_attribute *class_attr = to_class_attr(attr);
-       struct class *dc = to_class(kobj);
+       struct class_private *cp = to_class(kobj);
        ssize_t ret = -EIO;
 
        if (class_attr->show)
-               ret = class_attr->show(dc, buf);
+               ret = class_attr->show(cp->class, buf);
        return ret;
 }
 
@@ -39,17 +39,18 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr,
                                const char *buf, size_t count)
 {
        struct class_attribute *class_attr = to_class_attr(attr);
-       struct class *dc = to_class(kobj);
+       struct class_private *cp = to_class(kobj);
        ssize_t ret = -EIO;
 
        if (class_attr->store)
-               ret = class_attr->store(dc, buf, count);
+               ret = class_attr->store(cp->class, buf, count);
        return ret;
 }
 
 static void class_release(struct kobject *kobj)
 {
-       struct class *class = to_class(kobj);
+       struct class_private *cp = to_class(kobj);
+       struct class *class = cp->class;
 
        pr_debug("class '%s': release.\n", class->name);
 
@@ -70,7 +71,7 @@ static struct kobj_type class_ktype = {
        .release        = class_release,
 };
 
-/* Hotplug events for classes go to the class_obj subsys */
+/* Hotplug events for classes go to the class class_subsys */
 static struct kset *class_kset;
 
 
@@ -78,7 +79,8 @@ int class_create_file(struct class *cls, const struct class_attribute *attr)
 {
        int error;
        if (cls)
-               error = sysfs_create_file(&cls->subsys.kobj, &attr->attr);
+               error = sysfs_create_file(&cls->p->class_subsys.kobj,
+                                         &attr->attr);
        else
                error = -EINVAL;
        return error;
@@ -87,21 +89,20 @@ int class_create_file(struct class *cls, const struct class_attribute *attr)
 void class_remove_file(struct class *cls, const struct class_attribute *attr)
 {
        if (cls)
-               sysfs_remove_file(&cls->subsys.kobj, &attr->attr);
+               sysfs_remove_file(&cls->p->class_subsys.kobj, &attr->attr);
 }
 
 static struct class *class_get(struct class *cls)
 {
        if (cls)
-               return container_of(kset_get(&cls->subsys),
-                                   struct class, subsys);
-       return NULL;
+               kset_get(&cls->p->class_subsys);
+       return cls;
 }
 
 static void class_put(struct class *cls)
 {
        if (cls)
-               kset_put(&cls->subsys);
+               kset_put(&cls->p->class_subsys);
 }
 
 static int add_class_attrs(struct class *cls)
@@ -134,42 +135,57 @@ static void remove_class_attrs(struct class *cls)
        }
 }
 
-int class_register(struct class *cls)
+int __class_register(struct class *cls, struct lock_class_key *key)
 {
+       struct class_private *cp;
        int error;
 
        pr_debug("device class '%s': registering\n", cls->name);
 
-       INIT_LIST_HEAD(&cls->devices);
-       INIT_LIST_HEAD(&cls->interfaces);
-       kset_init(&cls->class_dirs);
-       init_MUTEX(&cls->sem);
-       error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name);
-       if (error)
+       cp = kzalloc(sizeof(*cp), GFP_KERNEL);
+       if (!cp)
+               return -ENOMEM;
+       INIT_LIST_HEAD(&cp->class_devices);
+       INIT_LIST_HEAD(&cp->class_interfaces);
+       kset_init(&cp->class_dirs);
+       __mutex_init(&cp->class_mutex, "struct class mutex", key);
+       error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name);
+       if (error) {
+               kfree(cp);
                return error;
+       }
+
+       /* set the default /sys/dev directory for devices of this class */
+       if (!cls->dev_kobj)
+               cls->dev_kobj = sysfs_dev_char_kobj;
 
 #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK)
        /* let the block class directory show up in the root of sysfs */
        if (cls != &block_class)
-               cls->subsys.kobj.kset = class_kset;
+               cp->class_subsys.kobj.kset = class_kset;
 #else
-       cls->subsys.kobj.kset = class_kset;
+       cp->class_subsys.kobj.kset = class_kset;
 #endif
-       cls->subsys.kobj.ktype = &class_ktype;
+       cp->class_subsys.kobj.ktype = &class_ktype;
+       cp->class = cls;
+       cls->p = cp;
 
-       error = kset_register(&cls->subsys);
-       if (!error) {
-               error = add_class_attrs(class_get(cls));
-               class_put(cls);
+       error = kset_register(&cp->class_subsys);
+       if (error) {
+               kfree(cp);
+               return error;
        }
+       error = add_class_attrs(class_get(cls));
+       class_put(cls);
        return error;
 }
+EXPORT_SYMBOL_GPL(__class_register);
 
 void class_unregister(struct class *cls)
 {
        pr_debug("device class '%s': unregistering\n", cls->name);
        remove_class_attrs(cls);
-       kset_unregister(&cls->subsys);
+       kset_unregister(&cls->p->class_subsys);
 }
 
 static void class_create_release(struct class *cls)
@@ -189,7 +205,8 @@ static void class_create_release(struct class *cls)
  * Note, the pointer created here is to be destroyed when finished by
  * making a call to class_destroy().
  */
-struct class *class_create(struct module *owner, const char *name)
+struct class *__class_create(struct module *owner, const char *name,
+                            struct lock_class_key *key)
 {
        struct class *cls;
        int retval;
@@ -204,7 +221,7 @@ struct class *class_create(struct module *owner, const char *name)
        cls->owner = owner;
        cls->class_release = class_create_release;
 
-       retval = class_register(cls);
+       retval = __class_register(cls, key);
        if (retval)
                goto error;
 
@@ -214,6 +231,7 @@ error:
        kfree(cls);
        return ERR_PTR(retval);
 }
+EXPORT_SYMBOL_GPL(__class_create);
 
 /**
  * class_destroy - destroys a struct class structure
@@ -252,39 +270,44 @@ char *make_class_name(const char *name, struct kobject *kobj)
 /**
  * class_for_each_device - device iterator
  * @class: the class we're iterating
+ * @start: the device to start with in the list, if any.
  * @data: data for the callback
  * @fn: function to be called for each device
  *
  * Iterate over @class's list of devices, and call @fn for each,
- * passing it @data.
+ * passing it @data.  If @start is set, the list iteration will start
+ * there, otherwise if it is NULL, the iteration starts at the
+ * beginning of the list.
  *
  * We check the return of @fn each time. If it returns anything
  * other than 0, we break out and return that value.
  *
- * Note, we hold class->sem in this function, so it can not be
+ * Note, we hold class->class_mutex in this function, so it can not be
  * re-acquired in @fn, otherwise it will self-deadlocking. For
  * example, calls to add or remove class members would be verboten.
  */
-int class_for_each_device(struct class *class, void *data,
-                          int (*fn)(struct device *, void *))
+int class_for_each_device(struct class *class, struct device *start,
+                         void *data, int (*fn)(struct device *, void *))
 {
        struct device *dev;
        int error = 0;
 
        if (!class)
                return -EINVAL;
-       down(&class->sem);
-       list_for_each_entry(dev, &class->devices, node) {
+       mutex_lock(&class->p->class_mutex);
+       list_for_each_entry(dev, &class->p->class_devices, node) {
+               if (start) {
+                       if (start == dev)
+                               start = NULL;
+                       continue;
+               }
                dev = get_device(dev);
-               if (dev) {
-                       error = fn(dev, data);
-                       put_device(dev);
-               } else
-                       error = -ENODEV;
+               error = fn(dev, data);
+               put_device(dev);
                if (error)
                        break;
        }
-       up(&class->sem);
+       mutex_unlock(&class->p->class_mutex);
 
        return error;
 }
@@ -293,6 +316,7 @@ EXPORT_SYMBOL_GPL(class_for_each_device);
 /**
  * class_find_device - device iterator for locating a particular device
  * @class: the class we're iterating
+ * @start: Device to begin with
  * @data: data for the match function
  * @match: function to check device
  *
@@ -306,12 +330,13 @@ EXPORT_SYMBOL_GPL(class_for_each_device);
  *
  * Note, you will need to drop the reference with put_device() after use.
  *
- * We hold class->sem in this function, so it can not be
+ * We hold class->class_mutex in this function, so it can not be
  * re-acquired in @match, otherwise it will self-deadlocking. For
  * example, calls to add or remove class members would be verboten.
  */
-struct device *class_find_device(struct class *class, void *data,
-                                  int (*match)(struct device *, void *))
+struct device *class_find_device(struct class *class, struct device *start,
+                                void *data,
+                                int (*match)(struct device *, void *))
 {
        struct device *dev;
        int found = 0;
@@ -319,19 +344,21 @@ struct device *class_find_device(struct class *class, void *data,
        if (!class)
                return NULL;
 
-       down(&class->sem);
-       list_for_each_entry(dev, &class->devices, node) {
+       mutex_lock(&class->p->class_mutex);
+       list_for_each_entry(dev, &class->p->class_devices, node) {
+               if (start) {
+                       if (start == dev)
+                               start = NULL;
+                       continue;
+               }
                dev = get_device(dev);
-               if (dev) {
-                       if (match(dev, data)) {
-                               found = 1;
-                               break;
-                       } else
-                               put_device(dev);
-               } else
+               if (match(dev, data)) {
+                       found = 1;
                        break;
+               } else
+                       put_device(dev);
        }
-       up(&class->sem);
+       mutex_unlock(&class->p->class_mutex);
 
        return found ? dev : NULL;
 }
@@ -349,13 +376,13 @@ int class_interface_register(struct class_interface *class_intf)
        if (!parent)
                return -EINVAL;
 
-       down(&parent->sem);
-       list_add_tail(&class_intf->node, &parent->interfaces);
+       mutex_lock(&parent->p->class_mutex);
+       list_add_tail(&class_intf->node, &parent->p->class_interfaces);
        if (class_intf->add_dev) {
-               list_for_each_entry(dev, &parent->devices, node)
+               list_for_each_entry(dev, &parent->p->class_devices, node)
                        class_intf->add_dev(dev, class_intf);
        }
-       up(&parent->sem);
+       mutex_unlock(&parent->p->class_mutex);
 
        return 0;
 }
@@ -368,13 +395,13 @@ void class_interface_unregister(struct class_interface *class_intf)
        if (!parent)
                return;
 
-       down(&parent->sem);
+       mutex_lock(&parent->p->class_mutex);
        list_del_init(&class_intf->node);
        if (class_intf->remove_dev) {
-               list_for_each_entry(dev, &parent->devices, node)
+               list_for_each_entry(dev, &parent->p->class_devices, node)
                        class_intf->remove_dev(dev, class_intf);
        }
-       up(&parent->sem);
+       mutex_unlock(&parent->p->class_mutex);
 
        class_put(parent);
 }
@@ -389,9 +416,7 @@ int __init classes_init(void)
 
 EXPORT_SYMBOL_GPL(class_create_file);
 EXPORT_SYMBOL_GPL(class_remove_file);
-EXPORT_SYMBOL_GPL(class_register);
 EXPORT_SYMBOL_GPL(class_unregister);
-EXPORT_SYMBOL_GPL(class_create);
 EXPORT_SYMBOL_GPL(class_destroy);
 
 EXPORT_SYMBOL_GPL(class_interface_register);
index ee0a51a3a41d876451395b0f2a93b6a06a430394..7d5c63c81a599fb220b0b2f831c95afaa454caed 100644 (file)
 #include <linux/genhd.h>
 #include <linux/kallsyms.h>
 #include <linux/semaphore.h>
+#include <linux/mutex.h>
 
 #include "base.h"
 #include "power/power.h"
 
 int (*platform_notify)(struct device *dev) = NULL;
 int (*platform_notify_remove)(struct device *dev) = NULL;
+static struct kobject *dev_kobj;
+struct kobject *sysfs_dev_char_kobj;
+struct kobject *sysfs_dev_block_kobj;
 
 #ifdef CONFIG_BLOCK
 static inline int device_is_not_partition(struct device *dev)
@@ -548,7 +552,7 @@ static struct kobject *get_device_parent(struct device *dev,
 {
        /* class devices without a parent live in /sys/class/<classname>/ */
        if (dev->class && (!parent || parent->class != dev->class))
-               return &dev->class->subsys.kobj;
+               return &dev->class->p->class_subsys.kobj;
        /* all other devices keep their parent */
        else if (parent)
                return &parent->kobj;
@@ -594,13 +598,13 @@ static struct kobject *get_device_parent(struct device *dev,
                        parent_kobj = &parent->kobj;
 
                /* find our class-directory at the parent and reference it */
-               spin_lock(&dev->class->class_dirs.list_lock);
-               list_for_each_entry(k, &dev->class->class_dirs.list, entry)
+               spin_lock(&dev->class->p->class_dirs.list_lock);
+               list_for_each_entry(k, &dev->class->p->class_dirs.list, entry)
                        if (k->parent == parent_kobj) {
                                kobj = kobject_get(k);
                                break;
                        }
-               spin_unlock(&dev->class->class_dirs.list_lock);
+               spin_unlock(&dev->class->p->class_dirs.list_lock);
                if (kobj)
                        return kobj;
 
@@ -608,7 +612,7 @@ static struct kobject *get_device_parent(struct device *dev,
                k = kobject_create();
                if (!k)
                        return NULL;
-               k->kset = &dev->class->class_dirs;
+               k->kset = &dev->class->p->class_dirs;
                retval = kobject_add(k, parent_kobj, "%s", dev->class->name);
                if (retval < 0) {
                        kobject_put(k);
@@ -627,7 +631,7 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
 {
        /* see if we live in a "glue" directory */
        if (!glue_dir || !dev->class ||
-           glue_dir->kset != &dev->class->class_dirs)
+           glue_dir->kset != &dev->class->p->class_dirs)
                return;
 
        kobject_put(glue_dir);
@@ -654,17 +658,18 @@ static int device_add_class_symlinks(struct device *dev)
        if (!dev->class)
                return 0;
 
-       error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj,
+       error = sysfs_create_link(&dev->kobj,
+                                 &dev->class->p->class_subsys.kobj,
                                  "subsystem");
        if (error)
                goto out;
 
 #ifdef CONFIG_SYSFS_DEPRECATED
        /* stacked class devices need a symlink in the class directory */
-       if (dev->kobj.parent != &dev->class->subsys.kobj &&
+       if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
            device_is_not_partition(dev)) {
-               error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
-                                         dev->bus_id);
+               error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
+                                         &dev->kobj, dev->bus_id);
                if (error)
                        goto out_subsys;
        }
@@ -701,13 +706,14 @@ out_device:
        if (dev->parent && device_is_not_partition(dev))
                sysfs_remove_link(&dev->kobj, "device");
 out_busid:
-       if (dev->kobj.parent != &dev->class->subsys.kobj &&
+       if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
            device_is_not_partition(dev))
-               sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
+               sysfs_remove_link(&dev->class->p->class_subsys.kobj,
+                                 dev->bus_id);
 #else
        /* link in the class directory pointing to the device */
-       error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
-                                 dev->bus_id);
+       error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
+                                 &dev->kobj, dev->bus_id);
        if (error)
                goto out_subsys;
 
@@ -720,7 +726,7 @@ out_busid:
        return 0;
 
 out_busid:
-       sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
+       sysfs_remove_link(&dev->class->p->class_subsys.kobj, dev->bus_id);
 #endif
 
 out_subsys:
@@ -746,14 +752,15 @@ static void device_remove_class_symlinks(struct device *dev)
                sysfs_remove_link(&dev->kobj, "device");
        }
 
-       if (dev->kobj.parent != &dev->class->subsys.kobj &&
+       if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
            device_is_not_partition(dev))
-               sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
+               sysfs_remove_link(&dev->class->p->class_subsys.kobj,
+                                 dev->bus_id);
 #else
        if (dev->parent && device_is_not_partition(dev))
                sysfs_remove_link(&dev->kobj, "device");
 
-       sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
+       sysfs_remove_link(&dev->class->p->class_subsys.kobj, dev->bus_id);
 #endif
 
        sysfs_remove_link(&dev->kobj, "subsystem");
@@ -775,6 +782,54 @@ int dev_set_name(struct device *dev, const char *fmt, ...)
 }
 EXPORT_SYMBOL_GPL(dev_set_name);
 
+/**
+ * device_to_dev_kobj - select a /sys/dev/ directory for the device
+ * @dev: device
+ *
+ * By default we select char/ for new entries.  Setting class->dev_obj
+ * to NULL prevents an entry from being created.  class->dev_kobj must
+ * be set (or cleared) before any devices are registered to the class
+ * otherwise device_create_sys_dev_entry() and
+ * device_remove_sys_dev_entry() will disagree about the the presence
+ * of the link.
+ */
+static struct kobject *device_to_dev_kobj(struct device *dev)
+{
+       struct kobject *kobj;
+
+       if (dev->class)
+               kobj = dev->class->dev_kobj;
+       else
+               kobj = sysfs_dev_char_kobj;
+
+       return kobj;
+}
+
+static int device_create_sys_dev_entry(struct device *dev)
+{
+       struct kobject *kobj = device_to_dev_kobj(dev);
+       int error = 0;
+       char devt_str[15];
+
+       if (kobj) {
+               format_dev_t(devt_str, dev->devt);
+               error = sysfs_create_link(kobj, &dev->kobj, devt_str);
+       }
+
+       return error;
+}
+
+static void device_remove_sys_dev_entry(struct device *dev)
+{
+       struct kobject *kobj = device_to_dev_kobj(dev);
+       char devt_str[15];
+
+       if (kobj) {
+               format_dev_t(devt_str, dev->devt);
+               sysfs_remove_link(kobj, devt_str);
+       }
+}
+
 /**
  * device_add - add device to device hierarchy.
  * @dev: device.
@@ -829,6 +884,10 @@ int device_add(struct device *dev)
                error = device_create_file(dev, &devt_attr);
                if (error)
                        goto ueventattrError;
+
+               error = device_create_sys_dev_entry(dev);
+               if (error)
+                       goto devtattrError;
        }
 
        error = device_add_class_symlinks(dev);
@@ -849,15 +908,16 @@ int device_add(struct device *dev)
                klist_add_tail(&dev->knode_parent, &parent->klist_children);
 
        if (dev->class) {
-               down(&dev->class->sem);
+               mutex_lock(&dev->class->p->class_mutex);
                /* tie the class to the device */
-               list_add_tail(&dev->node, &dev->class->devices);
+               list_add_tail(&dev->node, &dev->class->p->class_devices);
 
                /* notify any interfaces that the device is here */
-               list_for_each_entry(class_intf, &dev->class->interfaces, node)
+               list_for_each_entry(class_intf,
+                                   &dev->class->p->class_interfaces, node)
                        if (class_intf->add_dev)
                                class_intf->add_dev(dev, class_intf);
-               up(&dev->class->sem);
+               mutex_unlock(&dev->class->p->class_mutex);
        }
  Done:
        put_device(dev);
@@ -872,6 +932,9 @@ int device_add(struct device *dev)
  AttrsError:
        device_remove_class_symlinks(dev);
  SymlinkError:
+       if (MAJOR(dev->devt))
+               device_remove_sys_dev_entry(dev);
+ devtattrError:
        if (MAJOR(dev->devt))
                device_remove_file(dev, &devt_attr);
  ueventattrError:
@@ -948,19 +1011,22 @@ void device_del(struct device *dev)
        device_pm_remove(dev);
        if (parent)
                klist_del(&dev->knode_parent);
-       if (MAJOR(dev->devt))
+       if (MAJOR(dev->devt)) {
+               device_remove_sys_dev_entry(dev);
                device_remove_file(dev, &devt_attr);
+       }
        if (dev->class) {
                device_remove_class_symlinks(dev);
 
-               down(&dev->class->sem);
+               mutex_lock(&dev->class->p->class_mutex);
                /* notify any interfaces that the device is now gone */
-               list_for_each_entry(class_intf, &dev->class->interfaces, node)
+               list_for_each_entry(class_intf,
+                                   &dev->class->p->class_interfaces, node)
                        if (class_intf->remove_dev)
                                class_intf->remove_dev(dev, class_intf);
                /* remove the device from the class list */
                list_del_init(&dev->node);
-               up(&dev->class->sem);
+               mutex_unlock(&dev->class->p->class_mutex);
        }
        device_remove_file(dev, &uevent_attr);
        device_remove_attrs(dev);
@@ -1074,7 +1140,25 @@ int __init devices_init(void)
        devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
        if (!devices_kset)
                return -ENOMEM;
+       dev_kobj = kobject_create_and_add("dev", NULL);
+       if (!dev_kobj)
+               goto dev_kobj_err;
+       sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);
+       if (!sysfs_dev_block_kobj)
+               goto block_kobj_err;
+       sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);
+       if (!sysfs_dev_char_kobj)
+               goto char_kobj_err;
+
        return 0;
+
+ char_kobj_err:
+       kobject_put(sysfs_dev_block_kobj);
+ block_kobj_err:
+       kobject_put(dev_kobj);
+ dev_kobj_err:
+       kset_unregister(devices_kset);
+       return -ENOMEM;
 }
 
 EXPORT_SYMBOL_GPL(device_for_each_child);
@@ -1157,49 +1241,12 @@ error:
 }
 EXPORT_SYMBOL_GPL(device_create_vargs);
 
-/**
- * device_create_drvdata - creates a device and registers it with sysfs
- * @class: pointer to the struct class that this device should be registered to
- * @parent: pointer to the parent struct device of this new device, if any
- * @devt: the dev_t for the char device to be added
- * @drvdata: the data to be added to the device for callbacks
- * @fmt: string for the device's name
- *
- * This function can be used by char device classes.  A struct device
- * will be created in sysfs, registered to the specified class.
- *
- * A "dev" file will be created, showing the dev_t for the device, if
- * the dev_t is not 0,0.
- * If a pointer to a parent struct device is passed in, the newly created
- * struct device will be a child of that device in sysfs.
- * The pointer to the struct device will be returned from the call.
- * Any further sysfs files that might be required can be created using this
- * pointer.
- *
- * Note: the struct class passed to this function must have previously
- * been created with a call to class_create().
- */
-struct device *device_create_drvdata(struct class *class,
-                                    struct device *parent,
-                                    dev_t devt,
-                                    void *drvdata,
-                                    const char *fmt, ...)
-{
-       va_list vargs;
-       struct device *dev;
-
-       va_start(vargs, fmt);
-       dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
-       va_end(vargs);
-       return dev;
-}
-EXPORT_SYMBOL_GPL(device_create_drvdata);
-
 /**
  * device_create - creates a device and registers it with sysfs
  * @class: pointer to the struct class that this device should be registered to
  * @parent: pointer to the parent struct device of this new device, if any
  * @devt: the dev_t for the char device to be added
+ * @drvdata: the data to be added to the device for callbacks
  * @fmt: string for the device's name
  *
  * This function can be used by char device classes.  A struct device
@@ -1217,13 +1264,13 @@ EXPORT_SYMBOL_GPL(device_create_drvdata);
  * been created with a call to class_create().
  */
 struct device *device_create(struct class *class, struct device *parent,
-                            dev_t devt, const char *fmt, ...)
+                            dev_t devt, void *drvdata, const char *fmt, ...)
 {
        va_list vargs;
        struct device *dev;
 
        va_start(vargs, fmt);
-       dev = device_create_vargs(class, parent, devt, NULL, fmt, vargs);
+       dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
        va_end(vargs);
        return dev;
 }
@@ -1248,7 +1295,7 @@ void device_destroy(struct class *class, dev_t devt)
 {
        struct device *dev;
 
-       dev = class_find_device(class, &devt, __match_devt);
+       dev = class_find_device(class, NULL, &devt, __match_devt);
        if (dev) {
                put_device(dev);
                device_unregister(dev);
@@ -1298,8 +1345,9 @@ int device_rename(struct device *dev, char *new_name)
        if (old_class_name) {
                new_class_name = make_class_name(dev->class->name, &dev->kobj);
                if (new_class_name) {
-                       error = sysfs_create_link(&dev->parent->kobj,
-                                                 &dev->kobj, new_class_name);
+                       error = sysfs_create_link_nowarn(&dev->parent->kobj,
+                                                        &dev->kobj,
+                                                        new_class_name);
                        if (error)
                                goto out;
                        sysfs_remove_link(&dev->parent->kobj, old_class_name);
@@ -1307,11 +1355,12 @@ int device_rename(struct device *dev, char *new_name)
        }
 #else
        if (dev->class) {
-               error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
-                                         dev->bus_id);
+               error = sysfs_create_link_nowarn(&dev->class->p->class_subsys.kobj,
+                                                &dev->kobj, dev->bus_id);
                if (error)
                        goto out;
-               sysfs_remove_link(&dev->class->subsys.kobj, old_device_name);
+               sysfs_remove_link(&dev->class->p->class_subsys.kobj,
+                                 old_device_name);
        }
 #endif
 
@@ -1447,4 +1496,7 @@ void device_shutdown(void)
                        dev->driver->shutdown(dev);
                }
        }
+       kobject_put(sysfs_dev_char_kobj);
+       kobject_put(sysfs_dev_block_kobj);
+       kobject_put(dev_kobj);
 }
index 5000402ae09234267aa9112ef4fe36a7d36b0d4f..64f5d54f7edcee095ae8ead0a2f29d032ce546cd 100644 (file)
@@ -21,15 +21,16 @@ EXPORT_SYMBOL(cpu_sysdev_class);
 static DEFINE_PER_CPU(struct sys_device *, cpu_sys_devices);
 
 #ifdef CONFIG_HOTPLUG_CPU
-static ssize_t show_online(struct sys_device *dev, char *buf)
+static ssize_t show_online(struct sys_device *dev, struct sysdev_attribute *attr,
+                          char *buf)
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
 
        return sprintf(buf, "%u\n", !!cpu_online(cpu->sysdev.id));
 }
 
-static ssize_t __ref store_online(struct sys_device *dev, const char *buf,
-                           size_t count)
+static ssize_t __ref store_online(struct sys_device *dev, struct sysdev_attribute *attr,
+                                const char *buf, size_t count)
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
        ssize_t ret;
@@ -80,7 +81,8 @@ static inline void register_cpu_control(struct cpu *cpu)
 #ifdef CONFIG_KEXEC
 #include <linux/kexec.h>
 
-static ssize_t show_crash_notes(struct sys_device *dev, char *buf)
+static ssize_t show_crash_notes(struct sys_device *dev, struct sysdev_attribute *attr,
+                               char *buf)
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
        ssize_t rc;
index 937e8258981db78be0b81303d63a8e7ebc30d692..4d4e0e7b6e925e656c8346d63671f0179bca880e 100644 (file)
@@ -92,7 +92,8 @@ unregister_memory(struct memory_block *memory, struct mem_section *section)
  * uses.
  */
 
-static ssize_t show_mem_phys_index(struct sys_device *dev, char *buf)
+static ssize_t show_mem_phys_index(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct memory_block *mem =
                container_of(dev, struct memory_block, sysdev);
@@ -102,7 +103,8 @@ static ssize_t show_mem_phys_index(struct sys_device *dev, char *buf)
 /*
  * online, offline, going offline, etc.
  */
-static ssize_t show_mem_state(struct sys_device *dev, char *buf)
+static ssize_t show_mem_state(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct memory_block *mem =
                container_of(dev, struct memory_block, sysdev);
@@ -217,7 +219,8 @@ out:
 }
 
 static ssize_t
-store_mem_state(struct sys_device *dev, const char *buf, size_t count)
+store_mem_state(struct sys_device *dev,
+               struct sysdev_attribute *attr, const char *buf, size_t count)
 {
        struct memory_block *mem;
        unsigned int phys_section_nr;
@@ -248,7 +251,8 @@ out:
  * s.t. if I offline all of these sections I can then
  * remove the physical device?
  */
-static ssize_t show_phys_device(struct sys_device *dev, char *buf)
+static ssize_t show_phys_device(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct memory_block *mem =
                container_of(dev, struct memory_block, sysdev);
index 0f867a0833387fc7cfa5094450593c94f4905486..5116b78c632586884a19ab8b8329b798bc5cce14 100644 (file)
@@ -36,11 +36,13 @@ static ssize_t node_read_cpumap(struct sys_device *dev, int type, char *buf)
        return len;
 }
 
-static inline ssize_t node_read_cpumask(struct sys_device *dev, char *buf)
+static inline ssize_t node_read_cpumask(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        return node_read_cpumap(dev, 0, buf);
 }
-static inline ssize_t node_read_cpulist(struct sys_device *dev, char *buf)
+static inline ssize_t node_read_cpulist(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        return node_read_cpumap(dev, 1, buf);
 }
@@ -49,7 +51,8 @@ static SYSDEV_ATTR(cpumap,  S_IRUGO, node_read_cpumask, NULL);
 static SYSDEV_ATTR(cpulist, S_IRUGO, node_read_cpulist, NULL);
 
 #define K(x) ((x) << (PAGE_SHIFT - 10))
-static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
+static ssize_t node_read_meminfo(struct sys_device * dev,
+                       struct sysdev_attribute *attr, char * buf)
 {
        int n;
        int nid = dev->id;
@@ -112,7 +115,8 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
 #undef K
 static SYSDEV_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL);
 
-static ssize_t node_read_numastat(struct sys_device * dev, char * buf)
+static ssize_t node_read_numastat(struct sys_device * dev,
+                               struct sysdev_attribute *attr, char * buf)
 {
        return sprintf(buf,
                       "numa_hit %lu\n"
@@ -130,7 +134,8 @@ static ssize_t node_read_numastat(struct sys_device * dev, char * buf)
 }
 static SYSDEV_ATTR(numastat, S_IRUGO, node_read_numastat, NULL);
 
-static ssize_t node_read_distance(struct sys_device * dev, char * buf)
+static ssize_t node_read_distance(struct sys_device * dev,
+                       struct sysdev_attribute *attr, char * buf)
 {
        int nid = dev->id;
        int len = 0;
index 9b1b20b59e0a7b2dcc61bad05f078813e65f92fe..2aa6e8fc4defff41ffaa63745baa3a54029ece80 100644 (file)
@@ -194,7 +194,7 @@ static int show_dev_hash(unsigned int value)
                struct device * dev = to_device(entry);
                unsigned int hash = hash_string(DEVSEED, dev->bus_id, DEVHASH);
                if (hash == value) {
-                       printk("  hash matches device %s\n", dev->bus_id);
+                       dev_info(dev, "hash matches\n");
                        match++;
                }
                entry = entry->prev;
index 358bb0be3c0838b9233bae7b1eab1cc2b05ef1e6..40fc14f035402ec70de718977e309932dce7b576 100644 (file)
@@ -36,7 +36,7 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
        struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
 
        if (sysdev_attr->show)
-               return sysdev_attr->show(sysdev, buffer);
+               return sysdev_attr->show(sysdev, sysdev_attr, buffer);
        return -EIO;
 }
 
@@ -49,7 +49,7 @@ sysdev_store(struct kobject * kobj, struct attribute * attr,
        struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
 
        if (sysdev_attr->store)
-               return sysdev_attr->store(sysdev, buffer, count);
+               return sysdev_attr->store(sysdev, sysdev_attr, buffer, count);
        return -EIO;
 }
 
@@ -130,8 +130,8 @@ static struct kset *system_kset;
 
 int sysdev_class_register(struct sysdev_class * cls)
 {
-       pr_debug("Registering sysdev class '%s'\n",
-                kobject_name(&cls->kset.kobj));
+       pr_debug("Registering sysdev class '%s'\n", cls->name);
+
        INIT_LIST_HEAD(&cls->drivers);
        memset(&cls->kset.kobj, 0x00, sizeof(struct kobject));
        cls->kset.kobj.parent = &system_kset->kobj;
@@ -241,7 +241,8 @@ int sysdev_register(struct sys_device * sysdev)
        if (!cls)
                return -EINVAL;
 
-       pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj));
+       pr_debug("Registering sys device of class '%s'\n",
+                kobject_name(&cls->kset.kobj));
 
        /* initialize the kobject to 0, in case it had previously been used */
        memset(&sysdev->kobj, 0x00, sizeof(struct kobject));
@@ -257,6 +258,9 @@ int sysdev_register(struct sys_device * sysdev)
        if (!error) {
                struct sysdev_driver * drv;
 
+               pr_debug("Registering sys device '%s'\n",
+                        kobject_name(&sysdev->kobj));
+
                mutex_lock(&sysdev_drivers_lock);
                /* Generic notification is implicit, because it's that
                 * code that should have called us.
@@ -269,6 +273,7 @@ int sysdev_register(struct sys_device * sysdev)
                }
                mutex_unlock(&sysdev_drivers_lock);
        }
+
        kobject_uevent(&sysdev->kobj, KOBJ_ADD);
        return error;
 }
@@ -474,3 +479,52 @@ int __init system_bus_init(void)
 
 EXPORT_SYMBOL_GPL(sysdev_register);
 EXPORT_SYMBOL_GPL(sysdev_unregister);
+
+#define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr)
+
+ssize_t sysdev_store_ulong(struct sys_device *sysdev,
+                          struct sysdev_attribute *attr,
+                          const char *buf, size_t size)
+{
+       struct sysdev_ext_attribute *ea = to_ext_attr(attr);
+       char *end;
+       unsigned long new = simple_strtoul(buf, &end, 0);
+       if (end == buf)
+               return -EINVAL;
+       *(unsigned long *)(ea->var) = new;
+       return end - buf;
+}
+EXPORT_SYMBOL_GPL(sysdev_store_ulong);
+
+ssize_t sysdev_show_ulong(struct sys_device *sysdev,
+                         struct sysdev_attribute *attr,
+                         char *buf)
+{
+       struct sysdev_ext_attribute *ea = to_ext_attr(attr);
+       return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var));
+}
+EXPORT_SYMBOL_GPL(sysdev_show_ulong);
+
+ssize_t sysdev_store_int(struct sys_device *sysdev,
+                          struct sysdev_attribute *attr,
+                          const char *buf, size_t size)
+{
+       struct sysdev_ext_attribute *ea = to_ext_attr(attr);
+       char *end;
+       long new = simple_strtol(buf, &end, 0);
+       if (end == buf || new > INT_MAX || new < INT_MIN)
+               return -EINVAL;
+       *(int *)(ea->var) = new;
+       return end - buf;
+}
+EXPORT_SYMBOL_GPL(sysdev_store_int);
+
+ssize_t sysdev_show_int(struct sys_device *sysdev,
+                         struct sysdev_attribute *attr,
+                         char *buf)
+{
+       struct sysdev_ext_attribute *ea = to_ext_attr(attr);
+       return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var));
+}
+EXPORT_SYMBOL_GPL(sysdev_show_int);
+
index 3f6d9b0a6abed354ca07527e0294c8042dcc8ae0..199cd97e32e64b2c56338b2d74eb68ab5ce01de3 100644 (file)
@@ -34,7 +34,8 @@
 static SYSDEV_ATTR(_name, 0444, show_##_name, NULL)
 
 #define define_id_show_func(name)                              \
-static ssize_t show_##name(struct sys_device *dev, char *buf)  \
+static ssize_t show_##name(struct sys_device *dev,             \
+               struct sysdev_attribute *attr, char *buf)       \
 {                                                              \
        unsigned int cpu = dev->id;                             \
        return sprintf(buf, "%d\n", topology_##name(cpu));      \
@@ -59,14 +60,17 @@ static ssize_t show_cpumap(int type, cpumask_t *mask, char *buf)
 
 #ifdef arch_provides_topology_pointers
 #define define_siblings_show_map(name)                                 \
-static ssize_t show_##name(struct sys_device *dev, char *buf)  \
+static ssize_t show_##name(struct sys_device *dev,                     \
+                          struct sysdev_attribute *attr, char *buf)    \
 {                                                                      \
        unsigned int cpu = dev->id;                                     \
        return show_cpumap(0, &(topology_##name(cpu)), buf);            \
 }
 
 #define define_siblings_show_list(name)                                        \
-static ssize_t show_##name##_list(struct sys_device *dev, char *buf) \
+static ssize_t show_##name##_list(struct sys_device *dev,              \
+                                 struct sysdev_attribute *attr,        \
+                                 char *buf)                            \
 {                                                                      \
        unsigned int cpu = dev->id;                                     \
        return show_cpumap(1, &(topology_##name(cpu)), buf);            \
@@ -74,7 +78,8 @@ static ssize_t show_##name##_list(struct sys_device *dev, char *buf) \
 
 #else
 #define define_siblings_show_map(name)                                 \
-static ssize_t show_##name(struct sys_device *dev, char *buf)  \
+static ssize_t show_##name(struct sys_device *dev,                     \
+                          struct sysdev_attribute *attr, char *buf)    \
 {                                                                      \
        unsigned int cpu = dev->id;                                     \
        cpumask_t mask = topology_##name(cpu);                          \
@@ -82,7 +87,9 @@ static ssize_t show_##name(struct sys_device *dev, char *buf) \
 }
 
 #define define_siblings_show_list(name)                                        \
-static ssize_t show_##name##_list(struct sys_device *dev, char *buf) \
+static ssize_t show_##name##_list(struct sys_device *dev,              \
+                                 struct sysdev_attribute *attr,        \
+                                 char *buf)                            \
 {                                                                      \
        unsigned int cpu = dev->id;                                     \
        cpumask_t mask = topology_##name(cpu);                          \
index d1de68a3192088b11f20317d5405d05c35cd5071..c04440cd6a32d5bc5031aed5ec4fe50c4d50dd67 100644 (file)
@@ -277,8 +277,9 @@ aoechr_init(void)
                return PTR_ERR(aoe_class);
        }
        for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
-               device_create(aoe_class, NULL,
-                             MKDEV(AOE_MAJOR, chardevs[i].minor), chardevs[i].name);
+               device_create_drvdata(aoe_class, NULL,
+                                     MKDEV(AOE_MAJOR, chardevs[i].minor),
+                                     NULL, chardevs[i].name);
 
        return 0;
 }
index 9d92636350e5f67f1d2ebd7b60466859b4e301f9..d731ca42f8024f48a12214b064ed5ff3d13b8543 100644 (file)
@@ -686,8 +686,9 @@ static int __init pg_init(void)
        for (unit = 0; unit < PG_UNITS; unit++) {
                struct pg *dev = &devices[unit];
                if (dev->present)
-                       device_create(pg_class, NULL, MKDEV(major, unit),
-                                     "pg%u", unit);
+                       device_create_drvdata(pg_class, NULL,
+                                             MKDEV(major, unit), NULL,
+                                             "pg%u", unit);
        }
        err = 0;
        goto out;
index 5c74c3574a5adf77bb9120d77e9f45442cb3debe..673b8b2fd337a1e22b442eba939aa4c90a407b86 100644 (file)
@@ -979,10 +979,12 @@ static int __init pt_init(void)
 
        for (unit = 0; unit < PT_UNITS; unit++)
                if (pt[unit].present) {
-                       device_create(pt_class, NULL, MKDEV(major, unit),
-                                     "pt%d", unit);
-                       device_create(pt_class, NULL, MKDEV(major, unit + 128),
-                                     "pt%dn", unit);
+                       device_create_drvdata(pt_class, NULL,
+                                             MKDEV(major, unit), NULL,
+                                             "pt%d", unit);
+                       device_create_drvdata(pt_class, NULL,
+                                             MKDEV(major, unit + 128), NULL,
+                                             "pt%dn", unit);
                }
        goto out;
 
index 45bee918c46a821e5a5c4ec3c2a74ad96b8d8e72..158eed4d516188deb82b50b9f60ddbbd502b8302 100644 (file)
@@ -303,7 +303,9 @@ static struct kobj_type kobj_pkt_type_wqueue = {
 static void pkt_sysfs_dev_new(struct pktcdvd_device *pd)
 {
        if (class_pktcdvd) {
-               pd->dev = device_create(class_pktcdvd, NULL, pd->pkt_dev, "%s", pd->name);
+               pd->dev = device_create_drvdata(class_pktcdvd, NULL,
+                                               pd->pkt_dev, NULL,
+                                               "%s", pd->name);
                if (IS_ERR(pd->dev))
                        pd->dev = NULL;
        }
index 650e6b44ce65942471a98bfcbdae8759fe1ffcbc..e0bbbfb6a36bd2b98092a641ef1b496f3a6b9e07 100644 (file)
@@ -300,16 +300,6 @@ config SPECIALIX
          and compile this driver as kernel loadable module which will be
          called specialix.
 
-config SPECIALIX_RTSCTS
-       bool "Specialix DTR/RTS pin is RTS"
-       depends on SPECIALIX
-       help
-         The Specialix IO8+ card can only support either RTS or DTR. If you
-         say N here, the driver will use the pin as "DTR" when the tty is in
-         software handshake mode.  If you say Y here or hardware handshake is
-         on, it will always be RTS.  Read the file
-         <file:Documentation/specialix.txt> for more information.
-
 config SX
        tristate "Specialix SX (and SI) card support"
        depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA)
index 0e0d12a064622c3d3167e2db6cff59336dbe20d5..dc5a327d72d5782ade03eece6a5f128ada9d2329 100644 (file)
@@ -7,7 +7,7 @@
 #
 FONTMAPFILE = cp437.uni
 
-obj-y   += mem.o random.o tty_io.o n_tty.o tty_ioctl.o
+obj-y   += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o 
 
 obj-$(CONFIG_LEGACY_PTYS)      += pty.o
 obj-$(CONFIG_UNIX98_PTYS)      += pty.o
index 37457e5a4f2b8ce6d06f728788dbeee2a54e3fee..3530ff417a5165ef9b484d74295a3211373ed8d0 100644 (file)
@@ -1248,7 +1248,7 @@ static int rs_tiocmset(struct tty_struct *tty, struct file *file,
 /*
  * rs_break() --- routine which turns the break handling on or off
  */
-static void rs_break(struct tty_struct *tty, int break_state)
+static int rs_break(struct tty_struct *tty, int break_state)
 {
        struct async_struct * info = (struct async_struct *)tty->driver_data;
        unsigned long flags;
@@ -1263,6 +1263,7 @@ static void rs_break(struct tty_struct *tty, int break_state)
          custom.adkcon = AC_UARTBRK;
        mb();
        local_irq_restore(flags);
+       return 0;
 }
 
 
index e991dc85f2fbb9abebc466efaec00d24d9b11d98..fe6d774fe2e4cbaf6ae0994cab07fccab158acd9 100644 (file)
@@ -3700,14 +3700,15 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
 /*
  * cy_break() --- routine which turns the break handling on or off
  */
-static void cy_break(struct tty_struct *tty, int break_state)
+static int cy_break(struct tty_struct *tty, int break_state)
 {
        struct cyclades_port *info = tty->driver_data;
        struct cyclades_card *card;
        unsigned long flags;
+       int retval = 0;
 
        if (serial_paranoia_check(info, tty->name, "cy_break"))
-               return;
+               return -EINVAL;
 
        card = info->card;
 
@@ -3736,8 +3737,6 @@ static void cy_break(struct tty_struct *tty, int break_state)
                        }
                }
        } else {
-               int retval;
-
                if (break_state == -1) {
                        retval = cyz_issue_cmd(card,
                                info->line - card->first_line,
@@ -3758,6 +3757,7 @@ static void cy_break(struct tty_struct *tty, int break_state)
                }
        }
        spin_unlock_irqrestore(&card->card_lock, flags);
+       return retval;
 }                              /* cy_break */
 
 static int get_mon_info(struct cyclades_port *info,
index b9a30c30e2b8682a85822c764b8b05f3bd3bdb79..33c466a4888f092c15475601b503a473808a20fc 100644 (file)
@@ -500,7 +500,8 @@ static int __init dsp56k_init_driver(void)
                err = PTR_ERR(dsp56k_class);
                goto out_chrdev;
        }
-       device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), "dsp56k");
+       device_create_drvdata(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0),
+                             NULL, "dsp56k");
 
        printk(banner);
        goto out;
index ac9995f6578bc1694bf366e12723ae9fd44130ef..456e4ede049f2a0dad2bd0452199461272f1c353 100644 (file)
@@ -184,9 +184,8 @@ static void pc_stop(struct tty_struct *);
 static void pc_start(struct tty_struct *);
 static void pc_throttle(struct tty_struct *tty);
 static void pc_unthrottle(struct tty_struct *tty);
-static void digi_send_break(struct channel *ch, int msec);
+static int pc_send_break(struct tty_struct *tty, int msec);
 static void setup_empty_event(struct tty_struct *tty, struct channel *ch);
-static void epca_setup(char *, int *);
 
 static int pc_write(struct tty_struct *, const unsigned char *, int);
 static int pc_init(void);
@@ -1040,6 +1039,7 @@ static const struct tty_operations pc_ops = {
        .throttle = pc_throttle,
        .unthrottle = pc_unthrottle,
        .hangup = pc_hangup,
+       .break_ctl = pc_send_break
 };
 
 static int info_open(struct tty_struct *tty, struct file *filp)
@@ -1132,7 +1132,7 @@ static int __init pc_init(void)
        pc_driver->init_termios.c_lflag = 0;
        pc_driver->init_termios.c_ispeed = 9600;
        pc_driver->init_termios.c_ospeed = 9600;
-       pc_driver->flags = TTY_DRIVER_REAL_RAW;
+       pc_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK;
        tty_set_operations(pc_driver, &pc_ops);
 
        pc_info->owner = THIS_MODULE;
@@ -2177,7 +2177,6 @@ static int pc_ioctl(struct tty_struct *tty, struct file *file,
                                        unsigned int cmd, unsigned long arg)
 {
        digiflow_t dflow;
-       int retval;
        unsigned long flags;
        unsigned int mflag, mstat;
        unsigned char startc, stopc;
@@ -2189,37 +2188,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file *file,
                bc = ch->brdchan;
        else
                return -EINVAL;
-       /*
-        * For POSIX compliance we need to add more ioctls. See tty_ioctl.c in
-        * /usr/src/linux/drivers/char for a good example. In particular think
-        * about adding TCSETAF, TCSETAW, TCSETA, TCSETSF, TCSETSW, TCSETS.
-        */
        switch (cmd) {
-       case TCSBRK:    /* SVID version: non-zero arg --> no break */
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-               /* Setup an event to indicate when the transmit
-                  buffer empties */
-               spin_lock_irqsave(&epca_lock, flags);
-               setup_empty_event(tty, ch);
-               spin_unlock_irqrestore(&epca_lock, flags);
-               tty_wait_until_sent(tty, 0);
-               if (!arg)
-                       digi_send_break(ch, HZ / 4);    /* 1/4 second */
-               return 0;
-       case TCSBRKP:   /* support for POSIX tcsendbreak() */
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-               /* Setup an event to indicate when the transmit buffer
-                  empties */
-               spin_lock_irqsave(&epca_lock, flags);
-               setup_empty_event(tty, ch);
-               spin_unlock_irqrestore(&epca_lock, flags);
-               tty_wait_until_sent(tty, 0);
-               digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4);
-               return 0;
        case TIOCMODG:
                mflag = pc_tiocmget(tty, file);
                if (put_user(mflag, (unsigned long __user *)argp))
@@ -2505,10 +2474,14 @@ static void pc_unthrottle(struct tty_struct *tty)
        }
 }
 
-static void digi_send_break(struct channel *ch, int msec)
+static int pc_send_break(struct tty_struct *tty, int msec)
 {
+       struct channel *ch = (struct channel *) tty->driver_data;
        unsigned long flags;
 
+       if (msec == -1)
+               return -EOPNOTSUPP;
+
        spin_lock_irqsave(&epca_lock, flags);
        globalwinon(ch);
        /*
@@ -2521,6 +2494,7 @@ static void digi_send_break(struct channel *ch, int msec)
        fepcmd(ch, SENDBREAK, msec, 0, 10, 0);
        memoff(ch);
        spin_unlock_irqrestore(&epca_lock, flags);
+       return 0;
 }
 
 /* Caller MUST hold the lock */
@@ -2538,7 +2512,8 @@ static void setup_empty_event(struct tty_struct *tty, struct channel *ch)
        memoff(ch);
 }
 
-static void epca_setup(char *str, int *ints)
+#ifndef MODULE
+static void __init epca_setup(char *str, int *ints)
 {
        struct board_info board;
        int               index, loop, last;
@@ -2792,6 +2767,17 @@ static void epca_setup(char *str, int *ints)
        num_cards++;
 }
 
+static int __init epca_real_setup(char *str)
+{
+       int ints[11];
+
+       epca_setup(get_options(str, 11, ints), ints);
+       return 1;
+}
+
+__setup("digiepca", epca_real_setup);
+#endif
+
 enum epic_board_types {
        brd_xr = 0,
        brd_xem,
index 2eaf09f93e3d94b73852f57b19f49636788f364e..7f077c0097f663b5e432d01fb2a40f93c743ad30 100644 (file)
@@ -1725,13 +1725,13 @@ static int esp_tiocmset(struct tty_struct *tty, struct file *file,
 /*
  * rs_break() --- routine which turns the break handling on or off
  */
-static void esp_break(struct tty_struct *tty, int break_state)
+static int esp_break(struct tty_struct *tty, int break_state)
 {
        struct esp_struct *info = tty->driver_data;
        unsigned long flags;
 
        if (serial_paranoia_check(info, tty->name, "esp_break"))
-               return;
+               return -EINVAL;
 
        if (break_state == -1) {
                spin_lock_irqsave(&info->lock, flags);
@@ -1747,6 +1747,7 @@ static void esp_break(struct tty_struct *tty, int break_state)
                serial_out(info, UART_ESI_CMD2, 0x00);
                spin_unlock_irqrestore(&info->lock, flags);
        }
+       return 0;
 }
 
 static int rs_ioctl(struct tty_struct *tty, struct file *file,
index efd0b4db7c8ed6c5d6c6bbc5a473466f898fdf1d..8822eca58ffaca1b573f96a11c2f3949b61b93e1 100644 (file)
@@ -59,6 +59,19 @@ config HW_RANDOM_GEODE
 
          If unsure, say Y.
 
+config HW_RANDOM_N2RNG
+       tristate "Niagara2 Random Number Generator support"
+       depends on HW_RANDOM && SPARC64
+       default HW_RANDOM
+       ---help---
+         This driver provides kernel-side support for the Random Number
+         Generator hardware found on Niagara2 cpus.
+
+         To compile this driver as a module, choose M here: the
+         module will be called n2-rng.
+
+         If unsure, say Y.
+
 config HW_RANDOM_VIA
        tristate "VIA HW Random Number Generator support"
        depends on HW_RANDOM && X86_32
index b4940ddbb35f5993c80c164dbea1a2046915d1dd..b6effb7522c2997570d811414cc121b53779c0a9 100644 (file)
@@ -7,6 +7,8 @@ rng-core-y := core.o
 obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
 obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
 obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
+obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o
+n2-rng-y := n2-drv.o n2-asm.o
 obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o
 obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
 obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
diff --git a/drivers/char/hw_random/n2-asm.S b/drivers/char/hw_random/n2-asm.S
new file mode 100644 (file)
index 0000000..9b6eb5c
--- /dev/null
@@ -0,0 +1,79 @@
+/* n2-asm.S: Niagara2 RNG hypervisor call assembler.
+ *
+ * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
+ */
+#include <linux/linkage.h>
+#include <asm/hypervisor.h>
+#include "n2rng.h"
+
+       .text
+
+ENTRY(sun4v_rng_get_diag_ctl)
+       mov     HV_FAST_RNG_GET_DIAG_CTL, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+ENDPROC(sun4v_rng_get_diag_ctl)
+
+ENTRY(sun4v_rng_ctl_read_v1)
+       mov     %o1, %o3
+       mov     %o2, %o4
+       mov     HV_FAST_RNG_CTL_READ, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%o3]
+       retl
+        stx    %o2, [%o4]
+ENDPROC(sun4v_rng_ctl_read_v1)
+
+ENTRY(sun4v_rng_ctl_read_v2)
+       save    %sp, -192, %sp
+       mov     %i0, %o0
+       mov     %i1, %o1
+       mov     HV_FAST_RNG_CTL_READ, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%i2]
+       stx     %o2, [%i3]
+       stx     %o3, [%i4]
+       stx     %o4, [%i5]
+       ret
+       restore %g0, %o0, %o0
+ENDPROC(sun4v_rng_ctl_read_v2)
+
+ENTRY(sun4v_rng_ctl_write_v1)
+       mov     %o3, %o4
+       mov     HV_FAST_RNG_CTL_WRITE, %o5
+       ta      HV_FAST_TRAP
+       retl
+        stx    %o1, [%o4]
+ENDPROC(sun4v_rng_ctl_write_v1)
+
+ENTRY(sun4v_rng_ctl_write_v2)
+       mov     HV_FAST_RNG_CTL_WRITE, %o5
+       ta      HV_FAST_TRAP
+       retl
+        nop
+ENDPROC(sun4v_rng_ctl_write_v2)
+
+ENTRY(sun4v_rng_data_read_diag_v1)
+       mov     %o2, %o4
+       mov     HV_FAST_RNG_DATA_READ_DIAG, %o5
+       ta      HV_FAST_TRAP
+       retl
+        stx    %o1, [%o4]
+ENDPROC(sun4v_rng_data_read_diag_v1)
+
+ENTRY(sun4v_rng_data_read_diag_v2)
+       mov     %o3, %o4
+       mov     HV_FAST_RNG_DATA_READ_DIAG, %o5
+       ta      HV_FAST_TRAP
+       retl
+        stx    %o1, [%o4]
+ENDPROC(sun4v_rng_data_read_diag_v2)
+
+ENTRY(sun4v_rng_data_read)
+       mov     %o1, %o4
+       mov     HV_FAST_RNG_DATA_READ, %o5
+       ta      HV_FAST_TRAP
+       retl
+        stx    %o1, [%o4]
+ENDPROC(sun4v_rng_data_read)
diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c
new file mode 100644 (file)
index 0000000..5220f54
--- /dev/null
@@ -0,0 +1,771 @@
+/* n2-drv.c: Niagara-2 RNG driver.
+ *
+ * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/preempt.h>
+#include <linux/hw_random.h>
+
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#include <asm/hypervisor.h>
+
+#include "n2rng.h"
+
+#define DRV_MODULE_NAME                "n2rng"
+#define PFX DRV_MODULE_NAME    ": "
+#define DRV_MODULE_VERSION     "0.1"
+#define DRV_MODULE_RELDATE     "May 15, 2008"
+
+static char version[] __devinitdata =
+       DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+
+MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
+MODULE_DESCRIPTION("Niagara2 RNG driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_MODULE_VERSION);
+
+/* The Niagara2 RNG provides a 64-bit read-only random number
+ * register, plus a control register.  Access to the RNG is
+ * virtualized through the hypervisor so that both guests and control
+ * nodes can access the device.
+ *
+ * The entropy source consists of raw entropy sources, each
+ * constructed from a voltage controlled oscillator whose phase is
+ * jittered by thermal noise sources.
+ *
+ * The oscillator in each of the three raw entropy sources run at
+ * different frequencies.  Normally, all three generator outputs are
+ * gathered, xored together, and fed into a CRC circuit, the output of
+ * which is the 64-bit read-only register.
+ *
+ * Some time is necessary for all the necessary entropy to build up
+ * such that a full 64-bits of entropy are available in the register.
+ * In normal operating mode (RNG_CTL_LFSR is set), the chip implements
+ * an interlock which blocks register reads until sufficient entropy
+ * is available.
+ *
+ * A control register is provided for adjusting various aspects of RNG
+ * operation, and to enable diagnostic modes.  Each of the three raw
+ * entropy sources has an enable bit (RNG_CTL_ES{1,2,3}).  Also
+ * provided are fields for controlling the minimum time in cycles
+ * between read accesses to the register (RNG_CTL_WAIT, this controls
+ * the interlock described in the previous paragraph).
+ *
+ * The standard setting is to have the mode bit (RNG_CTL_LFSR) set,
+ * all three entropy sources enabled, and the interlock time set
+ * appropriately.
+ *
+ * The CRC polynomial used by the chip is:
+ *
+ * P(X) = x64 + x61 + x57 + x56 + x52 + x51 + x50 + x48 + x47 + x46 +
+ *        x43 + x42 + x41 + x39 + x38 + x37 + x35 + x32 + x28 + x25 +
+ *        x22 + x21 + x17 + x15 + x13 + x12 + x11 + x7 + x5 + x + 1
+ *
+ * The RNG_CTL_VCO value of each noise cell must be programmed
+ * seperately.  This is why 4 control register values must be provided
+ * to the hypervisor.  During a write, the hypervisor writes them all,
+ * one at a time, to the actual RNG_CTL register.  The first three
+ * values are used to setup the desired RNG_CTL_VCO for each entropy
+ * source, for example:
+ *
+ *     control 0: (1 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES1
+ *     control 1: (2 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES2
+ *     control 2: (3 << RNG_CTL_VCO_SHIFT) | RNG_CTL_ES3
+ *
+ * And then the fourth value sets the final chip state and enables
+ * desired.
+ */
+
+static int n2rng_hv_err_trans(unsigned long hv_err)
+{
+       switch (hv_err) {
+       case HV_EOK:
+               return 0;
+       case HV_EWOULDBLOCK:
+               return -EAGAIN;
+       case HV_ENOACCESS:
+               return -EPERM;
+       case HV_EIO:
+               return -EIO;
+       case HV_EBUSY:
+               return -EBUSY;
+       case HV_EBADALIGN:
+       case HV_ENORADDR:
+               return -EFAULT;
+       default:
+               return -EINVAL;
+       }
+}
+
+static unsigned long n2rng_generic_read_control_v2(unsigned long ra,
+                                                  unsigned long unit)
+{
+       unsigned long hv_err, state, ticks, watchdog_delta, watchdog_status;
+       int block = 0, busy = 0;
+
+       while (1) {
+               hv_err = sun4v_rng_ctl_read_v2(ra, unit, &state,
+                                              &ticks,
+                                              &watchdog_delta,
+                                              &watchdog_status);
+               if (hv_err == HV_EOK)
+                       break;
+
+               if (hv_err == HV_EBUSY) {
+                       if (++busy >= N2RNG_BUSY_LIMIT)
+                               break;
+
+                       udelay(1);
+               } else if (hv_err == HV_EWOULDBLOCK) {
+                       if (++block >= N2RNG_BLOCK_LIMIT)
+                               break;
+
+                       __delay(ticks);
+               } else
+                       break;
+       }
+
+       return hv_err;
+}
+
+/* In multi-socket situations, the hypervisor might need to
+ * queue up the RNG control register write if it's for a unit
+ * that is on a cpu socket other than the one we are executing on.
+ *
+ * We poll here waiting for a successful read of that control
+ * register to make sure the write has been actually performed.
+ */
+static unsigned long n2rng_control_settle_v2(struct n2rng *np, int unit)
+{
+       unsigned long ra = __pa(&np->scratch_control[0]);
+
+       return n2rng_generic_read_control_v2(ra, unit);
+}
+
+static unsigned long n2rng_write_ctl_one(struct n2rng *np, int unit,
+                                        unsigned long state,
+                                        unsigned long control_ra,
+                                        unsigned long watchdog_timeout,
+                                        unsigned long *ticks)
+{
+       unsigned long hv_err;
+
+       if (np->hvapi_major == 1) {
+               hv_err = sun4v_rng_ctl_write_v1(control_ra, state,
+                                               watchdog_timeout, ticks);
+       } else {
+               hv_err = sun4v_rng_ctl_write_v2(control_ra, state,
+                                               watchdog_timeout, unit);
+               if (hv_err == HV_EOK)
+                       hv_err = n2rng_control_settle_v2(np, unit);
+               *ticks = N2RNG_ACCUM_CYCLES_DEFAULT;
+       }
+
+       return hv_err;
+}
+
+static int n2rng_generic_read_data(unsigned long data_ra)
+{
+       unsigned long ticks, hv_err;
+       int block = 0, hcheck = 0;
+
+       while (1) {
+               hv_err = sun4v_rng_data_read(data_ra, &ticks);
+               if (hv_err == HV_EOK)
+                       return 0;
+
+               if (hv_err == HV_EWOULDBLOCK) {
+                       if (++block >= N2RNG_BLOCK_LIMIT)
+                               return -EWOULDBLOCK;
+                       __delay(ticks);
+               } else if (hv_err == HV_ENOACCESS) {
+                       return -EPERM;
+               } else if (hv_err == HV_EIO) {
+                       if (++hcheck >= N2RNG_HCHECK_LIMIT)
+                               return -EIO;
+                       udelay(10000);
+               } else
+                       return -ENODEV;
+       }
+}
+
+static unsigned long n2rng_read_diag_data_one(struct n2rng *np,
+                                             unsigned long unit,
+                                             unsigned long data_ra,
+                                             unsigned long data_len,
+                                             unsigned long *ticks)
+{
+       unsigned long hv_err;
+
+       if (np->hvapi_major == 1) {
+               hv_err = sun4v_rng_data_read_diag_v1(data_ra, data_len, ticks);
+       } else {
+               hv_err = sun4v_rng_data_read_diag_v2(data_ra, data_len,
+                                                    unit, ticks);
+               if (!*ticks)
+                       *ticks = N2RNG_ACCUM_CYCLES_DEFAULT;
+       }
+       return hv_err;
+}
+
+static int n2rng_generic_read_diag_data(struct n2rng *np,
+                                       unsigned long unit,
+                                       unsigned long data_ra,
+                                       unsigned long data_len)
+{
+       unsigned long ticks, hv_err;
+       int block = 0;
+
+       while (1) {
+               hv_err = n2rng_read_diag_data_one(np, unit,
+                                                 data_ra, data_len,
+                                                 &ticks);
+               if (hv_err == HV_EOK)
+                       return 0;
+
+               if (hv_err == HV_EWOULDBLOCK) {
+                       if (++block >= N2RNG_BLOCK_LIMIT)
+                               return -EWOULDBLOCK;
+                       __delay(ticks);
+               } else if (hv_err == HV_ENOACCESS) {
+                       return -EPERM;
+               } else if (hv_err == HV_EIO) {
+                       return -EIO;
+               } else
+                       return -ENODEV;
+       }
+}
+
+
+static int n2rng_generic_write_control(struct n2rng *np,
+                                      unsigned long control_ra,
+                                      unsigned long unit,
+                                      unsigned long state)
+{
+       unsigned long hv_err, ticks;
+       int block = 0, busy = 0;
+
+       while (1) {
+               hv_err = n2rng_write_ctl_one(np, unit, state, control_ra,
+                                            np->wd_timeo, &ticks);
+               if (hv_err == HV_EOK)
+                       return 0;
+
+               if (hv_err == HV_EWOULDBLOCK) {
+                       if (++block >= N2RNG_BLOCK_LIMIT)
+                               return -EWOULDBLOCK;
+                       __delay(ticks);
+               } else if (hv_err == HV_EBUSY) {
+                       if (++busy >= N2RNG_BUSY_LIMIT)
+                               return -EBUSY;
+                       udelay(1);
+               } else
+                       return -ENODEV;
+       }
+}
+
+/* Just try to see if we can successfully access the control register
+ * of the RNG on the domain on which we are currently executing.
+ */
+static int n2rng_try_read_ctl(struct n2rng *np)
+{
+       unsigned long hv_err;
+       unsigned long x;
+
+       if (np->hvapi_major == 1) {
+               hv_err = sun4v_rng_get_diag_ctl();
+       } else {
+               /* We purposefully give invalid arguments, HV_NOACCESS
+                * is higher priority than the errors we'd get from
+                * these other cases, and that's the error we are
+                * truly interested in.
+                */
+               hv_err = sun4v_rng_ctl_read_v2(0UL, ~0UL, &x, &x, &x, &x);
+               switch (hv_err) {
+               case HV_EWOULDBLOCK:
+               case HV_ENOACCESS:
+                       break;
+               default:
+                       hv_err = HV_EOK;
+                       break;
+               }
+       }
+
+       return n2rng_hv_err_trans(hv_err);
+}
+
+#define CONTROL_DEFAULT_BASE           \
+       ((2 << RNG_CTL_ASEL_SHIFT) |    \
+        (N2RNG_ACCUM_CYCLES_DEFAULT << RNG_CTL_WAIT_SHIFT) |   \
+        RNG_CTL_LFSR)
+
+#define CONTROL_DEFAULT_0              \
+       (CONTROL_DEFAULT_BASE |         \
+        (1 << RNG_CTL_VCO_SHIFT) |     \
+        RNG_CTL_ES1)
+#define CONTROL_DEFAULT_1              \
+       (CONTROL_DEFAULT_BASE |         \
+        (2 << RNG_CTL_VCO_SHIFT) |     \
+        RNG_CTL_ES2)
+#define CONTROL_DEFAULT_2              \
+       (CONTROL_DEFAULT_BASE |         \
+        (3 << RNG_CTL_VCO_SHIFT) |     \
+        RNG_CTL_ES3)
+#define CONTROL_DEFAULT_3              \
+       (CONTROL_DEFAULT_BASE |         \
+        RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3)
+
+static void n2rng_control_swstate_init(struct n2rng *np)
+{
+       int i;
+
+       np->flags |= N2RNG_FLAG_CONTROL;
+
+       np->health_check_sec = N2RNG_HEALTH_CHECK_SEC_DEFAULT;
+       np->accum_cycles = N2RNG_ACCUM_CYCLES_DEFAULT;
+       np->wd_timeo = N2RNG_WD_TIMEO_DEFAULT;
+
+       for (i = 0; i < np->num_units; i++) {
+               struct n2rng_unit *up = &np->units[i];
+
+               up->control[0] = CONTROL_DEFAULT_0;
+               up->control[1] = CONTROL_DEFAULT_1;
+               up->control[2] = CONTROL_DEFAULT_2;
+               up->control[3] = CONTROL_DEFAULT_3;
+       }
+
+       np->hv_state = HV_RNG_STATE_UNCONFIGURED;
+}
+
+static int n2rng_grab_diag_control(struct n2rng *np)
+{
+       int i, busy_count, err = -ENODEV;
+
+       busy_count = 0;
+       for (i = 0; i < 100; i++) {
+               err = n2rng_try_read_ctl(np);
+               if (err != -EAGAIN)
+                       break;
+
+               if (++busy_count > 100) {
+                       dev_err(&np->op->dev,
+                               "Grab diag control timeout.\n");
+                       return -ENODEV;
+               }
+
+               udelay(1);
+       }
+
+       return err;
+}
+
+static int n2rng_init_control(struct n2rng *np)
+{
+       int err = n2rng_grab_diag_control(np);
+
+       /* Not in the control domain, that's OK we are only a consumer
+        * of the RNG data, we don't setup and program it.
+        */
+       if (err == -EPERM)
+               return 0;
+       if (err)
+               return err;
+
+       n2rng_control_swstate_init(np);
+
+       return 0;
+}
+
+static int n2rng_data_read(struct hwrng *rng, u32 *data)
+{
+       struct n2rng *np = (struct n2rng *) rng->priv;
+       unsigned long ra = __pa(&np->test_data);
+       int len;
+
+       if (!(np->flags & N2RNG_FLAG_READY)) {
+               len = 0;
+       } else if (np->flags & N2RNG_FLAG_BUFFER_VALID) {
+               np->flags &= ~N2RNG_FLAG_BUFFER_VALID;
+               *data = np->buffer;
+               len = 4;
+       } else {
+               int err = n2rng_generic_read_data(ra);
+               if (!err) {
+                       np->buffer = np->test_data >> 32;
+                       *data = np->test_data & 0xffffffff;
+                       len = 4;
+               } else {
+                       dev_err(&np->op->dev, "RNG error, restesting\n");
+                       np->flags &= ~N2RNG_FLAG_READY;
+                       if (!(np->flags & N2RNG_FLAG_SHUTDOWN))
+                               schedule_delayed_work(&np->work, 0);
+                       len = 0;
+               }
+       }
+
+       return len;
+}
+
+/* On a guest node, just make sure we can read random data properly.
+ * If a control node reboots or reloads it's n2rng driver, this won't
+ * work during that time.  So we have to keep probing until the device
+ * becomes usable.
+ */
+static int n2rng_guest_check(struct n2rng *np)
+{
+       unsigned long ra = __pa(&np->test_data);
+
+       return n2rng_generic_read_data(ra);
+}
+
+static int n2rng_entropy_diag_read(struct n2rng *np, unsigned long unit,
+                                  u64 *pre_control, u64 pre_state,
+                                  u64 *buffer, unsigned long buf_len,
+                                  u64 *post_control, u64 post_state)
+{
+       unsigned long post_ctl_ra = __pa(post_control);
+       unsigned long pre_ctl_ra = __pa(pre_control);
+       unsigned long buffer_ra = __pa(buffer);
+       int err;
+
+       err = n2rng_generic_write_control(np, pre_ctl_ra, unit, pre_state);
+       if (err)
+               return err;
+
+       err = n2rng_generic_read_diag_data(np, unit,
+                                          buffer_ra, buf_len);
+
+       (void) n2rng_generic_write_control(np, post_ctl_ra, unit,
+                                          post_state);
+
+       return err;
+}
+
+static u64 advance_polynomial(u64 poly, u64 val, int count)
+{
+       int i;
+
+       for (i = 0; i < count; i++) {
+               int highbit_set = ((s64)val < 0);
+
+               val <<= 1;
+               if (highbit_set)
+                       val ^= poly;
+       }
+
+       return val;
+}
+
+static int n2rng_test_buffer_find(struct n2rng *np, u64 val)
+{
+       int i, count = 0;
+
+       /* Purposefully skip over the first word.  */
+       for (i = 1; i < SELFTEST_BUFFER_WORDS; i++) {
+               if (np->test_buffer[i] == val)
+                       count++;
+       }
+       return count;
+}
+
+static void n2rng_dump_test_buffer(struct n2rng *np)
+{
+       int i;
+
+       for (i = 0; i < SELFTEST_BUFFER_WORDS; i++)
+               dev_err(&np->op->dev, "Test buffer slot %d [0x%016lx]\n",
+                       i, np->test_buffer[i]);
+}
+
+static int n2rng_check_selftest_buffer(struct n2rng *np, unsigned long unit)
+{
+       u64 val = SELFTEST_VAL;
+       int err, matches, limit;
+
+       matches = 0;
+       for (limit = 0; limit < SELFTEST_LOOPS_MAX; limit++) {
+               matches += n2rng_test_buffer_find(np, val);
+               if (matches >= SELFTEST_MATCH_GOAL)
+                       break;
+               val = advance_polynomial(SELFTEST_POLY, val, 1);
+       }
+
+       err = 0;
+       if (limit >= SELFTEST_LOOPS_MAX) {
+               err = -ENODEV;
+               dev_err(&np->op->dev, "Selftest failed on unit %lu\n", unit);
+               n2rng_dump_test_buffer(np);
+       } else
+               dev_info(&np->op->dev, "Selftest passed on unit %lu\n", unit);
+
+       return err;
+}
+
+static int n2rng_control_selftest(struct n2rng *np, unsigned long unit)
+{
+       int err;
+
+       np->test_control[0] = (0x2 << RNG_CTL_ASEL_SHIFT);
+       np->test_control[1] = (0x2 << RNG_CTL_ASEL_SHIFT);
+       np->test_control[2] = (0x2 << RNG_CTL_ASEL_SHIFT);
+       np->test_control[3] = ((0x2 << RNG_CTL_ASEL_SHIFT) |
+                              RNG_CTL_LFSR |
+                              ((SELFTEST_TICKS - 2) << RNG_CTL_WAIT_SHIFT));
+
+
+       err = n2rng_entropy_diag_read(np, unit, np->test_control,
+                                     HV_RNG_STATE_HEALTHCHECK,
+                                     np->test_buffer,
+                                     sizeof(np->test_buffer),
+                                     &np->units[unit].control[0],
+                                     np->hv_state);
+       if (err)
+               return err;
+
+       return n2rng_check_selftest_buffer(np, unit);
+}
+
+static int n2rng_control_check(struct n2rng *np)
+{
+       int i;
+
+       for (i = 0; i < np->num_units; i++) {
+               int err = n2rng_control_selftest(np, i);
+               if (err)
+                       return err;
+       }
+       return 0;
+}
+
+/* The sanity checks passed, install the final configuration into the
+ * chip, it's ready to use.
+ */
+static int n2rng_control_configure_units(struct n2rng *np)
+{
+       int unit, err;
+
+       err = 0;
+       for (unit = 0; unit < np->num_units; unit++) {
+               struct n2rng_unit *up = &np->units[unit];
+               unsigned long ctl_ra = __pa(&up->control[0]);
+               int esrc;
+               u64 base;
+
+               base = ((np->accum_cycles << RNG_CTL_WAIT_SHIFT) |
+                       (2 << RNG_CTL_ASEL_SHIFT) |
+                       RNG_CTL_LFSR);
+
+               /* XXX This isn't the best.  We should fetch a bunch
+                * XXX of words using each entropy source combined XXX
+                * with each VCO setting, and see which combinations
+                * XXX give the best random data.
+                */
+               for (esrc = 0; esrc < 3; esrc++)
+                       up->control[esrc] = base |
+                               (esrc << RNG_CTL_VCO_SHIFT) |
+                               (RNG_CTL_ES1 << esrc);
+
+               up->control[3] = base |
+                       (RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3);
+
+               err = n2rng_generic_write_control(np, ctl_ra, unit,
+                                                 HV_RNG_STATE_CONFIGURED);
+               if (err)
+                       break;
+       }
+
+       return err;
+}
+
+static void n2rng_work(struct work_struct *work)
+{
+       struct n2rng *np = container_of(work, struct n2rng, work.work);
+       int err = 0;
+
+       if (!(np->flags & N2RNG_FLAG_CONTROL)) {
+               err = n2rng_guest_check(np);
+       } else {
+               preempt_disable();
+               err = n2rng_control_check(np);
+               preempt_enable();
+
+               if (!err)
+                       err = n2rng_control_configure_units(np);
+       }
+
+       if (!err) {
+               np->flags |= N2RNG_FLAG_READY;
+               dev_info(&np->op->dev, "RNG ready\n");
+       }
+
+       if (err && !(np->flags & N2RNG_FLAG_SHUTDOWN))
+               schedule_delayed_work(&np->work, HZ * 2);
+}
+
+static void __devinit n2rng_driver_version(void)
+{
+       static int n2rng_version_printed;
+
+       if (n2rng_version_printed++ == 0)
+               pr_info("%s", version);
+}
+
+static int __devinit n2rng_probe(struct of_device *op,
+                                const struct of_device_id *match)
+{
+       int victoria_falls = (match->data != NULL);
+       int err = -ENOMEM;
+       struct n2rng *np;
+
+       n2rng_driver_version();
+
+       np = kzalloc(sizeof(*np), GFP_KERNEL);
+       if (!np)
+               goto out;
+       np->op = op;
+
+       INIT_DELAYED_WORK(&np->work, n2rng_work);
+
+       if (victoria_falls)
+               np->flags |= N2RNG_FLAG_VF;
+
+       err = -ENODEV;
+       np->hvapi_major = 2;
+       if (sun4v_hvapi_register(HV_GRP_RNG,
+                                np->hvapi_major,
+                                &np->hvapi_minor)) {
+               np->hvapi_major = 1;
+               if (sun4v_hvapi_register(HV_GRP_RNG,
+                                        np->hvapi_major,
+                                        &np->hvapi_minor)) {
+                       dev_err(&op->dev, "Cannot register suitable "
+                               "HVAPI version.\n");
+                       goto out_free;
+               }
+       }
+
+       if (np->flags & N2RNG_FLAG_VF) {
+               if (np->hvapi_major < 2) {
+                       dev_err(&op->dev, "VF RNG requires HVAPI major "
+                               "version 2 or later, got %lu\n",
+                               np->hvapi_major);
+                       goto out_hvapi_unregister;
+               }
+               np->num_units = of_getintprop_default(op->node,
+                                                     "rng-#units", 0);
+               if (!np->num_units) {
+                       dev_err(&op->dev, "VF RNG lacks rng-#units property\n");
+                       goto out_hvapi_unregister;
+               }
+       } else
+               np->num_units = 1;
+
+       dev_info(&op->dev, "Registered RNG HVAPI major %lu minor %lu\n",
+                np->hvapi_major, np->hvapi_minor);
+
+       np->units = kzalloc(sizeof(struct n2rng_unit) * np->num_units,
+                           GFP_KERNEL);
+       err = -ENOMEM;
+       if (!np->units)
+               goto out_hvapi_unregister;
+
+       err = n2rng_init_control(np);
+       if (err)
+               goto out_free_units;
+
+       dev_info(&op->dev, "Found %s RNG, units: %d\n",
+                ((np->flags & N2RNG_FLAG_VF) ?
+                 "Victoria Falls" : "Niagara2"),
+                np->num_units);
+
+       np->hwrng.name = "n2rng";
+       np->hwrng.data_read = n2rng_data_read;
+       np->hwrng.priv = (unsigned long) np;
+
+       err = hwrng_register(&np->hwrng);
+       if (err)
+               goto out_free_units;
+
+       dev_set_drvdata(&op->dev, np);
+
+       schedule_delayed_work(&np->work, 0);
+
+       return 0;
+
+out_free_units:
+       kfree(np->units);
+       np->units = NULL;
+
+out_hvapi_unregister:
+       sun4v_hvapi_unregister(HV_GRP_RNG);
+
+out_free:
+       kfree(np);
+out:
+       return err;
+}
+
+static int __devexit n2rng_remove(struct of_device *op)
+{
+       struct n2rng *np = dev_get_drvdata(&op->dev);
+
+       np->flags |= N2RNG_FLAG_SHUTDOWN;
+
+       cancel_delayed_work_sync(&np->work);
+
+       hwrng_unregister(&np->hwrng);
+
+       sun4v_hvapi_unregister(HV_GRP_RNG);
+
+       kfree(np->units);
+       np->units = NULL;
+
+       kfree(np);
+
+       dev_set_drvdata(&op->dev, NULL);
+
+       return 0;
+}
+
+static struct of_device_id n2rng_match[] = {
+       {
+               .name           = "random-number-generator",
+               .compatible     = "SUNW,n2-rng",
+       },
+       {
+               .name           = "random-number-generator",
+               .compatible     = "SUNW,vf-rng",
+               .data           = (void *) 1,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, n2rng_match);
+
+static struct of_platform_driver n2rng_driver = {
+       .name           = "n2rng",
+       .match_table    = n2rng_match,
+       .probe          = n2rng_probe,
+       .remove         = __devexit_p(n2rng_remove),
+};
+
+static int __init n2rng_init(void)
+{
+       return of_register_driver(&n2rng_driver, &of_bus_type);
+}
+
+static void __exit n2rng_exit(void)
+{
+       of_unregister_driver(&n2rng_driver);
+}
+
+module_init(n2rng_init);
+module_exit(n2rng_exit);
diff --git a/drivers/char/hw_random/n2rng.h b/drivers/char/hw_random/n2rng.h
new file mode 100644 (file)
index 0000000..a2b81e7
--- /dev/null
@@ -0,0 +1,118 @@
+/* n2rng.h: Niagara2 RNG defines.
+ *
+ * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
+ */
+
+#ifndef _N2RNG_H
+#define _N2RNG_H
+
+#define RNG_CTL_WAIT       0x0000000001fffe00ULL /* Minimum wait time       */
+#define RNG_CTL_WAIT_SHIFT 9
+#define RNG_CTL_BYPASS     0x0000000000000100ULL /* VCO voltage source      */
+#define RNG_CTL_VCO        0x00000000000000c0ULL /* VCO rate control        */
+#define RNG_CTL_VCO_SHIFT  6
+#define RNG_CTL_ASEL       0x0000000000000030ULL /* Analog MUX select       */
+#define RNG_CTL_ASEL_SHIFT 4
+#define RNG_CTL_LFSR       0x0000000000000008ULL /* Use LFSR or plain shift */
+#define RNG_CTL_ES3        0x0000000000000004ULL /* Enable entropy source 3 */
+#define RNG_CTL_ES2        0x0000000000000002ULL /* Enable entropy source 2 */
+#define RNG_CTL_ES1        0x0000000000000001ULL /* Enable entropy source 1 */
+
+#define HV_FAST_RNG_GET_DIAG_CTL       0x130
+#define HV_FAST_RNG_CTL_READ           0x131
+#define HV_FAST_RNG_CTL_WRITE          0x132
+#define HV_FAST_RNG_DATA_READ_DIAG     0x133
+#define HV_FAST_RNG_DATA_READ          0x134
+
+#define HV_RNG_STATE_UNCONFIGURED      0
+#define HV_RNG_STATE_CONFIGURED                1
+#define HV_RNG_STATE_HEALTHCHECK       2
+#define HV_RNG_STATE_ERROR             3
+
+#define HV_RNG_NUM_CONTROL             4
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_rng_get_diag_ctl(void);
+extern unsigned long sun4v_rng_ctl_read_v1(unsigned long ctl_regs_ra,
+                                          unsigned long *state,
+                                          unsigned long *tick_delta);
+extern unsigned long sun4v_rng_ctl_read_v2(unsigned long ctl_regs_ra,
+                                          unsigned long unit,
+                                          unsigned long *state,
+                                          unsigned long *tick_delta,
+                                          unsigned long *watchdog,
+                                          unsigned long *write_status);
+extern unsigned long sun4v_rng_ctl_write_v1(unsigned long ctl_regs_ra,
+                                           unsigned long state,
+                                           unsigned long write_timeout,
+                                           unsigned long *tick_delta);
+extern unsigned long sun4v_rng_ctl_write_v2(unsigned long ctl_regs_ra,
+                                           unsigned long state,
+                                           unsigned long write_timeout,
+                                           unsigned long unit);
+extern unsigned long sun4v_rng_data_read_diag_v1(unsigned long data_ra,
+                                                unsigned long len,
+                                                unsigned long *tick_delta);
+extern unsigned long sun4v_rng_data_read_diag_v2(unsigned long data_ra,
+                                                unsigned long len,
+                                                unsigned long unit,
+                                                unsigned long *tick_delta);
+extern unsigned long sun4v_rng_data_read(unsigned long data_ra,
+                                        unsigned long *tick_delta);
+
+struct n2rng_unit {
+       u64                     control[HV_RNG_NUM_CONTROL];
+};
+
+struct n2rng {
+       struct of_device        *op;
+
+       unsigned long           flags;
+#define N2RNG_FLAG_VF          0x00000001 /* Victoria Falls RNG, else N2 */
+#define N2RNG_FLAG_CONTROL     0x00000002 /* Operating in control domain */
+#define N2RNG_FLAG_READY       0x00000008 /* Ready for hw-rng layer      */
+#define N2RNG_FLAG_SHUTDOWN    0x00000010 /* Driver unregistering        */
+#define N2RNG_FLAG_BUFFER_VALID        0x00000020 /* u32 buffer holds valid data */
+
+       int                     num_units;
+       struct n2rng_unit       *units;
+
+       struct hwrng            hwrng;
+       u32                     buffer;
+
+       /* Registered hypervisor group API major and minor version.  */
+       unsigned long           hvapi_major;
+       unsigned long           hvapi_minor;
+
+       struct delayed_work     work;
+
+       unsigned long           hv_state; /* HV_RNG_STATE_foo */
+
+       unsigned long           health_check_sec;
+       unsigned long           accum_cycles;
+       unsigned long           wd_timeo;
+#define N2RNG_HEALTH_CHECK_SEC_DEFAULT 0
+#define N2RNG_ACCUM_CYCLES_DEFAULT     2048
+#define N2RNG_WD_TIMEO_DEFAULT         0
+
+       u64                     scratch_control[HV_RNG_NUM_CONTROL];
+
+#define SELFTEST_TICKS         38859
+#define SELFTEST_VAL           ((u64)0xB8820C7BD387E32C)
+#define SELFTEST_POLY          ((u64)0x231DCEE91262B8A3)
+#define SELFTEST_MATCH_GOAL    6
+#define SELFTEST_LOOPS_MAX     40000
+#define SELFTEST_BUFFER_WORDS  8
+
+       u64                     test_data;
+       u64                     test_control[HV_RNG_NUM_CONTROL];
+       u64                     test_buffer[SELFTEST_BUFFER_WORDS];
+};
+
+#define N2RNG_BLOCK_LIMIT      60000
+#define N2RNG_BUSY_LIMIT       100
+#define N2RNG_HCHECK_LIMIT     100
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* _N2RNG_H */
index 5dc74404058f6eb46941a4af8bad71dfe3a5229e..9cb48fcd316c775007e596dc66a6adb0494ddfd9 100644 (file)
@@ -718,12 +718,12 @@ ip2_loadmain(int *iop, int *irqp)
                        }
 
                        if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
-                               device_create(ip2_class, NULL,
-                                               MKDEV(IP2_IPL_MAJOR, 4 * i),
-                                               "ipl%d", i);
-                               device_create(ip2_class, NULL,
-                                               MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
-                                               "stat%d", i);
+                               device_create_drvdata(ip2_class, NULL,
+                                                     MKDEV(IP2_IPL_MAJOR, 4 * i),
+                                                     NULL, "ipl%d", i);
+                               device_create_drvdata(ip2_class, NULL,
+                                                     MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
+                                                     NULL, "stat%d", i);
 
                            for ( box = 0; box < ABS_MAX_BOXES; ++box )
                            {
index c11a40483459f3bd581dd5429f65606b1d882f67..64e1c169e826814c922c6937f738424ba819891b 100644 (file)
@@ -871,7 +871,7 @@ static void ipmi_new_smi(int if_num, struct device *device)
        entry->dev = dev;
 
        mutex_lock(&reg_list_mutex);
-       device_create(ipmi_class, device, dev, "ipmi%d", if_num);
+       device_create_drvdata(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
        list_add(&entry->link, &reg_list);
        mutex_unlock(&reg_list_mutex);
 }
index d4281df10c22dbd54a28f790774c7636126cd709..8f7cc190b62d420116b5c0d30e70899c3332c94d 100644 (file)
@@ -1181,14 +1181,17 @@ static int isicom_chars_in_buffer(struct tty_struct *tty)
 }
 
 /* ioctl et all */
-static inline void isicom_send_break(struct isi_port *port,
-       unsigned long length)
+static int isicom_send_break(struct tty_struct *tty, int length)
 {
+       struct isi_port *port = tty->driver_data;
        struct isi_board *card = port->card;
        unsigned long base = card->base;
 
+       if (length == -1)
+               return -EOPNOTSUPP;
+
        if (!lock_card(card))
-               return;
+               return -EINVAL;
 
        outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
        outw((length & 0xff) << 8 | 0x00, base);
@@ -1196,6 +1199,7 @@ static inline void isicom_send_break(struct isi_port *port,
        InterruptTheCard(base);
 
        unlock_card(card);
+       return 0;
 }
 
 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
@@ -1305,28 +1309,11 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
 {
        struct isi_port *port = tty->driver_data;
        void __user *argp = (void __user *)arg;
-       int retval;
 
        if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
                return -ENODEV;
 
        switch (cmd) {
-       case TCSBRK:
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-               tty_wait_until_sent(tty, 0);
-               if (!arg)
-                       isicom_send_break(port, HZ/4);
-               return 0;
-
-       case TCSBRKP:
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-               tty_wait_until_sent(tty, 0);
-               isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4);
-               return 0;
        case TIOCGSERIAL:
                return isicom_get_serial_info(port, argp);
 
@@ -1459,6 +1446,7 @@ static const struct tty_operations isicom_ops = {
        .flush_buffer           = isicom_flush_buffer,
        .tiocmget               = isicom_tiocmget,
        .tiocmset               = isicom_tiocmset,
+       .break_ctl              = isicom_send_break,
 };
 
 static int __devinit reset_card(struct pci_dev *pdev,
@@ -1832,7 +1820,7 @@ static int __init isicom_init(void)
        isicom_normal->init_termios.c_cflag     = B9600 | CS8 | CREAD | HUPCL |
                CLOCAL;
        isicom_normal->flags                    = TTY_DRIVER_REAL_RAW |
-               TTY_DRIVER_DYNAMIC_DEV;
+               TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK;
        tty_set_operations(isicom_normal, &isicom_ops);
 
        retval = tty_register_driver(isicom_normal);
index 6ef1c565705c7d3bb129190374b2c8bff34e3053..843a2afaf2040f2a641af8ea33a4f10b570e5a04 100644 (file)
@@ -598,7 +598,7 @@ static int  stli_parsebrd(struct stlconf *confp, char **argp);
 static int     stli_open(struct tty_struct *tty, struct file *filp);
 static void    stli_close(struct tty_struct *tty, struct file *filp);
 static int     stli_write(struct tty_struct *tty, const unsigned char *buf, int count);
-static void    stli_putchar(struct tty_struct *tty, unsigned char ch);
+static int     stli_putchar(struct tty_struct *tty, unsigned char ch);
 static void    stli_flushchars(struct tty_struct *tty);
 static int     stli_writeroom(struct tty_struct *tty);
 static int     stli_charsinbuffer(struct tty_struct *tty);
@@ -609,7 +609,7 @@ static void stli_unthrottle(struct tty_struct *tty);
 static void    stli_stop(struct tty_struct *tty);
 static void    stli_start(struct tty_struct *tty);
 static void    stli_flushbuffer(struct tty_struct *tty);
-static void    stli_breakctl(struct tty_struct *tty, int state);
+static int     stli_breakctl(struct tty_struct *tty, int state);
 static void    stli_waituntilsent(struct tty_struct *tty, int timeout);
 static void    stli_sendxchar(struct tty_struct *tty, char ch);
 static void    stli_hangup(struct tty_struct *tty);
@@ -826,7 +826,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
  */
        portp->port.tty = tty;
        tty->driver_data = portp;
-       portp->refcount++;
+       portp->port.count++;
 
        wait_event_interruptible(portp->raw_wait,
                        !test_bit(ST_INITIALIZING, &portp->state));
@@ -888,9 +888,9 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
                spin_unlock_irqrestore(&stli_lock, flags);
                return;
        }
-       if ((tty->count == 1) && (portp->refcount != 1))
-               portp->refcount = 1;
-       if (portp->refcount-- > 1) {
+       if ((tty->count == 1) && (portp->port.count != 1))
+               portp->port.count = 1;
+       if (portp->port.count-- > 1) {
                spin_unlock_irqrestore(&stli_lock, flags);
                return;
        }
@@ -925,8 +925,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
        clear_bit(ST_TXBUSY, &portp->state);
        clear_bit(ST_RXSTOP, &portp->state);
        set_bit(TTY_IO_ERROR, &tty->flags);
-       if (tty->ldisc.flush_buffer)
-               (tty->ldisc.flush_buffer)(tty);
+       tty_ldisc_flush(tty);
        set_bit(ST_DOFLUSHRX, &portp->state);
        stli_flushbuffer(tty);
 
@@ -1202,7 +1201,7 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct
        spin_lock_irqsave(&stli_lock, flags);
        portp->openwaitcnt++;
        if (! tty_hung_up_p(filp))
-               portp->refcount--;
+               portp->port.count--;
        spin_unlock_irqrestore(&stli_lock, flags);
 
        for (;;) {
@@ -1231,7 +1230,7 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct
 
        spin_lock_irqsave(&stli_lock, flags);
        if (! tty_hung_up_p(filp))
-               portp->refcount++;
+               portp->port.count++;
        portp->openwaitcnt--;
        spin_unlock_irqrestore(&stli_lock, flags);
 
@@ -1333,7 +1332,7 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun
  *     first them do the new ports.
  */
 
-static void stli_putchar(struct tty_struct *tty, unsigned char ch)
+static int stli_putchar(struct tty_struct *tty, unsigned char ch)
 {
        if (tty != stli_txcooktty) {
                if (stli_txcooktty != NULL)
@@ -1342,6 +1341,7 @@ static void stli_putchar(struct tty_struct *tty, unsigned char ch)
        }
 
        stli_txcookbuf[stli_txcooksize++] = ch;
+       return 0;
 }
 
 /*****************************************************************************/
@@ -1660,7 +1660,6 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
 {
        struct stliport *portp;
        struct stlibrd *brdp;
-       unsigned int ival;
        int rc;
        void __user *argp = (void __user *)arg;
 
@@ -1857,7 +1856,7 @@ static void stli_hangup(struct tty_struct *tty)
        set_bit(TTY_IO_ERROR, &tty->flags);
        portp->port.tty = NULL;
        portp->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-       portp->refcount = 0;
+       portp->port.count = 0;
        spin_unlock_irqrestore(&stli_lock, flags);
 
        wake_up_interruptible(&portp->port.open_wait);
@@ -1909,7 +1908,7 @@ static void stli_flushbuffer(struct tty_struct *tty)
 
 /*****************************************************************************/
 
-static void stli_breakctl(struct tty_struct *tty, int state)
+static int stli_breakctl(struct tty_struct *tty, int state)
 {
        struct stlibrd  *brdp;
        struct stliport *portp;
@@ -1917,15 +1916,16 @@ static void stli_breakctl(struct tty_struct *tty, int state)
 
        portp = tty->driver_data;
        if (portp == NULL)
-               return;
+               return -EINVAL;
        if (portp->brdnr >= stli_nrbrds)
-               return;
+               return -EINVAL;
        brdp = stli_brds[portp->brdnr];
        if (brdp == NULL)
-               return;
+               return -EINVAL;
 
        arg = (state == -1) ? BREAKON : BREAKOFF;
        stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0);
+       return 0;
 }
 
 /*****************************************************************************/
@@ -4246,7 +4246,7 @@ static int stli_portcmdstats(struct stliport *portp)
        stli_comstats.panel = portp->panelnr;
        stli_comstats.port = portp->portnr;
        stli_comstats.state = portp->state;
-       stli_comstats.flags = portp->port.flag;
+       stli_comstats.flags = portp->port.flags;
 
        spin_lock_irqsave(&brd_lock, flags);
        if (portp->port.tty != NULL) {
@@ -4599,8 +4599,9 @@ static int __init istallion_module_init(void)
 
        istallion_class = class_create(THIS_MODULE, "staliomem");
        for (i = 0; i < 4; i++)
-               device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
-                             "staliomem%d", i);
+               device_create_drvdata(istallion_class, NULL,
+                                     MKDEV(STL_SIOMEMMAJOR, i),
+                                     NULL, "staliomem%d", i);
 
        return 0;
 err_deinit:
index d9a0a53c842d2f35632a069591d148bfc843c2d9..7b3a212c86b1ab21d5e3d783716ded2787f3729d 100644 (file)
@@ -46,6 +46,8 @@
 
 extern void ctrl_alt_del(void);
 
+#define to_handle_h(n) container_of(n, struct input_handle, h_node)
+
 /*
  * Exported functions/variables
  */
index 71abb4c33aa249d748826a317be08a3b8a4f7cd9..3f2719b9f77b5fca364477dfa7d096c66be759cb 100644 (file)
@@ -813,7 +813,8 @@ static int lp_register(int nr, struct parport *port)
        if (reset)
                lp_reset(nr);
 
-       device_create(lp_class, port->dev, MKDEV(LP_MAJOR, nr), "lp%d", nr);
+       device_create_drvdata(lp_class, port->dev, MKDEV(LP_MAJOR, nr), NULL,
+                             "lp%d", nr);
 
        printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, 
               (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven");
index 070e22e8ea9efb43a180149caa5a47d70faf471f..c2dba82eb5f7fa82bdb874b17f605ab01f80fb1f 100644 (file)
@@ -80,7 +80,7 @@ static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
 }
 #endif
 
-#ifdef CONFIG_NONPROMISC_DEVMEM
+#ifdef CONFIG_STRICT_DEVMEM
 static inline int range_is_allowed(unsigned long pfn, unsigned long size)
 {
        u64 from = ((u64)pfn) << PAGE_SHIFT;
@@ -989,9 +989,9 @@ static int __init chr_dev_init(void)
 
        mem_class = class_create(THIS_MODULE, "mem");
        for (i = 0; i < ARRAY_SIZE(devlist); i++)
-               device_create(mem_class, NULL,
-                             MKDEV(MEM_MAJOR, devlist[i].minor),
-                             devlist[i].name);
+               device_create_drvdata(mem_class, NULL,
+                                     MKDEV(MEM_MAJOR, devlist[i].minor),
+                                     NULL, devlist[i].name);
 
        return 0;
 }
index 6e1563c3d30aea0da63650ea8a3a64daaf6727be..999aa779c08a710601fabc93cacb6f52229c53ba 100644 (file)
@@ -217,8 +217,8 @@ int misc_register(struct miscdevice * misc)
                misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
        dev = MKDEV(MISC_MAJOR, misc->minor);
 
-       misc->this_device = device_create(misc_class, misc->parent, dev,
-                                         "%s", misc->name);
+       misc->this_device = device_create_drvdata(misc_class, misc->parent,
+                                                 dev, NULL, "%s", misc->name);
        if (IS_ERR(misc->this_device)) {
                err = PTR_ERR(misc->this_device);
                goto out;
index 192961fd71739d22ad4ff9a65df5a101bc460fbd..918711aa56f3c345edd050a68fa0189306dc63bc 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/interrupt.h>
 #include <linux/time.h>
 #include <linux/math64.h>
+#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/sn/addrs.h>
@@ -57,8 +58,8 @@ extern unsigned long sn_rtc_cycles_per_second;
 
 #define rtc_time()              (*RTC_COUNTER_ADDR)
 
-static int mmtimer_ioctl(struct inode *inode, struct file *file,
-                        unsigned int cmd, unsigned long arg);
+static long mmtimer_ioctl(struct file *file, unsigned int cmd,
+                                               unsigned long arg);
 static int mmtimer_mmap(struct file *file, struct vm_area_struct *vma);
 
 /*
@@ -67,9 +68,9 @@ static int mmtimer_mmap(struct file *file, struct vm_area_struct *vma);
 static unsigned long mmtimer_femtoperiod = 0;
 
 static const struct file_operations mmtimer_fops = {
-       .owner =        THIS_MODULE,
-       .mmap =         mmtimer_mmap,
-       .ioctl =        mmtimer_ioctl,
+       .owner = THIS_MODULE,
+       .mmap = mmtimer_mmap,
+       .unlocked_ioctl = mmtimer_ioctl,
 };
 
 /*
@@ -339,7 +340,6 @@ restart:
 
 /**
  * mmtimer_ioctl - ioctl interface for /dev/mmtimer
- * @inode: inode of the device
  * @file: file structure for the device
  * @cmd: command to execute
  * @arg: optional argument to command
@@ -365,11 +365,13 @@ restart:
  * %MMTIMER_GETCOUNTER - Gets the current value in the counter and places it
  * in the address specified by @arg.
  */
-static int mmtimer_ioctl(struct inode *inode, struct file *file,
-                        unsigned int cmd, unsigned long arg)
+static long mmtimer_ioctl(struct file *file, unsigned int cmd,
+                                               unsigned long arg)
 {
        int ret = 0;
 
+       lock_kernel();
+
        switch (cmd) {
        case MMTIMER_GETOFFSET: /* offset of the counter */
                /*
@@ -384,15 +386,14 @@ static int mmtimer_ioctl(struct inode *inode, struct file *file,
        case MMTIMER_GETRES: /* resolution of the clock in 10^-15 s */
                if(copy_to_user((unsigned long __user *)arg,
                                &mmtimer_femtoperiod, sizeof(unsigned long)))
-                       return -EFAULT;
+                       ret = -EFAULT;
                break;
 
        case MMTIMER_GETFREQ: /* frequency in Hz */
                if(copy_to_user((unsigned long __user *)arg,
                                &sn_rtc_cycles_per_second,
                                sizeof(unsigned long)))
-                       return -EFAULT;
-               ret = 0;
+                       ret = -EFAULT;
                break;
 
        case MMTIMER_GETBITS: /* number of bits in the clock */
@@ -406,13 +407,13 @@ static int mmtimer_ioctl(struct inode *inode, struct file *file,
        case MMTIMER_GETCOUNTER:
                if(copy_to_user((unsigned long __user *)arg,
                                RTC_COUNTER_ADDR, sizeof(unsigned long)))
-                       return -EFAULT;
+                       ret = -EFAULT;
                break;
        default:
-               ret = -ENOSYS;
+               ret = -ENOTTY;
                break;
        }
-
+       unlock_kernel();
        return ret;
 }
 
index 2bba250ffc8e03f5e357bf42731307104539b258..d3d7864e0c1ef566b86d9a5cfb72c45d2aaf5836 100644 (file)
@@ -374,12 +374,13 @@ copy:
        return ret;
 }
 
-static void moxa_break_ctl(struct tty_struct *tty, int state)
+static int moxa_break_ctl(struct tty_struct *tty, int state)
 {
        struct moxa_port *port = tty->driver_data;
 
        moxafunc(port->tableAddr, state ? FC_SendBreak : FC_StopBreak,
                        Magic_code);
+       return 0;
 }
 
 static const struct tty_operations moxa_ops = {
index 6307e301bd262120dcc59308016dbb1846f36c01..4c756bbba94831aafa3895853394409688c896c6 100644 (file)
@@ -47,7 +47,7 @@
 
 #include "mxser.h"
 
-#define        MXSER_VERSION   "2.0.3"         /* 1.11 */
+#define        MXSER_VERSION   "2.0.4"         /* 1.12 */
 #define        MXSERMAJOR       174
 #define        MXSERCUMAJOR     175
 
 #define UART_MCR_AFE           0x20
 #define UART_LSR_SPECIAL       0x1E
 
+#define PCI_DEVICE_ID_POS104UL 0x1044
 #define PCI_DEVICE_ID_CB108    0x1080
+#define PCI_DEVICE_ID_CP102UF  0x1023
 #define PCI_DEVICE_ID_CB114    0x1142
 #define PCI_DEVICE_ID_CP114UL  0x1143
 #define PCI_DEVICE_ID_CB134I   0x1341
 #define PCI_DEVICE_ID_CP138U   0x1380
-#define PCI_DEVICE_ID_POS104UL 0x1044
 
 
 #define C168_ASIC_ID    1
@@ -142,7 +143,8 @@ static const struct mxser_cardinfo mxser_cards[] = {
        { "CB-134I series",     4, },
        { "CP-138U series",     8, },
        { "POS-104UL series",   4, },
-       { "CP-114UL series",    4, }
+       { "CP-114UL series",    4, },
+/*30*/ { "CP-102UF series",    2, }
 };
 
 /* driver_data correspond to the lines in the structure above
@@ -172,6 +174,7 @@ static struct pci_device_id mxser_pcibrds[] = {
        { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U),      .driver_data = 27 },
        { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL),    .driver_data = 28 },
        { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL),     .driver_data = 29 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP102UF),     .driver_data = 30 },
        { }
 };
 MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
@@ -1414,7 +1417,6 @@ static int mxser_set_serial_info(struct mxser_port *info,
                info->port.closing_wait = new_serial.closing_wait * HZ / 100;
                info->port.tty->low_latency =
                                (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
-               info->port.tty->low_latency = 0;
                if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
                                (new_serial.baud_base != info->baud_base ||
                                new_serial.custom_divisor !=
@@ -1464,27 +1466,6 @@ static int mxser_get_lsr_info(struct mxser_port *info,
        return put_user(result, value);
 }
 
-/*
- * This routine sends a break character out the serial port.
- */
-static void mxser_send_break(struct mxser_port *info, int duration)
-{
-       unsigned long flags;
-
-       if (!info->ioaddr)
-               return;
-       set_current_state(TASK_INTERRUPTIBLE);
-       spin_lock_irqsave(&info->slock, flags);
-       outb(inb(info->ioaddr + UART_LCR) | UART_LCR_SBC,
-               info->ioaddr + UART_LCR);
-       spin_unlock_irqrestore(&info->slock, flags);
-       schedule_timeout(duration);
-       spin_lock_irqsave(&info->slock, flags);
-       outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC,
-               info->ioaddr + UART_LCR);
-       spin_unlock_irqrestore(&info->slock, flags);
-}
-
 static int mxser_tiocmget(struct tty_struct *tty, struct file *file)
 {
        struct mxser_port *info = tty->driver_data;
@@ -1872,21 +1853,6 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
                return -EIO;
 
        switch (cmd) {
-       case TCSBRK:            /* SVID version: non-zero arg --> no break */
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-               tty_wait_until_sent(tty, 0);
-               if (!arg)
-                       mxser_send_break(info, HZ / 4); /* 1/4 second */
-               return 0;
-       case TCSBRKP:           /* support for POSIX tcsendbreak() */
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-               tty_wait_until_sent(tty, 0);
-               mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
-               return 0;
        case TIOCGSERIAL:
                lock_kernel();
                retval = mxser_get_serial_info(info, argp);
@@ -2219,7 +2185,7 @@ static void mxser_hangup(struct tty_struct *tty)
 /*
  * mxser_rs_break() --- routine which turns the break handling on or off
  */
-static void mxser_rs_break(struct tty_struct *tty, int break_state)
+static int mxser_rs_break(struct tty_struct *tty, int break_state)
 {
        struct mxser_port *info = tty->driver_data;
        unsigned long flags;
@@ -2232,6 +2198,7 @@ static void mxser_rs_break(struct tty_struct *tty, int break_state)
                outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC,
                        info->ioaddr + UART_LCR);
        spin_unlock_irqrestore(&info->slock, flags);
+       return 0;
 }
 
 static void mxser_receive_chars(struct mxser_port *port, int *status)
index ed4e03333ab4646029f61236a554daa23a65a2df..69ec6399c714b206ea11de8c30d8ba75fd0a9bd6 100644 (file)
@@ -677,6 +677,10 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
        /* Allocate transmit buffer */
        /* sleep until transmit buffer available */             
        while (!(tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list))) {
+               if (file->f_flags & O_NONBLOCK) {
+                       error = -EAGAIN;
+                       break;
+               }
                schedule();
                        
                n_hdlc = tty2n_hdlc (tty);
index a22662b6a1a50fc6aa25f7a000d619abd7ba1bc7..39f6357e3b5d0a63e432cf0238cc84aba4b8d33f 100644 (file)
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
index e4a4fbd37d7a3062cd8d91faf397cbdf28443186..f070ae7bd91a1d905eab711a6ee8d013ae8f3eeb 100644 (file)
@@ -1896,7 +1896,7 @@ static int cm4000_probe(struct pcmcia_device *link)
                return ret;
        }
 
-       device_create(cmm_class, NULL, MKDEV(major, i), "cmm%d", i);
+       device_create_drvdata(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i);
 
        return 0;
 }
index 6181f8a9b0bd0309cb4670dd0d572af91fc8689f..0b5934bef7a4301049f19c8d82393544742f4a84 100644 (file)
@@ -653,7 +653,8 @@ static int reader_probe(struct pcmcia_device *link)
                return ret;
        }
 
-       device_create(cmx_class, NULL, MKDEV(major, i), "cmx%d", i);
+       device_create_drvdata(cmx_class, NULL, MKDEV(major, i), NULL,
+                             "cmx%d", i);
 
        return 0;
 }
index b694d430f10e4fcdb6af4440af28d0ea3a01543b..d1fceabe3aefcd5b54d8b071626a057b87564f8b 100644 (file)
@@ -2230,7 +2230,7 @@ static int tiocmset(struct tty_struct *tty, struct file *file,
  * Arguments:          tty             pointer to tty instance data
  *                     break_state     -1=set break condition, 0=clear
  */
-static void mgslpc_break(struct tty_struct *tty, int break_state)
+static int mgslpc_break(struct tty_struct *tty, int break_state)
 {
        MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data;
        unsigned long flags;
@@ -2240,7 +2240,7 @@ static void mgslpc_break(struct tty_struct *tty, int break_state)
                         __FILE__,__LINE__, info->device_name, break_state);
 
        if (mgslpc_paranoia_check(info, tty->name, "mgslpc_break"))
-               return;
+               return -EINVAL;
 
        spin_lock_irqsave(&info->lock,flags);
        if (break_state == -1)
@@ -2248,6 +2248,7 @@ static void mgslpc_break(struct tty_struct *tty, int break_state)
        else
                clear_reg_bits(info, CHA+DAFO, BIT6);
        spin_unlock_irqrestore(&info->lock,flags);
+       return 0;
 }
 
 /* Service an IOCTL request
index f6e6acadd9a017d98b562a9c2f2da7178a412161..7af7a7e6b9c2e570ff53eff4152e5f61d6cf7738 100644 (file)
@@ -752,8 +752,9 @@ static const struct file_operations pp_fops = {
 
 static void pp_attach(struct parport *port)
 {
-       device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number),
-                       "parport%d", port->number);
+       device_create_drvdata(ppdev_class, port->dev,
+                             MKDEV(PP_MAJOR, port->number),
+                             NULL, "parport%d", port->number);
 }
 
 static void pp_detach(struct parport *port)
index 505fcbe884a4aad394ae212396677d258b3d25fb..47b8cf281d4a79766c0717dec1ea4380d2bf9717 100644 (file)
@@ -131,8 +131,8 @@ raw_ioctl(struct inode *inode, struct file *filp,
 static void bind_device(struct raw_config_request *rq)
 {
        device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor));
-       device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor),
-                     "raw%d", rq->raw_minor);
+       device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor),
+                             NULL, "raw%d", rq->raw_minor);
 }
 
 /*
@@ -283,7 +283,8 @@ static int __init raw_init(void)
                ret = PTR_ERR(raw_class);
                goto error_region;
        }
-       device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), "rawctl");
+       device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL,
+                             "rawctl");
 
        return 0;
 
index 724b2b20f4b2bc881a02cef4dd090fbb22207915..2c6c8f33d6b43e7dda4d7b03fb8f0615698d0bb3 100644 (file)
@@ -1250,11 +1250,15 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file,
        return 0;
 }
 
-static void rc_send_break(struct riscom_port *port, unsigned long length)
+static int rc_send_break(struct tty_struct *tty, int length)
 {
+       struct riscom_port *port = (struct riscom_port *)tty->driver_data;
        struct riscom_board *bp = port_Board(port);
        unsigned long flags;
 
+       if (length == 0 || length == -1)
+               return -EOPNOTSUPP;
+
        spin_lock_irqsave(&riscom_lock, flags);
 
        port->break_length = RISCOM_TPS / HZ * length;
@@ -1268,6 +1272,7 @@ static void rc_send_break(struct riscom_port *port, unsigned long length)
        rc_wait_CCR(bp);
 
        spin_unlock_irqrestore(&riscom_lock, flags);
+       return 0;
 }
 
 static int rc_set_serial_info(struct riscom_port *port,
@@ -1342,27 +1347,12 @@ static int rc_ioctl(struct tty_struct *tty, struct file *filp,
 {
        struct riscom_port *port = (struct riscom_port *)tty->driver_data;
        void __user *argp = (void __user *)arg;
-       int retval = 0;
+       int retval;
 
        if (rc_paranoia_check(port, tty->name, "rc_ioctl"))
                return -ENODEV;
 
        switch (cmd) {
-       case TCSBRK:    /* SVID version: non-zero arg --> no break */
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-               tty_wait_until_sent(tty, 0);
-               if (!arg)
-                       rc_send_break(port, HZ/4);      /* 1/4 second */
-               break;
-       case TCSBRKP:   /* support for POSIX tcsendbreak() */
-               retval = tty_check_change(tty);
-               if (retval)
-                       return retval;
-               tty_wait_until_sent(tty, 0);
-               rc_send_break(port, arg ? arg*(HZ/10) : HZ/4);
-               break;
        case TIOCGSERIAL:
                lock_kernel();
                retval = rc_get_serial_info(port, argp);
@@ -1517,6 +1507,7 @@ static const struct tty_operations riscom_ops = {
        .hangup = rc_hangup,
        .tiocmget = rc_tiocmget,
        .tiocmset = rc_tiocmset,
+       .break_ctl = rc_send_break,
 };
 
 static int __init rc_init_drivers(void)
@@ -1538,7 +1529,7 @@ static int __init rc_init_drivers(void)
                B9600 | CS8 | CREAD | HUPCL | CLOCAL;
        riscom_driver->init_termios.c_ispeed = 9600;
        riscom_driver->init_termios.c_ospeed = 9600;
-       riscom_driver->flags = TTY_DRIVER_REAL_RAW;
+       riscom_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK;
        tty_set_operations(riscom_driver, &riscom_ops);
        error = tty_register_driver(riscom_driver);
        if (error != 0) {
index e670eae2f5102562967c1768cc6392eac29f1765..584d791e84a6ed85634e359d76dfd4bfaeb397d4 100644 (file)
@@ -1236,13 +1236,13 @@ static void rp_set_termios(struct tty_struct *tty,
        }
 }
 
-static void rp_break(struct tty_struct *tty, int break_state)
+static int rp_break(struct tty_struct *tty, int break_state)
 {
        struct r_port *info = (struct r_port *) tty->driver_data;
        unsigned long flags;
 
        if (rocket_paranoia_check(info, "rp_break"))
-               return;
+               return -EINVAL;
 
        spin_lock_irqsave(&info->slock, flags);
        if (break_state == -1)
@@ -1250,6 +1250,7 @@ static void rp_break(struct tty_struct *tty, int break_state)
        else
                sClrBreak(&info->channel);
        spin_unlock_irqrestore(&info->slock, flags);
+       return 0;
 }
 
 /*
index 0b799ac1b04957f501d4c50539f58e7ee28199cd..3ce60df14c0a623f5aff950148f034938988a5f9 100644 (file)
@@ -444,7 +444,8 @@ scdrv_init(void)
                                continue;
                        }
 
-                       device_create(snsc_class, NULL, dev, "%s", devname);
+                       device_create_drvdata(snsc_class, NULL, dev, NULL,
+                                             "%s", devname);
 
                        ia64_sn_irtr_intr_enable(scd->scd_nasid,
                                                 0 /*ignored */ ,
index 037dc47e4cb10b544ce88890816714d605cb0734..242fd46fda22fef8747909efb71f29b8ded4c157 100644 (file)
@@ -77,7 +77,7 @@
 
 #include <linux/module.h>
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/ioport.h>
@@ -92,7 +92,7 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/init.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 #include "specialix_io8.h"
 #include "cd1865.h"
 
 static int sx_debug;
 static int sx_rxfifo = SPECIALIX_RXFIFO;
+static int sx_rtscts;
 
 #ifdef DEBUG
-#define dprintk(f, str...) if (sx_debug & f) printk (str)
+#define dprintk(f, str...) if (sx_debug & f) printk(str)
 #else
 #define dprintk(f, str...) /* nothing */
 #endif
@@ -131,10 +132,8 @@ static int sx_rxfifo = SPECIALIX_RXFIFO;
 #define SX_DEBUG_FIFO    0x0800
 
 
-#define func_enter() dprintk (SX_DEBUG_FLOW, "io8: enter %s\n",__func__)
-#define func_exit()  dprintk (SX_DEBUG_FLOW, "io8: exit  %s\n", __func__)
-
-#define jiffies_from_ms(a) ((((a) * HZ)/1000)+1)
+#define func_enter() dprintk(SX_DEBUG_FLOW, "io8: enter %s\n", __func__)
+#define func_exit()  dprintk(SX_DEBUG_FLOW, "io8: exit  %s\n", __func__)
 
 
 /* Configurable options: */
@@ -142,17 +141,6 @@ static int sx_rxfifo = SPECIALIX_RXFIFO;
 /* Am I paranoid or not ? ;-) */
 #define SPECIALIX_PARANOIA_CHECK
 
-/* Do I trust the IRQ from the card? (enabeling it doesn't seem to help)
-   When the IRQ routine leaves the chip in a state that is keeps on
-   requiring attention, the timer doesn't help either. */
-#undef SPECIALIX_TIMER
-
-#ifdef SPECIALIX_TIMER
-static int sx_poll = HZ;
-#endif
-
-
-
 /*
  * The following defines are mostly for testing purposes. But if you need
  * some nice reporting in your syslog, you can define them also.
@@ -162,16 +150,6 @@ static int sx_poll = HZ;
 
 
 
-#ifdef CONFIG_SPECIALIX_RTSCTS
-#define SX_CRTSCTS(bla) 1
-#else
-#define SX_CRTSCTS(tty) C_CRTSCTS(tty)
-#endif
-
-
-/* Used to be outb (0xff, 0x80); */
-#define short_pause() udelay (1)
-
 
 #define SPECIALIX_LEGAL_FLAGS \
        (ASYNC_HUP_NOTIFY   | ASYNC_SAK          | ASYNC_SPLIT_TERMIOS   | \
@@ -190,21 +168,14 @@ static struct specialix_board sx_board[SX_NBOARD] =  {
 static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
 
 
-#ifdef SPECIALIX_TIMER
-static struct timer_list missed_irq_timer;
-static irqreturn_t sx_interrupt(int irq, void * dev_id);
-#endif
-
-
-
-static inline int sx_paranoia_check(struct specialix_port const * port,
+static int sx_paranoia_check(struct specialix_port const *port,
                                    char *name, const char *routine)
 {
 #ifdef SPECIALIX_PARANOIA_CHECK
-       static const char *badmagic =
-               KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
-       static const char *badinfo =
-               KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
+       static const char *badmagic = KERN_ERR
+         "sx: Warning: bad specialix port magic number for device %s in %s\n";
+       static const char *badinfo = KERN_ERR
+         "sx: Warning: null specialix port for device %s in %s\n";
 
        if (!port) {
                printk(badinfo, name, routine);
@@ -226,66 +197,69 @@ static inline int sx_paranoia_check(struct specialix_port const * port,
  */
 
 /* Get board number from pointer */
-static inline int board_No (struct specialix_board * bp)
+static inline int board_No(struct specialix_board *bp)
 {
        return bp - sx_board;
 }
 
 
 /* Get port number from pointer */
-static inline int port_No (struct specialix_port const * port)
+static inline int port_No(struct specialix_port const *port)
 {
        return SX_PORT(port - sx_port);
 }
 
 
 /* Get pointer to board from pointer to port */
-static inline struct specialix_board * port_Board(struct specialix_port const * port)
+static inline struct specialix_board *port_Board(
+                                       struct specialix_port const *port)
 {
        return &sx_board[SX_BOARD(port - sx_port)];
 }
 
 
 /* Input Byte from CL CD186x register */
-static inline unsigned char sx_in(struct specialix_board  * bp, unsigned short reg)
+static inline unsigned char sx_in(struct specialix_board *bp,
+                                                       unsigned short reg)
 {
        bp->reg = reg | 0x80;
-       outb (reg | 0x80, bp->base + SX_ADDR_REG);
-       return inb  (bp->base + SX_DATA_REG);
+       outb(reg | 0x80, bp->base + SX_ADDR_REG);
+       return inb(bp->base + SX_DATA_REG);
 }
 
 
 /* Output Byte to CL CD186x register */
-static inline void sx_out(struct specialix_board  * bp, unsigned short reg,
+static inline void sx_out(struct specialix_board *bp, unsigned short reg,
                          unsigned char val)
 {
        bp->reg = reg | 0x80;
-       outb (reg | 0x80, bp->base + SX_ADDR_REG);
-       outb (val, bp->base + SX_DATA_REG);
+       outb(reg | 0x80, bp->base + SX_ADDR_REG);
+       outb(val, bp->base + SX_DATA_REG);
 }
 
 
 /* Input Byte from CL CD186x register */
-static inline unsigned char sx_in_off(struct specialix_board  * bp, unsigned short reg)
+static inline unsigned char sx_in_off(struct specialix_board *bp,
+                               unsigned short reg)
 {
        bp->reg = reg;
-       outb (reg, bp->base + SX_ADDR_REG);
-       return inb  (bp->base + SX_DATA_REG);
+       outb(reg, bp->base + SX_ADDR_REG);
+       return inb(bp->base + SX_DATA_REG);
 }
 
 
 /* Output Byte to CL CD186x register */
-static inline void sx_out_off(struct specialix_board  * bp, unsigned short reg,
-                         unsigned char val)
+static inline void sx_out_off(struct specialix_board  *bp,
+                               unsigned short reg, unsigned char val)
 {
        bp->reg = reg;
-       outb (reg, bp->base + SX_ADDR_REG);
-       outb (val, bp->base + SX_DATA_REG);
+       outb(reg, bp->base + SX_ADDR_REG);
+       outb(val, bp->base + SX_DATA_REG);
 }
 
 
 /* Wait for Channel Command Register ready */
-static inline void sx_wait_CCR(struct specialix_board  * bp)
+static void sx_wait_CCR(struct specialix_board  *bp)
 {
        unsigned long delay, flags;
        unsigned char ccr;
@@ -296,7 +270,7 @@ static inline void sx_wait_CCR(struct specialix_board  * bp)
                spin_unlock_irqrestore(&bp->lock, flags);
                if (!ccr)
                        return;
-               udelay (1);
+               udelay(1);
        }
 
        printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
@@ -304,7 +278,7 @@ static inline void sx_wait_CCR(struct specialix_board  * bp)
 
 
 /* Wait for Channel Command Register ready */
-static inline void sx_wait_CCR_off(struct specialix_board  * bp)
+static void sx_wait_CCR_off(struct specialix_board  *bp)
 {
        unsigned long delay;
        unsigned char crr;
@@ -316,7 +290,7 @@ static inline void sx_wait_CCR_off(struct specialix_board  * bp)
                spin_unlock_irqrestore(&bp->lock, flags);
                if (!crr)
                        return;
-               udelay (1);
+               udelay(1);
        }
 
        printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
@@ -327,7 +301,7 @@ static inline void sx_wait_CCR_off(struct specialix_board  * bp)
  *  specialix IO8+ IO range functions.
  */
 
-static inline int sx_request_io_range(struct specialix_board * bp)
+static int sx_request_io_range(struct specialix_board *bp)
 {
        return request_region(bp->base,
                bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
@@ -335,15 +309,15 @@ static inline int sx_request_io_range(struct specialix_board * bp)
 }
 
 
-static inline void sx_release_io_range(struct specialix_board * bp)
+static void sx_release_io_range(struct specialix_board *bp)
 {
-       release_region(bp->base,
-                      bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
+       release_region(bp->base, bp->flags & SX_BOARD_IS_PCI ?
+                                       SX_PCI_IO_SPACE : SX_IO_SPACE);
 }
 
 
 /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
-static int sx_set_irq ( struct specialix_board *bp)
+static int sx_set_irq(struct specialix_board *bp)
 {
        int virq;
        int i;
@@ -353,15 +327,24 @@ static int sx_set_irq ( struct specialix_board *bp)
                return 1;
        switch (bp->irq) {
        /* In the same order as in the docs... */
-       case 15: virq = 0;break;
-       case 12: virq = 1;break;
-       case 11: virq = 2;break;
-       case 9:  virq = 3;break;
-       default: printk (KERN_ERR "Speclialix: cannot set irq to %d.\n", bp->irq);
-                return 0;
+       case 15:
+               virq = 0;
+               break;
+       case 12:
+               virq = 1;
+               break;
+       case 11:
+               virq = 2;
+               break;
+       case 9:
+               virq = 3;
+               break;
+       default:printk(KERN_ERR
+                           "Speclialix: cannot set irq to %d.\n", bp->irq);
+               return 0;
        }
        spin_lock_irqsave(&bp->lock, flags);
-       for (i=0;i<2;i++) {
+       for (i = 0; i < 2; i++) {
                sx_out(bp, CD186x_CAR, i);
                sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
        }
@@ -371,7 +354,7 @@ static int sx_set_irq ( struct specialix_board *bp)
 
 
 /* Reset and setup CD186x chip */
-static int sx_init_CD186x(struct specialix_board  * bp)
+static int sx_init_CD186x(struct specialix_board  *bp)
 {
        unsigned long flags;
        int scaler;
@@ -390,7 +373,7 @@ static int sx_init_CD186x(struct specialix_board  * bp)
        sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT);      /* Prio for transmitter intr */
        sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT);      /* Prio for receiver intr    */
        /* Set RegAckEn */
-       sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
+       sx_out_off(bp, CD186x_SRCR, sx_in(bp, CD186x_SRCR) | SRCR_REGACKEN);
 
        /* Setting up prescaler. We need 4 ticks per 1 ms */
        scaler =  SX_OSCFREQ/SPECIALIX_TPS;
@@ -399,9 +382,9 @@ static int sx_init_CD186x(struct specialix_board  * bp)
        sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
        spin_unlock_irqrestore(&bp->lock, flags);
 
-       if (!sx_set_irq (bp)) {
+       if (!sx_set_irq(bp)) {
                /* Figure out how to pass this along... */
-               printk (KERN_ERR "Cannot set irq to %d.\n", bp->irq);
+               printk(KERN_ERR "Cannot set irq to %d.\n", bp->irq);
                rv = 0;
        }
 
@@ -410,16 +393,16 @@ static int sx_init_CD186x(struct specialix_board  * bp)
 }
 
 
-static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
+static int read_cross_byte(struct specialix_board *bp, int reg, int bit)
 {
        int i;
        int t;
        unsigned long flags;
 
        spin_lock_irqsave(&bp->lock, flags);
-       for (i=0, t=0;i<8;i++) {
-               sx_out_off (bp, CD186x_CAR, i);
-               if (sx_in_off (bp, reg) & bit)
+       for (i = 0, t = 0; i < 8; i++) {
+               sx_out_off(bp, CD186x_CAR, i);
+               if (sx_in_off(bp, reg) & bit)
                        t |= 1 << i;
        }
        spin_unlock_irqrestore(&bp->lock, flags);
@@ -428,37 +411,10 @@ static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
 }
 
 
-#ifdef SPECIALIX_TIMER
-void missed_irq (unsigned long data)
-{
-       unsigned char irq;
-       unsigned long flags;
-       struct specialix_board  *bp = (struct specialix_board *)data;
-
-       spin_lock_irqsave(&bp->lock, flags);
-       irq = sx_in ((struct specialix_board *)data, CD186x_SRSR) &
-                                                   (SRSR_RREQint |
-                                                    SRSR_TREQint |
-                                                    SRSR_MREQint);
-       spin_unlock_irqrestore(&bp->lock, flags);
-       if (irq) {
-               printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
-               sx_interrupt (-1, bp);
-       }
-       mod_timer(&missed_irq_timer, jiffies + sx_poll);
-}
-#endif
-
-
-
 /* Main probing routine, also sets irq. */
 static int sx_probe(struct specialix_board *bp)
 {
        unsigned char val1, val2;
-#if 0
-       int irqs = 0;
-       int retries;
-#endif
        int rev;
        int chip;
 
@@ -471,17 +427,18 @@ static int sx_probe(struct specialix_board *bp)
 
        /* Are the I/O ports here ? */
        sx_out_off(bp, CD186x_PPRL, 0x5a);
-       short_pause ();
+       udelay(1);
        val1 = sx_in_off(bp, CD186x_PPRL);
 
        sx_out_off(bp, CD186x_PPRL, 0xa5);
-       short_pause ();
+       udelay(1);
        val2 = sx_in_off(bp, CD186x_PPRL);
 
 
-       if ((val1 != 0x5a) || (val2 != 0xa5)) {
-               printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
-                      board_No(bp), bp->base);
+       if (val1 != 0x5a || val2 != 0xa5) {
+               printk(KERN_INFO
+                       "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
+                                               board_No(bp), bp->base);
                sx_release_io_range(bp);
                func_exit();
                return 1;
@@ -489,10 +446,11 @@ static int sx_probe(struct specialix_board *bp)
 
        /* Check the DSR lines that Specialix uses as board
           identification */
-       val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
-       val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
-       dprintk (SX_DEBUG_INIT, "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
-               board_No(bp),  val1, val2);
+       val1 = read_cross_byte(bp, CD186x_MSVR, MSVR_DSR);
+       val2 = read_cross_byte(bp, CD186x_MSVR, MSVR_RTS);
+       dprintk(SX_DEBUG_INIT,
+                       "sx%d: DSR lines are: %02x, rts lines are: %02x\n",
+                                       board_No(bp), val1, val2);
 
        /* They managed to switch the bit order between the docs and
           the IO8+ card. The new PCI card now conforms to old docs.
@@ -500,7 +458,8 @@ static int sx_probe(struct specialix_board *bp)
           old card. */
        val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
        if (val1 != val2) {
-               printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
+               printk(KERN_INFO
+                 "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
                       board_No(bp), val2, bp->base, val1);
                sx_release_io_range(bp);
                func_exit();
@@ -508,47 +467,6 @@ static int sx_probe(struct specialix_board *bp)
        }
 
 
-#if 0
-       /* It's time to find IRQ for this board */
-       for (retries = 0; retries < 5 && irqs <= 0; retries++) {
-               irqs = probe_irq_on();
-               sx_init_CD186x(bp);                     /* Reset CD186x chip       */
-               sx_out(bp, CD186x_CAR, 2);               /* Select port 2          */
-               sx_wait_CCR(bp);
-               sx_out(bp, CD186x_CCR, CCR_TXEN);        /* Enable transmitter     */
-               sx_out(bp, CD186x_IER, IER_TXRDY);       /* Enable tx empty intr   */
-               msleep(50);
-               irqs = probe_irq_off(irqs);
-
-               dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
-               dprintk (SX_DEBUG_INIT, "TRAR = %02x, ", sx_in(bp, CD186x_TRAR));
-               dprintk (SX_DEBUG_INIT, "GIVR = %02x, ", sx_in(bp, CD186x_GIVR));
-               dprintk (SX_DEBUG_INIT, "GICR = %02x, ", sx_in(bp, CD186x_GICR));
-               dprintk (SX_DEBUG_INIT, "\n");
-
-               /* Reset CD186x again      */
-               if (!sx_init_CD186x(bp)) {
-                       /* Hmmm. This is dead code anyway. */
-               }
-
-               dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
-                       val1, val2, val3);
-
-       }
-
-#if 0
-       if (irqs <= 0) {
-               printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
-                      board_No(bp), bp->base);
-               sx_release_io_range(bp);
-               func_exit();
-               return 1;
-       }
-#endif
-       printk (KERN_INFO "Started with irq=%d, but now have irq=%d.\n", bp->irq, irqs);
-       if (irqs > 0)
-               bp->irq = irqs;
-#endif
        /* Reset CD186x again  */
        if (!sx_init_CD186x(bp)) {
                sx_release_io_range(bp);
@@ -560,7 +478,7 @@ static int sx_probe(struct specialix_board *bp)
        bp->flags |= SX_BOARD_PRESENT;
 
        /* Chip           revcode   pkgtype
-                         GFRCR     SRCR bit 7
+                         GFRCR     SRCR bit 7
           CD180 rev B    0x81      0
           CD180 rev C    0x82      0
           CD1864 rev A   0x82      1
@@ -570,24 +488,32 @@ static int sx_probe(struct specialix_board *bp)
         */
 
        switch (sx_in_off(bp, CD186x_GFRCR)) {
-       case 0x82:chip = 1864;rev='A';break;
-       case 0x83:chip = 1865;rev='A';break;
-       case 0x84:chip = 1865;rev='B';break;
-       case 0x85:chip = 1865;rev='C';break; /* Does not exist at this time */
-       default:chip=-1;rev='x';
+       case 0x82:
+               chip = 1864;
+               rev = 'A';
+               break;
+       case 0x83:
+               chip = 1865;
+               rev = 'A';
+               break;
+       case 0x84:
+               chip = 1865;
+               rev = 'B';
+               break;
+       case 0x85:
+               chip = 1865;
+               rev = 'C';
+               break; /* Does not exist at this time */
+       default:
+               chip = -1;
+               rev = 'x';
        }
 
-       dprintk (SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR) );
-
-#ifdef SPECIALIX_TIMER
-       setup_timer(&missed_irq_timer, missed_irq, (unsigned long)bp);
-       mod_timer(&missed_irq_timer, jiffies + sx_poll);
-#endif
+       dprintk(SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR));
 
-       printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
-              board_No(bp),
-              bp->base, bp->irq,
-              chip, rev);
+       printk(KERN_INFO
+    "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
+                               board_No(bp), bp->base, bp->irq, chip, rev);
 
        func_exit();
        return 0;
@@ -598,20 +524,22 @@ static int sx_probe(struct specialix_board *bp)
  *  Interrupt processing routines.
  * */
 
-static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
-                                              unsigned char const * what)
+static struct specialix_port *sx_get_port(struct specialix_board *bp,
+                                              unsigned char const *what)
 {
        unsigned char channel;
-       struct specialix_port * port = NULL;
+       struct specialix_port *port = NULL;
 
        channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
-       dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel);
+       dprintk(SX_DEBUG_CHAN, "channel: %d\n", channel);
        if (channel < CD186x_NCH) {
                port = &sx_port[board_No(bp) * SX_NPORT + channel];
-               dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n",board_No(bp) * SX_NPORT + channel,  port, port->port.flags & ASYNC_INITIALIZED);
+               dprintk(SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n",
+                       board_No(bp) * SX_NPORT + channel,  port,
+                       port->port.flags & ASYNC_INITIALIZED);
 
                if (port->port.flags & ASYNC_INITIALIZED) {
-                       dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
+                       dprintk(SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
                        func_exit();
                        return port;
                }
@@ -622,7 +550,7 @@ static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
 }
 
 
-static inline void sx_receive_exc(struct specialix_board * bp)
+static void sx_receive_exc(struct specialix_board *bp)
 {
        struct specialix_port *port;
        struct tty_struct *tty;
@@ -633,7 +561,7 @@ static inline void sx_receive_exc(struct specialix_board * bp)
 
        port = sx_get_port(bp, "Receive");
        if (!port) {
-               dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
+               dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
                func_exit();
                return;
        }
@@ -641,19 +569,21 @@ static inline void sx_receive_exc(struct specialix_board * bp)
 
        status = sx_in(bp, CD186x_RCSR);
 
-       dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
+       dprintk(SX_DEBUG_RX, "status: 0x%x\n", status);
        if (status & RCSR_OE) {
                port->overrun++;
-               dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Overrun. Total %ld overruns.\n",
-                      board_No(bp), port_No(port), port->overrun);
+               dprintk(SX_DEBUG_FIFO,
+                       "sx%d: port %d: Overrun. Total %ld overruns.\n",
+                               board_No(bp), port_No(port), port->overrun);
        }
        status &= port->mark_mask;
 
        /* This flip buffer check needs to be below the reading of the
           status register to reset the chip's IRQ.... */
        if (tty_buffer_request_room(tty, 1) == 0) {
-               dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
-                      board_No(bp), port_No(port));
+               dprintk(SX_DEBUG_FIFO,
+                   "sx%d: port %d: Working around flip buffer overflow.\n",
+                                       board_No(bp), port_No(port));
                func_exit();
                return;
        }
@@ -664,8 +594,9 @@ static inline void sx_receive_exc(struct specialix_board * bp)
                return;
        }
        if (status & RCSR_TOUT) {
-               printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
-                      board_No(bp), port_No(port));
+               printk(KERN_INFO
+                   "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
+                                       board_No(bp), port_No(port));
                func_exit();
                return;
 
@@ -688,13 +619,13 @@ static inline void sx_receive_exc(struct specialix_board * bp)
        else
                flag = TTY_NORMAL;
 
-       if(tty_insert_flip_char(tty, ch, flag))
+       if (tty_insert_flip_char(tty, ch, flag))
                tty_flip_buffer_push(tty);
        func_exit();
 }
 
 
-static inline void sx_receive(struct specialix_board * bp)
+static void sx_receive(struct specialix_board *bp)
 {
        struct specialix_port *port;
        struct tty_struct *tty;
@@ -702,15 +633,16 @@ static inline void sx_receive(struct specialix_board * bp)
 
        func_enter();
 
-       if (!(port = sx_get_port(bp, "Receive"))) {
-               dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
+       port = sx_get_port(bp, "Receive");
+       if (port == NULL) {
+               dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n");
                func_exit();
                return;
        }
        tty = port->port.tty;
 
        count = sx_in(bp, CD186x_RDCR);
-       dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
+       dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
        port->hits[count > 8 ? 9 : count]++;
 
        tty_buffer_request_room(tty, count);
@@ -722,18 +654,19 @@ static inline void sx_receive(struct specialix_board * bp)
 }
 
 
-static inline void sx_transmit(struct specialix_board * bp)
+static void sx_transmit(struct specialix_board *bp)
 {
        struct specialix_port *port;
        struct tty_struct *tty;
        unsigned char count;
 
        func_enter();
-       if (!(port = sx_get_port(bp, "Transmit"))) {
+       port = sx_get_port(bp, "Transmit");
+       if (port == NULL) {
                func_exit();
                return;
        }
-       dprintk (SX_DEBUG_TX, "port: %p\n", port);
+       dprintk(SX_DEBUG_TX, "port: %p\n", port);
        tty = port->port.tty;
 
        if (port->IER & IER_TXEMPTY) {
@@ -765,7 +698,8 @@ static inline void sx_transmit(struct specialix_board * bp)
                        sx_out(bp, CD186x_TDR, CD186x_C_ESC);
                        sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
                        sx_out(bp, CD186x_TDR, count);
-                       if (!(port->break_length -= count))
+                       port->break_length -= count;
+                       if (port->break_length == 0)
                                port->break_length--;
                } else {
                        sx_out(bp, CD186x_TDR, CD186x_C_ESC);
@@ -794,36 +728,36 @@ static inline void sx_transmit(struct specialix_board * bp)
                sx_out(bp, CD186x_IER, port->IER);
        }
        if (port->xmit_cnt <= port->wakeup_chars)
-               tty_wakeup(tty);
+               tty_wakeup(tty);
 
        func_exit();
 }
 
 
-static inline void sx_check_modem(struct specialix_board * bp)
+static void sx_check_modem(struct specialix_board *bp)
 {
        struct specialix_port *port;
        struct tty_struct *tty;
        unsigned char mcr;
        int msvr_cd;
 
-       dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
-       if (!(port = sx_get_port(bp, "Modem")))
+       dprintk(SX_DEBUG_SIGNALS, "Modem intr. ");
+       port = sx_get_port(bp, "Modem");
+       if (port == NULL)
                return;
 
        tty = port->port.tty;
 
        mcr = sx_in(bp, CD186x_MCR);
-       printk ("mcr = %02x.\n", mcr);
 
        if ((mcr & MCR_CDCHG)) {
-               dprintk (SX_DEBUG_SIGNALS, "CD just changed... ");
+               dprintk(SX_DEBUG_SIGNALS, "CD just changed... ");
                msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
                if (msvr_cd) {
-                       dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
+                       dprintk(SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
                        wake_up_interruptible(&port->port.open_wait);
                } else {
-                       dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n");
+                       dprintk(SX_DEBUG_SIGNALS, "Sending HUP.\n");
                        tty_hangup(tty);
                }
        }
@@ -874,9 +808,12 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id)
 
        spin_lock_irqsave(&bp->lock, flags);
 
-       dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
+       dprintk(SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__,
+               port_No(sx_get_port(bp, "INT")),
+               SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
        if (!(bp->flags & SX_BOARD_ACTIVE)) {
-               dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", bp->irq);
+               dprintk(SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n",
+                                                               bp->irq);
                spin_unlock_irqrestore(&bp->lock, flags);
                func_exit();
                return IRQ_NONE;
@@ -884,10 +821,11 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id)
 
        saved_reg = bp->reg;
 
-       while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
-                                          (SRSR_RREQint |
-                                           SRSR_TREQint |
-                                           SRSR_MREQint)))) {
+       while (++loop < 16) {
+               status = sx_in(bp, CD186x_SRSR) &
+                               (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint);
+               if (status == 0)
+                       break;
                if (status & SRSR_RREQint) {
                        ack = sx_in(bp, CD186x_RRAR);
 
@@ -896,8 +834,9 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id)
                        else if (ack == (SX_ID | GIVR_IT_REXC))
                                sx_receive_exc(bp);
                        else
-                               printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
-                                      board_No(bp), status, ack);
+                               printk(KERN_ERR
+                               "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
+                                               board_No(bp), status, ack);
 
                } else if (status & SRSR_TREQint) {
                        ack = sx_in(bp, CD186x_TRAR);
@@ -906,14 +845,16 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id)
                                sx_transmit(bp);
                        else
                                printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n",
-                                      board_No(bp), status, ack, port_No (sx_get_port (bp, "Int")));
+                                       board_No(bp), status, ack,
+                                       port_No(sx_get_port(bp, "Int")));
                } else if (status & SRSR_MREQint) {
                        ack = sx_in(bp, CD186x_MRAR);
 
                        if (ack == (SX_ID | GIVR_IT_MODEM))
                                sx_check_modem(bp);
                        else
-                               printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
+                               printk(KERN_ERR
+                                 "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
                                       board_No(bp), status, ack);
 
                }
@@ -921,7 +862,7 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id)
                sx_out(bp, CD186x_EOIR, 0);   /* Mark end of interrupt */
        }
        bp->reg = saved_reg;
-       outb (bp->reg, bp->base + SX_ADDR_REG);
+       outb(bp->reg, bp->base + SX_ADDR_REG);
        spin_unlock_irqrestore(&bp->lock, flags);
        func_exit();
        return IRQ_HANDLED;
@@ -932,36 +873,26 @@ static irqreturn_t sx_interrupt(int dummy, void *dev_id)
  *  Routines for open & close processing.
  */
 
-static void turn_ints_off (struct specialix_board *bp)
+static void turn_ints_off(struct specialix_board *bp)
 {
        unsigned long flags;
 
        func_enter();
-       if (bp->flags & SX_BOARD_IS_PCI) {
-               /* This was intended for enabeling the interrupt on the
-                * PCI card. However it seems that it's already enabled
-                * and as PCI interrupts can be shared, there is no real
-                * reason to have to turn it off. */
-       }
-
        spin_lock_irqsave(&bp->lock, flags);
-       (void) sx_in_off (bp, 0); /* Turn off interrupts. */
+       (void) sx_in_off(bp, 0); /* Turn off interrupts. */
        spin_unlock_irqrestore(&bp->lock, flags);
 
        func_exit();
 }
 
-static void turn_ints_on (struct specialix_board *bp)
+static void turn_ints_on(struct specialix_board *bp)
 {
        unsigned long flags;
 
        func_enter();
 
-       if (bp->flags & SX_BOARD_IS_PCI) {
-               /* play with the PCI chip. See comment above. */
-       }
        spin_lock_irqsave(&bp->lock, flags);
-       (void) sx_in (bp, 0); /* Turn ON interrupts. */
+       (void) sx_in(bp, 0); /* Turn ON interrupts. */
        spin_unlock_irqrestore(&bp->lock, flags);
 
        func_exit();
@@ -969,7 +900,7 @@ static void turn_ints_on (struct specialix_board *bp)
 
 
 /* Called with disabled interrupts */
-static inline int sx_setup_board(struct specialix_board * bp)
+static int sx_setup_board(struct specialix_board *bp)
 {
        int error;
 
@@ -977,14 +908,16 @@ static inline int sx_setup_board(struct specialix_board * bp)
                return 0;
 
        if (bp->flags & SX_BOARD_IS_PCI)
-               error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
+               error = request_irq(bp->irq, sx_interrupt,
+                       IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp);
        else
-               error = request_irq(bp->irq, sx_interrupt, IRQF_DISABLED, "specialix IO8+", bp);
+               error = request_irq(bp->irq, sx_interrupt,
+                       IRQF_DISABLED, "specialix IO8+", bp);
 
        if (error)
                return error;
 
-       turn_ints_on (bp);
+       turn_ints_on(bp);
        bp->flags |= SX_BOARD_ACTIVE;
 
        return 0;
@@ -992,7 +925,7 @@ static inline int sx_setup_board(struct specialix_board * bp)
 
 
 /* Called with disabled interrupts */
-static inline void sx_shutdown_board(struct specialix_board *bp)
+static void sx_shutdown_board(struct specialix_board *bp)
 {
        func_enter();
 
@@ -1003,22 +936,26 @@ static inline void sx_shutdown_board(struct specialix_board *bp)
 
        bp->flags &= ~SX_BOARD_ACTIVE;
 
-       dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
-                bp->irq, board_No (bp));
+       dprintk(SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
+                bp->irq, board_No(bp));
        free_irq(bp->irq, bp);
-
-       turn_ints_off (bp);
-
-
+       turn_ints_off(bp);
        func_exit();
 }
 
+static unsigned int sx_crtscts(struct tty_struct *tty)
+{
+       if (sx_rtscts)
+               return C_CRTSCTS(tty);
+       return 1;
+}
 
 /*
  * Setting up port characteristics.
  * Must be called with disabled interrupts
  */
-static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
+static void sx_change_speed(struct specialix_board *bp,
+                                               struct specialix_port *port)
 {
        struct tty_struct *tty;
        unsigned long baud;
@@ -1030,7 +967,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
 
        func_enter();
 
-       if (!(tty = port->port.tty) || !tty->termios) {
+       tty = port->port.tty;
+       if (!tty || !tty->termios) {
                func_exit();
                return;
        }
@@ -1043,12 +981,12 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
 
        /* The Specialix board doens't implement the RTS lines.
           They are used to set the IRQ level. Don't touch them. */
-       if (SX_CRTSCTS(tty))
+       if (sx_crtscts(tty))
                port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
        else
                port->MSVR =  (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
        spin_unlock_irqrestore(&bp->lock, flags);
-       dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
+       dprintk(SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
        baud = tty_get_baud_rate(tty);
 
        if (baud == 38400) {
@@ -1060,21 +998,19 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
 
        if (!baud) {
                /* Drop DTR & exit */
-               dprintk (SX_DEBUG_TERMIOS, "Dropping DTR...  Hmm....\n");
-               if (!SX_CRTSCTS (tty)) {
-                       port -> MSVR &= ~ MSVR_DTR;
+               dprintk(SX_DEBUG_TERMIOS, "Dropping DTR...  Hmm....\n");
+               if (!sx_crtscts(tty)) {
+                       port->MSVR &= ~MSVR_DTR;
                        spin_lock_irqsave(&bp->lock, flags);
-                       sx_out(bp, CD186x_MSVR, port->MSVR );
+                       sx_out(bp, CD186x_MSVR, port->MSVR);
                        spin_unlock_irqrestore(&bp->lock, flags);
-               }
-               else
-                       dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
+               } else
+                       dprintk(SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
                return;
        } else {
                /* Set DTR on */
-               if (!SX_CRTSCTS (tty)) {
-                       port ->MSVR |= MSVR_DTR;
-               }
+               if (!sx_crtscts(tty))
+                       port->MSVR |= MSVR_DTR;
        }
 
        /*
@@ -1083,28 +1019,27 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
 
        /* Set baud rate for port */
        tmp = port->custom_divisor ;
-       if ( tmp )
-               printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n"
-                                 "This is an untested option, please be carefull.\n",
-                                 port_No (port), tmp);
+       if (tmp)
+               printk(KERN_INFO
+                       "sx%d: Using custom baud rate divisor %ld. \n"
+                       "This is an untested option, please be careful.\n",
+                                                       port_No(port), tmp);
        else
-               tmp = (((SX_OSCFREQ + baud/2) / baud +
-                        CD186x_TPC/2) / CD186x_TPC);
+               tmp = (((SX_OSCFREQ + baud/2) / baud + CD186x_TPC/2) /
+                                                               CD186x_TPC);
 
-       if ((tmp < 0x10) && time_before(again, jiffies)) {
+       if (tmp < 0x10 && time_before(again, jiffies)) {
                again = jiffies + HZ * 60;
                /* Page 48 of version 2.0 of the CL-CD1865 databook */
                if (tmp >= 12) {
-                       printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
-                               "Performance degradation is possible.\n"
-                               "Read specialix.txt for more info.\n",
-                               port_No (port), tmp);
+                       printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
+                               "Performance degradation is possible.\n"
+                               "Read specialix.txt for more info.\n",
+                                               port_No(port), tmp);
                } else {
-                       printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
-                               "Warning: overstressing Cirrus chip. "
-                               "This might not work.\n"
-                               "Read specialix.txt for more info.\n",
-                               port_No (port), tmp);
+                       printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
+               "Warning: overstressing Cirrus chip. This might not work.\n"
+               "Read specialix.txt for more info.\n", port_No(port), tmp);
                }
        }
        spin_lock_irqsave(&bp->lock, flags);
@@ -1114,7 +1049,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
        sx_out(bp, CD186x_TBPRL, tmp & 0xff);
        spin_unlock_irqrestore(&bp->lock, flags);
        if (port->custom_divisor)
-               baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
+               baud = (SX_OSCFREQ + port->custom_divisor/2) /
+                                                       port->custom_divisor;
        baud = (baud + 5) / 10;         /* Estimated CPS */
 
        /* Two timer ticks seems enough to wakeup something like SLIP driver */
@@ -1129,16 +1065,16 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
        sx_out(bp, CD186x_RTPR, tmp);
        spin_unlock_irqrestore(&bp->lock, flags);
        switch (C_CSIZE(tty)) {
-        case CS5:
+       case CS5:
                cor1 |= COR1_5BITS;
                break;
-        case CS6:
+       case CS6:
                cor1 |= COR1_6BITS;
                break;
-        case CS7:
+       case CS7:
                cor1 |= COR1_7BITS;
                break;
-        case CS8:
+       case CS8:
                cor1 |= COR1_8BITS;
                break;
        }
@@ -1175,7 +1111,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
                mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
                mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
                spin_lock_irqsave(&bp->lock, flags);
-               tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
+               tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) &
+                                                       (MSVR_CTS|MSVR_DSR));
                spin_unlock_irqrestore(&bp->lock, flags);
 #else
                port->COR2 |= COR2_CTSAE;
@@ -1219,7 +1156,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
        spin_lock_irqsave(&bp->lock, flags);
        sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
        /* Setting up modem option registers */
-       dprintk (SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", mcor1, mcor2);
+       dprintk(SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n",
+                                                               mcor1, mcor2);
        sx_out(bp, CD186x_MCOR1, mcor1);
        sx_out(bp, CD186x_MCOR2, mcor2);
        spin_unlock_irqrestore(&bp->lock, flags);
@@ -1238,7 +1176,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
 
 
 /* Must be called with interrupts enabled */
-static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port)
+static int sx_setup_port(struct specialix_board *bp,
+                                               struct specialix_port *port)
 {
        unsigned long flags;
 
@@ -1253,7 +1192,8 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
                /* We may sleep in get_zeroed_page() */
                unsigned long tmp;
 
-               if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
+               tmp = get_zeroed_page(GFP_KERNEL);
+               if (tmp == 0L) {
                        func_exit();
                        return -ENOMEM;
                }
@@ -1284,7 +1224,8 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
 
 
 /* Must be called with interrupts disabled */
-static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port)
+static void sx_shutdown_port(struct specialix_board *bp,
+                                               struct specialix_port *port)
 {
        struct tty_struct *tty;
        int i;
@@ -1298,11 +1239,11 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
        }
 
        if (sx_debug & SX_DEBUG_FIFO) {
-               dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
-                       board_No(bp), port_No(port), port->overrun);
-               for (i = 0; i < 10; i++) {
+               dprintk(SX_DEBUG_FIFO,
+                       "sx%d: port %d: %ld overruns, FIFO hits [ ",
+                               board_No(bp), port_No(port), port->overrun);
+               for (i = 0; i < 10; i++)
                        dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]);
-               }
                dprintk(SX_DEBUG_FIFO, "].\n");
        }
 
@@ -1315,7 +1256,8 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
        spin_lock_irqsave(&bp->lock, flags);
        sx_out(bp, CD186x_CAR, port_No(port));
 
-       if (!(tty = port->port.tty) || C_HUPCL(tty)) {
+       tty = port->port.tty;
+       if (tty == NULL || C_HUPCL(tty)) {
                /* Drop DTR */
                sx_out(bp, CD186x_MSVDTR, 0);
        }
@@ -1338,8 +1280,8 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
 }
 
 
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
-                           struct specialix_port *port)
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
+                                               struct specialix_port *port)
 {
        DECLARE_WAITQUEUE(wait,  current);
        struct specialix_board *bp = port_Board(port);
@@ -1389,23 +1331,22 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
        retval = 0;
        add_wait_queue(&port->port.open_wait, &wait);
        spin_lock_irqsave(&port->lock, flags);
-       if (!tty_hung_up_p(filp)) {
+       if (!tty_hung_up_p(filp))
                port->port.count--;
-       }
        spin_unlock_irqrestore(&port->lock, flags);
        port->port.blocked_open++;
        while (1) {
                spin_lock_irqsave(&bp->lock, flags);
                sx_out(bp, CD186x_CAR, port_No(port));
                CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
-               if (SX_CRTSCTS (tty)) {
+               if (sx_crtscts(tty)) {
                        /* Activate RTS */
                        port->MSVR |= MSVR_DTR;         /* WTF? */
-                       sx_out (bp, CD186x_MSVR, port->MSVR);
+                       sx_out(bp, CD186x_MSVR, port->MSVR);
                } else {
                        /* Activate DTR */
                        port->MSVR |= MSVR_DTR;
-                       sx_out (bp, CD186x_MSVR, port->MSVR);
+                       sx_out(bp, CD186x_MSVR, port->MSVR);
                }
                spin_unlock_irqrestore(&bp->lock, flags);
                set_current_state(TASK_INTERRUPTIBLE);
@@ -1430,9 +1371,8 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
        set_current_state(TASK_RUNNING);
        remove_wait_queue(&port->port.open_wait, &wait);
        spin_lock_irqsave(&port->lock, flags);
-       if (!tty_hung_up_p(filp)) {
+       if (!tty_hung_up_p(filp))
                port->port.count++;
-       }
        port->port.blocked_open--;
        spin_unlock_irqrestore(&port->lock, flags);
        if (retval) {
@@ -1446,12 +1386,12 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
 }
 
 
-static int sx_open(struct tty_struct * tty, struct file * filp)
+static int sx_open(struct tty_struct *tty, struct file *filp)
 {
        int board;
        int error;
-       struct specialix_port * port;
-       struct specialix_board * bp;
+       struct specialix_port *port;
+       struct specialix_board *bp;
        int i;
        unsigned long flags;
 
@@ -1468,17 +1408,19 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
        port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
        port->overrun = 0;
        for (i = 0; i < 10; i++)
-               port->hits[i]=0;
+               port->hits[i] = 0;
 
-       dprintk (SX_DEBUG_OPEN, "Board = %d, bp = %p, port = %p, portno = %d.\n",
-               board, bp, port, SX_PORT(tty->index));
+       dprintk(SX_DEBUG_OPEN,
+                       "Board = %d, bp = %p, port = %p, portno = %d.\n",
+                                board, bp, port, SX_PORT(tty->index));
 
        if (sx_paranoia_check(port, tty->name, "sx_open")) {
                func_enter();
                return -ENODEV;
        }
 
-       if ((error = sx_setup_board(bp))) {
+       error = sx_setup_board(bp);
+       if (error) {
                func_exit();
                return error;
        }
@@ -1490,12 +1432,14 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
        port->port.tty = tty;
        spin_unlock_irqrestore(&bp->lock, flags);
 
-       if ((error = sx_setup_port(bp, port))) {
+       error = sx_setup_port(bp, port);
+       if (error) {
                func_enter();
                return error;
        }
 
-       if ((error = block_til_ready(tty, filp, port))) {
+       error = block_til_ready(tty, filp, port);
+       if (error) {
                func_enter();
                return error;
        }
@@ -1508,7 +1452,7 @@ static void sx_flush_buffer(struct tty_struct *tty)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        unsigned long flags;
-       struct specialix_board  * bp;
+       struct specialix_board  *bp;
 
        func_enter();
 
@@ -1526,9 +1470,9 @@ static void sx_flush_buffer(struct tty_struct *tty)
        func_exit();
 }
 
-static void sx_close(struct tty_struct * tty, struct file * filp)
+static void sx_close(struct tty_struct *tty, struct file *filp)
 {
-       struct specialix_port *port = (struct specialix_port *) tty->driver_data;
+       struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        struct specialix_board *bp;
        unsigned long flags;
        unsigned long timeout;
@@ -1547,7 +1491,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
        }
 
        bp = port_Board(port);
-       if ((tty->count == 1) && (port->port.count != 1)) {
+       if (tty->count == 1 && port->port.count != 1) {
                printk(KERN_ERR "sx%d: sx_close: bad port count;"
                       " tty->count is 1, port count is %d\n",
                       board_No(bp), port->port.count);
@@ -1570,17 +1514,16 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
         */
        tty->closing = 1;
        spin_unlock_irqrestore(&port->lock, flags);
-       dprintk (SX_DEBUG_OPEN, "Closing\n");
-       if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
+       dprintk(SX_DEBUG_OPEN, "Closing\n");
+       if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
                tty_wait_until_sent(tty, port->port.closing_wait);
-       }
        /*
         * At this point we stop accepting input.  To do this, we
         * disable the receive line status interrupts, and tell the
         * interrupt driver to stop checking the data ready bit in the
         * line status register.
         */
-       dprintk (SX_DEBUG_OPEN, "Closed\n");
+       dprintk(SX_DEBUG_OPEN, "Closed\n");
        port->IER &= ~IER_RXD;
        if (port->port.flags & ASYNC_INITIALIZED) {
                port->IER &= ~IER_TXRDY;
@@ -1595,11 +1538,11 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
                 * important if there is a transmit FIFO!
                 */
                timeout = jiffies+HZ;
-               while(port->IER & IER_TXEMPTY) {
-                       set_current_state (TASK_INTERRUPTIBLE);
+               while (port->IER & IER_TXEMPTY) {
+                       set_current_state(TASK_INTERRUPTIBLE);
                        msleep_interruptible(jiffies_to_msecs(port->timeout));
                        if (time_after(jiffies, timeout)) {
-                               printk (KERN_INFO "Timeout waiting for close\n");
+                               printk(KERN_INFO "Timeout waiting for close\n");
                                break;
                        }
                }
@@ -1607,13 +1550,15 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
        }
 
        if (--bp->count < 0) {
-               printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
-                      board_No(bp), bp->count, tty->index);
+               printk(KERN_ERR
+                   "sx%d: sx_shutdown_port: bad board count: %d port: %d\n",
+                               board_No(bp), bp->count, tty->index);
                bp->count = 0;
        }
        if (--port->port.count < 0) {
-               printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
-                      board_No(bp), port_No(port), port->port.count);
+               printk(KERN_ERR
+                       "sx%d: sx_close: bad port count for tty%d: %d\n",
+                               board_No(bp), port_No(port), port->port.count);
                port->port.count = 0;
        }
 
@@ -1625,9 +1570,9 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
        port->port.tty = NULL;
        spin_unlock_irqrestore(&port->lock, flags);
        if (port->port.blocked_open) {
-               if (port->port.close_delay) {
-                       msleep_interruptible(jiffies_to_msecs(port->port.close_delay));
-               }
+               if (port->port.close_delay)
+                       msleep_interruptible(
+                               jiffies_to_msecs(port->port.close_delay));
                wake_up_interruptible(&port->port.open_wait);
        }
        port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
@@ -1637,8 +1582,8 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
 }
 
 
-static int sx_write(struct tty_struct * tty,
-                    const unsigned char *buf, int count)
+static int sx_write(struct tty_struct *tty,
+                                       const unsigned char *buf, int count)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        struct specialix_board *bp;
@@ -1690,11 +1635,11 @@ static int sx_write(struct tty_struct * tty,
 }
 
 
-static int sx_put_char(struct tty_struct * tty, unsigned char ch)
+static int sx_put_char(struct tty_struct *tty, unsigned char ch)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        unsigned long flags;
-       struct specialix_board  * bp;
+       struct specialix_board  *bp;
 
        func_enter();
 
@@ -1702,7 +1647,7 @@ static int sx_put_char(struct tty_struct * tty, unsigned char ch)
                func_exit();
                return 0;
        }
-       dprintk (SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
+       dprintk(SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf);
        if (!port->xmit_buf) {
                func_exit();
                return 0;
@@ -1710,14 +1655,15 @@ static int sx_put_char(struct tty_struct * tty, unsigned char ch)
        bp = port_Board(port);
        spin_lock_irqsave(&port->lock, flags);
 
-       dprintk (SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", port->xmit_cnt, port->xmit_buf);
-       if ((port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) || (!port->xmit_buf)) {
+       dprintk(SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n",
+                                       port->xmit_cnt, port->xmit_buf);
+       if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1 || !port->xmit_buf) {
                spin_unlock_irqrestore(&port->lock, flags);
-               dprintk (SX_DEBUG_TX, "Exit size\n");
+               dprintk(SX_DEBUG_TX, "Exit size\n");
                func_exit();
                return 0;
        }
-       dprintk (SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
+       dprintk(SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf);
        port->xmit_buf[port->xmit_head++] = ch;
        port->xmit_head &= SERIAL_XMIT_SIZE - 1;
        port->xmit_cnt++;
@@ -1728,11 +1674,11 @@ static int sx_put_char(struct tty_struct * tty, unsigned char ch)
 }
 
 
-static void sx_flush_chars(struct tty_struct * tty)
+static void sx_flush_chars(struct tty_struct *tty)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        unsigned long flags;
-       struct specialix_board  * bp = port_Board(port);
+       struct specialix_board  *bp = port_Board(port);
 
        func_enter();
 
@@ -1755,7 +1701,7 @@ static void sx_flush_chars(struct tty_struct * tty)
 }
 
 
-static int sx_write_room(struct tty_struct * tty)
+static int sx_write_room(struct tty_struct *tty)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        int     ret;
@@ -1790,12 +1736,10 @@ static int sx_chars_in_buffer(struct tty_struct *tty)
        return port->xmit_cnt;
 }
 
-
-
 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
-       struct specialix_board * bp;
+       struct specialix_board *bp;
        unsigned char status;
        unsigned int result;
        unsigned long flags;
@@ -1808,25 +1752,23 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file)
        }
 
        bp = port_Board(port);
-       spin_lock_irqsave (&bp->lock, flags);
+       spin_lock_irqsave(&bp->lock, flags);
        sx_out(bp, CD186x_CAR, port_No(port));
        status = sx_in(bp, CD186x_MSVR);
        spin_unlock_irqrestore(&bp->lock, flags);
-       dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
-               port_No(port), status, sx_in (bp, CD186x_CAR));
-       dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
-       if (SX_CRTSCTS(port->port.tty)) {
-               result  = /*   (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
-                         |   ((status & MSVR_DTR) ? TIOCM_RTS : 0)
-                         |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
-                         |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
-                         |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
+       dprintk(SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
+                       port_No(port), status, sx_in(bp, CD186x_CAR));
+       dprintk(SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
+       if (sx_crtscts(port->port.tty)) {
+               result  = TIOCM_DTR | TIOCM_DSR
+                         |   ((status & MSVR_DTR) ? TIOCM_RTS : 0)
+                         |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
+                         |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
        } else {
-               result  = /*   (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
-                         |   ((status & MSVR_DTR) ? TIOCM_DTR : 0)
-                         |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
-                         |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
-                         |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
+               result  = TIOCM_RTS | TIOCM_DSR
+                         |   ((status & MSVR_DTR) ? TIOCM_DTR : 0)
+                         |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
+                         |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
        }
 
        func_exit();
@@ -1852,24 +1794,14 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file,
        bp = port_Board(port);
 
        spin_lock_irqsave(&port->lock, flags);
-   /*  if (set & TIOCM_RTS)
-               port->MSVR |= MSVR_RTS; */
-   /*   if (set & TIOCM_DTR)
-               port->MSVR |= MSVR_DTR; */
-
-       if (SX_CRTSCTS(port->port.tty)) {
+       if (sx_crtscts(port->port.tty)) {
                if (set & TIOCM_RTS)
                        port->MSVR |= MSVR_DTR;
        } else {
                if (set & TIOCM_DTR)
                        port->MSVR |= MSVR_DTR;
        }
-
-  /*   if (clear & TIOCM_RTS)
-               port->MSVR &= ~MSVR_RTS; */
-  /*    if (clear & TIOCM_DTR)
-               port->MSVR &= ~MSVR_DTR; */
-       if (SX_CRTSCTS(port->port.tty)) {
+       if (sx_crtscts(port->port.tty)) {
                if (clear & TIOCM_RTS)
                        port->MSVR &= ~MSVR_DTR;
        } else {
@@ -1886,14 +1818,17 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file,
 }
 
 
-static inline void sx_send_break(struct specialix_port * port, unsigned long length)
+static int sx_send_break(struct tty_struct *tty, int length)
 {
+       struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        struct specialix_board *bp = port_Board(port);
        unsigned long flags;
 
        func_enter();
+       if (length == 0 || length == -1)
+               return -EOPNOTSUPP;
 
-       spin_lock_irqsave (&port->lock, flags);
+       spin_lock_irqsave(&port->lock, flags);
        port->break_length = SPECIALIX_TPS / HZ * length;
        port->COR2 |= COR2_ETC;
        port->IER  |= IER_TXRDY;
@@ -1902,7 +1837,7 @@ static inline void sx_send_break(struct specialix_port * port, unsigned long len
        sx_out(bp, CD186x_COR2, port->COR2);
        sx_out(bp, CD186x_IER, port->IER);
        spin_unlock_irqrestore(&bp->lock, flags);
-       spin_unlock_irqrestore (&port->lock, flags);
+       spin_unlock_irqrestore(&port->lock, flags);
        sx_wait_CCR(bp);
        spin_lock_irqsave(&bp->lock, flags);
        sx_out(bp, CD186x_CCR, CCR_CORCHG2);
@@ -1910,11 +1845,12 @@ static inline void sx_send_break(struct specialix_port * port, unsigned long len
        sx_wait_CCR(bp);
 
        func_exit();
+       return 0;
 }
 
 
-static inline int sx_set_serial_info(struct specialix_port * port,
-                                     struct serial_struct __user * newinfo)
+static int sx_set_serial_info(struct specialix_port *port,
+                                       struct serial_struct __user *newinfo)
 {
        struct serial_struct tmp;
        struct specialix_board *bp = port_Board(port);
@@ -1943,25 +1879,25 @@ static inline int sx_set_serial_info(struct specialix_port * port,
                        return -EPERM;
                }
                port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
-                                 (tmp.flags & ASYNC_USR_MASK));
+                                               (tmp.flags & ASYNC_USR_MASK));
                port->custom_divisor = tmp.custom_divisor;
        } else {
                port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
-                                 (tmp.flags & ASYNC_FLAGS));
+                                               (tmp.flags & ASYNC_FLAGS));
                port->port.close_delay = tmp.close_delay;
                port->port.closing_wait = tmp.closing_wait;
                port->custom_divisor = tmp.custom_divisor;
        }
-       if (change_speed) {
+       if (change_speed)
                sx_change_speed(bp, port);
-       }
+
        func_exit();
        unlock_kernel();
        return 0;
 }
 
 
-static inline int sx_get_serial_info(struct specialix_port * port,
+static int sx_get_serial_info(struct specialix_port *port,
                                     struct serial_struct __user *retinfo)
 {
        struct serial_struct tmp;
@@ -1992,11 +1928,10 @@ static inline int sx_get_serial_info(struct specialix_port * port,
 }
 
 
-static int sx_ioctl(struct tty_struct * tty, struct file * filp,
-                    unsigned int cmd, unsigned long arg)
+static int sx_ioctl(struct tty_struct *tty, struct file *filp,
+                               unsigned int cmd, unsigned long arg)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
-       int retval;
        void __user *argp = (void __user *)arg;
 
        func_enter();
@@ -2007,34 +1942,14 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
        }
 
        switch (cmd) {
-        case TCSBRK:   /* SVID version: non-zero arg --> no break */
-               retval = tty_check_change(tty);
-               if (retval) {
-                       func_exit();
-                       return retval;
-               }
-               tty_wait_until_sent(tty, 0);
-               if (!arg)
-                       sx_send_break(port, HZ/4);      /* 1/4 second */
-               return 0;
-        case TCSBRKP:  /* support for POSIX tcsendbreak() */
-               retval = tty_check_change(tty);
-               if (retval) {
-                       func_exit();
-                       return retval;
-               }
-               tty_wait_until_sent(tty, 0);
-               sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
+       case TIOCGSERIAL:
                func_exit();
-               return 0;
-        case TIOCGSERIAL:
-                func_exit();
                return sx_get_serial_info(port, argp);
-        case TIOCSSERIAL:
-                func_exit();
+       case TIOCSSERIAL:
+               func_exit();
                return sx_set_serial_info(port, argp);
-        default:
-                func_exit();
+       default:
+               func_exit();
                return -ENOIOCTLCMD;
        }
        func_exit();
@@ -2042,7 +1957,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
 }
 
 
-static void sx_throttle(struct tty_struct * tty)
+static void sx_throttle(struct tty_struct *tty)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        struct specialix_board *bp;
@@ -2058,15 +1973,16 @@ static void sx_throttle(struct tty_struct * tty)
        bp = port_Board(port);
 
        /* Use DTR instead of RTS ! */
-       if (SX_CRTSCTS (tty))
+       if (sx_crtscts(tty))
                port->MSVR &= ~MSVR_DTR;
        else {
                /* Auch!!! I think the system shouldn't call this then. */
                /* Or maybe we're supposed (allowed?) to do our side of hw
                   handshake anyway, even when hardware handshake is off.
                   When you see this in your logs, please report.... */
-               printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
-                        port_No (port));
+               printk(KERN_ERR
+                  "sx%d: Need to throttle, but can't (hardware hs is off)\n",
+                                                       port_No(port));
        }
        spin_lock_irqsave(&bp->lock, flags);
        sx_out(bp, CD186x_CAR, port_No(port));
@@ -2086,7 +2002,7 @@ static void sx_throttle(struct tty_struct * tty)
 }
 
 
-static void sx_unthrottle(struct tty_struct * tty)
+static void sx_unthrottle(struct tty_struct *tty)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        struct specialix_board *bp;
@@ -2103,9 +2019,9 @@ static void sx_unthrottle(struct tty_struct * tty)
 
        spin_lock_irqsave(&port->lock, flags);
        /* XXXX Use DTR INSTEAD???? */
-       if (SX_CRTSCTS(tty)) {
+       if (sx_crtscts(tty))
                port->MSVR |= MSVR_DTR;
-       /* Else clause: see remark in "sx_throttle"... */
+       /* Else clause: see remark in "sx_throttle"... */
        spin_lock_irqsave(&bp->lock, flags);
        sx_out(bp, CD186x_CAR, port_No(port));
        spin_unlock_irqrestore(&bp->lock, flags);
@@ -2127,7 +2043,7 @@ static void sx_unthrottle(struct tty_struct * tty)
 }
 
 
-static void sx_stop(struct tty_struct * tty)
+static void sx_stop(struct tty_struct *tty)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        struct specialix_board *bp;
@@ -2154,7 +2070,7 @@ static void sx_stop(struct tty_struct * tty)
 }
 
 
-static void sx_start(struct tty_struct * tty)
+static void sx_start(struct tty_struct *tty)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        struct specialix_board *bp;
@@ -2182,7 +2098,7 @@ static void sx_start(struct tty_struct * tty)
        func_exit();
 }
 
-static void sx_hangup(struct tty_struct * tty)
+static void sx_hangup(struct tty_struct *tty)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        struct specialix_board *bp;
@@ -2201,8 +2117,9 @@ static void sx_hangup(struct tty_struct * tty)
        spin_lock_irqsave(&port->lock, flags);
        bp->count -= port->port.count;
        if (bp->count < 0) {
-               printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
-                       board_No(bp), bp->count, tty->index);
+               printk(KERN_ERR
+                       "sx%d: sx_hangup: bad board count: %d port: %d\n",
+                                       board_No(bp), bp->count, tty->index);
                bp->count = 0;
        }
        port->port.count = 0;
@@ -2215,11 +2132,12 @@ static void sx_hangup(struct tty_struct * tty)
 }
 
 
-static void sx_set_termios(struct tty_struct * tty, struct ktermios * old_termios)
+static void sx_set_termios(struct tty_struct *tty,
+                                       struct ktermios *old_termios)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        unsigned long flags;
-       struct specialix_board  * bp;
+       struct specialix_board  *bp;
 
        if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
                return;
@@ -2254,6 +2172,7 @@ static const struct tty_operations sx_ops = {
        .hangup = sx_hangup,
        .tiocmget = sx_tiocmget,
        .tiocmset = sx_tiocmset,
+       .break_ctl = sx_send_break,
 };
 
 static int sx_init_drivers(void)
@@ -2280,13 +2199,16 @@ static int sx_init_drivers(void)
                B9600 | CS8 | CREAD | HUPCL | CLOCAL;
        specialix_driver->init_termios.c_ispeed = 9600;
        specialix_driver->init_termios.c_ospeed = 9600;
-       specialix_driver->flags = TTY_DRIVER_REAL_RAW;
+       specialix_driver->flags = TTY_DRIVER_REAL_RAW |
+                                               TTY_DRIVER_HARDWARE_BREAK;
        tty_set_operations(specialix_driver, &sx_ops);
 
-       if ((error = tty_register_driver(specialix_driver))) {
+       error = tty_register_driver(specialix_driver);
+       if (error) {
                put_tty_driver(specialix_driver);
-               printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %d\n",
-                      error);
+               printk(KERN_ERR
+                 "sx: Couldn't register specialix IO8+ driver, error = %d\n",
+                                                               error);
                func_exit();
                return 1;
        }
@@ -2322,11 +2244,11 @@ static int __init specialix_init(void)
 
        printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n");
        printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n");
-#ifdef CONFIG_SPECIALIX_RTSCTS
-       printk (KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
-#else
-       printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
-#endif
+       if (sx_rtscts)
+               printk(KERN_INFO
+                       "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
+       else
+               printk(KERN_INFO "sx: DTR/RTS pin is always RTS.\n");
 
        for (i = 0; i < SX_NBOARD; i++)
                spin_lock_init(&sx_board[i].lock);
@@ -2344,27 +2266,27 @@ static int __init specialix_init(void)
        {
                struct pci_dev *pdev = NULL;
 
-               i=0;
+               i = 0;
                while (i < SX_NBOARD) {
                        if (sx_board[i].flags & SX_BOARD_PRESENT) {
                                i++;
                                continue;
                        }
-                       pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,
-                                               PCI_DEVICE_ID_SPECIALIX_IO8,
-                                               pdev);
-                       if (!pdev) break;
+                       pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX,
+                                       PCI_DEVICE_ID_SPECIALIX_IO8, pdev);
+                       if (!pdev)
+                               break;
 
                        if (pci_enable_device(pdev))
                                continue;
 
                        sx_board[i].irq = pdev->irq;
 
-                       sx_board[i].base = pci_resource_start (pdev, 2);
+                       sx_board[i].base = pci_resource_start(pdev, 2);
 
                        sx_board[i].flags |= SX_BOARD_IS_PCI;
                        if (!sx_probe(&sx_board[i]))
-                               found ++;
+                               found++;
                }
                /* May exit pci_get sequence early with lots of boards */
                if (pdev != NULL)
@@ -2384,16 +2306,13 @@ static int __init specialix_init(void)
 }
 
 static int iobase[SX_NBOARD]  = {0,};
-
-static int irq [SX_NBOARD] = {0,};
+static int irq[SX_NBOARD] = {0,};
 
 module_param_array(iobase, int, NULL, 0);
 module_param_array(irq, int, NULL, 0);
 module_param(sx_debug, int, 0);
+module_param(sx_rtscts, int, 0);
 module_param(sx_rxfifo, int, 0);
-#ifdef SPECIALIX_TIMER
-module_param(sx_poll, int, 0);
-#endif
 
 /*
  * You can setup up to 4 boards.
@@ -2411,10 +2330,10 @@ static int __init specialix_init_module(void)
        func_enter();
 
        if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
-               for(i = 0; i < SX_NBOARD; i++) {
+               for (i = 0; i < SX_NBOARD; i++) {
                        sx_board[i].base = iobase[i];
                        sx_board[i].irq = irq[i];
-                       sx_board[i].count= 0;
+                       sx_board[i].count = 0;
                }
        }
 
@@ -2433,10 +2352,6 @@ static void __exit specialix_exit_module(void)
        for (i = 0; i < SX_NBOARD; i++)
                if (sx_board[i].flags & SX_BOARD_PRESENT)
                        sx_release_io_range(&sx_board[i]);
-#ifdef SPECIALIX_TIMER
-       del_timer_sync(&missed_irq_timer);
-#endif
-
        func_exit();
 }
 
index 0243efb0be957df493937e1fbfb5ad44b215d486..b976248e10727dd7f8e8610dc02da65efa064828 100644 (file)
@@ -1025,7 +1025,7 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count
 
 /*****************************************************************************/
 
-static void stl_putchar(struct tty_struct *tty, unsigned char ch)
+static int stl_putchar(struct tty_struct *tty, unsigned char ch)
 {
        struct stlport  *portp;
        unsigned int    len;
@@ -1034,12 +1034,12 @@ static void stl_putchar(struct tty_struct *tty, unsigned char ch)
        pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch);
 
        if (tty == NULL)
-               return;
+               return -EINVAL;
        portp = tty->driver_data;
        if (portp == NULL)
-               return;
+               return -EINVAL;
        if (portp->tx.buf == NULL)
-               return;
+               return -EINVAL;
 
        head = portp->tx.head;
        tail = portp->tx.tail;
@@ -1053,6 +1053,7 @@ static void stl_putchar(struct tty_struct *tty, unsigned char ch)
                        head = portp->tx.buf;
        }       
        portp->tx.head = head;
+       return 0;
 }
 
 /*****************************************************************************/
@@ -1460,19 +1461,20 @@ static void stl_hangup(struct tty_struct *tty)
 
 /*****************************************************************************/
 
-static void stl_breakctl(struct tty_struct *tty, int state)
+static int stl_breakctl(struct tty_struct *tty, int state)
 {
        struct stlport  *portp;
 
        pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state);
 
        if (tty == NULL)
-               return;
+               return -EINVAL;
        portp = tty->driver_data;
        if (portp == NULL)
-               return;
+               return -EINVAL;
 
        stl_sendbreak(portp, ((state == -1) ? 1 : 2));
+       return 0;
 }
 
 /*****************************************************************************/
@@ -4753,8 +4755,8 @@ static int __init stallion_module_init(void)
        if (IS_ERR(stallion_class))
                printk("STALLION: failed to create class\n");
        for (i = 0; i < 4; i++)
-               device_create(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
-                             "staliomem%d", i);
+               device_create_drvdata(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
+                                     NULL, "staliomem%d", i);
 
        return 0;
 err_unrtty:
index d5cffcd6a572d47330dbfe295547d33af44e1f38..2162439bbe487544c589c6f0c054e6d849257a94 100644 (file)
@@ -1840,7 +1840,7 @@ static int sx_fw_ioctl(struct inode *inode, struct file *filp,
        return rc;
 }
 
-static void sx_break(struct tty_struct *tty, int flag)
+static int sx_break(struct tty_struct *tty, int flag)
 {
        struct sx_port *port = tty->driver_data;
        int rv;
@@ -1857,6 +1857,7 @@ static void sx_break(struct tty_struct *tty, int flag)
                        read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat)));
        unlock_kernel();
        func_exit();
+       return 0;
 }
 
 static int sx_tiocmget(struct tty_struct *tty, struct file *file)
index 527d220aa4aacab7bf3f78cb9687750b8bf74940..ef6706f09061ebcc056667b37d94f974f96917fb 100644 (file)
@@ -2897,9 +2897,9 @@ static int tiocmset(struct tty_struct *tty, struct file *file,
  *
  * Arguments:          tty             pointer to tty instance data
  *                     break_state     -1=set break condition, 0=clear
- * Return Value:       None
+ * Return Value:       error code
  */
-static void mgsl_break(struct tty_struct *tty, int break_state)
+static int mgsl_break(struct tty_struct *tty, int break_state)
 {
        struct mgsl_struct * info = (struct mgsl_struct *)tty->driver_data;
        unsigned long flags;
@@ -2909,7 +2909,7 @@ static void mgsl_break(struct tty_struct *tty, int break_state)
                         __FILE__,__LINE__, info->device_name, break_state);
                         
        if (mgsl_paranoia_check(info, tty->name, "mgsl_break"))
-               return;
+               return -EINVAL;
 
        spin_lock_irqsave(&info->irq_spinlock,flags);
        if (break_state == -1)
@@ -2917,6 +2917,7 @@ static void mgsl_break(struct tty_struct *tty, int break_state)
        else 
                usc_OutReg(info,IOCR,(u16)(usc_InReg(info,IOCR) & ~BIT7));
        spin_unlock_irqrestore(&info->irq_spinlock,flags);
+       return 0;
        
 }      /* end of mgsl_break() */
 
index 2c3e43bb2cc933184ea94cc6abd04a1b82c6b312..3e9058993e41805c0b2cd699ad836c76844fe398 100644 (file)
@@ -165,7 +165,7 @@ static int  read_proc(char *page, char **start, off_t off, int count,int *eof, v
 static int  chars_in_buffer(struct tty_struct *tty);
 static void throttle(struct tty_struct * tty);
 static void unthrottle(struct tty_struct * tty);
-static void set_break(struct tty_struct *tty, int break_state);
+static int set_break(struct tty_struct *tty, int break_state);
 
 /*
  * generic HDLC support and callbacks
@@ -214,6 +214,7 @@ struct slgt_desc
        char *buf;          /* virtual  address of data buffer */
        unsigned int pdesc; /* physical address of this descriptor */
        dma_addr_t buf_dma_addr;
+       unsigned short buf_count;
 };
 
 #define set_desc_buffer(a,b) (a).pbuf = cpu_to_le32((unsigned int)(b))
@@ -302,7 +303,7 @@ struct slgt_info {
        u32 idle_mode;
        u32 max_frame_size;       /* as set by device config */
 
-       unsigned int raw_rx_size;
+       unsigned int rbuf_fill_level;
        unsigned int if_mode;
 
        /* device status */
@@ -466,6 +467,7 @@ static void tx_start(struct slgt_info *info);
 static void tx_stop(struct slgt_info *info);
 static void tx_set_idle(struct slgt_info *info);
 static unsigned int free_tbuf_count(struct slgt_info *info);
+static unsigned int tbuf_bytes(struct slgt_info *info);
 static void reset_tbufs(struct slgt_info *info);
 static void tdma_reset(struct slgt_info *info);
 static void tdma_start(struct slgt_info *info);
@@ -513,7 +515,7 @@ static int  wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr);
 static int  tiocmget(struct tty_struct *tty, struct file *file);
 static int  tiocmset(struct tty_struct *tty, struct file *file,
                     unsigned int set, unsigned int clear);
-static void set_break(struct tty_struct *tty, int break_state);
+static int set_break(struct tty_struct *tty, int break_state);
 static int  get_interface(struct slgt_info *info, int __user *if_mode);
 static int  set_interface(struct slgt_info *info, int if_mode);
 static int  set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
@@ -849,6 +851,7 @@ static int write(struct tty_struct *tty,
        int ret = 0;
        struct slgt_info *info = tty->driver_data;
        unsigned long flags;
+       unsigned int bufs_needed;
 
        if (sanity_check(info, tty->name, "write"))
                goto cleanup;
@@ -865,25 +868,16 @@ static int write(struct tty_struct *tty,
        if (!count)
                goto cleanup;
 
-       if (info->params.mode == MGSL_MODE_RAW ||
-           info->params.mode == MGSL_MODE_MONOSYNC ||
-           info->params.mode == MGSL_MODE_BISYNC) {
-               unsigned int bufs_needed = (count/DMABUFSIZE);
-               unsigned int bufs_free = free_tbuf_count(info);
-               if (count % DMABUFSIZE)
-                       ++bufs_needed;
-               if (bufs_needed > bufs_free)
-                       goto cleanup;
-       } else {
-               if (info->tx_active)
-                       goto cleanup;
-               if (info->tx_count) {
-                       /* send accumulated data from send_char() calls */
-                       /* as frame and wait before accepting more data. */
-                       tx_load(info, info->tx_buf, info->tx_count);
-                       goto start;
-               }
+       if (!info->tx_active && info->tx_count) {
+               /* send accumulated data from send_char() */
+               tx_load(info, info->tx_buf, info->tx_count);
+               goto start;
        }
+       bufs_needed = (count/DMABUFSIZE);
+       if (count % DMABUFSIZE)
+               ++bufs_needed;
+       if (bufs_needed > free_tbuf_count(info))
+               goto cleanup;
 
        ret = info->tx_count = count;
        tx_load(info, buf, count);
@@ -1396,10 +1390,12 @@ done:
 static int chars_in_buffer(struct tty_struct *tty)
 {
        struct slgt_info *info = tty->driver_data;
+       int count;
        if (sanity_check(info, tty->name, "chars_in_buffer"))
                return 0;
-       DBGINFO(("%s chars_in_buffer()=%d\n", info->device_name, info->tx_count));
-       return info->tx_count;
+       count = tbuf_bytes(info);
+       DBGINFO(("%s chars_in_buffer()=%d\n", info->device_name, count));
+       return count;
 }
 
 /*
@@ -1452,14 +1448,14 @@ static void unthrottle(struct tty_struct * tty)
  * set or clear transmit break condition
  * break_state -1=set break condition, 0=clear
  */
-static void set_break(struct tty_struct *tty, int break_state)
+static int set_break(struct tty_struct *tty, int break_state)
 {
        struct slgt_info *info = tty->driver_data;
        unsigned short value;
        unsigned long flags;
 
        if (sanity_check(info, tty->name, "set_break"))
-               return;
+               return -EINVAL;
        DBGINFO(("%s set_break(%d)\n", info->device_name, break_state));
 
        spin_lock_irqsave(&info->lock,flags);
@@ -1470,6 +1466,7 @@ static void set_break(struct tty_struct *tty, int break_state)
                value &= ~BIT6;
        wr_reg16(info, TCR, value);
        spin_unlock_irqrestore(&info->lock,flags);
+       return 0;
 }
 
 #if SYNCLINK_GENERIC_HDLC
@@ -2679,8 +2676,31 @@ static int tx_abort(struct slgt_info *info)
 static int rx_enable(struct slgt_info *info, int enable)
 {
        unsigned long flags;
-       DBGINFO(("%s rx_enable(%d)\n", info->device_name, enable));
+       unsigned int rbuf_fill_level;
+       DBGINFO(("%s rx_enable(%08x)\n", info->device_name, enable));
        spin_lock_irqsave(&info->lock,flags);
+       /*
+        * enable[31..16] = receive DMA buffer fill level
+        * 0 = noop (leave fill level unchanged)
+        * fill level must be multiple of 4 and <= buffer size
+        */
+       rbuf_fill_level = ((unsigned int)enable) >> 16;
+       if (rbuf_fill_level) {
+               if ((rbuf_fill_level > DMABUFSIZE) || (rbuf_fill_level % 4)) {
+                       spin_unlock_irqrestore(&info->lock, flags);
+                       return -EINVAL;
+               }
+               info->rbuf_fill_level = rbuf_fill_level;
+               rx_stop(info); /* restart receiver to use new fill level */
+       }
+
+       /*
+        * enable[1..0] = receiver enable command
+        * 0 = disable
+        * 1 = enable
+        * 2 = enable or force hunt mode if already enabled
+        */
+       enable &= 3;
        if (enable) {
                if (!info->rx_enabled)
                        rx_start(info);
@@ -3447,7 +3467,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
                info->magic = MGSL_MAGIC;
                INIT_WORK(&info->task, bh_handler);
                info->max_frame_size = 4096;
-               info->raw_rx_size = DMABUFSIZE;
+               info->rbuf_fill_level = DMABUFSIZE;
                info->port.close_delay = 5*HZ/10;
                info->port.closing_wait = 30*HZ;
                init_waitqueue_head(&info->status_event_wait_q);
@@ -3934,15 +3954,7 @@ static void tdma_start(struct slgt_info *info)
 
        /* set 1st descriptor address */
        wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
-       switch(info->params.mode) {
-       case MGSL_MODE_RAW:
-       case MGSL_MODE_MONOSYNC:
-       case MGSL_MODE_BISYNC:
-               wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
-               break;
-       default:
-               wr_reg32(info, TDCSR, BIT0); /* DMA enable */
-       }
+       wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
 }
 
 static void tx_stop(struct slgt_info *info)
@@ -4145,7 +4157,7 @@ static void sync_mode(struct slgt_info *info)
         * 01      enable
         * 00      auto-CTS enable
         */
-       val = 0;
+       val = BIT2;
 
        switch(info->params.mode) {
        case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;
@@ -4418,6 +4430,8 @@ static void msc_set_vcr(struct slgt_info *info)
                break;
        }
 
+       if (info->if_mode & MGSL_INTERFACE_MSB_FIRST)
+               val |= BIT4;
        if (info->signals & SerialSignal_DTR)
                val |= BIT3;
        if (info->signals & SerialSignal_RTS)
@@ -4456,16 +4470,7 @@ static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last
        while(!done) {
                /* reset current buffer for reuse */
                info->rbufs[i].status = 0;
-               switch(info->params.mode) {
-               case MGSL_MODE_RAW:
-               case MGSL_MODE_MONOSYNC:
-               case MGSL_MODE_BISYNC:
-                       set_desc_count(info->rbufs[i], info->raw_rx_size);
-                       break;
-               default:
-                       set_desc_count(info->rbufs[i], DMABUFSIZE);
-               }
-
+               set_desc_count(info->rbufs[i], info->rbuf_fill_level);
                if (i == last)
                        done = 1;
                if (++i == info->rbuf_count)
@@ -4572,7 +4577,7 @@ check_again:
 
        DBGBH(("%s rx frame status=%04X size=%d\n",
                info->device_name, status, framesize));
-       DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, DMABUFSIZE), "rx");
+       DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, info->rbuf_fill_level), "rx");
 
        if (framesize) {
                if (!(info->params.crc_type & HDLC_CRC_RETURN_EX)) {
@@ -4592,7 +4597,7 @@ check_again:
                        info->icount.rxok++;
 
                        while(copy_count) {
-                               int partial_count = min(copy_count, DMABUFSIZE);
+                               int partial_count = min_t(int, copy_count, info->rbuf_fill_level);
                                memcpy(p, info->rbufs[i].buf, partial_count);
                                p += partial_count;
                                copy_count -= partial_count;
@@ -4683,6 +4688,56 @@ static unsigned int free_tbuf_count(struct slgt_info *info)
        return count;
 }
 
+/*
+ * return number of bytes in unsent transmit DMA buffers
+ * and the serial controller tx FIFO
+ */
+static unsigned int tbuf_bytes(struct slgt_info *info)
+{
+       unsigned int total_count = 0;
+       unsigned int i = info->tbuf_current;
+       unsigned int reg_value;
+       unsigned int count;
+       unsigned int active_buf_count = 0;
+
+       /*
+        * Add descriptor counts for all tx DMA buffers.
+        * If count is zero (cleared by DMA controller after read),
+        * the buffer is complete or is actively being read from.
+        *
+        * Record buf_count of last buffer with zero count starting
+        * from current ring position. buf_count is mirror
+        * copy of count and is not cleared by serial controller.
+        * If DMA controller is active, that buffer is actively
+        * being read so add to total.
+        */
+       do {
+               count = desc_count(info->tbufs[i]);
+               if (count)
+                       total_count += count;
+               else if (!total_count)
+                       active_buf_count = info->tbufs[i].buf_count;
+               if (++i == info->tbuf_count)
+                       i = 0;
+       } while (i != info->tbuf_current);
+
+       /* read tx DMA status register */
+       reg_value = rd_reg32(info, TDCSR);
+
+       /* if tx DMA active, last zero count buffer is in use */
+       if (reg_value & BIT0)
+               total_count += active_buf_count;
+
+       /* add tx FIFO count = reg_value[15..8] */
+       total_count += (reg_value >> 8) & 0xff;
+
+       /* if transmitter active add one byte for shift register */
+       if (info->tx_active)
+               total_count++;
+
+       return total_count;
+}
+
 /*
  * load transmit DMA buffer(s) with data
  */
@@ -4721,6 +4776,7 @@ static void tx_load(struct slgt_info *info, const char *buf, unsigned int size)
                        set_desc_eof(*d, 0);
 
                set_desc_count(*d, count);
+               d->buf_count = count;
        }
 
        info->tbuf_current = i;
index 5768c4136342ec153216c8a9fad57274a0b94252..c0490cbd0db2e99bf0e149ef99b03d2506711c6c 100644 (file)
@@ -527,7 +527,7 @@ static int  read_proc(char *page, char **start, off_t off, int count,int *eof, v
 static int  chars_in_buffer(struct tty_struct *tty);
 static void throttle(struct tty_struct * tty);
 static void unthrottle(struct tty_struct * tty);
-static void set_break(struct tty_struct *tty, int break_state);
+static int set_break(struct tty_struct *tty, int break_state);
 
 #if SYNCLINK_GENERIC_HDLC
 #define dev_to_port(D) (dev_to_hdlc(D)->priv)
@@ -552,7 +552,7 @@ static int  wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr);
 static int  tiocmget(struct tty_struct *tty, struct file *file);
 static int  tiocmset(struct tty_struct *tty, struct file *file,
                     unsigned int set, unsigned int clear);
-static void set_break(struct tty_struct *tty, int break_state);
+static int  set_break(struct tty_struct *tty, int break_state);
 
 static void add_device(SLMP_INFO *info);
 static void device_init(int adapter_num, struct pci_dev *pdev);
@@ -1587,7 +1587,7 @@ static void unthrottle(struct tty_struct * tty)
 /* set or clear transmit break condition
  * break_state -1=set break condition, 0=clear
  */
-static void set_break(struct tty_struct *tty, int break_state)
+static int set_break(struct tty_struct *tty, int break_state)
 {
        unsigned char RegValue;
        SLMP_INFO * info = (SLMP_INFO *)tty->driver_data;
@@ -1598,7 +1598,7 @@ static void set_break(struct tty_struct *tty, int break_state)
                         __FILE__,__LINE__, info->device_name, break_state);
 
        if (sanity_check(info, tty->name, "set_break"))
-               return;
+               return -EINVAL;
 
        spin_lock_irqsave(&info->lock,flags);
        RegValue = read_reg(info, CTL);
@@ -1608,6 +1608,7 @@ static void set_break(struct tty_struct *tty, int break_state)
                RegValue &= ~BIT3;
        write_reg(info, CTL, RegValue);
        spin_unlock_irqrestore(&info->lock,flags);
+       return 0;
 }
 
 #if SYNCLINK_GENERIC_HDLC
index 82f6a8c863320101f3f8a677f34192d03bded8d2..fa48dba5ba5e94ff5833f16c8e4e758bb1ffbd66 100644 (file)
@@ -655,558 +655,6 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
 
 
 
-/**
- *     tty_set_termios_ldisc           -       set ldisc field
- *     @tty: tty structure
- *     @num: line discipline number
- *
- *     This is probably overkill for real world processors but
- *     they are not on hot paths so a little discipline won't do
- *     any harm.
- *
- *     Locking: takes termios_mutex
- */
-
-static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
-{
-       mutex_lock(&tty->termios_mutex);
-       tty->termios->c_line = num;
-       mutex_unlock(&tty->termios_mutex);
-}
-
-/*
- *     This guards the refcounted line discipline lists. The lock
- *     must be taken with irqs off because there are hangup path
- *     callers who will do ldisc lookups and cannot sleep.
- */
-
-static DEFINE_SPINLOCK(tty_ldisc_lock);
-static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
-/* Line disc dispatch table */
-static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
-
-/**
- *     tty_register_ldisc      -       install a line discipline
- *     @disc: ldisc number
- *     @new_ldisc: pointer to the ldisc object
- *
- *     Installs a new line discipline into the kernel. The discipline
- *     is set up as unreferenced and then made available to the kernel
- *     from this point onwards.
- *
- *     Locking:
- *             takes tty_ldisc_lock to guard against ldisc races
- */
-
-int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
-{
-       unsigned long flags;
-       int ret = 0;
-
-       if (disc < N_TTY || disc >= NR_LDISCS)
-               return -EINVAL;
-
-       spin_lock_irqsave(&tty_ldisc_lock, flags);
-       tty_ldiscs[disc] = new_ldisc;
-       new_ldisc->num = disc;
-       new_ldisc->refcount = 0;
-       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL(tty_register_ldisc);
-
-/**
- *     tty_unregister_ldisc    -       unload a line discipline
- *     @disc: ldisc number
- *     @new_ldisc: pointer to the ldisc object
- *
- *     Remove a line discipline from the kernel providing it is not
- *     currently in use.
- *
- *     Locking:
- *             takes tty_ldisc_lock to guard against ldisc races
- */
-
-int tty_unregister_ldisc(int disc)
-{
-       unsigned long flags;
-       int ret = 0;
-
-       if (disc < N_TTY || disc >= NR_LDISCS)
-               return -EINVAL;
-
-       spin_lock_irqsave(&tty_ldisc_lock, flags);
-       if (tty_ldiscs[disc]->refcount)
-               ret = -EBUSY;
-       else
-               tty_ldiscs[disc] = NULL;
-       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL(tty_unregister_ldisc);
-
-
-/**
- *     tty_ldisc_try_get       -       try and reference an ldisc
- *     @disc: ldisc number
- *     @ld: tty ldisc structure to complete
- *
- *     Attempt to open and lock a line discipline into place. Return
- *     the line discipline refcounted and assigned in ld. On an error
- *     report the error code back
- */
-
-static int tty_ldisc_try_get(int disc, struct tty_ldisc *ld)
-{
-       unsigned long flags;
-       struct tty_ldisc_ops *ldops;
-       int err = -EINVAL;
-       
-       spin_lock_irqsave(&tty_ldisc_lock, flags);
-       ld->ops = NULL;
-       ldops = tty_ldiscs[disc];
-       /* Check the entry is defined */
-       if (ldops) {
-               /* If the module is being unloaded we can't use it */
-               if (!try_module_get(ldops->owner))
-                       err = -EAGAIN;
-               else {
-                       /* lock it */
-                       ldops->refcount++;
-                       ld->ops = ldops;
-                       err = 0;
-               }
-       }
-       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-       return err;
-}
-
-/**
- *     tty_ldisc_get           -       take a reference to an ldisc
- *     @disc: ldisc number
- *     @ld: tty line discipline structure to use
- *
- *     Takes a reference to a line discipline. Deals with refcounts and
- *     module locking counts. Returns NULL if the discipline is not available.
- *     Returns a pointer to the discipline and bumps the ref count if it is
- *     available
- *
- *     Locking:
- *             takes tty_ldisc_lock to guard against ldisc races
- */
-
-static int tty_ldisc_get(int disc, struct tty_ldisc *ld)
-{
-       int err;
-
-       if (disc < N_TTY || disc >= NR_LDISCS)
-               return -EINVAL;
-       err = tty_ldisc_try_get(disc, ld);
-       if (err == -EAGAIN) {
-               request_module("tty-ldisc-%d", disc);
-               err = tty_ldisc_try_get(disc, ld);
-       }
-       return err;
-}
-
-/**
- *     tty_ldisc_put           -       drop ldisc reference
- *     @disc: ldisc number
- *
- *     Drop a reference to a line discipline. Manage refcounts and
- *     module usage counts
- *
- *     Locking:
- *             takes tty_ldisc_lock to guard against ldisc races
- */
-
-static void tty_ldisc_put(struct tty_ldisc_ops *ld)
-{
-       unsigned long flags;
-       int disc = ld->num;
-
-       BUG_ON(disc < N_TTY || disc >= NR_LDISCS);
-
-       spin_lock_irqsave(&tty_ldisc_lock, flags);
-       ld = tty_ldiscs[disc];
-       BUG_ON(ld->refcount == 0);
-       ld->refcount--;
-       module_put(ld->owner);
-       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-}
-
-static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
-{
-       return (*pos < NR_LDISCS) ? pos : NULL;
-}
-
-static void * tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
-{
-       (*pos)++;
-       return (*pos < NR_LDISCS) ? pos : NULL;
-}
-
-static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
-{
-}
-
-static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
-{
-       int i = *(loff_t *)v;
-       struct tty_ldisc ld;
-       
-       if (tty_ldisc_get(i, &ld) < 0)
-               return 0;
-       seq_printf(m, "%-10s %2d\n", ld.ops->name ? ld.ops->name : "???", i);
-       tty_ldisc_put(ld.ops);
-       return 0;
-}
-
-static const struct seq_operations tty_ldiscs_seq_ops = {
-       .start  = tty_ldiscs_seq_start,
-       .next   = tty_ldiscs_seq_next,
-       .stop   = tty_ldiscs_seq_stop,
-       .show   = tty_ldiscs_seq_show,
-};
-
-static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &tty_ldiscs_seq_ops);
-}
-
-const struct file_operations tty_ldiscs_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = proc_tty_ldiscs_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-};
-
-/**
- *     tty_ldisc_assign        -       set ldisc on a tty
- *     @tty: tty to assign
- *     @ld: line discipline
- *
- *     Install an instance of a line discipline into a tty structure. The
- *     ldisc must have a reference count above zero to ensure it remains/
- *     The tty instance refcount starts at zero.
- *
- *     Locking:
- *             Caller must hold references
- */
-
-static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
-{
-       ld->refcount = 0;
-       tty->ldisc = *ld;
-}
-
-/**
- *     tty_ldisc_try           -       internal helper
- *     @tty: the tty
- *
- *     Make a single attempt to grab and bump the refcount on
- *     the tty ldisc. Return 0 on failure or 1 on success. This is
- *     used to implement both the waiting and non waiting versions
- *     of tty_ldisc_ref
- *
- *     Locking: takes tty_ldisc_lock
- */
-
-static int tty_ldisc_try(struct tty_struct *tty)
-{
-       unsigned long flags;
-       struct tty_ldisc *ld;
-       int ret = 0;
-
-       spin_lock_irqsave(&tty_ldisc_lock, flags);
-       ld = &tty->ldisc;
-       if (test_bit(TTY_LDISC, &tty->flags)) {
-               ld->refcount++;
-               ret = 1;
-       }
-       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-       return ret;
-}
-
-/**
- *     tty_ldisc_ref_wait      -       wait for the tty ldisc
- *     @tty: tty device
- *
- *     Dereference the line discipline for the terminal and take a
- *     reference to it. If the line discipline is in flux then
- *     wait patiently until it changes.
- *
- *     Note: Must not be called from an IRQ/timer context. The caller
- *     must also be careful not to hold other locks that will deadlock
- *     against a discipline change, such as an existing ldisc reference
- *     (which we check for)
- *
- *     Locking: call functions take tty_ldisc_lock
- */
-
-struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
-{
-       /* wait_event is a macro */
-       wait_event(tty_ldisc_wait, tty_ldisc_try(tty));
-       if (tty->ldisc.refcount == 0)
-               printk(KERN_ERR "tty_ldisc_ref_wait\n");
-       return &tty->ldisc;
-}
-
-EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
-
-/**
- *     tty_ldisc_ref           -       get the tty ldisc
- *     @tty: tty device
- *
- *     Dereference the line discipline for the terminal and take a
- *     reference to it. If the line discipline is in flux then
- *     return NULL. Can be called from IRQ and timer functions.
- *
- *     Locking: called functions take tty_ldisc_lock
- */
-
-struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
-{
-       if (tty_ldisc_try(tty))
-               return &tty->ldisc;
-       return NULL;
-}
-
-EXPORT_SYMBOL_GPL(tty_ldisc_ref);
-
-/**
- *     tty_ldisc_deref         -       free a tty ldisc reference
- *     @ld: reference to free up
- *
- *     Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May
- *     be called in IRQ context.
- *
- *     Locking: takes tty_ldisc_lock
- */
-
-void tty_ldisc_deref(struct tty_ldisc *ld)
-{
-       unsigned long flags;
-
-       BUG_ON(ld == NULL);
-
-       spin_lock_irqsave(&tty_ldisc_lock, flags);
-       if (ld->refcount == 0)
-               printk(KERN_ERR "tty_ldisc_deref: no references.\n");
-       else
-               ld->refcount--;
-       if (ld->refcount == 0)
-               wake_up(&tty_ldisc_wait);
-       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-}
-
-EXPORT_SYMBOL_GPL(tty_ldisc_deref);
-
-/**
- *     tty_ldisc_enable        -       allow ldisc use
- *     @tty: terminal to activate ldisc on
- *
- *     Set the TTY_LDISC flag when the line discipline can be called
- *     again. Do necessary wakeups for existing sleepers.
- *
- *     Note: nobody should set this bit except via this function. Clearing
- *     directly is allowed.
- */
-
-static void tty_ldisc_enable(struct tty_struct *tty)
-{
-       set_bit(TTY_LDISC, &tty->flags);
-       wake_up(&tty_ldisc_wait);
-}
-
-/**
- *     tty_ldisc_restore       -       helper for tty ldisc change
- *     @tty: tty to recover
- *     @old: previous ldisc
- *
- *     Restore the previous line discipline or N_TTY when a line discipline
- *     change fails due to an open error
- */
-
-static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
-{
-       char buf[64];
-       struct tty_ldisc new_ldisc;
-
-       /* There is an outstanding reference here so this is safe */
-       tty_ldisc_get(old->ops->num, old);
-       tty_ldisc_assign(tty, old);
-       tty_set_termios_ldisc(tty, old->ops->num);
-       if (old->ops->open && (old->ops->open(tty) < 0)) {
-               tty_ldisc_put(old->ops);
-               /* This driver is always present */
-               if (tty_ldisc_get(N_TTY, &new_ldisc) < 0)
-                       panic("n_tty: get");
-               tty_ldisc_assign(tty, &new_ldisc);
-               tty_set_termios_ldisc(tty, N_TTY);
-               if (new_ldisc.ops->open) {
-                       int r = new_ldisc.ops->open(tty);
-                               if (r < 0)
-                               panic("Couldn't open N_TTY ldisc for "
-                                     "%s --- error %d.",
-                                     tty_name(tty, buf), r);
-               }
-       }
-}
-
-/**
- *     tty_set_ldisc           -       set line discipline
- *     @tty: the terminal to set
- *     @ldisc: the line discipline
- *
- *     Set the discipline of a tty line. Must be called from a process
- *     context.
- *
- *     Locking: takes tty_ldisc_lock.
- *              called functions take termios_mutex
- */
-
-static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
-{
-       int retval;
-       struct tty_ldisc o_ldisc, new_ldisc;
-       int work;
-       unsigned long flags;
-       struct tty_struct *o_tty;
-
-restart:
-       /* This is a bit ugly for now but means we can break the 'ldisc
-          is part of the tty struct' assumption later */
-       retval = tty_ldisc_get(ldisc, &new_ldisc);
-       if (retval)
-               return retval;
-
-       /*
-        *      Problem: What do we do if this blocks ?
-        */
-
-       tty_wait_until_sent(tty, 0);
-
-       if (tty->ldisc.ops->num == ldisc) {
-               tty_ldisc_put(new_ldisc.ops);
-               return 0;
-       }
-
-       /*
-        *      No more input please, we are switching. The new ldisc
-        *      will update this value in the ldisc open function
-        */
-
-       tty->receive_room = 0;
-
-       o_ldisc = tty->ldisc;
-       o_tty = tty->link;
-
-       /*
-        *      Make sure we don't change while someone holds a
-        *      reference to the line discipline. The TTY_LDISC bit
-        *      prevents anyone taking a reference once it is clear.
-        *      We need the lock to avoid racing reference takers.
-        */
-
-       spin_lock_irqsave(&tty_ldisc_lock, flags);
-       if (tty->ldisc.refcount || (o_tty && o_tty->ldisc.refcount)) {
-               if (tty->ldisc.refcount) {
-                       /* Free the new ldisc we grabbed. Must drop the lock
-                          first. */
-                       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-                       tty_ldisc_put(o_ldisc.ops);
-                       /*
-                        * There are several reasons we may be busy, including
-                        * random momentary I/O traffic. We must therefore
-                        * retry. We could distinguish between blocking ops
-                        * and retries if we made tty_ldisc_wait() smarter.
-                        * That is up for discussion.
-                        */
-                       if (wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
-                               return -ERESTARTSYS;
-                       goto restart;
-               }
-               if (o_tty && o_tty->ldisc.refcount) {
-                       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-                       tty_ldisc_put(o_tty->ldisc.ops);
-                       if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
-                               return -ERESTARTSYS;
-                       goto restart;
-               }
-       }
-       /*
-        *      If the TTY_LDISC bit is set, then we are racing against
-        *      another ldisc change
-        */
-       if (!test_bit(TTY_LDISC, &tty->flags)) {
-               struct tty_ldisc *ld;
-               spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-               tty_ldisc_put(new_ldisc.ops);
-               ld = tty_ldisc_ref_wait(tty);
-               tty_ldisc_deref(ld);
-               goto restart;
-       }
-
-       clear_bit(TTY_LDISC, &tty->flags);
-       if (o_tty)
-               clear_bit(TTY_LDISC, &o_tty->flags);
-       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-       
-       /*
-        *      From this point on we know nobody has an ldisc
-        *      usage reference, nor can they obtain one until
-        *      we say so later on.
-        */
-
-       work = cancel_delayed_work(&tty->buf.work);
-       /*
-        * Wait for ->hangup_work and ->buf.work handlers to terminate
-        * MUST NOT hold locks here.
-        */
-       flush_scheduled_work();
-       /* Shutdown the current discipline. */
-       if (o_ldisc.ops->close)
-               (o_ldisc.ops->close)(tty);
-
-       /* Now set up the new line discipline. */
-       tty_ldisc_assign(tty, &new_ldisc);
-       tty_set_termios_ldisc(tty, ldisc);
-       if (new_ldisc.ops->open)
-               retval = (new_ldisc.ops->open)(tty);
-       if (retval < 0) {
-               tty_ldisc_put(new_ldisc.ops);
-               tty_ldisc_restore(tty, &o_ldisc);
-       }
-       /* At this point we hold a reference to the new ldisc and a
-          a reference to the old ldisc. If we ended up flipping back
-          to the existing ldisc we have two references to it */
-
-       if (tty->ldisc.ops->num != o_ldisc.ops->num && tty->ops->set_ldisc)
-               tty->ops->set_ldisc(tty);
-
-       tty_ldisc_put(o_ldisc.ops);
-
-       /*
-        *      Allow ldisc referencing to occur as soon as the driver
-        *      ldisc callback completes.
-        */
-
-       tty_ldisc_enable(tty);
-       if (o_tty)
-               tty_ldisc_enable(o_tty);
-
-       /* Restart it in case no characters kick it off. Safe if
-          already running */
-       if (work)
-               schedule_delayed_work(&tty->buf.work, 1);
-       return retval;
-}
-
 /**
  *     get_tty_driver          -       find device of a tty
  *     @dev_t: device identifier
@@ -1467,7 +915,7 @@ static void tty_reset_termios(struct tty_struct *tty)
  *     do_tty_hangup           -       actual handler for hangup events
  *     @work: tty device
  *
-k *    This can be called by the "eventd" kernel thread.  That is process
+ *     This can be called by the "eventd" kernel thread.  That is process
  *     synchronous but doesn't hold any locks, so we need to make sure we
  *     have the appropriate locks for what we're doing.
  *
@@ -2193,7 +1641,6 @@ static int init_dev(struct tty_driver *driver, int idx,
        struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc;
        struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
        int retval = 0;
-       struct tty_ldisc *ld;
 
        /* check whether we're reopening an existing tty */
        if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
@@ -2342,25 +1789,12 @@ static int init_dev(struct tty_driver *driver, int idx,
         * If we fail here just call release_tty to clean up.  No need
         * to decrement the use counts, as release_tty doesn't care.
         */
-        
-       ld = &tty->ldisc;
 
-       if (ld->ops->open) {
-               retval = (ld->ops->open)(tty);
-               if (retval)
-                       goto release_mem_out;
-       }
-       if (o_tty && o_tty->ldisc.ops->open) {
-               retval = (o_tty->ldisc.ops->open)(o_tty);
-               if (retval) {
-                       if (ld->ops->close)
-                               (ld->ops->close)(tty);
-                       goto release_mem_out;
-               }
-               tty_ldisc_enable(o_tty);
-       }
-       tty_ldisc_enable(tty);
-       goto success;
+       retval = tty_ldisc_setup(tty, o_tty);
+
+       if (retval)
+               goto release_mem_out;
+        goto success;
 
        /*
         * This fast open can be used if the tty is already open.
@@ -2498,12 +1932,10 @@ static void release_tty(struct tty_struct *tty, int idx)
 static void release_dev(struct file *filp)
 {
        struct tty_struct *tty, *o_tty;
-       struct tty_ldisc ld;
        int     pty_master, tty_closing, o_tty_closing, do_sleep;
        int     devpts;
        int     idx;
        char    buf[64];
-       unsigned long flags;
 
        tty = (struct tty_struct *)filp->private_data;
        if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode,
@@ -2705,56 +2137,9 @@ static void release_dev(struct file *filp)
        printk(KERN_DEBUG "freeing tty structure...");
 #endif
        /*
-        * Prevent flush_to_ldisc() from rescheduling the work for later.  Then
-        * kill any delayed work. As this is the final close it does not
-        * race with the set_ldisc code path.
+        * Ask the line discipline code to release its structures
         */
-       clear_bit(TTY_LDISC, &tty->flags);
-       cancel_delayed_work(&tty->buf.work);
-
-       /*
-        * Wait for ->hangup_work and ->buf.work handlers to terminate
-        */
-
-       flush_scheduled_work();
-
-       /*
-        * Wait for any short term users (we know they are just driver
-        * side waiters as the file is closing so user count on the file
-        * side is zero.
-        */
-       spin_lock_irqsave(&tty_ldisc_lock, flags);
-       while (tty->ldisc.refcount) {
-               spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-               wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0);
-               spin_lock_irqsave(&tty_ldisc_lock, flags);
-       }
-       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-       /*
-        * Shutdown the current line discipline, and reset it to N_TTY.
-        *
-        * FIXME: this MUST get fixed for the new reflocking
-        */
-       if (tty->ldisc.ops->close)
-               (tty->ldisc.ops->close)(tty);
-       tty_ldisc_put(tty->ldisc.ops);
-
-       /*
-        *      Switch the line discipline back
-        */
-       WARN_ON(tty_ldisc_get(N_TTY, &ld));
-       tty_ldisc_assign(tty, &ld);
-       tty_set_termios_ldisc(tty, N_TTY);
-       if (o_tty) {
-               /* FIXME: could o_tty be in setldisc here ? */
-               clear_bit(TTY_LDISC, &o_tty->flags);
-               if (o_tty->ldisc.ops->close)
-                       (o_tty->ldisc.ops->close)(o_tty);
-               tty_ldisc_put(o_tty->ldisc.ops);
-               WARN_ON(tty_ldisc_get(N_TTY, &ld));
-               tty_ldisc_assign(o_tty, &ld);
-               tty_set_termios_ldisc(o_tty, N_TTY);
-       }
+       tty_ldisc_release(tty, o_tty);
        /*
         * The release_tty function takes care of the details of clearing
         * the slots and preserving the termios structure.
@@ -3464,16 +2849,29 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
 
 static int send_break(struct tty_struct *tty, unsigned int duration)
 {
-       if (tty_write_lock(tty, 0) < 0)
-               return -EINTR;
-       tty->ops->break_ctl(tty, -1);
-       if (!signal_pending(current))
-               msleep_interruptible(duration);
-       tty->ops->break_ctl(tty, 0);
-       tty_write_unlock(tty);
-       if (signal_pending(current))
-               return -EINTR;
-       return 0;
+       int retval;
+
+       if (tty->ops->break_ctl == NULL)
+               return 0;
+
+       if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK)
+               retval = tty->ops->break_ctl(tty, duration);
+       else {
+               /* Do the work ourselves */
+               if (tty_write_lock(tty, 0) < 0)
+                       return -EINTR;
+               retval = tty->ops->break_ctl(tty, -1);
+               if (retval)
+                       goto out;
+               if (!signal_pending(current))
+                       msleep_interruptible(duration);
+               retval = tty->ops->break_ctl(tty, 0);
+out:
+               tty_write_unlock(tty);
+               if (signal_pending(current))
+                       retval = -EINTR;
+       }
+       return retval;
 }
 
 /**
@@ -3564,36 +2962,6 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
            tty->driver->subtype == PTY_TYPE_MASTER)
                real_tty = tty->link;
 
-       /*
-        * Break handling by driver
-        */
-
-       retval = -EINVAL;
-
-       if (!tty->ops->break_ctl) {
-               switch (cmd) {
-               case TIOCSBRK:
-               case TIOCCBRK:
-                       if (tty->ops->ioctl)
-                               retval = tty->ops->ioctl(tty, file, cmd, arg);
-                       if (retval != -EINVAL && retval != -ENOIOCTLCMD)
-                               printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
-                       return retval;
-
-               /* These two ioctl's always return success; even if */
-               /* the driver doesn't support them. */
-               case TCSBRK:
-               case TCSBRKP:
-                       if (!tty->ops->ioctl)
-                               return 0;
-                       retval = tty->ops->ioctl(tty, file, cmd, arg);
-                       if (retval != -EINVAL && retval != -ENOIOCTLCMD)
-                               printk(KERN_WARNING "tty: driver %s needs updating to use break_ctl\n", tty->driver->name);
-                       if (retval == -ENOIOCTLCMD)
-                               retval = 0;
-                       return retval;
-               }
-       }
 
        /*
         * Factor out some common prep work
@@ -3615,6 +2983,9 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                break;
        }
 
+       /*
+        *      Now do the stuff.
+        */
        switch (cmd) {
        case TIOCSTI:
                return tiocsti(tty, p);
@@ -3658,12 +3029,11 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
         */
        case TIOCSBRK:  /* Turn break on, unconditionally */
                if (tty->ops->break_ctl)
-                       tty->ops->break_ctl(tty, -1);
+                       return tty->ops->break_ctl(tty, -1);
                return 0;
-
        case TIOCCBRK:  /* Turn break off, unconditionally */
                if (tty->ops->break_ctl)
-                       tty->ops->break_ctl(tty, 0);
+                       return tty->ops->break_ctl(tty, 0);
                return 0;
        case TCSBRK:   /* SVID version: non-zero arg --> no break */
                /* non-zero arg means wait for all output data
@@ -3962,12 +3332,9 @@ EXPORT_SYMBOL(tty_flip_buffer_push);
 
 static void initialize_tty_struct(struct tty_struct *tty)
 {
-       struct tty_ldisc ld;
        memset(tty, 0, sizeof(struct tty_struct));
        tty->magic = TTY_MAGIC;
-       if (tty_ldisc_get(N_TTY, &ld) < 0)
-               panic("n_tty: init_tty");
-       tty_ldisc_assign(tty, &ld);
+       tty_ldisc_init(tty);
        tty->session = NULL;
        tty->pgrp = NULL;
        tty->overrun_time = jiffies;
@@ -4045,7 +3412,7 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index,
        else
                tty_line_name(driver, index, name);
 
-       return device_create(tty_class, device, dev, name);
+       return device_create_drvdata(tty_class, device, dev, NULL, name);
 }
 
 /**
@@ -4280,7 +3647,7 @@ void __init console_init(void)
        initcall_t *call;
 
        /* Setup the default TTY line discipline. */
-       (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
+       tty_ldisc_begin();
 
        /*
         * set up the console device so that later boot sequences can
@@ -4323,20 +3690,22 @@ static int __init tty_init(void)
        if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
                panic("Couldn't register /dev/tty driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), "tty");
+       device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL,
+                             "tty");
 
        cdev_init(&console_cdev, &console_fops);
        if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
                panic("Couldn't register /dev/console driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), "console");
+       device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
+                             "console");
 
 #ifdef CONFIG_UNIX98_PTYS
        cdev_init(&ptmx_cdev, &ptmx_fops);
        if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
                panic("Couldn't register /dev/ptmx driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), "ptmx");
+       device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
 #endif
 
 #ifdef CONFIG_VT
@@ -4344,7 +3713,7 @@ static int __init tty_init(void)
        if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
            register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
                panic("Couldn't register /dev/tty0 driver\n");
-       device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), "tty0");
+       device_create_drvdata(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
 
        vty_init();
 #endif
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
new file mode 100644 (file)
index 0000000..241cbde
--- /dev/null
@@ -0,0 +1,714 @@
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/fcntl.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/devpts_fs.h>
+#include <linux/file.h>
+#include <linux/fdtable.h>
+#include <linux/console.h>
+#include <linux/timer.h>
+#include <linux/ctype.h>
+#include <linux/kd.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/smp_lock.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+
+#include <linux/uaccess.h>
+#include <asm/system.h>
+
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+
+#include <linux/kmod.h>
+#include <linux/nsproxy.h>
+
+/*
+ *     This guards the refcounted line discipline lists. The lock
+ *     must be taken with irqs off because there are hangup path
+ *     callers who will do ldisc lookups and cannot sleep.
+ */
+
+static DEFINE_SPINLOCK(tty_ldisc_lock);
+static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
+/* Line disc dispatch table */
+static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
+
+/**
+ *     tty_register_ldisc      -       install a line discipline
+ *     @disc: ldisc number
+ *     @new_ldisc: pointer to the ldisc object
+ *
+ *     Installs a new line discipline into the kernel. The discipline
+ *     is set up as unreferenced and then made available to the kernel
+ *     from this point onwards.
+ *
+ *     Locking:
+ *             takes tty_ldisc_lock to guard against ldisc races
+ */
+
+int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       if (disc < N_TTY || disc >= NR_LDISCS)
+               return -EINVAL;
+
+       spin_lock_irqsave(&tty_ldisc_lock, flags);
+       tty_ldiscs[disc] = new_ldisc;
+       new_ldisc->num = disc;
+       new_ldisc->refcount = 0;
+       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(tty_register_ldisc);
+
+/**
+ *     tty_unregister_ldisc    -       unload a line discipline
+ *     @disc: ldisc number
+ *     @new_ldisc: pointer to the ldisc object
+ *
+ *     Remove a line discipline from the kernel providing it is not
+ *     currently in use.
+ *
+ *     Locking:
+ *             takes tty_ldisc_lock to guard against ldisc races
+ */
+
+int tty_unregister_ldisc(int disc)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       if (disc < N_TTY || disc >= NR_LDISCS)
+               return -EINVAL;
+
+       spin_lock_irqsave(&tty_ldisc_lock, flags);
+       if (tty_ldiscs[disc]->refcount)
+               ret = -EBUSY;
+       else
+               tty_ldiscs[disc] = NULL;
+       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(tty_unregister_ldisc);
+
+
+/**
+ *     tty_ldisc_try_get       -       try and reference an ldisc
+ *     @disc: ldisc number
+ *     @ld: tty ldisc structure to complete
+ *
+ *     Attempt to open and lock a line discipline into place. Return
+ *     the line discipline refcounted and assigned in ld. On an error
+ *     report the error code back
+ */
+
+static int tty_ldisc_try_get(int disc, struct tty_ldisc *ld)
+{
+       unsigned long flags;
+       struct tty_ldisc_ops *ldops;
+       int err = -EINVAL;
+       
+       spin_lock_irqsave(&tty_ldisc_lock, flags);
+       ld->ops = NULL;
+       ldops = tty_ldiscs[disc];
+       /* Check the entry is defined */
+       if (ldops) {
+               /* If the module is being unloaded we can't use it */
+               if (!try_module_get(ldops->owner))
+                       err = -EAGAIN;
+               else {
+                       /* lock it */
+                       ldops->refcount++;
+                       ld->ops = ldops;
+                       err = 0;
+               }
+       }
+       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+       return err;
+}
+
+/**
+ *     tty_ldisc_get           -       take a reference to an ldisc
+ *     @disc: ldisc number
+ *     @ld: tty line discipline structure to use
+ *
+ *     Takes a reference to a line discipline. Deals with refcounts and
+ *     module locking counts. Returns NULL if the discipline is not available.
+ *     Returns a pointer to the discipline and bumps the ref count if it is
+ *     available
+ *
+ *     Locking:
+ *             takes tty_ldisc_lock to guard against ldisc races
+ */
+
+static int tty_ldisc_get(int disc, struct tty_ldisc *ld)
+{
+       int err;
+
+       if (disc < N_TTY || disc >= NR_LDISCS)
+               return -EINVAL;
+       err = tty_ldisc_try_get(disc, ld);
+       if (err == -EAGAIN) {
+               request_module("tty-ldisc-%d", disc);
+               err = tty_ldisc_try_get(disc, ld);
+       }
+       return err;
+}
+
+/**
+ *     tty_ldisc_put           -       drop ldisc reference
+ *     @disc: ldisc number
+ *
+ *     Drop a reference to a line discipline. Manage refcounts and
+ *     module usage counts
+ *
+ *     Locking:
+ *             takes tty_ldisc_lock to guard against ldisc races
+ */
+
+static void tty_ldisc_put(struct tty_ldisc_ops *ld)
+{
+       unsigned long flags;
+       int disc = ld->num;
+
+       BUG_ON(disc < N_TTY || disc >= NR_LDISCS);
+
+       spin_lock_irqsave(&tty_ldisc_lock, flags);
+       ld = tty_ldiscs[disc];
+       BUG_ON(ld->refcount == 0);
+       ld->refcount--;
+       module_put(ld->owner);
+       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+}
+
+static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
+{
+       return (*pos < NR_LDISCS) ? pos : NULL;
+}
+
+static void * tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+       (*pos)++;
+       return (*pos < NR_LDISCS) ? pos : NULL;
+}
+
+static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
+{
+}
+
+static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
+{
+       int i = *(loff_t *)v;
+       struct tty_ldisc ld;
+       
+       if (tty_ldisc_get(i, &ld) < 0)
+               return 0;
+       seq_printf(m, "%-10s %2d\n", ld.ops->name ? ld.ops->name : "???", i);
+       tty_ldisc_put(ld.ops);
+       return 0;
+}
+
+static const struct seq_operations tty_ldiscs_seq_ops = {
+       .start  = tty_ldiscs_seq_start,
+       .next   = tty_ldiscs_seq_next,
+       .stop   = tty_ldiscs_seq_stop,
+       .show   = tty_ldiscs_seq_show,
+};
+
+static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &tty_ldiscs_seq_ops);
+}
+
+const struct file_operations tty_ldiscs_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = proc_tty_ldiscs_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+/**
+ *     tty_ldisc_assign        -       set ldisc on a tty
+ *     @tty: tty to assign
+ *     @ld: line discipline
+ *
+ *     Install an instance of a line discipline into a tty structure. The
+ *     ldisc must have a reference count above zero to ensure it remains/
+ *     The tty instance refcount starts at zero.
+ *
+ *     Locking:
+ *             Caller must hold references
+ */
+
+static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
+{
+       ld->refcount = 0;
+       tty->ldisc = *ld;
+}
+
+/**
+ *     tty_ldisc_try           -       internal helper
+ *     @tty: the tty
+ *
+ *     Make a single attempt to grab and bump the refcount on
+ *     the tty ldisc. Return 0 on failure or 1 on success. This is
+ *     used to implement both the waiting and non waiting versions
+ *     of tty_ldisc_ref
+ *
+ *     Locking: takes tty_ldisc_lock
+ */
+
+static int tty_ldisc_try(struct tty_struct *tty)
+{
+       unsigned long flags;
+       struct tty_ldisc *ld;
+       int ret = 0;
+
+       spin_lock_irqsave(&tty_ldisc_lock, flags);
+       ld = &tty->ldisc;
+       if (test_bit(TTY_LDISC, &tty->flags)) {
+               ld->refcount++;
+               ret = 1;
+       }
+       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+       return ret;
+}
+
+/**
+ *     tty_ldisc_ref_wait      -       wait for the tty ldisc
+ *     @tty: tty device
+ *
+ *     Dereference the line discipline for the terminal and take a
+ *     reference to it. If the line discipline is in flux then
+ *     wait patiently until it changes.
+ *
+ *     Note: Must not be called from an IRQ/timer context. The caller
+ *     must also be careful not to hold other locks that will deadlock
+ *     against a discipline change, such as an existing ldisc reference
+ *     (which we check for)
+ *
+ *     Locking: call functions take tty_ldisc_lock
+ */
+
+struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
+{
+       /* wait_event is a macro */
+       wait_event(tty_ldisc_wait, tty_ldisc_try(tty));
+       if (tty->ldisc.refcount == 0)
+               printk(KERN_ERR "tty_ldisc_ref_wait\n");
+       return &tty->ldisc;
+}
+
+EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
+
+/**
+ *     tty_ldisc_ref           -       get the tty ldisc
+ *     @tty: tty device
+ *
+ *     Dereference the line discipline for the terminal and take a
+ *     reference to it. If the line discipline is in flux then
+ *     return NULL. Can be called from IRQ and timer functions.
+ *
+ *     Locking: called functions take tty_ldisc_lock
+ */
+
+struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
+{
+       if (tty_ldisc_try(tty))
+               return &tty->ldisc;
+       return NULL;
+}
+
+EXPORT_SYMBOL_GPL(tty_ldisc_ref);
+
+/**
+ *     tty_ldisc_deref         -       free a tty ldisc reference
+ *     @ld: reference to free up
+ *
+ *     Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May
+ *     be called in IRQ context.
+ *
+ *     Locking: takes tty_ldisc_lock
+ */
+
+void tty_ldisc_deref(struct tty_ldisc *ld)
+{
+       unsigned long flags;
+
+       BUG_ON(ld == NULL);
+
+       spin_lock_irqsave(&tty_ldisc_lock, flags);
+       if (ld->refcount == 0)
+               printk(KERN_ERR "tty_ldisc_deref: no references.\n");
+       else
+               ld->refcount--;
+       if (ld->refcount == 0)
+               wake_up(&tty_ldisc_wait);
+       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+}
+
+EXPORT_SYMBOL_GPL(tty_ldisc_deref);
+
+/**
+ *     tty_ldisc_enable        -       allow ldisc use
+ *     @tty: terminal to activate ldisc on
+ *
+ *     Set the TTY_LDISC flag when the line discipline can be called
+ *     again. Do necessary wakeups for existing sleepers.
+ *
+ *     Note: nobody should set this bit except via this function. Clearing
+ *     directly is allowed.
+ */
+
+void tty_ldisc_enable(struct tty_struct *tty)
+{
+       set_bit(TTY_LDISC, &tty->flags);
+       wake_up(&tty_ldisc_wait);
+}
+
+/**
+ *     tty_set_termios_ldisc           -       set ldisc field
+ *     @tty: tty structure
+ *     @num: line discipline number
+ *
+ *     This is probably overkill for real world processors but
+ *     they are not on hot paths so a little discipline won't do
+ *     any harm.
+ *
+ *     Locking: takes termios_mutex
+ */
+
+static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
+{
+       mutex_lock(&tty->termios_mutex);
+       tty->termios->c_line = num;
+       mutex_unlock(&tty->termios_mutex);
+}
+
+
+/**
+ *     tty_ldisc_restore       -       helper for tty ldisc change
+ *     @tty: tty to recover
+ *     @old: previous ldisc
+ *
+ *     Restore the previous line discipline or N_TTY when a line discipline
+ *     change fails due to an open error
+ */
+
+static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
+{
+       char buf[64];
+       struct tty_ldisc new_ldisc;
+
+       /* There is an outstanding reference here so this is safe */
+       tty_ldisc_get(old->ops->num, old);
+       tty_ldisc_assign(tty, old);
+       tty_set_termios_ldisc(tty, old->ops->num);
+       if (old->ops->open && (old->ops->open(tty) < 0)) {
+               tty_ldisc_put(old->ops);
+               /* This driver is always present */
+               if (tty_ldisc_get(N_TTY, &new_ldisc) < 0)
+                       panic("n_tty: get");
+               tty_ldisc_assign(tty, &new_ldisc);
+               tty_set_termios_ldisc(tty, N_TTY);
+               if (new_ldisc.ops->open) {
+                       int r = new_ldisc.ops->open(tty);
+                               if (r < 0)
+                               panic("Couldn't open N_TTY ldisc for "
+                                     "%s --- error %d.",
+                                     tty_name(tty, buf), r);
+               }
+       }
+}
+
+/**
+ *     tty_set_ldisc           -       set line discipline
+ *     @tty: the terminal to set
+ *     @ldisc: the line discipline
+ *
+ *     Set the discipline of a tty line. Must be called from a process
+ *     context.
+ *
+ *     Locking: takes tty_ldisc_lock.
+ *              called functions take termios_mutex
+ */
+
+int tty_set_ldisc(struct tty_struct *tty, int ldisc)
+{
+       int retval;
+       struct tty_ldisc o_ldisc, new_ldisc;
+       int work;
+       unsigned long flags;
+       struct tty_struct *o_tty;
+
+restart:
+       /* This is a bit ugly for now but means we can break the 'ldisc
+          is part of the tty struct' assumption later */
+       retval = tty_ldisc_get(ldisc, &new_ldisc);
+       if (retval)
+               return retval;
+
+       /*
+        *      Problem: What do we do if this blocks ?
+        */
+
+       tty_wait_until_sent(tty, 0);
+
+       if (tty->ldisc.ops->num == ldisc) {
+               tty_ldisc_put(new_ldisc.ops);
+               return 0;
+       }
+
+       /*
+        *      No more input please, we are switching. The new ldisc
+        *      will update this value in the ldisc open function
+        */
+
+       tty->receive_room = 0;
+
+       o_ldisc = tty->ldisc;
+       o_tty = tty->link;
+
+       /*
+        *      Make sure we don't change while someone holds a
+        *      reference to the line discipline. The TTY_LDISC bit
+        *      prevents anyone taking a reference once it is clear.
+        *      We need the lock to avoid racing reference takers.
+        */
+
+       spin_lock_irqsave(&tty_ldisc_lock, flags);
+       if (tty->ldisc.refcount || (o_tty && o_tty->ldisc.refcount)) {
+               if (tty->ldisc.refcount) {
+                       /* Free the new ldisc we grabbed. Must drop the lock
+                          first. */
+                       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+                       tty_ldisc_put(o_ldisc.ops);
+                       /*
+                        * There are several reasons we may be busy, including
+                        * random momentary I/O traffic. We must therefore
+                        * retry. We could distinguish between blocking ops
+                        * and retries if we made tty_ldisc_wait() smarter.
+                        * That is up for discussion.
+                        */
+                       if (wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
+                               return -ERESTARTSYS;
+                       goto restart;
+               }
+               if (o_tty && o_tty->ldisc.refcount) {
+                       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+                       tty_ldisc_put(o_tty->ldisc.ops);
+                       if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
+                               return -ERESTARTSYS;
+                       goto restart;
+               }
+       }
+       /*
+        *      If the TTY_LDISC bit is set, then we are racing against
+        *      another ldisc change
+        */
+       if (!test_bit(TTY_LDISC, &tty->flags)) {
+               struct tty_ldisc *ld;
+               spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+               tty_ldisc_put(new_ldisc.ops);
+               ld = tty_ldisc_ref_wait(tty);
+               tty_ldisc_deref(ld);
+               goto restart;
+       }
+
+       clear_bit(TTY_LDISC, &tty->flags);
+       if (o_tty)
+               clear_bit(TTY_LDISC, &o_tty->flags);
+       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+       
+       /*
+        *      From this point on we know nobody has an ldisc
+        *      usage reference, nor can they obtain one until
+        *      we say so later on.
+        */
+
+       work = cancel_delayed_work(&tty->buf.work);
+       /*
+        * Wait for ->hangup_work and ->buf.work handlers to terminate
+        * MUST NOT hold locks here.
+        */
+       flush_scheduled_work();
+       /* Shutdown the current discipline. */
+       if (o_ldisc.ops->close)
+               (o_ldisc.ops->close)(tty);
+
+       /* Now set up the new line discipline. */
+       tty_ldisc_assign(tty, &new_ldisc);
+       tty_set_termios_ldisc(tty, ldisc);
+       if (new_ldisc.ops->open)
+               retval = (new_ldisc.ops->open)(tty);
+       if (retval < 0) {
+               tty_ldisc_put(new_ldisc.ops);
+               tty_ldisc_restore(tty, &o_ldisc);
+       }
+       /* At this point we hold a reference to the new ldisc and a
+          a reference to the old ldisc. If we ended up flipping back
+          to the existing ldisc we have two references to it */
+
+       if (tty->ldisc.ops->num != o_ldisc.ops->num && tty->ops->set_ldisc)
+               tty->ops->set_ldisc(tty);
+
+       tty_ldisc_put(o_ldisc.ops);
+
+       /*
+        *      Allow ldisc referencing to occur as soon as the driver
+        *      ldisc callback completes.
+        */
+
+       tty_ldisc_enable(tty);
+       if (o_tty)
+               tty_ldisc_enable(o_tty);
+
+       /* Restart it in case no characters kick it off. Safe if
+          already running */
+       if (work)
+               schedule_delayed_work(&tty->buf.work, 1);
+       return retval;
+}
+
+
+/**
+ *     tty_ldisc_setup                 -       open line discipline
+ *     @tty: tty being shut down
+ *     @o_tty: pair tty for pty/tty pairs
+ *
+ *     Called during the initial open of a tty/pty pair in order to set up the
+ *     line discplines and bind them to the tty.
+ */
+
+int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
+{
+       struct tty_ldisc *ld = &tty->ldisc;
+       int retval;
+
+       if (ld->ops->open) {
+               retval = (ld->ops->open)(tty);
+               if (retval)
+                       return retval;
+       }
+       if (o_tty && o_tty->ldisc.ops->open) {
+               retval = (o_tty->ldisc.ops->open)(o_tty);
+               if (retval) {
+                       if (ld->ops->close)
+                               (ld->ops->close)(tty);
+                       return retval;
+               }
+               tty_ldisc_enable(o_tty);
+       }
+       tty_ldisc_enable(tty);
+       return 0;
+}
+
+/**
+ *     tty_ldisc_release               -       release line discipline
+ *     @tty: tty being shut down
+ *     @o_tty: pair tty for pty/tty pairs
+ *
+ *     Called during the final close of a tty/pty pair in order to shut down the
+ *     line discpline layer.
+ */
+
+void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
+{
+       unsigned long flags;
+       struct tty_ldisc ld;
+       /*
+        * Prevent flush_to_ldisc() from rescheduling the work for later.  Then
+        * kill any delayed work. As this is the final close it does not
+        * race with the set_ldisc code path.
+        */
+       clear_bit(TTY_LDISC, &tty->flags);
+       cancel_delayed_work(&tty->buf.work);
+
+       /*
+        * Wait for ->hangup_work and ->buf.work handlers to terminate
+        */
+
+       flush_scheduled_work();
+
+       /*
+        * Wait for any short term users (we know they are just driver
+        * side waiters as the file is closing so user count on the file
+        * side is zero.
+        */
+       spin_lock_irqsave(&tty_ldisc_lock, flags);
+       while (tty->ldisc.refcount) {
+               spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+               wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0);
+               spin_lock_irqsave(&tty_ldisc_lock, flags);
+       }
+       spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+       /*
+        * Shutdown the current line discipline, and reset it to N_TTY.
+        *
+        * FIXME: this MUST get fixed for the new reflocking
+        */
+       if (tty->ldisc.ops->close)
+               (tty->ldisc.ops->close)(tty);
+       tty_ldisc_put(tty->ldisc.ops);
+
+       /*
+        *      Switch the line discipline back
+        */
+       WARN_ON(tty_ldisc_get(N_TTY, &ld));
+       tty_ldisc_assign(tty, &ld);
+       tty_set_termios_ldisc(tty, N_TTY);
+       if (o_tty) {
+               /* FIXME: could o_tty be in setldisc here ? */
+               clear_bit(TTY_LDISC, &o_tty->flags);
+               if (o_tty->ldisc.ops->close)
+                       (o_tty->ldisc.ops->close)(o_tty);
+               tty_ldisc_put(o_tty->ldisc.ops);
+               WARN_ON(tty_ldisc_get(N_TTY, &ld));
+               tty_ldisc_assign(o_tty, &ld);
+               tty_set_termios_ldisc(o_tty, N_TTY);
+       }
+}
+
+/**
+ *     tty_ldisc_init          -       ldisc setup for new tty
+ *     @tty: tty being allocated
+ *
+ *     Set up the line discipline objects for a newly allocated tty. Note that
+ *     the tty structure is not completely set up when this call is made.
+ */
+
+void tty_ldisc_init(struct tty_struct *tty)
+{
+       struct tty_ldisc ld;
+       if (tty_ldisc_get(N_TTY, &ld) < 0)
+               panic("n_tty: init_tty");
+       tty_ldisc_assign(tty, &ld);
+}
+
+void tty_ldisc_begin(void)
+{
+       /* Setup the default TTY line discipline. */
+       (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
+}
index eebfad2777d29ac9bfd7134eab259c11c7bd5a79..c2ae52dd53d1a6447affa697afaa53c9f9f9f7f7 100644 (file)
@@ -481,10 +481,10 @@ static struct class *vc_class;
 
 void vcs_make_sysfs(struct tty_struct *tty)
 {
-       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
-                       "vcs%u", tty->index + 1);
-       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
-                       "vcsa%u", tty->index + 1);
+       device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
+                             NULL, "vcs%u", tty->index + 1);
+       device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
+                             NULL, "vcsa%u", tty->index + 1);
 }
 
 void vcs_remove_sysfs(struct tty_struct *tty)
@@ -499,7 +499,7 @@ int __init vcs_init(void)
                panic("unable to get major %d for vcs device", VCS_MAJOR);
        vc_class = class_create(THIS_MODULE, "vc");
 
-       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), "vcs");
-       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), "vcsa");
+       device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
+       device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
        return 0;
 }
index e5da98d8f9cd70f493ecb8c9d7521639f937e779..7a70a40ad639855b4f3880386ef7b34f47d71f46 100644 (file)
@@ -886,10 +886,10 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
        state[i].cur_part = 0;
        for (j = 0; j < MAX_PARTITIONS; ++j)
                state[i].part_stat_rwi[j] = VIOT_IDLE;
-       device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i),
-                       "iseries!vt%d", i);
-       device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
-                       "iseries!nvt%d", i);
+       device_create_drvdata(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i),
+                             NULL, "iseries!vt%d", i);
+       device_create_drvdata(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
+                             NULL, "iseries!nvt%d", i);
        printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries "
                        "resource %10.10s type %4.4s, model %3.3s\n",
                        i, viotape_unitinfo[i].rsrcname,
index f17ac043b551ee3bc6deb01148d45baac2bd2f2d..69c5afe97f19ef6e6fc932ceabcfc42420ff6d32 100644 (file)
@@ -85,7 +85,7 @@ static irqreturn_t scc_rx_int(int irq, void *data);
 static irqreturn_t scc_stat_int(int irq, void *data);
 static irqreturn_t scc_spcond_int(int irq, void *data);
 static void scc_setsignals(struct scc_port *port, int dtr, int rts);
-static void scc_break_ctl(struct tty_struct *tty, int break_state);
+static int scc_break_ctl(struct tty_struct *tty, int break_state);
 
 static struct tty_driver *scc_driver;
 
@@ -942,7 +942,7 @@ static int scc_ioctl(struct tty_struct *tty, struct file *file,
 }
 
 
-static void scc_break_ctl(struct tty_struct *tty, int break_state)
+static int scc_break_ctl(struct tty_struct *tty, int break_state)
 {
        struct scc_port *port = (struct scc_port *)tty->driver_data;
        unsigned long   flags;
@@ -952,6 +952,7 @@ static void scc_break_ctl(struct tty_struct *tty, int break_state)
        SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK, 
                        break_state ? TCR_SEND_BREAK : 0);
        local_irq_restore(flags);
+       return 0;
 }
 
 
index 935f1c207a1f0edfe7056fee448e4ff337164229..e32a076d5f1f8f182025341d98d3a89f25a9f4f8 100644 (file)
@@ -3425,9 +3425,10 @@ int register_con_driver(const struct consw *csw, int first, int last)
        if (retval)
                goto err;
 
-       con_driver->dev = device_create(vtconsole_class, NULL,
-                                       MKDEV(0, con_driver->node),
-                                       "vtcon%i", con_driver->node);
+       con_driver->dev = device_create_drvdata(vtconsole_class, NULL,
+                                               MKDEV(0, con_driver->node),
+                                               NULL, "vtcon%i",
+                                               con_driver->node);
 
        if (IS_ERR(con_driver->dev)) {
                printk(KERN_WARNING "Unable to create device for %s; "
@@ -3535,9 +3536,10 @@ static int __init vtconsole_class_init(void)
                struct con_driver *con = &registered_con_driver[i];
 
                if (con->con && !con->dev) {
-                       con->dev = device_create(vtconsole_class, NULL,
-                                                MKDEV(0, con->node),
-                                                "vtcon%i", con->node);
+                       con->dev = device_create_drvdata(vtconsole_class, NULL,
+                                                        MKDEV(0, con->node),
+                                                        NULL, "vtcon%i",
+                                                        con->node);
 
                        if (IS_ERR(con->dev)) {
                                printk(KERN_WARNING "Unable to create "
index 1e1b81e57cdcf7060739a42bd6862d2d5a2caab7..51966ccf4ea3f56c4449f88c93906ab81e136111 100644 (file)
@@ -658,8 +658,9 @@ static int __devinit hwicap_setup(struct device *dev, int id,
                dev_err(dev, "cdev_add() failed\n");
                goto failed3;
        }
-       /*  devfs_mk_cdev(devt, S_IFCHR|S_IRUGO|S_IWUGO, DRIVER_NAME); */
-       device_create(icap_class, dev, devt, "%s%d", DRIVER_NAME, id);
+
+       device_create_drvdata(icap_class, dev, devt, NULL,
+                             "%s%d", DRIVER_NAME, id);
        return 0;               /* success */
 
  failed3:
index d8f8b1e0edde129f6511b051ee2565b38d86bd75..8d6a3ff026729e181d330c4111dc467249df25ae 100644 (file)
  * also protects the cpufreq_cpu_data array.
  */
 static struct cpufreq_driver *cpufreq_driver;
-static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
+static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
 #ifdef CONFIG_HOTPLUG_CPU
 /* This one keeps track of the previously set governor of a removed CPU */
-static struct cpufreq_governor *cpufreq_cpu_governor[NR_CPUS];
+static DEFINE_PER_CPU(struct cpufreq_governor *, cpufreq_cpu_governor);
 #endif
 static DEFINE_SPINLOCK(cpufreq_driver_lock);
 
@@ -135,7 +135,7 @@ struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
        struct cpufreq_policy *data;
        unsigned long flags;
 
-       if (cpu >= NR_CPUS)
+       if (cpu >= nr_cpu_ids)
                goto err_out;
 
        /* get the cpufreq driver */
@@ -149,7 +149,7 @@ struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
 
 
        /* get the CPU */
-       data = cpufreq_cpu_data[cpu];
+       data = per_cpu(cpufreq_cpu_data, cpu);
 
        if (!data)
                goto err_out_put_module;
@@ -327,7 +327,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
        dprintk("notification %u of frequency transition to %u kHz\n",
                state, freqs->new);
 
-       policy = cpufreq_cpu_data[freqs->cpu];
+       policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
        switch (state) {
 
        case CPUFREQ_PRECHANGE:
@@ -828,8 +828,8 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
 #ifdef CONFIG_SMP
 
 #ifdef CONFIG_HOTPLUG_CPU
-       if (cpufreq_cpu_governor[cpu]){
-               policy->governor = cpufreq_cpu_governor[cpu];
+       if (per_cpu(cpufreq_cpu_governor, cpu)) {
+               policy->governor = per_cpu(cpufreq_cpu_governor, cpu);
                dprintk("Restoring governor %s for cpu %d\n",
                       policy->governor->name, cpu);
        }
@@ -854,7 +854,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
 
                        spin_lock_irqsave(&cpufreq_driver_lock, flags);
                        managed_policy->cpus = policy->cpus;
-                       cpufreq_cpu_data[cpu] = managed_policy;
+                       per_cpu(cpufreq_cpu_data, cpu) = managed_policy;
                        spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
                        dprintk("CPU already managed, adding link\n");
@@ -899,7 +899,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
 
        spin_lock_irqsave(&cpufreq_driver_lock, flags);
        for_each_cpu_mask_nr(j, policy->cpus) {
-               cpufreq_cpu_data[j] = policy;
+               per_cpu(cpufreq_cpu_data, j) = policy;
                per_cpu(policy_cpu, j) = policy->cpu;
        }
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
@@ -946,7 +946,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
 err_out_unregister:
        spin_lock_irqsave(&cpufreq_driver_lock, flags);
        for_each_cpu_mask_nr(j, policy->cpus)
-               cpufreq_cpu_data[j] = NULL;
+               per_cpu(cpufreq_cpu_data, j) = NULL;
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
        kobject_put(&policy->kobj);
@@ -989,7 +989,7 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
        dprintk("unregistering CPU %u\n", cpu);
 
        spin_lock_irqsave(&cpufreq_driver_lock, flags);
-       data = cpufreq_cpu_data[cpu];
+       data = per_cpu(cpufreq_cpu_data, cpu);
 
        if (!data) {
                spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
@@ -997,7 +997,7 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
                unlock_policy_rwsem_write(cpu);
                return -EINVAL;
        }
-       cpufreq_cpu_data[cpu] = NULL;
+       per_cpu(cpufreq_cpu_data, cpu) = NULL;
 
 
 #ifdef CONFIG_SMP
@@ -1019,19 +1019,19 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
 #ifdef CONFIG_SMP
 
 #ifdef CONFIG_HOTPLUG_CPU
-       cpufreq_cpu_governor[cpu] = data->governor;
+       per_cpu(cpufreq_cpu_governor, cpu) = data->governor;
 #endif
 
        /* if we have other CPUs still registered, we need to unlink them,
         * or else wait_for_completion below will lock up. Clean the
-        * cpufreq_cpu_data[] while holding the lock, and remove the sysfs
-        * links afterwards.
+        * per_cpu(cpufreq_cpu_data) while holding the lock, and remove
+        * the sysfs links afterwards.
         */
        if (unlikely(cpus_weight(data->cpus) > 1)) {
                for_each_cpu_mask_nr(j, data->cpus) {
                        if (j == cpu)
                                continue;
-                       cpufreq_cpu_data[j] = NULL;
+                       per_cpu(cpufreq_cpu_data, j) = NULL;
                }
        }
 
@@ -1043,7 +1043,7 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
                                continue;
                        dprintk("removing link for cpu %u\n", j);
 #ifdef CONFIG_HOTPLUG_CPU
-                       cpufreq_cpu_governor[j] = data->governor;
+                       per_cpu(cpufreq_cpu_governor, j) = data->governor;
 #endif
                        cpu_sys_dev = get_cpu_sysdev(j);
                        sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
@@ -1153,7 +1153,7 @@ EXPORT_SYMBOL(cpufreq_quick_get);
 
 static unsigned int __cpufreq_get(unsigned int cpu)
 {
-       struct cpufreq_policy *policy = cpufreq_cpu_data[cpu];
+       struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
        unsigned int ret_freq = 0;
 
        if (!cpufreq_driver->get)
@@ -1822,16 +1822,19 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
        cpufreq_driver = driver_data;
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
-       ret = sysdev_driver_register(&cpu_sysdev_class,&cpufreq_sysdev_driver);
+       ret = sysdev_driver_register(&cpu_sysdev_class,
+                                       &cpufreq_sysdev_driver);
 
        if ((!ret) && !(cpufreq_driver->flags & CPUFREQ_STICKY)) {
                int i;
                ret = -ENODEV;
 
                /* check for at least one working CPU */
-               for (i=0; i<NR_CPUS; i++)
-                       if (cpufreq_cpu_data[i])
+               for (i = 0; i < nr_cpu_ids; i++)
+                       if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
                                ret = 0;
+                               break;
+                       }
 
                /* if all ->init() calls failed, unregister */
                if (ret) {
index ae70d63a8b26eabb2b02d8c2ea28721fcd934b2a..c0ff97d375d79c83cdd3e52dbf65dc900c94c7a3 100644 (file)
@@ -43,7 +43,7 @@ struct cpufreq_stats {
 #endif
 };
 
-static struct cpufreq_stats *cpufreq_stats_table[NR_CPUS];
+static DEFINE_PER_CPU(struct cpufreq_stats *, cpufreq_stats_table);
 
 struct cpufreq_stats_attribute {
        struct attribute attr;
@@ -58,7 +58,7 @@ cpufreq_stats_update (unsigned int cpu)
 
        cur_time = get_jiffies_64();
        spin_lock(&cpufreq_stats_lock);
-       stat = cpufreq_stats_table[cpu];
+       stat = per_cpu(cpufreq_stats_table, cpu);
        if (stat->time_in_state)
                stat->time_in_state[stat->last_index] =
                        cputime64_add(stat->time_in_state[stat->last_index],
@@ -71,11 +71,11 @@ cpufreq_stats_update (unsigned int cpu)
 static ssize_t
 show_total_trans(struct cpufreq_policy *policy, char *buf)
 {
-       struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+       struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu);
        if (!stat)
                return 0;
        return sprintf(buf, "%d\n",
-                       cpufreq_stats_table[stat->cpu]->total_trans);
+                       per_cpu(cpufreq_stats_table, stat->cpu)->total_trans);
 }
 
 static ssize_t
@@ -83,7 +83,7 @@ show_time_in_state(struct cpufreq_policy *policy, char *buf)
 {
        ssize_t len = 0;
        int i;
-       struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+       struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu);
        if (!stat)
                return 0;
        cpufreq_stats_update(stat->cpu);
@@ -101,7 +101,7 @@ show_trans_table(struct cpufreq_policy *policy, char *buf)
        ssize_t len = 0;
        int i, j;
 
-       struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+       struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu);
        if (!stat)
                return 0;
        cpufreq_stats_update(stat->cpu);
@@ -170,7 +170,7 @@ freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
 
 static void cpufreq_stats_free_table(unsigned int cpu)
 {
-       struct cpufreq_stats *stat = cpufreq_stats_table[cpu];
+       struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, cpu);
        struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
        if (policy && policy->cpu == cpu)
                sysfs_remove_group(&policy->kobj, &stats_attr_group);
@@ -178,7 +178,7 @@ static void cpufreq_stats_free_table(unsigned int cpu)
                kfree(stat->time_in_state);
                kfree(stat);
        }
-       cpufreq_stats_table[cpu] = NULL;
+       per_cpu(cpufreq_stats_table, cpu) = NULL;
        if (policy)
                cpufreq_cpu_put(policy);
 }
@@ -192,7 +192,7 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
        struct cpufreq_policy *data;
        unsigned int alloc_size;
        unsigned int cpu = policy->cpu;
-       if (cpufreq_stats_table[cpu])
+       if (per_cpu(cpufreq_stats_table, cpu))
                return -EBUSY;
        if ((stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL)) == NULL)
                return -ENOMEM;
@@ -207,7 +207,7 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
                goto error_out;
 
        stat->cpu = cpu;
-       cpufreq_stats_table[cpu] = stat;
+       per_cpu(cpufreq_stats_table, cpu) = stat;
 
        for (i=0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
                unsigned int freq = table[i].frequency;
@@ -251,7 +251,7 @@ error_out:
        cpufreq_cpu_put(data);
 error_get_fail:
        kfree(stat);
-       cpufreq_stats_table[cpu] = NULL;
+       per_cpu(cpufreq_stats_table, cpu) = NULL;
        return ret;
 }
 
@@ -284,7 +284,7 @@ cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val,
        if (val != CPUFREQ_POSTCHANGE)
                return 0;
 
-       stat = cpufreq_stats_table[freq->cpu];
+       stat = per_cpu(cpufreq_stats_table, freq->cpu);
        if (!stat)
                return 0;
 
index b64c6bc445e31580074fe7cc437fdfdf3e880cb9..9071d80fbba2427d6b29c911832e169bf201466a 100644 (file)
@@ -174,7 +174,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
 
-static struct cpufreq_frequency_table *show_table[NR_CPUS];
+static DEFINE_PER_CPU(struct cpufreq_frequency_table *, show_table);
 /**
  * show_available_freqs - show available frequencies for the specified CPU
  */
@@ -185,10 +185,10 @@ static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf)
        ssize_t count = 0;
        struct cpufreq_frequency_table *table;
 
-       if (!show_table[cpu])
+       if (!per_cpu(show_table, cpu))
                return -ENODEV;
 
-       table = show_table[cpu];
+       table = per_cpu(show_table, cpu);
 
        for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
                if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
@@ -217,20 +217,20 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
                                      unsigned int cpu)
 {
        dprintk("setting show_table for cpu %u to %p\n", cpu, table);
-       show_table[cpu] = table;
+       per_cpu(show_table, cpu) = table;
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_attr);
 
 void cpufreq_frequency_table_put_attr(unsigned int cpu)
 {
        dprintk("clearing show_table for cpu %u\n", cpu);
-       show_table[cpu] = NULL;
+       per_cpu(show_table, cpu) = NULL;
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr);
 
 struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
 {
-       return show_table[cpu];
+       return per_cpu(show_table, cpu);
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
 
index e949618b9be0ee3d0e95b48bbac4fd5f93ad21f2..31a0e0b455b6e3c61ffef1ef004351fac0085dcd 100644 (file)
@@ -21,7 +21,8 @@ static int __init cpuidle_sysfs_setup(char *unused)
 }
 __setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup);
 
-static ssize_t show_available_governors(struct sys_device *dev, char *buf)
+static ssize_t show_available_governors(struct sys_device *dev,
+               struct sysdev_attribute *attr, char *buf)
 {
        ssize_t i = 0;
        struct cpuidle_governor *tmp;
@@ -39,7 +40,8 @@ out:
        return i;
 }
 
-static ssize_t show_current_driver(struct sys_device *dev, char *buf)
+static ssize_t show_current_driver(struct sys_device *dev,
+               struct sysdev_attribute *attr, char *buf)
 {
        ssize_t ret;
 
@@ -53,7 +55,8 @@ static ssize_t show_current_driver(struct sys_device *dev, char *buf)
        return ret;
 }
 
-static ssize_t show_current_governor(struct sys_device *dev, char *buf)
+static ssize_t show_current_governor(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        ssize_t ret;
 
@@ -68,6 +71,7 @@ static ssize_t show_current_governor(struct sys_device *dev, char *buf)
 }
 
 static ssize_t store_current_governor(struct sys_device *dev,
+       struct sysdev_attribute *attr,
        const char *buf, size_t count)
 {
        char gov_name[CPUIDLE_NAME_LEN];
index bf5b92f86df7e07ca3813a4e127f21c7b92f9bff..ec249d2db633edb68d57ad22f8f27d42e2c8e5f4 100644 (file)
 #include <linux/device.h>
 #include <linux/dca.h>
 
-MODULE_LICENSE("GPL");
+#define DCA_VERSION "1.4"
 
-/* For now we're assuming a single, global, DCA provider for the system. */
+MODULE_VERSION(DCA_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Intel Corporation");
 
 static DEFINE_SPINLOCK(dca_lock);
 
-static struct dca_provider *global_dca = NULL;
+static LIST_HEAD(dca_providers);
+
+static struct dca_provider *dca_find_provider_by_dev(struct device *dev)
+{
+       struct dca_provider *dca, *ret = NULL;
+
+       list_for_each_entry(dca, &dca_providers, node) {
+               if ((!dev) || (dca->ops->dev_managed(dca, dev))) {
+                       ret = dca;
+                       break;
+               }
+       }
+
+       return ret;
+}
 
 /**
  * dca_add_requester - add a dca client to the list
@@ -42,25 +58,39 @@ static struct dca_provider *global_dca = NULL;
  */
 int dca_add_requester(struct device *dev)
 {
-       int err, slot;
+       struct dca_provider *dca;
+       int err, slot = -ENODEV;
 
-       if (!global_dca)
-               return -ENODEV;
+       if (!dev)
+               return -EFAULT;
 
        spin_lock(&dca_lock);
-       slot = global_dca->ops->add_requester(global_dca, dev);
-       spin_unlock(&dca_lock);
-       if (slot < 0)
+
+       /* check if the requester has not been added already */
+       dca = dca_find_provider_by_dev(dev);
+       if (dca) {
+               spin_unlock(&dca_lock);
+               return -EEXIST;
+       }
+
+       list_for_each_entry(dca, &dca_providers, node) {
+               slot = dca->ops->add_requester(dca, dev);
+               if (slot >= 0)
+                       break;
+       }
+       if (slot < 0) {
+               spin_unlock(&dca_lock);
                return slot;
+       }
 
-       err = dca_sysfs_add_req(global_dca, dev, slot);
+       err = dca_sysfs_add_req(dca, dev, slot);
        if (err) {
-               spin_lock(&dca_lock);
-               global_dca->ops->remove_requester(global_dca, dev);
+               dca->ops->remove_requester(dca, dev);
                spin_unlock(&dca_lock);
                return err;
        }
 
+       spin_unlock(&dca_lock);
        return 0;
 }
 EXPORT_SYMBOL_GPL(dca_add_requester);
@@ -71,30 +101,78 @@ EXPORT_SYMBOL_GPL(dca_add_requester);
  */
 int dca_remove_requester(struct device *dev)
 {
+       struct dca_provider *dca;
        int slot;
-       if (!global_dca)
-               return -ENODEV;
+
+       if (!dev)
+               return -EFAULT;
 
        spin_lock(&dca_lock);
-       slot = global_dca->ops->remove_requester(global_dca, dev);
-       spin_unlock(&dca_lock);
-       if (slot < 0)
+       dca = dca_find_provider_by_dev(dev);
+       if (!dca) {
+               spin_unlock(&dca_lock);
+               return -ENODEV;
+       }
+       slot = dca->ops->remove_requester(dca, dev);
+       if (slot < 0) {
+               spin_unlock(&dca_lock);
                return slot;
+       }
 
-       dca_sysfs_remove_req(global_dca, slot);
+       dca_sysfs_remove_req(dca, slot);
+
+       spin_unlock(&dca_lock);
        return 0;
 }
 EXPORT_SYMBOL_GPL(dca_remove_requester);
 
 /**
- * dca_get_tag - return the dca tag for the given cpu
+ * dca_common_get_tag - return the dca tag (serves both new and old api)
+ * @dev - the device that wants dca service
  * @cpu - the cpuid as returned by get_cpu()
  */
-u8 dca_get_tag(int cpu)
+u8 dca_common_get_tag(struct device *dev, int cpu)
 {
-       if (!global_dca)
+       struct dca_provider *dca;
+       u8 tag;
+
+       spin_lock(&dca_lock);
+
+       dca = dca_find_provider_by_dev(dev);
+       if (!dca) {
+               spin_unlock(&dca_lock);
                return -ENODEV;
-       return global_dca->ops->get_tag(global_dca, cpu);
+       }
+       tag = dca->ops->get_tag(dca, dev, cpu);
+
+       spin_unlock(&dca_lock);
+       return tag;
+}
+
+/**
+ * dca3_get_tag - return the dca tag to the requester device
+ *                for the given cpu (new api)
+ * @dev - the device that wants dca service
+ * @cpu - the cpuid as returned by get_cpu()
+ */
+u8 dca3_get_tag(struct device *dev, int cpu)
+{
+       if (!dev)
+               return -EFAULT;
+
+       return dca_common_get_tag(dev, cpu);
+}
+EXPORT_SYMBOL_GPL(dca3_get_tag);
+
+/**
+ * dca_get_tag - return the dca tag for the given cpu (old api)
+ * @cpu - the cpuid as returned by get_cpu()
+ */
+u8 dca_get_tag(int cpu)
+{
+       struct device *dev = NULL;
+
+       return dca_common_get_tag(dev, cpu);
 }
 EXPORT_SYMBOL_GPL(dca_get_tag);
 
@@ -140,12 +218,10 @@ int register_dca_provider(struct dca_provider *dca, struct device *dev)
 {
        int err;
 
-       if (global_dca)
-               return -EEXIST;
        err = dca_sysfs_add_provider(dca, dev);
        if (err)
                return err;
-       global_dca = dca;
+       list_add(&dca->node, &dca_providers);
        blocking_notifier_call_chain(&dca_provider_chain,
                                     DCA_PROVIDER_ADD, NULL);
        return 0;
@@ -158,11 +234,9 @@ EXPORT_SYMBOL_GPL(register_dca_provider);
  */
 void unregister_dca_provider(struct dca_provider *dca)
 {
-       if (!global_dca)
-               return;
        blocking_notifier_call_chain(&dca_provider_chain,
                                     DCA_PROVIDER_REMOVE, NULL);
-       global_dca = NULL;
+       list_del(&dca->node);
        dca_sysfs_remove_provider(dca);
 }
 EXPORT_SYMBOL_GPL(unregister_dca_provider);
@@ -187,6 +261,7 @@ EXPORT_SYMBOL_GPL(dca_unregister_notify);
 
 static int __init dca_init(void)
 {
+       printk(KERN_ERR "dca service started, version %s\n", DCA_VERSION);
        return dca_sysfs_init();
 }
 
index 011328faa5f21c88b1c007eb405129137e709a87..7af4b403bd2d12a6f3219f8f8d6615f5de69def1 100644 (file)
@@ -13,9 +13,11 @@ static spinlock_t dca_idr_lock;
 int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot)
 {
        struct device *cd;
+       static int req_count;
 
-       cd = device_create(dca_class, dca->cd, MKDEV(0, slot + 1),
-                          "requester%d", slot);
+       cd = device_create_drvdata(dca_class, dca->cd,
+                                  MKDEV(0, slot + 1), NULL,
+                                  "requester%d", req_count++);
        if (IS_ERR(cd))
                return PTR_ERR(cd);
        return 0;
@@ -46,7 +48,8 @@ idr_try_again:
                return err;
        }
 
-       cd = device_create(dca_class, dev, MKDEV(0, 0), "dca%d", dca->id);
+       cd = device_create_drvdata(dca_class, dev, MKDEV(0, 0), NULL,
+                                  "dca%d", dca->id);
        if (IS_ERR(cd)) {
                spin_lock(&dca_idr_lock);
                idr_remove(&dca_idr, dca->id);
index 6239c3df30ac53fd877e4779c721068568556e1d..cd303901eb5b20c13b1636ec32614d3ac8800a60 100644 (file)
@@ -4,13 +4,14 @@
 
 menuconfig DMADEVICES
        bool "DMA Engine support"
-       depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX || PPC
-       depends on !HIGHMEM64G
+       depends on !HIGHMEM64G && HAS_DMA
        help
          DMA engines can do asynchronous data transfers without
          involving the host CPU.  Currently, this framework can be
          used to offload memory copies in the network stack and
-         RAID operations in the MD driver.
+         RAID operations in the MD driver.  This menu only presents
+         DMA Device drivers supported by the configured arch, it may
+         be empty in some cases.
 
 if DMADEVICES
 
@@ -37,6 +38,15 @@ config INTEL_IOP_ADMA
        help
          Enable support for the Intel(R) IOP Series RAID engines.
 
+config DW_DMAC
+       tristate "Synopsys DesignWare AHB DMA support"
+       depends on AVR32
+       select DMA_ENGINE
+       default y if CPU_AT32AP7000
+       help
+         Support the Synopsys DesignWare AHB DMA controller.  This
+         can be integrated in chips such as the Atmel AT32ap7000.
+
 config FSL_DMA
        bool "Freescale MPC85xx/MPC83xx DMA support"
        depends on PPC
@@ -46,6 +56,14 @@ config FSL_DMA
          MPC8560/40, MPC8555, MPC8548 and MPC8641 processors.
          The MPC8349, MPC8360 is also supported.
 
+config MV_XOR
+       bool "Marvell XOR engine support"
+       depends on PLAT_ORION
+       select ASYNC_CORE
+       select DMA_ENGINE
+       ---help---
+         Enable support for the Marvell XOR engine.
+
 config DMA_ENGINE
        bool
 
@@ -55,10 +73,19 @@ comment "DMA Clients"
 config NET_DMA
        bool "Network: TCP receive copy offload"
        depends on DMA_ENGINE && NET
+       default (INTEL_IOATDMA || FSL_DMA)
        help
          This enables the use of DMA engines in the network stack to
          offload receive copy-to-user operations, freeing CPU cycles.
-         Since this is the main user of the DMA engine, it should be enabled;
-         say Y here.
+
+         Say Y here if you enabled INTEL_IOATDMA or FSL_DMA, otherwise
+         say N.
+
+config DMATEST
+       tristate "DMA Test client"
+       depends on DMA_ENGINE
+       help
+         Simple DMA test client. Say N unless you're debugging a
+         DMA Device driver.
 
 endif
index c8036d94590277d24f994a82c61fccbe51a89f07..14f59527d4f6bc5ab02e750e7580f209506cd7c1 100644 (file)
@@ -1,6 +1,9 @@
 obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
 obj-$(CONFIG_NET_DMA) += iovlock.o
+obj-$(CONFIG_DMATEST) += dmatest.o
 obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
 ioatdma-objs := ioat.o ioat_dma.o ioat_dca.o
 obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
 obj-$(CONFIG_FSL_DMA) += fsldma.o
+obj-$(CONFIG_MV_XOR) += mv_xor.o
+obj-$(CONFIG_DW_DMAC) += dw_dmac.o
index 97b329e767983172a7069687d4d8fedb1e28cee7..dc003a3a787d545207fed8be6e81bb4aacd970c1 100644 (file)
@@ -169,12 +169,18 @@ static void dma_client_chan_alloc(struct dma_client *client)
        enum dma_state_client ack;
 
        /* Find a channel */
-       list_for_each_entry(device, &dma_device_list, global_node)
+       list_for_each_entry(device, &dma_device_list, global_node) {
+               /* Does the client require a specific DMA controller? */
+               if (client->slave && client->slave->dma_dev
+                               && client->slave->dma_dev != device->dev)
+                       continue;
+
                list_for_each_entry(chan, &device->channels, device_node) {
                        if (!dma_chan_satisfies_mask(chan, client->cap_mask))
                                continue;
 
-                       desc = chan->device->device_alloc_chan_resources(chan);
+                       desc = chan->device->device_alloc_chan_resources(
+                                       chan, client);
                        if (desc >= 0) {
                                ack = client->event_callback(client,
                                                chan,
@@ -183,12 +189,14 @@ static void dma_client_chan_alloc(struct dma_client *client)
                                /* we are done once this client rejects
                                 * an available resource
                                 */
-                               if (ack == DMA_ACK)
+                               if (ack == DMA_ACK) {
                                        dma_chan_get(chan);
-                               else if (ack == DMA_NAK)
+                                       chan->client_count++;
+                               } else if (ack == DMA_NAK)
                                        return;
                        }
                }
+       }
 }
 
 enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)
@@ -272,8 +280,10 @@ static void dma_clients_notify_removed(struct dma_chan *chan)
                /* client was holding resources for this channel so
                 * free it
                 */
-               if (ack == DMA_ACK)
+               if (ack == DMA_ACK) {
                        dma_chan_put(chan);
+                       chan->client_count--;
+               }
        }
 
        mutex_unlock(&dma_list_mutex);
@@ -285,6 +295,10 @@ static void dma_clients_notify_removed(struct dma_chan *chan)
  */
 void dma_async_client_register(struct dma_client *client)
 {
+       /* validate client data */
+       BUG_ON(dma_has_cap(DMA_SLAVE, client->cap_mask) &&
+               !client->slave);
+
        mutex_lock(&dma_list_mutex);
        list_add_tail(&client->global_node, &dma_client_list);
        mutex_unlock(&dma_list_mutex);
@@ -313,8 +327,10 @@ void dma_async_client_unregister(struct dma_client *client)
                        ack = client->event_callback(client, chan,
                                DMA_RESOURCE_REMOVED);
 
-                       if (ack == DMA_ACK)
+                       if (ack == DMA_ACK) {
                                dma_chan_put(chan);
+                               chan->client_count--;
+                       }
                }
 
        list_del(&client->global_node);
@@ -359,6 +375,10 @@ int dma_async_device_register(struct dma_device *device)
                !device->device_prep_dma_memset);
        BUG_ON(dma_has_cap(DMA_INTERRUPT, device->cap_mask) &&
                !device->device_prep_dma_interrupt);
+       BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) &&
+               !device->device_prep_slave_sg);
+       BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) &&
+               !device->device_terminate_all);
 
        BUG_ON(!device->device_alloc_chan_resources);
        BUG_ON(!device->device_free_chan_resources);
@@ -378,7 +398,7 @@ int dma_async_device_register(struct dma_device *device)
 
                chan->chan_id = chancnt++;
                chan->dev.class = &dma_devclass;
-               chan->dev.parent = NULL;
+               chan->dev.parent = device->dev;
                snprintf(chan->dev.bus_id, BUS_ID_SIZE, "dma%dchan%d",
                         device->dev_id, chan->chan_id);
 
@@ -394,6 +414,7 @@ int dma_async_device_register(struct dma_device *device)
                kref_get(&device->refcount);
                kref_get(&device->refcount);
                kref_init(&chan->refcount);
+               chan->client_count = 0;
                chan->slow_ref = 0;
                INIT_RCU_HEAD(&chan->rcu);
        }
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
new file mode 100644 (file)
index 0000000..a08d197
--- /dev/null
@@ -0,0 +1,444 @@
+/*
+ * DMA Engine test module
+ *
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * 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/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/random.h>
+#include <linux/wait.h>
+
+static unsigned int test_buf_size = 16384;
+module_param(test_buf_size, uint, S_IRUGO);
+MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer");
+
+static char test_channel[BUS_ID_SIZE];
+module_param_string(channel, test_channel, sizeof(test_channel), S_IRUGO);
+MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)");
+
+static char test_device[BUS_ID_SIZE];
+module_param_string(device, test_device, sizeof(test_device), S_IRUGO);
+MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)");
+
+static unsigned int threads_per_chan = 1;
+module_param(threads_per_chan, uint, S_IRUGO);
+MODULE_PARM_DESC(threads_per_chan,
+               "Number of threads to start per channel (default: 1)");
+
+static unsigned int max_channels;
+module_param(max_channels, uint, S_IRUGO);
+MODULE_PARM_DESC(nr_channels,
+               "Maximum number of channels to use (default: all)");
+
+/*
+ * Initialization patterns. All bytes in the source buffer has bit 7
+ * set, all bytes in the destination buffer has bit 7 cleared.
+ *
+ * Bit 6 is set for all bytes which are to be copied by the DMA
+ * engine. Bit 5 is set for all bytes which are to be overwritten by
+ * the DMA engine.
+ *
+ * The remaining bits are the inverse of a counter which increments by
+ * one for each byte address.
+ */
+#define PATTERN_SRC            0x80
+#define PATTERN_DST            0x00
+#define PATTERN_COPY           0x40
+#define PATTERN_OVERWRITE      0x20
+#define PATTERN_COUNT_MASK     0x1f
+
+struct dmatest_thread {
+       struct list_head        node;
+       struct task_struct      *task;
+       struct dma_chan         *chan;
+       u8                      *srcbuf;
+       u8                      *dstbuf;
+};
+
+struct dmatest_chan {
+       struct list_head        node;
+       struct dma_chan         *chan;
+       struct list_head        threads;
+};
+
+/*
+ * These are protected by dma_list_mutex since they're only used by
+ * the DMA client event callback
+ */
+static LIST_HEAD(dmatest_channels);
+static unsigned int nr_channels;
+
+static bool dmatest_match_channel(struct dma_chan *chan)
+{
+       if (test_channel[0] == '\0')
+               return true;
+       return strcmp(chan->dev.bus_id, test_channel) == 0;
+}
+
+static bool dmatest_match_device(struct dma_device *device)
+{
+       if (test_device[0] == '\0')
+               return true;
+       return strcmp(device->dev->bus_id, test_device) == 0;
+}
+
+static unsigned long dmatest_random(void)
+{
+       unsigned long buf;
+
+       get_random_bytes(&buf, sizeof(buf));
+       return buf;
+}
+
+static void dmatest_init_srcbuf(u8 *buf, unsigned int start, unsigned int len)
+{
+       unsigned int i;
+
+       for (i = 0; i < start; i++)
+               buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+       for ( ; i < start + len; i++)
+               buf[i] = PATTERN_SRC | PATTERN_COPY
+                       | (~i & PATTERN_COUNT_MASK);;
+       for ( ; i < test_buf_size; i++)
+               buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+}
+
+static void dmatest_init_dstbuf(u8 *buf, unsigned int start, unsigned int len)
+{
+       unsigned int i;
+
+       for (i = 0; i < start; i++)
+               buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+       for ( ; i < start + len; i++)
+               buf[i] = PATTERN_DST | PATTERN_OVERWRITE
+                       | (~i & PATTERN_COUNT_MASK);
+       for ( ; i < test_buf_size; i++)
+               buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+}
+
+static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
+               unsigned int counter, bool is_srcbuf)
+{
+       u8              diff = actual ^ pattern;
+       u8              expected = pattern | (~counter & PATTERN_COUNT_MASK);
+       const char      *thread_name = current->comm;
+
+       if (is_srcbuf)
+               pr_warning("%s: srcbuf[0x%x] overwritten!"
+                               " Expected %02x, got %02x\n",
+                               thread_name, index, expected, actual);
+       else if ((pattern & PATTERN_COPY)
+                       && (diff & (PATTERN_COPY | PATTERN_OVERWRITE)))
+               pr_warning("%s: dstbuf[0x%x] not copied!"
+                               " Expected %02x, got %02x\n",
+                               thread_name, index, expected, actual);
+       else if (diff & PATTERN_SRC)
+               pr_warning("%s: dstbuf[0x%x] was copied!"
+                               " Expected %02x, got %02x\n",
+                               thread_name, index, expected, actual);
+       else
+               pr_warning("%s: dstbuf[0x%x] mismatch!"
+                               " Expected %02x, got %02x\n",
+                               thread_name, index, expected, actual);
+}
+
+static unsigned int dmatest_verify(u8 *buf, unsigned int start,
+               unsigned int end, unsigned int counter, u8 pattern,
+               bool is_srcbuf)
+{
+       unsigned int i;
+       unsigned int error_count = 0;
+       u8 actual;
+
+       for (i = start; i < end; i++) {
+               actual = buf[i];
+               if (actual != (pattern | (~counter & PATTERN_COUNT_MASK))) {
+                       if (error_count < 32)
+                               dmatest_mismatch(actual, pattern, i, counter,
+                                               is_srcbuf);
+                       error_count++;
+               }
+               counter++;
+       }
+
+       if (error_count > 32)
+               pr_warning("%s: %u errors suppressed\n",
+                       current->comm, error_count - 32);
+
+       return error_count;
+}
+
+/*
+ * This function repeatedly tests DMA transfers of various lengths and
+ * offsets until it is told to exit by kthread_stop(). There may be
+ * multiple threads running this function in parallel for a single
+ * channel, and there may be multiple channels being tested in
+ * parallel.
+ *
+ * Before each test, the source and destination buffer is initialized
+ * with a known pattern. This pattern is different depending on
+ * whether it's in an area which is supposed to be copied or
+ * overwritten, and different in the source and destination buffers.
+ * So if the DMA engine doesn't copy exactly what we tell it to copy,
+ * we'll notice.
+ */
+static int dmatest_func(void *data)
+{
+       struct dmatest_thread   *thread = data;
+       struct dma_chan         *chan;
+       const char              *thread_name;
+       unsigned int            src_off, dst_off, len;
+       unsigned int            error_count;
+       unsigned int            failed_tests = 0;
+       unsigned int            total_tests = 0;
+       dma_cookie_t            cookie;
+       enum dma_status         status;
+       int                     ret;
+
+       thread_name = current->comm;
+
+       ret = -ENOMEM;
+       thread->srcbuf = kmalloc(test_buf_size, GFP_KERNEL);
+       if (!thread->srcbuf)
+               goto err_srcbuf;
+       thread->dstbuf = kmalloc(test_buf_size, GFP_KERNEL);
+       if (!thread->dstbuf)
+               goto err_dstbuf;
+
+       smp_rmb();
+       chan = thread->chan;
+       dma_chan_get(chan);
+
+       while (!kthread_should_stop()) {
+               total_tests++;
+
+               len = dmatest_random() % test_buf_size + 1;
+               src_off = dmatest_random() % (test_buf_size - len + 1);
+               dst_off = dmatest_random() % (test_buf_size - len + 1);
+
+               dmatest_init_srcbuf(thread->srcbuf, src_off, len);
+               dmatest_init_dstbuf(thread->dstbuf, dst_off, len);
+
+               cookie = dma_async_memcpy_buf_to_buf(chan,
+                               thread->dstbuf + dst_off,
+                               thread->srcbuf + src_off,
+                               len);
+               if (dma_submit_error(cookie)) {
+                       pr_warning("%s: #%u: submit error %d with src_off=0x%x "
+                                       "dst_off=0x%x len=0x%x\n",
+                                       thread_name, total_tests - 1, cookie,
+                                       src_off, dst_off, len);
+                       msleep(100);
+                       failed_tests++;
+                       continue;
+               }
+               dma_async_memcpy_issue_pending(chan);
+
+               do {
+                       msleep(1);
+                       status = dma_async_memcpy_complete(
+                                       chan, cookie, NULL, NULL);
+               } while (status == DMA_IN_PROGRESS);
+
+               if (status == DMA_ERROR) {
+                       pr_warning("%s: #%u: error during copy\n",
+                                       thread_name, total_tests - 1);
+                       failed_tests++;
+                       continue;
+               }
+
+               error_count = 0;
+
+               pr_debug("%s: verifying source buffer...\n", thread_name);
+               error_count += dmatest_verify(thread->srcbuf, 0, src_off,
+                               0, PATTERN_SRC, true);
+               error_count += dmatest_verify(thread->srcbuf, src_off,
+                               src_off + len, src_off,
+                               PATTERN_SRC | PATTERN_COPY, true);
+               error_count += dmatest_verify(thread->srcbuf, src_off + len,
+                               test_buf_size, src_off + len,
+                               PATTERN_SRC, true);
+
+               pr_debug("%s: verifying dest buffer...\n",
+                               thread->task->comm);
+               error_count += dmatest_verify(thread->dstbuf, 0, dst_off,
+                               0, PATTERN_DST, false);
+               error_count += dmatest_verify(thread->dstbuf, dst_off,
+                               dst_off + len, src_off,
+                               PATTERN_SRC | PATTERN_COPY, false);
+               error_count += dmatest_verify(thread->dstbuf, dst_off + len,
+                               test_buf_size, dst_off + len,
+                               PATTERN_DST, false);
+
+               if (error_count) {
+                       pr_warning("%s: #%u: %u errors with "
+                               "src_off=0x%x dst_off=0x%x len=0x%x\n",
+                               thread_name, total_tests - 1, error_count,
+                               src_off, dst_off, len);
+                       failed_tests++;
+               } else {
+                       pr_debug("%s: #%u: No errors with "
+                               "src_off=0x%x dst_off=0x%x len=0x%x\n",
+                               thread_name, total_tests - 1,
+                               src_off, dst_off, len);
+               }
+       }
+
+       ret = 0;
+       dma_chan_put(chan);
+       kfree(thread->dstbuf);
+err_dstbuf:
+       kfree(thread->srcbuf);
+err_srcbuf:
+       pr_notice("%s: terminating after %u tests, %u failures (status %d)\n",
+                       thread_name, total_tests, failed_tests, ret);
+       return ret;
+}
+
+static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
+{
+       struct dmatest_thread   *thread;
+       struct dmatest_thread   *_thread;
+       int                     ret;
+
+       list_for_each_entry_safe(thread, _thread, &dtc->threads, node) {
+               ret = kthread_stop(thread->task);
+               pr_debug("dmatest: thread %s exited with status %d\n",
+                               thread->task->comm, ret);
+               list_del(&thread->node);
+               kfree(thread);
+       }
+       kfree(dtc);
+}
+
+static enum dma_state_client dmatest_add_channel(struct dma_chan *chan)
+{
+       struct dmatest_chan     *dtc;
+       struct dmatest_thread   *thread;
+       unsigned int            i;
+
+       dtc = kmalloc(sizeof(struct dmatest_chan), GFP_ATOMIC);
+       if (!dtc) {
+               pr_warning("dmatest: No memory for %s\n", chan->dev.bus_id);
+               return DMA_NAK;
+       }
+
+       dtc->chan = chan;
+       INIT_LIST_HEAD(&dtc->threads);
+
+       for (i = 0; i < threads_per_chan; i++) {
+               thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL);
+               if (!thread) {
+                       pr_warning("dmatest: No memory for %s-test%u\n",
+                                       chan->dev.bus_id, i);
+                       break;
+               }
+               thread->chan = dtc->chan;
+               smp_wmb();
+               thread->task = kthread_run(dmatest_func, thread, "%s-test%u",
+                               chan->dev.bus_id, i);
+               if (IS_ERR(thread->task)) {
+                       pr_warning("dmatest: Failed to run thread %s-test%u\n",
+                                       chan->dev.bus_id, i);
+                       kfree(thread);
+                       break;
+               }
+
+               /* srcbuf and dstbuf are allocated by the thread itself */
+
+               list_add_tail(&thread->node, &dtc->threads);
+       }
+
+       pr_info("dmatest: Started %u threads using %s\n", i, chan->dev.bus_id);
+
+       list_add_tail(&dtc->node, &dmatest_channels);
+       nr_channels++;
+
+       return DMA_ACK;
+}
+
+static enum dma_state_client dmatest_remove_channel(struct dma_chan *chan)
+{
+       struct dmatest_chan     *dtc, *_dtc;
+
+       list_for_each_entry_safe(dtc, _dtc, &dmatest_channels, node) {
+               if (dtc->chan == chan) {
+                       list_del(&dtc->node);
+                       dmatest_cleanup_channel(dtc);
+                       pr_debug("dmatest: lost channel %s\n",
+                                       chan->dev.bus_id);
+                       return DMA_ACK;
+               }
+       }
+
+       return DMA_DUP;
+}
+
+/*
+ * Start testing threads as new channels are assigned to us, and kill
+ * them when the channels go away.
+ *
+ * When we unregister the client, all channels are removed so this
+ * will also take care of cleaning things up when the module is
+ * unloaded.
+ */
+static enum dma_state_client
+dmatest_event(struct dma_client *client, struct dma_chan *chan,
+               enum dma_state state)
+{
+       enum dma_state_client   ack = DMA_NAK;
+
+       switch (state) {
+       case DMA_RESOURCE_AVAILABLE:
+               if (!dmatest_match_channel(chan)
+                               || !dmatest_match_device(chan->device))
+                       ack = DMA_DUP;
+               else if (max_channels && nr_channels >= max_channels)
+                       ack = DMA_NAK;
+               else
+                       ack = dmatest_add_channel(chan);
+               break;
+
+       case DMA_RESOURCE_REMOVED:
+               ack = dmatest_remove_channel(chan);
+               break;
+
+       default:
+               pr_info("dmatest: Unhandled event %u (%s)\n",
+                               state, chan->dev.bus_id);
+               break;
+       }
+
+       return ack;
+}
+
+static struct dma_client dmatest_client = {
+       .event_callback = dmatest_event,
+};
+
+static int __init dmatest_init(void)
+{
+       dma_cap_set(DMA_MEMCPY, dmatest_client.cap_mask);
+       dma_async_client_register(&dmatest_client);
+       dma_async_client_chan_request(&dmatest_client);
+
+       return 0;
+}
+module_init(dmatest_init);
+
+static void __exit dmatest_exit(void)
+{
+       dma_async_client_unregister(&dmatest_client);
+}
+module_exit(dmatest_exit);
+
+MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
new file mode 100644 (file)
index 0000000..94df917
--- /dev/null
@@ -0,0 +1,1122 @@
+/*
+ * Driver for the Synopsys DesignWare DMA Controller (aka DMACA on
+ * AVR32 systems.)
+ *
+ * Copyright (C) 2007-2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "dw_dmac_regs.h"
+
+/*
+ * This supports the Synopsys "DesignWare AHB Central DMA Controller",
+ * (DW_ahb_dmac) which is used with various AMBA 2.0 systems (not all
+ * of which use ARM any more).  See the "Databook" from Synopsys for
+ * information beyond what licensees probably provide.
+ *
+ * The driver has currently been tested only with the Atmel AT32AP7000,
+ * which does not support descriptor writeback.
+ */
+
+/* NOTE:  DMS+SMS is system-specific. We should get this information
+ * from the platform code somehow.
+ */
+#define DWC_DEFAULT_CTLLO      (DWC_CTLL_DST_MSIZE(0)          \
+                               | DWC_CTLL_SRC_MSIZE(0)         \
+                               | DWC_CTLL_DMS(0)               \
+                               | DWC_CTLL_SMS(1)               \
+                               | DWC_CTLL_LLP_D_EN             \
+                               | DWC_CTLL_LLP_S_EN)
+
+/*
+ * This is configuration-dependent and usually a funny size like 4095.
+ * Let's round it down to the nearest power of two.
+ *
+ * Note that this is a transfer count, i.e. if we transfer 32-bit
+ * words, we can do 8192 bytes per descriptor.
+ *
+ * This parameter is also system-specific.
+ */
+#define DWC_MAX_COUNT  2048U
+
+/*
+ * Number of descriptors to allocate for each channel. This should be
+ * made configurable somehow; preferably, the clients (at least the
+ * ones using slave transfers) should be able to give us a hint.
+ */
+#define NR_DESCS_PER_CHANNEL   64
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Because we're not relying on writeback from the controller (it may not
+ * even be configured into the core!) we don't need to use dma_pool.  These
+ * descriptors -- and associated data -- are cacheable.  We do need to make
+ * sure their dcache entries are written back before handing them off to
+ * the controller, though.
+ */
+
+static struct dw_desc *dwc_first_active(struct dw_dma_chan *dwc)
+{
+       return list_entry(dwc->active_list.next, struct dw_desc, desc_node);
+}
+
+static struct dw_desc *dwc_first_queued(struct dw_dma_chan *dwc)
+{
+       return list_entry(dwc->queue.next, struct dw_desc, desc_node);
+}
+
+static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc)
+{
+       struct dw_desc *desc, *_desc;
+       struct dw_desc *ret = NULL;
+       unsigned int i = 0;
+
+       spin_lock_bh(&dwc->lock);
+       list_for_each_entry_safe(desc, _desc, &dwc->free_list, desc_node) {
+               if (async_tx_test_ack(&desc->txd)) {
+                       list_del(&desc->desc_node);
+                       ret = desc;
+                       break;
+               }
+               dev_dbg(&dwc->chan.dev, "desc %p not ACKed\n", desc);
+               i++;
+       }
+       spin_unlock_bh(&dwc->lock);
+
+       dev_vdbg(&dwc->chan.dev, "scanned %u descriptors on freelist\n", i);
+
+       return ret;
+}
+
+static void dwc_sync_desc_for_cpu(struct dw_dma_chan *dwc, struct dw_desc *desc)
+{
+       struct dw_desc  *child;
+
+       list_for_each_entry(child, &desc->txd.tx_list, desc_node)
+               dma_sync_single_for_cpu(dwc->chan.dev.parent,
+                               child->txd.phys, sizeof(child->lli),
+                               DMA_TO_DEVICE);
+       dma_sync_single_for_cpu(dwc->chan.dev.parent,
+                       desc->txd.phys, sizeof(desc->lli),
+                       DMA_TO_DEVICE);
+}
+
+/*
+ * Move a descriptor, including any children, to the free list.
+ * `desc' must not be on any lists.
+ */
+static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc)
+{
+       if (desc) {
+               struct dw_desc *child;
+
+               dwc_sync_desc_for_cpu(dwc, desc);
+
+               spin_lock_bh(&dwc->lock);
+               list_for_each_entry(child, &desc->txd.tx_list, desc_node)
+                       dev_vdbg(&dwc->chan.dev,
+                                       "moving child desc %p to freelist\n",
+                                       child);
+               list_splice_init(&desc->txd.tx_list, &dwc->free_list);
+               dev_vdbg(&dwc->chan.dev, "moving desc %p to freelist\n", desc);
+               list_add(&desc->desc_node, &dwc->free_list);
+               spin_unlock_bh(&dwc->lock);
+       }
+}
+
+/* Called with dwc->lock held and bh disabled */
+static dma_cookie_t
+dwc_assign_cookie(struct dw_dma_chan *dwc, struct dw_desc *desc)
+{
+       dma_cookie_t cookie = dwc->chan.cookie;
+
+       if (++cookie < 0)
+               cookie = 1;
+
+       dwc->chan.cookie = cookie;
+       desc->txd.cookie = cookie;
+
+       return cookie;
+}
+
+/*----------------------------------------------------------------------*/
+
+/* Called with dwc->lock held and bh disabled */
+static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
+{
+       struct dw_dma   *dw = to_dw_dma(dwc->chan.device);
+
+       /* ASSERT:  channel is idle */
+       if (dma_readl(dw, CH_EN) & dwc->mask) {
+               dev_err(&dwc->chan.dev,
+                       "BUG: Attempted to start non-idle channel\n");
+               dev_err(&dwc->chan.dev,
+                       "  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+                       channel_readl(dwc, SAR),
+                       channel_readl(dwc, DAR),
+                       channel_readl(dwc, LLP),
+                       channel_readl(dwc, CTL_HI),
+                       channel_readl(dwc, CTL_LO));
+
+               /* The tasklet will hopefully advance the queue... */
+               return;
+       }
+
+       channel_writel(dwc, LLP, first->txd.phys);
+       channel_writel(dwc, CTL_LO,
+                       DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
+       channel_writel(dwc, CTL_HI, 0);
+       channel_set_bit(dw, CH_EN, dwc->mask);
+}
+
+/*----------------------------------------------------------------------*/
+
+static void
+dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc)
+{
+       dma_async_tx_callback           callback;
+       void                            *param;
+       struct dma_async_tx_descriptor  *txd = &desc->txd;
+
+       dev_vdbg(&dwc->chan.dev, "descriptor %u complete\n", txd->cookie);
+
+       dwc->completed = txd->cookie;
+       callback = txd->callback;
+       param = txd->callback_param;
+
+       dwc_sync_desc_for_cpu(dwc, desc);
+       list_splice_init(&txd->tx_list, &dwc->free_list);
+       list_move(&desc->desc_node, &dwc->free_list);
+
+       /*
+        * We use dma_unmap_page() regardless of how the buffers were
+        * mapped before they were submitted...
+        */
+       if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP))
+               dma_unmap_page(dwc->chan.dev.parent, desc->lli.dar, desc->len,
+                               DMA_FROM_DEVICE);
+       if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP))
+               dma_unmap_page(dwc->chan.dev.parent, desc->lli.sar, desc->len,
+                               DMA_TO_DEVICE);
+
+       /*
+        * The API requires that no submissions are done from a
+        * callback, so we don't need to drop the lock here
+        */
+       if (callback)
+               callback(param);
+}
+
+static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc)
+{
+       struct dw_desc *desc, *_desc;
+       LIST_HEAD(list);
+
+       if (dma_readl(dw, CH_EN) & dwc->mask) {
+               dev_err(&dwc->chan.dev,
+                       "BUG: XFER bit set, but channel not idle!\n");
+
+               /* Try to continue after resetting the channel... */
+               channel_clear_bit(dw, CH_EN, dwc->mask);
+               while (dma_readl(dw, CH_EN) & dwc->mask)
+                       cpu_relax();
+       }
+
+       /*
+        * Submit queued descriptors ASAP, i.e. before we go through
+        * the completed ones.
+        */
+       if (!list_empty(&dwc->queue))
+               dwc_dostart(dwc, dwc_first_queued(dwc));
+       list_splice_init(&dwc->active_list, &list);
+       list_splice_init(&dwc->queue, &dwc->active_list);
+
+       list_for_each_entry_safe(desc, _desc, &list, desc_node)
+               dwc_descriptor_complete(dwc, desc);
+}
+
+static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
+{
+       dma_addr_t llp;
+       struct dw_desc *desc, *_desc;
+       struct dw_desc *child;
+       u32 status_xfer;
+
+       /*
+        * Clear block interrupt flag before scanning so that we don't
+        * miss any, and read LLP before RAW_XFER to ensure it is
+        * valid if we decide to scan the list.
+        */
+       dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+       llp = channel_readl(dwc, LLP);
+       status_xfer = dma_readl(dw, RAW.XFER);
+
+       if (status_xfer & dwc->mask) {
+               /* Everything we've submitted is done */
+               dma_writel(dw, CLEAR.XFER, dwc->mask);
+               dwc_complete_all(dw, dwc);
+               return;
+       }
+
+       dev_vdbg(&dwc->chan.dev, "scan_descriptors: llp=0x%x\n", llp);
+
+       list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
+               if (desc->lli.llp == llp)
+                       /* This one is currently in progress */
+                       return;
+
+               list_for_each_entry(child, &desc->txd.tx_list, desc_node)
+                       if (child->lli.llp == llp)
+                               /* Currently in progress */
+                               return;
+
+               /*
+                * No descriptors so far seem to be in progress, i.e.
+                * this one must be done.
+                */
+               dwc_descriptor_complete(dwc, desc);
+       }
+
+       dev_err(&dwc->chan.dev,
+               "BUG: All descriptors done, but channel not idle!\n");
+
+       /* Try to continue after resetting the channel... */
+       channel_clear_bit(dw, CH_EN, dwc->mask);
+       while (dma_readl(dw, CH_EN) & dwc->mask)
+               cpu_relax();
+
+       if (!list_empty(&dwc->queue)) {
+               dwc_dostart(dwc, dwc_first_queued(dwc));
+               list_splice_init(&dwc->queue, &dwc->active_list);
+       }
+}
+
+static void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli)
+{
+       dev_printk(KERN_CRIT, &dwc->chan.dev,
+                       "  desc: s0x%x d0x%x l0x%x c0x%x:%x\n",
+                       lli->sar, lli->dar, lli->llp,
+                       lli->ctlhi, lli->ctllo);
+}
+
+static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc)
+{
+       struct dw_desc *bad_desc;
+       struct dw_desc *child;
+
+       dwc_scan_descriptors(dw, dwc);
+
+       /*
+        * The descriptor currently at the head of the active list is
+        * borked. Since we don't have any way to report errors, we'll
+        * just have to scream loudly and try to carry on.
+        */
+       bad_desc = dwc_first_active(dwc);
+       list_del_init(&bad_desc->desc_node);
+       list_splice_init(&dwc->queue, dwc->active_list.prev);
+
+       /* Clear the error flag and try to restart the controller */
+       dma_writel(dw, CLEAR.ERROR, dwc->mask);
+       if (!list_empty(&dwc->active_list))
+               dwc_dostart(dwc, dwc_first_active(dwc));
+
+       /*
+        * KERN_CRITICAL may seem harsh, but since this only happens
+        * when someone submits a bad physical address in a
+        * descriptor, we should consider ourselves lucky that the
+        * controller flagged an error instead of scribbling over
+        * random memory locations.
+        */
+       dev_printk(KERN_CRIT, &dwc->chan.dev,
+                       "Bad descriptor submitted for DMA!\n");
+       dev_printk(KERN_CRIT, &dwc->chan.dev,
+                       "  cookie: %d\n", bad_desc->txd.cookie);
+       dwc_dump_lli(dwc, &bad_desc->lli);
+       list_for_each_entry(child, &bad_desc->txd.tx_list, desc_node)
+               dwc_dump_lli(dwc, &child->lli);
+
+       /* Pretend the descriptor completed successfully */
+       dwc_descriptor_complete(dwc, bad_desc);
+}
+
+static void dw_dma_tasklet(unsigned long data)
+{
+       struct dw_dma *dw = (struct dw_dma *)data;
+       struct dw_dma_chan *dwc;
+       u32 status_block;
+       u32 status_xfer;
+       u32 status_err;
+       int i;
+
+       status_block = dma_readl(dw, RAW.BLOCK);
+       status_xfer = dma_readl(dw, RAW.BLOCK);
+       status_err = dma_readl(dw, RAW.ERROR);
+
+       dev_vdbg(dw->dma.dev, "tasklet: status_block=%x status_err=%x\n",
+                       status_block, status_err);
+
+       for (i = 0; i < dw->dma.chancnt; i++) {
+               dwc = &dw->chan[i];
+               spin_lock(&dwc->lock);
+               if (status_err & (1 << i))
+                       dwc_handle_error(dw, dwc);
+               else if ((status_block | status_xfer) & (1 << i))
+                       dwc_scan_descriptors(dw, dwc);
+               spin_unlock(&dwc->lock);
+       }
+
+       /*
+        * Re-enable interrupts. Block Complete interrupts are only
+        * enabled if the INT_EN bit in the descriptor is set. This
+        * will trigger a scan before the whole list is done.
+        */
+       channel_set_bit(dw, MASK.XFER, dw->all_chan_mask);
+       channel_set_bit(dw, MASK.BLOCK, dw->all_chan_mask);
+       channel_set_bit(dw, MASK.ERROR, dw->all_chan_mask);
+}
+
+static irqreturn_t dw_dma_interrupt(int irq, void *dev_id)
+{
+       struct dw_dma *dw = dev_id;
+       u32 status;
+
+       dev_vdbg(dw->dma.dev, "interrupt: status=0x%x\n",
+                       dma_readl(dw, STATUS_INT));
+
+       /*
+        * Just disable the interrupts. We'll turn them back on in the
+        * softirq handler.
+        */
+       channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
+       channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
+       channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
+
+       status = dma_readl(dw, STATUS_INT);
+       if (status) {
+               dev_err(dw->dma.dev,
+                       "BUG: Unexpected interrupts pending: 0x%x\n",
+                       status);
+
+               /* Try to recover */
+               channel_clear_bit(dw, MASK.XFER, (1 << 8) - 1);
+               channel_clear_bit(dw, MASK.BLOCK, (1 << 8) - 1);
+               channel_clear_bit(dw, MASK.SRC_TRAN, (1 << 8) - 1);
+               channel_clear_bit(dw, MASK.DST_TRAN, (1 << 8) - 1);
+               channel_clear_bit(dw, MASK.ERROR, (1 << 8) - 1);
+       }
+
+       tasklet_schedule(&dw->tasklet);
+
+       return IRQ_HANDLED;
+}
+
+/*----------------------------------------------------------------------*/
+
+static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+       struct dw_desc          *desc = txd_to_dw_desc(tx);
+       struct dw_dma_chan      *dwc = to_dw_dma_chan(tx->chan);
+       dma_cookie_t            cookie;
+
+       spin_lock_bh(&dwc->lock);
+       cookie = dwc_assign_cookie(dwc, desc);
+
+       /*
+        * REVISIT: We should attempt to chain as many descriptors as
+        * possible, perhaps even appending to those already submitted
+        * for DMA. But this is hard to do in a race-free manner.
+        */
+       if (list_empty(&dwc->active_list)) {
+               dev_vdbg(&tx->chan->dev, "tx_submit: started %u\n",
+                               desc->txd.cookie);
+               dwc_dostart(dwc, desc);
+               list_add_tail(&desc->desc_node, &dwc->active_list);
+       } else {
+               dev_vdbg(&tx->chan->dev, "tx_submit: queued %u\n",
+                               desc->txd.cookie);
+
+               list_add_tail(&desc->desc_node, &dwc->queue);
+       }
+
+       spin_unlock_bh(&dwc->lock);
+
+       return cookie;
+}
+
+static struct dma_async_tx_descriptor *
+dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
+               size_t len, unsigned long flags)
+{
+       struct dw_dma_chan      *dwc = to_dw_dma_chan(chan);
+       struct dw_desc          *desc;
+       struct dw_desc          *first;
+       struct dw_desc          *prev;
+       size_t                  xfer_count;
+       size_t                  offset;
+       unsigned int            src_width;
+       unsigned int            dst_width;
+       u32                     ctllo;
+
+       dev_vdbg(&chan->dev, "prep_dma_memcpy d0x%x s0x%x l0x%zx f0x%lx\n",
+                       dest, src, len, flags);
+
+       if (unlikely(!len)) {
+               dev_dbg(&chan->dev, "prep_dma_memcpy: length is zero!\n");
+               return NULL;
+       }
+
+       /*
+        * We can be a lot more clever here, but this should take care
+        * of the most common optimization.
+        */
+       if (!((src | dest  | len) & 3))
+               src_width = dst_width = 2;
+       else if (!((src | dest | len) & 1))
+               src_width = dst_width = 1;
+       else
+               src_width = dst_width = 0;
+
+       ctllo = DWC_DEFAULT_CTLLO
+                       | DWC_CTLL_DST_WIDTH(dst_width)
+                       | DWC_CTLL_SRC_WIDTH(src_width)
+                       | DWC_CTLL_DST_INC
+                       | DWC_CTLL_SRC_INC
+                       | DWC_CTLL_FC_M2M;
+       prev = first = NULL;
+
+       for (offset = 0; offset < len; offset += xfer_count << src_width) {
+               xfer_count = min_t(size_t, (len - offset) >> src_width,
+                               DWC_MAX_COUNT);
+
+               desc = dwc_desc_get(dwc);
+               if (!desc)
+                       goto err_desc_get;
+
+               desc->lli.sar = src + offset;
+               desc->lli.dar = dest + offset;
+               desc->lli.ctllo = ctllo;
+               desc->lli.ctlhi = xfer_count;
+
+               if (!first) {
+                       first = desc;
+               } else {
+                       prev->lli.llp = desc->txd.phys;
+                       dma_sync_single_for_device(chan->dev.parent,
+                                       prev->txd.phys, sizeof(prev->lli),
+                                       DMA_TO_DEVICE);
+                       list_add_tail(&desc->desc_node,
+                                       &first->txd.tx_list);
+               }
+               prev = desc;
+       }
+
+
+       if (flags & DMA_PREP_INTERRUPT)
+               /* Trigger interrupt after last block */
+               prev->lli.ctllo |= DWC_CTLL_INT_EN;
+
+       prev->lli.llp = 0;
+       dma_sync_single_for_device(chan->dev.parent,
+                       prev->txd.phys, sizeof(prev->lli),
+                       DMA_TO_DEVICE);
+
+       first->txd.flags = flags;
+       first->len = len;
+
+       return &first->txd;
+
+err_desc_get:
+       dwc_desc_put(dwc, first);
+       return NULL;
+}
+
+static struct dma_async_tx_descriptor *
+dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+               unsigned int sg_len, enum dma_data_direction direction,
+               unsigned long flags)
+{
+       struct dw_dma_chan      *dwc = to_dw_dma_chan(chan);
+       struct dw_dma_slave     *dws = dwc->dws;
+       struct dw_desc          *prev;
+       struct dw_desc          *first;
+       u32                     ctllo;
+       dma_addr_t              reg;
+       unsigned int            reg_width;
+       unsigned int            mem_width;
+       unsigned int            i;
+       struct scatterlist      *sg;
+       size_t                  total_len = 0;
+
+       dev_vdbg(&chan->dev, "prep_dma_slave\n");
+
+       if (unlikely(!dws || !sg_len))
+               return NULL;
+
+       reg_width = dws->slave.reg_width;
+       prev = first = NULL;
+
+       sg_len = dma_map_sg(chan->dev.parent, sgl, sg_len, direction);
+
+       switch (direction) {
+       case DMA_TO_DEVICE:
+               ctllo = (DWC_DEFAULT_CTLLO
+                               | DWC_CTLL_DST_WIDTH(reg_width)
+                               | DWC_CTLL_DST_FIX
+                               | DWC_CTLL_SRC_INC
+                               | DWC_CTLL_FC_M2P);
+               reg = dws->slave.tx_reg;
+               for_each_sg(sgl, sg, sg_len, i) {
+                       struct dw_desc  *desc;
+                       u32             len;
+                       u32             mem;
+
+                       desc = dwc_desc_get(dwc);
+                       if (!desc) {
+                               dev_err(&chan->dev,
+                                       "not enough descriptors available\n");
+                               goto err_desc_get;
+                       }
+
+                       mem = sg_phys(sg);
+                       len = sg_dma_len(sg);
+                       mem_width = 2;
+                       if (unlikely(mem & 3 || len & 3))
+                               mem_width = 0;
+
+                       desc->lli.sar = mem;
+                       desc->lli.dar = reg;
+                       desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width);
+                       desc->lli.ctlhi = len >> mem_width;
+
+                       if (!first) {
+                               first = desc;
+                       } else {
+                               prev->lli.llp = desc->txd.phys;
+                               dma_sync_single_for_device(chan->dev.parent,
+                                               prev->txd.phys,
+                                               sizeof(prev->lli),
+                                               DMA_TO_DEVICE);
+                               list_add_tail(&desc->desc_node,
+                                               &first->txd.tx_list);
+                       }
+                       prev = desc;
+                       total_len += len;
+               }
+               break;
+       case DMA_FROM_DEVICE:
+               ctllo = (DWC_DEFAULT_CTLLO
+                               | DWC_CTLL_SRC_WIDTH(reg_width)
+                               | DWC_CTLL_DST_INC
+                               | DWC_CTLL_SRC_FIX
+                               | DWC_CTLL_FC_P2M);
+
+               reg = dws->slave.rx_reg;
+               for_each_sg(sgl, sg, sg_len, i) {
+                       struct dw_desc  *desc;
+                       u32             len;
+                       u32             mem;
+
+                       desc = dwc_desc_get(dwc);
+                       if (!desc) {
+                               dev_err(&chan->dev,
+                                       "not enough descriptors available\n");
+                               goto err_desc_get;
+                       }
+
+                       mem = sg_phys(sg);
+                       len = sg_dma_len(sg);
+                       mem_width = 2;
+                       if (unlikely(mem & 3 || len & 3))
+                               mem_width = 0;
+
+                       desc->lli.sar = reg;
+                       desc->lli.dar = mem;
+                       desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width);
+                       desc->lli.ctlhi = len >> reg_width;
+
+                       if (!first) {
+                               first = desc;
+                       } else {
+                               prev->lli.llp = desc->txd.phys;
+                               dma_sync_single_for_device(chan->dev.parent,
+                                               prev->txd.phys,
+                                               sizeof(prev->lli),
+                                               DMA_TO_DEVICE);
+                               list_add_tail(&desc->desc_node,
+                                               &first->txd.tx_list);
+                       }
+                       prev = desc;
+                       total_len += len;
+               }
+               break;
+       default:
+               return NULL;
+       }
+
+       if (flags & DMA_PREP_INTERRUPT)
+               /* Trigger interrupt after last block */
+               prev->lli.ctllo |= DWC_CTLL_INT_EN;
+
+       prev->lli.llp = 0;
+       dma_sync_single_for_device(chan->dev.parent,
+                       prev->txd.phys, sizeof(prev->lli),
+                       DMA_TO_DEVICE);
+
+       first->len = total_len;
+
+       return &first->txd;
+
+err_desc_get:
+       dwc_desc_put(dwc, first);
+       return NULL;
+}
+
+static void dwc_terminate_all(struct dma_chan *chan)
+{
+       struct dw_dma_chan      *dwc = to_dw_dma_chan(chan);
+       struct dw_dma           *dw = to_dw_dma(chan->device);
+       struct dw_desc          *desc, *_desc;
+       LIST_HEAD(list);
+
+       /*
+        * This is only called when something went wrong elsewhere, so
+        * we don't really care about the data. Just disable the
+        * channel. We still have to poll the channel enable bit due
+        * to AHB/HSB limitations.
+        */
+       spin_lock_bh(&dwc->lock);
+
+       channel_clear_bit(dw, CH_EN, dwc->mask);
+
+       while (dma_readl(dw, CH_EN) & dwc->mask)
+               cpu_relax();
+
+       /* active_list entries will end up before queued entries */
+       list_splice_init(&dwc->queue, &list);
+       list_splice_init(&dwc->active_list, &list);
+
+       spin_unlock_bh(&dwc->lock);
+
+       /* Flush all pending and queued descriptors */
+       list_for_each_entry_safe(desc, _desc, &list, desc_node)
+               dwc_descriptor_complete(dwc, desc);
+}
+
+static enum dma_status
+dwc_is_tx_complete(struct dma_chan *chan,
+               dma_cookie_t cookie,
+               dma_cookie_t *done, dma_cookie_t *used)
+{
+       struct dw_dma_chan      *dwc = to_dw_dma_chan(chan);
+       dma_cookie_t            last_used;
+       dma_cookie_t            last_complete;
+       int                     ret;
+
+       last_complete = dwc->completed;
+       last_used = chan->cookie;
+
+       ret = dma_async_is_complete(cookie, last_complete, last_used);
+       if (ret != DMA_SUCCESS) {
+               dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
+
+               last_complete = dwc->completed;
+               last_used = chan->cookie;
+
+               ret = dma_async_is_complete(cookie, last_complete, last_used);
+       }
+
+       if (done)
+               *done = last_complete;
+       if (used)
+               *used = last_used;
+
+       return ret;
+}
+
+static void dwc_issue_pending(struct dma_chan *chan)
+{
+       struct dw_dma_chan      *dwc = to_dw_dma_chan(chan);
+
+       spin_lock_bh(&dwc->lock);
+       if (!list_empty(&dwc->queue))
+               dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
+       spin_unlock_bh(&dwc->lock);
+}
+
+static int dwc_alloc_chan_resources(struct dma_chan *chan,
+               struct dma_client *client)
+{
+       struct dw_dma_chan      *dwc = to_dw_dma_chan(chan);
+       struct dw_dma           *dw = to_dw_dma(chan->device);
+       struct dw_desc          *desc;
+       struct dma_slave        *slave;
+       struct dw_dma_slave     *dws;
+       int                     i;
+       u32                     cfghi;
+       u32                     cfglo;
+
+       dev_vdbg(&chan->dev, "alloc_chan_resources\n");
+
+       /* Channels doing slave DMA can only handle one client. */
+       if (dwc->dws || client->slave) {
+               if (chan->client_count)
+                       return -EBUSY;
+       }
+
+       /* ASSERT:  channel is idle */
+       if (dma_readl(dw, CH_EN) & dwc->mask) {
+               dev_dbg(&chan->dev, "DMA channel not idle?\n");
+               return -EIO;
+       }
+
+       dwc->completed = chan->cookie = 1;
+
+       cfghi = DWC_CFGH_FIFO_MODE;
+       cfglo = 0;
+
+       slave = client->slave;
+       if (slave) {
+               /*
+                * We need controller-specific data to set up slave
+                * transfers.
+                */
+               BUG_ON(!slave->dma_dev || slave->dma_dev != dw->dma.dev);
+
+               dws = container_of(slave, struct dw_dma_slave, slave);
+
+               dwc->dws = dws;
+               cfghi = dws->cfg_hi;
+               cfglo = dws->cfg_lo;
+       } else {
+               dwc->dws = NULL;
+       }
+
+       channel_writel(dwc, CFG_LO, cfglo);
+       channel_writel(dwc, CFG_HI, cfghi);
+
+       /*
+        * NOTE: some controllers may have additional features that we
+        * need to initialize here, like "scatter-gather" (which
+        * doesn't mean what you think it means), and status writeback.
+        */
+
+       spin_lock_bh(&dwc->lock);
+       i = dwc->descs_allocated;
+       while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) {
+               spin_unlock_bh(&dwc->lock);
+
+               desc = kzalloc(sizeof(struct dw_desc), GFP_KERNEL);
+               if (!desc) {
+                       dev_info(&chan->dev,
+                               "only allocated %d descriptors\n", i);
+                       spin_lock_bh(&dwc->lock);
+                       break;
+               }
+
+               dma_async_tx_descriptor_init(&desc->txd, chan);
+               desc->txd.tx_submit = dwc_tx_submit;
+               desc->txd.flags = DMA_CTRL_ACK;
+               INIT_LIST_HEAD(&desc->txd.tx_list);
+               desc->txd.phys = dma_map_single(chan->dev.parent, &desc->lli,
+                               sizeof(desc->lli), DMA_TO_DEVICE);
+               dwc_desc_put(dwc, desc);
+
+               spin_lock_bh(&dwc->lock);
+               i = ++dwc->descs_allocated;
+       }
+
+       /* Enable interrupts */
+       channel_set_bit(dw, MASK.XFER, dwc->mask);
+       channel_set_bit(dw, MASK.BLOCK, dwc->mask);
+       channel_set_bit(dw, MASK.ERROR, dwc->mask);
+
+       spin_unlock_bh(&dwc->lock);
+
+       dev_dbg(&chan->dev,
+               "alloc_chan_resources allocated %d descriptors\n", i);
+
+       return i;
+}
+
+static void dwc_free_chan_resources(struct dma_chan *chan)
+{
+       struct dw_dma_chan      *dwc = to_dw_dma_chan(chan);
+       struct dw_dma           *dw = to_dw_dma(chan->device);
+       struct dw_desc          *desc, *_desc;
+       LIST_HEAD(list);
+
+       dev_dbg(&chan->dev, "free_chan_resources (descs allocated=%u)\n",
+                       dwc->descs_allocated);
+
+       /* ASSERT:  channel is idle */
+       BUG_ON(!list_empty(&dwc->active_list));
+       BUG_ON(!list_empty(&dwc->queue));
+       BUG_ON(dma_readl(to_dw_dma(chan->device), CH_EN) & dwc->mask);
+
+       spin_lock_bh(&dwc->lock);
+       list_splice_init(&dwc->free_list, &list);
+       dwc->descs_allocated = 0;
+       dwc->dws = NULL;
+
+       /* Disable interrupts */
+       channel_clear_bit(dw, MASK.XFER, dwc->mask);
+       channel_clear_bit(dw, MASK.BLOCK, dwc->mask);
+       channel_clear_bit(dw, MASK.ERROR, dwc->mask);
+
+       spin_unlock_bh(&dwc->lock);
+
+       list_for_each_entry_safe(desc, _desc, &list, desc_node) {
+               dev_vdbg(&chan->dev, "  freeing descriptor %p\n", desc);
+               dma_unmap_single(chan->dev.parent, desc->txd.phys,
+                               sizeof(desc->lli), DMA_TO_DEVICE);
+               kfree(desc);
+       }
+
+       dev_vdbg(&chan->dev, "free_chan_resources done\n");
+}
+
+/*----------------------------------------------------------------------*/
+
+static void dw_dma_off(struct dw_dma *dw)
+{
+       dma_writel(dw, CFG, 0);
+
+       channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
+       channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
+       channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask);
+       channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask);
+       channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
+
+       while (dma_readl(dw, CFG) & DW_CFG_DMA_EN)
+               cpu_relax();
+}
+
+static int __init dw_probe(struct platform_device *pdev)
+{
+       struct dw_dma_platform_data *pdata;
+       struct resource         *io;
+       struct dw_dma           *dw;
+       size_t                  size;
+       int                     irq;
+       int                     err;
+       int                     i;
+
+       pdata = pdev->dev.platform_data;
+       if (!pdata || pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS)
+               return -EINVAL;
+
+       io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!io)
+               return -EINVAL;
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               return irq;
+
+       size = sizeof(struct dw_dma);
+       size += pdata->nr_channels * sizeof(struct dw_dma_chan);
+       dw = kzalloc(size, GFP_KERNEL);
+       if (!dw)
+               return -ENOMEM;
+
+       if (!request_mem_region(io->start, DW_REGLEN, pdev->dev.driver->name)) {
+               err = -EBUSY;
+               goto err_kfree;
+       }
+
+       memset(dw, 0, sizeof *dw);
+
+       dw->regs = ioremap(io->start, DW_REGLEN);
+       if (!dw->regs) {
+               err = -ENOMEM;
+               goto err_release_r;
+       }
+
+       dw->clk = clk_get(&pdev->dev, "hclk");
+       if (IS_ERR(dw->clk)) {
+               err = PTR_ERR(dw->clk);
+               goto err_clk;
+       }
+       clk_enable(dw->clk);
+
+       /* force dma off, just in case */
+       dw_dma_off(dw);
+
+       err = request_irq(irq, dw_dma_interrupt, 0, "dw_dmac", dw);
+       if (err)
+               goto err_irq;
+
+       platform_set_drvdata(pdev, dw);
+
+       tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw);
+
+       dw->all_chan_mask = (1 << pdata->nr_channels) - 1;
+
+       INIT_LIST_HEAD(&dw->dma.channels);
+       for (i = 0; i < pdata->nr_channels; i++, dw->dma.chancnt++) {
+               struct dw_dma_chan      *dwc = &dw->chan[i];
+
+               dwc->chan.device = &dw->dma;
+               dwc->chan.cookie = dwc->completed = 1;
+               dwc->chan.chan_id = i;
+               list_add_tail(&dwc->chan.device_node, &dw->dma.channels);
+
+               dwc->ch_regs = &__dw_regs(dw)->CHAN[i];
+               spin_lock_init(&dwc->lock);
+               dwc->mask = 1 << i;
+
+               INIT_LIST_HEAD(&dwc->active_list);
+               INIT_LIST_HEAD(&dwc->queue);
+               INIT_LIST_HEAD(&dwc->free_list);
+
+               channel_clear_bit(dw, CH_EN, dwc->mask);
+       }
+
+       /* Clear/disable all interrupts on all channels. */
+       dma_writel(dw, CLEAR.XFER, dw->all_chan_mask);
+       dma_writel(dw, CLEAR.BLOCK, dw->all_chan_mask);
+       dma_writel(dw, CLEAR.SRC_TRAN, dw->all_chan_mask);
+       dma_writel(dw, CLEAR.DST_TRAN, dw->all_chan_mask);
+       dma_writel(dw, CLEAR.ERROR, dw->all_chan_mask);
+
+       channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
+       channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
+       channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask);
+       channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask);
+       channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
+
+       dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask);
+       dma_cap_set(DMA_SLAVE, dw->dma.cap_mask);
+       dw->dma.dev = &pdev->dev;
+       dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources;
+       dw->dma.device_free_chan_resources = dwc_free_chan_resources;
+
+       dw->dma.device_prep_dma_memcpy = dwc_prep_dma_memcpy;
+
+       dw->dma.device_prep_slave_sg = dwc_prep_slave_sg;
+       dw->dma.device_terminate_all = dwc_terminate_all;
+
+       dw->dma.device_is_tx_complete = dwc_is_tx_complete;
+       dw->dma.device_issue_pending = dwc_issue_pending;
+
+       dma_writel(dw, CFG, DW_CFG_DMA_EN);
+
+       printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n",
+                       pdev->dev.bus_id, dw->dma.chancnt);
+
+       dma_async_device_register(&dw->dma);
+
+       return 0;
+
+err_irq:
+       clk_disable(dw->clk);
+       clk_put(dw->clk);
+err_clk:
+       iounmap(dw->regs);
+       dw->regs = NULL;
+err_release_r:
+       release_resource(io);
+err_kfree:
+       kfree(dw);
+       return err;
+}
+
+static int __exit dw_remove(struct platform_device *pdev)
+{
+       struct dw_dma           *dw = platform_get_drvdata(pdev);
+       struct dw_dma_chan      *dwc, *_dwc;
+       struct resource         *io;
+
+       dw_dma_off(dw);
+       dma_async_device_unregister(&dw->dma);
+
+       free_irq(platform_get_irq(pdev, 0), dw);
+       tasklet_kill(&dw->tasklet);
+
+       list_for_each_entry_safe(dwc, _dwc, &dw->dma.channels,
+                       chan.device_node) {
+               list_del(&dwc->chan.device_node);
+               channel_clear_bit(dw, CH_EN, dwc->mask);
+       }
+
+       clk_disable(dw->clk);
+       clk_put(dw->clk);
+
+       iounmap(dw->regs);
+       dw->regs = NULL;
+
+       io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(io->start, DW_REGLEN);
+
+       kfree(dw);
+
+       return 0;
+}
+
+static void dw_shutdown(struct platform_device *pdev)
+{
+       struct dw_dma   *dw = platform_get_drvdata(pdev);
+
+       dw_dma_off(platform_get_drvdata(pdev));
+       clk_disable(dw->clk);
+}
+
+static int dw_suspend_late(struct platform_device *pdev, pm_message_t mesg)
+{
+       struct dw_dma   *dw = platform_get_drvdata(pdev);
+
+       dw_dma_off(platform_get_drvdata(pdev));
+       clk_disable(dw->clk);
+       return 0;
+}
+
+static int dw_resume_early(struct platform_device *pdev)
+{
+       struct dw_dma   *dw = platform_get_drvdata(pdev);
+
+       clk_enable(dw->clk);
+       dma_writel(dw, CFG, DW_CFG_DMA_EN);
+       return 0;
+
+}
+
+static struct platform_driver dw_driver = {
+       .remove         = __exit_p(dw_remove),
+       .shutdown       = dw_shutdown,
+       .suspend_late   = dw_suspend_late,
+       .resume_early   = dw_resume_early,
+       .driver = {
+               .name   = "dw_dmac",
+       },
+};
+
+static int __init dw_init(void)
+{
+       return platform_driver_probe(&dw_driver, dw_probe);
+}
+module_init(dw_init);
+
+static void __exit dw_exit(void)
+{
+       platform_driver_unregister(&dw_driver);
+}
+module_exit(dw_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver");
+MODULE_AUTHOR("Haavard Skinnemoen <haavard.skinnemoen@atmel.com>");
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
new file mode 100644 (file)
index 0000000..00fdd18
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Driver for the Synopsys DesignWare AHB DMA Controller
+ *
+ * Copyright (C) 2005-2007 Atmel Corporation
+ *
+ * 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/dw_dmac.h>
+
+#define DW_DMA_MAX_NR_CHANNELS 8
+
+/*
+ * Redefine this macro to handle differences between 32- and 64-bit
+ * addressing, big vs. little endian, etc.
+ */
+#define DW_REG(name)           u32 name; u32 __pad_##name
+
+/* Hardware register definitions. */
+struct dw_dma_chan_regs {
+       DW_REG(SAR);            /* Source Address Register */
+       DW_REG(DAR);            /* Destination Address Register */
+       DW_REG(LLP);            /* Linked List Pointer */
+       u32     CTL_LO;         /* Control Register Low */
+       u32     CTL_HI;         /* Control Register High */
+       DW_REG(SSTAT);
+       DW_REG(DSTAT);
+       DW_REG(SSTATAR);
+       DW_REG(DSTATAR);
+       u32     CFG_LO;         /* Configuration Register Low */
+       u32     CFG_HI;         /* Configuration Register High */
+       DW_REG(SGR);
+       DW_REG(DSR);
+};
+
+struct dw_dma_irq_regs {
+       DW_REG(XFER);
+       DW_REG(BLOCK);
+       DW_REG(SRC_TRAN);
+       DW_REG(DST_TRAN);
+       DW_REG(ERROR);
+};
+
+struct dw_dma_regs {
+       /* per-channel registers */
+       struct dw_dma_chan_regs CHAN[DW_DMA_MAX_NR_CHANNELS];
+
+       /* irq handling */
+       struct dw_dma_irq_regs  RAW;            /* r */
+       struct dw_dma_irq_regs  STATUS;         /* r (raw & mask) */
+       struct dw_dma_irq_regs  MASK;           /* rw (set = irq enabled) */
+       struct dw_dma_irq_regs  CLEAR;          /* w (ack, affects "raw") */
+
+       DW_REG(STATUS_INT);                     /* r */
+
+       /* software handshaking */
+       DW_REG(REQ_SRC);
+       DW_REG(REQ_DST);
+       DW_REG(SGL_REQ_SRC);
+       DW_REG(SGL_REQ_DST);
+       DW_REG(LAST_SRC);
+       DW_REG(LAST_DST);
+
+       /* miscellaneous */
+       DW_REG(CFG);
+       DW_REG(CH_EN);
+       DW_REG(ID);
+       DW_REG(TEST);
+
+       /* optional encoded params, 0x3c8..0x3 */
+};
+
+/* Bitfields in CTL_LO */
+#define DWC_CTLL_INT_EN                (1 << 0)        /* irqs enabled? */
+#define DWC_CTLL_DST_WIDTH(n)  ((n)<<1)        /* bytes per element */
+#define DWC_CTLL_SRC_WIDTH(n)  ((n)<<4)
+#define DWC_CTLL_DST_INC       (0<<7)          /* DAR update/not */
+#define DWC_CTLL_DST_DEC       (1<<7)
+#define DWC_CTLL_DST_FIX       (2<<7)
+#define DWC_CTLL_SRC_INC       (0<<7)          /* SAR update/not */
+#define DWC_CTLL_SRC_DEC       (1<<9)
+#define DWC_CTLL_SRC_FIX       (2<<9)
+#define DWC_CTLL_DST_MSIZE(n)  ((n)<<11)       /* burst, #elements */
+#define DWC_CTLL_SRC_MSIZE(n)  ((n)<<14)
+#define DWC_CTLL_S_GATH_EN     (1 << 17)       /* src gather, !FIX */
+#define DWC_CTLL_D_SCAT_EN     (1 << 18)       /* dst scatter, !FIX */
+#define DWC_CTLL_FC_M2M                (0 << 20)       /* mem-to-mem */
+#define DWC_CTLL_FC_M2P                (1 << 20)       /* mem-to-periph */
+#define DWC_CTLL_FC_P2M                (2 << 20)       /* periph-to-mem */
+#define DWC_CTLL_FC_P2P                (3 << 20)       /* periph-to-periph */
+/* plus 4 transfer types for peripheral-as-flow-controller */
+#define DWC_CTLL_DMS(n)                ((n)<<23)       /* dst master select */
+#define DWC_CTLL_SMS(n)                ((n)<<25)       /* src master select */
+#define DWC_CTLL_LLP_D_EN      (1 << 27)       /* dest block chain */
+#define DWC_CTLL_LLP_S_EN      (1 << 28)       /* src block chain */
+
+/* Bitfields in CTL_HI */
+#define DWC_CTLH_DONE          0x00001000
+#define DWC_CTLH_BLOCK_TS_MASK 0x00000fff
+
+/* Bitfields in CFG_LO. Platform-configurable bits are in <linux/dw_dmac.h> */
+#define DWC_CFGL_CH_SUSP       (1 << 8)        /* pause xfer */
+#define DWC_CFGL_FIFO_EMPTY    (1 << 9)        /* pause xfer */
+#define DWC_CFGL_HS_DST                (1 << 10)       /* handshake w/dst */
+#define DWC_CFGL_HS_SRC                (1 << 11)       /* handshake w/src */
+#define DWC_CFGL_MAX_BURST(x)  ((x) << 20)
+#define DWC_CFGL_RELOAD_SAR    (1 << 30)
+#define DWC_CFGL_RELOAD_DAR    (1 << 31)
+
+/* Bitfields in CFG_HI. Platform-configurable bits are in <linux/dw_dmac.h> */
+#define DWC_CFGH_DS_UPD_EN     (1 << 5)
+#define DWC_CFGH_SS_UPD_EN     (1 << 6)
+
+/* Bitfields in SGR */
+#define DWC_SGR_SGI(x)         ((x) << 0)
+#define DWC_SGR_SGC(x)         ((x) << 20)
+
+/* Bitfields in DSR */
+#define DWC_DSR_DSI(x)         ((x) << 0)
+#define DWC_DSR_DSC(x)         ((x) << 20)
+
+/* Bitfields in CFG */
+#define DW_CFG_DMA_EN          (1 << 0)
+
+#define DW_REGLEN              0x400
+
+struct dw_dma_chan {
+       struct dma_chan         chan;
+       void __iomem            *ch_regs;
+       u8                      mask;
+
+       spinlock_t              lock;
+
+       /* these other elements are all protected by lock */
+       dma_cookie_t            completed;
+       struct list_head        active_list;
+       struct list_head        queue;
+       struct list_head        free_list;
+
+       struct dw_dma_slave     *dws;
+
+       unsigned int            descs_allocated;
+};
+
+static inline struct dw_dma_chan_regs __iomem *
+__dwc_regs(struct dw_dma_chan *dwc)
+{
+       return dwc->ch_regs;
+}
+
+#define channel_readl(dwc, name) \
+       __raw_readl(&(__dwc_regs(dwc)->name))
+#define channel_writel(dwc, name, val) \
+       __raw_writel((val), &(__dwc_regs(dwc)->name))
+
+static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan)
+{
+       return container_of(chan, struct dw_dma_chan, chan);
+}
+
+
+struct dw_dma {
+       struct dma_device       dma;
+       void __iomem            *regs;
+       struct tasklet_struct   tasklet;
+       struct clk              *clk;
+
+       u8                      all_chan_mask;
+
+       struct dw_dma_chan      chan[0];
+};
+
+static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw)
+{
+       return dw->regs;
+}
+
+#define dma_readl(dw, name) \
+       __raw_readl(&(__dw_regs(dw)->name))
+#define dma_writel(dw, name, val) \
+       __raw_writel((val), &(__dw_regs(dw)->name))
+
+#define channel_set_bit(dw, reg, mask) \
+       dma_writel(dw, reg, ((mask) << 8) | (mask))
+#define channel_clear_bit(dw, reg, mask) \
+       dma_writel(dw, reg, ((mask) << 8) | 0)
+
+static inline struct dw_dma *to_dw_dma(struct dma_device *ddev)
+{
+       return container_of(ddev, struct dw_dma, dma);
+}
+
+/* LLI == Linked List Item; a.k.a. DMA block descriptor */
+struct dw_lli {
+       /* values that are not changed by hardware */
+       dma_addr_t      sar;
+       dma_addr_t      dar;
+       dma_addr_t      llp;            /* chain to next lli */
+       u32             ctllo;
+       /* values that may get written back: */
+       u32             ctlhi;
+       /* sstat and dstat can snapshot peripheral register state.
+        * silicon config may discard either or both...
+        */
+       u32             sstat;
+       u32             dstat;
+};
+
+struct dw_desc {
+       /* FIRST values the hardware uses */
+       struct dw_lli                   lli;
+
+       /* THEN values for driver housekeeping */
+       struct list_head                desc_node;
+       struct dma_async_tx_descriptor  txd;
+       size_t                          len;
+};
+
+static inline struct dw_desc *
+txd_to_dw_desc(struct dma_async_tx_descriptor *txd)
+{
+       return container_of(txd, struct dw_desc, txd);
+}
index 054eabffc185a893ff32ab51c01dfd876ab84b43..c0059ca5834075e70f3fc59512d9ff69617bee29 100644 (file)
@@ -366,7 +366,8 @@ static struct fsl_desc_sw *fsl_dma_alloc_descriptor(
  *
  * Return - The number of descriptors allocated.
  */
-static int fsl_dma_alloc_chan_resources(struct dma_chan *chan)
+static int fsl_dma_alloc_chan_resources(struct dma_chan *chan,
+                                       struct dma_client *client)
 {
        struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
        LIST_HEAD(tmp_list);
@@ -809,8 +810,7 @@ static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan)
        if (!src) {
                dev_err(fsl_chan->dev,
                                "selftest: Cannot alloc memory for test!\n");
-               err = -ENOMEM;
-               goto out;
+               return -ENOMEM;
        }
 
        dest = src + test_size;
@@ -820,7 +820,7 @@ static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan)
 
        chan = &fsl_chan->common;
 
-       if (fsl_dma_alloc_chan_resources(chan) < 1) {
+       if (fsl_dma_alloc_chan_resources(chan, NULL) < 1) {
                dev_err(fsl_chan->dev,
                                "selftest: Cannot alloc resources for DMA\n");
                err = -ENODEV;
@@ -842,13 +842,13 @@ static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan)
        if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) {
                dev_err(fsl_chan->dev, "selftest: Time out!\n");
                err = -ENODEV;
-               goto out;
+               goto free_resources;
        }
 
        /* Test free and re-alloc channel resources */
        fsl_dma_free_chan_resources(chan);
 
-       if (fsl_dma_alloc_chan_resources(chan) < 1) {
+       if (fsl_dma_alloc_chan_resources(chan, NULL) < 1) {
                dev_err(fsl_chan->dev,
                                "selftest: Cannot alloc resources for DMA\n");
                err = -ENODEV;
@@ -927,8 +927,7 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
        if (!new_fsl_chan) {
                dev_err(&dev->dev, "No free memory for allocating "
                                "dma channels!\n");
-               err = -ENOMEM;
-               goto err;
+               return -ENOMEM;
        }
 
        /* get dma channel register base */
@@ -936,7 +935,7 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
        if (err) {
                dev_err(&dev->dev, "Can't get %s property 'reg'\n",
                                dev->node->full_name);
-               goto err;
+               goto err_no_reg;
        }
 
        new_fsl_chan->feature = *(u32 *)match->data;
@@ -958,7 +957,7 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
                dev_err(&dev->dev, "There is no %d channel!\n",
                                new_fsl_chan->id);
                err = -EINVAL;
-               goto err;
+               goto err_no_chan;
        }
        fdev->chan[new_fsl_chan->id] = new_fsl_chan;
        tasklet_init(&new_fsl_chan->tasklet, dma_do_tasklet,
@@ -997,23 +996,26 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
                if (err) {
                        dev_err(&dev->dev, "DMA channel %s request_irq error "
                                "with return %d\n", dev->node->full_name, err);
-                       goto err;
+                       goto err_no_irq;
                }
        }
 
        err = fsl_dma_self_test(new_fsl_chan);
        if (err)
-               goto err;
+               goto err_self_test;
 
        dev_info(&dev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id,
                                match->compatible, new_fsl_chan->irq);
 
        return 0;
-err:
-       dma_halt(new_fsl_chan);
-       iounmap(new_fsl_chan->reg_base);
+
+err_self_test:
        free_irq(new_fsl_chan->irq, new_fsl_chan);
+err_no_irq:
        list_del(&new_fsl_chan->common.device_node);
+err_no_chan:
+       iounmap(new_fsl_chan->reg_base);
+err_no_reg:
        kfree(new_fsl_chan);
        return err;
 }
@@ -1054,8 +1056,7 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev,
        fdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL);
        if (!fdev) {
                dev_err(&dev->dev, "No enough memory for 'priv'\n");
-               err = -ENOMEM;
-               goto err;
+               return -ENOMEM;
        }
        fdev->dev = &dev->dev;
        INIT_LIST_HEAD(&fdev->common.channels);
@@ -1065,7 +1066,7 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev,
        if (err) {
                dev_err(&dev->dev, "Can't get %s property 'reg'\n",
                                dev->node->full_name);
-               goto err;
+               goto err_no_reg;
        }
 
        dev_info(&dev->dev, "Probe the Freescale DMA driver for %s "
@@ -1103,6 +1104,7 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev,
 
 err:
        iounmap(fdev->reg_base);
+err_no_reg:
        kfree(fdev);
        return err;
 }
index 16e0fd8facfb8ca30aaa4427815f165b0f60317f..9b16a3af9a0af6a9a377d0f10048216ac0f86510 100644 (file)
@@ -47,6 +47,16 @@ static struct pci_device_id ioat_pci_tbl[] = {
 
        /* I/OAT v2 platforms */
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB) },
+
+       /* I/OAT v3 platforms */
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_TBG0) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_TBG1) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_TBG2) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_TBG3) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_TBG4) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_TBG5) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_TBG6) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_TBG7) },
        { 0, }
 };
 
@@ -83,6 +93,11 @@ static int ioat_setup_functionality(struct pci_dev *pdev, void __iomem *iobase)
                if (device->dma && ioat_dca_enabled)
                        device->dca = ioat2_dca_init(pdev, iobase);
                break;
+       case IOAT_VER_3_0:
+               device->dma = ioat_dma_probe(pdev, iobase);
+               if (device->dma && ioat_dca_enabled)
+                       device->dca = ioat3_dca_init(pdev, iobase);
+               break;
        default:
                err = -ENODEV;
                break;
index 9e922760b7ffc4b76688bf56652e72085827e7da..6cf622da0286481fccb32a73285c72c83fb6a57b 100644 (file)
 #include "ioatdma_registers.h"
 
 /*
- * Bit 16 of a tag map entry is the "valid" bit, if it is set then bits 0:15
+ * Bit 7 of a tag map entry is the "valid" bit, if it is set then bits 0:6
  * contain the bit number of the APIC ID to map into the DCA tag.  If the valid
  * bit is not set, then the value must be 0 or 1 and defines the bit in the tag.
  */
 #define DCA_TAG_MAP_VALID 0x80
 
+#define DCA3_TAG_MAP_BIT_TO_INV 0x80
+#define DCA3_TAG_MAP_BIT_TO_SEL 0x40
+#define DCA3_TAG_MAP_LITERAL_VAL 0x1
+
+#define DCA_TAG_MAP_MASK 0xDF
+
 /*
  * "Legacy" DCA systems do not implement the DCA register set in the
  * I/OAT device.  Software needs direct support for their tag mappings.
@@ -95,6 +101,7 @@ struct ioat_dca_slot {
 };
 
 #define IOAT_DCA_MAX_REQ 6
+#define IOAT3_DCA_MAX_REQ 2
 
 struct ioat_dca_priv {
        void __iomem            *iobase;
@@ -171,7 +178,9 @@ static int ioat_dca_remove_requester(struct dca_provider *dca,
        return -ENODEV;
 }
 
-static u8 ioat_dca_get_tag(struct dca_provider *dca, int cpu)
+static u8 ioat_dca_get_tag(struct dca_provider *dca,
+                          struct device *dev,
+                          int cpu)
 {
        struct ioat_dca_priv *ioatdca = dca_priv(dca);
        int i, apic_id, bit, value;
@@ -193,10 +202,26 @@ static u8 ioat_dca_get_tag(struct dca_provider *dca, int cpu)
        return tag;
 }
 
+static int ioat_dca_dev_managed(struct dca_provider *dca,
+                               struct device *dev)
+{
+       struct ioat_dca_priv *ioatdca = dca_priv(dca);
+       struct pci_dev *pdev;
+       int i;
+
+       pdev = to_pci_dev(dev);
+       for (i = 0; i < ioatdca->max_requesters; i++) {
+               if (ioatdca->req_slots[i].pdev == pdev)
+                       return 1;
+       }
+       return 0;
+}
+
 static struct dca_ops ioat_dca_ops = {
        .add_requester          = ioat_dca_add_requester,
        .remove_requester       = ioat_dca_remove_requester,
        .get_tag                = ioat_dca_get_tag,
+       .dev_managed            = ioat_dca_dev_managed,
 };
 
 
@@ -207,6 +232,8 @@ struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase)
        u8 *tag_map = NULL;
        int i;
        int err;
+       u8 version;
+       u8 max_requesters;
 
        if (!system_has_dca_enabled(pdev))
                return NULL;
@@ -237,15 +264,20 @@ struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase)
        if (tag_map == NULL)
                return NULL;
 
+       version = readb(iobase + IOAT_VER_OFFSET);
+       if (version == IOAT_VER_3_0)
+               max_requesters = IOAT3_DCA_MAX_REQ;
+       else
+               max_requesters = IOAT_DCA_MAX_REQ;
+
        dca = alloc_dca_provider(&ioat_dca_ops,
                        sizeof(*ioatdca) +
-                       (sizeof(struct ioat_dca_slot) * IOAT_DCA_MAX_REQ));
+                       (sizeof(struct ioat_dca_slot) * max_requesters));
        if (!dca)
                return NULL;
 
        ioatdca = dca_priv(dca);
-       ioatdca->max_requesters = IOAT_DCA_MAX_REQ;
-
+       ioatdca->max_requesters = max_requesters;
        ioatdca->dca_base = iobase + 0x54;
 
        /* copy over the APIC ID to DCA tag mapping */
@@ -323,11 +355,13 @@ static int ioat2_dca_remove_requester(struct dca_provider *dca,
        return -ENODEV;
 }
 
-static u8 ioat2_dca_get_tag(struct dca_provider *dca, int cpu)
+static u8 ioat2_dca_get_tag(struct dca_provider *dca,
+                           struct device *dev,
+                           int cpu)
 {
        u8 tag;
 
-       tag = ioat_dca_get_tag(dca, cpu);
+       tag = ioat_dca_get_tag(dca, dev, cpu);
        tag = (~tag) & 0x1F;
        return tag;
 }
@@ -336,6 +370,7 @@ static struct dca_ops ioat2_dca_ops = {
        .add_requester          = ioat2_dca_add_requester,
        .remove_requester       = ioat2_dca_remove_requester,
        .get_tag                = ioat2_dca_get_tag,
+       .dev_managed            = ioat_dca_dev_managed,
 };
 
 static int ioat2_dca_count_dca_slots(void __iomem *iobase, u16 dca_offset)
@@ -425,3 +460,198 @@ struct dca_provider *ioat2_dca_init(struct pci_dev *pdev, void __iomem *iobase)
 
        return dca;
 }
+
+static int ioat3_dca_add_requester(struct dca_provider *dca, struct device *dev)
+{
+       struct ioat_dca_priv *ioatdca = dca_priv(dca);
+       struct pci_dev *pdev;
+       int i;
+       u16 id;
+       u16 global_req_table;
+
+       /* This implementation only supports PCI-Express */
+       if (dev->bus != &pci_bus_type)
+               return -ENODEV;
+       pdev = to_pci_dev(dev);
+       id = dcaid_from_pcidev(pdev);
+
+       if (ioatdca->requester_count == ioatdca->max_requesters)
+               return -ENODEV;
+
+       for (i = 0; i < ioatdca->max_requesters; i++) {
+               if (ioatdca->req_slots[i].pdev == NULL) {
+                       /* found an empty slot */
+                       ioatdca->requester_count++;
+                       ioatdca->req_slots[i].pdev = pdev;
+                       ioatdca->req_slots[i].rid = id;
+                       global_req_table =
+                             readw(ioatdca->dca_base + IOAT3_DCA_GREQID_OFFSET);
+                       writel(id | IOAT_DCA_GREQID_VALID,
+                              ioatdca->iobase + global_req_table + (i * 4));
+                       return i;
+               }
+       }
+       /* Error, ioatdma->requester_count is out of whack */
+       return -EFAULT;
+}
+
+static int ioat3_dca_remove_requester(struct dca_provider *dca,
+                                     struct device *dev)
+{
+       struct ioat_dca_priv *ioatdca = dca_priv(dca);
+       struct pci_dev *pdev;
+       int i;
+       u16 global_req_table;
+
+       /* This implementation only supports PCI-Express */
+       if (dev->bus != &pci_bus_type)
+               return -ENODEV;
+       pdev = to_pci_dev(dev);
+
+       for (i = 0; i < ioatdca->max_requesters; i++) {
+               if (ioatdca->req_slots[i].pdev == pdev) {
+                       global_req_table =
+                             readw(ioatdca->dca_base + IOAT3_DCA_GREQID_OFFSET);
+                       writel(0, ioatdca->iobase + global_req_table + (i * 4));
+                       ioatdca->req_slots[i].pdev = NULL;
+                       ioatdca->req_slots[i].rid = 0;
+                       ioatdca->requester_count--;
+                       return i;
+               }
+       }
+       return -ENODEV;
+}
+
+static u8 ioat3_dca_get_tag(struct dca_provider *dca,
+                           struct device *dev,
+                           int cpu)
+{
+       u8 tag;
+
+       struct ioat_dca_priv *ioatdca = dca_priv(dca);
+       int i, apic_id, bit, value;
+       u8 entry;
+
+       tag = 0;
+       apic_id = cpu_physical_id(cpu);
+
+       for (i = 0; i < IOAT_TAG_MAP_LEN; i++) {
+               entry = ioatdca->tag_map[i];
+               if (entry & DCA3_TAG_MAP_BIT_TO_SEL) {
+                       bit = entry &
+                               ~(DCA3_TAG_MAP_BIT_TO_SEL | DCA3_TAG_MAP_BIT_TO_INV);
+                       value = (apic_id & (1 << bit)) ? 1 : 0;
+               } else if (entry & DCA3_TAG_MAP_BIT_TO_INV) {
+                       bit = entry & ~DCA3_TAG_MAP_BIT_TO_INV;
+                       value = (apic_id & (1 << bit)) ? 0 : 1;
+               } else {
+                       value = (entry & DCA3_TAG_MAP_LITERAL_VAL) ? 1 : 0;
+               }
+               tag |= (value << i);
+       }
+
+       return tag;
+}
+
+static struct dca_ops ioat3_dca_ops = {
+       .add_requester          = ioat3_dca_add_requester,
+       .remove_requester       = ioat3_dca_remove_requester,
+       .get_tag                = ioat3_dca_get_tag,
+       .dev_managed            = ioat_dca_dev_managed,
+};
+
+static int ioat3_dca_count_dca_slots(void *iobase, u16 dca_offset)
+{
+       int slots = 0;
+       u32 req;
+       u16 global_req_table;
+
+       global_req_table = readw(iobase + dca_offset + IOAT3_DCA_GREQID_OFFSET);
+       if (global_req_table == 0)
+               return 0;
+
+       do {
+               req = readl(iobase + global_req_table + (slots * sizeof(u32)));
+               slots++;
+       } while ((req & IOAT_DCA_GREQID_LASTID) == 0);
+
+       return slots;
+}
+
+struct dca_provider *ioat3_dca_init(struct pci_dev *pdev, void __iomem *iobase)
+{
+       struct dca_provider *dca;
+       struct ioat_dca_priv *ioatdca;
+       int slots;
+       int i;
+       int err;
+       u16 dca_offset;
+       u16 csi_fsb_control;
+       u16 pcie_control;
+       u8 bit;
+
+       union {
+               u64 full;
+               struct {
+                       u32 low;
+                       u32 high;
+               };
+       } tag_map;
+
+       if (!system_has_dca_enabled(pdev))
+               return NULL;
+
+       dca_offset = readw(iobase + IOAT_DCAOFFSET_OFFSET);
+       if (dca_offset == 0)
+               return NULL;
+
+       slots = ioat3_dca_count_dca_slots(iobase, dca_offset);
+       if (slots == 0)
+               return NULL;
+
+       dca = alloc_dca_provider(&ioat3_dca_ops,
+                                sizeof(*ioatdca)
+                                     + (sizeof(struct ioat_dca_slot) * slots));
+       if (!dca)
+               return NULL;
+
+       ioatdca = dca_priv(dca);
+       ioatdca->iobase = iobase;
+       ioatdca->dca_base = iobase + dca_offset;
+       ioatdca->max_requesters = slots;
+
+       /* some bios might not know to turn these on */
+       csi_fsb_control = readw(ioatdca->dca_base + IOAT3_CSI_CONTROL_OFFSET);
+       if ((csi_fsb_control & IOAT3_CSI_CONTROL_PREFETCH) == 0) {
+               csi_fsb_control |= IOAT3_CSI_CONTROL_PREFETCH;
+               writew(csi_fsb_control,
+                      ioatdca->dca_base + IOAT3_CSI_CONTROL_OFFSET);
+       }
+       pcie_control = readw(ioatdca->dca_base + IOAT3_PCI_CONTROL_OFFSET);
+       if ((pcie_control & IOAT3_PCI_CONTROL_MEMWR) == 0) {
+               pcie_control |= IOAT3_PCI_CONTROL_MEMWR;
+               writew(pcie_control,
+                      ioatdca->dca_base + IOAT3_PCI_CONTROL_OFFSET);
+       }
+
+
+       /* TODO version, compatibility and configuration checks */
+
+       /* copy out the APIC to DCA tag map */
+       tag_map.low =
+               readl(ioatdca->dca_base + IOAT3_APICID_TAG_MAP_OFFSET_LOW);
+       tag_map.high =
+               readl(ioatdca->dca_base + IOAT3_APICID_TAG_MAP_OFFSET_HIGH);
+       for (i = 0; i < 8; i++) {
+               bit = tag_map.full >> (8 * i);
+               ioatdca->tag_map[i] = bit & DCA_TAG_MAP_MASK;
+       }
+
+       err = register_dca_provider(dca, &pdev->dev);
+       if (err) {
+               free_dca_provider(dca);
+               return NULL;
+       }
+
+       return dca;
+}
index 318e8a22d81423a4da8cfb759be3c9854148252e..a52156e568867e827c30f0008de9477df493b730 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/dmaengine.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/workqueue.h>
 #include "ioatdma.h"
 #include "ioatdma_registers.h"
 #include "ioatdma_hw.h"
 #define to_ioat_desc(lh) container_of(lh, struct ioat_desc_sw, node)
 #define tx_to_ioat_desc(tx) container_of(tx, struct ioat_desc_sw, async_tx)
 
+#define chan_num(ch) ((int)((ch)->reg_base - (ch)->device->reg_base) / 0x80)
 static int ioat_pending_level = 4;
 module_param(ioat_pending_level, int, 0644);
 MODULE_PARM_DESC(ioat_pending_level,
                 "high-water mark for pushing ioat descriptors (default: 4)");
 
+#define RESET_DELAY  msecs_to_jiffies(100)
+#define WATCHDOG_DELAY  round_jiffies(msecs_to_jiffies(2000))
+static void ioat_dma_chan_reset_part2(struct work_struct *work);
+static void ioat_dma_chan_watchdog(struct work_struct *work);
+
+/*
+ * workaround for IOAT ver.3.0 null descriptor issue
+ * (channel returns error when size is 0)
+ */
+#define NULL_DESC_BUFFER_SIZE 1
+
 /* internal functions */
 static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan);
 static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan);
@@ -122,6 +135,38 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
        int i;
        struct ioat_dma_chan *ioat_chan;
 
+       /*
+        * IOAT ver.3 workarounds
+        */
+       if (device->version == IOAT_VER_3_0) {
+               u32 chan_err_mask;
+               u16 dev_id;
+               u32 dmauncerrsts;
+
+               /*
+                * Write CHANERRMSK_INT with 3E07h to mask out the errors
+                * that can cause stability issues for IOAT ver.3
+                */
+               chan_err_mask = 0x3E07;
+               pci_write_config_dword(device->pdev,
+                       IOAT_PCI_CHANERRMASK_INT_OFFSET,
+                       chan_err_mask);
+
+               /*
+                * Clear DMAUNCERRSTS Cfg-Reg Parity Error status bit
+                * (workaround for spurious config parity error after restart)
+                */
+               pci_read_config_word(device->pdev,
+                       IOAT_PCI_DEVICE_ID_OFFSET,
+                       &dev_id);
+               if (dev_id == PCI_DEVICE_ID_INTEL_IOAT_TBG0) {
+                       dmauncerrsts = 0x10;
+                       pci_write_config_dword(device->pdev,
+                               IOAT_PCI_DMAUNCERRSTS_OFFSET,
+                               dmauncerrsts);
+               }
+       }
+
        device->common.chancnt = readb(device->reg_base + IOAT_CHANCNT_OFFSET);
        xfercap_scale = readb(device->reg_base + IOAT_XFERCAP_OFFSET);
        xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale));
@@ -137,6 +182,7 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
                ioat_chan->reg_base = device->reg_base + (0x80 * (i + 1));
                ioat_chan->xfercap = xfercap;
                ioat_chan->desccount = 0;
+               INIT_DELAYED_WORK(&ioat_chan->work, ioat_dma_chan_reset_part2);
                if (ioat_chan->device->version != IOAT_VER_1_2) {
                        writel(IOAT_DCACTRL_CMPL_WRITE_ENABLE
                                        | IOAT_DMA_DCA_ANY_CPU,
@@ -175,7 +221,7 @@ static void ioat1_dma_memcpy_issue_pending(struct dma_chan *chan)
 {
        struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
 
-       if (ioat_chan->pending != 0) {
+       if (ioat_chan->pending > 0) {
                spin_lock_bh(&ioat_chan->desc_lock);
                __ioat1_dma_memcpy_issue_pending(ioat_chan);
                spin_unlock_bh(&ioat_chan->desc_lock);
@@ -194,13 +240,228 @@ static void ioat2_dma_memcpy_issue_pending(struct dma_chan *chan)
 {
        struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
 
-       if (ioat_chan->pending != 0) {
+       if (ioat_chan->pending > 0) {
                spin_lock_bh(&ioat_chan->desc_lock);
                __ioat2_dma_memcpy_issue_pending(ioat_chan);
                spin_unlock_bh(&ioat_chan->desc_lock);
        }
 }
 
+
+/**
+ * ioat_dma_chan_reset_part2 - reinit the channel after a reset
+ */
+static void ioat_dma_chan_reset_part2(struct work_struct *work)
+{
+       struct ioat_dma_chan *ioat_chan =
+               container_of(work, struct ioat_dma_chan, work.work);
+       struct ioat_desc_sw *desc;
+
+       spin_lock_bh(&ioat_chan->cleanup_lock);
+       spin_lock_bh(&ioat_chan->desc_lock);
+
+       ioat_chan->completion_virt->low = 0;
+       ioat_chan->completion_virt->high = 0;
+       ioat_chan->pending = 0;
+
+       /*
+        * count the descriptors waiting, and be sure to do it
+        * right for both the CB1 line and the CB2 ring
+        */
+       ioat_chan->dmacount = 0;
+       if (ioat_chan->used_desc.prev) {
+               desc = to_ioat_desc(ioat_chan->used_desc.prev);
+               do {
+                       ioat_chan->dmacount++;
+                       desc = to_ioat_desc(desc->node.next);
+               } while (&desc->node != ioat_chan->used_desc.next);
+       }
+
+       /*
+        * write the new starting descriptor address
+        * this puts channel engine into ARMED state
+        */
+       desc = to_ioat_desc(ioat_chan->used_desc.prev);
+       switch (ioat_chan->device->version) {
+       case IOAT_VER_1_2:
+               writel(((u64) desc->async_tx.phys) & 0x00000000FFFFFFFF,
+                      ioat_chan->reg_base + IOAT1_CHAINADDR_OFFSET_LOW);
+               writel(((u64) desc->async_tx.phys) >> 32,
+                      ioat_chan->reg_base + IOAT1_CHAINADDR_OFFSET_HIGH);
+
+               writeb(IOAT_CHANCMD_START, ioat_chan->reg_base
+                       + IOAT_CHANCMD_OFFSET(ioat_chan->device->version));
+               break;
+       case IOAT_VER_2_0:
+               writel(((u64) desc->async_tx.phys) & 0x00000000FFFFFFFF,
+                      ioat_chan->reg_base + IOAT2_CHAINADDR_OFFSET_LOW);
+               writel(((u64) desc->async_tx.phys) >> 32,
+                      ioat_chan->reg_base + IOAT2_CHAINADDR_OFFSET_HIGH);
+
+               /* tell the engine to go with what's left to be done */
+               writew(ioat_chan->dmacount,
+                      ioat_chan->reg_base + IOAT_CHAN_DMACOUNT_OFFSET);
+
+               break;
+       }
+       dev_err(&ioat_chan->device->pdev->dev,
+               "chan%d reset - %d descs waiting, %d total desc\n",
+               chan_num(ioat_chan), ioat_chan->dmacount, ioat_chan->desccount);
+
+       spin_unlock_bh(&ioat_chan->desc_lock);
+       spin_unlock_bh(&ioat_chan->cleanup_lock);
+}
+
+/**
+ * ioat_dma_reset_channel - restart a channel
+ * @ioat_chan: IOAT DMA channel handle
+ */
+static void ioat_dma_reset_channel(struct ioat_dma_chan *ioat_chan)
+{
+       u32 chansts, chanerr;
+
+       if (!ioat_chan->used_desc.prev)
+               return;
+
+       chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
+       chansts = (ioat_chan->completion_virt->low
+                                       & IOAT_CHANSTS_DMA_TRANSFER_STATUS);
+       if (chanerr) {
+               dev_err(&ioat_chan->device->pdev->dev,
+                       "chan%d, CHANSTS = 0x%08x CHANERR = 0x%04x, clearing\n",
+                       chan_num(ioat_chan), chansts, chanerr);
+               writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
+       }
+
+       /*
+        * whack it upside the head with a reset
+        * and wait for things to settle out.
+        * force the pending count to a really big negative
+        * to make sure no one forces an issue_pending
+        * while we're waiting.
+        */
+
+       spin_lock_bh(&ioat_chan->desc_lock);
+       ioat_chan->pending = INT_MIN;
+       writeb(IOAT_CHANCMD_RESET,
+              ioat_chan->reg_base
+              + IOAT_CHANCMD_OFFSET(ioat_chan->device->version));
+       spin_unlock_bh(&ioat_chan->desc_lock);
+
+       /* schedule the 2nd half instead of sleeping a long time */
+       schedule_delayed_work(&ioat_chan->work, RESET_DELAY);
+}
+
+/**
+ * ioat_dma_chan_watchdog - watch for stuck channels
+ */
+static void ioat_dma_chan_watchdog(struct work_struct *work)
+{
+       struct ioatdma_device *device =
+               container_of(work, struct ioatdma_device, work.work);
+       struct ioat_dma_chan *ioat_chan;
+       int i;
+
+       union {
+               u64 full;
+               struct {
+                       u32 low;
+                       u32 high;
+               };
+       } completion_hw;
+       unsigned long compl_desc_addr_hw;
+
+       for (i = 0; i < device->common.chancnt; i++) {
+               ioat_chan = ioat_lookup_chan_by_index(device, i);
+
+               if (ioat_chan->device->version == IOAT_VER_1_2
+                       /* have we started processing anything yet */
+                   && ioat_chan->last_completion
+                       /* have we completed any since last watchdog cycle? */
+                   && (ioat_chan->last_completion ==
+                               ioat_chan->watchdog_completion)
+                       /* has TCP stuck on one cookie since last watchdog? */
+                   && (ioat_chan->watchdog_tcp_cookie ==
+                               ioat_chan->watchdog_last_tcp_cookie)
+                   && (ioat_chan->watchdog_tcp_cookie !=
+                               ioat_chan->completed_cookie)
+                       /* is there something in the chain to be processed? */
+                       /* CB1 chain always has at least the last one processed */
+                   && (ioat_chan->used_desc.prev != ioat_chan->used_desc.next)
+                   && ioat_chan->pending == 0) {
+
+                       /*
+                        * check CHANSTS register for completed
+                        * descriptor address.
+                        * if it is different than completion writeback,
+                        * it is not zero
+                        * and it has changed since the last watchdog
+                        *     we can assume that channel
+                        *     is still working correctly
+                        *     and the problem is in completion writeback.
+                        *     update completion writeback
+                        *     with actual CHANSTS value
+                        * else
+                        *     try resetting the channel
+                        */
+
+                       completion_hw.low = readl(ioat_chan->reg_base +
+                               IOAT_CHANSTS_OFFSET_LOW(ioat_chan->device->version));
+                       completion_hw.high = readl(ioat_chan->reg_base +
+                               IOAT_CHANSTS_OFFSET_HIGH(ioat_chan->device->version));
+#if (BITS_PER_LONG == 64)
+                       compl_desc_addr_hw =
+                               completion_hw.full
+                               & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR;
+#else
+                       compl_desc_addr_hw =
+                               completion_hw.low & IOAT_LOW_COMPLETION_MASK;
+#endif
+
+                       if ((compl_desc_addr_hw != 0)
+                          && (compl_desc_addr_hw != ioat_chan->watchdog_completion)
+                          && (compl_desc_addr_hw != ioat_chan->last_compl_desc_addr_hw)) {
+                               ioat_chan->last_compl_desc_addr_hw = compl_desc_addr_hw;
+                               ioat_chan->completion_virt->low = completion_hw.low;
+                               ioat_chan->completion_virt->high = completion_hw.high;
+                       } else {
+                               ioat_dma_reset_channel(ioat_chan);
+                               ioat_chan->watchdog_completion = 0;
+                               ioat_chan->last_compl_desc_addr_hw = 0;
+                       }
+
+               /*
+                * for version 2.0 if there are descriptors yet to be processed
+                * and the last completed hasn't changed since the last watchdog
+                *      if they haven't hit the pending level
+                *          issue the pending to push them through
+                *      else
+                *          try resetting the channel
+                */
+               } else if (ioat_chan->device->version == IOAT_VER_2_0
+                   && ioat_chan->used_desc.prev
+                   && ioat_chan->last_completion
+                   && ioat_chan->last_completion == ioat_chan->watchdog_completion) {
+
+                       if (ioat_chan->pending < ioat_pending_level)
+                               ioat2_dma_memcpy_issue_pending(&ioat_chan->common);
+                       else {
+                               ioat_dma_reset_channel(ioat_chan);
+                               ioat_chan->watchdog_completion = 0;
+                       }
+               } else {
+                       ioat_chan->last_compl_desc_addr_hw = 0;
+                       ioat_chan->watchdog_completion
+                                       = ioat_chan->last_completion;
+               }
+
+               ioat_chan->watchdog_last_tcp_cookie =
+                       ioat_chan->watchdog_tcp_cookie;
+       }
+
+       schedule_delayed_work(&device->work, WATCHDOG_DELAY);
+}
+
 static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx)
 {
        struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
@@ -250,6 +511,13 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx)
                prev = new;
        } while (len && (new = ioat1_dma_get_next_descriptor(ioat_chan)));
 
+       if (!new) {
+               dev_err(&ioat_chan->device->pdev->dev,
+                       "tx submit failed\n");
+               spin_unlock_bh(&ioat_chan->desc_lock);
+               return -ENOMEM;
+       }
+
        hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
        if (new->async_tx.callback) {
                hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
@@ -335,7 +603,14 @@ static dma_cookie_t ioat2_tx_submit(struct dma_async_tx_descriptor *tx)
                desc_count++;
        } while (len && (new = ioat2_dma_get_next_descriptor(ioat_chan)));
 
-       hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
+       if (!new) {
+               dev_err(&ioat_chan->device->pdev->dev,
+                       "tx submit failed\n");
+               spin_unlock_bh(&ioat_chan->desc_lock);
+               return -ENOMEM;
+       }
+
+       hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
        if (new->async_tx.callback) {
                hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
                if (first != new) {
@@ -406,6 +681,7 @@ static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
                desc_sw->async_tx.tx_submit = ioat1_tx_submit;
                break;
        case IOAT_VER_2_0:
+       case IOAT_VER_3_0:
                desc_sw->async_tx.tx_submit = ioat2_tx_submit;
                break;
        }
@@ -452,7 +728,8 @@ static void ioat2_dma_massage_chan_desc(struct ioat_dma_chan *ioat_chan)
  * ioat_dma_alloc_chan_resources - returns the number of allocated descriptors
  * @chan: the channel to be filled out
  */
-static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
+static int ioat_dma_alloc_chan_resources(struct dma_chan *chan,
+                                        struct dma_client *client)
 {
        struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
        struct ioat_desc_sw *desc;
@@ -555,6 +832,7 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
                }
                break;
        case IOAT_VER_2_0:
+       case IOAT_VER_3_0:
                list_for_each_entry_safe(desc, _desc,
                                         ioat_chan->free_desc.next, node) {
                        list_del(&desc->node);
@@ -585,6 +863,10 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan)
        ioat_chan->last_completion = ioat_chan->completion_addr = 0;
        ioat_chan->pending = 0;
        ioat_chan->dmacount = 0;
+       ioat_chan->watchdog_completion = 0;
+       ioat_chan->last_compl_desc_addr_hw = 0;
+       ioat_chan->watchdog_tcp_cookie =
+               ioat_chan->watchdog_last_tcp_cookie = 0;
 }
 
 /**
@@ -640,7 +922,8 @@ ioat2_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
 
                /* set up the noop descriptor */
                noop_desc = to_ioat_desc(ioat_chan->used_desc.next);
-               noop_desc->hw->size = 0;
+               /* set size to non-zero value (channel returns error when size is 0) */
+               noop_desc->hw->size = NULL_DESC_BUFFER_SIZE;
                noop_desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL;
                noop_desc->hw->src_addr = 0;
                noop_desc->hw->dst_addr = 0;
@@ -690,6 +973,7 @@ static struct ioat_desc_sw *ioat_dma_get_next_descriptor(
                return ioat1_dma_get_next_descriptor(ioat_chan);
                break;
        case IOAT_VER_2_0:
+       case IOAT_VER_3_0:
                return ioat2_dma_get_next_descriptor(ioat_chan);
                break;
        }
@@ -716,8 +1000,12 @@ static struct dma_async_tx_descriptor *ioat1_dma_prep_memcpy(
                new->src = dma_src;
                new->async_tx.flags = flags;
                return &new->async_tx;
-       } else
+       } else {
+               dev_err(&ioat_chan->device->pdev->dev,
+                       "chan%d - get_next_desc failed: %d descs waiting, %d total desc\n",
+                       chan_num(ioat_chan), ioat_chan->dmacount, ioat_chan->desccount);
                return NULL;
+       }
 }
 
 static struct dma_async_tx_descriptor *ioat2_dma_prep_memcpy(
@@ -744,8 +1032,13 @@ static struct dma_async_tx_descriptor *ioat2_dma_prep_memcpy(
                new->src = dma_src;
                new->async_tx.flags = flags;
                return &new->async_tx;
-       } else
+       } else {
+               spin_unlock_bh(&ioat_chan->desc_lock);
+               dev_err(&ioat_chan->device->pdev->dev,
+                       "chan%d - get_next_desc failed: %d descs waiting, %d total desc\n",
+                       chan_num(ioat_chan), ioat_chan->dmacount, ioat_chan->desccount);
                return NULL;
+       }
 }
 
 static void ioat_dma_cleanup_tasklet(unsigned long data)
@@ -756,6 +1049,27 @@ static void ioat_dma_cleanup_tasklet(unsigned long data)
               chan->reg_base + IOAT_CHANCTRL_OFFSET);
 }
 
+static void
+ioat_dma_unmap(struct ioat_dma_chan *ioat_chan, struct ioat_desc_sw *desc)
+{
+       /*
+        * yes we are unmapping both _page and _single
+        * alloc'd regions with unmap_page. Is this
+        * *really* that bad?
+        */
+       if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP))
+               pci_unmap_page(ioat_chan->device->pdev,
+                               pci_unmap_addr(desc, dst),
+                               pci_unmap_len(desc, len),
+                               PCI_DMA_FROMDEVICE);
+
+       if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP))
+               pci_unmap_page(ioat_chan->device->pdev,
+                               pci_unmap_addr(desc, src),
+                               pci_unmap_len(desc, len),
+                               PCI_DMA_TODEVICE);
+}
+
 /**
  * ioat_dma_memcpy_cleanup - cleanup up finished descriptors
  * @chan: ioat channel to be cleaned up
@@ -799,11 +1113,27 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
 
        if (phys_complete == ioat_chan->last_completion) {
                spin_unlock_bh(&ioat_chan->cleanup_lock);
+               /*
+                * perhaps we're stuck so hard that the watchdog can't go off?
+                * try to catch it after 2 seconds
+                */
+               if (ioat_chan->device->version != IOAT_VER_3_0) {
+                       if (time_after(jiffies,
+                                      ioat_chan->last_completion_time + HZ*WATCHDOG_DELAY)) {
+                               ioat_dma_chan_watchdog(&(ioat_chan->device->work.work));
+                               ioat_chan->last_completion_time = jiffies;
+                       }
+               }
                return;
        }
+       ioat_chan->last_completion_time = jiffies;
 
        cookie = 0;
-       spin_lock_bh(&ioat_chan->desc_lock);
+       if (!spin_trylock_bh(&ioat_chan->desc_lock)) {
+               spin_unlock_bh(&ioat_chan->cleanup_lock);
+               return;
+       }
+
        switch (ioat_chan->device->version) {
        case IOAT_VER_1_2:
                list_for_each_entry_safe(desc, _desc,
@@ -816,21 +1146,7 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
                         */
                        if (desc->async_tx.cookie) {
                                cookie = desc->async_tx.cookie;
-
-                               /*
-                                * yes we are unmapping both _page and _single
-                                * alloc'd regions with unmap_page. Is this
-                                * *really* that bad?
-                                */
-                               pci_unmap_page(ioat_chan->device->pdev,
-                                               pci_unmap_addr(desc, dst),
-                                               pci_unmap_len(desc, len),
-                                               PCI_DMA_FROMDEVICE);
-                               pci_unmap_page(ioat_chan->device->pdev,
-                                               pci_unmap_addr(desc, src),
-                                               pci_unmap_len(desc, len),
-                                               PCI_DMA_TODEVICE);
-
+                               ioat_dma_unmap(ioat_chan, desc);
                                if (desc->async_tx.callback) {
                                        desc->async_tx.callback(desc->async_tx.callback_param);
                                        desc->async_tx.callback = NULL;
@@ -862,6 +1178,7 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
                }
                break;
        case IOAT_VER_2_0:
+       case IOAT_VER_3_0:
                /* has some other thread has already cleaned up? */
                if (ioat_chan->used_desc.prev == NULL)
                        break;
@@ -889,16 +1206,7 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
                                if (desc->async_tx.cookie) {
                                        cookie = desc->async_tx.cookie;
                                        desc->async_tx.cookie = 0;
-
-                                       pci_unmap_page(ioat_chan->device->pdev,
-                                                     pci_unmap_addr(desc, dst),
-                                                     pci_unmap_len(desc, len),
-                                                     PCI_DMA_FROMDEVICE);
-                                       pci_unmap_page(ioat_chan->device->pdev,
-                                                     pci_unmap_addr(desc, src),
-                                                     pci_unmap_len(desc, len),
-                                                     PCI_DMA_TODEVICE);
-
+                                       ioat_dma_unmap(ioat_chan, desc);
                                        if (desc->async_tx.callback) {
                                                desc->async_tx.callback(desc->async_tx.callback_param);
                                                desc->async_tx.callback = NULL;
@@ -943,6 +1251,7 @@ static enum dma_status ioat_dma_is_complete(struct dma_chan *chan,
 
        last_used = chan->cookie;
        last_complete = ioat_chan->completed_cookie;
+       ioat_chan->watchdog_tcp_cookie = cookie;
 
        if (done)
                *done = last_complete;
@@ -973,10 +1282,19 @@ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan)
        spin_lock_bh(&ioat_chan->desc_lock);
 
        desc = ioat_dma_get_next_descriptor(ioat_chan);
+
+       if (!desc) {
+               dev_err(&ioat_chan->device->pdev->dev,
+                       "Unable to start null desc - get next desc failed\n");
+               spin_unlock_bh(&ioat_chan->desc_lock);
+               return;
+       }
+
        desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL
                                | IOAT_DMA_DESCRIPTOR_CTL_INT_GN
                                | IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
-       desc->hw->size = 0;
+       /* set size to non-zero value (channel returns error when size is 0) */
+       desc->hw->size = NULL_DESC_BUFFER_SIZE;
        desc->hw->src_addr = 0;
        desc->hw->dst_addr = 0;
        async_tx_ack(&desc->async_tx);
@@ -994,6 +1312,7 @@ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan)
                        + IOAT_CHANCMD_OFFSET(ioat_chan->device->version));
                break;
        case IOAT_VER_2_0:
+       case IOAT_VER_3_0:
                writel(((u64) desc->async_tx.phys) & 0x00000000FFFFFFFF,
                       ioat_chan->reg_base + IOAT2_CHAINADDR_OFFSET_LOW);
                writel(((u64) desc->async_tx.phys) >> 32,
@@ -1049,7 +1368,7 @@ static int ioat_dma_self_test(struct ioatdma_device *device)
        dma_chan = container_of(device->common.channels.next,
                                struct dma_chan,
                                device_node);
-       if (device->common.device_alloc_chan_resources(dma_chan) < 1) {
+       if (device->common.device_alloc_chan_resources(dma_chan, NULL) < 1) {
                dev_err(&device->pdev->dev,
                        "selftest cannot allocate chan resource\n");
                err = -ENODEV;
@@ -1312,6 +1631,7 @@ struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
                                                ioat1_dma_memcpy_issue_pending;
                break;
        case IOAT_VER_2_0:
+       case IOAT_VER_3_0:
                device->common.device_prep_dma_memcpy = ioat2_dma_prep_memcpy;
                device->common.device_issue_pending =
                                                ioat2_dma_memcpy_issue_pending;
@@ -1331,8 +1651,16 @@ struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
        if (err)
                goto err_self_test;
 
+       ioat_set_tcp_copy_break(device);
+
        dma_async_device_register(&device->common);
 
+       if (device->version != IOAT_VER_3_0) {
+               INIT_DELAYED_WORK(&device->work, ioat_dma_chan_watchdog);
+               schedule_delayed_work(&device->work,
+                                     WATCHDOG_DELAY);
+       }
+
        return device;
 
 err_self_test:
@@ -1365,6 +1693,10 @@ void ioat_dma_remove(struct ioatdma_device *device)
        pci_release_regions(device->pdev);
        pci_disable_device(device->pdev);
 
+       if (device->version != IOAT_VER_3_0) {
+               cancel_delayed_work(&device->work);
+       }
+
        list_for_each_entry_safe(chan, _chan,
                                 &device->common.channels, device_node) {
                ioat_chan = to_ioat_chan(chan);
index f2c7fedbf009b545c72e13fe69cfae54117ed4b9..a3306d0e1372a44b2950bc06d220d9b716f0bb00 100644 (file)
@@ -27,8 +27,9 @@
 #include <linux/dmapool.h>
 #include <linux/cache.h>
 #include <linux/pci_ids.h>
+#include <net/tcp.h>
 
-#define IOAT_DMA_VERSION  "2.04"
+#define IOAT_DMA_VERSION  "3.30"
 
 enum ioat_interrupt {
        none = 0,
@@ -40,6 +41,7 @@ enum ioat_interrupt {
 
 #define IOAT_LOW_COMPLETION_MASK       0xffffffc0
 #define IOAT_DMA_DCA_ANY_CPU           ~0
+#define IOAT_WATCHDOG_PERIOD           (2 * HZ)
 
 
 /**
@@ -62,6 +64,7 @@ struct ioatdma_device {
        struct dma_device common;
        u8 version;
        enum ioat_interrupt irq_mode;
+       struct delayed_work work;
        struct msix_entry msix_entries[4];
        struct ioat_dma_chan *idx[4];
 };
@@ -75,6 +78,7 @@ struct ioat_dma_chan {
 
        dma_cookie_t completed_cookie;
        unsigned long last_completion;
+       unsigned long last_completion_time;
 
        size_t xfercap; /* XFERCAP register value expanded out */
 
@@ -82,6 +86,10 @@ struct ioat_dma_chan {
        spinlock_t desc_lock;
        struct list_head free_desc;
        struct list_head used_desc;
+       unsigned long watchdog_completion;
+       int watchdog_tcp_cookie;
+       u32 watchdog_last_tcp_cookie;
+       struct delayed_work work;
 
        int pending;
        int dmacount;
@@ -98,6 +106,7 @@ struct ioat_dma_chan {
                        u32 high;
                };
        } *completion_virt;
+       unsigned long last_compl_desc_addr_hw;
        struct tasklet_struct cleanup_task;
 };
 
@@ -121,17 +130,34 @@ struct ioat_desc_sw {
        struct dma_async_tx_descriptor async_tx;
 };
 
+static inline void ioat_set_tcp_copy_break(struct ioatdma_device *dev)
+{
+       #ifdef CONFIG_NET_DMA
+       switch (dev->version) {
+       case IOAT_VER_1_2:
+       case IOAT_VER_3_0:
+               sysctl_tcp_dma_copybreak = 4096;
+               break;
+       case IOAT_VER_2_0:
+               sysctl_tcp_dma_copybreak = 2048;
+               break;
+       }
+       #endif
+}
+
 #if defined(CONFIG_INTEL_IOATDMA) || defined(CONFIG_INTEL_IOATDMA_MODULE)
 struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
                                      void __iomem *iobase);
 void ioat_dma_remove(struct ioatdma_device *device);
 struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase);
 struct dca_provider *ioat2_dca_init(struct pci_dev *pdev, void __iomem *iobase);
+struct dca_provider *ioat3_dca_init(struct pci_dev *pdev, void __iomem *iobase);
 #else
 #define ioat_dma_probe(pdev, iobase)    NULL
 #define ioat_dma_remove(device)         do { } while (0)
 #define ioat_dca_init(pdev, iobase)    NULL
 #define ioat2_dca_init(pdev, iobase)   NULL
+#define ioat3_dca_init(pdev, iobase)   NULL
 #endif
 
 #endif /* IOATDMA_H */
index dd470fa91d86a4e10d8187e63d095125fb5a8526..f1ae2c776f7487b40e695395e3562679f420b29e 100644 (file)
@@ -35,6 +35,7 @@
 #define IOAT_PCI_SID            0x8086
 #define IOAT_VER_1_2            0x12    /* Version 1.2 */
 #define IOAT_VER_2_0            0x20    /* Version 2.0 */
+#define IOAT_VER_3_0            0x30    /* Version 3.0 */
 
 struct ioat_dma_descriptor {
        uint32_t        size;
index 9832d7ebd931a0a76dafc6d66948b37e4a16da52..827cb503cac6979a0fa98e3fbd25a113e14fda27 100644 (file)
 #define IOAT_PCI_DMACTRL_DMA_EN                        0x00000001
 #define IOAT_PCI_DMACTRL_MSI_EN                        0x00000002
 
+#define IOAT_PCI_DEVICE_ID_OFFSET              0x02
+#define IOAT_PCI_DMAUNCERRSTS_OFFSET           0x148
+#define IOAT_PCI_CHANERRMASK_INT_OFFSET                0x184
+
 /* MMIO Device Registers */
 #define IOAT_CHANCNT_OFFSET                    0x00    /*  8-bit */
 
 #define IOAT_DCA_GREQID_VALID       0x20000000
 #define IOAT_DCA_GREQID_LASTID      0x80000000
 
+#define IOAT3_CSI_CAPABILITY_OFFSET 0x08
+#define IOAT3_CSI_CAPABILITY_PREFETCH    0x1
+
+#define IOAT3_PCI_CAPABILITY_OFFSET 0x0A
+#define IOAT3_PCI_CAPABILITY_MEMWR  0x1
+
+#define IOAT3_CSI_CONTROL_OFFSET    0x0C
+#define IOAT3_CSI_CONTROL_PREFETCH  0x1
+
+#define IOAT3_PCI_CONTROL_OFFSET    0x0E
+#define IOAT3_PCI_CONTROL_MEMWR     0x1
+
+#define IOAT3_APICID_TAG_MAP_OFFSET 0x10
+#define IOAT3_APICID_TAG_MAP_OFFSET_LOW  0x10
+#define IOAT3_APICID_TAG_MAP_OFFSET_HIGH 0x14
 
+#define IOAT3_DCA_GREQID_OFFSET     0x02
 
 #define IOAT1_CHAINADDR_OFFSET         0x0C    /* 64-bit Descriptor Chain Address Register */
 #define IOAT2_CHAINADDR_OFFSET         0x10    /* 64-bit Descriptor Chain Address Register */
index 0ec0f431e6a1d4bc30a179850ddadfbcec2d1ff3..85bfeba4d85eab01eb9e2c7b339eeccd674e2b0b 100644 (file)
@@ -82,17 +82,24 @@ iop_adma_run_tx_complete_actions(struct iop_adma_desc_slot *desc,
                        struct device *dev =
                                &iop_chan->device->pdev->dev;
                        u32 len = unmap->unmap_len;
-                       u32 src_cnt = unmap->unmap_src_cnt;
-                       dma_addr_t addr = iop_desc_get_dest_addr(unmap,
-                               iop_chan);
-
-                       dma_unmap_page(dev, addr, len, DMA_FROM_DEVICE);
-                       while (src_cnt--) {
-                               addr = iop_desc_get_src_addr(unmap,
-                                                       iop_chan,
-                                                       src_cnt);
-                               dma_unmap_page(dev, addr, len,
-                                       DMA_TO_DEVICE);
+                       enum dma_ctrl_flags flags = desc->async_tx.flags;
+                       u32 src_cnt;
+                       dma_addr_t addr;
+
+                       if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+                               addr = iop_desc_get_dest_addr(unmap, iop_chan);
+                               dma_unmap_page(dev, addr, len, DMA_FROM_DEVICE);
+                       }
+
+                       if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+                               src_cnt = unmap->unmap_src_cnt;
+                               while (src_cnt--) {
+                                       addr = iop_desc_get_src_addr(unmap,
+                                                                    iop_chan,
+                                                                    src_cnt);
+                                       dma_unmap_page(dev, addr, len,
+                                                      DMA_TO_DEVICE);
+                               }
                        }
                        desc->group_head = NULL;
                }
@@ -366,8 +373,8 @@ retry:
        if (!retry++)
                goto retry;
 
-       /* try to free some slots if the allocation fails */
-       tasklet_schedule(&iop_chan->irq_tasklet);
+       /* perform direct reclaim if the allocation fails */
+       __iop_adma_slot_cleanup(iop_chan);
 
        return NULL;
 }
@@ -443,8 +450,18 @@ iop_adma_tx_submit(struct dma_async_tx_descriptor *tx)
 static void iop_chan_start_null_memcpy(struct iop_adma_chan *iop_chan);
 static void iop_chan_start_null_xor(struct iop_adma_chan *iop_chan);
 
-/* returns the number of allocated descriptors */
-static int iop_adma_alloc_chan_resources(struct dma_chan *chan)
+/**
+ * iop_adma_alloc_chan_resources -  returns the number of allocated descriptors
+ * @chan - allocate descriptor resources for this channel
+ * @client - current client requesting the channel be ready for requests
+ *
+ * Note: We keep the slots for 1 operation on iop_chan->chain at all times.  To
+ * avoid deadlock, via async_xor, num_descs_in_pool must at a minimum be
+ * greater than 2x the number slots needed to satisfy a device->max_xor
+ * request.
+ * */
+static int iop_adma_alloc_chan_resources(struct dma_chan *chan,
+                                        struct dma_client *client)
 {
        char *hw_desc;
        int idx;
@@ -838,7 +855,7 @@ static int __devinit iop_adma_memcpy_self_test(struct iop_adma_device *device)
        dma_chan = container_of(device->common.channels.next,
                                struct dma_chan,
                                device_node);
-       if (iop_adma_alloc_chan_resources(dma_chan) < 1) {
+       if (iop_adma_alloc_chan_resources(dma_chan, NULL) < 1) {
                err = -ENODEV;
                goto out;
        }
@@ -936,7 +953,7 @@ iop_adma_xor_zero_sum_self_test(struct iop_adma_device *device)
        dma_chan = container_of(device->common.channels.next,
                                struct dma_chan,
                                device_node);
-       if (iop_adma_alloc_chan_resources(dma_chan) < 1) {
+       if (iop_adma_alloc_chan_resources(dma_chan, NULL) < 1) {
                err = -ENODEV;
                goto out;
        }
@@ -1387,6 +1404,8 @@ static void iop_chan_start_null_xor(struct iop_adma_chan *iop_chan)
        spin_unlock_bh(&iop_chan->lock);
 }
 
+MODULE_ALIAS("platform:iop-adma");
+
 static struct platform_driver iop_adma_driver = {
        .probe          = iop_adma_probe,
        .remove         = iop_adma_remove,
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
new file mode 100644 (file)
index 0000000..a4e4494
--- /dev/null
@@ -0,0 +1,1375 @@
+/*
+ * offload engine driver for the Marvell XOR engine
+ * Copyright (C) 2007, 2008, Marvell International Ltd.
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/async_tx.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/memory.h>
+#include <asm/plat-orion/mv_xor.h>
+#include "mv_xor.h"
+
+static void mv_xor_issue_pending(struct dma_chan *chan);
+
+#define to_mv_xor_chan(chan)           \
+       container_of(chan, struct mv_xor_chan, common)
+
+#define to_mv_xor_device(dev)          \
+       container_of(dev, struct mv_xor_device, common)
+
+#define to_mv_xor_slot(tx)             \
+       container_of(tx, struct mv_xor_desc_slot, async_tx)
+
+static void mv_desc_init(struct mv_xor_desc_slot *desc, unsigned long flags)
+{
+       struct mv_xor_desc *hw_desc = desc->hw_desc;
+
+       hw_desc->status = (1 << 31);
+       hw_desc->phy_next_desc = 0;
+       hw_desc->desc_command = (1 << 31);
+}
+
+static u32 mv_desc_get_dest_addr(struct mv_xor_desc_slot *desc)
+{
+       struct mv_xor_desc *hw_desc = desc->hw_desc;
+       return hw_desc->phy_dest_addr;
+}
+
+static u32 mv_desc_get_src_addr(struct mv_xor_desc_slot *desc,
+                               int src_idx)
+{
+       struct mv_xor_desc *hw_desc = desc->hw_desc;
+       return hw_desc->phy_src_addr[src_idx];
+}
+
+
+static void mv_desc_set_byte_count(struct mv_xor_desc_slot *desc,
+                                  u32 byte_count)
+{
+       struct mv_xor_desc *hw_desc = desc->hw_desc;
+       hw_desc->byte_count = byte_count;
+}
+
+static void mv_desc_set_next_desc(struct mv_xor_desc_slot *desc,
+                                 u32 next_desc_addr)
+{
+       struct mv_xor_desc *hw_desc = desc->hw_desc;
+       BUG_ON(hw_desc->phy_next_desc);
+       hw_desc->phy_next_desc = next_desc_addr;
+}
+
+static void mv_desc_clear_next_desc(struct mv_xor_desc_slot *desc)
+{
+       struct mv_xor_desc *hw_desc = desc->hw_desc;
+       hw_desc->phy_next_desc = 0;
+}
+
+static void mv_desc_set_block_fill_val(struct mv_xor_desc_slot *desc, u32 val)
+{
+       desc->value = val;
+}
+
+static void mv_desc_set_dest_addr(struct mv_xor_desc_slot *desc,
+                                 dma_addr_t addr)
+{
+       struct mv_xor_desc *hw_desc = desc->hw_desc;
+       hw_desc->phy_dest_addr = addr;
+}
+
+static int mv_chan_memset_slot_count(size_t len)
+{
+       return 1;
+}
+
+#define mv_chan_memcpy_slot_count(c) mv_chan_memset_slot_count(c)
+
+static void mv_desc_set_src_addr(struct mv_xor_desc_slot *desc,
+                                int index, dma_addr_t addr)
+{
+       struct mv_xor_desc *hw_desc = desc->hw_desc;
+       hw_desc->phy_src_addr[index] = addr;
+       if (desc->type == DMA_XOR)
+               hw_desc->desc_command |= (1 << index);
+}
+
+static u32 mv_chan_get_current_desc(struct mv_xor_chan *chan)
+{
+       return __raw_readl(XOR_CURR_DESC(chan));
+}
+
+static void mv_chan_set_next_descriptor(struct mv_xor_chan *chan,
+                                       u32 next_desc_addr)
+{
+       __raw_writel(next_desc_addr, XOR_NEXT_DESC(chan));
+}
+
+static void mv_chan_set_dest_pointer(struct mv_xor_chan *chan, u32 desc_addr)
+{
+       __raw_writel(desc_addr, XOR_DEST_POINTER(chan));
+}
+
+static void mv_chan_set_block_size(struct mv_xor_chan *chan, u32 block_size)
+{
+       __raw_writel(block_size, XOR_BLOCK_SIZE(chan));
+}
+
+static void mv_chan_set_value(struct mv_xor_chan *chan, u32 value)
+{
+       __raw_writel(value, XOR_INIT_VALUE_LOW(chan));
+       __raw_writel(value, XOR_INIT_VALUE_HIGH(chan));
+}
+
+static void mv_chan_unmask_interrupts(struct mv_xor_chan *chan)
+{
+       u32 val = __raw_readl(XOR_INTR_MASK(chan));
+       val |= XOR_INTR_MASK_VALUE << (chan->idx * 16);
+       __raw_writel(val, XOR_INTR_MASK(chan));
+}
+
+static u32 mv_chan_get_intr_cause(struct mv_xor_chan *chan)
+{
+       u32 intr_cause = __raw_readl(XOR_INTR_CAUSE(chan));
+       intr_cause = (intr_cause >> (chan->idx * 16)) & 0xFFFF;
+       return intr_cause;
+}
+
+static int mv_is_err_intr(u32 intr_cause)
+{
+       if (intr_cause & ((1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)))
+               return 1;
+
+       return 0;
+}
+
+static void mv_xor_device_clear_eoc_cause(struct mv_xor_chan *chan)
+{
+       u32 val = (1 << (1 + (chan->idx * 16)));
+       dev_dbg(chan->device->common.dev, "%s, val 0x%08x\n", __func__, val);
+       __raw_writel(val, XOR_INTR_CAUSE(chan));
+}
+
+static void mv_xor_device_clear_err_status(struct mv_xor_chan *chan)
+{
+       u32 val = 0xFFFF0000 >> (chan->idx * 16);
+       __raw_writel(val, XOR_INTR_CAUSE(chan));
+}
+
+static int mv_can_chain(struct mv_xor_desc_slot *desc)
+{
+       struct mv_xor_desc_slot *chain_old_tail = list_entry(
+               desc->chain_node.prev, struct mv_xor_desc_slot, chain_node);
+
+       if (chain_old_tail->type != desc->type)
+               return 0;
+       if (desc->type == DMA_MEMSET)
+               return 0;
+
+       return 1;
+}
+
+static void mv_set_mode(struct mv_xor_chan *chan,
+                              enum dma_transaction_type type)
+{
+       u32 op_mode;
+       u32 config = __raw_readl(XOR_CONFIG(chan));
+
+       switch (type) {
+       case DMA_XOR:
+               op_mode = XOR_OPERATION_MODE_XOR;
+               break;
+       case DMA_MEMCPY:
+               op_mode = XOR_OPERATION_MODE_MEMCPY;
+               break;
+       case DMA_MEMSET:
+               op_mode = XOR_OPERATION_MODE_MEMSET;
+               break;
+       default:
+               dev_printk(KERN_ERR, chan->device->common.dev,
+                          "error: unsupported operation %d.\n",
+                          type);
+               BUG();
+               return;
+       }
+
+       config &= ~0x7;
+       config |= op_mode;
+       __raw_writel(config, XOR_CONFIG(chan));
+       chan->current_type = type;
+}
+
+static void mv_chan_activate(struct mv_xor_chan *chan)
+{
+       u32 activation;
+
+       dev_dbg(chan->device->common.dev, " activate chan.\n");
+       activation = __raw_readl(XOR_ACTIVATION(chan));
+       activation |= 0x1;
+       __raw_writel(activation, XOR_ACTIVATION(chan));
+}
+
+static char mv_chan_is_busy(struct mv_xor_chan *chan)
+{
+       u32 state = __raw_readl(XOR_ACTIVATION(chan));
+
+       state = (state >> 4) & 0x3;
+
+       return (state == 1) ? 1 : 0;
+}
+
+static int mv_chan_xor_slot_count(size_t len, int src_cnt)
+{
+       return 1;
+}
+
+/**
+ * mv_xor_free_slots - flags descriptor slots for reuse
+ * @slot: Slot to free
+ * Caller must hold &mv_chan->lock while calling this function
+ */
+static void mv_xor_free_slots(struct mv_xor_chan *mv_chan,
+                             struct mv_xor_desc_slot *slot)
+{
+       dev_dbg(mv_chan->device->common.dev, "%s %d slot %p\n",
+               __func__, __LINE__, slot);
+
+       slot->slots_per_op = 0;
+
+}
+
+/*
+ * mv_xor_start_new_chain - program the engine to operate on new chain headed by
+ * sw_desc
+ * Caller must hold &mv_chan->lock while calling this function
+ */
+static void mv_xor_start_new_chain(struct mv_xor_chan *mv_chan,
+                                  struct mv_xor_desc_slot *sw_desc)
+{
+       dev_dbg(mv_chan->device->common.dev, "%s %d: sw_desc %p\n",
+               __func__, __LINE__, sw_desc);
+       if (sw_desc->type != mv_chan->current_type)
+               mv_set_mode(mv_chan, sw_desc->type);
+
+       if (sw_desc->type == DMA_MEMSET) {
+               /* for memset requests we need to program the engine, no
+                * descriptors used.
+                */
+               struct mv_xor_desc *hw_desc = sw_desc->hw_desc;
+               mv_chan_set_dest_pointer(mv_chan, hw_desc->phy_dest_addr);
+               mv_chan_set_block_size(mv_chan, sw_desc->unmap_len);
+               mv_chan_set_value(mv_chan, sw_desc->value);
+       } else {
+               /* set the hardware chain */
+               mv_chan_set_next_descriptor(mv_chan, sw_desc->async_tx.phys);
+       }
+       mv_chan->pending += sw_desc->slot_cnt;
+       mv_xor_issue_pending(&mv_chan->common);
+}
+
+static dma_cookie_t
+mv_xor_run_tx_complete_actions(struct mv_xor_desc_slot *desc,
+       struct mv_xor_chan *mv_chan, dma_cookie_t cookie)
+{
+       BUG_ON(desc->async_tx.cookie < 0);
+
+       if (desc->async_tx.cookie > 0) {
+               cookie = desc->async_tx.cookie;
+
+               /* call the callback (must not sleep or submit new
+                * operations to this channel)
+                */
+               if (desc->async_tx.callback)
+                       desc->async_tx.callback(
+                               desc->async_tx.callback_param);
+
+               /* unmap dma addresses
+                * (unmap_single vs unmap_page?)
+                */
+               if (desc->group_head && desc->unmap_len) {
+                       struct mv_xor_desc_slot *unmap = desc->group_head;
+                       struct device *dev =
+                               &mv_chan->device->pdev->dev;
+                       u32 len = unmap->unmap_len;
+                       enum dma_ctrl_flags flags = desc->async_tx.flags;
+                       u32 src_cnt;
+                       dma_addr_t addr;
+
+                       if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+                               addr = mv_desc_get_dest_addr(unmap);
+                               dma_unmap_page(dev, addr, len, DMA_FROM_DEVICE);
+                       }
+
+                       if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+                               src_cnt = unmap->unmap_src_cnt;
+                               while (src_cnt--) {
+                                       addr = mv_desc_get_src_addr(unmap,
+                                                                   src_cnt);
+                                       dma_unmap_page(dev, addr, len,
+                                                      DMA_TO_DEVICE);
+                               }
+                       }
+                       desc->group_head = NULL;
+               }
+       }
+
+       /* run dependent operations */
+       async_tx_run_dependencies(&desc->async_tx);
+
+       return cookie;
+}
+
+static int
+mv_xor_clean_completed_slots(struct mv_xor_chan *mv_chan)
+{
+       struct mv_xor_desc_slot *iter, *_iter;
+
+       dev_dbg(mv_chan->device->common.dev, "%s %d\n", __func__, __LINE__);
+       list_for_each_entry_safe(iter, _iter, &mv_chan->completed_slots,
+                                completed_node) {
+
+               if (async_tx_test_ack(&iter->async_tx)) {
+                       list_del(&iter->completed_node);
+                       mv_xor_free_slots(mv_chan, iter);
+               }
+       }
+       return 0;
+}
+
+static int
+mv_xor_clean_slot(struct mv_xor_desc_slot *desc,
+       struct mv_xor_chan *mv_chan)
+{
+       dev_dbg(mv_chan->device->common.dev, "%s %d: desc %p flags %d\n",
+               __func__, __LINE__, desc, desc->async_tx.flags);
+       list_del(&desc->chain_node);
+       /* the client is allowed to attach dependent operations
+        * until 'ack' is set
+        */
+       if (!async_tx_test_ack(&desc->async_tx)) {
+               /* move this slot to the completed_slots */
+               list_add_tail(&desc->completed_node, &mv_chan->completed_slots);
+               return 0;
+       }
+
+       mv_xor_free_slots(mv_chan, desc);
+       return 0;
+}
+
+static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan)
+{
+       struct mv_xor_desc_slot *iter, *_iter;
+       dma_cookie_t cookie = 0;
+       int busy = mv_chan_is_busy(mv_chan);
+       u32 current_desc = mv_chan_get_current_desc(mv_chan);
+       int seen_current = 0;
+
+       dev_dbg(mv_chan->device->common.dev, "%s %d\n", __func__, __LINE__);
+       dev_dbg(mv_chan->device->common.dev, "current_desc %x\n", current_desc);
+       mv_xor_clean_completed_slots(mv_chan);
+
+       /* free completed slots from the chain starting with
+        * the oldest descriptor
+        */
+
+       list_for_each_entry_safe(iter, _iter, &mv_chan->chain,
+                                       chain_node) {
+               prefetch(_iter);
+               prefetch(&_iter->async_tx);
+
+               /* do not advance past the current descriptor loaded into the
+                * hardware channel, subsequent descriptors are either in
+                * process or have not been submitted
+                */
+               if (seen_current)
+                       break;
+
+               /* stop the search if we reach the current descriptor and the
+                * channel is busy
+                */
+               if (iter->async_tx.phys == current_desc) {
+                       seen_current = 1;
+                       if (busy)
+                               break;
+               }
+
+               cookie = mv_xor_run_tx_complete_actions(iter, mv_chan, cookie);
+
+               if (mv_xor_clean_slot(iter, mv_chan))
+                       break;
+       }
+
+       if ((busy == 0) && !list_empty(&mv_chan->chain)) {
+               struct mv_xor_desc_slot *chain_head;
+               chain_head = list_entry(mv_chan->chain.next,
+                                       struct mv_xor_desc_slot,
+                                       chain_node);
+
+               mv_xor_start_new_chain(mv_chan, chain_head);
+       }
+
+       if (cookie > 0)
+               mv_chan->completed_cookie = cookie;
+}
+
+static void
+mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan)
+{
+       spin_lock_bh(&mv_chan->lock);
+       __mv_xor_slot_cleanup(mv_chan);
+       spin_unlock_bh(&mv_chan->lock);
+}
+
+static void mv_xor_tasklet(unsigned long data)
+{
+       struct mv_xor_chan *chan = (struct mv_xor_chan *) data;
+       __mv_xor_slot_cleanup(chan);
+}
+
+static struct mv_xor_desc_slot *
+mv_xor_alloc_slots(struct mv_xor_chan *mv_chan, int num_slots,
+                   int slots_per_op)
+{
+       struct mv_xor_desc_slot *iter, *_iter, *alloc_start = NULL;
+       LIST_HEAD(chain);
+       int slots_found, retry = 0;
+
+       /* start search from the last allocated descrtiptor
+        * if a contiguous allocation can not be found start searching
+        * from the beginning of the list
+        */
+retry:
+       slots_found = 0;
+       if (retry == 0)
+               iter = mv_chan->last_used;
+       else
+               iter = list_entry(&mv_chan->all_slots,
+                       struct mv_xor_desc_slot,
+                       slot_node);
+
+       list_for_each_entry_safe_continue(
+               iter, _iter, &mv_chan->all_slots, slot_node) {
+               prefetch(_iter);
+               prefetch(&_iter->async_tx);
+               if (iter->slots_per_op) {
+                       /* give up after finding the first busy slot
+                        * on the second pass through the list
+                        */
+                       if (retry)
+                               break;
+
+                       slots_found = 0;
+                       continue;
+               }
+
+               /* start the allocation if the slot is correctly aligned */
+               if (!slots_found++)
+                       alloc_start = iter;
+
+               if (slots_found == num_slots) {
+                       struct mv_xor_desc_slot *alloc_tail = NULL;
+                       struct mv_xor_desc_slot *last_used = NULL;
+                       iter = alloc_start;
+                       while (num_slots) {
+                               int i;
+
+                               /* pre-ack all but the last descriptor */
+                               async_tx_ack(&iter->async_tx);
+
+                               list_add_tail(&iter->chain_node, &chain);
+                               alloc_tail = iter;
+                               iter->async_tx.cookie = 0;
+                               iter->slot_cnt = num_slots;
+                               iter->xor_check_result = NULL;
+                               for (i = 0; i < slots_per_op; i++) {
+                                       iter->slots_per_op = slots_per_op - i;
+                                       last_used = iter;
+                                       iter = list_entry(iter->slot_node.next,
+                                               struct mv_xor_desc_slot,
+                                               slot_node);
+                               }
+                               num_slots -= slots_per_op;
+                       }
+                       alloc_tail->group_head = alloc_start;
+                       alloc_tail->async_tx.cookie = -EBUSY;
+                       list_splice(&chain, &alloc_tail->async_tx.tx_list);
+                       mv_chan->last_used = last_used;
+                       mv_desc_clear_next_desc(alloc_start);
+                       mv_desc_clear_next_desc(alloc_tail);
+                       return alloc_tail;
+               }
+       }
+       if (!retry++)
+               goto retry;
+
+       /* try to free some slots if the allocation fails */
+       tasklet_schedule(&mv_chan->irq_tasklet);
+
+       return NULL;
+}
+
+static dma_cookie_t
+mv_desc_assign_cookie(struct mv_xor_chan *mv_chan,
+                     struct mv_xor_desc_slot *desc)
+{
+       dma_cookie_t cookie = mv_chan->common.cookie;
+
+       if (++cookie < 0)
+               cookie = 1;
+       mv_chan->common.cookie = desc->async_tx.cookie = cookie;
+       return cookie;
+}
+
+/************************ DMA engine API functions ****************************/
+static dma_cookie_t
+mv_xor_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+       struct mv_xor_desc_slot *sw_desc = to_mv_xor_slot(tx);
+       struct mv_xor_chan *mv_chan = to_mv_xor_chan(tx->chan);
+       struct mv_xor_desc_slot *grp_start, *old_chain_tail;
+       dma_cookie_t cookie;
+       int new_hw_chain = 1;
+
+       dev_dbg(mv_chan->device->common.dev,
+               "%s sw_desc %p: async_tx %p\n",
+               __func__, sw_desc, &sw_desc->async_tx);
+
+       grp_start = sw_desc->group_head;
+
+       spin_lock_bh(&mv_chan->lock);
+       cookie = mv_desc_assign_cookie(mv_chan, sw_desc);
+
+       if (list_empty(&mv_chan->chain))
+               list_splice_init(&sw_desc->async_tx.tx_list, &mv_chan->chain);
+       else {
+               new_hw_chain = 0;
+
+               old_chain_tail = list_entry(mv_chan->chain.prev,
+                                           struct mv_xor_desc_slot,
+                                           chain_node);
+               list_splice_init(&grp_start->async_tx.tx_list,
+                                &old_chain_tail->chain_node);
+
+               if (!mv_can_chain(grp_start))
+                       goto submit_done;
+
+               dev_dbg(mv_chan->device->common.dev, "Append to last desc %x\n",
+                       old_chain_tail->async_tx.phys);
+
+               /* fix up the hardware chain */
+               mv_desc_set_next_desc(old_chain_tail, grp_start->async_tx.phys);
+
+               /* if the channel is not busy */
+               if (!mv_chan_is_busy(mv_chan)) {
+                       u32 current_desc = mv_chan_get_current_desc(mv_chan);
+                       /*
+                        * and the curren desc is the end of the chain before
+                        * the append, then we need to start the channel
+                        */
+                       if (current_desc == old_chain_tail->async_tx.phys)
+                               new_hw_chain = 1;
+               }
+       }
+
+       if (new_hw_chain)
+               mv_xor_start_new_chain(mv_chan, grp_start);
+
+submit_done:
+       spin_unlock_bh(&mv_chan->lock);
+
+       return cookie;
+}
+
+/* returns the number of allocated descriptors */
+static int mv_xor_alloc_chan_resources(struct dma_chan *chan,
+                                      struct dma_client *client)
+{
+       char *hw_desc;
+       int idx;
+       struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
+       struct mv_xor_desc_slot *slot = NULL;
+       struct mv_xor_platform_data *plat_data =
+               mv_chan->device->pdev->dev.platform_data;
+       int num_descs_in_pool = plat_data->pool_size/MV_XOR_SLOT_SIZE;
+
+       /* Allocate descriptor slots */
+       idx = mv_chan->slots_allocated;
+       while (idx < num_descs_in_pool) {
+               slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+               if (!slot) {
+                       printk(KERN_INFO "MV XOR Channel only initialized"
+                               " %d descriptor slots", idx);
+                       break;
+               }
+               hw_desc = (char *) mv_chan->device->dma_desc_pool_virt;
+               slot->hw_desc = (void *) &hw_desc[idx * MV_XOR_SLOT_SIZE];
+
+               dma_async_tx_descriptor_init(&slot->async_tx, chan);
+               slot->async_tx.tx_submit = mv_xor_tx_submit;
+               INIT_LIST_HEAD(&slot->chain_node);
+               INIT_LIST_HEAD(&slot->slot_node);
+               INIT_LIST_HEAD(&slot->async_tx.tx_list);
+               hw_desc = (char *) mv_chan->device->dma_desc_pool;
+               slot->async_tx.phys =
+                       (dma_addr_t) &hw_desc[idx * MV_XOR_SLOT_SIZE];
+               slot->idx = idx++;
+
+               spin_lock_bh(&mv_chan->lock);
+               mv_chan->slots_allocated = idx;
+               list_add_tail(&slot->slot_node, &mv_chan->all_slots);
+               spin_unlock_bh(&mv_chan->lock);
+       }
+
+       if (mv_chan->slots_allocated && !mv_chan->last_used)
+               mv_chan->last_used = list_entry(mv_chan->all_slots.next,
+                                       struct mv_xor_desc_slot,
+                                       slot_node);
+
+       dev_dbg(mv_chan->device->common.dev,
+               "allocated %d descriptor slots last_used: %p\n",
+               mv_chan->slots_allocated, mv_chan->last_used);
+
+       return mv_chan->slots_allocated ? : -ENOMEM;
+}
+
+static struct dma_async_tx_descriptor *
+mv_xor_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
+               size_t len, unsigned long flags)
+{
+       struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
+       struct mv_xor_desc_slot *sw_desc, *grp_start;
+       int slot_cnt;
+
+       dev_dbg(mv_chan->device->common.dev,
+               "%s dest: %x src %x len: %u flags: %ld\n",
+               __func__, dest, src, len, flags);
+       if (unlikely(len < MV_XOR_MIN_BYTE_COUNT))
+               return NULL;
+
+       BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT));
+
+       spin_lock_bh(&mv_chan->lock);
+       slot_cnt = mv_chan_memcpy_slot_count(len);
+       sw_desc = mv_xor_alloc_slots(mv_chan, slot_cnt, 1);
+       if (sw_desc) {
+               sw_desc->type = DMA_MEMCPY;
+               sw_desc->async_tx.flags = flags;
+               grp_start = sw_desc->group_head;
+               mv_desc_init(grp_start, flags);
+               mv_desc_set_byte_count(grp_start, len);
+               mv_desc_set_dest_addr(sw_desc->group_head, dest);
+               mv_desc_set_src_addr(grp_start, 0, src);
+               sw_desc->unmap_src_cnt = 1;
+               sw_desc->unmap_len = len;
+       }
+       spin_unlock_bh(&mv_chan->lock);
+
+       dev_dbg(mv_chan->device->common.dev,
+               "%s sw_desc %p async_tx %p\n",
+               __func__, sw_desc, sw_desc ? &sw_desc->async_tx : 0);
+
+       return sw_desc ? &sw_desc->async_tx : NULL;
+}
+
+static struct dma_async_tx_descriptor *
+mv_xor_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value,
+                      size_t len, unsigned long flags)
+{
+       struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
+       struct mv_xor_desc_slot *sw_desc, *grp_start;
+       int slot_cnt;
+
+       dev_dbg(mv_chan->device->common.dev,
+               "%s dest: %x len: %u flags: %ld\n",
+               __func__, dest, len, flags);
+       if (unlikely(len < MV_XOR_MIN_BYTE_COUNT))
+               return NULL;
+
+       BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT));
+
+       spin_lock_bh(&mv_chan->lock);
+       slot_cnt = mv_chan_memset_slot_count(len);
+       sw_desc = mv_xor_alloc_slots(mv_chan, slot_cnt, 1);
+       if (sw_desc) {
+               sw_desc->type = DMA_MEMSET;
+               sw_desc->async_tx.flags = flags;
+               grp_start = sw_desc->group_head;
+               mv_desc_init(grp_start, flags);
+               mv_desc_set_byte_count(grp_start, len);
+               mv_desc_set_dest_addr(sw_desc->group_head, dest);
+               mv_desc_set_block_fill_val(grp_start, value);
+               sw_desc->unmap_src_cnt = 1;
+               sw_desc->unmap_len = len;
+       }
+       spin_unlock_bh(&mv_chan->lock);
+       dev_dbg(mv_chan->device->common.dev,
+               "%s sw_desc %p async_tx %p \n",
+               __func__, sw_desc, &sw_desc->async_tx);
+       return sw_desc ? &sw_desc->async_tx : NULL;
+}
+
+static struct dma_async_tx_descriptor *
+mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,
+                   unsigned int src_cnt, size_t len, unsigned long flags)
+{
+       struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
+       struct mv_xor_desc_slot *sw_desc, *grp_start;
+       int slot_cnt;
+
+       if (unlikely(len < MV_XOR_MIN_BYTE_COUNT))
+               return NULL;
+
+       BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT));
+
+       dev_dbg(mv_chan->device->common.dev,
+               "%s src_cnt: %d len: dest %x %u flags: %ld\n",
+               __func__, src_cnt, len, dest, flags);
+
+       spin_lock_bh(&mv_chan->lock);
+       slot_cnt = mv_chan_xor_slot_count(len, src_cnt);
+       sw_desc = mv_xor_alloc_slots(mv_chan, slot_cnt, 1);
+       if (sw_desc) {
+               sw_desc->type = DMA_XOR;
+               sw_desc->async_tx.flags = flags;
+               grp_start = sw_desc->group_head;
+               mv_desc_init(grp_start, flags);
+               /* the byte count field is the same as in memcpy desc*/
+               mv_desc_set_byte_count(grp_start, len);
+               mv_desc_set_dest_addr(sw_desc->group_head, dest);
+               sw_desc->unmap_src_cnt = src_cnt;
+               sw_desc->unmap_len = len;
+               while (src_cnt--)
+                       mv_desc_set_src_addr(grp_start, src_cnt, src[src_cnt]);
+       }
+       spin_unlock_bh(&mv_chan->lock);
+       dev_dbg(mv_chan->device->common.dev,
+               "%s sw_desc %p async_tx %p \n",
+               __func__, sw_desc, &sw_desc->async_tx);
+       return sw_desc ? &sw_desc->async_tx : NULL;
+}
+
+static void mv_xor_free_chan_resources(struct dma_chan *chan)
+{
+       struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
+       struct mv_xor_desc_slot *iter, *_iter;
+       int in_use_descs = 0;
+
+       mv_xor_slot_cleanup(mv_chan);
+
+       spin_lock_bh(&mv_chan->lock);
+       list_for_each_entry_safe(iter, _iter, &mv_chan->chain,
+                                       chain_node) {
+               in_use_descs++;
+               list_del(&iter->chain_node);
+       }
+       list_for_each_entry_safe(iter, _iter, &mv_chan->completed_slots,
+                                completed_node) {
+               in_use_descs++;
+               list_del(&iter->completed_node);
+       }
+       list_for_each_entry_safe_reverse(
+               iter, _iter, &mv_chan->all_slots, slot_node) {
+               list_del(&iter->slot_node);
+               kfree(iter);
+               mv_chan->slots_allocated--;
+       }
+       mv_chan->last_used = NULL;
+
+       dev_dbg(mv_chan->device->common.dev, "%s slots_allocated %d\n",
+               __func__, mv_chan->slots_allocated);
+       spin_unlock_bh(&mv_chan->lock);
+
+       if (in_use_descs)
+               dev_err(mv_chan->device->common.dev,
+                       "freeing %d in use descriptors!\n", in_use_descs);
+}
+
+/**
+ * mv_xor_is_complete - poll the status of an XOR transaction
+ * @chan: XOR channel handle
+ * @cookie: XOR transaction identifier
+ */
+static enum dma_status mv_xor_is_complete(struct dma_chan *chan,
+                                         dma_cookie_t cookie,
+                                         dma_cookie_t *done,
+                                         dma_cookie_t *used)
+{
+       struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
+       dma_cookie_t last_used;
+       dma_cookie_t last_complete;
+       enum dma_status ret;
+
+       last_used = chan->cookie;
+       last_complete = mv_chan->completed_cookie;
+       mv_chan->is_complete_cookie = cookie;
+       if (done)
+               *done = last_complete;
+       if (used)
+               *used = last_used;
+
+       ret = dma_async_is_complete(cookie, last_complete, last_used);
+       if (ret == DMA_SUCCESS) {
+               mv_xor_clean_completed_slots(mv_chan);
+               return ret;
+       }
+       mv_xor_slot_cleanup(mv_chan);
+
+       last_used = chan->cookie;
+       last_complete = mv_chan->completed_cookie;
+
+       if (done)
+               *done = last_complete;
+       if (used)
+               *used = last_used;
+
+       return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+static void mv_dump_xor_regs(struct mv_xor_chan *chan)
+{
+       u32 val;
+
+       val = __raw_readl(XOR_CONFIG(chan));
+       dev_printk(KERN_ERR, chan->device->common.dev,
+                  "config       0x%08x.\n", val);
+
+       val = __raw_readl(XOR_ACTIVATION(chan));
+       dev_printk(KERN_ERR, chan->device->common.dev,
+                  "activation   0x%08x.\n", val);
+
+       val = __raw_readl(XOR_INTR_CAUSE(chan));
+       dev_printk(KERN_ERR, chan->device->common.dev,
+                  "intr cause   0x%08x.\n", val);
+
+       val = __raw_readl(XOR_INTR_MASK(chan));
+       dev_printk(KERN_ERR, chan->device->common.dev,
+                  "intr mask    0x%08x.\n", val);
+
+       val = __raw_readl(XOR_ERROR_CAUSE(chan));
+       dev_printk(KERN_ERR, chan->device->common.dev,
+                  "error cause  0x%08x.\n", val);
+
+       val = __raw_readl(XOR_ERROR_ADDR(chan));
+       dev_printk(KERN_ERR, chan->device->common.dev,
+                  "error addr   0x%08x.\n", val);
+}
+
+static void mv_xor_err_interrupt_handler(struct mv_xor_chan *chan,
+                                        u32 intr_cause)
+{
+       if (intr_cause & (1 << 4)) {
+            dev_dbg(chan->device->common.dev,
+                    "ignore this error\n");
+            return;
+       }
+
+       dev_printk(KERN_ERR, chan->device->common.dev,
+                  "error on chan %d. intr cause 0x%08x.\n",
+                  chan->idx, intr_cause);
+
+       mv_dump_xor_regs(chan);
+       BUG();
+}
+
+static irqreturn_t mv_xor_interrupt_handler(int irq, void *data)
+{
+       struct mv_xor_chan *chan = data;
+       u32 intr_cause = mv_chan_get_intr_cause(chan);
+
+       dev_dbg(chan->device->common.dev, "intr cause %x\n", intr_cause);
+
+       if (mv_is_err_intr(intr_cause))
+               mv_xor_err_interrupt_handler(chan, intr_cause);
+
+       tasklet_schedule(&chan->irq_tasklet);
+
+       mv_xor_device_clear_eoc_cause(chan);
+
+       return IRQ_HANDLED;
+}
+
+static void mv_xor_issue_pending(struct dma_chan *chan)
+{
+       struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
+
+       if (mv_chan->pending >= MV_XOR_THRESHOLD) {
+               mv_chan->pending = 0;
+               mv_chan_activate(mv_chan);
+       }
+}
+
+/*
+ * Perform a transaction to verify the HW works.
+ */
+#define MV_XOR_TEST_SIZE 2000
+
+static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device)
+{
+       int i;
+       void *src, *dest;
+       dma_addr_t src_dma, dest_dma;
+       struct dma_chan *dma_chan;
+       dma_cookie_t cookie;
+       struct dma_async_tx_descriptor *tx;
+       int err = 0;
+       struct mv_xor_chan *mv_chan;
+
+       src = kmalloc(sizeof(u8) * MV_XOR_TEST_SIZE, GFP_KERNEL);
+       if (!src)
+               return -ENOMEM;
+
+       dest = kzalloc(sizeof(u8) * MV_XOR_TEST_SIZE, GFP_KERNEL);
+       if (!dest) {
+               kfree(src);
+               return -ENOMEM;
+       }
+
+       /* Fill in src buffer */
+       for (i = 0; i < MV_XOR_TEST_SIZE; i++)
+               ((u8 *) src)[i] = (u8)i;
+
+       /* Start copy, using first DMA channel */
+       dma_chan = container_of(device->common.channels.next,
+                               struct dma_chan,
+                               device_node);
+       if (mv_xor_alloc_chan_resources(dma_chan, NULL) < 1) {
+               err = -ENODEV;
+               goto out;
+       }
+
+       dest_dma = dma_map_single(dma_chan->device->dev, dest,
+                                 MV_XOR_TEST_SIZE, DMA_FROM_DEVICE);
+
+       src_dma = dma_map_single(dma_chan->device->dev, src,
+                                MV_XOR_TEST_SIZE, DMA_TO_DEVICE);
+
+       tx = mv_xor_prep_dma_memcpy(dma_chan, dest_dma, src_dma,
+                                   MV_XOR_TEST_SIZE, 0);
+       cookie = mv_xor_tx_submit(tx);
+       mv_xor_issue_pending(dma_chan);
+       async_tx_ack(tx);
+       msleep(1);
+
+       if (mv_xor_is_complete(dma_chan, cookie, NULL, NULL) !=
+           DMA_SUCCESS) {
+               dev_printk(KERN_ERR, dma_chan->device->dev,
+                          "Self-test copy timed out, disabling\n");
+               err = -ENODEV;
+               goto free_resources;
+       }
+
+       mv_chan = to_mv_xor_chan(dma_chan);
+       dma_sync_single_for_cpu(&mv_chan->device->pdev->dev, dest_dma,
+                               MV_XOR_TEST_SIZE, DMA_FROM_DEVICE);
+       if (memcmp(src, dest, MV_XOR_TEST_SIZE)) {
+               dev_printk(KERN_ERR, dma_chan->device->dev,
+                          "Self-test copy failed compare, disabling\n");
+               err = -ENODEV;
+               goto free_resources;
+       }
+
+free_resources:
+       mv_xor_free_chan_resources(dma_chan);
+out:
+       kfree(src);
+       kfree(dest);
+       return err;
+}
+
+#define MV_XOR_NUM_SRC_TEST 4 /* must be <= 15 */
+static int __devinit
+mv_xor_xor_self_test(struct mv_xor_device *device)
+{
+       int i, src_idx;
+       struct page *dest;
+       struct page *xor_srcs[MV_XOR_NUM_SRC_TEST];
+       dma_addr_t dma_srcs[MV_XOR_NUM_SRC_TEST];
+       dma_addr_t dest_dma;
+       struct dma_async_tx_descriptor *tx;
+       struct dma_chan *dma_chan;
+       dma_cookie_t cookie;
+       u8 cmp_byte = 0;
+       u32 cmp_word;
+       int err = 0;
+       struct mv_xor_chan *mv_chan;
+
+       for (src_idx = 0; src_idx < MV_XOR_NUM_SRC_TEST; src_idx++) {
+               xor_srcs[src_idx] = alloc_page(GFP_KERNEL);
+               if (!xor_srcs[src_idx])
+                       while (src_idx--) {
+                               __free_page(xor_srcs[src_idx]);
+                               return -ENOMEM;
+                       }
+       }
+
+       dest = alloc_page(GFP_KERNEL);
+       if (!dest)
+               while (src_idx--) {
+                       __free_page(xor_srcs[src_idx]);
+                       return -ENOMEM;
+               }
+
+       /* Fill in src buffers */
+       for (src_idx = 0; src_idx < MV_XOR_NUM_SRC_TEST; src_idx++) {
+               u8 *ptr = page_address(xor_srcs[src_idx]);
+               for (i = 0; i < PAGE_SIZE; i++)
+                       ptr[i] = (1 << src_idx);
+       }
+
+       for (src_idx = 0; src_idx < MV_XOR_NUM_SRC_TEST; src_idx++)
+               cmp_byte ^= (u8) (1 << src_idx);
+
+       cmp_word = (cmp_byte << 24) | (cmp_byte << 16) |
+               (cmp_byte << 8) | cmp_byte;
+
+       memset(page_address(dest), 0, PAGE_SIZE);
+
+       dma_chan = container_of(device->common.channels.next,
+                               struct dma_chan,
+                               device_node);
+       if (mv_xor_alloc_chan_resources(dma_chan, NULL) < 1) {
+               err = -ENODEV;
+               goto out;
+       }
+
+       /* test xor */
+       dest_dma = dma_map_page(dma_chan->device->dev, dest, 0, PAGE_SIZE,
+                               DMA_FROM_DEVICE);
+
+       for (i = 0; i < MV_XOR_NUM_SRC_TEST; i++)
+               dma_srcs[i] = dma_map_page(dma_chan->device->dev, xor_srcs[i],
+                                          0, PAGE_SIZE, DMA_TO_DEVICE);
+
+       tx = mv_xor_prep_dma_xor(dma_chan, dest_dma, dma_srcs,
+                                MV_XOR_NUM_SRC_TEST, PAGE_SIZE, 0);
+
+       cookie = mv_xor_tx_submit(tx);
+       mv_xor_issue_pending(dma_chan);
+       async_tx_ack(tx);
+       msleep(8);
+
+       if (mv_xor_is_complete(dma_chan, cookie, NULL, NULL) !=
+           DMA_SUCCESS) {
+               dev_printk(KERN_ERR, dma_chan->device->dev,
+                          "Self-test xor timed out, disabling\n");
+               err = -ENODEV;
+               goto free_resources;
+       }
+
+       mv_chan = to_mv_xor_chan(dma_chan);
+       dma_sync_single_for_cpu(&mv_chan->device->pdev->dev, dest_dma,
+                               PAGE_SIZE, DMA_FROM_DEVICE);
+       for (i = 0; i < (PAGE_SIZE / sizeof(u32)); i++) {
+               u32 *ptr = page_address(dest);
+               if (ptr[i] != cmp_word) {
+                       dev_printk(KERN_ERR, dma_chan->device->dev,
+                                  "Self-test xor failed compare, disabling."
+                                  " index %d, data %x, expected %x\n", i,
+                                  ptr[i], cmp_word);
+                       err = -ENODEV;
+                       goto free_resources;
+               }
+       }
+
+free_resources:
+       mv_xor_free_chan_resources(dma_chan);
+out:
+       src_idx = MV_XOR_NUM_SRC_TEST;
+       while (src_idx--)
+               __free_page(xor_srcs[src_idx]);
+       __free_page(dest);
+       return err;
+}
+
+static int __devexit mv_xor_remove(struct platform_device *dev)
+{
+       struct mv_xor_device *device = platform_get_drvdata(dev);
+       struct dma_chan *chan, *_chan;
+       struct mv_xor_chan *mv_chan;
+       struct mv_xor_platform_data *plat_data = dev->dev.platform_data;
+
+       dma_async_device_unregister(&device->common);
+
+       dma_free_coherent(&dev->dev, plat_data->pool_size,
+                       device->dma_desc_pool_virt, device->dma_desc_pool);
+
+       list_for_each_entry_safe(chan, _chan, &device->common.channels,
+                               device_node) {
+               mv_chan = to_mv_xor_chan(chan);
+               list_del(&chan->device_node);
+       }
+
+       return 0;
+}
+
+static int __devinit mv_xor_probe(struct platform_device *pdev)
+{
+       int ret = 0;
+       int irq;
+       struct mv_xor_device *adev;
+       struct mv_xor_chan *mv_chan;
+       struct dma_device *dma_dev;
+       struct mv_xor_platform_data *plat_data = pdev->dev.platform_data;
+
+
+       adev = devm_kzalloc(&pdev->dev, sizeof(*adev), GFP_KERNEL);
+       if (!adev)
+               return -ENOMEM;
+
+       dma_dev = &adev->common;
+
+       /* allocate coherent memory for hardware descriptors
+        * note: writecombine gives slightly better performance, but
+        * requires that we explicitly flush the writes
+        */
+       adev->dma_desc_pool_virt = dma_alloc_writecombine(&pdev->dev,
+                                                         plat_data->pool_size,
+                                                         &adev->dma_desc_pool,
+                                                         GFP_KERNEL);
+       if (!adev->dma_desc_pool_virt)
+               return -ENOMEM;
+
+       adev->id = plat_data->hw_id;
+
+       /* discover transaction capabilites from the platform data */
+       dma_dev->cap_mask = plat_data->cap_mask;
+       adev->pdev = pdev;
+       platform_set_drvdata(pdev, adev);
+
+       adev->shared = platform_get_drvdata(plat_data->shared);
+
+       INIT_LIST_HEAD(&dma_dev->channels);
+
+       /* set base routines */
+       dma_dev->device_alloc_chan_resources = mv_xor_alloc_chan_resources;
+       dma_dev->device_free_chan_resources = mv_xor_free_chan_resources;
+       dma_dev->device_is_tx_complete = mv_xor_is_complete;
+       dma_dev->device_issue_pending = mv_xor_issue_pending;
+       dma_dev->dev = &pdev->dev;
+
+       /* set prep routines based on capability */
+       if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask))
+               dma_dev->device_prep_dma_memcpy = mv_xor_prep_dma_memcpy;
+       if (dma_has_cap(DMA_MEMSET, dma_dev->cap_mask))
+               dma_dev->device_prep_dma_memset = mv_xor_prep_dma_memset;
+       if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
+               dma_dev->max_xor = 8;                  ;
+               dma_dev->device_prep_dma_xor = mv_xor_prep_dma_xor;
+       }
+
+       mv_chan = devm_kzalloc(&pdev->dev, sizeof(*mv_chan), GFP_KERNEL);
+       if (!mv_chan) {
+               ret = -ENOMEM;
+               goto err_free_dma;
+       }
+       mv_chan->device = adev;
+       mv_chan->idx = plat_data->hw_id;
+       mv_chan->mmr_base = adev->shared->xor_base;
+
+       if (!mv_chan->mmr_base) {
+               ret = -ENOMEM;
+               goto err_free_dma;
+       }
+       tasklet_init(&mv_chan->irq_tasklet, mv_xor_tasklet, (unsigned long)
+                    mv_chan);
+
+       /* clear errors before enabling interrupts */
+       mv_xor_device_clear_err_status(mv_chan);
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = irq;
+               goto err_free_dma;
+       }
+       ret = devm_request_irq(&pdev->dev, irq,
+                              mv_xor_interrupt_handler,
+                              0, dev_name(&pdev->dev), mv_chan);
+       if (ret)
+               goto err_free_dma;
+
+       mv_chan_unmask_interrupts(mv_chan);
+
+       mv_set_mode(mv_chan, DMA_MEMCPY);
+
+       spin_lock_init(&mv_chan->lock);
+       INIT_LIST_HEAD(&mv_chan->chain);
+       INIT_LIST_HEAD(&mv_chan->completed_slots);
+       INIT_LIST_HEAD(&mv_chan->all_slots);
+       INIT_RCU_HEAD(&mv_chan->common.rcu);
+       mv_chan->common.device = dma_dev;
+
+       list_add_tail(&mv_chan->common.device_node, &dma_dev->channels);
+
+       if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
+               ret = mv_xor_memcpy_self_test(adev);
+               dev_dbg(&pdev->dev, "memcpy self test returned %d\n", ret);
+               if (ret)
+                       goto err_free_dma;
+       }
+
+       if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
+               ret = mv_xor_xor_self_test(adev);
+               dev_dbg(&pdev->dev, "xor self test returned %d\n", ret);
+               if (ret)
+                       goto err_free_dma;
+       }
+
+       dev_printk(KERN_INFO, &pdev->dev, "Marvell XOR: "
+         "( %s%s%s%s)\n",
+         dma_has_cap(DMA_XOR, dma_dev->cap_mask) ? "xor " : "",
+         dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)  ? "fill " : "",
+         dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask) ? "cpy " : "",
+         dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : "");
+
+       dma_async_device_register(dma_dev);
+       goto out;
+
+ err_free_dma:
+       dma_free_coherent(&adev->pdev->dev, plat_data->pool_size,
+                       adev->dma_desc_pool_virt, adev->dma_desc_pool);
+ out:
+       return ret;
+}
+
+static void
+mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp,
+                        struct mbus_dram_target_info *dram)
+{
+       void __iomem *base = msp->xor_base;
+       u32 win_enable = 0;
+       int i;
+
+       for (i = 0; i < 8; i++) {
+               writel(0, base + WINDOW_BASE(i));
+               writel(0, base + WINDOW_SIZE(i));
+               if (i < 4)
+                       writel(0, base + WINDOW_REMAP_HIGH(i));
+       }
+
+       for (i = 0; i < dram->num_cs; i++) {
+               struct mbus_dram_window *cs = dram->cs + i;
+
+               writel((cs->base & 0xffff0000) |
+                      (cs->mbus_attr << 8) |
+                      dram->mbus_dram_target_id, base + WINDOW_BASE(i));
+               writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i));
+
+               win_enable |= (1 << i);
+               win_enable |= 3 << (16 + (2 * i));
+       }
+
+       writel(win_enable, base + WINDOW_BAR_ENABLE(0));
+       writel(win_enable, base + WINDOW_BAR_ENABLE(1));
+}
+
+static struct platform_driver mv_xor_driver = {
+       .probe          = mv_xor_probe,
+       .remove         = mv_xor_remove,
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = MV_XOR_NAME,
+       },
+};
+
+static int mv_xor_shared_probe(struct platform_device *pdev)
+{
+       struct mv_xor_platform_shared_data *msd = pdev->dev.platform_data;
+       struct mv_xor_shared_private *msp;
+       struct resource *res;
+
+       dev_printk(KERN_NOTICE, &pdev->dev, "Marvell shared XOR driver\n");
+
+       msp = devm_kzalloc(&pdev->dev, sizeof(*msp), GFP_KERNEL);
+       if (!msp)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENODEV;
+
+       msp->xor_base = devm_ioremap(&pdev->dev, res->start,
+                                    res->end - res->start + 1);
+       if (!msp->xor_base)
+               return -EBUSY;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (!res)
+               return -ENODEV;
+
+       msp->xor_high_base = devm_ioremap(&pdev->dev, res->start,
+                                         res->end - res->start + 1);
+       if (!msp->xor_high_base)
+               return -EBUSY;
+
+       platform_set_drvdata(pdev, msp);
+
+       /*
+        * (Re-)program MBUS remapping windows if we are asked to.
+        */
+       if (msd != NULL && msd->dram != NULL)
+               mv_xor_conf_mbus_windows(msp, msd->dram);
+
+       return 0;
+}
+
+static int mv_xor_shared_remove(struct platform_device *pdev)
+{
+       return 0;
+}
+
+static struct platform_driver mv_xor_shared_driver = {
+       .probe          = mv_xor_shared_probe,
+       .remove         = mv_xor_shared_remove,
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = MV_XOR_SHARED_NAME,
+       },
+};
+
+
+static int __init mv_xor_init(void)
+{
+       int rc;
+
+       rc = platform_driver_register(&mv_xor_shared_driver);
+       if (!rc) {
+               rc = platform_driver_register(&mv_xor_driver);
+               if (rc)
+                       platform_driver_unregister(&mv_xor_shared_driver);
+       }
+       return rc;
+}
+module_init(mv_xor_init);
+
+/* it's currently unsafe to unload this module */
+#if 0
+static void __exit mv_xor_exit(void)
+{
+       platform_driver_unregister(&mv_xor_driver);
+       platform_driver_unregister(&mv_xor_shared_driver);
+       return;
+}
+
+module_exit(mv_xor_exit);
+#endif
+
+MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>");
+MODULE_DESCRIPTION("DMA engine driver for Marvell's XOR engine");
+MODULE_LICENSE("GPL");
diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h
new file mode 100644 (file)
index 0000000..06cafe1
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2007, 2008, Marvell International Ltd.
+ *
+ * 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 MV_XOR_H
+#define MV_XOR_H
+
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/dmaengine.h>
+#include <linux/interrupt.h>
+
+#define USE_TIMER
+#define MV_XOR_SLOT_SIZE               64
+#define MV_XOR_THRESHOLD               1
+
+#define XOR_OPERATION_MODE_XOR         0
+#define XOR_OPERATION_MODE_MEMCPY      2
+#define XOR_OPERATION_MODE_MEMSET      4
+
+#define XOR_CURR_DESC(chan)    (chan->mmr_base + 0x210 + (chan->idx * 4))
+#define XOR_NEXT_DESC(chan)    (chan->mmr_base + 0x200 + (chan->idx * 4))
+#define XOR_BYTE_COUNT(chan)   (chan->mmr_base + 0x220 + (chan->idx * 4))
+#define XOR_DEST_POINTER(chan) (chan->mmr_base + 0x2B0 + (chan->idx * 4))
+#define XOR_BLOCK_SIZE(chan)   (chan->mmr_base + 0x2C0 + (chan->idx * 4))
+#define XOR_INIT_VALUE_LOW(chan)       (chan->mmr_base + 0x2E0)
+#define XOR_INIT_VALUE_HIGH(chan)      (chan->mmr_base + 0x2E4)
+
+#define XOR_CONFIG(chan)       (chan->mmr_base + 0x10 + (chan->idx * 4))
+#define XOR_ACTIVATION(chan)   (chan->mmr_base + 0x20 + (chan->idx * 4))
+#define XOR_INTR_CAUSE(chan)   (chan->mmr_base + 0x30)
+#define XOR_INTR_MASK(chan)    (chan->mmr_base + 0x40)
+#define XOR_ERROR_CAUSE(chan)  (chan->mmr_base + 0x50)
+#define XOR_ERROR_ADDR(chan)   (chan->mmr_base + 0x60)
+#define XOR_INTR_MASK_VALUE    0x3F5
+
+#define WINDOW_BASE(w)         (0x250 + ((w) << 2))
+#define WINDOW_SIZE(w)         (0x270 + ((w) << 2))
+#define WINDOW_REMAP_HIGH(w)   (0x290 + ((w) << 2))
+#define WINDOW_BAR_ENABLE(chan)        (0x240 + ((chan) << 2))
+
+struct mv_xor_shared_private {
+       void __iomem    *xor_base;
+       void __iomem    *xor_high_base;
+};
+
+
+/**
+ * struct mv_xor_device - internal representation of a XOR device
+ * @pdev: Platform device
+ * @id: HW XOR Device selector
+ * @dma_desc_pool: base of DMA descriptor region (DMA address)
+ * @dma_desc_pool_virt: base of DMA descriptor region (CPU address)
+ * @common: embedded struct dma_device
+ */
+struct mv_xor_device {
+       struct platform_device          *pdev;
+       int                             id;
+       dma_addr_t                      dma_desc_pool;
+       void                            *dma_desc_pool_virt;
+       struct dma_device               common;
+       struct mv_xor_shared_private    *shared;
+};
+
+/**
+ * struct mv_xor_chan - internal representation of a XOR channel
+ * @pending: allows batching of hardware operations
+ * @completed_cookie: identifier for the most recently completed operation
+ * @lock: serializes enqueue/dequeue operations to the descriptors pool
+ * @mmr_base: memory mapped register base
+ * @idx: the index of the xor channel
+ * @chain: device chain view of the descriptors
+ * @completed_slots: slots completed by HW but still need to be acked
+ * @device: parent device
+ * @common: common dmaengine channel object members
+ * @last_used: place holder for allocation to continue from where it left off
+ * @all_slots: complete domain of slots usable by the channel
+ * @slots_allocated: records the actual size of the descriptor slot pool
+ * @irq_tasklet: bottom half where mv_xor_slot_cleanup runs
+ */
+struct mv_xor_chan {
+       int                     pending;
+       dma_cookie_t            completed_cookie;
+       spinlock_t              lock; /* protects the descriptor slot pool */
+       void __iomem            *mmr_base;
+       unsigned int            idx;
+       enum dma_transaction_type       current_type;
+       struct list_head        chain;
+       struct list_head        completed_slots;
+       struct mv_xor_device    *device;
+       struct dma_chan         common;
+       struct mv_xor_desc_slot *last_used;
+       struct list_head        all_slots;
+       int                     slots_allocated;
+       struct tasklet_struct   irq_tasklet;
+#ifdef USE_TIMER
+       unsigned long           cleanup_time;
+       u32                     current_on_last_cleanup;
+       dma_cookie_t            is_complete_cookie;
+#endif
+};
+
+/**
+ * struct mv_xor_desc_slot - software descriptor
+ * @slot_node: node on the mv_xor_chan.all_slots list
+ * @chain_node: node on the mv_xor_chan.chain list
+ * @completed_node: node on the mv_xor_chan.completed_slots list
+ * @hw_desc: virtual address of the hardware descriptor chain
+ * @phys: hardware address of the hardware descriptor chain
+ * @group_head: first operation in a transaction
+ * @slot_cnt: total slots used in an transaction (group of operations)
+ * @slots_per_op: number of slots per operation
+ * @idx: pool index
+ * @unmap_src_cnt: number of xor sources
+ * @unmap_len: transaction bytecount
+ * @async_tx: support for the async_tx api
+ * @group_list: list of slots that make up a multi-descriptor transaction
+ *     for example transfer lengths larger than the supported hw max
+ * @xor_check_result: result of zero sum
+ * @crc32_result: result crc calculation
+ */
+struct mv_xor_desc_slot {
+       struct list_head        slot_node;
+       struct list_head        chain_node;
+       struct list_head        completed_node;
+       enum dma_transaction_type       type;
+       void                    *hw_desc;
+       struct mv_xor_desc_slot *group_head;
+       u16                     slot_cnt;
+       u16                     slots_per_op;
+       u16                     idx;
+       u16                     unmap_src_cnt;
+       u32                     value;
+       size_t                  unmap_len;
+       struct dma_async_tx_descriptor  async_tx;
+       union {
+               u32             *xor_check_result;
+               u32             *crc32_result;
+       };
+#ifdef USE_TIMER
+       unsigned long           arrival_time;
+       struct timer_list       timeout;
+#endif
+};
+
+/* This structure describes XOR descriptor size 64bytes        */
+struct mv_xor_desc {
+       u32 status;             /* descriptor execution status */
+       u32 crc32_result;       /* result of CRC-32 calculation */
+       u32 desc_command;       /* type of operation to be carried out */
+       u32 phy_next_desc;      /* next descriptor address pointer */
+       u32 byte_count;         /* size of src/dst blocks in bytes */
+       u32 phy_dest_addr;      /* destination block address */
+       u32 phy_src_addr[8];    /* source block addresses */
+       u32 reserved0;
+       u32 reserved1;
+};
+
+#define to_mv_sw_desc(addr_hw_desc)            \
+       container_of(addr_hw_desc, struct mv_xor_desc_slot, hw_desc)
+
+#define mv_hw_desc_slot_idx(hw_desc, idx)      \
+       ((void *)(((unsigned long)hw_desc) + ((idx) << 5)))
+
+#define MV_XOR_MIN_BYTE_COUNT  (128)
+#define XOR_MAX_BYTE_COUNT     ((16 * 1024 * 1024) - 1)
+#define MV_XOR_MAX_BYTE_COUNT  XOR_MAX_BYTE_COUNT
+
+
+#endif
index b54112ffd28282dd04eed8ffd243c7685c7d10df..0e024fe2d8c486ce8ab0bddca34b91e8b9f53165 100644 (file)
@@ -33,7 +33,7 @@ static void cell_edac_count_ce(struct mem_ctl_info *mci, int chan, u64 ar)
 {
        struct cell_edac_priv           *priv = mci->pvt_info;
        struct csrow_info               *csrow = &mci->csrows[0];
-       unsigned long                   address, pfn, offset;
+       unsigned long                   address, pfn, offset, syndrome;
 
        dev_dbg(mci->dev, "ECC CE err on node %d, channel %d, ar = 0x%016lx\n",
                priv->node, chan, ar);
@@ -44,10 +44,11 @@ static void cell_edac_count_ce(struct mem_ctl_info *mci, int chan, u64 ar)
                address = (address << 1) | chan;
        pfn = address >> PAGE_SHIFT;
        offset = address & ~PAGE_MASK;
+       syndrome = (ar & 0x000000001fe00000ul) >> 21;
 
        /* TODO: Decoding of the error addresss */
        edac_mc_handle_ce(mci, csrow->first_page + pfn, offset,
-                         0, 0, chan, "");
+                         syndrome, 0, chan, "");
 }
 
 static void cell_edac_count_ue(struct mem_ctl_info *mci, int chan, u64 ar)
index 70abf93fe6b0e823239409613aa28ca1e2045d71..5369ce957c6d5397146cbbcb71c75aed01ebaa57 100644 (file)
@@ -9,7 +9,7 @@ obj-${CONFIG_EISA_VIRTUAL_ROOT} += virtual_root.o
 
 
 # Ugly hack to get DEVICE_NAME_SIZE value...
-DEVICE_NAME_SIZE =$(shell awk '$$1=="\#define" && $$2=="DEVICE_NAME_SIZE" {print $$3-1}' $(srctree)/include/linux/device.h)
+DEVICE_NAME_SIZE = 50
 
 $(obj)/eisa-bus.o: $(obj)/devlist.h
 
index 65dcf0432653b51b1593f94a4ae237584fe3a907..c950bf8606d967b07639ed14e0bfd643136df57d 100644 (file)
@@ -22,7 +22,7 @@
 
 struct eisa_device_info {
        struct eisa_device_id id;
-       char name[DEVICE_NAME_SIZE];
+       char name[50];
 };
 
 #ifdef CONFIG_EISA_NAMES
@@ -63,7 +63,7 @@ static void __init eisa_name_device (struct eisa_device *edev)
                if (!strcmp (edev->id.sig, eisa_table[i].id.sig)) {
                        strlcpy (edev->pretty_name,
                                 eisa_table[i].name,
-                                DEVICE_NAME_SIZE);
+                                sizeof(edev->pretty_name));
                        return;
                }
        }
index 008c38ba774f588f3a739983bb6f47e48ef618f5..fced1909cbba0dd055c2a01cd73fc5303138750b 100644 (file)
@@ -45,7 +45,7 @@ config GPIO_PCA953X
          will be called pca953x.
 
 config GPIO_PCF857X
-       tristate "PCF857x, PCA857x, and PCA967x I2C GPIO expanders"
+       tristate "PCF857x, PCA{85,96}7x, and MAX732[89] I2C GPIO expanders"
        depends on I2C
        help
          Say yes here to provide access to most "quasi-bidirectional" I2C
@@ -54,7 +54,8 @@ config GPIO_PCF857X
          some of them.  Compatible models include:
 
          8 bits:   pcf8574, pcf8574a, pca8574, pca8574a,
-                   pca9670, pca9672, pca9674, pca9674a
+                   pca9670, pca9672, pca9674, pca9674a,
+                   max7328, max7329
 
          16 bits:  pcf8575, pcf8575c, pca8575,
                    pca9671, pca9673, pca9675
@@ -69,6 +70,12 @@ config GPIO_PCF857X
 
 comment "SPI GPIO expanders:"
 
+config GPIO_MAX7301
+       tristate "Maxim MAX7301 GPIO expander"
+       depends on SPI_MASTER
+       help
+         gpio driver for Maxim MAX7301 SPI GPIO expander.
+
 config GPIO_MCP23S08
        tristate "Microchip MCP23S08 I/O expander"
        depends on SPI_MASTER
index fdde9923cf332e67fbab712cf110ddabdc7beebe..16e796dc5410fe8659466d54b250b357eee1a6ac 100644 (file)
@@ -4,6 +4,7 @@ ccflags-$(CONFIG_DEBUG_GPIO)    += -DDEBUG
 
 obj-$(CONFIG_HAVE_GPIO_LIB)    += gpiolib.o
 
+obj-$(CONFIG_GPIO_MAX7301)     += max7301.o
 obj-$(CONFIG_GPIO_MCP23S08)    += mcp23s08.o
 obj-$(CONFIG_GPIO_PCA953X)     += pca953x.o
 obj-$(CONFIG_GPIO_PCF857X)     += pcf857x.o
diff --git a/drivers/gpio/max7301.c b/drivers/gpio/max7301.c
new file mode 100644 (file)
index 0000000..39c795a
--- /dev/null
@@ -0,0 +1,339 @@
+/**
+ * drivers/gpio/max7301.c
+ *
+ * Copyright (C) 2006 Juergen Beisert, Pengutronix
+ * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
+ *
+ * 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 Maxim's MAX7301 device is an SPI driven GPIO expander. There are
+ * 28 GPIOs. 8 of them can trigger an interrupt. See datasheet for more
+ * details
+ * Note:
+ * - DIN must be stable at the rising edge of clock.
+ * - when writing:
+ *   - always clock in 16 clocks at once
+ *   - at DIN: D15 first, D0 last
+ *   - D0..D7 = databyte, D8..D14 = commandbyte
+ *   - D15 = low -> write command
+ * - when reading
+ *   - always clock in 16 clocks at once
+ *   - at DIN: D15 first, D0 last
+ *   - D0..D7 = dummy, D8..D14 = register address
+ *   - D15 = high -> read command
+ *   - raise CS and assert it again
+ *   - always clock in 16 clocks at once
+ *   - at DOUT: D15 first, D0 last
+ *   - D0..D7 contains the data from the first cycle
+ *
+ * The driver exports a standard gpiochip interface
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/max7301.h>
+#include <linux/gpio.h>
+
+#define DRIVER_NAME "max7301"
+
+/*
+ * Pin configurations, see MAX7301 datasheet page 6
+ */
+#define PIN_CONFIG_MASK 0x03
+#define PIN_CONFIG_IN_PULLUP 0x03
+#define PIN_CONFIG_IN_WO_PULLUP 0x02
+#define PIN_CONFIG_OUT 0x01
+
+#define PIN_NUMBER 28
+
+
+/*
+ * Some registers must be read back to modify.
+ * To save time we cache them here in memory
+ */
+struct max7301 {
+       struct mutex    lock;
+       u8              port_config[8]; /* field 0 is unused */
+       u32             out_level;      /* cached output levels */
+       struct gpio_chip chip;
+       struct spi_device *spi;
+};
+
+/**
+ * max7301_write - Write a new register content
+ * @spi: The SPI device
+ * @reg: Register offset
+ * @val: Value to write
+ *
+ * A write to the MAX7301 means one message with one transfer
+ *
+ * Returns 0 if successful or a negative value on error
+ */
+static int max7301_write(struct spi_device *spi, unsigned int reg, unsigned int val)
+{
+       u16 word = ((reg & 0x7F) << 8) | (val & 0xFF);
+       return spi_write(spi, (const u8 *)&word, sizeof(word));
+}
+
+/**
+ * max7301_read - Read back register content
+ * @spi: The SPI device
+ * @reg: Register offset
+ *
+ * A read from the MAX7301 means two transfers; here, one message each
+ *
+ * Returns positive 8 bit value from device if successful or a
+ * negative value on error
+ */
+static int max7301_read(struct spi_device *spi, unsigned int reg)
+{
+       int ret;
+       u16 word;
+
+       word = 0x8000 | (reg << 8);
+       ret = spi_write(spi, (const u8 *)&word, sizeof(word));
+       if (ret)
+               return ret;
+       /*
+        * This relies on the fact, that a transfer with NULL tx_buf shifts out
+        * zero bytes (=NOOP for MAX7301)
+        */
+       ret = spi_read(spi, (u8 *)&word, sizeof(word));
+       if (ret)
+               return ret;
+       return word & 0xff;
+}
+
+static int max7301_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+       struct max7301 *ts = container_of(chip, struct max7301, chip);
+       u8 *config;
+       int ret;
+
+       /* First 4 pins are unused in the controller */
+       offset += 4;
+
+       config = &ts->port_config[offset >> 2];
+
+       mutex_lock(&ts->lock);
+
+       /* Standard GPIO API doesn't support pull-ups, has to be extended.
+        * Hard-coding no pollup for now. */
+       *config = (*config & ~(3 << (offset & 3))) | (1 << (offset & 3));
+
+       ret = max7301_write(ts->spi, 0x08 + (offset >> 2), *config);
+
+       mutex_unlock(&ts->lock);
+
+       return ret;
+}
+
+static int __max7301_set(struct max7301 *ts, unsigned offset, int value)
+{
+       if (value) {
+               ts->out_level |= 1 << offset;
+               return max7301_write(ts->spi, 0x20 + offset, 0x01);
+       } else {
+               ts->out_level &= ~(1 << offset);
+               return max7301_write(ts->spi, 0x20 + offset, 0x00);
+       }
+}
+
+static int max7301_direction_output(struct gpio_chip *chip, unsigned offset,
+                                   int value)
+{
+       struct max7301 *ts = container_of(chip, struct max7301, chip);
+       u8 *config;
+       int ret;
+
+       /* First 4 pins are unused in the controller */
+       offset += 4;
+
+       config = &ts->port_config[offset >> 2];
+
+       mutex_lock(&ts->lock);
+
+       *config = (*config & ~(3 << (offset & 3))) | (1 << (offset & 3));
+
+       ret = __max7301_set(ts, offset, value);
+
+       if (!ret)
+               ret = max7301_write(ts->spi, 0x08 + (offset >> 2), *config);
+
+       mutex_unlock(&ts->lock);
+
+       return ret;
+}
+
+static int max7301_get(struct gpio_chip *chip, unsigned offset)
+{
+       struct max7301 *ts = container_of(chip, struct max7301, chip);
+       int config, level = -EINVAL;
+
+       /* First 4 pins are unused in the controller */
+       offset += 4;
+
+       mutex_lock(&ts->lock);
+
+       config = (ts->port_config[offset >> 2] >> ((offset & 3) * 2)) & 3;
+
+       switch (config) {
+       case 1:
+               /* Output: return cached level */
+               level =  !!(ts->out_level & (1 << offset));
+               break;
+       case 2:
+       case 3:
+               /* Input: read out */
+               level = max7301_read(ts->spi, 0x20 + offset) & 0x01;
+       }
+       mutex_unlock(&ts->lock);
+
+       return level;
+}
+
+static void max7301_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+       struct max7301 *ts = container_of(chip, struct max7301, chip);
+
+       /* First 4 pins are unused in the controller */
+       offset += 4;
+
+       mutex_lock(&ts->lock);
+
+       __max7301_set(ts, offset, value);
+
+       mutex_unlock(&ts->lock);
+}
+
+static int __devinit max7301_probe(struct spi_device *spi)
+{
+       struct max7301 *ts;
+       struct max7301_platform_data *pdata;
+       int i, ret;
+
+       pdata = spi->dev.platform_data;
+       if (!pdata || !pdata->base)
+               return -ENODEV;
+
+       /*
+        * bits_per_word cannot be configured in platform data
+        */
+       spi->bits_per_word = 16;
+
+       ret = spi_setup(spi);
+       if (ret < 0)
+               return ret;
+
+       ts = kzalloc(sizeof(struct max7301), GFP_KERNEL);
+       if (!ts)
+               return -ENOMEM;
+
+       mutex_init(&ts->lock);
+
+       dev_set_drvdata(&spi->dev, ts);
+
+       /* Power up the chip and disable IRQ output */
+       max7301_write(spi, 0x04, 0x01);
+
+       ts->spi = spi;
+
+       ts->chip.label = DRIVER_NAME,
+
+       ts->chip.direction_input = max7301_direction_input;
+       ts->chip.get = max7301_get;
+       ts->chip.direction_output = max7301_direction_output;
+       ts->chip.set = max7301_set;
+
+       ts->chip.base = pdata->base;
+       ts->chip.ngpio = PIN_NUMBER;
+       ts->chip.can_sleep = 1;
+       ts->chip.dev = &spi->dev;
+       ts->chip.owner = THIS_MODULE;
+
+       ret = gpiochip_add(&ts->chip);
+       if (ret)
+               goto exit_destroy;
+
+       /*
+        * tristate all pins in hardware and cache the
+        * register values for later use.
+        */
+       for (i = 1; i < 8; i++) {
+               int j;
+               /* 0xAA means input with internal pullup disabled */
+               max7301_write(spi, 0x08 + i, 0xAA);
+               ts->port_config[i] = 0xAA;
+               for (j = 0; j < 4; j++) {
+                       int idx = ts->chip.base + (i - 1) * 4 + j;
+                       ret = gpio_direction_input(idx);
+                       if (ret)
+                               goto exit_remove;
+                       gpio_free(idx);
+               }
+       }
+       return ret;
+
+exit_remove:
+       gpiochip_remove(&ts->chip);
+exit_destroy:
+       dev_set_drvdata(&spi->dev, NULL);
+       mutex_destroy(&ts->lock);
+       kfree(ts);
+       return ret;
+}
+
+static int max7301_remove(struct spi_device *spi)
+{
+       struct max7301 *ts;
+       int ret;
+
+       ts = dev_get_drvdata(&spi->dev);
+       if (ts == NULL)
+               return -ENODEV;
+
+       dev_set_drvdata(&spi->dev, NULL);
+
+       /* Power down the chip and disable IRQ output */
+       max7301_write(spi, 0x04, 0x00);
+
+       ret = gpiochip_remove(&ts->chip);
+       if (!ret) {
+               mutex_destroy(&ts->lock);
+               kfree(ts);
+       } else
+               dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n",
+                       ret);
+
+       return ret;
+}
+
+static struct spi_driver max7301_driver = {
+       .driver = {
+               .name           = DRIVER_NAME,
+               .owner          = THIS_MODULE,
+       },
+       .probe          = max7301_probe,
+       .remove         = __devexit_p(max7301_remove),
+};
+
+static int __init max7301_init(void)
+{
+       return spi_register_driver(&max7301_driver);
+}
+
+static void __exit max7301_exit(void)
+{
+       spi_unregister_driver(&max7301_driver);
+}
+
+module_init(max7301_init);
+module_exit(max7301_exit);
+
+MODULE_AUTHOR("Juergen Beisert");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MAX7301 SPI based GPIO-Expander");
index aa6cc8b2a2bc88afbeca4dec1b67bc75c05288a0..d25d356c4f200c9a197a5ac84373f7441e415e3a 100644 (file)
@@ -37,6 +37,8 @@ static const struct i2c_device_id pcf857x_id[] = {
        { "pca9671", 16 },
        { "pca9673", 16 },
        { "pca9675", 16 },
+       { "max7328", 8 },
+       { "max7329", 8 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, pcf857x_id);
@@ -56,6 +58,7 @@ MODULE_DEVICE_TABLE(i2c, pcf857x_id);
 struct pcf857x {
        struct gpio_chip        chip;
        struct i2c_client       *client;
+       struct mutex            lock;           /* protect 'out' */
        unsigned                out;            /* software latch */
 };
 
@@ -66,9 +69,14 @@ struct pcf857x {
 static int pcf857x_input8(struct gpio_chip *chip, unsigned offset)
 {
        struct pcf857x  *gpio = container_of(chip, struct pcf857x, chip);
+       int             status;
 
+       mutex_lock(&gpio->lock);
        gpio->out |= (1 << offset);
-       return i2c_smbus_write_byte(gpio->client, gpio->out);
+       status = i2c_smbus_write_byte(gpio->client, gpio->out);
+       mutex_unlock(&gpio->lock);
+
+       return status;
 }
 
 static int pcf857x_get8(struct gpio_chip *chip, unsigned offset)
@@ -84,12 +92,17 @@ static int pcf857x_output8(struct gpio_chip *chip, unsigned offset, int value)
 {
        struct pcf857x  *gpio = container_of(chip, struct pcf857x, chip);
        unsigned        bit = 1 << offset;
+       int             status;
 
+       mutex_lock(&gpio->lock);
        if (value)
                gpio->out |= bit;
        else
                gpio->out &= ~bit;
-       return i2c_smbus_write_byte(gpio->client, gpio->out);
+       status = i2c_smbus_write_byte(gpio->client, gpio->out);
+       mutex_unlock(&gpio->lock);
+
+       return status;
 }
 
 static void pcf857x_set8(struct gpio_chip *chip, unsigned offset, int value)
@@ -124,9 +137,14 @@ static int i2c_read_le16(struct i2c_client *client)
 static int pcf857x_input16(struct gpio_chip *chip, unsigned offset)
 {
        struct pcf857x  *gpio = container_of(chip, struct pcf857x, chip);
+       int             status;
 
+       mutex_lock(&gpio->lock);
        gpio->out |= (1 << offset);
-       return i2c_write_le16(gpio->client, gpio->out);
+       status = i2c_write_le16(gpio->client, gpio->out);
+       mutex_unlock(&gpio->lock);
+
+       return status;
 }
 
 static int pcf857x_get16(struct gpio_chip *chip, unsigned offset)
@@ -142,12 +160,17 @@ static int pcf857x_output16(struct gpio_chip *chip, unsigned offset, int value)
 {
        struct pcf857x  *gpio = container_of(chip, struct pcf857x, chip);
        unsigned        bit = 1 << offset;
+       int             status;
 
+       mutex_lock(&gpio->lock);
        if (value)
                gpio->out |= bit;
        else
                gpio->out &= ~bit;
-       return i2c_write_le16(gpio->client, gpio->out);
+       status = i2c_write_le16(gpio->client, gpio->out);
+       mutex_unlock(&gpio->lock);
+
+       return status;
 }
 
 static void pcf857x_set16(struct gpio_chip *chip, unsigned offset, int value)
@@ -173,6 +196,8 @@ static int pcf857x_probe(struct i2c_client *client,
        if (!gpio)
                return -ENOMEM;
 
+       mutex_init(&gpio->lock);
+
        gpio->chip.base = pdata->gpio_base;
        gpio->chip.can_sleep = 1;
        gpio->chip.owner = THIS_MODULE;
index f43d6d3cf2fa2429d5689bbe05e87cf0f99358e0..426ac5add585c03df6dbdae3c8b2baca175ef043 100644 (file)
@@ -780,7 +780,7 @@ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
  */
 static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
 {
-       __le64 x;
+       u64 x;
        u64 m = (1ULL << n) - 1;
 
        if (n > 32)
@@ -796,10 +796,10 @@ static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u3
        report += offset >> 3;
        offset &= 7;
 
-       x = get_unaligned((__le64 *)report);
-       x &= cpu_to_le64(~(m << offset));
-       x |= cpu_to_le64(((u64) value) << offset);
-       put_unaligned(x, (__le64 *) report);
+       x = get_unaligned_le64(report);
+       x &= ~(m << offset);
+       x |= ((u64)value) << offset;
+       put_unaligned_le64(x, report);
 }
 
 /*
index 4c2052c658f1465f6a8d89494b03a8783a7ba6e3..16feea014494284e9d165af05f8b47f993557f38 100644 (file)
@@ -89,6 +89,29 @@ static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct input_de
        return 1;
 }
 
+static int quirk_gyration_remote(struct hid_usage *usage, struct input_dev *input,
+                             unsigned long **bit, int *max)
+{
+       if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
+               return 0;
+
+       set_bit(EV_REP, input->evbit);
+       switch(usage->hid & HID_USAGE) {
+               /* Reported on Gyration MCE Remote */
+               case 0x00d: map_key_clear(KEY_HOME);            break;
+               case 0x024: map_key_clear(KEY_DVD);             break;
+               case 0x025: map_key_clear(KEY_PVR);             break;
+               case 0x046: map_key_clear(KEY_MEDIA);           break;
+               case 0x047: map_key_clear(KEY_MP3);             break;
+               case 0x049: map_key_clear(KEY_CAMERA);          break;
+               case 0x04a: map_key_clear(KEY_VIDEO);           break;
+
+               default:
+                       return 0;
+       }
+       return 1;
+}
+
 static int quirk_chicony_tactical_pad(struct hid_usage *usage, struct input_dev *input,
                              unsigned long **bit, int *max)
 {
@@ -303,6 +326,9 @@ static int quirk_sunplus_wdesktop(struct hid_usage *usage, struct input_dev *inp
 #define VENDOR_ID_EZKEY                                0x0518
 #define DEVICE_ID_BTC_8193                     0x0002
 
+#define VENDOR_ID_GYRATION                     0x0c16
+#define DEVICE_ID_GYRATION_REMOTE              0x0002
+
 #define VENDOR_ID_LOGITECH                     0x046d
 #define DEVICE_ID_LOGITECH_RECEIVER            0xc101
 #define DEVICE_ID_S510_RECEIVER                        0xc50c
@@ -337,6 +363,8 @@ static const struct hid_input_blacklist {
 
        { VENDOR_ID_EZKEY, DEVICE_ID_BTC_8193, quirk_btc_8193 },
 
+       { VENDOR_ID_GYRATION, DEVICE_ID_GYRATION_REMOTE, quirk_gyration_remote },
+
        { VENDOR_ID_LOGITECH, DEVICE_ID_LOGITECH_RECEIVER, quirk_logitech_ultrax_remote },
        { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER, quirk_logitech_wireless },
        { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER_2, quirk_logitech_wireless },
@@ -438,6 +466,18 @@ int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struc
                input_event(input, usage->type, REL_WHEEL, -value);
                return 1;
        }
+
+       /* Gyration MCE remote "Sleep" key */
+       if (hid->vendor == VENDOR_ID_GYRATION &&
+           hid->product == DEVICE_ID_GYRATION_REMOTE &&
+           (usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK &&
+           (usage->hid & 0xff) == 0x82) {
+               input_event(input, usage->type, usage->code, 1);
+               input_sync(input);
+               input_event(input, usage->type, usage->code, 0);
+               input_sync(input);
+               return 1;
+       }
        return 0;
 }
 
index 5c52a20ad3447abd4cd4b94d7bc37f14746ab230..1b2e8dc3398d7bf972243507d695f14e2093aaa0 100644 (file)
@@ -100,6 +100,8 @@ static struct hidinput_key_translation apple_fn_keys[] = {
        { KEY_F2,       KEY_BRIGHTNESSUP,   APPLE_FLAG_FKEY },
        { KEY_F3,       KEY_FN_F5,          APPLE_FLAG_FKEY }, /* Exposé */
        { KEY_F4,       KEY_FN_F4,          APPLE_FLAG_FKEY }, /* Dashboard */
+       { KEY_F5,       KEY_KBDILLUMDOWN,   APPLE_FLAG_FKEY },
+       { KEY_F6,       KEY_KBDILLUMUP,     APPLE_FLAG_FKEY },
        { KEY_F7,       KEY_PREVIOUSSONG,   APPLE_FLAG_FKEY },
        { KEY_F8,       KEY_PLAYPAUSE,      APPLE_FLAG_FKEY },
        { KEY_F9,       KEY_NEXTSONG,       APPLE_FLAG_FKEY },
@@ -612,6 +614,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                                case 0x0b6: map_key_clear(KEY_PREVIOUSSONG);    break;
                                case 0x0b7: map_key_clear(KEY_STOPCD);          break;
                                case 0x0b8: map_key_clear(KEY_EJECTCD);         break;
+                               case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT);    break;
 
                                case 0x0cd: map_key_clear(KEY_PLAYPAUSE);       break;
                                case 0x0e0: map_abs_clear(ABS_VOLUME);          break;
index 2fde6c63f47dffa2d89c224cd15c1be215d4d20e..c40f0403edafe1390d5fecb66604e095c8f70057 100644 (file)
@@ -105,6 +105,7 @@ out:
 static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
        unsigned int minor = iminor(file->f_path.dentry->d_inode);
+       /* FIXME: What stops hidraw_table going NULL */
        struct hid_device *dev = hidraw_table[minor]->hid;
        __u8 *buf;
        int ret = 0;
@@ -211,38 +212,43 @@ static int hidraw_release(struct inode * inode, struct file * file)
                        kfree(list->hidraw);
        }
 
+       kfree(list);
+
        return 0;
 }
 
-static int hidraw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long hidraw_ioctl(struct file *file, unsigned int cmd,
+                                                       unsigned long arg)
 {
+       struct inode *inode = file->f_path.dentry->d_inode;
        unsigned int minor = iminor(inode);
+       long ret = 0;
+       /* FIXME: What stops hidraw_table going NULL */
        struct hidraw *dev = hidraw_table[minor];
        void __user *user_arg = (void __user*) arg;
 
+       lock_kernel();
        switch (cmd) {
                case HIDIOCGRDESCSIZE:
                        if (put_user(dev->hid->rsize, (int __user *)arg))
-                               return -EFAULT;
-                       return 0;
+                               ret = -EFAULT;
+                       break;
 
                case HIDIOCGRDESC:
                        {
                                __u32 len;
 
                                if (get_user(len, (int __user *)arg))
-                                       return -EFAULT;
-
-                               if (len > HID_MAX_DESCRIPTOR_SIZE - 1)
-                                       return -EINVAL;
-
-                               if (copy_to_user(user_arg + offsetof(
-                                                               struct hidraw_report_descriptor,
-                                                               value[0]),
-                                                       dev->hid->rdesc,
-                                                       min(dev->hid->rsize, len)))
-                                               return -EFAULT;
-                               return 0;
+                                       ret = -EFAULT;
+                               else if (len > HID_MAX_DESCRIPTOR_SIZE - 1)
+                                       ret = -EINVAL;
+                               else if (copy_to_user(user_arg + offsetof(
+                                       struct hidraw_report_descriptor,
+                                       value[0]),
+                                       dev->hid->rdesc,
+                                       min(dev->hid->rsize, len)))
+                                       ret = -EFAULT;
+                               break;
                        }
                case HIDIOCGRAWINFO:
                        {
@@ -252,15 +258,13 @@ static int hidraw_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                                dinfo.vendor = dev->hid->vendor;
                                dinfo.product = dev->hid->product;
                                if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
-                                       return -EFAULT;
-
-                               return 0;
+                                       ret = -EFAULT;
+                               break;
                        }
                default:
-                       printk(KERN_EMERG "hidraw: unsupported ioctl() %x\n",
-                                       cmd);
+                       ret = -ENOTTY;
        }
-       return -EINVAL;
+       return ret;
 }
 
 static const struct file_operations hidraw_ops = {
@@ -270,7 +274,7 @@ static const struct file_operations hidraw_ops = {
        .poll =         hidraw_poll,
        .open =         hidraw_open,
        .release =      hidraw_release,
-       .ioctl =        hidraw_ioctl,
+       .unlocked_ioctl = hidraw_ioctl,
 };
 
 void hidraw_report_event(struct hid_device *hid, u8 *data, int len)
@@ -322,8 +326,9 @@ int hidraw_connect(struct hid_device *hid)
                goto out;
        }
 
-       dev->dev = device_create(hidraw_class, NULL, MKDEV(hidraw_major, minor),
-                               "%s%d", "hidraw", minor);
+       dev->dev = device_create_drvdata(hidraw_class, NULL,
+                                        MKDEV(hidraw_major, minor), NULL,
+                                        "%s%d", "hidraw", minor);
 
        if (IS_ERR(dev->dev)) {
                spin_lock(&minors_lock);
index 01427c51c7cc71b602d4df4535ab8b745e65a791..27fe4d8912cb9a6a1e1b847b0899103199fdbbe9 100644 (file)
@@ -122,7 +122,7 @@ static void hid_reset(struct work_struct *work)
                dev_dbg(&usbhid->intf->dev, "resetting device\n");
                rc = rc_lock = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf);
                if (rc_lock >= 0) {
-                       rc = usb_reset_composite_device(hid_to_usb_dev(hid), usbhid->intf);
+                       rc = usb_reset_device(hid_to_usb_dev(hid));
                        if (rc_lock)
                                usb_unlock_device(hid_to_usb_dev(hid));
                }
index 1df832a8fcbc6251f180d25ce809f11c803bcec9..61e78a4369b9e811952bf0e36c450b46129b0923 100644 (file)
 #define USB_DEVICE_ID_APPLE_ALU_ANSI   0x0220
 #define USB_DEVICE_ID_APPLE_ALU_ISO    0x0221
 #define USB_DEVICE_ID_APPLE_ALU_JIS    0x0222
+#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI    0x0223
+#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO     0x0224
+#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS     0x0225
 #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI    0x0229
 #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO     0x022a
 #define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS     0x022b
 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI  0x022c
 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO   0x022d
 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS   0x022e
+#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI   0x0230
+#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO    0x0231
+#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS    0x0232
 #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY   0x030a
 #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY    0x030b
 #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242
 #define USB_DEVICE_ID_LD_MACHINETEST   0x2040
 
 #define USB_VENDOR_ID_LOGITECH         0x046d
+#define USB_DEVICE_ID_LOGITECH_LX3     0xc044
+#define USB_DEVICE_ID_LOGITECH_V150    0xc047
 #define USB_DEVICE_ID_LOGITECH_RECEIVER        0xc101
 #define USB_DEVICE_ID_LOGITECH_HARMONY  0xc110
 #define USB_DEVICE_ID_LOGITECH_HARMONY_2 0xc111
 #define USB_DEVICE_ID_S510_RECEIVER_2  0xc517
 #define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500  0xc512
 #define USB_DEVICE_ID_MX3000_RECEIVER  0xc513
+#define USB_DEVICE_ID_DINOVO_DESKTOP   0xc704
 #define USB_DEVICE_ID_DINOVO_EDGE      0xc714
 #define USB_DEVICE_ID_DINOVO_MINI      0xc71f
 
@@ -443,7 +452,8 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD },
        { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
        { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
-       
+
+       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP, HID_QUIRK_DUPLICATE_USAGES },
        { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES },
        { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI, HID_QUIRK_DUPLICATE_USAGES },
 
@@ -593,6 +603,8 @@ static const struct hid_blacklist {
 
        { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
        { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
+       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_LX3, HID_QUIRK_INVERT_HWHEEL },
+       { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150, HID_QUIRK_INVERT_HWHEEL },
 
        { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS },
        { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS },
@@ -642,6 +654,12 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN },
        { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
        { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, HID_QUIRK_APPLE_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS, HID_QUIRK_APPLE_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, HID_QUIRK_APPLE_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, HID_QUIRK_APPLE_HAS_FN },
        { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
        { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
 
@@ -1128,7 +1146,7 @@ static void usbhid_fixup_microsoft_descriptor(unsigned char *rdesc, int rsize)
                         && rdesc[557] == 0x19
                         && rdesc[559] == 0x29) {
                printk(KERN_INFO "Fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n");
-               rdesc[284] = rdesc[304] = rdesc[558] = 0x35;
+               rdesc[284] = rdesc[304] = rdesc[557] = 0x35;
                rdesc[352] = 0x36;
                rdesc[286] = rdesc[355] = 0x46;
                rdesc[306] = rdesc[559] = 0x45;
index 95cc192bc7af7573087d2ce67e634371d40caf6e..842e9edb888ed889c27c19fd2ca705c3da38010f 100644 (file)
@@ -406,6 +406,7 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
        uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
        if (!uref_multi)
                return -ENOMEM;
+       lock_kernel();
        uref = &uref_multi->uref;
        if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
                if (copy_from_user(uref_multi, user_arg,
@@ -501,12 +502,15 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
                }
 
 goodreturn:
+               unlock_kernel();
                kfree(uref_multi);
                return 0;
 fault:
+               unlock_kernel();
                kfree(uref_multi);
                return -EFAULT;
 inval:
+               unlock_kernel();
                kfree(uref_multi);
                return -EINVAL;
        }
@@ -540,7 +544,7 @@ static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd,
        return len;
 }
 
-static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct hiddev_list *list = file->private_data;
        struct hiddev *hiddev = list->hiddev;
@@ -555,7 +559,10 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
        struct usbhid_device *usbhid = hid->driver_data;
        void __user *user_arg = (void __user *)arg;
        int i;
+       
+       /* Called without BKL by compat methods so no BKL taken */
 
+       /* FIXME: Who or what stop this racing with a disconnect ?? */
        if (!hiddev->exist)
                return -EIO;
 
@@ -756,8 +763,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 #ifdef CONFIG_COMPAT
 static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-       struct inode *inode = file->f_path.dentry->d_inode;
-       return hiddev_ioctl(inode, file, cmd, (unsigned long)compat_ptr(arg));
+       return hiddev_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
 }
 #endif
 
@@ -768,7 +774,7 @@ static const struct file_operations hiddev_fops = {
        .poll =         hiddev_poll,
        .open =         hiddev_open,
        .release =      hiddev_release,
-       .ioctl =        hiddev_ioctl,
+       .unlocked_ioctl =       hiddev_ioctl,
        .fasync =       hiddev_fasync,
 #ifdef CONFIG_COMPAT
        .compat_ioctl   = hiddev_compat_ioctl,
index 3cd46d2e53c1851828b31df4fc85da846381b3b5..0caaafe018438db68b33acc4ac0d695c717d4058 100644 (file)
@@ -43,7 +43,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE(DRIVER_LICENSE);
 
-static unsigned char usb_kbd_keycode[256] = {
+static const unsigned char usb_kbd_keycode[256] = {
          0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
         50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,
          4,  5,  6,  7,  8,  9, 10, 11, 28,  1, 14, 15, 57, 12, 13, 26,
@@ -233,14 +233,6 @@ static int usb_kbd_probe(struct usb_interface *iface,
        if (!usb_endpoint_is_int_in(endpoint))
                return -ENODEV;
 
-#ifdef CONFIG_USB_HID
-       if (usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
-                               le16_to_cpu(dev->descriptor.idProduct))
-                       & HID_QUIRK_IGNORE) {
-               return -ENODEV;
-       }
-#endif
-
        pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
        maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
index 703e9d0e871460df091ce77d8cd35697a09424e3..35689ef172cc5240fdb4a7882ccaf13fbe3913df 100644 (file)
@@ -129,14 +129,6 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
        if (!usb_endpoint_is_int_in(endpoint))
                return -ENODEV;
 
-#ifdef CONFIG_USB_HID
-       if (usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
-                               le16_to_cpu(dev->descriptor.idProduct))
-                       & (HID_QUIRK_IGNORE|HID_QUIRK_IGNORE_MOUSE)) {
-               return -ENODEV;
-       }
-#endif
-
        pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
        maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
index 50f22690d6114a51518f40003083a578693c11f9..a4d92d246d52620e1efb09288df69fdcbf352303 100644 (file)
@@ -581,6 +581,8 @@ static int __init hdaps_init(void)
        /* initialize the input class */
        idev = hdaps_idev->input;
        idev->name = "hdaps";
+       idev->phys = "isa1600/input0";
+       idev->id.bustype = BUS_ISA;
        idev->dev.parent = &pdev->dev;
        idev->evbit[0] = BIT_MASK(EV_ABS);
        input_set_abs_params(idev, ABS_X,
index 3db28450a3b34504facc27cc8a9611a8e53569cd..7321a88a51128adef8ba40016e03f0648b7e4a97 100644 (file)
@@ -55,7 +55,8 @@ again:
                return ERR_PTR(err);
 
        id = id & MAX_ID_MASK;
-       hwdev = device_create(hwmon_class, dev, MKDEV(0,0), HWMON_ID_FORMAT, id);
+       hwdev = device_create_drvdata(hwmon_class, dev, MKDEV(0, 0), NULL,
+                                     HWMON_ID_FORMAT, id);
 
        if (IS_ERR(hwdev)) {
                spin_lock(&idr_lock);
index 7608df83d6d1e0625a8b0de306a799dac62143d3..7bf38c418086e45aee6f7d6ba47f256eb65e47f6 100644 (file)
@@ -722,7 +722,8 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
 
        INIT_LIST_HEAD(&driver->clients);
        /* Walk the adapters that are already present */
-       class_for_each_device(&i2c_adapter_class, driver, __attach_adapter);
+       class_for_each_device(&i2c_adapter_class, NULL, driver,
+                             __attach_adapter);
 
        mutex_unlock(&core_lock);
        return 0;
@@ -782,7 +783,8 @@ void i2c_del_driver(struct i2c_driver *driver)
 {
        mutex_lock(&core_lock);
 
-       class_for_each_device(&i2c_adapter_class, driver, __detach_adapter);
+       class_for_each_device(&i2c_adapter_class, NULL, driver,
+                             __detach_adapter);
 
        driver_unregister(&driver->driver);
        pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
index 86727fa8858fcf808a1a1373efe0ecc46a2e5678..9d55c6383b2323bd908b782095420196498842aa 100644 (file)
@@ -521,9 +521,9 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
                return PTR_ERR(i2c_dev);
 
        /* register this i2c device with the driver core */
-       i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,
-                                    MKDEV(I2C_MAJOR, adap->nr),
-                                    "i2c-%d", adap->nr);
+       i2c_dev->dev = device_create_drvdata(i2c_dev_class, &adap->dev,
+                                            MKDEV(I2C_MAJOR, adap->nr),
+                                            NULL, "i2c-%d", adap->nr);
        if (IS_ERR(i2c_dev->dev)) {
                res = PTR_ERR(i2c_dev->dev);
                goto error;
index 15b09b89588a033b1e6f967b05f5fe8615286e08..04d9c4d459d00f61e77efcee48ea91797dc0e0a0 100644 (file)
@@ -510,6 +510,7 @@ config BLK_DEV_TRIFLEX
 
 config BLK_DEV_CY82C693
        tristate "CY82C693 chipset support"
+       depends on ALPHA
        select IDE_TIMINGS
        select BLK_DEV_IDEDMA_PCI
        help
@@ -548,6 +549,7 @@ config BLK_DEV_CS5535
 
 config BLK_DEV_HPT34X
        tristate "HPT34X chipset support"
+       depends on BROKEN
        select BLK_DEV_IDEDMA_PCI
        help
          This driver adds up to 4 more EIDE devices sharing a single
index 52f58c88578337a1029265250ca8775b89bf90e4..f575e8341aec8f3e2580486e6f0432045bb73bbc 100644 (file)
@@ -72,7 +72,7 @@ struct icside_state {
        void __iomem *ioc_base;
        unsigned int sel;
        unsigned int type;
-       ide_hwif_t *hwif[2];
+       struct ide_host *host;
 };
 
 #define ICS_TYPE_A3IN  0
@@ -375,12 +375,14 @@ static int icside_dma_test_irq(ide_drive_t *drive)
 
 static void icside_dma_timeout(ide_drive_t *drive)
 {
+       ide_hwif_t *hwif = drive->hwif;
+
        printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
 
        if (icside_dma_test_irq(drive))
                return;
 
-       ide_dump_status(drive, "DMA timeout", ide_read_status(drive));
+       ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif));
 
        icside_dma_end(drive);
 }
@@ -440,10 +442,10 @@ static void icside_setup_ports(hw_regs_t *hw, void __iomem *base,
 static int __init
 icside_register_v5(struct icside_state *state, struct expansion_card *ec)
 {
-       ide_hwif_t *hwif;
        void __iomem *base;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-       hw_regs_t hw;
+       struct ide_host *host;
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+       int ret;
 
        base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
        if (!base)
@@ -463,22 +465,23 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
 
        icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec);
 
-       hwif = ide_find_port();
-       if (!hwif)
+       host = ide_host_alloc(NULL, hws);
+       if (host == NULL)
                return -ENODEV;
 
-       ide_init_port_hw(hwif, &hw);
-       default_hwif_mmiops(hwif);
-
-       state->hwif[0] = hwif;
+       state->host = host;
 
        ecard_set_drvdata(ec, state);
 
-       idx[0] = hwif->index;
-
-       ide_device_add(idx, NULL);
+       ret = ide_host_register(host, NULL, hws);
+       if (ret)
+               goto err_free;
 
        return 0;
+err_free:
+       ide_host_free(host);
+       ecard_set_drvdata(ec, NULL);
+       return ret;
 }
 
 static const struct ide_port_info icside_v6_port_info __initdata = {
@@ -493,13 +496,12 @@ static const struct ide_port_info icside_v6_port_info __initdata = {
 static int __init
 icside_register_v6(struct icside_state *state, struct expansion_card *ec)
 {
-       ide_hwif_t *hwif, *mate;
        void __iomem *ioc_base, *easi_base;
+       struct ide_host *host;
        unsigned int sel = 0;
        int ret;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+       hw_regs_t hw[2], *hws[] = { &hw[0], NULL, NULL, NULL };
        struct ide_port_info d = icside_v6_port_info;
-       hw_regs_t hw[2];
 
        ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
        if (!ioc_base) {
@@ -538,28 +540,11 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
        icside_setup_ports(&hw[0], easi_base, &icside_cardinfo_v6_1, ec);
        icside_setup_ports(&hw[1], easi_base, &icside_cardinfo_v6_2, ec);
 
-       /*
-        * Find and register the interfaces.
-        */
-       hwif = ide_find_port();
-       if (hwif == NULL)
+       host = ide_host_alloc(&d, hws);
+       if (host == NULL)
                return -ENODEV;
 
-       ide_init_port_hw(hwif, &hw[0]);
-       default_hwif_mmiops(hwif);
-
-       idx[0] = hwif->index;
-
-       mate = ide_find_port();
-       if (mate) {
-               ide_init_port_hw(mate, &hw[1]);
-               default_hwif_mmiops(mate);
-
-               idx[1] = mate->index;
-       }
-
-       state->hwif[0]    = hwif;
-       state->hwif[1]    = mate;
+       state->host = host;
 
        ecard_set_drvdata(ec, state);
 
@@ -569,11 +554,17 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
                d.dma_ops = NULL;
        }
 
-       ide_device_add(idx, &d);
+       ret = ide_host_register(host, NULL, hws);
+       if (ret)
+               goto err_free;
 
        return 0;
-
- out:
+err_free:
+       ide_host_free(host);
+       if (d.dma_ops)
+               free_dma(ec->dma);
+       ecard_set_drvdata(ec, NULL);
+out:
        return ret;
 }
 
index 2f311da4c963bf5b26ef2dc391f1555de2690076..176532ffae0efcc5b2b28fffef70de95da378475 100644 (file)
 
 static int __init ide_arm_init(void)
 {
-       ide_hwif_t *hwif;
-       hw_regs_t hw;
        unsigned long base = IDE_ARM_IO, ctl = IDE_ARM_IO + 0x206;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
        if (!request_region(base, 8, DRV_NAME)) {
                printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
@@ -51,15 +49,7 @@ static int __init ide_arm_init(void)
        hw.irq = IDE_ARM_IRQ;
        hw.chipset = ide_generic;
 
-       hwif = ide_find_port();
-       if (hwif) {
-               ide_init_port_hw(hwif, &hw);
-               idx[0] = hwif->index;
-
-               ide_device_add(idx, NULL);
-       }
-
-       return 0;
+       return ide_host_add(NULL, hws, NULL);
 }
 
 module_init(ide_arm_init);
index c79b85b6e4a34e82b135cee906842656bc3652a9..65bb4b8fd57086946e02c2c09bf907fa9909980b 100644 (file)
@@ -316,15 +316,14 @@ static u8 __devinit palm_bk3710_cable_detect(ide_hwif_t *hwif)
 static int __devinit palm_bk3710_init_dma(ide_hwif_t *hwif,
                                          const struct ide_port_info *d)
 {
-       unsigned long base =
-               hwif->io_ports.data_addr - IDE_PALM_ATA_PRI_REG_OFFSET;
-
        printk(KERN_INFO "    %s: MMIO-DMA\n", hwif->name);
 
        if (ide_allocate_dma_engine(hwif))
                return -1;
 
-       ide_setup_dma(hwif, base);
+       hwif->dma_base = hwif->io_ports.data_addr - IDE_PALM_ATA_PRI_REG_OFFSET;
+
+       hwif->dma_ops = &sff_dma_ops;
 
        return 0;
 }
@@ -348,11 +347,10 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev)
 {
        struct clk *clk;
        struct resource *mem, *irq;
-       ide_hwif_t *hwif;
+       struct ide_host *host;
        unsigned long base, rate;
-       int i;
-       hw_regs_t hw;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+       int i, rc;
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
        clk = clk_get(NULL, "IDECLK");
        if (IS_ERR(clk))
@@ -394,24 +392,14 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev)
        hw.irq = irq->start;
        hw.chipset = ide_palm3710;
 
-       hwif = ide_find_port();
-       if (hwif == NULL)
+       rc = ide_host_add(&palm_bk3710_port_info, hws, NULL);
+       if (rc)
                goto out;
 
-       i = hwif->index;
-
-       ide_init_port_hw(hwif, &hw);
-
-       default_hwif_mmiops(hwif);
-
-       idx[0] = i;
-
-       ide_device_add(idx, &palm_bk3710_port_info);
-
        return 0;
 out:
        printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n");
-       return -ENODEV;
+       return rc;
 }
 
 /* work with hotplug and coldplug */
index 43057e0303c89016e1098f6b410d6870c8cd5bf0..2bdd8b734afb6221aed29958c9a696e4f341614b 100644 (file)
@@ -32,11 +32,10 @@ static void rapide_setup_ports(hw_regs_t *hw, void __iomem *base,
 static int __devinit
 rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
-       ide_hwif_t *hwif;
        void __iomem *base;
+       struct ide_host *host;
        int ret;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-       hw_regs_t hw;
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
        ret = ecard_request_resources(ec);
        if (ret)
@@ -53,20 +52,11 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
        hw.chipset = ide_generic;
        hw.dev = &ec->dev;
 
-       hwif = ide_find_port();
-       if (hwif == NULL) {
-               ret = -ENOENT;
+       ret = ide_host_add(&rapide_port_info, hws, &host);
+       if (ret)
                goto release;
-       }
-
-       ide_init_port_hw(hwif, &hw);
-       default_hwif_mmiops(hwif);
-
-       idx[0] = hwif->index;
-
-       ide_device_add(idx, &rapide_port_info);
 
-       ecard_set_drvdata(ec, hwif);
+       ecard_set_drvdata(ec, host);
        goto out;
 
  release:
@@ -77,11 +67,11 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
 
 static void __devexit rapide_remove(struct expansion_card *ec)
 {
-       ide_hwif_t *hwif = ecard_get_drvdata(ec);
+       struct ide_host *host = ecard_get_drvdata(ec);
 
        ecard_set_drvdata(ec, NULL);
 
-       ide_unregister(hwif);
+       ide_host_remove(host);
 
        ecard_release_resources(ec);
 }
index 20fad6d542cc75178dee5cd0629ad6d890f8a88a..bde7a585f1987e3488e318982754143399a3709e 100644 (file)
@@ -100,6 +100,8 @@ static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task)
        /* be sure we're looking at the low order bits */
        outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
 
+       if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
+               tf->feature = inb(io_ports->feature_addr);
        if (task->tf_flags & IDE_TFLAG_IN_NSECT)
                tf->nsect  = inb(io_ports->nsect_addr);
        if (task->tf_flags & IDE_TFLAG_IN_LBAL)
@@ -153,6 +155,21 @@ static void h8300_output_data(ide_drive_t *drive, struct request *rq,
        mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
 }
 
+static const struct ide_tp_ops h8300_tp_ops = {
+       .exec_command           = ide_exec_command,
+       .read_status            = ide_read_status,
+       .read_altstatus         = ide_read_altstatus,
+       .read_sff_dma_status    = ide_read_sff_dma_status,
+
+       .set_irq                = ide_set_irq,
+
+       .tf_load                = h8300_tf_load,
+       .tf_read                = h8300_tf_read,
+
+       .input_data             = h8300_input_data,
+       .output_data            = h8300_output_data,
+};
+
 #define H8300_IDE_GAP (2)
 
 static inline void hw_setup(hw_regs_t *hw)
@@ -167,27 +184,14 @@ static inline void hw_setup(hw_regs_t *hw)
        hw->chipset = ide_generic;
 }
 
-static inline void hwif_setup(ide_hwif_t *hwif)
-{
-       default_hwif_iops(hwif);
-
-       hwif->tf_load = h8300_tf_load;
-       hwif->tf_read = h8300_tf_read;
-
-       hwif->input_data  = h8300_input_data;
-       hwif->output_data = h8300_output_data;
-}
-
 static const struct ide_port_info h8300_port_info = {
+       .tp_ops                 = &h8300_tp_ops,
        .host_flags             = IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_NO_DMA,
 };
 
 static int __init h8300_ide_init(void)
 {
-       hw_regs_t hw;
-       ide_hwif_t *hwif;
-       int index;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
        printk(KERN_INFO DRV_NAME ": H8/300 generic IDE interface\n");
 
@@ -200,19 +204,7 @@ static int __init h8300_ide_init(void)
 
        hw_setup(&hw);
 
-       hwif = ide_find_port_slot(&h8300_port_info);
-       if (hwif == NULL)
-               return -ENOENT;
-
-       index = hwif->index;
-       ide_init_port_hw(hwif, &hw);
-       hwif_setup(hwif);
-
-       idx[0] = index;
-
-       ide_device_add(idx, &h8300_port_info);
-
-       return 0;
+       return ide_host_add(&h8300_port_info, hws, NULL);
 
 out_busy:
        printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n");
index 2802031de670a3bfa3f211e9c6a31a184e040948..adf04f99cdebb20f9d63e15c0010fa34b6db5e39 100644 (file)
@@ -22,6 +22,8 @@ ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
        void (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int))
 {
        ide_hwif_t *hwif = drive->hwif;
+       struct request *rq = hwif->hwgroup->rq;
+       const struct ide_tp_ops *tp_ops = hwif->tp_ops;
        xfer_func_t *xferfunc;
        unsigned int temp;
        u16 bcount;
@@ -30,12 +32,12 @@ ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
        debug_log("Enter %s - interrupt handler\n", __func__);
 
        if (pc->flags & PC_FLAG_TIMEDOUT) {
-               pc->callback(drive);
+               drive->pc_callback(drive);
                return ide_stopped;
        }
 
        /* Clear the interrupt */
-       stat = ide_read_status(drive);
+       stat = tp_ops->read_status(hwif);
 
        if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
                if (hwif->dma_ops->dma_end(drive) ||
@@ -63,8 +65,9 @@ ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
                local_irq_enable_in_hardirq();
 
                if (drive->media == ide_tape && !scsi &&
-                   (stat & ERR_STAT) && pc->c[0] == REQUEST_SENSE)
+                   (stat & ERR_STAT) && rq->cmd[0] == REQUEST_SENSE)
                        stat &= ~ERR_STAT;
+
                if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) {
                        /* Error detected */
                        debug_log("%s: I/O error\n", drive->name);
@@ -75,16 +78,17 @@ ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
                                        goto cmd_finished;
                        }
 
-                       if (pc->c[0] == REQUEST_SENSE) {
+                       if (rq->cmd[0] == REQUEST_SENSE) {
                                printk(KERN_ERR "%s: I/O error in request sense"
                                                " command\n", drive->name);
                                return ide_do_reset(drive);
                        }
 
-                       debug_log("[cmd %x]: check condition\n", pc->c[0]);
+                       debug_log("[cmd %x]: check condition\n", rq->cmd[0]);
 
                        /* Retry operation */
                        retry_pc(drive);
+
                        /* queued, but not started */
                        return ide_stopped;
                }
@@ -95,8 +99,10 @@ cmd_finished:
                        dsc_handle(drive);
                        return ide_stopped;
                }
+
                /* Command finished - Call the callback function */
-               pc->callback(drive);
+               drive->pc_callback(drive);
+
                return ide_stopped;
        }
 
@@ -107,16 +113,15 @@ cmd_finished:
                ide_dma_off(drive);
                return ide_do_reset(drive);
        }
-       /* Get the number of bytes to transfer on this interrupt. */
-       bcount = (hwif->INB(hwif->io_ports.lbah_addr) << 8) |
-                 hwif->INB(hwif->io_ports.lbam_addr);
 
-       ireason = hwif->INB(hwif->io_ports.nsect_addr);
+       /* Get the number of bytes to transfer on this interrupt. */
+       ide_read_bcount_and_ireason(drive, &bcount, &ireason);
 
        if (ireason & CD) {
                printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__);
                return ide_do_reset(drive);
        }
+
        if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) {
                /* Hopefully, we will never get here */
                printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
@@ -125,6 +130,7 @@ cmd_finished:
                                (ireason & IO) ? "Read" : "Write");
                return ide_do_reset(drive);
        }
+
        if (!(pc->flags & PC_FLAG_WRITING)) {
                /* Reading - Check that we have enough space */
                temp = pc->xferred + bcount;
@@ -142,7 +148,7 @@ cmd_finished:
                                        if (pc->sg)
                                                io_buffers(drive, pc, temp, 0);
                                        else
-                                               hwif->input_data(drive, NULL,
+                                               tp_ops->input_data(drive, NULL,
                                                        pc->cur_pos, temp);
                                        printk(KERN_ERR "%s: transferred %d of "
                                                        "%d bytes\n",
@@ -159,9 +165,9 @@ cmd_finished:
                        debug_log("The device wants to send us more data than "
                                  "expected - allowing transfer\n");
                }
-               xferfunc = hwif->input_data;
+               xferfunc = tp_ops->input_data;
        } else
-               xferfunc = hwif->output_data;
+               xferfunc = tp_ops->output_data;
 
        if ((drive->media == ide_floppy && !scsi && !pc->buf) ||
            (drive->media == ide_tape && !scsi && pc->bh) ||
@@ -175,7 +181,7 @@ cmd_finished:
        pc->cur_pos += bcount;
 
        debug_log("[cmd %x] transferred %d bytes on that intr.\n",
-                 pc->c[0], bcount);
+                 rq->cmd[0], bcount);
 
        /* And set the interrupt handler again */
        ide_set_handler(drive, handler, timeout, expiry);
@@ -183,16 +189,27 @@ cmd_finished:
 }
 EXPORT_SYMBOL_GPL(ide_pc_intr);
 
+static u8 ide_read_ireason(ide_drive_t *drive)
+{
+       ide_task_t task;
+
+       memset(&task, 0, sizeof(task));
+       task.tf_flags = IDE_TFLAG_IN_NSECT;
+
+       drive->hwif->tp_ops->tf_read(drive, &task);
+
+       return task.tf.nsect & 3;
+}
+
 static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
 {
-       ide_hwif_t *hwif = drive->hwif;
        int retries = 100;
 
        while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) {
                printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
                                "a packet command, retrying\n", drive->name);
                udelay(100);
-               ireason = hwif->INB(hwif->io_ports.nsect_addr);
+               ireason = ide_read_ireason(drive);
                if (retries == 0) {
                        printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
                                        "a packet command, ignoring\n",
@@ -210,6 +227,7 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
                                ide_expiry_t *expiry)
 {
        ide_hwif_t *hwif = drive->hwif;
+       struct request *rq = hwif->hwgroup->rq;
        ide_startstop_t startstop;
        u8 ireason;
 
@@ -219,7 +237,7 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
                return startstop;
        }
 
-       ireason = hwif->INB(hwif->io_ports.nsect_addr);
+       ireason = ide_read_ireason(drive);
        if (drive->media == ide_tape && !drive->scsi)
                ireason = ide_wait_ireason(drive, ireason);
 
@@ -239,8 +257,8 @@ ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
        }
 
        /* Send the actual packet */
-       if ((pc->flags & PC_FLAG_ZIP_DRIVE) == 0)
-               hwif->output_data(drive, NULL, pc->c, 12);
+       if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
+               hwif->tp_ops->output_data(drive, NULL, rq->cmd, 12);
 
        return ide_started;
 }
@@ -284,7 +302,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc,
                           bcount, dma);
 
        /* Issue the packet command */
-       if (pc->flags & PC_FLAG_DRQ_INTERRUPT) {
+       if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
                ide_execute_command(drive, WIN_PACKETCMD, handler,
                                    timeout, NULL);
                return ide_started;
index 6e29dd5320901c65cfe9f9b985cf28c8997832ac..4e73aeee40534f553c65075c6b1b4730c2253123 100644 (file)
@@ -85,10 +85,8 @@ static void ide_cd_put(struct cdrom_info *cd)
 /* Mark that we've seen a media change and invalidate our internal buffers. */
 static void cdrom_saw_media_change(ide_drive_t *drive)
 {
-       struct cdrom_info *cd = drive->driver_data;
-
-       cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED;
-       cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID;
+       drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED;
+       drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;
 }
 
 static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
@@ -280,11 +278,12 @@ static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st)
  */
 static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
 {
-       struct request *rq = HWGROUP(drive)->rq;
+       ide_hwif_t *hwif = drive->hwif;
+       struct request *rq = hwif->hwgroup->rq;
        int stat, err, sense_key;
 
        /* check for errors */
-       stat = ide_read_status(drive);
+       stat = hwif->tp_ops->read_status(hwif);
 
        if (stat_ret)
                *stat_ret = stat;
@@ -528,7 +527,7 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
        ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL,
                           xferlen, info->dma);
 
-       if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) {
+       if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
                /* waiting for CDB interrupt, not DMA yet. */
                if (info->dma)
                        drive->waiting_for_dma = 0;
@@ -560,7 +559,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
        struct cdrom_info *info = drive->driver_data;
        ide_startstop_t startstop;
 
-       if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) {
+       if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
                /*
                 * Here we should have been called after receiving an interrupt
                 * from the device.  DRQ should how be set.
@@ -589,7 +588,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
                cmd_len = ATAPI_MIN_CDB_BYTES;
 
        /* send the command to the device */
-       hwif->output_data(drive, NULL, rq->cmd, cmd_len);
+       hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
 
        /* start the DMA if need be */
        if (info->dma)
@@ -606,6 +605,8 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
 static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
                                int len, int ireason, int rw)
 {
+       ide_hwif_t *hwif = drive->hwif;
+
        /*
         * ireason == 0: the drive wants to receive data from us
         * ireason == 2: the drive is expecting to transfer data to us
@@ -624,7 +625,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
                 * Some drives (ASUS) seem to tell us that status info is
                 * available.  Just get it and ignore.
                 */
-               (void)ide_read_status(drive);
+               (void)hwif->tp_ops->read_status(hwif);
                return 0;
        } else {
                /* drive wants a command packet, or invalid ireason... */
@@ -645,20 +646,18 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
  */
 static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
 {
-       struct cdrom_info *cd = drive->driver_data;
-
        if ((len % SECTOR_SIZE) == 0)
                return 0;
 
        printk(KERN_ERR "%s: %s: Bad transfer size %d\n",
                        drive->name, __func__, len);
 
-       if (cd->cd_flags & IDE_CD_FLAG_LIMIT_NFRAMES)
+       if (drive->atapi_flags & IDE_AFLAG_LIMIT_NFRAMES)
                printk(KERN_ERR "  This drive is not supported by "
                                "this version of the driver\n");
        else {
                printk(KERN_ERR "  Trying to limit transfer sizes\n");
-               cd->cd_flags |= IDE_CD_FLAG_LIMIT_NFRAMES;
+               drive->atapi_flags |= IDE_AFLAG_LIMIT_NFRAMES;
        }
 
        return 1;
@@ -735,7 +734,7 @@ static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive)
        if (cdrom_decode_status(drive, 0, &stat))
                return ide_stopped;
 
-       info->cd_flags |= IDE_CD_FLAG_SEEKING;
+       drive->atapi_flags |= IDE_AFLAG_SEEKING;
 
        if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) {
                if (--retry == 0)
@@ -892,10 +891,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
        struct request *rq = HWGROUP(drive)->rq;
        xfer_func_t *xferfunc;
        ide_expiry_t *expiry = NULL;
-       int dma_error = 0, dma, stat, ireason, len, thislen, uptodate = 0;
+       int dma_error = 0, dma, stat, thislen, uptodate = 0;
        int write = (rq_data_dir(rq) == WRITE) ? 1 : 0;
        unsigned int timeout;
-       u8 lowcyl, highcyl;
+       u16 len;
+       u8 ireason;
 
        /* check for errors */
        dma = info->dma;
@@ -923,12 +923,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
                goto end_request;
        }
 
-       /* ok we fall to pio :/ */
-       ireason = hwif->INB(hwif->io_ports.nsect_addr) & 0x3;
-       lowcyl  = hwif->INB(hwif->io_ports.lbam_addr);
-       highcyl = hwif->INB(hwif->io_ports.lbah_addr);
-
-       len = lowcyl + (256 * highcyl);
+       ide_read_bcount_and_ireason(drive, &len, &ireason);
 
        thislen = blk_fs_request(rq) ? len : rq->data_len;
        if (thislen > len)
@@ -991,10 +986,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 
        if (ireason == 0) {
                write = 1;
-               xferfunc = hwif->output_data;
+               xferfunc = hwif->tp_ops->output_data;
        } else {
                write = 0;
-               xferfunc = hwif->input_data;
+               xferfunc = hwif->tp_ops->input_data;
        }
 
        /* transfer data */
@@ -1198,9 +1193,10 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
        int xferlen;
 
        if (blk_fs_request(rq)) {
-               if (info->cd_flags & IDE_CD_FLAG_SEEKING) {
+               if (drive->atapi_flags & IDE_AFLAG_SEEKING) {
+                       ide_hwif_t *hwif = drive->hwif;
                        unsigned long elapsed = jiffies - info->start_seek;
-                       int stat = ide_read_status(drive);
+                       int stat = hwif->tp_ops->read_status(hwif);
 
                        if ((stat & SEEK_STAT) != SEEK_STAT) {
                                if (elapsed < IDECD_SEEK_TIMEOUT) {
@@ -1211,7 +1207,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
                                printk(KERN_ERR "%s: DSC timeout\n",
                                                drive->name);
                        }
-                       info->cd_flags &= ~IDE_CD_FLAG_SEEKING;
+                       drive->atapi_flags &= ~IDE_AFLAG_SEEKING;
                }
                if (rq_data_dir(rq) == READ &&
                    IDE_LARGE_SEEK(info->last_block, block,
@@ -1288,7 +1284,7 @@ int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
         */
        cmd[7] = cdi->sanyo_slot % 3;
 
-       return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, sense, 0, REQ_QUIET);
+       return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, sense, 0, REQ_QUIET);
 }
 
 static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
@@ -1296,8 +1292,8 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
                               struct request_sense *sense)
 {
        struct {
-               __u32 lba;
-               __u32 blocklen;
+               __be32 lba;
+               __be32 blocklen;
        } capbuf;
 
        int stat;
@@ -1369,7 +1365,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
         */
        (void) cdrom_check_status(drive, sense);
 
-       if (info->cd_flags & IDE_CD_FLAG_TOC_VALID)
+       if (drive->atapi_flags & IDE_AFLAG_TOC_VALID)
                return 0;
 
        /* try to get the total cdrom capacity and sector size */
@@ -1391,7 +1387,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
        if (stat)
                return stat;
 
-       if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) {
+       if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
                toc->hdr.first_track = BCD2BIN(toc->hdr.first_track);
                toc->hdr.last_track  = BCD2BIN(toc->hdr.last_track);
        }
@@ -1432,7 +1428,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
                if (stat)
                        return stat;
 
-               if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) {
+               if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
                        toc->hdr.first_track = (u8)BIN2BCD(CDROM_LEADOUT);
                        toc->hdr.last_track = (u8)BIN2BCD(CDROM_LEADOUT);
                } else {
@@ -1446,14 +1442,14 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
 
        toc->hdr.toc_length = be16_to_cpu(toc->hdr.toc_length);
 
-       if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) {
+       if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
                toc->hdr.first_track = BCD2BIN(toc->hdr.first_track);
                toc->hdr.last_track  = BCD2BIN(toc->hdr.last_track);
        }
 
        for (i = 0; i <= ntracks; i++) {
-               if (info->cd_flags & IDE_CD_FLAG_TOCADDR_AS_BCD) {
-                       if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD)
+               if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) {
+                       if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD)
                                toc->ent[i].track = BCD2BIN(toc->ent[i].track);
                        msf_from_bcd(&toc->ent[i].addr.msf);
                }
@@ -1476,7 +1472,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
                toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */
        }
 
-       if (info->cd_flags & IDE_CD_FLAG_TOCADDR_AS_BCD) {
+       if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) {
                /* re-read multisession information using MSF format */
                stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
                                           sizeof(ms_tmp), sense);
@@ -1500,7 +1496,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
        }
 
        /* Remember that we've read this stuff. */
-       info->cd_flags |= IDE_CD_FLAG_TOC_VALID;
+       drive->atapi_flags |= IDE_AFLAG_TOC_VALID;
 
        return 0;
 }
@@ -1512,7 +1508,7 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
        struct packet_command cgc;
        int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE;
 
-       if ((info->cd_flags & IDE_CD_FLAG_FULL_CAPS_PAGE) == 0)
+       if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0)
                size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE;
 
        init_cdrom_command(&cgc, buf, size, CGC_DATA_UNKNOWN);
@@ -1530,15 +1526,12 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
        struct cdrom_info *cd = drive->driver_data;
        u16 curspeed, maxspeed;
 
-       curspeed = *(u16 *)&buf[8 + 14];
-       maxspeed = *(u16 *)&buf[8 +  8];
-
-       if (cd->cd_flags & IDE_CD_FLAG_LE_SPEED_FIELDS) {
-               curspeed = le16_to_cpu(curspeed);
-               maxspeed = le16_to_cpu(maxspeed);
+       if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) {
+               curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]);
+               maxspeed = le16_to_cpup((__le16 *)&buf[8 + 8]);
        } else {
-               curspeed = be16_to_cpu(curspeed);
-               maxspeed = be16_to_cpu(maxspeed);
+               curspeed = be16_to_cpup((__be16 *)&buf[8 + 14]);
+               maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]);
        }
 
        cd->current_speed = (curspeed + (176/2)) / 176;
@@ -1579,7 +1572,7 @@ static int ide_cdrom_register(ide_drive_t *drive, int nslots)
        devinfo->handle = drive;
        strcpy(devinfo->name, drive->name);
 
-       if (info->cd_flags & IDE_CD_FLAG_NO_SPEED_SELECT)
+       if (drive->atapi_flags & IDE_AFLAG_NO_SPEED_SELECT)
                devinfo->mask |= CDC_SELECT_SPEED;
 
        devinfo->disk = info->disk;
@@ -1605,8 +1598,8 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
                return nslots;
        }
 
-       if (cd->cd_flags & IDE_CD_FLAG_PRE_ATAPI12) {
-               cd->cd_flags &= ~IDE_CD_FLAG_NO_EJECT;
+       if (drive->atapi_flags & IDE_AFLAG_PRE_ATAPI12) {
+               drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT;
                cdi->mask &= ~CDC_PLAY_AUDIO;
                return nslots;
        }
@@ -1624,9 +1617,9 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
                return 0;
 
        if ((buf[8 + 6] & 0x01) == 0)
-               cd->cd_flags |= IDE_CD_FLAG_NO_DOORLOCK;
+               drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
        if (buf[8 + 6] & 0x08)
-               cd->cd_flags &= ~IDE_CD_FLAG_NO_EJECT;
+               drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT;
        if (buf[8 + 3] & 0x01)
                cdi->mask &= ~CDC_CD_R;
        if (buf[8 + 3] & 0x02)
@@ -1637,7 +1630,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
                cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM);
        if (buf[8 + 3] & 0x10)
                cdi->mask &= ~CDC_DVD_R;
-       if ((buf[8 + 4] & 0x01) || (cd->cd_flags & IDE_CD_FLAG_PLAY_AUDIO_OK))
+       if ((buf[8 + 4] & 0x01) || (drive->atapi_flags & IDE_AFLAG_PLAY_AUDIO_OK))
                cdi->mask &= ~CDC_PLAY_AUDIO;
 
        mechtype = buf[8 + 6] >> 5;
@@ -1679,7 +1672,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
        else
                printk(KERN_CONT " drive");
 
-       printk(KERN_CONT ", %dkB Cache\n", be16_to_cpu(*(u16 *)&buf[8 + 12]));
+       printk(KERN_CONT ", %dkB Cache\n", be16_to_cpup((__be16 *)&buf[8 + 12]));
 
        return nslots;
 }
@@ -1802,43 +1795,43 @@ static inline void ide_cdrom_add_settings(ide_drive_t *drive) { ; }
 
 static const struct cd_list_entry ide_cd_quirks_list[] = {
        /* Limit transfer size per interrupt. */
-       { "SAMSUNG CD-ROM SCR-2430", NULL,   IDE_CD_FLAG_LIMIT_NFRAMES      },
-       { "SAMSUNG CD-ROM SCR-2432", NULL,   IDE_CD_FLAG_LIMIT_NFRAMES      },
+       { "SAMSUNG CD-ROM SCR-2430", NULL,   IDE_AFLAG_LIMIT_NFRAMES         },
+       { "SAMSUNG CD-ROM SCR-2432", NULL,   IDE_AFLAG_LIMIT_NFRAMES         },
        /* SCR-3231 doesn't support the SET_CD_SPEED command. */
-       { "SAMSUNG CD-ROM SCR-3231", NULL,   IDE_CD_FLAG_NO_SPEED_SELECT    },
+       { "SAMSUNG CD-ROM SCR-3231", NULL,   IDE_AFLAG_NO_SPEED_SELECT       },
        /* Old NEC260 (not R) was released before ATAPI 1.2 spec. */
-       { "NEC CD-ROM DRIVE:260",    "1.01", IDE_CD_FLAG_TOCADDR_AS_BCD |
-                                            IDE_CD_FLAG_PRE_ATAPI12,       },
+       { "NEC CD-ROM DRIVE:260",    "1.01", IDE_AFLAG_TOCADDR_AS_BCD |
+                                            IDE_AFLAG_PRE_ATAPI12,          },
        /* Vertos 300, some versions of this drive like to talk BCD. */
-       { "V003S0DS",                NULL,   IDE_CD_FLAG_VERTOS_300_SSD,    },
+       { "V003S0DS",                NULL,   IDE_AFLAG_VERTOS_300_SSD,       },
        /* Vertos 600 ESD. */
-       { "V006E0DS",                NULL,   IDE_CD_FLAG_VERTOS_600_ESD,    },
+       { "V006E0DS",                NULL,   IDE_AFLAG_VERTOS_600_ESD,       },
        /*
         * Sanyo 3 CD changer uses a non-standard command for CD changing
         * (by default standard ATAPI support for CD changers is used).
         */
-       { "CD-ROM CDR-C3 G",         NULL,   IDE_CD_FLAG_SANYO_3CD          },
-       { "CD-ROM CDR-C3G",          NULL,   IDE_CD_FLAG_SANYO_3CD          },
-       { "CD-ROM CDR_C36",          NULL,   IDE_CD_FLAG_SANYO_3CD          },
+       { "CD-ROM CDR-C3 G",         NULL,   IDE_AFLAG_SANYO_3CD             },
+       { "CD-ROM CDR-C3G",          NULL,   IDE_AFLAG_SANYO_3CD             },
+       { "CD-ROM CDR_C36",          NULL,   IDE_AFLAG_SANYO_3CD             },
        /* Stingray 8X CD-ROM. */
-       { "STINGRAY 8422 IDE 8X CD-ROM 7-27-95", NULL, IDE_CD_FLAG_PRE_ATAPI12},
+       { "STINGRAY 8422 IDE 8X CD-ROM 7-27-95", NULL, IDE_AFLAG_PRE_ATAPI12 },
        /*
         * ACER 50X CD-ROM and WPI 32X CD-ROM require the full spec length
         * mode sense page capabilities size, but older drives break.
         */
-       { "ATAPI CD ROM DRIVE 50X MAX", NULL,   IDE_CD_FLAG_FULL_CAPS_PAGE  },
-       { "WPI CDS-32X",                NULL,   IDE_CD_FLAG_FULL_CAPS_PAGE  },
+       { "ATAPI CD ROM DRIVE 50X MAX", NULL,   IDE_AFLAG_FULL_CAPS_PAGE     },
+       { "WPI CDS-32X",                NULL,   IDE_AFLAG_FULL_CAPS_PAGE     },
        /* ACER/AOpen 24X CD-ROM has the speed fields byte-swapped. */
-       { "",                        "241N", IDE_CD_FLAG_LE_SPEED_FIELDS    },
+       { "",                        "241N", IDE_AFLAG_LE_SPEED_FIELDS       },
        /*
         * Some drives used by Apple don't advertise audio play
         * but they do support reading TOC & audio datas.
         */
-       { "MATSHITADVD-ROM SR-8187", NULL,   IDE_CD_FLAG_PLAY_AUDIO_OK      },
-       { "MATSHITADVD-ROM SR-8186", NULL,   IDE_CD_FLAG_PLAY_AUDIO_OK      },
-       { "MATSHITADVD-ROM SR-8176", NULL,   IDE_CD_FLAG_PLAY_AUDIO_OK      },
-       { "MATSHITADVD-ROM SR-8174", NULL,   IDE_CD_FLAG_PLAY_AUDIO_OK      },
-       { "Optiarc DVD RW AD-5200A", NULL,   IDE_CD_FLAG_PLAY_AUDIO_OK      },
+       { "MATSHITADVD-ROM SR-8187", NULL,   IDE_AFLAG_PLAY_AUDIO_OK         },
+       { "MATSHITADVD-ROM SR-8186", NULL,   IDE_AFLAG_PLAY_AUDIO_OK         },
+       { "MATSHITADVD-ROM SR-8176", NULL,   IDE_AFLAG_PLAY_AUDIO_OK         },
+       { "MATSHITADVD-ROM SR-8174", NULL,   IDE_AFLAG_PLAY_AUDIO_OK         },
+       { "Optiarc DVD RW AD-5200A", NULL,   IDE_AFLAG_PLAY_AUDIO_OK         },
        { NULL, NULL, 0 }
 };
 
@@ -1873,20 +1866,20 @@ static int ide_cdrom_setup(ide_drive_t *drive)
 
        drive->special.all      = 0;
 
-       cd->cd_flags = IDE_CD_FLAG_MEDIA_CHANGED | IDE_CD_FLAG_NO_EJECT |
+       drive->atapi_flags = IDE_AFLAG_MEDIA_CHANGED | IDE_AFLAG_NO_EJECT |
                       ide_cd_flags(id);
 
        if ((id->config & 0x0060) == 0x20)
-               cd->cd_flags |= IDE_CD_FLAG_DRQ_INTERRUPT;
+               drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;
 
-       if ((cd->cd_flags & IDE_CD_FLAG_VERTOS_300_SSD) &&
+       if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) &&
            id->fw_rev[4] == '1' && id->fw_rev[6] <= '2')
-               cd->cd_flags |= (IDE_CD_FLAG_TOCTRACKS_AS_BCD |
-                                IDE_CD_FLAG_TOCADDR_AS_BCD);
-       else if ((cd->cd_flags & IDE_CD_FLAG_VERTOS_600_ESD) &&
+               drive->atapi_flags |= (IDE_AFLAG_TOCTRACKS_AS_BCD |
+                                    IDE_AFLAG_TOCADDR_AS_BCD);
+       else if ((drive->atapi_flags & IDE_AFLAG_VERTOS_600_ESD) &&
                 id->fw_rev[4] == '1' && id->fw_rev[6] <= '2')
-               cd->cd_flags |= IDE_CD_FLAG_TOCTRACKS_AS_BCD;
-       else if (cd->cd_flags & IDE_CD_FLAG_SANYO_3CD)
+               drive->atapi_flags |= IDE_AFLAG_TOCTRACKS_AS_BCD;
+       else if (drive->atapi_flags & IDE_AFLAG_SANYO_3CD)
                /* 3 => use CD in slot 0 */
                cdi->sanyo_slot = 3;
 
index fe0ea36e4124d1c1ba1cc438d9c8538918122664..61a4599b77dbf3c37528799118c181960a5f5786 100644 (file)
 #define ATAPI_CAPABILITIES_PAGE_SIZE           (8 + 20)
 #define ATAPI_CAPABILITIES_PAGE_PAD_SIZE       4
 
-enum {
-       /* Device sends an interrupt when ready for a packet command. */
-       IDE_CD_FLAG_DRQ_INTERRUPT       = (1 << 0),
-       /* Drive cannot lock the door. */
-       IDE_CD_FLAG_NO_DOORLOCK         = (1 << 1),
-       /* Drive cannot eject the disc. */
-       IDE_CD_FLAG_NO_EJECT            = (1 << 2),
-       /* Drive is a pre ATAPI 1.2 drive. */
-       IDE_CD_FLAG_PRE_ATAPI12         = (1 << 3),
-       /* TOC addresses are in BCD. */
-       IDE_CD_FLAG_TOCADDR_AS_BCD      = (1 << 4),
-       /* TOC track numbers are in BCD. */
-       IDE_CD_FLAG_TOCTRACKS_AS_BCD    = (1 << 5),
-       /*
-        * Drive does not provide data in multiples of SECTOR_SIZE
-        * when more than one interrupt is needed.
-        */
-       IDE_CD_FLAG_LIMIT_NFRAMES       = (1 << 6),
-       /* Seeking in progress. */
-       IDE_CD_FLAG_SEEKING             = (1 << 7),
-       /* Driver has noticed a media change. */
-       IDE_CD_FLAG_MEDIA_CHANGED       = (1 << 8),
-       /* Saved TOC information is current. */
-       IDE_CD_FLAG_TOC_VALID           = (1 << 9),
-       /* We think that the drive door is locked. */
-       IDE_CD_FLAG_DOOR_LOCKED         = (1 << 10),
-       /* SET_CD_SPEED command is unsupported. */
-       IDE_CD_FLAG_NO_SPEED_SELECT     = (1 << 11),
-       IDE_CD_FLAG_VERTOS_300_SSD      = (1 << 12),
-       IDE_CD_FLAG_VERTOS_600_ESD      = (1 << 13),
-       IDE_CD_FLAG_SANYO_3CD           = (1 << 14),
-       IDE_CD_FLAG_FULL_CAPS_PAGE      = (1 << 15),
-       IDE_CD_FLAG_PLAY_AUDIO_OK       = (1 << 16),
-       IDE_CD_FLAG_LE_SPEED_FIELDS     = (1 << 17),
-};
-
 /* Structure of a MSF cdrom address. */
 struct atapi_msf {
        byte reserved;
@@ -128,8 +92,6 @@ struct cdrom_info {
        unsigned long last_block;
        unsigned long start_seek;
 
-       unsigned int cd_flags;
-
        u8 max_speed;           /* Max speed of the drive. */
        u8 current_speed;       /* Current speed of the drive. */
 
index 24d002addf73d5c5b6b1e9af1dcad6ceed15dd7b..74231b41f611b5c63a2e60198ab9b742405deb33 100644 (file)
@@ -27,10 +27,9 @@ int ide_cdrom_open_real(struct cdrom_device_info *cdi, int purpose)
 void ide_cdrom_release_real(struct cdrom_device_info *cdi)
 {
        ide_drive_t *drive = cdi->handle;
-       struct cdrom_info *cd = drive->driver_data;
 
        if (!cdi->use_count)
-               cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID;
+               drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;
 }
 
 /*
@@ -83,13 +82,12 @@ int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi,
                                       int slot_nr)
 {
        ide_drive_t *drive = cdi->handle;
-       struct cdrom_info *cd = drive->driver_data;
        int retval;
 
        if (slot_nr == CDSL_CURRENT) {
                (void) cdrom_check_status(drive, NULL);
-               retval = (cd->cd_flags & IDE_CD_FLAG_MEDIA_CHANGED) ? 1 : 0;
-               cd->cd_flags &= ~IDE_CD_FLAG_MEDIA_CHANGED;
+               retval = (drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED) ? 1 : 0;
+               drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED;
                return retval;
        } else {
                return -EINVAL;
@@ -107,11 +105,11 @@ int cdrom_eject(ide_drive_t *drive, int ejectflag,
        char loej = 0x02;
        unsigned char cmd[BLK_MAX_CDB];
 
-       if ((cd->cd_flags & IDE_CD_FLAG_NO_EJECT) && !ejectflag)
+       if ((drive->atapi_flags & IDE_AFLAG_NO_EJECT) && !ejectflag)
                return -EDRIVE_CANT_DO_THIS;
 
        /* reload fails on some drives, if the tray is locked */
-       if ((cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED) && ejectflag)
+       if ((drive->atapi_flags & IDE_AFLAG_DOOR_LOCKED) && ejectflag)
                return 0;
 
        /* only tell drive to close tray if open, if it can do that */
@@ -123,7 +121,7 @@ int cdrom_eject(ide_drive_t *drive, int ejectflag,
        cmd[0] = GPCMD_START_STOP_UNIT;
        cmd[4] = loej | (ejectflag != 0);
 
-       return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, sense, 0, 0);
+       return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, sense, 0, 0);
 }
 
 /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
@@ -131,7 +129,6 @@ static
 int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
                    struct request_sense *sense)
 {
-       struct cdrom_info *cd = drive->driver_data;
        struct request_sense my_sense;
        int stat;
 
@@ -139,7 +136,7 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
                sense = &my_sense;
 
        /* If the drive cannot lock the door, just pretend. */
-       if (cd->cd_flags & IDE_CD_FLAG_NO_DOORLOCK) {
+       if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK) {
                stat = 0;
        } else {
                unsigned char cmd[BLK_MAX_CDB];
@@ -149,7 +146,7 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
                cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
                cmd[4] = lockflag ? 1 : 0;
 
-               stat = ide_cd_queue_pc(drive, cmd, 0, NULL, 0,
+               stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL,
                                       sense, 0, 0);
        }
 
@@ -160,7 +157,7 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
            (sense->asc == 0x24 || sense->asc == 0x20)) {
                printk(KERN_ERR "%s: door locking not supported\n",
                        drive->name);
-               cd->cd_flags |= IDE_CD_FLAG_NO_DOORLOCK;
+               drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
                stat = 0;
        }
 
@@ -170,9 +167,9 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
 
        if (stat == 0) {
                if (lockflag)
-                       cd->cd_flags |= IDE_CD_FLAG_DOOR_LOCKED;
+                       drive->atapi_flags |= IDE_AFLAG_DOOR_LOCKED;
                else
-                       cd->cd_flags &= ~IDE_CD_FLAG_DOOR_LOCKED;
+                       drive->atapi_flags &= ~IDE_AFLAG_DOOR_LOCKED;
        }
 
        return stat;
@@ -231,7 +228,7 @@ int ide_cdrom_select_speed(struct cdrom_device_info *cdi, int speed)
                cmd[5] = speed & 0xff;
        }
 
-       stat = ide_cd_queue_pc(drive, cmd, 0, NULL, 0, &sense, 0, 0);
+       stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, &sense, 0, 0);
 
        if (!ide_cdrom_get_capabilities(drive, buf)) {
                ide_cdrom_update_speed(drive, buf);
@@ -250,7 +247,7 @@ int ide_cdrom_get_last_session(struct cdrom_device_info *cdi,
        struct request_sense sense;
        int ret;
 
-       if ((info->cd_flags & IDE_CD_FLAG_TOC_VALID) == 0 || !info->toc) {
+       if ((drive->atapi_flags & IDE_AFLAG_TOC_VALID) == 0 || !info->toc) {
                ret = ide_cd_read_toc(drive, &sense);
                if (ret)
                        return ret;
@@ -308,7 +305,7 @@ int ide_cdrom_reset(struct cdrom_device_info *cdi)
         * A reset will unlock the door. If it was previously locked,
         * lock it again.
         */
-       if (cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED)
+       if (drive->atapi_flags & IDE_AFLAG_DOOR_LOCKED)
                (void)ide_cd_lockdoor(drive, 1, &sense);
 
        return ret;
@@ -324,7 +321,7 @@ static int ide_cd_get_toc_entry(ide_drive_t *drive, int track,
        /*
         * don't serve cached data, if the toc isn't valid
         */
-       if ((info->cd_flags & IDE_CD_FLAG_TOC_VALID) == 0)
+       if ((drive->atapi_flags & IDE_AFLAG_TOC_VALID) == 0)
                return -EINVAL;
 
        /* Check validity of requested track number. */
@@ -374,7 +371,7 @@ static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg)
        lba_to_msf(lba_start,   &cmd[3], &cmd[4], &cmd[5]);
        lba_to_msf(lba_end - 1, &cmd[6], &cmd[7], &cmd[8]);
 
-       return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, &sense, 0, 0);
+       return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, &sense, 0, 0);
 }
 
 static int ide_cd_read_tochdr(ide_drive_t *drive, void *arg)
index 3a2e80237c10f5d6daa1a0f377769428af2ba17d..df5fe5756871ca31b135a736dfc64f9d1097bec6 100644 (file)
@@ -158,7 +158,7 @@ static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma)
        write = (task->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
 
        if (dma)
-               index = drive->vdma ? 4 : 8;
+               index = 8;
        else
                index = drive->mult_count ? 0 : 4;
 
index 7ee44f86bc5475065a962f8b2380cd0b86158d1b..be99d463dcc7dfa0265498280e103715ee61bf61 100644 (file)
@@ -100,10 +100,11 @@ static const struct drive_list_entry drive_blacklist [] = {
  
 ide_startstop_t ide_dma_intr (ide_drive_t *drive)
 {
+       ide_hwif_t *hwif = drive->hwif;
        u8 stat = 0, dma_stat = 0;
 
-       dma_stat = drive->hwif->dma_ops->dma_end(drive);
-       stat = ide_read_status(drive);
+       dma_stat = hwif->dma_ops->dma_end(drive);
+       stat = hwif->tp_ops->read_status(hwif);
 
        if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
                if (!dma_stat) {
@@ -334,7 +335,7 @@ static int config_drive_for_dma (ide_drive_t *drive)
 static int dma_timer_expiry (ide_drive_t *drive)
 {
        ide_hwif_t *hwif        = HWIF(drive);
-       u8 dma_stat             = hwif->INB(hwif->dma_status);
+       u8 dma_stat             = hwif->tp_ops->read_sff_dma_status(hwif);
 
        printk(KERN_WARNING "%s: dma_timer_expiry: dma status == 0x%02x\n",
                drive->name, dma_stat);
@@ -369,14 +370,18 @@ void ide_dma_host_set(ide_drive_t *drive, int on)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        u8 unit                 = (drive->select.b.unit & 0x01);
-       u8 dma_stat             = hwif->INB(hwif->dma_status);
+       u8 dma_stat             = hwif->tp_ops->read_sff_dma_status(hwif);
 
        if (on)
                dma_stat |= (1 << (5 + unit));
        else
                dma_stat &= ~(1 << (5 + unit));
 
-       hwif->OUTB(dma_stat, hwif->dma_status);
+       if (hwif->host_flags & IDE_HFLAG_MMIO)
+               writeb(dma_stat,
+                      (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
+       else
+               outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS);
 }
 
 EXPORT_SYMBOL_GPL(ide_dma_host_set);
@@ -449,6 +454,7 @@ int ide_dma_setup(ide_drive_t *drive)
        ide_hwif_t *hwif = drive->hwif;
        struct request *rq = HWGROUP(drive)->rq;
        unsigned int reading;
+       u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
        u8 dma_stat;
 
        if (rq_data_dir(rq))
@@ -470,13 +476,21 @@ int ide_dma_setup(ide_drive_t *drive)
                outl(hwif->dmatable_dma, hwif->dma_base + ATA_DMA_TABLE_OFS);
 
        /* specify r/w */
-       hwif->OUTB(reading, hwif->dma_command);
+       if (mmio)
+               writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+       else
+               outb(reading, hwif->dma_base + ATA_DMA_CMD);
 
-       /* read dma_status for INTR & ERROR flags */
-       dma_stat = hwif->INB(hwif->dma_status);
+       /* read DMA status for INTR & ERROR flags */
+       dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
 
        /* clear INTR & ERROR flags */
-       hwif->OUTB(dma_stat|6, hwif->dma_status);
+       if (mmio)
+               writeb(dma_stat | 6,
+                      (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
+       else
+               outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
+
        drive->waiting_for_dma = 1;
        return 0;
 }
@@ -492,16 +506,24 @@ EXPORT_SYMBOL_GPL(ide_dma_exec_cmd);
 
 void ide_dma_start(ide_drive_t *drive)
 {
-       ide_hwif_t *hwif        = HWIF(drive);
-       u8 dma_cmd              = hwif->INB(hwif->dma_command);
+       ide_hwif_t *hwif = drive->hwif;
+       u8 dma_cmd;
 
        /* Note that this is done *after* the cmd has
         * been issued to the drive, as per the BM-IDE spec.
         * The Promise Ultra33 doesn't work correctly when
         * we do this part before issuing the drive cmd.
         */
-       /* start DMA */
-       hwif->OUTB(dma_cmd|1, hwif->dma_command);
+       if (hwif->host_flags & IDE_HFLAG_MMIO) {
+               dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+               /* start DMA */
+               writeb(dma_cmd | 1,
+                      (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+       } else {
+               dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
+               outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD);
+       }
+
        hwif->dma = 1;
        wmb();
 }
@@ -511,18 +533,33 @@ EXPORT_SYMBOL_GPL(ide_dma_start);
 /* returns 1 on error, 0 otherwise */
 int __ide_dma_end (ide_drive_t *drive)
 {
-       ide_hwif_t *hwif        = HWIF(drive);
+       ide_hwif_t *hwif = drive->hwif;
+       u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
        u8 dma_stat = 0, dma_cmd = 0;
 
        drive->waiting_for_dma = 0;
-       /* get dma_command mode */
-       dma_cmd = hwif->INB(hwif->dma_command);
-       /* stop DMA */
-       hwif->OUTB(dma_cmd&~1, hwif->dma_command);
+
+       if (mmio) {
+               /* get DMA command mode */
+               dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+               /* stop DMA */
+               writeb(dma_cmd & ~1,
+                      (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+       } else {
+               dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
+               outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
+       }
+
        /* get DMA status */
-       dma_stat = hwif->INB(hwif->dma_status);
-       /* clear the INTR & ERROR bits */
-       hwif->OUTB(dma_stat|6, hwif->dma_status);
+       dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+
+       if (mmio)
+               /* clear the INTR & ERROR bits */
+               writeb(dma_stat | 6,
+                      (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
+       else
+               outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
+
        /* purge DMA mappings */
        ide_destroy_dmatable(drive);
        /* verify good DMA status */
@@ -537,7 +574,7 @@ EXPORT_SYMBOL(__ide_dma_end);
 int ide_dma_test_irq(ide_drive_t *drive)
 {
        ide_hwif_t *hwif        = HWIF(drive);
-       u8 dma_stat             = hwif->INB(hwif->dma_status);
+       u8 dma_stat             = hwif->tp_ops->read_sff_dma_status(hwif);
 
        /* return 1 if INTR asserted */
        if ((dma_stat & 4) == 4)
@@ -719,9 +756,8 @@ static int ide_tune_dma(ide_drive_t *drive)
 static int ide_dma_check(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
-       int vdma = (hwif->host_flags & IDE_HFLAG_VDMA)? 1 : 0;
 
-       if (!vdma && ide_tune_dma(drive))
+       if (ide_tune_dma(drive))
                return 0;
 
        /* TODO: always do PIO fallback */
@@ -730,7 +766,7 @@ static int ide_dma_check(ide_drive_t *drive)
 
        ide_set_max_pio(drive);
 
-       return vdma ? 0 : -1;
+       return -1;
 }
 
 int ide_id_dma_bug(ide_drive_t *drive)
@@ -842,7 +878,7 @@ int ide_allocate_dma_engine(ide_hwif_t *hwif)
 }
 EXPORT_SYMBOL_GPL(ide_allocate_dma_engine);
 
-static const struct ide_dma_ops sff_dma_ops = {
+const struct ide_dma_ops sff_dma_ops = {
        .dma_host_set           = ide_dma_host_set,
        .dma_setup              = ide_dma_setup,
        .dma_exec_cmd           = ide_dma_exec_cmd,
@@ -852,18 +888,5 @@ static const struct ide_dma_ops sff_dma_ops = {
        .dma_timeout            = ide_dma_timeout,
        .dma_lost_irq           = ide_dma_lost_irq,
 };
-
-void ide_setup_dma(ide_hwif_t *hwif, unsigned long base)
-{
-       hwif->dma_base = base;
-
-       if (!hwif->dma_command)
-               hwif->dma_command       = hwif->dma_base + 0;
-       if (!hwif->dma_status)
-               hwif->dma_status        = hwif->dma_base + 2;
-
-       hwif->dma_ops = &sff_dma_ops;
-}
-
-EXPORT_SYMBOL_GPL(ide_setup_dma);
+EXPORT_SYMBOL_GPL(sff_dma_ops);
 #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */
index 011d72011cc45524fcad2d1098de83a0c786b59d..3d8e6dd0f41e11f031e7dad1a1be1c434430cbf0 100644 (file)
@@ -125,26 +125,10 @@ typedef struct ide_floppy_obj {
        int wp;
        /* Supports format progress report */
        int srfp;
-       /* Status/Action flags */
-       unsigned long flags;
 } idefloppy_floppy_t;
 
 #define IDEFLOPPY_TICKS_DELAY  HZ/20   /* default delay for ZIP 100 (50ms) */
 
-/* Floppy flag bits values. */
-enum {
-       /* DRQ interrupt device */
-       IDEFLOPPY_FLAG_DRQ_INTERRUPT            = (1 << 0),
-       /* Media may have changed */
-       IDEFLOPPY_FLAG_MEDIA_CHANGED            = (1 << 1),
-       /* Format in progress */
-       IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS       = (1 << 2),
-       /* Avoid commands not supported in Clik drive */
-       IDEFLOPPY_FLAG_CLIK_DRIVE               = (1 << 3),
-       /* Requires BH algorithm for packets */
-       IDEFLOPPY_FLAG_ZIP_DRIVE                = (1 << 4),
-};
-
 /* Defines for the MODE SENSE command */
 #define MODE_SENSE_CURRENT             0x00
 #define MODE_SENSE_CHANGEABLE          0x01
@@ -247,9 +231,9 @@ static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
 
                data = bvec_kmap_irq(bvec, &flags);
                if (direction)
-                       hwif->output_data(drive, NULL, data, count);
+                       hwif->tp_ops->output_data(drive, NULL, data, count);
                else
-                       hwif->input_data(drive, NULL, data, count);
+                       hwif->tp_ops->input_data(drive, NULL, data, count);
                bvec_kunmap_irq(data, &flags);
 
                bcount -= count;
@@ -291,6 +275,7 @@ static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
        rq->cmd_type = REQ_TYPE_SPECIAL;
        rq->cmd_flags |= REQ_PREEMPT;
        rq->rq_disk = floppy->disk;
+       memcpy(rq->cmd, pc->c, 12);
        ide_do_drive_cmd(drive, rq);
 }
 
@@ -354,7 +339,6 @@ static void idefloppy_init_pc(struct ide_atapi_pc *pc)
        memset(pc, 0, sizeof(*pc));
        pc->buf = pc->pc_buf;
        pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE;
-       pc->callback = ide_floppy_callback;
 }
 
 static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc)
@@ -402,7 +386,7 @@ static int idefloppy_transfer_pc(ide_drive_t *drive)
        idefloppy_floppy_t *floppy = drive->driver_data;
 
        /* Send the actual packet */
-       drive->hwif->output_data(drive, NULL, floppy->pc->c, 12);
+       drive->hwif->tp_ops->output_data(drive, NULL, floppy->pc->c, 12);
 
        /* Timeout for the packet command */
        return IDEFLOPPY_WAIT_CMD;
@@ -429,7 +413,7 @@ static ide_startstop_t idefloppy_start_pc_transfer(ide_drive_t *drive)
         * 40 and 50msec work well. idefloppy_pc_intr will not be actually
         * used until after the packet is moved in about 50 msec.
         */
-       if (pc->flags & PC_FLAG_ZIP_DRIVE) {
+       if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {
                timeout = floppy->ticks;
                expiry = &idefloppy_transfer_pc;
        } else {
@@ -474,7 +458,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
                pc->error = IDEFLOPPY_ERROR_GENERAL;
 
                floppy->failed_pc = NULL;
-               pc->callback(drive);
+               drive->pc_callback(drive);
                return ide_stopped;
        }
 
@@ -574,6 +558,8 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy,
        put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]);
        put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]);
 
+       memcpy(rq->cmd, pc->c, 12);
+
        pc->rq = rq;
        pc->b_count = cmd == READ ? 0 : rq->bio->bi_size;
        if (rq->cmd_flags & REQ_RW)
@@ -647,12 +633,6 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
                return ide_stopped;
        }
 
-       if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT)
-               pc->flags |= PC_FLAG_DRQ_INTERRUPT;
-
-       if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE)
-               pc->flags |= PC_FLAG_ZIP_DRIVE;
-
        pc->rq = rq;
 
        return idefloppy_issue_pc(drive, pc);
@@ -671,6 +651,7 @@ static int idefloppy_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
        rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
        rq->buffer = (char *) pc;
        rq->cmd_type = REQ_TYPE_SPECIAL;
+       memcpy(rq->cmd, pc->c, 12);
        error = blk_execute_rq(drive->queue, floppy->disk, rq, 0);
        blk_put_request(rq);
 
@@ -795,7 +776,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
                switch (pc.buf[desc_start + 4] & 0x03) {
                /* Clik! drive returns this instead of CAPACITY_CURRENT */
                case CAPACITY_UNFORMATTED:
-                       if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE))
+                       if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE))
                                /*
                                 * If it is not a clik drive, break out
                                 * (maintains previous driver behaviour)
@@ -841,7 +822,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
        }
 
        /* Clik! disk does not support get_flexible_disk_page */
-       if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE))
+       if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE))
                (void) ide_floppy_get_flexible_disk_page(drive);
 
        set_capacity(floppy->disk, floppy->blocks * floppy->bs_factor);
@@ -949,11 +930,12 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg)
 
                /* Else assume format_unit has finished, and we're at 0x10000 */
        } else {
+               ide_hwif_t *hwif = drive->hwif;
                unsigned long flags;
                u8 stat;
 
                local_irq_save(flags);
-               stat = ide_read_status(drive);
+               stat = hwif->tp_ops->read_status(hwif);
                local_irq_restore(flags);
 
                progress_indication = ((stat & SEEK_STAT) == 0) ? 0 : 0x10000;
@@ -1039,9 +1021,10 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy)
 
        *((u16 *) &gcw) = drive->id->config;
        floppy->pc = floppy->pc_stack;
+       drive->pc_callback = ide_floppy_callback;
 
        if (((gcw[0] & 0x60) >> 5) == 1)
-               floppy->flags |= IDEFLOPPY_FLAG_DRQ_INTERRUPT;
+               drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;
        /*
         * We used to check revisions here. At this point however I'm giving up.
         * Just assume they are all broken, its easier.
@@ -1052,7 +1035,7 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy)
         * we'll leave the limitation below for the 2.2.x tree.
         */
        if (!strncmp(drive->id->model, "IOMEGA ZIP 100 ATAPI", 20)) {
-               floppy->flags |= IDEFLOPPY_FLAG_ZIP_DRIVE;
+               drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE;
                /* This value will be visible in the /proc/ide/hdx/settings */
                floppy->ticks = IDEFLOPPY_TICKS_DELAY;
                blk_queue_max_sectors(drive->queue, 64);
@@ -1064,7 +1047,7 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy)
         */
        if (strncmp(drive->id->model, "IOMEGA Clik!", 11) == 0) {
                blk_queue_max_sectors(drive->queue, 64);
-               floppy->flags |= IDEFLOPPY_FLAG_CLIK_DRIVE;
+               drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE;
        }
 
        (void) ide_floppy_get_capacity(drive);
@@ -1153,7 +1136,7 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
        floppy->openers++;
 
        if (floppy->openers == 1) {
-               floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
+               drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
                /* Just in case */
 
                idefloppy_init_pc(&pc);
@@ -1180,14 +1163,14 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
                        ret = -EROFS;
                        goto out_put_floppy;
                }
-               floppy->flags |= IDEFLOPPY_FLAG_MEDIA_CHANGED;
+               drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED;
                /* IOMEGA Clik! drives do not support lock/unlock commands */
-               if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) {
+               if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) {
                        idefloppy_create_prevent_cmd(&pc, 1);
                        (void) idefloppy_queue_pc_tail(drive, &pc);
                }
                check_disk_change(inode->i_bdev);
-       } else if (floppy->flags & IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS) {
+       } else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) {
                ret = -EBUSY;
                goto out_put_floppy;
        }
@@ -1210,12 +1193,12 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
 
        if (floppy->openers == 1) {
                /* IOMEGA Clik! drives do not support lock/unlock commands */
-               if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) {
+               if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) {
                        idefloppy_create_prevent_cmd(&pc, 0);
                        (void) idefloppy_queue_pc_tail(drive, &pc);
                }
 
-               floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
+               drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
        }
 
        floppy->openers--;
@@ -1236,15 +1219,17 @@ static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        return 0;
 }
 
-static int ide_floppy_lockdoor(idefloppy_floppy_t *floppy,
-               struct ide_atapi_pc *pc, unsigned long arg, unsigned int cmd)
+static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc,
+                              unsigned long arg, unsigned int cmd)
 {
+       idefloppy_floppy_t *floppy = drive->driver_data;
+
        if (floppy->openers > 1)
                return -EBUSY;
 
        /* The IOMEGA Clik! Drive doesn't support this command -
         * no room for an eject mechanism */
-       if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) {
+       if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) {
                int prevent = arg ? 1 : 0;
 
                if (cmd == CDROMEJECT)
@@ -1265,16 +1250,17 @@ static int ide_floppy_lockdoor(idefloppy_floppy_t *floppy,
 static int ide_floppy_format_unit(idefloppy_floppy_t *floppy,
                                  int __user *arg)
 {
-       int blocks, length, flags, err = 0;
        struct ide_atapi_pc pc;
+       ide_drive_t *drive = floppy->drive;
+       int blocks, length, flags, err = 0;
 
        if (floppy->openers > 1) {
                /* Don't format if someone is using the disk */
-               floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
+               drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
                return -EBUSY;
        }
 
-       floppy->flags |= IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
+       drive->atapi_flags |= IDE_AFLAG_FORMAT_IN_PROGRESS;
 
        /*
         * Send ATAPI_FORMAT_UNIT to the drive.
@@ -1298,15 +1284,15 @@ static int ide_floppy_format_unit(idefloppy_floppy_t *floppy,
                goto out;
        }
 
-       (void) idefloppy_get_sfrp_bit(floppy->drive);
+       (void) idefloppy_get_sfrp_bit(drive);
        idefloppy_create_format_unit_cmd(&pc, blocks, length, flags);
 
-       if (idefloppy_queue_pc_tail(floppy->drive, &pc))
+       if (idefloppy_queue_pc_tail(drive, &pc))
                err = -EIO;
 
 out:
        if (err)
-               floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS;
+               drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
        return err;
 }
 
@@ -1325,7 +1311,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
        case CDROMEJECT:
                /* fall through */
        case CDROM_LOCKDOOR:
-               return ide_floppy_lockdoor(floppy, &pc, arg, cmd);
+               return ide_floppy_lockdoor(drive, &pc, arg, cmd);
        case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED:
                return 0;
        case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:
@@ -1366,8 +1352,8 @@ static int idefloppy_media_changed(struct gendisk *disk)
                drive->attach = 0;
                return 0;
        }
-       ret = !!(floppy->flags & IDEFLOPPY_FLAG_MEDIA_CHANGED);
-       floppy->flags &= ~IDEFLOPPY_FLAG_MEDIA_CHANGED;
+       ret = !!(drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED);
+       drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED;
        return ret;
 }
 
index 2d92214096ab9fca7b1e5f85865757366a57a97d..31d98fec775f32e1732d13970a304fa7012a7e95 100644 (file)
@@ -28,29 +28,21 @@ MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports");
 
 static ssize_t store_add(struct class *cls, const char *buf, size_t n)
 {
-       ide_hwif_t *hwif;
        unsigned int base, ctl;
-       int irq;
-       hw_regs_t hw;
-       u8 idx[] = { 0xff, 0xff, 0xff, 0xff };
+       int irq, rc;
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
        if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3)
                return -EINVAL;
 
-       hwif = ide_find_port();
-       if (hwif == NULL)
-               return -ENOENT;
-
        memset(&hw, 0, sizeof(hw));
        ide_std_init_ports(&hw, base, ctl);
        hw.irq = irq;
        hw.chipset = ide_generic;
 
-       ide_init_port_hw(hwif, &hw);
-
-       idx[0] = hwif->index;
-
-       ide_device_add(idx, NULL);
+       rc = ide_host_add(NULL, hws, NULL);
+       if (rc)
+               return rc;
 
        return n;
 };
@@ -90,18 +82,18 @@ static int __init ide_generic_sysfs_init(void)
 
 static int __init ide_generic_init(void)
 {
-       u8 idx[MAX_HWIFS];
-       int i;
+       hw_regs_t hw[MAX_HWIFS], *hws[MAX_HWIFS];
+       struct ide_host *host;
+       unsigned long io_addr;
+       int i, rc;
 
        printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" module "
                         "parameter for probing all legacy ISA IDE ports\n");
 
        for (i = 0; i < MAX_HWIFS; i++) {
-               ide_hwif_t *hwif;
-               unsigned long io_addr = ide_default_io_base(i);
-               hw_regs_t hw;
+               io_addr = ide_default_io_base(i);
 
-               idx[i] = 0xff;
+               hws[i] = NULL;
 
                if ((probe_mask & (1 << i)) && io_addr) {
                        if (!request_region(io_addr, 8, DRV_NAME)) {
@@ -119,33 +111,42 @@ static int __init ide_generic_init(void)
                                continue;
                        }
 
-                       /*
-                        * Skip probing if the corresponding
-                        * slot is already occupied.
-                        */
-                       hwif = ide_find_port();
-                       if (hwif == NULL || hwif->index != i) {
-                               idx[i] = 0xff;
-                               continue;
-                       }
-
-                       memset(&hw, 0, sizeof(hw));
-                       ide_std_init_ports(&hw, io_addr, io_addr + 0x206);
-                       hw.irq = ide_default_irq(io_addr);
-                       hw.chipset = ide_generic;
-                       ide_init_port_hw(hwif, &hw);
+                       memset(&hw[i], 0, sizeof(hw[i]));
+                       ide_std_init_ports(&hw[i], io_addr, io_addr + 0x206);
+                       hw[i].irq = ide_default_irq(io_addr);
+                       hw[i].chipset = ide_generic;
 
-                       idx[i] = i;
+                       hws[i] = &hw[i];
                }
        }
 
-       ide_device_add_all(idx, NULL);
+       host = ide_host_alloc_all(NULL, hws);
+       if (host == NULL) {
+               rc = -ENOMEM;
+               goto err;
+       }
+
+       rc = ide_host_register(host, NULL, hws);
+       if (rc)
+               goto err_free;
 
        if (ide_generic_sysfs_init())
                printk(KERN_ERR DRV_NAME ": failed to create ide_generic "
                                         "class\n");
 
        return 0;
+err_free:
+       ide_host_free(host);
+err:
+       for (i = 0; i < MAX_HWIFS; i++) {
+               if (hws[i] == NULL)
+                       continue;
+
+               io_addr = hws[i]->io_ports.data_addr;
+               release_region(io_addr + 0x206, 1);
+               release_region(io_addr, 8);
+       }
+       return rc;
 }
 
 module_init(ide_generic_init);
index 661b75a89d4dc4d2227a09d3ce69819a6132e42e..a896a283f27fdd04d7e211c2c2d81b3924d8bd9f 100644 (file)
@@ -330,7 +330,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
                        tf->error = err;
                        tf->status = stat;
 
-                       drive->hwif->tf_read(drive, task);
+                       drive->hwif->tp_ops->tf_read(drive, task);
 
                        if (task->tf_flags & IDE_TFLAG_DYN)
                                kfree(task);
@@ -381,8 +381,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
                if (err == ABRT_ERR) {
                        if (drive->select.b.lba &&
                            /* some newer drives don't support WIN_SPECIFY */
-                           hwif->INB(hwif->io_ports.command_addr) ==
-                               WIN_SPECIFY)
+                           hwif->tp_ops->read_status(hwif) == WIN_SPECIFY)
                                return ide_stopped;
                } else if ((err & BAD_CRC) == BAD_CRC) {
                        /* UDMA crc error, just retry the operation */
@@ -408,7 +407,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
                return ide_stopped;
        }
 
-       if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
+       if (hwif->tp_ops->read_status(hwif) & (BUSY_STAT | DRQ_STAT))
                rq->errors |= ERROR_RESET;
 
        if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
@@ -435,10 +434,9 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u
                /* add decoding error stuff */
        }
 
-       if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
+       if (hwif->tp_ops->read_status(hwif) & (BUSY_STAT | DRQ_STAT))
                /* force an abort */
-               hwif->OUTBSYNC(hwif, WIN_IDLEIMMEDIATE,
-                              hwif->io_ports.command_addr);
+               hwif->tp_ops->exec_command(hwif, WIN_IDLEIMMEDIATE);
 
        if (rq->errors >= ERROR_MAX) {
                ide_kill_rq(drive, rq);
@@ -712,7 +710,8 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
 #ifdef DEBUG
        printk("%s: DRIVE_CMD (null)\n", drive->name);
 #endif
-       ide_end_drive_cmd(drive, ide_read_status(drive), ide_read_error(drive));
+       ide_end_drive_cmd(drive, hwif->tp_ops->read_status(hwif),
+                         ide_read_error(drive));
 
        return ide_stopped;
 }
@@ -747,16 +746,17 @@ static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
                 * the bus may be broken enough to walk on our toes at this
                 * point.
                 */
+               ide_hwif_t *hwif = drive->hwif;
                int rc;
 #ifdef DEBUG_PM
                printk("%s: Wakeup request inited, waiting for !BSY...\n", drive->name);
 #endif
-               rc = ide_wait_not_busy(HWIF(drive), 35000);
+               rc = ide_wait_not_busy(hwif, 35000);
                if (rc)
                        printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
                SELECT_DRIVE(drive);
-               ide_set_irq(drive, 1);
-               rc = ide_wait_not_busy(HWIF(drive), 100000);
+               hwif->tp_ops->set_irq(hwif, 1);
+               rc = ide_wait_not_busy(hwif, 100000);
                if (rc)
                        printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
        }
@@ -1042,7 +1042,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
                         * quirk_list may not like intr setups/cleanups
                         */
                        if (drive->quirk_list != 1)
-                               ide_set_irq(drive, 0);
+                               hwif->tp_ops->set_irq(hwif, 0);
                }
                hwgroup->hwif = hwif;
                hwgroup->drive = drive;
@@ -1142,7 +1142,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
                printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
                (void)hwif->dma_ops->dma_end(drive);
                ret = ide_error(drive, "dma timeout error",
-                               ide_read_status(drive));
+                               hwif->tp_ops->read_status(hwif));
        } else {
                printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
                hwif->dma_ops->dma_timeout(drive);
@@ -1267,7 +1267,7 @@ void ide_timer_expiry (unsigned long data)
                                } else
                                        startstop =
                                        ide_error(drive, "irq timeout",
-                                                 ide_read_status(drive));
+                                                 hwif->tp_ops->read_status(hwif));
                        }
                        drive->service_time = jiffies - drive->service_start;
                        spin_lock_irq(&ide_lock);
@@ -1323,7 +1323,8 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
         */
        do {
                if (hwif->irq == irq) {
-                       stat = hwif->INB(hwif->io_ports.status_addr);
+                       stat = hwif->tp_ops->read_status(hwif);
+
                        if (!OK_STAT(stat, READY_STAT, BAD_STAT)) {
                                /* Try to not flood the console with msgs */
                                static unsigned long last_msgtime, count;
@@ -1413,7 +1414,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
                         * Whack the status register, just in case
                         * we have a leftover pending IRQ.
                         */
-                       (void) hwif->INB(hwif->io_ports.status_addr);
+                       (void)hwif->tp_ops->read_status(hwif);
 #endif /* CONFIG_BLK_DEV_IDEPCI */
                }
                spin_unlock_irqrestore(&ide_lock, flags);
@@ -1519,6 +1520,7 @@ EXPORT_SYMBOL(ide_do_drive_cmd);
 
 void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)
 {
+       ide_hwif_t *hwif = drive->hwif;
        ide_task_t task;
 
        memset(&task, 0, sizeof(task));
@@ -1529,9 +1531,9 @@ void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)
        task.tf.lbah    = (bcount >> 8) & 0xff;
 
        ide_tf_dump(drive->name, &task.tf);
-       ide_set_irq(drive, 1);
+       hwif->tp_ops->set_irq(hwif, 1);
        SELECT_MASK(drive, 0);
-       drive->hwif->tf_load(drive, &task);
+       hwif->tp_ops->tf_load(drive, &task);
 }
 
 EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load);
@@ -1543,9 +1545,9 @@ void ide_pad_transfer(ide_drive_t *drive, int write, int len)
 
        while (len > 0) {
                if (write)
-                       hwif->output_data(drive, NULL, buf, min(4, len));
+                       hwif->tp_ops->output_data(drive, NULL, buf, min(4, len));
                else
-                       hwif->input_data(drive, NULL, buf, min(4, len));
+                       hwif->tp_ops->input_data(drive, NULL, buf, min(4, len));
                len -= 4;
        }
 }
index 44aaec256a30d94b3d07f8a8b39a4283873c60a5..07da5fb9eaff0d760e93c5736b1b3dedb19f58de 100644 (file)
@@ -42,18 +42,6 @@ static void ide_outb (u8 val, unsigned long port)
        outb(val, port);
 }
 
-static void ide_outbsync(ide_hwif_t *hwif, u8 addr, unsigned long port)
-{
-       outb(addr, port);
-}
-
-void default_hwif_iops (ide_hwif_t *hwif)
-{
-       hwif->OUTB      = ide_outb;
-       hwif->OUTBSYNC  = ide_outbsync;
-       hwif->INB       = ide_inb;
-}
-
 /*
  *     MMIO operations, typically used for SATA controllers
  */
@@ -68,31 +56,19 @@ static void ide_mm_outb (u8 value, unsigned long port)
        writeb(value, (void __iomem *) port);
 }
 
-static void ide_mm_outbsync(ide_hwif_t *hwif, u8 value, unsigned long port)
-{
-       writeb(value, (void __iomem *) port);
-}
-
-void default_hwif_mmiops (ide_hwif_t *hwif)
-{
-       hwif->OUTB      = ide_mm_outb;
-       /* Most systems will need to override OUTBSYNC, alas however
-          this one is controller specific! */
-       hwif->OUTBSYNC  = ide_mm_outbsync;
-       hwif->INB       = ide_mm_inb;
-}
-
-EXPORT_SYMBOL(default_hwif_mmiops);
-
 void SELECT_DRIVE (ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
        const struct ide_port_ops *port_ops = hwif->port_ops;
+       ide_task_t task;
 
        if (port_ops && port_ops->selectproc)
                port_ops->selectproc(drive);
 
-       hwif->OUTB(drive->select.all, hwif->io_ports.device_addr);
+       memset(&task, 0, sizeof(task));
+       task.tf_flags = IDE_TFLAG_OUT_DEVICE;
+
+       drive->hwif->tp_ops->tf_load(drive, &task);
 }
 
 void SELECT_MASK(ide_drive_t *drive, int mask)
@@ -103,7 +79,61 @@ void SELECT_MASK(ide_drive_t *drive, int mask)
                port_ops->maskproc(drive, mask);
 }
 
-static void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
+{
+       if (hwif->host_flags & IDE_HFLAG_MMIO)
+               writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
+       else
+               outb(cmd, hwif->io_ports.command_addr);
+}
+EXPORT_SYMBOL_GPL(ide_exec_command);
+
+u8 ide_read_status(ide_hwif_t *hwif)
+{
+       if (hwif->host_flags & IDE_HFLAG_MMIO)
+               return readb((void __iomem *)hwif->io_ports.status_addr);
+       else
+               return inb(hwif->io_ports.status_addr);
+}
+EXPORT_SYMBOL_GPL(ide_read_status);
+
+u8 ide_read_altstatus(ide_hwif_t *hwif)
+{
+       if (hwif->host_flags & IDE_HFLAG_MMIO)
+               return readb((void __iomem *)hwif->io_ports.ctl_addr);
+       else
+               return inb(hwif->io_ports.ctl_addr);
+}
+EXPORT_SYMBOL_GPL(ide_read_altstatus);
+
+u8 ide_read_sff_dma_status(ide_hwif_t *hwif)
+{
+       if (hwif->host_flags & IDE_HFLAG_MMIO)
+               return readb((void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
+       else
+               return inb(hwif->dma_base + ATA_DMA_STATUS);
+}
+EXPORT_SYMBOL_GPL(ide_read_sff_dma_status);
+
+void ide_set_irq(ide_hwif_t *hwif, int on)
+{
+       u8 ctl = ATA_DEVCTL_OBS;
+
+       if (on == 4) { /* hack for SRST */
+               ctl |= 4;
+               on &= ~4;
+       }
+
+       ctl |= on ? 0 : 2;
+
+       if (hwif->host_flags & IDE_HFLAG_MMIO)
+               writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
+       else
+               outb(ctl, hwif->io_ports.ctl_addr);
+}
+EXPORT_SYMBOL_GPL(ide_set_irq);
+
+void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
 {
        ide_hwif_t *hwif = drive->hwif;
        struct ide_io_ports *io_ports = &hwif->io_ports;
@@ -155,8 +185,9 @@ static void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
                tf_outb((tf->device & HIHI) | drive->select.all,
                         io_ports->device_addr);
 }
+EXPORT_SYMBOL_GPL(ide_tf_load);
 
-static void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
 {
        ide_hwif_t *hwif = drive->hwif;
        struct ide_io_ports *io_ports = &hwif->io_ports;
@@ -188,6 +219,8 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
        /* be sure we're looking at the low order bits */
        tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
 
+       if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
+               tf->feature = tf_inb(io_ports->feature_addr);
        if (task->tf_flags & IDE_TFLAG_IN_NSECT)
                tf->nsect  = tf_inb(io_ports->nsect_addr);
        if (task->tf_flags & IDE_TFLAG_IN_LBAL)
@@ -214,6 +247,7 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
                        tf->hob_lbah    = tf_inb(io_ports->lbah_addr);
        }
 }
+EXPORT_SYMBOL_GPL(ide_tf_read);
 
 /*
  * Some localbus EIDE interfaces require a special access sequence
@@ -236,8 +270,8 @@ static void ata_vlb_sync(unsigned long port)
  * so if an odd len is specified, be sure that there's at least one
  * extra byte allocated for the buffer.
  */
-static void ata_input_data(ide_drive_t *drive, struct request *rq,
-                          void *buf, unsigned int len)
+void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf,
+                   unsigned int len)
 {
        ide_hwif_t *hwif = drive->hwif;
        struct ide_io_ports *io_ports = &hwif->io_ports;
@@ -277,12 +311,13 @@ static void ata_input_data(ide_drive_t *drive, struct request *rq,
                        insw(data_addr, buf, len / 2);
        }
 }
+EXPORT_SYMBOL_GPL(ide_input_data);
 
 /*
  * This is used for most PIO data transfers *to* the IDE interface
  */
-static void ata_output_data(ide_drive_t *drive, struct request *rq,
-                           void *buf, unsigned int len)
+void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf,
+                    unsigned int len)
 {
        ide_hwif_t *hwif = drive->hwif;
        struct ide_io_ports *io_ports = &hwif->io_ports;
@@ -320,15 +355,50 @@ static void ata_output_data(ide_drive_t *drive, struct request *rq,
                        outsw(data_addr, buf, len / 2);
        }
 }
+EXPORT_SYMBOL_GPL(ide_output_data);
+
+u8 ide_read_error(ide_drive_t *drive)
+{
+       ide_task_t task;
+
+       memset(&task, 0, sizeof(task));
+       task.tf_flags = IDE_TFLAG_IN_FEATURE;
+
+       drive->hwif->tp_ops->tf_read(drive, &task);
+
+       return task.tf.error;
+}
+EXPORT_SYMBOL_GPL(ide_read_error);
 
-void default_hwif_transport(ide_hwif_t *hwif)
+void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
 {
-       hwif->tf_load     = ide_tf_load;
-       hwif->tf_read     = ide_tf_read;
+       ide_task_t task;
+
+       memset(&task, 0, sizeof(task));
+       task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
+                       IDE_TFLAG_IN_NSECT;
 
-       hwif->input_data  = ata_input_data;
-       hwif->output_data = ata_output_data;
+       drive->hwif->tp_ops->tf_read(drive, &task);
+
+       *bcount = (task.tf.lbah << 8) | task.tf.lbam;
+       *ireason = task.tf.nsect & 3;
 }
+EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
+
+const struct ide_tp_ops default_tp_ops = {
+       .exec_command           = ide_exec_command,
+       .read_status            = ide_read_status,
+       .read_altstatus         = ide_read_altstatus,
+       .read_sff_dma_status    = ide_read_sff_dma_status,
+
+       .set_irq                = ide_set_irq,
+
+       .tf_load                = ide_tf_load,
+       .tf_read                = ide_tf_read,
+
+       .input_data             = ide_input_data,
+       .output_data            = ide_output_data,
+};
 
 void ide_fix_driveid (struct hd_driveid *id)
 {
@@ -483,10 +553,10 @@ int drive_is_ready (ide_drive_t *drive)
         * about possible isa-pnp and pci-pnp issues yet.
         */
        if (hwif->io_ports.ctl_addr)
-               stat = ide_read_altstatus(drive);
+               stat = hwif->tp_ops->read_altstatus(hwif);
        else
                /* Note: this may clear a pending IRQ!! */
-               stat = ide_read_status(drive);
+               stat = hwif->tp_ops->read_status(hwif);
 
        if (stat & BUSY_STAT)
                /* drive busy:  definitely not interrupting */
@@ -511,24 +581,26 @@ EXPORT_SYMBOL(drive_is_ready);
  */
 static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat)
 {
+       ide_hwif_t *hwif = drive->hwif;
+       const struct ide_tp_ops *tp_ops = hwif->tp_ops;
        unsigned long flags;
        int i;
        u8 stat;
 
        udelay(1);      /* spec allows drive 400ns to assert "BUSY" */
-       stat = ide_read_status(drive);
+       stat = tp_ops->read_status(hwif);
 
        if (stat & BUSY_STAT) {
                local_irq_set(flags);
                timeout += jiffies;
-               while ((stat = ide_read_status(drive)) & BUSY_STAT) {
+               while ((stat = tp_ops->read_status(hwif)) & BUSY_STAT) {
                        if (time_after(jiffies, timeout)) {
                                /*
                                 * One last read after the timeout in case
                                 * heavy interrupt load made us not make any
                                 * progress during the timeout..
                                 */
-                               stat = ide_read_status(drive);
+                               stat = tp_ops->read_status(hwif);
                                if (!(stat & BUSY_STAT))
                                        break;
 
@@ -548,7 +620,7 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti
         */
        for (i = 0; i < 10; i++) {
                udelay(1);
-               stat = ide_read_status(drive);
+               stat = tp_ops->read_status(hwif);
 
                if (OK_STAT(stat, good, bad)) {
                        *rstat = stat;
@@ -674,6 +746,7 @@ no_80w:
 int ide_driveid_update(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
+       const struct ide_tp_ops *tp_ops = hwif->tp_ops;
        struct hd_driveid *id;
        unsigned long timeout, flags;
        u8 stat;
@@ -684,9 +757,9 @@ int ide_driveid_update(ide_drive_t *drive)
         */
 
        SELECT_MASK(drive, 1);
-       ide_set_irq(drive, 0);
+       tp_ops->set_irq(hwif, 0);
        msleep(50);
-       hwif->OUTBSYNC(hwif, WIN_IDENTIFY, hwif->io_ports.command_addr);
+       tp_ops->exec_command(hwif, WIN_IDENTIFY);
        timeout = jiffies + WAIT_WORSTCASE;
        do {
                if (time_after(jiffies, timeout)) {
@@ -695,11 +768,11 @@ int ide_driveid_update(ide_drive_t *drive)
                }
 
                msleep(50);     /* give drive a breather */
-               stat = ide_read_altstatus(drive);
+               stat = tp_ops->read_altstatus(hwif);
        } while (stat & BUSY_STAT);
 
        msleep(50);     /* wait for IRQ and DRQ_STAT */
-       stat = ide_read_status(drive);
+       stat = tp_ops->read_status(hwif);
 
        if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) {
                SELECT_MASK(drive, 0);
@@ -713,8 +786,8 @@ int ide_driveid_update(ide_drive_t *drive)
                local_irq_restore(flags);
                return 0;
        }
-       hwif->input_data(drive, NULL, id, SECTOR_SIZE);
-       (void)ide_read_status(drive);   /* clear drive IRQ */
+       tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
+       (void)tp_ops->read_status(hwif);        /* clear drive IRQ */
        local_irq_enable();
        local_irq_restore(flags);
        ide_fix_driveid(id);
@@ -735,9 +808,10 @@ int ide_driveid_update(ide_drive_t *drive)
 int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
 {
        ide_hwif_t *hwif = drive->hwif;
-       struct ide_io_ports *io_ports = &hwif->io_ports;
+       const struct ide_tp_ops *tp_ops = hwif->tp_ops;
        int error = 0;
        u8 stat;
+       ide_task_t task;
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
        if (hwif->dma_ops)      /* check if host supports DMA */
@@ -770,12 +844,19 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
        SELECT_DRIVE(drive);
        SELECT_MASK(drive, 0);
        udelay(1);
-       ide_set_irq(drive, 0);
-       hwif->OUTB(speed, io_ports->nsect_addr);
-       hwif->OUTB(SETFEATURES_XFER, io_ports->feature_addr);
-       hwif->OUTBSYNC(hwif, WIN_SETFEATURES, io_ports->command_addr);
+       tp_ops->set_irq(hwif, 0);
+
+       memset(&task, 0, sizeof(task));
+       task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT;
+       task.tf.feature = SETFEATURES_XFER;
+       task.tf.nsect   = speed;
+
+       tp_ops->tf_load(drive, &task);
+
+       tp_ops->exec_command(hwif, WIN_SETFEATURES);
+
        if (drive->quirk_list == 2)
-               ide_set_irq(drive, 1);
+               tp_ops->set_irq(hwif, 1);
 
        error = __ide_wait_stat(drive, drive->ready_stat,
                                BUSY_STAT|DRQ_STAT|ERR_STAT,
@@ -796,8 +877,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
 
  skip:
 #ifdef CONFIG_BLK_DEV_IDEDMA
-       if ((speed >= XFER_SW_DMA_0 || (hwif->host_flags & IDE_HFLAG_VDMA)) &&
-           drive->using_dma)
+       if (speed >= XFER_SW_DMA_0 && drive->using_dma)
                hwif->dma_ops->dma_host_set(drive, 1);
        else if (hwif->dma_ops) /* check if host supports DMA */
                ide_dma_off_quietly(drive);
@@ -881,7 +961,7 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
 
        spin_lock_irqsave(&ide_lock, flags);
        __ide_set_handler(drive, handler, timeout, expiry);
-       hwif->OUTBSYNC(hwif, cmd, hwif->io_ports.command_addr);
+       hwif->tp_ops->exec_command(hwif, cmd);
        /*
         * Drive takes 400nS to respond, we must avoid the IRQ being
         * serviced before that.
@@ -899,7 +979,7 @@ void ide_execute_pkt_cmd(ide_drive_t *drive)
        unsigned long flags;
 
        spin_lock_irqsave(&ide_lock, flags);
-       hwif->OUTBSYNC(hwif, WIN_PACKETCMD, hwif->io_ports.command_addr);
+       hwif->tp_ops->exec_command(hwif, WIN_PACKETCMD);
        ndelay(400);
        spin_unlock_irqrestore(&ide_lock, flags);
 }
@@ -924,12 +1004,13 @@ static ide_startstop_t do_reset1 (ide_drive_t *, int);
  */
 static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
 {
-       ide_hwgroup_t *hwgroup  = HWGROUP(drive);
+       ide_hwif_t *hwif = drive->hwif;
+       ide_hwgroup_t *hwgroup = hwif->hwgroup;
        u8 stat;
 
        SELECT_DRIVE(drive);
        udelay (10);
-       stat = ide_read_status(drive);
+       stat = hwif->tp_ops->read_status(hwif);
 
        if (OK_STAT(stat, 0, BUSY_STAT))
                printk("%s: ATAPI reset complete\n", drive->name);
@@ -975,7 +1056,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
                }
        }
 
-       tmp = ide_read_status(drive);
+       tmp = hwif->tp_ops->read_status(hwif);
 
        if (!OK_STAT(tmp, 0, BUSY_STAT)) {
                if (time_before(jiffies, hwgroup->poll_timeout)) {
@@ -1089,8 +1170,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
        ide_hwif_t *hwif;
        ide_hwgroup_t *hwgroup;
        struct ide_io_ports *io_ports;
+       const struct ide_tp_ops *tp_ops;
        const struct ide_port_ops *port_ops;
-       u8 ctl;
 
        spin_lock_irqsave(&ide_lock, flags);
        hwif = HWIF(drive);
@@ -1098,6 +1179,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
 
        io_ports = &hwif->io_ports;
 
+       tp_ops = hwif->tp_ops;
+
        /* We must not reset with running handlers */
        BUG_ON(hwgroup->handler != NULL);
 
@@ -1106,7 +1189,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
                pre_reset(drive);
                SELECT_DRIVE(drive);
                udelay (20);
-               hwif->OUTBSYNC(hwif, WIN_SRST, io_ports->command_addr);
+               tp_ops->exec_command(hwif, WIN_SRST);
                ndelay(400);
                hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
                hwgroup->polling = 1;
@@ -1135,16 +1218,15 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
         * immediate interrupt due to the edge transition it produces.
         * This single interrupt gives us a "fast poll" for drives that
         * recover from reset very quickly, saving us the first 50ms wait time.
+        *
+        * TODO: add ->softreset method and stop abusing ->set_irq
         */
        /* set SRST and nIEN */
-       hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS | 6, io_ports->ctl_addr);
+       tp_ops->set_irq(hwif, 4);
        /* more than enough time */
        udelay(10);
-       if (drive->quirk_list == 2)
-               ctl = ATA_DEVCTL_OBS;           /* clear SRST and nIEN */
-       else
-               ctl = ATA_DEVCTL_OBS | 2;       /* clear SRST, leave nIEN */
-       hwif->OUTBSYNC(hwif, ctl, io_ports->ctl_addr);
+       /* clear SRST, leave nIEN (unless device is on the quirk list) */
+       tp_ops->set_irq(hwif, drive->quirk_list == 2);
        /* more than enough time */
        udelay(10);
        hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
@@ -1189,7 +1271,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout)
                 * about locking issues (2.5 work ?).
                 */
                mdelay(1);
-               stat = hwif->INB(hwif->io_ports.status_addr);
+               stat = hwif->tp_ops->read_status(hwif);
                if ((stat & BUSY_STAT) == 0)
                        return 0;
                /*
index 13af72f09ec499571d0125ce3784cc8b26baabdd..97fefabea8b8daee5203b42114fc9c5ba4933dbd 100644 (file)
@@ -266,22 +266,11 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
 
        rate = ide_rate_filter(drive, rate);
 
+       BUG_ON(rate < XFER_PIO_0);
+
        if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
                return ide_set_pio_mode(drive, rate);
 
-       /*
-        * TODO: transfer modes 0x00-0x07 passed from the user-space are
-        * currently handled here which needs fixing (please note that such
-        * case could happen iff the transfer mode has already been set on
-        * the device by ide-proc.c::set_xfer_rate()).
-        */
-       if (rate < XFER_PIO_0) {
-               if (hwif->host_flags & IDE_HFLAG_ABUSE_SET_DMA_MODE)
-                       return ide_set_dma_mode(drive, rate);
-               else
-                       return ide_config_drive_speed(drive, rate);
-       }
-
        return ide_set_dma_mode(drive, rate);
 }
 
@@ -336,7 +325,7 @@ static void ide_dump_sector(ide_drive_t *drive)
        else
                task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE;
 
-       drive->hwif->tf_read(drive, &task);
+       drive->hwif->tp_ops->tf_read(drive, &task);
 
        if (lba48 || (tf->device & ATA_LBA))
                printk(", LBAsect=%llu",
index 03f2ef5470a3756cfac07a093110ef4dd234a9e0..bac9b392b68967dfde75c6344cc8af9c6277e79d 100644 (file)
@@ -29,9 +29,10 @@ static struct pnp_device_id idepnp_devices[] = {
 
 static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
 {
-       hw_regs_t hw;
-       ide_hwif_t *hwif;
+       struct ide_host *host;
        unsigned long base, ctl;
+       int rc;
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
        printk(KERN_INFO DRV_NAME ": generic PnP IDE interface\n");
 
@@ -59,31 +60,25 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
        hw.irq = pnp_irq(dev, 0);
        hw.chipset = ide_generic;
 
-       hwif = ide_find_port();
-       if (hwif) {
-               u8 index = hwif->index;
-               u8 idx[4] = { index, 0xff, 0xff, 0xff };
+       rc = ide_host_add(NULL, hws, &host);
+       if (rc)
+               goto out;
 
-               ide_init_port_hw(hwif, &hw);
-
-               pnp_set_drvdata(dev, hwif);
-
-               ide_device_add(idx, NULL);
-
-               return 0;
-       }
+       pnp_set_drvdata(dev, host);
 
+       return 0;
+out:
        release_region(ctl, 1);
        release_region(base, 8);
 
-       return -1;
+       return rc;
 }
 
 static void idepnp_remove(struct pnp_dev *dev)
 {
-       ide_hwif_t *hwif = pnp_get_drvdata(dev);
+       struct ide_host *host = pnp_get_drvdata(dev);
 
-       ide_unregister(hwif);
+       ide_host_remove(host);
 
        release_region(pnp_port_start(dev, 1), 1);
        release_region(pnp_port_start(dev, 0), 8);
index 235ebdb29b28a75d76ef3eaac651216c98c382ce..4aa76c45375562450dfe836d955dcddf9e27e799 100644 (file)
@@ -39,8 +39,6 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-static ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */
-
 /**
  *     generic_id              -       add a generic drive id
  *     @drive: drive to make an ID block for
@@ -126,7 +124,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
 
        id = drive->id;
        /* read 512 bytes of id info */
-       hwif->input_data(drive, NULL, id, SECTOR_SIZE);
+       hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
 
        drive->id_read = 1;
        local_irq_enable();
@@ -267,6 +265,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
 {
        ide_hwif_t *hwif = HWIF(drive);
        struct ide_io_ports *io_ports = &hwif->io_ports;
+       const struct ide_tp_ops *tp_ops = hwif->tp_ops;
        int use_altstatus = 0, rc;
        unsigned long timeout;
        u8 s = 0, a = 0;
@@ -275,8 +274,8 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
        msleep(50);
 
        if (io_ports->ctl_addr) {
-               a = ide_read_altstatus(drive);
-               s = ide_read_status(drive);
+               a = tp_ops->read_altstatus(hwif);
+               s = tp_ops->read_status(hwif);
                if ((a ^ s) & ~INDEX_STAT)
                        /* ancient Seagate drives, broken interfaces */
                        printk(KERN_INFO "%s: probing with STATUS(0x%02x) "
@@ -290,12 +289,18 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
        /* set features register for atapi
         * identify command to be sure of reply
         */
-       if ((cmd == WIN_PIDENTIFY))
-               /* disable dma & overlap */
-               hwif->OUTB(0, io_ports->feature_addr);
+       if (cmd == WIN_PIDENTIFY) {
+               ide_task_t task;
+
+               memset(&task, 0, sizeof(task));
+               /* disable DMA & overlap */
+               task.tf_flags = IDE_TFLAG_OUT_FEATURE;
+
+               tp_ops->tf_load(drive, &task);
+       }
 
        /* ask drive for ID */
-       hwif->OUTBSYNC(hwif, cmd, hwif->io_ports.command_addr);
+       tp_ops->exec_command(hwif, cmd);
 
        timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
        timeout += jiffies;
@@ -306,13 +311,13 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
                }
                /* give drive a breather */
                msleep(50);
-               s = use_altstatus ? ide_read_altstatus(drive)
-                                 : ide_read_status(drive);
+               s = use_altstatus ? tp_ops->read_altstatus(hwif)
+                                 : tp_ops->read_status(hwif);
        } while (s & BUSY_STAT);
 
        /* wait for IRQ and DRQ_STAT */
        msleep(50);
-       s = ide_read_status(drive);
+       s = tp_ops->read_status(hwif);
 
        if (OK_STAT(s, DRQ_STAT, BAD_R_STAT)) {
                unsigned long flags;
@@ -324,7 +329,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
                /* drive responded with ID */
                rc = 0;
                /* clear drive IRQ */
-               (void)ide_read_status(drive);
+               (void)tp_ops->read_status(hwif);
                local_irq_restore(flags);
        } else {
                /* drive refused ID */
@@ -346,6 +351,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
 static int try_to_identify (ide_drive_t *drive, u8 cmd)
 {
        ide_hwif_t *hwif = HWIF(drive);
+       const struct ide_tp_ops *tp_ops = hwif->tp_ops;
        int retval;
        int autoprobe = 0;
        unsigned long cookie = 0;
@@ -361,7 +367,7 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)
                        autoprobe = 1;
                        cookie = probe_irq_on();
                }
-               ide_set_irq(drive, autoprobe);
+               tp_ops->set_irq(hwif, autoprobe);
        }
 
        retval = actual_try_to_identify(drive, cmd);
@@ -369,9 +375,9 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)
        if (autoprobe) {
                int irq;
 
-               ide_set_irq(drive, 0);
+               tp_ops->set_irq(hwif, 0);
                /* clear drive IRQ */
-               (void)ide_read_status(drive);
+               (void)tp_ops->read_status(hwif);
                udelay(5);
                irq = probe_irq_off(cookie);
                if (!hwif->irq) {
@@ -396,7 +402,7 @@ static int ide_busy_sleep(ide_hwif_t *hwif)
 
        do {
                msleep(50);
-               stat = hwif->INB(hwif->io_ports.status_addr);
+               stat = hwif->tp_ops->read_status(hwif);
                if ((stat & BUSY_STAT) == 0)
                        return 0;
        } while (time_before(jiffies, timeout));
@@ -404,6 +410,18 @@ static int ide_busy_sleep(ide_hwif_t *hwif)
        return 1;
 }
 
+static u8 ide_read_device(ide_drive_t *drive)
+{
+       ide_task_t task;
+
+       memset(&task, 0, sizeof(task));
+       task.tf_flags = IDE_TFLAG_IN_DEVICE;
+
+       drive->hwif->tp_ops->tf_read(drive, &task);
+
+       return task.tf.device;
+}
+
 /**
  *     do_probe                -       probe an IDE device
  *     @drive: drive to probe
@@ -428,7 +446,7 @@ static int ide_busy_sleep(ide_hwif_t *hwif)
 static int do_probe (ide_drive_t *drive, u8 cmd)
 {
        ide_hwif_t *hwif = HWIF(drive);
-       struct ide_io_ports *io_ports = &hwif->io_ports;
+       const struct ide_tp_ops *tp_ops = hwif->tp_ops;
        int rc;
        u8 stat;
 
@@ -449,8 +467,8 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
        msleep(50);
        SELECT_DRIVE(drive);
        msleep(50);
-       if (hwif->INB(io_ports->device_addr) != drive->select.all &&
-           !drive->present) {
+
+       if (ide_read_device(drive) != drive->select.all && !drive->present) {
                if (drive->select.b.unit != 0) {
                        /* exit with drive0 selected */
                        SELECT_DRIVE(&hwif->drives[0]);
@@ -461,7 +479,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
                return 3;
        }
 
-       stat = ide_read_status(drive);
+       stat = tp_ops->read_status(hwif);
 
        if (OK_STAT(stat, READY_STAT, BUSY_STAT) ||
            drive->present || cmd == WIN_PIDENTIFY) {
@@ -471,7 +489,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
                        rc = try_to_identify(drive,cmd);
                }
 
-               stat = ide_read_status(drive);
+               stat = tp_ops->read_status(hwif);
 
                if (stat == (BUSY_STAT | READY_STAT))
                        return 4;
@@ -482,13 +500,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
                        msleep(50);
                        SELECT_DRIVE(drive);
                        msleep(50);
-                       hwif->OUTBSYNC(hwif, WIN_SRST, io_ports->command_addr);
+                       tp_ops->exec_command(hwif, WIN_SRST);
                        (void)ide_busy_sleep(hwif);
                        rc = try_to_identify(drive, cmd);
                }
 
                /* ensure drive IRQ is clear */
-               stat = ide_read_status(drive);
+               stat = tp_ops->read_status(hwif);
 
                if (rc == 1)
                        printk(KERN_ERR "%s: no response (status = 0x%02x)\n",
@@ -502,7 +520,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
                SELECT_DRIVE(&hwif->drives[0]);
                msleep(50);
                /* ensure drive irq is clear */
-               (void)ide_read_status(drive);
+               (void)tp_ops->read_status(hwif);
        }
        return rc;
 }
@@ -513,12 +531,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
 static void enable_nest (ide_drive_t *drive)
 {
        ide_hwif_t *hwif = HWIF(drive);
+       const struct ide_tp_ops *tp_ops = hwif->tp_ops;
        u8 stat;
 
        printk("%s: enabling %s -- ", hwif->name, drive->id->model);
        SELECT_DRIVE(drive);
        msleep(50);
-       hwif->OUTBSYNC(hwif, EXABYTE_ENABLE_NEST, hwif->io_ports.command_addr);
+       tp_ops->exec_command(hwif, EXABYTE_ENABLE_NEST);
 
        if (ide_busy_sleep(hwif)) {
                printk(KERN_CONT "failed (timeout)\n");
@@ -527,7 +546,7 @@ static void enable_nest (ide_drive_t *drive)
 
        msleep(50);
 
-       stat = ide_read_status(drive);
+       stat = tp_ops->read_status(hwif);
 
        if (!OK_STAT(stat, 0, BAD_STAT))
                printk(KERN_CONT "failed (status = 0x%02x)\n", stat);
@@ -619,7 +638,7 @@ static inline u8 probe_for_drive (ide_drive_t *drive)
        return drive->present;
 }
 
-static void hwif_release_dev (struct device *dev)
+static void hwif_release_dev(struct device *dev)
 {
        ide_hwif_t *hwif = container_of(dev, ide_hwif_t, gendev);
 
@@ -709,7 +728,7 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
                /* Ignore disks that we will not probe for later. */
                if (!drive->noprobe || drive->present) {
                        SELECT_DRIVE(drive);
-                       ide_set_irq(drive, 1);
+                       hwif->tp_ops->set_irq(hwif, 1);
                        mdelay(2);
                        rc = ide_wait_not_busy(hwif, 35000);
                        if (rc)
@@ -971,6 +990,45 @@ static void ide_port_setup_devices(ide_hwif_t *hwif)
        mutex_unlock(&ide_cfg_mtx);
 }
 
+static ide_hwif_t *ide_ports[MAX_HWIFS];
+
+void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
+{
+       ide_hwgroup_t *hwgroup = hwif->hwgroup;
+
+       ide_ports[hwif->index] = NULL;
+
+       spin_lock_irq(&ide_lock);
+       /*
+        * Remove us from the hwgroup, and free
+        * the hwgroup if we were the only member
+        */
+       if (hwif->next == hwif) {
+               BUG_ON(hwgroup->hwif != hwif);
+               kfree(hwgroup);
+       } else {
+               /* There is another interface in hwgroup.
+                * Unlink us, and set hwgroup->drive and ->hwif to
+                * something sane.
+                */
+               ide_hwif_t *g = hwgroup->hwif;
+
+               while (g->next != hwif)
+                       g = g->next;
+               g->next = hwif->next;
+               if (hwgroup->hwif == hwif) {
+                       /* Chose a random hwif for hwgroup->hwif.
+                        * It's guaranteed that there are no drives
+                        * left in the hwgroup.
+                        */
+                       BUG_ON(hwgroup->drive != NULL);
+                       hwgroup->hwif = g;
+               }
+               BUG_ON(hwgroup->hwif == hwif);
+       }
+       spin_unlock_irq(&ide_lock);
+}
+
 /*
  * This routine sets up the irq for an ide interface, and creates a new
  * hwgroup for the irq/hwif if none was previously assigned.
@@ -998,8 +1056,9 @@ static int init_irq (ide_hwif_t *hwif)
         * Group up with any other hwifs that share our irq(s).
         */
        for (index = 0; index < MAX_HWIFS; index++) {
-               ide_hwif_t *h = &ide_hwifs[index];
-               if (h->hwgroup) {  /* scan only initialized hwif's */
+               ide_hwif_t *h = ide_ports[index];
+
+               if (h && h->hwgroup) {  /* scan only initialized ports */
                        if (hwif->irq == h->irq) {
                                hwif->sharing_irq = h->sharing_irq = 1;
                                if (hwif->chipset != ide_pci ||
@@ -1053,6 +1112,8 @@ static int init_irq (ide_hwif_t *hwif)
                hwgroup->timer.data = (unsigned long) hwgroup;
        }
 
+       ide_ports[hwif->index] = hwif;
+
        /*
         * Allocate the irq, if not already obtained for another hwif
         */
@@ -1066,8 +1127,7 @@ static int init_irq (ide_hwif_t *hwif)
                        sa = IRQF_SHARED;
 
                if (io_ports->ctl_addr)
-                       /* clear nIEN */
-                       hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS, io_ports->ctl_addr);
+                       hwif->tp_ops->set_irq(hwif, 1);
 
                if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup))
                        goto out_unlink;
@@ -1345,6 +1405,9 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
        hwif->host_flags |= d->host_flags;
        hwif->pio_mask = d->pio_mask;
 
+       if (d->tp_ops)
+               hwif->tp_ops = d->tp_ops;
+
        /* ->set_pio_mode for DTC2278 is currently limited to port 0 */
        if (hwif->chipset != ide_dtc2278 || hwif->channel == 0)
                hwif->port_ops = d->port_ops;
@@ -1363,6 +1426,7 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
 
                if (rc < 0) {
                        printk(KERN_INFO "%s: DMA disabled\n", hwif->name);
+                       hwif->dma_base = 0;
                        hwif->swdma_mask = 0;
                        hwif->mwdma_mask = 0;
                        hwif->ultra_mask = 0;
@@ -1446,18 +1510,20 @@ static int ide_sysfs_register_port(ide_hwif_t *hwif)
        return rc;
 }
 
+static unsigned int ide_indexes;
+
 /**
- *     ide_find_port_slot      -       find free ide_hwifs[] slot
+ *     ide_find_port_slot      -       find free port slot
  *     @d: IDE port info
  *
- *     Return the new hwif.  If we are out of free slots return NULL.
+ *     Return the new port slot index or -ENOENT if we are out of free slots.
  */
 
-ide_hwif_t *ide_find_port_slot(const struct ide_port_info *d)
+static int ide_find_port_slot(const struct ide_port_info *d)
 {
-       ide_hwif_t *hwif;
-       int i;
+       int idx = -ENOENT;
        u8 bootable = (d && (d->host_flags & IDE_HFLAG_NON_BOOTABLE)) ? 0 : 1;
+       u8 i = (d && (d->host_flags & IDE_HFLAG_QD_2ND_PORT)) ? 1 : 0;;
 
        /*
         * Claim an unassigned slot.
@@ -1469,51 +1535,106 @@ ide_hwif_t *ide_find_port_slot(const struct ide_port_info *d)
         * Unless there is a bootable card that does not use the standard
         * ports 0x1f0/0x170 (the ide0/ide1 defaults).
         */
-       if (bootable) {
-               i = (d && (d->host_flags & IDE_HFLAG_QD_2ND_PORT)) ? 1 : 0;
-
-               for (; i < MAX_HWIFS; i++) {
-                       hwif = &ide_hwifs[i];
-                       if (hwif->chipset == ide_unknown)
-                               goto out_found;
-               }
+       mutex_lock(&ide_cfg_mtx);
+       if (MAX_HWIFS == 1) {
+               if (ide_indexes == 0 && i == 0)
+                       idx = 1;
        } else {
-               for (i = 2; i < MAX_HWIFS; i++) {
-                       hwif = &ide_hwifs[i];
-                       if (hwif->chipset == ide_unknown)
-                               goto out_found;
+               if (bootable) {
+                       if ((ide_indexes | i) != (1 << MAX_HWIFS) - 1)
+                               idx = ffz(ide_indexes | i);
+               } else {
+                       if ((ide_indexes | 3) != (1 << MAX_HWIFS) - 1)
+                               idx = ffz(ide_indexes | 3);
+                       else if ((ide_indexes & 3) != 3)
+                               idx = ffz(ide_indexes);
                }
-               for (i = 0; i < 2 && i < MAX_HWIFS; i++) {
-                       hwif = &ide_hwifs[i];
-                       if (hwif->chipset == ide_unknown)
-                               goto out_found;
+       }
+       if (idx >= 0)
+               ide_indexes |= (1 << idx);
+       mutex_unlock(&ide_cfg_mtx);
+
+       return idx;
+}
+
+static void ide_free_port_slot(int idx)
+{
+       mutex_lock(&ide_cfg_mtx);
+       ide_indexes &= ~(1 << idx);
+       mutex_unlock(&ide_cfg_mtx);
+}
+
+struct ide_host *ide_host_alloc_all(const struct ide_port_info *d,
+                                   hw_regs_t **hws)
+{
+       struct ide_host *host;
+       int i;
+
+       host = kzalloc(sizeof(*host), GFP_KERNEL);
+       if (host == NULL)
+               return NULL;
+
+       for (i = 0; i < MAX_HWIFS; i++) {
+               ide_hwif_t *hwif;
+               int idx;
+
+               if (hws[i] == NULL)
+                       continue;
+
+               hwif = kzalloc(sizeof(*hwif), GFP_KERNEL);
+               if (hwif == NULL)
+                       continue;
+
+               idx = ide_find_port_slot(d);
+               if (idx < 0) {
+                       printk(KERN_ERR "%s: no free slot for interface\n",
+                                       d ? d->name : "ide");
+                       kfree(hwif);
+                       continue;
                }
+
+               ide_init_port_data(hwif, idx);
+
+               host->ports[i] = hwif;
+               host->n_ports++;
        }
 
-       printk(KERN_ERR "%s: no free slot for interface\n",
-                       d ? d->name : "ide");
+       if (host->n_ports == 0) {
+               kfree(host);
+               return NULL;
+       }
 
-       return NULL;
+       return host;
+}
+EXPORT_SYMBOL_GPL(ide_host_alloc_all);
+
+struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
+{
+       hw_regs_t *hws_all[MAX_HWIFS];
+       int i;
 
-out_found:
-       ide_init_port_data(hwif, i);
-       return hwif;
+       for (i = 0; i < MAX_HWIFS; i++)
+               hws_all[i] = (i < 4) ? hws[i] : NULL;
+
+       return ide_host_alloc_all(d, hws_all);
 }
-EXPORT_SYMBOL_GPL(ide_find_port_slot);
+EXPORT_SYMBOL_GPL(ide_host_alloc);
 
-int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
+int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
+                     hw_regs_t **hws)
 {
        ide_hwif_t *hwif, *mate = NULL;
-       int i, rc = 0;
+       int i, j = 0;
 
        for (i = 0; i < MAX_HWIFS; i++) {
-               if (idx[i] == 0xff) {
+               hwif = host->ports[i];
+
+               if (hwif == NULL) {
                        mate = NULL;
                        continue;
                }
 
-               hwif = &ide_hwifs[idx[i]];
-
+               ide_init_port_hw(hwif, hws[i]);
                ide_port_apply_params(hwif);
 
                if (d == NULL) {
@@ -1534,10 +1655,10 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
        }
 
        for (i = 0; i < MAX_HWIFS; i++) {
-               if (idx[i] == 0xff)
-                       continue;
+               hwif = host->ports[i];
 
-               hwif = &ide_hwifs[idx[i]];
+               if (hwif == NULL)
+                       continue;
 
                if (ide_probe_port(hwif) == 0)
                        hwif->present = 1;
@@ -1551,19 +1672,20 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
        }
 
        for (i = 0; i < MAX_HWIFS; i++) {
-               if (idx[i] == 0xff)
-                       continue;
+               hwif = host->ports[i];
 
-               hwif = &ide_hwifs[idx[i]];
+               if (hwif == NULL)
+                       continue;
 
                if (hwif_init(hwif) == 0) {
                        printk(KERN_INFO "%s: failed to initialize IDE "
                                         "interface\n", hwif->name);
                        hwif->present = 0;
-                       rc = -1;
                        continue;
                }
 
+               j++;
+
                if (hwif->present)
                        ide_port_setup_devices(hwif);
 
@@ -1574,10 +1696,10 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
        }
 
        for (i = 0; i < MAX_HWIFS; i++) {
-               if (idx[i] == 0xff)
-                       continue;
+               hwif = host->ports[i];
 
-               hwif = &ide_hwifs[idx[i]];
+               if (hwif == NULL)
+                       continue;
 
                if (hwif->chipset == ide_unknown)
                        hwif->chipset = ide_generic;
@@ -1587,10 +1709,10 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
        }
 
        for (i = 0; i < MAX_HWIFS; i++) {
-               if (idx[i] == 0xff)
-                       continue;
+               hwif = host->ports[i];
 
-               hwif = &ide_hwifs[idx[i]];
+               if (hwif == NULL)
+                       continue;
 
                ide_sysfs_register_port(hwif);
                ide_proc_register_port(hwif);
@@ -1599,21 +1721,64 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
                        ide_proc_port_register_devices(hwif);
        }
 
-       return rc;
+       return j ? 0 : -1;
 }
-EXPORT_SYMBOL_GPL(ide_device_add_all);
+EXPORT_SYMBOL_GPL(ide_host_register);
 
-int ide_device_add(u8 idx[4], const struct ide_port_info *d)
+int ide_host_add(const struct ide_port_info *d, hw_regs_t **hws,
+                struct ide_host **hostp)
 {
-       u8 idx_all[MAX_HWIFS];
+       struct ide_host *host;
+       int rc;
+
+       host = ide_host_alloc(d, hws);
+       if (host == NULL)
+               return -ENOMEM;
+
+       rc = ide_host_register(host, d, hws);
+       if (rc) {
+               ide_host_free(host);
+               return rc;
+       }
+
+       if (hostp)
+               *hostp = host;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ide_host_add);
+
+void ide_host_free(struct ide_host *host)
+{
+       ide_hwif_t *hwif;
        int i;
 
-       for (i = 0; i < MAX_HWIFS; i++)
-               idx_all[i] = (i < 4) ? idx[i] : 0xff;
+       for (i = 0; i < MAX_HWIFS; i++) {
+               hwif = host->ports[i];
 
-       return ide_device_add_all(idx_all, d);
+               if (hwif == NULL)
+                       continue;
+
+               ide_free_port_slot(hwif->index);
+               kfree(hwif);
+       }
+
+       kfree(host);
 }
-EXPORT_SYMBOL_GPL(ide_device_add);
+EXPORT_SYMBOL_GPL(ide_host_free);
+
+void ide_host_remove(struct ide_host *host)
+{
+       int i;
+
+       for (i = 0; i < MAX_HWIFS; i++) {
+               if (host->ports[i])
+                       ide_unregister(host->ports[i]);
+       }
+
+       ide_host_free(host);
+}
+EXPORT_SYMBOL_GPL(ide_host_remove);
 
 void ide_port_scan(ide_hwif_t *hwif)
 {
@@ -1634,11 +1799,10 @@ void ide_port_scan(ide_hwif_t *hwif)
 }
 EXPORT_SYMBOL_GPL(ide_port_scan);
 
-static void ide_legacy_init_one(u8 *idx, hw_regs_t *hw, u8 port_no,
-                               const struct ide_port_info *d,
+static void ide_legacy_init_one(hw_regs_t **hws, hw_regs_t *hw,
+                               u8 port_no, const struct ide_port_info *d,
                                unsigned long config)
 {
-       ide_hwif_t *hwif;
        unsigned long base, ctl;
        int irq;
 
@@ -1668,33 +1832,25 @@ static void ide_legacy_init_one(u8 *idx, hw_regs_t *hw, u8 port_no,
        ide_std_init_ports(hw, base, ctl);
        hw->irq = irq;
        hw->chipset = d->chipset;
+       hw->config = config;
 
-       hwif = ide_find_port_slot(d);
-       if (hwif) {
-               ide_init_port_hw(hwif, hw);
-               if (config)
-                       hwif->config_data = config;
-               idx[port_no] = hwif->index;
-       }
+       hws[port_no] = hw;
 }
 
 int ide_legacy_device_add(const struct ide_port_info *d, unsigned long config)
 {
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-       hw_regs_t hw[2];
+       hw_regs_t hw[2], *hws[] = { NULL, NULL, NULL, NULL };
 
        memset(&hw, 0, sizeof(hw));
 
        if ((d->host_flags & IDE_HFLAG_QD_2ND_PORT) == 0)
-               ide_legacy_init_one(idx, &hw[0], 0, d, config);
-       ide_legacy_init_one(idx, &hw[1], 1, d, config);
+               ide_legacy_init_one(hws, &hw[0], 0, d, config);
+       ide_legacy_init_one(hws, &hw[1], 1, d, config);
 
-       if (idx[0] == 0xff && idx[1] == 0xff &&
+       if (hws[0] == NULL && hws[1] == NULL &&
            (d->host_flags & IDE_HFLAG_SINGLE))
                return -ENOENT;
 
-       ide_device_add(idx, d);
-
-       return 0;
+       return ide_host_add(d, hws, NULL);
 }
 EXPORT_SYMBOL_GPL(ide_legacy_device_add);
index 8af88bf0969bde8bf41926e1e5834deed20022f6..151c91e933dab156adb2606f4a55384fc4866ad0 100644 (file)
@@ -345,7 +345,7 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
        ide_task_t task;
        int err;
 
-       if (arg < 0 || arg > 70)
+       if (arg < XFER_PIO_0 || arg > XFER_UDMA_6)
                return -EINVAL;
 
        memset(&task, 0, sizeof(task));
@@ -357,7 +357,7 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
 
        err = ide_no_data_taskfile(drive, &task);
 
-       if (!err && arg) {
+       if (!err) {
                ide_set_xfer_rate(drive, (u8) arg);
                ide_driveid_update(drive);
        }
index b711ab96e28751c053c105a05371ba073808d0fe..6962ca4891a134517774fa9dbf7ec533ee938b5b 100644 (file)
@@ -195,23 +195,6 @@ enum {
 #define IDETAPE_BLOCK_DESCRIPTOR       0
 #define IDETAPE_CAPABILITIES_PAGE      0x2a
 
-/* Tape flag bits values. */
-enum {
-       IDETAPE_FLAG_IGNORE_DSC         = (1 << 0),
-       /* 0 When the tape position is unknown */
-       IDETAPE_FLAG_ADDRESS_VALID      = (1 << 1),
-       /* Device already opened */
-       IDETAPE_FLAG_BUSY               = (1 << 2),
-       /* Attempt to auto-detect the current user block size */
-       IDETAPE_FLAG_DETECT_BS          = (1 << 3),
-       /* Currently on a filemark */
-       IDETAPE_FLAG_FILEMARK           = (1 << 4),
-       /* DRQ interrupt device */
-       IDETAPE_FLAG_DRQ_INTERRUPT      = (1 << 5),
-       /* 0 = no tape is loaded, so we don't rewind after ejecting */
-       IDETAPE_FLAG_MEDIUM_PRESENT     = (1 << 6),
-};
-
 /*
  * Most of our global data which we need to save even as we leave the driver due
  * to an interrupt or a timer event is stored in the struct defined below.
@@ -312,8 +295,6 @@ typedef struct ide_tape_obj {
        /* Wasted space in each stage */
        int excess_bh_size;
 
-       /* Status/Action flags: long for set_bit */
-       unsigned long flags;
        /* protects the ide-tape queue */
        spinlock_t lock;
 
@@ -398,7 +379,7 @@ static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
                count = min(
                        (unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
                        bcount);
-               drive->hwif->input_data(drive, NULL, bh->b_data +
+               drive->hwif->tp_ops->input_data(drive, NULL, bh->b_data +
                                        atomic_read(&bh->b_count), count);
                bcount -= count;
                atomic_add(count, &bh->b_count);
@@ -424,7 +405,7 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
                        return;
                }
                count = min((unsigned int)pc->b_count, (unsigned int)bcount);
-               drive->hwif->output_data(drive, NULL, pc->b_data, count);
+               drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count);
                bcount -= count;
                pc->b_data += count;
                pc->b_count -= count;
@@ -585,7 +566,6 @@ static void ide_tape_kfree_buffer(idetape_tape_t *tape)
                bh = bh->b_reqnext;
                kfree(prev_bh);
        }
-       kfree(tape->merge_bh);
 }
 
 static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
@@ -665,7 +645,7 @@ static void ide_tape_callback(ide_drive_t *drive)
                if (readpos[0] & 0x4) {
                        printk(KERN_INFO "ide-tape: Block location is unknown"
                                         "to the tape\n");
-                       clear_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags);
+                       clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
                        uptodate = 0;
                } else {
                        debug_log(DBG_SENSE, "Block Location - %u\n",
@@ -673,7 +653,7 @@ static void ide_tape_callback(ide_drive_t *drive)
 
                        tape->partition = readpos[1];
                        tape->first_frame = be32_to_cpu(*(u32 *)&readpos[4]);
-                       set_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags);
+                       set_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
                }
        }
 
@@ -690,7 +670,6 @@ static void idetape_init_pc(struct ide_atapi_pc *pc)
        pc->buf_size = IDETAPE_PC_BUFFER_SIZE;
        pc->bh = NULL;
        pc->b_data = NULL;
-       pc->callback = ide_tape_callback;
 }
 
 static void idetape_create_request_sense_cmd(struct ide_atapi_pc *pc)
@@ -705,7 +684,7 @@ static void idetape_init_rq(struct request *rq, u8 cmd)
 {
        blk_rq_init(NULL, rq);
        rq->cmd_type = REQ_TYPE_SPECIAL;
-       rq->cmd[0] = cmd;
+       rq->cmd[13] = cmd;
 }
 
 /*
@@ -732,6 +711,7 @@ static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
        rq->cmd_flags |= REQ_PREEMPT;
        rq->buffer = (char *) pc;
        rq->rq_disk = tape->disk;
+       memcpy(rq->cmd, pc->c, 12);
        ide_do_drive_cmd(drive, rq);
 }
 
@@ -742,7 +722,6 @@ static void idetape_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc,
  */
 static void idetape_retry_pc(ide_drive_t *drive)
 {
-       idetape_tape_t *tape = drive->driver_data;
        struct ide_atapi_pc *pc;
        struct request *rq;
 
@@ -750,7 +729,7 @@ static void idetape_retry_pc(ide_drive_t *drive)
        pc = idetape_next_pc_storage(drive);
        rq = idetape_next_rq_storage(drive);
        idetape_create_request_sense_cmd(pc);
-       set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags);
+       set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
        idetape_queue_pc_head(drive, pc, rq);
 }
 
@@ -887,7 +866,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
                        pc->error = IDETAPE_ERROR_GENERAL;
                }
                tape->failed_pc = NULL;
-               pc->callback(drive);
+               drive->pc_callback(drive);
                return ide_stopped;
        }
        debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]);
@@ -927,11 +906,12 @@ static void idetape_create_mode_sense_cmd(struct ide_atapi_pc *pc, u8 page_code)
 
 static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
 {
+       ide_hwif_t *hwif = drive->hwif;
        idetape_tape_t *tape = drive->driver_data;
        struct ide_atapi_pc *pc = tape->pc;
        u8 stat;
 
-       stat = ide_read_status(drive);
+       stat = hwif->tp_ops->read_status(hwif);
 
        if (stat & SEEK_STAT) {
                if (stat & ERR_STAT) {
@@ -948,14 +928,17 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
                pc->error = IDETAPE_ERROR_GENERAL;
                tape->failed_pc = NULL;
        }
-       pc->callback(drive);
+       drive->pc_callback(drive);
        return ide_stopped;
 }
 
 static void ide_tape_create_rw_cmd(idetape_tape_t *tape,
-               struct ide_atapi_pc *pc, unsigned int length,
-               struct idetape_bh *bh, u8 opcode)
+                                  struct ide_atapi_pc *pc, struct request *rq,
+                                  u8 opcode)
 {
+       struct idetape_bh *bh = (struct idetape_bh *)rq->special;
+       unsigned int length = rq->current_nr_sectors;
+
        idetape_init_pc(pc);
        put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]);
        pc->c[1] = 1;
@@ -975,11 +958,14 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape,
                pc->b_data = bh->b_data;
                pc->b_count = atomic_read(&bh->b_count);
        }
+
+       memcpy(rq->cmd, pc->c, 12);
 }
 
 static ide_startstop_t idetape_do_request(ide_drive_t *drive,
                                          struct request *rq, sector_t block)
 {
+       ide_hwif_t *hwif = drive->hwif;
        idetape_tape_t *tape = drive->driver_data;
        struct ide_atapi_pc *pc = NULL;
        struct request *postponed_rq = tape->postponed_rq;
@@ -1017,17 +1003,17 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
         * If the tape is still busy, postpone our request and service
         * the other device meanwhile.
         */
-       stat = ide_read_status(drive);
+       stat = hwif->tp_ops->read_status(hwif);
 
-       if (!drive->dsc_overlap && !(rq->cmd[0] & REQ_IDETAPE_PC2))
-               set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags);
+       if (!drive->dsc_overlap && !(rq->cmd[13] & REQ_IDETAPE_PC2))
+               set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
 
        if (drive->post_reset == 1) {
-               set_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags);
+               set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
                drive->post_reset = 0;
        }
 
-       if (!test_and_clear_bit(IDETAPE_FLAG_IGNORE_DSC, &tape->flags) &&
+       if (!test_and_clear_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags) &&
            (stat & SEEK_STAT) == 0) {
                if (postponed_rq == NULL) {
                        tape->dsc_polling_start = jiffies;
@@ -1036,7 +1022,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
                } else if (time_after(jiffies, tape->dsc_timeout)) {
                        printk(KERN_ERR "ide-tape: %s: DSC timeout\n",
                                tape->name);
-                       if (rq->cmd[0] & REQ_IDETAPE_PC2) {
+                       if (rq->cmd[13] & REQ_IDETAPE_PC2) {
                                idetape_media_access_finished(drive);
                                return ide_stopped;
                        } else {
@@ -1049,35 +1035,29 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
                idetape_postpone_request(drive);
                return ide_stopped;
        }
-       if (rq->cmd[0] & REQ_IDETAPE_READ) {
+       if (rq->cmd[13] & REQ_IDETAPE_READ) {
                pc = idetape_next_pc_storage(drive);
-               ide_tape_create_rw_cmd(tape, pc, rq->current_nr_sectors,
-                                       (struct idetape_bh *)rq->special,
-                                       READ_6);
+               ide_tape_create_rw_cmd(tape, pc, rq, READ_6);
                goto out;
        }
-       if (rq->cmd[0] & REQ_IDETAPE_WRITE) {
+       if (rq->cmd[13] & REQ_IDETAPE_WRITE) {
                pc = idetape_next_pc_storage(drive);
-               ide_tape_create_rw_cmd(tape, pc, rq->current_nr_sectors,
-                                        (struct idetape_bh *)rq->special,
-                                        WRITE_6);
+               ide_tape_create_rw_cmd(tape, pc, rq, WRITE_6);
                goto out;
        }
-       if (rq->cmd[0] & REQ_IDETAPE_PC1) {
+       if (rq->cmd[13] & REQ_IDETAPE_PC1) {
                pc = (struct ide_atapi_pc *) rq->buffer;
-               rq->cmd[0] &= ~(REQ_IDETAPE_PC1);
-               rq->cmd[0] |= REQ_IDETAPE_PC2;
+               rq->cmd[13] &= ~(REQ_IDETAPE_PC1);
+               rq->cmd[13] |= REQ_IDETAPE_PC2;
                goto out;
        }
-       if (rq->cmd[0] & REQ_IDETAPE_PC2) {
+       if (rq->cmd[13] & REQ_IDETAPE_PC2) {
                idetape_media_access_finished(drive);
                return ide_stopped;
        }
        BUG();
-out:
-       if (test_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags))
-               pc->flags |= PC_FLAG_DRQ_INTERRUPT;
 
+out:
        return idetape_issue_pc(drive, pc);
 }
 
@@ -1281,8 +1261,9 @@ static int idetape_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc)
 
        rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
        rq->cmd_type = REQ_TYPE_SPECIAL;
-       rq->cmd[0] = REQ_IDETAPE_PC1;
+       rq->cmd[13] = REQ_IDETAPE_PC1;
        rq->buffer = (char *)pc;
+       memcpy(rq->cmd, pc->c, 12);
        error = blk_execute_rq(drive->queue, tape->disk, rq, 0);
        blk_put_request(rq);
        return error;
@@ -1304,7 +1285,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
        int load_attempted = 0;
 
        /* Wait for the tape to become ready */
-       set_bit(IDETAPE_FLAG_MEDIUM_PRESENT, &tape->flags);
+       set_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags);
        timeout += jiffies;
        while (time_before(jiffies, timeout)) {
                idetape_create_test_unit_ready_cmd(&pc);
@@ -1397,7 +1378,7 @@ static void __ide_tape_discard_merge_buffer(ide_drive_t *drive)
        if (tape->chrdev_dir != IDETAPE_DIR_READ)
                return;
 
-       clear_bit(IDETAPE_FLAG_FILEMARK, &tape->flags);
+       clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags);
        tape->merge_bh_size = 0;
        if (tape->merge_bh != NULL) {
                ide_tape_kfree_buffer(tape);
@@ -1465,7 +1446,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
 
        rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
        rq->cmd_type = REQ_TYPE_SPECIAL;
-       rq->cmd[0] = cmd;
+       rq->cmd[13] = cmd;
        rq->rq_disk = tape->disk;
        rq->special = (void *)bh;
        rq->sector = tape->first_frame;
@@ -1636,7 +1617,7 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks)
        debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks);
 
        /* If we are at a filemark, return a read length of 0 */
-       if (test_bit(IDETAPE_FLAG_FILEMARK, &tape->flags))
+       if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags))
                return 0;
 
        idetape_init_read(drive);
@@ -1746,7 +1727,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
 
        if (tape->chrdev_dir == IDETAPE_DIR_READ) {
                tape->merge_bh_size = 0;
-               if (test_and_clear_bit(IDETAPE_FLAG_FILEMARK, &tape->flags))
+               if (test_and_clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags))
                        ++count;
                ide_tape_discard_merge_buffer(drive, 0);
        }
@@ -1801,7 +1782,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
        debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count);
 
        if (tape->chrdev_dir != IDETAPE_DIR_READ) {
-               if (test_bit(IDETAPE_FLAG_DETECT_BS, &tape->flags))
+               if (test_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags))
                        if (count > tape->blk_size &&
                            (count % tape->blk_size) == 0)
                                tape->user_bs_factor = count / tape->blk_size;
@@ -1841,7 +1822,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
                tape->merge_bh_size = bytes_read-temp;
        }
 finish:
-       if (!actually_read && test_bit(IDETAPE_FLAG_FILEMARK, &tape->flags)) {
+       if (!actually_read && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) {
                debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name);
 
                idetape_space_over_filemarks(drive, MTFSF, 1);
@@ -2027,7 +2008,7 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
                                              !IDETAPE_LU_LOAD_MASK);
                retval = idetape_queue_pc_tail(drive, &pc);
                if (!retval)
-                       clear_bit(IDETAPE_FLAG_MEDIUM_PRESENT, &tape->flags);
+                       clear_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags);
                return retval;
        case MTNOP:
                ide_tape_discard_merge_buffer(drive, 0);
@@ -2050,9 +2031,9 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
                            mt_count % tape->blk_size)
                                return -EIO;
                        tape->user_bs_factor = mt_count / tape->blk_size;
-                       clear_bit(IDETAPE_FLAG_DETECT_BS, &tape->flags);
+                       clear_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags);
                } else
-                       set_bit(IDETAPE_FLAG_DETECT_BS, &tape->flags);
+                       set_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags);
                return 0;
        case MTSEEK:
                ide_tape_discard_merge_buffer(drive, 0);
@@ -2202,20 +2183,20 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
 
        filp->private_data = tape;
 
-       if (test_and_set_bit(IDETAPE_FLAG_BUSY, &tape->flags)) {
+       if (test_and_set_bit(IDE_AFLAG_BUSY, &drive->atapi_flags)) {
                retval = -EBUSY;
                goto out_put_tape;
        }
 
        retval = idetape_wait_ready(drive, 60 * HZ);
        if (retval) {
-               clear_bit(IDETAPE_FLAG_BUSY, &tape->flags);
+               clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags);
                printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name);
                goto out_put_tape;
        }
 
        idetape_read_position(drive);
-       if (!test_bit(IDETAPE_FLAG_ADDRESS_VALID, &tape->flags))
+       if (!test_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags))
                (void)idetape_rewind_tape(drive);
 
        /* Read block size and write protect status from drive. */
@@ -2231,7 +2212,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
        if (tape->write_prot) {
                if ((filp->f_flags & O_ACCMODE) == O_WRONLY ||
                    (filp->f_flags & O_ACCMODE) == O_RDWR) {
-                       clear_bit(IDETAPE_FLAG_BUSY, &tape->flags);
+                       clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags);
                        retval = -EROFS;
                        goto out_put_tape;
                }
@@ -2291,7 +2272,7 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
                        ide_tape_discard_merge_buffer(drive, 1);
        }
 
-       if (minor < 128 && test_bit(IDETAPE_FLAG_MEDIUM_PRESENT, &tape->flags))
+       if (minor < 128 && test_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags))
                (void) idetape_rewind_tape(drive);
        if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
                if (tape->door_locked == DOOR_LOCKED) {
@@ -2301,7 +2282,7 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
                        }
                }
        }
-       clear_bit(IDETAPE_FLAG_BUSY, &tape->flags);
+       clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags);
        ide_tape_put(tape);
        unlock_kernel();
        return 0;
@@ -2464,6 +2445,8 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
        u8 gcw[2];
        u16 *ctl = (u16 *)&tape->caps[12];
 
+       drive->pc_callback = ide_tape_callback;
+
        spin_lock_init(&tape->lock);
        drive->dsc_overlap = 1;
        if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) {
@@ -2484,7 +2467,7 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
 
        /* Command packet DRQ type */
        if (((gcw[0] & 0x60) >> 5) == 1)
-               set_bit(IDETAPE_FLAG_DRQ_INTERRUPT, &tape->flags);
+               set_bit(IDE_AFLAG_DRQ_INTERRUPT, &drive->atapi_flags);
 
        idetape_get_inquiry_results(drive);
        idetape_get_mode_sense_results(drive);
@@ -2697,10 +2680,12 @@ static int ide_tape_probe(ide_drive_t *drive)
 
        idetape_setup(drive, tape, minor);
 
-       device_create(idetape_sysfs_class, &drive->gendev,
-                     MKDEV(IDETAPE_MAJOR, minor), "%s", tape->name);
-       device_create(idetape_sysfs_class, &drive->gendev,
-                       MKDEV(IDETAPE_MAJOR, minor + 128), "n%s", tape->name);
+       device_create_drvdata(idetape_sysfs_class, &drive->gendev,
+                             MKDEV(IDETAPE_MAJOR, minor), NULL,
+                             "%s", tape->name);
+       device_create_drvdata(idetape_sysfs_class, &drive->gendev,
+                             MKDEV(IDETAPE_MAJOR, minor + 128), NULL,
+                             "n%s", tape->name);
 
        g->fops = &idetape_block_ops;
        ide_register_region(g);
index 1fbdb746dc88a761a7edf9a66d49e7f68e66b179..aeddbbd69e862e6526ee25d7a83e6143e1c5468f 100644 (file)
@@ -64,6 +64,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
        ide_hwif_t *hwif        = HWIF(drive);
        struct ide_taskfile *tf = &task->tf;
        ide_handler_t *handler = NULL;
+       const struct ide_tp_ops *tp_ops = hwif->tp_ops;
        const struct ide_dma_ops *dma_ops = hwif->dma_ops;
 
        if (task->data_phase == TASKFILE_MULTI_IN ||
@@ -80,15 +81,15 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
 
        if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
                ide_tf_dump(drive->name, tf);
-               ide_set_irq(drive, 1);
+               tp_ops->set_irq(hwif, 1);
                SELECT_MASK(drive, 0);
-               hwif->tf_load(drive, task);
+               tp_ops->tf_load(drive, task);
        }
 
        switch (task->data_phase) {
        case TASKFILE_MULTI_OUT:
        case TASKFILE_OUT:
-               hwif->OUTBSYNC(hwif, tf->command, hwif->io_ports.command_addr);
+               tp_ops->exec_command(hwif, tf->command);
                ndelay(400);    /* FIXME */
                return pre_task_out_intr(drive, task->rq);
        case TASKFILE_MULTI_IN:
@@ -124,7 +125,8 @@ EXPORT_SYMBOL_GPL(do_rw_taskfile);
  */
 static ide_startstop_t set_multmode_intr(ide_drive_t *drive)
 {
-       u8 stat = ide_read_status(drive);
+       ide_hwif_t *hwif = drive->hwif;
+       u8 stat = hwif->tp_ops->read_status(hwif);
 
        if (OK_STAT(stat, READY_STAT, BAD_STAT))
                drive->mult_count = drive->mult_req;
@@ -141,11 +143,16 @@ static ide_startstop_t set_multmode_intr(ide_drive_t *drive)
  */
 static ide_startstop_t set_geometry_intr(ide_drive_t *drive)
 {
+       ide_hwif_t *hwif = drive->hwif;
        int retries = 5;
        u8 stat;
 
-       while (((stat = ide_read_status(drive)) & BUSY_STAT) && retries--)
+       while (1) {
+               stat = hwif->tp_ops->read_status(hwif);
+               if ((stat & BUSY_STAT) == 0 || retries-- == 0)
+                       break;
                udelay(10);
+       };
 
        if (OK_STAT(stat, READY_STAT, BAD_STAT))
                return ide_stopped;
@@ -162,7 +169,8 @@ static ide_startstop_t set_geometry_intr(ide_drive_t *drive)
  */
 static ide_startstop_t recal_intr(ide_drive_t *drive)
 {
-       u8 stat = ide_read_status(drive);
+       ide_hwif_t *hwif = drive->hwif;
+       u8 stat = hwif->tp_ops->read_status(hwif);
 
        if (!OK_STAT(stat, READY_STAT, BAD_STAT))
                return ide_error(drive, "recal_intr", stat);
@@ -174,11 +182,12 @@ static ide_startstop_t recal_intr(ide_drive_t *drive)
  */
 static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
 {
-       ide_task_t *args        = HWGROUP(drive)->rq->special;
+       ide_hwif_t *hwif = drive->hwif;
+       ide_task_t *args = hwif->hwgroup->rq->special;
        u8 stat;
 
        local_irq_enable_in_hardirq();
-       stat = ide_read_status(drive);
+       stat = hwif->tp_ops->read_status(hwif);
 
        if (!OK_STAT(stat, READY_STAT, BAD_STAT))
                return ide_error(drive, "task_no_data_intr", stat);
@@ -192,6 +201,7 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
 
 static u8 wait_drive_not_busy(ide_drive_t *drive)
 {
+       ide_hwif_t *hwif = drive->hwif;
        int retries;
        u8 stat;
 
@@ -200,7 +210,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
         * take up to 6 ms on some ATAPI devices, so we will wait max 10 ms.
         */
        for (retries = 0; retries < 1000; retries++) {
-               stat = ide_read_status(drive);
+               stat = hwif->tp_ops->read_status(hwif);
 
                if (stat & BUSY_STAT)
                        udelay(10);
@@ -255,9 +265,9 @@ static void ide_pio_sector(ide_drive_t *drive, struct request *rq,
 
        /* do the actual data transfer */
        if (write)
-               hwif->output_data(drive, rq, buf, SECTOR_SIZE);
+               hwif->tp_ops->output_data(drive, rq, buf, SECTOR_SIZE);
        else
-               hwif->input_data(drive, rq, buf, SECTOR_SIZE);
+               hwif->tp_ops->input_data(drive, rq, buf, SECTOR_SIZE);
 
        kunmap_atomic(buf, KM_BIO_SRC_IRQ);
 #ifdef CONFIG_HIGHMEM
@@ -383,8 +393,8 @@ static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq
 static ide_startstop_t task_in_intr(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
-       struct request *rq = HWGROUP(drive)->rq;
-       u8 stat = ide_read_status(drive);
+       struct request *rq = hwif->hwgroup->rq;
+       u8 stat = hwif->tp_ops->read_status(hwif);
 
        /* Error? */
        if (stat & ERR_STAT)
@@ -418,7 +428,7 @@ static ide_startstop_t task_out_intr (ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
        struct request *rq = HWGROUP(drive)->rq;
-       u8 stat = ide_read_status(drive);
+       u8 stat = hwif->tp_ops->read_status(hwif);
 
        if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
                return task_error(drive, rq, __func__, stat);
index d4a6b102a77227d29b4052281704f4053700156d..60f0ca66aa93735d68f27478888cf01132457d47 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1994-1998        Linus Torvalds & authors (see below)
- *  Copyrifht (C) 2003-2005, 2007   Bartlomiej Zolnierkiewicz
+ *  Copyright (C) 2003-2005, 2007   Bartlomiej Zolnierkiewicz
  */
 
 /*
@@ -101,8 +101,7 @@ void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
 
        init_completion(&hwif->gendev_rel_comp);
 
-       default_hwif_iops(hwif);
-       default_hwif_transport(hwif);
+       hwif->tp_ops = &default_tp_ops;
 
        ide_port_init_devices_data(hwif);
 }
@@ -134,41 +133,6 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif)
        }
 }
 
-void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
-{
-       ide_hwgroup_t *hwgroup = hwif->hwgroup;
-
-       spin_lock_irq(&ide_lock);
-       /*
-        * Remove us from the hwgroup, and free
-        * the hwgroup if we were the only member
-        */
-       if (hwif->next == hwif) {
-               BUG_ON(hwgroup->hwif != hwif);
-               kfree(hwgroup);
-       } else {
-               /* There is another interface in hwgroup.
-                * Unlink us, and set hwgroup->drive and ->hwif to
-                * something sane.
-                */
-               ide_hwif_t *g = hwgroup->hwif;
-
-               while (g->next != hwif)
-                       g = g->next;
-               g->next = hwif->next;
-               if (hwgroup->hwif == hwif) {
-                       /* Chose a random hwif for hwgroup->hwif.
-                        * It's guaranteed that there are no drives
-                        * left in the hwgroup.
-                        */
-                       BUG_ON(hwgroup->drive != NULL);
-                       hwgroup->hwif = g;
-               }
-               BUG_ON(hwgroup->hwif == hwif);
-       }
-       spin_unlock_irq(&ide_lock);
-}
-
 /* Called with ide_lock held. */
 static void __ide_port_unregister_devices(ide_hwif_t *hwif)
 {
@@ -269,16 +233,9 @@ void ide_unregister(ide_hwif_t *hwif)
        if (hwif->dma_base)
                ide_release_dma_engine(hwif);
 
-       spin_lock_irq(&ide_lock);
-       /* restore hwif data to pristine status */
-       ide_init_port_data(hwif, hwif->index);
-       spin_unlock_irq(&ide_lock);
-
        mutex_unlock(&ide_cfg_mtx);
 }
 
-EXPORT_SYMBOL(ide_unregister);
-
 void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
 {
        memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports));
@@ -287,8 +244,8 @@ void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
        hwif->dev = hw->dev;
        hwif->gendev.parent = hw->parent ? hw->parent : hw->dev;
        hwif->ack_intr = hw->ack_intr;
+       hwif->config_data = hw->config;
 }
-EXPORT_SYMBOL_GPL(ide_init_port_hw);
 
 /*
  *     Locks for IDE setting functionality
index 0497e7f85b09112c5fb39c1e5901e3d4231cb6f4..7c2afa97f41775e410835d539a174d14452f75ed 100644 (file)
@@ -37,6 +37,8 @@
 #define CATWEASEL_NUM_HWIFS    3
 #define XSURF_NUM_HWIFS         2
 
+#define MAX_NUM_HWIFS          3
+
     /*
      *  Bases of the IDE interfaces (relative to the board address)
      */
@@ -148,18 +150,14 @@ static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base,
 
 static int __init buddha_init(void)
 {
-       hw_regs_t hw;
-       ide_hwif_t *hwif;
-       int i;
-
        struct zorro_dev *z = NULL;
        u_long buddha_board = 0;
        BuddhaType type;
-       int buddha_num_hwifs;
+       int buddha_num_hwifs, i;
 
        while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
                unsigned long board;
-               u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+               hw_regs_t hw[MAX_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL };
 
                if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) {
                        buddha_num_hwifs = BUDDHA_NUM_HWIFS;
@@ -221,19 +219,13 @@ fail_base2:
                                ack_intr = xsurf_ack_intr;
                        }
 
-                       buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr);
+                       buddha_setup_ports(&hw[i], base, ctl, irq_port,
+                                          ack_intr);
 
-                       hwif = ide_find_port();
-                       if (hwif) {
-                               u8 index = hwif->index;
-
-                               ide_init_port_hw(hwif, &hw);
-
-                               idx[i] = index;
-                       }
+                       hws[i] = &hw[i];
                }
 
-               ide_device_add(idx, NULL);
+               ide_host_add(NULL, hws, NULL);
        }
 
        return 0;
index 129a812bb57f5f124e4f3d7ef8f43b3356501c9f..724f95073d803df6ad53cfd23ebed54449c1402a 100644 (file)
@@ -66,6 +66,27 @@ static void falconide_output_data(ide_drive_t *drive, struct request *rq,
        outsw_swapw(data_addr, buf, (len + 1) / 2);
 }
 
+/* Atari has a byte-swapped IDE interface */
+static const struct ide_tp_ops falconide_tp_ops = {
+       .exec_command           = ide_exec_command,
+       .read_status            = ide_read_status,
+       .read_altstatus         = ide_read_altstatus,
+       .read_sff_dma_status    = ide_read_sff_dma_status,
+
+       .set_irq                = ide_set_irq,
+
+       .tf_load                = ide_tf_load,
+       .tf_read                = ide_tf_read,
+
+       .input_data             = falconide_input_data,
+       .output_data            = falconide_output_data,
+};
+
+static const struct ide_port_info falconide_port_info = {
+       .tp_ops                 = &falconide_tp_ops,
+       .host_flags             = IDE_HFLAG_NO_DMA,
+};
+
 static void __init falconide_setup_ports(hw_regs_t *hw)
 {
        int i;
@@ -91,11 +112,12 @@ static void __init falconide_setup_ports(hw_regs_t *hw)
 
 static int __init falconide_init(void)
 {
-       hw_regs_t hw;
-       ide_hwif_t *hwif;
+       struct ide_host *host;
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+       int rc;
 
        if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE))
-               return 0;
+               return -ENODEV;
 
        printk(KERN_INFO "ide: Falcon IDE controller\n");
 
@@ -106,23 +128,25 @@ static int __init falconide_init(void)
 
        falconide_setup_ports(&hw);
 
-       hwif = ide_find_port();
-       if (hwif) {
-               u8 index = hwif->index;
-               u8 idx[4] = { index, 0xff, 0xff, 0xff };
-
-               ide_init_port_hw(hwif, &hw);
+       host = ide_host_alloc(&falconide_port_info, hws);
+       if (host == NULL) {
+               rc = -ENOMEM;
+               goto err;
+       }
 
-               /* Atari has a byte-swapped IDE interface */
-               hwif->input_data  = falconide_input_data;
-               hwif->output_data = falconide_output_data;
+       ide_get_lock(NULL, NULL);
+       rc = ide_host_register(host, &falconide_port_info, hws);
+       ide_release_lock();
 
-               ide_get_lock(NULL, NULL);
-               ide_device_add(idx, NULL);
-               ide_release_lock();
-       }
+       if (rc)
+               goto err_free;
 
        return 0;
+err_free:
+       ide_host_free(host);
+err:
+       release_mem_region(ATA_HD_BASE, 0x40);
+       return rc;
 }
 
 module_init(falconide_init);
index 7e74b20202dff34fc1edfe79c1503e85bb28a13d..dd5c467d8dd0582ac454bfd8796f2332a4a777b1 100644 (file)
@@ -31,6 +31,8 @@
 #define GAYLE_BASE_4000        0xdd2020        /* A4000/A4000T */
 #define GAYLE_BASE_1200        0xda0000        /* A1200/A600 and E-Matrix 530 */
 
+#define GAYLE_IDEREG_SIZE      0x2000
+
     /*
      *  Offsets from one of the above bases
      */
 #define GAYLE_NUM_HWIFS                1
 #define GAYLE_NUM_PROBE_HWIFS  GAYLE_NUM_HWIFS
 #define GAYLE_HAS_CONTROL_REG  1
-#define GAYLE_IDEREG_SIZE      0x2000
 #else /* CONFIG_BLK_DEV_IDEDOUBLER */
 #define GAYLE_NUM_HWIFS                2
 #define GAYLE_NUM_PROBE_HWIFS  (ide_doubler ? GAYLE_NUM_HWIFS : \
                                               GAYLE_NUM_HWIFS-1)
 #define GAYLE_HAS_CONTROL_REG  (!ide_doubler)
-#define GAYLE_IDEREG_SIZE      (ide_doubler ? 0x1000 : 0x2000)
 
 static int ide_doubler;
 module_param_named(doubler, ide_doubler, bool, 0);
@@ -124,8 +124,11 @@ static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base,
 
 static int __init gayle_init(void)
 {
+    unsigned long phys_base, res_start, res_n;
+    unsigned long base, ctrlport, irqport;
+    ide_ack_intr_t *ack_intr;
     int a4000, i;
-    u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+    hw_regs_t hw[GAYLE_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL };
 
     if (!MACH_IS_AMIGA)
        return -ENODEV;
@@ -148,13 +151,6 @@ found:
 #endif
                         "");
 
-    for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) {
-       unsigned long base, ctrlport, irqport;
-       ide_ack_intr_t *ack_intr;
-       hw_regs_t hw;
-       ide_hwif_t *hwif;
-       unsigned long phys_base, res_start, res_n;
-
        if (a4000) {
            phys_base = GAYLE_BASE_4000;
            irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_4000);
@@ -168,33 +164,22 @@ found:
  * FIXME: we now have selectable modes between mmio v/s iomio
  */
 
-       phys_base += i*GAYLE_NEXT_PORT;
-
        res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1);
        res_n = GAYLE_IDEREG_SIZE;
 
        if (!request_mem_region(res_start, res_n, "IDE"))
-           continue;
+               return -EBUSY;
 
-       base = (unsigned long)ZTWO_VADDR(phys_base);
+    for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) {
+       base = (unsigned long)ZTWO_VADDR(phys_base + i * GAYLE_NEXT_PORT);
        ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0;
 
-       gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr);
-
-       hwif = ide_find_port();
-       if (hwif) {
-           u8 index = hwif->index;
+       gayle_setup_ports(&hw[i], base, ctrlport, irqport, ack_intr);
 
-           ide_init_port_hw(hwif, &hw);
-
-           idx[i] = index;
-       } else
-           release_mem_region(res_start, res_n);
+       hws[i] = &hw[i];
     }
 
-    ide_device_add(idx, NULL);
-
-    return 0;
+    return ide_host_add(NULL, hws, NULL);
 }
 
 module_init(gayle_init);
index 89c8ff0a4d085f81e89bffba2fc3ba12a89f97c2..c76d55de6996413496ddc9c8d725f3feb633c860 100644 (file)
@@ -28,10 +28,8 @@ static const struct ide_port_info ide_4drives_port_info = {
 
 static int __init ide_4drives_init(void)
 {
-       ide_hwif_t *hwif, *mate;
        unsigned long base = 0x1f0, ctl = 0x3f6;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-       hw_regs_t hw;
+       hw_regs_t hw, *hws[] = { &hw, &hw, NULL, NULL };
 
        if (probe_4drives == 0)
                return -ENODEV;
@@ -55,21 +53,7 @@ static int __init ide_4drives_init(void)
        hw.irq = 14;
        hw.chipset = ide_4drives;
 
-       hwif = ide_find_port();
-       if (hwif) {
-               ide_init_port_hw(hwif, &hw);
-               idx[0] = hwif->index;
-       }
-
-       mate = ide_find_port();
-       if (mate) {
-               ide_init_port_hw(mate, &hw);
-               idx[1] = mate->index;
-       }
-
-       ide_device_add(idx, &ide_4drives_port_info);
-
-       return 0;
+       return ide_host_add(&ide_4drives_port_info, hws, NULL);
 }
 
 module_init(ide_4drives_init);
index 27b1e0b7ecb49b8b68e18248a1b53b80982f83ce..21bfac137844f689afbeb9d094a7e0f773625e3f 100644 (file)
@@ -74,7 +74,7 @@ INT_MODULE_PARM(pc_debug, 0);
 
 typedef struct ide_info_t {
        struct pcmcia_device    *p_dev;
-       ide_hwif_t              *hwif;
+       struct ide_host         *host;
     int                ndev;
     dev_node_t node;
 } ide_info_t;
@@ -132,7 +132,7 @@ static int ide_probe(struct pcmcia_device *link)
 static void ide_detach(struct pcmcia_device *link)
 {
     ide_info_t *info = link->priv;
-    ide_hwif_t *hwif = info->hwif;
+    ide_hwif_t *hwif = info->host->ports[0];
     unsigned long data_addr, ctl_addr;
 
     DEBUG(0, "ide_detach(0x%p)\n", link);
@@ -157,13 +157,13 @@ static const struct ide_port_info idecs_port_info = {
        .host_flags             = IDE_HFLAG_NO_DMA,
 };
 
-static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl,
+static struct ide_host *idecs_register(unsigned long io, unsigned long ctl,
                                unsigned long irq, struct pcmcia_device *handle)
 {
+    struct ide_host *host;
     ide_hwif_t *hwif;
-    hw_regs_t hw;
-    int i;
-    u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+    int i, rc;
+    hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
     if (!request_region(io, 8, DRV_NAME)) {
        printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
@@ -184,30 +184,24 @@ static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl,
     hw.chipset = ide_pci;
     hw.dev = &handle->dev;
 
-    hwif = ide_find_port();
-    if (hwif == NULL)
+    rc = ide_host_add(&idecs_port_info, hws, &host);
+    if (rc)
        goto out_release;
 
-    i = hwif->index;
-
-    ide_init_port_hw(hwif, &hw);
-
-    idx[0] = i;
-
-    ide_device_add(idx, &idecs_port_info);
+    hwif = host->ports[0];
 
     if (hwif->present)
-       return hwif;
+       return host;
 
     /* retry registration in case device is still spinning up */
     for (i = 0; i < 10; i++) {
        msleep(100);
        ide_port_scan(hwif);
        if (hwif->present)
-           return hwif;
+           return host;
     }
 
-    return hwif;
+    return host;
 
 out_release:
     release_region(ctl, 1);
@@ -239,7 +233,7 @@ static int ide_config(struct pcmcia_device *link)
     cistpl_cftable_entry_t *cfg;
     int pass, last_ret = 0, last_fn = 0, is_kme = 0;
     unsigned long io_base, ctl_base;
-    ide_hwif_t *hwif;
+    struct ide_host *host;
 
     DEBUG(0, "ide_config(0x%p)\n", link);
 
@@ -334,21 +328,21 @@ static int ide_config(struct pcmcia_device *link)
     if (is_kme)
        outb(0x81, ctl_base+1);
 
-     hwif = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link);
-     if (hwif == NULL && link->io.NumPorts1 == 0x20) {
+     host = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link);
+     if (host == NULL && link->io.NumPorts1 == 0x20) {
            outb(0x02, ctl_base + 0x10);
-           hwif = idecs_register(io_base + 0x10, ctl_base + 0x10,
+           host = idecs_register(io_base + 0x10, ctl_base + 0x10,
                                  link->irq.AssignedIRQ, link);
     }
 
-    if (hwif == NULL)
+    if (host == NULL)
        goto failed;
 
     info->ndev = 1;
-    sprintf(info->node.dev_name, "hd%c", 'a' + hwif->index * 2);
-    info->node.major = hwif->major;
+    sprintf(info->node.dev_name, "hd%c", 'a' + host->ports[0]->index * 2);
+    info->node.major = host->ports[0]->major;
     info->node.minor = 0;
-    info->hwif = hwif;
+    info->host = host;
     link->dev_node = &info->node;
     printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n",
           info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10);
@@ -379,15 +373,15 @@ failed:
 static void ide_release(struct pcmcia_device *link)
 {
     ide_info_t *info = link->priv;
-    ide_hwif_t *hwif = info->hwif;
+    struct ide_host *host = info->host;
 
     DEBUG(0, "ide_release(0x%p)\n", link);
 
-    if (info->ndev) {
+    if (info->ndev)
        /* FIXME: if this fails we need to queue the cleanup somehow
           -- need to investigate the required PCMCIA magic */
-       ide_unregister(hwif);
-    }
+       ide_host_remove(host);
+
     info->ndev = 0;
 
     pcmcia_disable_device(link);
index a249562b34b52b1ddfb8401136dd5b9c062fd0f6..051b4ab0f359d033745e0a035235a656dea7be4e 100644 (file)
@@ -52,12 +52,10 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
 {
        struct resource *res_base, *res_alt, *res_irq;
        void __iomem *base, *alt_base;
-       ide_hwif_t *hwif;
        struct pata_platform_info *pdata;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-       int ret = 0;
-       int mmio = 0;
-       hw_regs_t hw;
+       struct ide_host *host;
+       int ret = 0, mmio = 0;
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
        struct ide_port_info d = platform_ide_port_info;
 
        pdata = pdev->dev.platform_data;
@@ -94,28 +92,18 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
                        res_alt->start, res_alt->end - res_alt->start + 1);
        }
 
-       hwif = ide_find_port();
-       if (!hwif) {
-               ret = -ENODEV;
-               goto out;
-       }
-
        memset(&hw, 0, sizeof(hw));
        plat_ide_setup_ports(&hw, base, alt_base, pdata, res_irq->start);
        hw.dev = &pdev->dev;
 
-       ide_init_port_hw(hwif, &hw);
-
-       if (mmio) {
+       if (mmio)
                d.host_flags |= IDE_HFLAG_MMIO;
-               default_hwif_mmiops(hwif);
-       }
 
-       idx[0] = hwif->index;
-
-       ide_device_add(idx, &d);
+       ret = ide_host_add(&d, hws, &host);
+       if (ret)
+               goto out;
 
-       platform_set_drvdata(pdev, hwif);
+       platform_set_drvdata(pdev, host);
 
        return 0;
 
@@ -125,9 +113,9 @@ out:
 
 static int __devexit plat_ide_remove(struct platform_device *pdev)
 {
-       ide_hwif_t *hwif = pdev->dev.driver_data;
+       struct ide_host *host = pdev->dev.driver_data;
 
-       ide_unregister(hwif);
+       ide_host_remove(host);
 
        return 0;
 }
index 0a6195bcfeda40681da03a0e53dfe3d769a802be..a0bb167980e745fee8be4274edc0579101de22c3 100644 (file)
@@ -91,11 +91,10 @@ static const char *mac_ide_name[] =
 
 static int __init macide_init(void)
 {
-       ide_hwif_t *hwif;
        ide_ack_intr_t *ack_intr;
        unsigned long base;
        int irq;
-       hw_regs_t hw;
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
        if (!MACH_IS_MAC)
                return -ENODEV;
@@ -125,17 +124,7 @@ static int __init macide_init(void)
 
        macide_setup_ports(&hw, base, irq, ack_intr);
 
-       hwif = ide_find_port();
-       if (hwif) {
-               u8 index = hwif->index;
-               u8 idx[4] = { index, 0xff, 0xff, 0xff };
-
-               ide_init_port_hw(hwif, &hw);
-
-               ide_device_add(idx, NULL);
-       }
-
-       return 0;
+       return ide_host_add(NULL, hws, NULL);
 }
 
 module_init(macide_init);
index 9c2b9d078f69e5bc993e5d9fc88a0b0f03d9669d..4abd8fc781979df7dea762bd6ece387a7f436509 100644 (file)
@@ -96,6 +96,27 @@ static void q40ide_output_data(ide_drive_t *drive, struct request *rq,
        outsw_swapw(data_addr, buf, (len + 1) / 2);
 }
 
+/* Q40 has a byte-swapped IDE interface */
+static const struct ide_tp_ops q40ide_tp_ops = {
+       .exec_command           = ide_exec_command,
+       .read_status            = ide_read_status,
+       .read_altstatus         = ide_read_altstatus,
+       .read_sff_dma_status    = ide_read_sff_dma_status,
+
+       .set_irq                = ide_set_irq,
+
+       .tf_load                = ide_tf_load,
+       .tf_read                = ide_tf_read,
+
+       .input_data             = q40ide_input_data,
+       .output_data            = q40ide_output_data,
+};
+
+static const struct ide_port_info q40ide_port_info = {
+       .tp_ops                 = &q40ide_tp_ops,
+       .host_flags             = IDE_HFLAG_NO_DMA,
+};
+
 /* 
  * the static array is needed to have the name reported in /proc/ioports,
  * hwif->name unfortunately isn't available yet
@@ -111,9 +132,7 @@ static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={
 static int __init q40ide_init(void)
 {
     int i;
-    ide_hwif_t *hwif;
-    const char *name;
-    u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+    hw_regs_t hw[Q40IDE_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL };
 
     if (!MACH_IS_Q40)
       return -ENODEV;
@@ -121,9 +140,8 @@ static int __init q40ide_init(void)
     printk(KERN_INFO "ide: Q40 IDE controller\n");
 
     for (i = 0; i < Q40IDE_NUM_HWIFS; i++) {
-       hw_regs_t hw;
+       const char *name = q40_ide_names[i];
 
-       name = q40_ide_names[i];
        if (!request_region(pcide_bases[i], 8, name)) {
                printk("could not reserve ports %lx-%lx for %s\n",
                       pcide_bases[i],pcide_bases[i]+8,name);
@@ -135,26 +153,13 @@ static int __init q40ide_init(void)
                release_region(pcide_bases[i], 8);
                continue;
        }
-       q40_ide_setup_ports(&hw, pcide_bases[i],
-                       NULL,
-//                     m68kide_iops,
+       q40_ide_setup_ports(&hw[i], pcide_bases[i], NULL,
                        q40ide_default_irq(pcide_bases[i]));
 
-       hwif = ide_find_port();
-       if (hwif) {
-               ide_init_port_hw(hwif, &hw);
-
-               /* Q40 has a byte-swapped IDE interface */
-               hwif->input_data  = q40ide_input_data;
-               hwif->output_data = q40ide_output_data;
-
-               idx[i] = hwif->index;
-       }
+       hws[i] = &hw[i];
     }
 
-    ide_device_add(idx, NULL);
-
-    return 0;
+    return ide_host_add(&q40ide_port_info, hws, NULL);
 }
 
 module_init(q40ide_init);
index 48d57cae63c69c267f42d08339e8ec42d13fa85e..11b7f61aae40f7a7d7ec8d29be48cd6c5ec78313 100644 (file)
@@ -519,6 +519,23 @@ static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif)
        *ata_regs = ahwif->regbase + (14 << IDE_REG_SHIFT);
 }
 
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
+static const struct ide_tp_ops au1xxx_tp_ops = {
+       .exec_command           = ide_exec_command,
+       .read_status            = ide_read_status,
+       .read_altstatus         = ide_read_altstatus,
+       .read_sff_dma_status    = ide_read_sff_dma_status,
+
+       .set_irq                = ide_set_irq,
+
+       .tf_load                = ide_tf_load,
+       .tf_read                = ide_tf_read,
+
+       .input_data             = au1xxx_input_data,
+       .output_data            = au1xxx_output_data,
+};
+#endif
+
 static const struct ide_port_ops au1xxx_port_ops = {
        .set_pio_mode           = au1xxx_set_pio_mode,
        .set_dma_mode           = auide_set_dma_mode,
@@ -526,6 +543,9 @@ static const struct ide_port_ops au1xxx_port_ops = {
 
 static const struct ide_port_info au1xxx_port_info = {
        .init_dma               = auide_ddma_init,
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
+       .tp_ops                 = &au1xxx_tp_ops,
+#endif
        .port_ops               = &au1xxx_port_ops,
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
        .dma_ops                = &au1xxx_dma_ops,
@@ -543,11 +563,10 @@ static int au_ide_probe(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        _auide_hwif *ahwif = &auide_hwif;
-       ide_hwif_t *hwif;
        struct resource *res;
+       struct ide_host *host;
        int ret = 0;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-       hw_regs_t hw;
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
 #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
        char *mode = "MWDMA2";
@@ -584,36 +603,19 @@ static int au_ide_probe(struct device *dev)
                goto out;
        }
 
-       hwif = ide_find_port();
-       if (hwif == NULL) {
-               ret = -ENOENT;
-               goto out;
-       }
-
        memset(&hw, 0, sizeof(hw));
        auide_setup_ports(&hw, ahwif);
        hw.irq = ahwif->irq;
        hw.dev = dev;
        hw.chipset = ide_au1xxx;
 
-       ide_init_port_hw(hwif, &hw);
-
-       /* If the user has selected DDMA assisted copies,
-          then set up a few local I/O function entry points 
-       */
-
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA     
-       hwif->input_data  = au1xxx_input_data;
-       hwif->output_data = au1xxx_output_data;
-#endif
-
-       auide_hwif.hwif                 = hwif;
-
-       idx[0] = hwif->index;
+       ret = ide_host_add(&au1xxx_port_info, hws, &host);
+       if (ret)
+               goto out;
 
-       ide_device_add(idx, &au1xxx_port_info);
+       auide_hwif.hwif = host->ports[0];
 
-       dev_set_drvdata(dev, hwif);
+       dev_set_drvdata(dev, host);
 
        printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
 
@@ -625,10 +627,10 @@ static int au_ide_remove(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        struct resource *res;
-       ide_hwif_t *hwif = dev_get_drvdata(dev);
+       struct ide_host *host = dev_get_drvdata(dev);
        _auide_hwif *ahwif = &auide_hwif;
 
-       ide_unregister(hwif);
+       ide_host_remove(host);
 
        iounmap((void *)ahwif->regbase);
 
index 9f1212cc4aed3e33152a1ff0c32eebf62ee0f987..badf79fc9e3a1c67c3eef99bbbce4cb9c31eb355 100644 (file)
@@ -72,12 +72,11 @@ static const struct ide_port_info swarm_port_info = {
  */
 static int __devinit swarm_ide_probe(struct device *dev)
 {
-       ide_hwif_t *hwif;
        u8 __iomem *base;
+       struct ide_host *host;
        phys_t offset, size;
-       hw_regs_t hw;
-       int i;
-       u8 idx[] = { 0xff, 0xff, 0xff, 0xff };
+       int i, rc;
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
        if (!SIBYTE_HAVE_IDE)
                return -ENODEV;
@@ -116,26 +115,17 @@ static int __devinit swarm_ide_probe(struct device *dev)
        hw.irq = K_INT_GB_IDE;
        hw.chipset = ide_generic;
 
-       hwif = ide_find_port_slot(&swarm_port_info);
-       if (hwif == NULL)
+       rc = ide_host_add(&swarm_port_info, hws, &host);
+       if (rc)
                goto err;
 
-       ide_init_port_hw(hwif, &hw);
-
-       /* Setup MMIO ops. */
-       default_hwif_mmiops(hwif);
-
-       idx[0] = hwif->index;
-
-       ide_device_add(idx, &swarm_port_info);
-
-       dev_set_drvdata(dev, hwif);
+       dev_set_drvdata(dev, host);
 
        return 0;
 err:
        release_resource(&swarm_ide_resource);
        iounmap(base);
-       return -ENOMEM;
+       return rc;
 }
 
 static struct device_driver swarm_ide_driver = {
index ae7a4329a581065dc10f1f18c83b1d5a7daedb1d..fbc43e121e6b19856f4ceb528c299d5dd682656e 100644 (file)
@@ -195,7 +195,6 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
                .host_flags     = IDE_HFLAG_SERIALIZE |
                                  IDE_HFLAG_NO_ATAPI_DMA |
                                  IDE_HFLAG_NO_DSC |
-                                 IDE_HFLAG_ABUSE_SET_DMA_MODE |
                                  IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
                .mwdma_mask     = ATA_MWDMA2,
@@ -205,7 +204,6 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
                .init_chipset   = init_chipset_aec62xx,
                .port_ops       = &atp86x_port_ops,
                .host_flags     = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_NO_AUTODMA |
-                                 IDE_HFLAG_ABUSE_SET_DMA_MODE |
                                  IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
                .mwdma_mask     = ATA_MWDMA2,
@@ -216,7 +214,6 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
                .enablebits     = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
                .port_ops       = &atp86x_port_ops,
                .host_flags     = IDE_HFLAG_NO_ATAPI_DMA |
-                                 IDE_HFLAG_ABUSE_SET_DMA_MODE |
                                  IDE_HFLAG_NON_BOOTABLE,
                .pio_mask       = ATA_PIO4,
                .mwdma_mask     = ATA_MWDMA2,
@@ -226,7 +223,6 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
                .init_chipset   = init_chipset_aec62xx,
                .port_ops       = &atp86x_port_ops,
                .host_flags     = IDE_HFLAG_NO_ATAPI_DMA |
-                                 IDE_HFLAG_ABUSE_SET_DMA_MODE |
                                  IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
                .mwdma_mask     = ATA_MWDMA2,
@@ -237,7 +233,6 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
                .enablebits     = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
                .port_ops       = &atp86x_port_ops,
                .host_flags     = IDE_HFLAG_NO_ATAPI_DMA |
-                                 IDE_HFLAG_ABUSE_SET_DMA_MODE |
                                  IDE_HFLAG_OFF_BOARD,
                .pio_mask       = ATA_PIO4,
                .mwdma_mask     = ATA_MWDMA2,
index 80d19c0eb78097d09cc822cb0ed27273563ce1cf..5ef7817ac64f852e5042f45a281ea243bcf4a802 100644 (file)
@@ -471,7 +471,15 @@ static int __devinit init_dma_ali15x3(ide_hwif_t *hwif,
        struct pci_dev *dev = to_pci_dev(hwif->dev);
        unsigned long base = ide_pci_dma_base(hwif, d);
 
-       if (base == 0 || ide_pci_set_master(dev, d->name) < 0)
+       if (base == 0)
+               return -1;
+
+       hwif->dma_base = base;
+
+       if (ide_pci_check_simplex(hwif, d) < 0)
+               return -1;
+
+       if (ide_pci_set_master(dev, d->name) < 0)
                return -1;
 
        if (!hwif->channel)
@@ -483,7 +491,7 @@ static int __devinit init_dma_ali15x3(ide_hwif_t *hwif,
        if (ide_allocate_dma_engine(hwif))
                return -1;
 
-       ide_setup_dma(hwif, base);
+       hwif->dma_ops = &sff_dma_ops;
 
        return 0;
 }
index 0bfcdd0e77b318a94691c69da0f7a6bdb8d261a6..ef7d971031eee6bad1aef03c49aedec4e6369c78 100644 (file)
@@ -218,7 +218,6 @@ static const struct ide_port_ops amd_port_ops = {
 
 #define IDE_HFLAGS_AMD \
        (IDE_HFLAG_PIO_NO_BLACKLIST | \
-        IDE_HFLAG_ABUSE_SET_DMA_MODE | \
         IDE_HFLAG_POST_SET_MODE | \
         IDE_HFLAG_IO_32BIT | \
         IDE_HFLAG_UNMASK_IRQS)
index 1ad1e23e310577c2875994fe421e969d6c61ab55..e6c62006ca1a48a2bdc2c460562f452aab58d347 100644 (file)
@@ -180,11 +180,6 @@ static u8 recovery_counts[4] = {16, 16, 16, 16}; /* Recovery count (encoded) */
 
 static DEFINE_SPINLOCK(cmd640_lock);
 
-/*
- * These are initialized to point at the devices we control
- */
-static ide_hwif_t  *cmd_hwif0, *cmd_hwif1;
-
 /*
  * Interface to access cmd640x registers
  */
@@ -717,8 +712,7 @@ static int __init cmd640x_init(void)
        int second_port_cmd640 = 0, rc;
        const char *bus_type, *port2;
        u8 b, cfr;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-       hw_regs_t hw[2];
+       hw_regs_t hw[2], *hws[] = { NULL, NULL, NULL, NULL };
 
        if (cmd640_vlb && probe_for_cmd640_vlb()) {
                bus_type = "VLB";
@@ -781,15 +775,10 @@ static int __init cmd640x_init(void)
        printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x"
                         "\n", 'a' + cmd640_chip_version - 1, bus_type, cfr);
 
-       cmd_hwif0 = ide_find_port();
-
        /*
         * Initialize data for primary port
         */
-       if (cmd_hwif0) {
-               ide_init_port_hw(cmd_hwif0, &hw[0]);
-               idx[0] = cmd_hwif0->index;
-       }
+       hws[0] = &hw[0];
 
        /*
         * Ensure compatibility by always using the slowest timings
@@ -829,13 +818,9 @@ static int __init cmd640x_init(void)
        /*
         * Initialize data for secondary cmd640 port, if enabled
         */
-       if (second_port_cmd640) {
-               cmd_hwif1 = ide_find_port();
-               if (cmd_hwif1) {
-                       ide_init_port_hw(cmd_hwif1, &hw[1]);
-                       idx[1] = cmd_hwif1->index;
-               }
-       }
+       if (second_port_cmd640)
+               hws[1] = &hw[1];
+
        printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n",
                         second_port_cmd640 ? "" : "not ", port2);
 
@@ -843,9 +828,7 @@ static int __init cmd640x_init(void)
        cmd640_dump_regs();
 #endif
 
-       ide_device_add(idx, &cmd640_port_info);
-
-       return 1;
+       return ide_host_add(&cmd640_port_info, hws, NULL);
 }
 
 module_param_named(probe_vlb, cmd640_vlb, bool, 0);
index cfa784bacf48678f712e169775a4f10293a89cc0..ce58bfcdb3c6c645c51b70321d799dfa0157524b 100644 (file)
@@ -262,7 +262,7 @@ static int cmd648_dma_test_irq(ide_drive_t *drive)
        unsigned long base      = hwif->dma_base - (hwif->channel * 8);
        u8 irq_mask             = hwif->channel ? MRDMODE_INTR_CH1 :
                                                  MRDMODE_INTR_CH0;
-       u8 dma_stat             = inb(hwif->dma_status);
+       u8 dma_stat             = inb(hwif->dma_base + ATA_DMA_STATUS);
        u8 mrdmode              = inb(base + 1);
 
 #ifdef DEBUG
@@ -286,7 +286,7 @@ static int cmd64x_dma_test_irq(ide_drive_t *drive)
        int irq_reg             = hwif->channel ? ARTTIM23 : CFR;
        u8  irq_mask            = hwif->channel ? ARTTIM23_INTR_CH1 :
                                                  CFR_INTR_CH0;
-       u8  dma_stat            = inb(hwif->dma_status);
+       u8  dma_stat            = inb(hwif->dma_base + ATA_DMA_STATUS);
        u8  irq_stat            = 0;
 
        (void) pci_read_config_byte(dev, irq_reg, &irq_stat);
@@ -317,13 +317,13 @@ static int cmd646_1_dma_end(ide_drive_t *drive)
 
        drive->waiting_for_dma = 0;
        /* get DMA status */
-       dma_stat = inb(hwif->dma_status);
+       dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
        /* read DMA command state */
-       dma_cmd = inb(hwif->dma_command);
+       dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
        /* stop DMA */
-       outb(dma_cmd & ~1, hwif->dma_command);
+       outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
        /* clear the INTR & ERROR bits */
-       outb(dma_stat | 6, hwif->dma_status);
+       outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
        /* and free any DMA resources */
        ide_destroy_dmatable(drive);
        /* verify good DMA status */
index 992b1cf8db6976be67833338a6932ba19593e4aa..b03d8ae947e6fc10c6682d8944cae1dea4f5f4f9 100644 (file)
@@ -62,8 +62,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
        struct pci_dev *pdev = to_pci_dev(hwif->dev);
        int controller = drive->dn > 1 ? 1 : 0;
 
-       /* FIXME: if DMA = 1 do we need to set the DMA bit here ? */
-
        /* 8bit CAT/CRT - 8bit command timing for channel */
        pci_write_config_byte(pdev, 0x62 + controller, 
                (cs5520_pio_clocks[pio].recovery << 4) |
@@ -89,46 +87,17 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
        cs5520_set_pio_mode(drive, 0);
 }
 
-/*
- *     We wrap the DMA activate to set the vdma flag. This is needed
- *     so that the IDE DMA layer issues PIO not DMA commands over the
- *     DMA channel
- *
- *     ATAPI is harder so disable it for now using IDE_HFLAG_NO_ATAPI_DMA
- */
-
-static void cs5520_dma_host_set(ide_drive_t *drive, int on)
-{
-       drive->vdma = on;
-       ide_dma_host_set(drive, on);
-}
-
 static const struct ide_port_ops cs5520_port_ops = {
        .set_pio_mode           = cs5520_set_pio_mode,
        .set_dma_mode           = cs5520_set_dma_mode,
 };
 
-static const struct ide_dma_ops cs5520_dma_ops = {
-       .dma_host_set           = cs5520_dma_host_set,
-       .dma_setup              = ide_dma_setup,
-       .dma_exec_cmd           = ide_dma_exec_cmd,
-       .dma_start              = ide_dma_start,
-       .dma_end                = __ide_dma_end,
-       .dma_test_irq           = ide_dma_test_irq,
-       .dma_lost_irq           = ide_dma_lost_irq,
-       .dma_timeout            = ide_dma_timeout,
-};
-
-/* FIXME: VDMA is disabled because it caused system hangs */
 #define DECLARE_CS_DEV(name_str)                               \
        {                                                       \
                .name           = name_str,                     \
                .port_ops       = &cs5520_port_ops,             \
-               .dma_ops        = &cs5520_dma_ops,              \
                .host_flags     = IDE_HFLAG_ISA_PORTS |         \
-                                 IDE_HFLAG_CS5520 |            \
-                                 IDE_HFLAG_NO_ATAPI_DMA |      \
-                                 IDE_HFLAG_ABUSE_SET_DMA_MODE, \
+                                 IDE_HFLAG_CS5520,             \
                .pio_mask       = ATA_PIO4,                     \
        }
 
@@ -146,7 +115,7 @@ static const struct ide_port_info cyrix_chipsets[] __devinitdata = {
 static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        const struct ide_port_info *d = &cyrix_chipsets[id->driver_data];
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+       hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL };
 
        ide_setup_pci_noise(dev, d);
 
@@ -168,11 +137,9 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
         *      do all the device setup for us
         */
 
-       ide_pci_setup_ports(dev, d, 14, &idx[0]);
-
-       ide_device_add(idx, d);
+       ide_pci_setup_ports(dev, d, 14, &hw[0], &hws[0]);
 
-       return 0;
+       return ide_host_add(d, hws, NULL);
 }
 
 static const struct pci_device_id cs5520_pci_tbl[] = {
index dc97c48623f3fc438fb2237d259d55eb2046d985..5404fe4f701d79cc4bc651c99548ce35da9d4c67 100644 (file)
@@ -171,8 +171,7 @@ static const struct ide_port_ops cs5535_port_ops = {
 static const struct ide_port_info cs5535_chipset __devinitdata = {
        .name           = "CS5535",
        .port_ops       = &cs5535_port_ops,
-       .host_flags     = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE |
-                         IDE_HFLAG_ABUSE_SET_DMA_MODE,
+       .host_flags     = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE,
        .pio_mask       = ATA_PIO4,
        .mwdma_mask     = ATA_MWDMA2,
        .udma_mask      = ATA_UDMA4,
index 0106e2a2df77a3ab8c42fd9092e440c3a309a9b9..f84bfb4f600f1a0ba3473c4ab7fb8275dc7093db 100644 (file)
@@ -56,11 +56,10 @@ static const struct ide_port_info delkin_cb_port_info = {
 static int __devinit
 delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
 {
+       struct ide_host *host;
        unsigned long base;
-       hw_regs_t hw;
-       ide_hwif_t *hwif = NULL;
        int i, rc;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
 
        rc = pci_enable_device(dev);
        if (rc) {
@@ -87,34 +86,26 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
        hw.dev = &dev->dev;
        hw.chipset = ide_pci;           /* this enables IRQ sharing */
 
-       hwif = ide_find_port();
-       if (hwif == NULL)
+       rc = ide_host_add(&delkin_cb_port_info, hws, &host);
+       if (rc)
                goto out_disable;
 
-       i = hwif->index;
-
-       ide_init_port_hw(hwif, &hw);
-
-       idx[0] = i;
-
-       ide_device_add(idx, &delkin_cb_port_info);
-
-       pci_set_drvdata(dev, hwif);
+       pci_set_drvdata(dev, host);
 
        return 0;
 
 out_disable:
        pci_release_regions(dev);
        pci_disable_device(dev);
-       return -ENODEV;
+       return rc;
 }
 
 static void
 delkin_cb_remove (struct pci_dev *dev)
 {
-       ide_hwif_t *hwif = pci_get_drvdata(dev);
+       struct ide_host *host = pci_get_drvdata(dev);
 
-       ide_unregister(hwif);
+       ide_host_remove(host);
 
        pci_release_regions(dev);
        pci_disable_device(dev);
index 84c36c117194cb731e24e2ea60ee7b67e2df5681..9e1d1c4741da5567509c28a671ea9e82aa410139 100644 (file)
@@ -123,7 +123,6 @@ static const struct ide_port_ops hpt34x_port_ops = {
 #define IDE_HFLAGS_HPT34X \
        (IDE_HFLAG_NO_ATAPI_DMA | \
         IDE_HFLAG_NO_DSC | \
-        IDE_HFLAG_ABUSE_SET_DMA_MODE | \
         IDE_HFLAG_NO_AUTODMA)
 
 static const struct ide_port_info hpt34x_chipsets[] __devinitdata = {
index 397c6cbe953c0e42fc8a7636b9eca36377a429b6..1f1135ce7cd6616f9626c062013168e6d5b3af9c 100644 (file)
@@ -801,9 +801,9 @@ static void hpt370_irq_timeout(ide_drive_t *drive)
        printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo & 0x1ff);
 
        /* get DMA command mode */
-       dma_cmd = inb(hwif->dma_command);
+       dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
        /* stop DMA */
-       outb(dma_cmd & ~0x1, hwif->dma_command);
+       outb(dma_cmd & ~0x1, hwif->dma_base + ATA_DMA_CMD);
        hpt370_clear_engine(drive);
 }
 
@@ -818,12 +818,12 @@ static void hpt370_dma_start(ide_drive_t *drive)
 static int hpt370_dma_end(ide_drive_t *drive)
 {
        ide_hwif_t *hwif        = HWIF(drive);
-       u8  dma_stat            = inb(hwif->dma_status);
+       u8  dma_stat            = inb(hwif->dma_base + ATA_DMA_STATUS);
 
        if (dma_stat & 0x01) {
                /* wait a little */
                udelay(20);
-               dma_stat = inb(hwif->dma_status);
+               dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
                if (dma_stat & 0x01)
                        hpt370_irq_timeout(drive);
        }
@@ -850,7 +850,7 @@ static int hpt374_dma_test_irq(ide_drive_t *drive)
                return 0;
        }
 
-       dma_stat = inb(hwif->dma_status);
+       dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
        /* return 1 if INTR asserted */
        if (dma_stat & 4)
                return 1;
@@ -1320,7 +1320,15 @@ static int __devinit init_dma_hpt366(ide_hwif_t *hwif,
        unsigned long flags, base = ide_pci_dma_base(hwif, d);
        u8 dma_old, dma_new, masterdma = 0, slavedma = 0;
 
-       if (base == 0 || ide_pci_set_master(dev, d->name) < 0)
+       if (base == 0)
+               return -1;
+
+       hwif->dma_base = base;
+
+       if (ide_pci_check_simplex(hwif, d) < 0)
+               return -1;
+
+       if (ide_pci_set_master(dev, d->name) < 0)
                return -1;
 
        dma_old = inb(base + 2);
@@ -1346,7 +1354,7 @@ static int __devinit init_dma_hpt366(ide_hwif_t *hwif,
        if (ide_allocate_dma_engine(hwif))
                return -1;
 
-       ide_setup_dma(hwif, base);
+       hwif->dma_ops = &sff_dma_ops;
 
        return 0;
 }
@@ -1401,7 +1409,6 @@ static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
 
 #define IDE_HFLAGS_HPT3XX \
        (IDE_HFLAG_NO_ATAPI_DMA | \
-        IDE_HFLAG_ABUSE_SET_DMA_MODE | \
         IDE_HFLAG_OFF_BOARD)
 
 static const struct ide_port_ops hpt3xx_port_ops = {
index 45ba71a7182fdf87a4d988a0c4eee66cb224c6d4..5cd2b32ff0ef000d61a06047bddb19f9a911c342 100644 (file)
  */
 #include <asm/superio.h>
 
-static unsigned long superio_ide_status[2];
-static unsigned long superio_ide_select[2];
-static unsigned long superio_ide_dma_status[2];
-
 #define SUPERIO_IDE_MAX_RETRIES 25
 
 /* Because of a defect in Super I/O, all reads of the PCI DMA status 
@@ -40,27 +36,28 @@ static unsigned long superio_ide_dma_status[2];
  */
 static u8 superio_ide_inb (unsigned long port)
 {
-       if (port == superio_ide_status[0] ||
-           port == superio_ide_status[1] ||
-           port == superio_ide_select[0] ||
-           port == superio_ide_select[1] ||
-           port == superio_ide_dma_status[0] ||
-           port == superio_ide_dma_status[1]) {
-               u8 tmp;
-               int retries = SUPERIO_IDE_MAX_RETRIES;
+       u8 tmp;
+       int retries = SUPERIO_IDE_MAX_RETRIES;
 
-               /* printk(" [ reading port 0x%x with retry ] ", port); */
+       /* printk(" [ reading port 0x%x with retry ] ", port); */
 
-               do {
-                       tmp = inb(port);
-                       if (tmp == 0)
-                               udelay(50);
-               } while (tmp == 0 && retries-- > 0);
+       do {
+               tmp = inb(port);
+               if (tmp == 0)
+                       udelay(50);
+       } while (tmp == 0 && retries-- > 0);
 
-               return tmp;
-       }
+       return tmp;
+}
 
-       return inb(port);
+static u8 superio_read_status(ide_hwif_t *hwif)
+{
+       return superio_ide_inb(hwif->io_ports.status_addr);
+}
+
+static u8 superio_read_sff_dma_status(ide_hwif_t *hwif)
+{
+       return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS);
 }
 
 static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
@@ -78,6 +75,8 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
        /* be sure we're looking at the low order bits */
        outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
 
+       if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
+               tf->feature = inb(io_ports->feature_addr);
        if (task->tf_flags & IDE_TFLAG_IN_NSECT)
                tf->nsect  = inb(io_ports->nsect_addr);
        if (task->tf_flags & IDE_TFLAG_IN_LBAL)
@@ -105,36 +104,32 @@ static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
        }
 }
 
-static void __devinit superio_ide_init_iops (struct hwif_s *hwif)
-{
-       struct pci_dev *pdev = to_pci_dev(hwif->dev);
-       u32 base, dmabase;
-       u8 port = hwif->channel, tmp;
+static const struct ide_tp_ops superio_tp_ops = {
+       .exec_command           = ide_exec_command,
+       .read_status            = superio_read_status,
+       .read_altstatus         = ide_read_altstatus,
+       .read_sff_dma_status    = superio_read_sff_dma_status,
 
-       base = pci_resource_start(pdev, port * 2) & ~3;
-       dmabase = pci_resource_start(pdev, 4) & ~3;
-
-       superio_ide_status[port] = base + 7;
-       superio_ide_select[port] = base + 6;
-       superio_ide_dma_status[port] = dmabase + (!port ? 2 : 0xa);
-
-       /* Clear error/interrupt, enable dma */
-       tmp = superio_ide_inb(superio_ide_dma_status[port]);
-       outb(tmp | 0x66, superio_ide_dma_status[port]);
+       .set_irq                = ide_set_irq,
 
-       hwif->tf_read = superio_tf_read;
+       .tf_load                = ide_tf_load,
+       .tf_read                = superio_tf_read,
 
-       /* We need to override inb to workaround a SuperIO errata */
-       hwif->INB = superio_ide_inb;
-}
+       .input_data             = ide_input_data,
+       .output_data            = ide_output_data,
+};
 
-static void __devinit init_iops_ns87415(ide_hwif_t *hwif)
+static void __devinit superio_init_iops(struct hwif_s *hwif)
 {
-       struct pci_dev *dev = to_pci_dev(hwif->dev);
+       struct pci_dev *pdev = to_pci_dev(hwif->dev);
+       u32 dma_stat;
+       u8 port = hwif->channel, tmp;
 
-       if (PCI_SLOT(dev->devfn) == 0xE)
-               /* Built-in - assume it's under superio. */
-               superio_ide_init_iops(hwif);
+       dma_stat = (pci_resource_start(pdev, 4) & ~3) + (!port ? 2 : 0xa);
+
+       /* Clear error/interrupt, enable dma */
+       tmp = superio_ide_inb(dma_stat);
+       outb(tmp | 0x66, dma_stat);
 }
 #endif
 
@@ -200,14 +195,14 @@ static int ns87415_dma_end(ide_drive_t *drive)
        u8 dma_stat = 0, dma_cmd = 0;
 
        drive->waiting_for_dma = 0;
-       dma_stat = hwif->INB(hwif->dma_status);
-       /* get dma command mode */
-       dma_cmd = hwif->INB(hwif->dma_command);
+       dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+       /* get DMA command mode */
+       dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
        /* stop DMA */
-       outb(dma_cmd & ~1, hwif->dma_command);
+       outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
        /* from ERRATA: clear the INTR & ERROR bits */
-       dma_cmd = hwif->INB(hwif->dma_command);
-       outb(dma_cmd | 6, hwif->dma_command);
+       dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
+       outb(dma_cmd | 6, hwif->dma_base + ATA_DMA_CMD);
        /* and free any DMA resources */
        ide_destroy_dmatable(drive);
        /* verify good DMA status */
@@ -276,7 +271,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
                outb(8, hwif->io_ports.ctl_addr);
                do {
                        udelay(50);
-                       stat = hwif->INB(hwif->io_ports.status_addr);
+                       stat = hwif->tp_ops->read_status(hwif);
                        if (stat == 0xff)
                                break;
                } while ((stat & BUSY_STAT) && --timeout);
@@ -291,7 +286,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
        if (!hwif->dma_base)
                return;
 
-       outb(0x60, hwif->dma_status);
+       outb(0x60, hwif->dma_base + ATA_DMA_STATUS);
 }
 
 static const struct ide_port_ops ns87415_port_ops = {
@@ -311,9 +306,6 @@ static const struct ide_dma_ops ns87415_dma_ops = {
 
 static const struct ide_port_info ns87415_chipset __devinitdata = {
        .name           = "NS87415",
-#ifdef CONFIG_SUPERIO
-       .init_iops      = init_iops_ns87415,
-#endif
        .init_hwif      = init_hwif_ns87415,
        .port_ops       = &ns87415_port_ops,
        .dma_ops        = &ns87415_dma_ops,
@@ -323,7 +315,16 @@ static const struct ide_port_info ns87415_chipset __devinitdata = {
 
 static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       return ide_setup_pci_device(dev, &ns87415_chipset);
+       struct ide_port_info d = ns87415_chipset;
+
+#ifdef CONFIG_SUPERIO
+       if (PCI_SLOT(dev->devfn) == 0xE) {
+               /* Built-in - assume it's under superio. */
+               d.init_iops = superio_init_iops;
+               d.tp_ops = &superio_tp_ops;
+       }
+#endif
+       return ide_setup_pci_device(dev, &d);
 }
 
 static const struct pci_device_id ns87415_pci_tbl[] = {
index fca89eda5c022cf8538eeaa0e89dd9344223d6ec..e54dc653b8c4aa609edbb6d16a0ab85e0bfa034b 100644 (file)
@@ -206,7 +206,7 @@ static int pdc202xx_dma_test_irq(ide_drive_t *drive)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        unsigned long high_16   = hwif->extra_base - 16;
-       u8 dma_stat             = inb(hwif->dma_status);
+       u8 dma_stat             = inb(hwif->dma_base + ATA_DMA_STATUS);
        u8 sc1d                 = inb(high_16 + 0x001d);
 
        if (hwif->channel) {
@@ -312,7 +312,6 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
 
 #define IDE_HFLAGS_PDC202XX \
        (IDE_HFLAG_ERROR_STOPS_FIFO | \
-        IDE_HFLAG_ABUSE_SET_DMA_MODE | \
         IDE_HFLAG_OFF_BOARD)
 
 static const struct ide_port_ops pdc20246_port_ops = {
index f04738d14a6f93b8499222dedef55ac582f4961c..0ce41b4dddafc543855f7c491c8fcf6599b666d2 100644 (file)
@@ -227,9 +227,9 @@ static void piix_dma_clear_irq(ide_drive_t *drive)
        u8 dma_stat;
 
        /* clear the INTR & ERROR bits */
-       dma_stat = inb(hwif->dma_status);
+       dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
        /* Should we force the bit as well ? */
-       outb(dma_stat, hwif->dma_status);
+       outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS);
 }
 
 struct ich_laptop {
index 789c66dfbde5a424f841cb8e5874a1e887f6959f..94a7ab86423616e7889c4bc4a2fa63f1f1d5b7b5 100644 (file)
@@ -65,7 +65,7 @@
 
 static struct scc_ports {
        unsigned long ctl, dma;
-       ide_hwif_t *hwif;  /* for removing port from system */
+       struct ide_host *host;  /* for removing port from system */
 } scc_ports[MAX_HWIFS];
 
 /* PIO transfer mode  table */
@@ -126,6 +126,46 @@ static u8 scc_ide_inb(unsigned long port)
        return (u8)data;
 }
 
+static void scc_exec_command(ide_hwif_t *hwif, u8 cmd)
+{
+       out_be32((void *)hwif->io_ports.command_addr, cmd);
+       eieio();
+       in_be32((void *)(hwif->dma_base + 0x01c));
+       eieio();
+}
+
+static u8 scc_read_status(ide_hwif_t *hwif)
+{
+       return (u8)in_be32((void *)hwif->io_ports.status_addr);
+}
+
+static u8 scc_read_altstatus(ide_hwif_t *hwif)
+{
+       return (u8)in_be32((void *)hwif->io_ports.ctl_addr);
+}
+
+static u8 scc_read_sff_dma_status(ide_hwif_t *hwif)
+{
+       return (u8)in_be32((void *)(hwif->dma_base + 4));
+}
+
+static void scc_set_irq(ide_hwif_t *hwif, int on)
+{
+       u8 ctl = ATA_DEVCTL_OBS;
+
+       if (on == 4) { /* hack for SRST */
+               ctl |= 4;
+               on &= ~4;
+       }
+
+       ctl |= on ? 0 : 2;
+
+       out_be32((void *)hwif->io_ports.ctl_addr, ctl);
+       eieio();
+       in_be32((void *)(hwif->dma_base + 0x01c));
+       eieio();
+}
+
 static void scc_ide_insw(unsigned long port, void *addr, u32 count)
 {
        u16 *ptr = (u16 *)addr;
@@ -148,14 +188,6 @@ static void scc_ide_outb(u8 addr, unsigned long port)
        out_be32((void*)port, addr);
 }
 
-static void scc_ide_outbsync(ide_hwif_t *hwif, u8 addr, unsigned long port)
-{
-       out_be32((void*)port, addr);
-       eieio();
-       in_be32((void*)(hwif->dma_base + 0x01c));
-       eieio();
-}
-
 static void
 scc_ide_outsw(unsigned long port, void *addr, u32 count)
 {
@@ -261,14 +293,14 @@ static void scc_dma_host_set(ide_drive_t *drive, int on)
 {
        ide_hwif_t *hwif = drive->hwif;
        u8 unit = (drive->select.b.unit & 0x01);
-       u8 dma_stat = scc_ide_inb(hwif->dma_status);
+       u8 dma_stat = scc_ide_inb(hwif->dma_base + 4);
 
        if (on)
                dma_stat |= (1 << (5 + unit));
        else
                dma_stat &= ~(1 << (5 + unit));
 
-       scc_ide_outb(dma_stat, hwif->dma_status);
+       scc_ide_outb(dma_stat, hwif->dma_base + 4);
 }
 
 /**
@@ -304,13 +336,13 @@ static int scc_dma_setup(ide_drive_t *drive)
        out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma);
 
        /* specify r/w */
-       out_be32((void __iomem *)hwif->dma_command, reading);
+       out_be32((void __iomem *)hwif->dma_base, reading);
 
-       /* read dma_status for INTR & ERROR flags */
-       dma_stat = in_be32((void __iomem *)hwif->dma_status);
+       /* read DMA status for INTR & ERROR flags */
+       dma_stat = in_be32((void __iomem *)(hwif->dma_base + 4));
 
        /* clear INTR & ERROR flags */
-       out_be32((void __iomem *)hwif->dma_status, dma_stat|6);
+       out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6);
        drive->waiting_for_dma = 1;
        return 0;
 }
@@ -318,10 +350,10 @@ static int scc_dma_setup(ide_drive_t *drive)
 static void scc_dma_start(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
-       u8 dma_cmd = scc_ide_inb(hwif->dma_command);
+       u8 dma_cmd = scc_ide_inb(hwif->dma_base);
 
        /* start DMA */
-       scc_ide_outb(dma_cmd | 1, hwif->dma_command);
+       scc_ide_outb(dma_cmd | 1, hwif->dma_base);
        hwif->dma = 1;
        wmb();
 }
@@ -333,13 +365,13 @@ static int __scc_dma_end(ide_drive_t *drive)
 
        drive->waiting_for_dma = 0;
        /* get DMA command mode */
-       dma_cmd = scc_ide_inb(hwif->dma_command);
+       dma_cmd = scc_ide_inb(hwif->dma_base);
        /* stop DMA */
-       scc_ide_outb(dma_cmd & ~1, hwif->dma_command);
+       scc_ide_outb(dma_cmd & ~1, hwif->dma_base);
        /* get DMA status */
-       dma_stat = scc_ide_inb(hwif->dma_status);
+       dma_stat = scc_ide_inb(hwif->dma_base + 4);
        /* clear the INTR & ERROR bits */
-       scc_ide_outb(dma_stat | 6, hwif->dma_status);
+       scc_ide_outb(dma_stat | 6, hwif->dma_base + 4);
        /* purge DMA mappings */
        ide_destroy_dmatable(drive);
        /* verify good DMA status */
@@ -359,6 +391,7 @@ static int __scc_dma_end(ide_drive_t *drive)
 static int scc_dma_end(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = HWIF(drive);
+       void __iomem *dma_base = (void __iomem *)hwif->dma_base;
        unsigned long intsts_port = hwif->dma_base + 0x014;
        u32 reg;
        int dma_stat, data_loss = 0;
@@ -397,7 +430,7 @@ static int scc_dma_end(ide_drive_t *drive)
                        printk(KERN_WARNING "%s: SERROR\n", SCC_PATA_NAME);
                        out_be32((void __iomem *)intsts_port, INTSTS_SERROR|INTSTS_BMSINT);
 
-                       out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
+                       out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS);
                        continue;
                }
 
@@ -412,7 +445,7 @@ static int scc_dma_end(ide_drive_t *drive)
 
                        out_be32((void __iomem *)intsts_port, INTSTS_PRERR|INTSTS_BMSINT);
 
-                       out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
+                       out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS);
                        continue;
                }
 
@@ -420,12 +453,12 @@ static int scc_dma_end(ide_drive_t *drive)
                        printk(KERN_WARNING "%s: Response Error\n", SCC_PATA_NAME);
                        out_be32((void __iomem *)intsts_port, INTSTS_RERR|INTSTS_BMSINT);
 
-                       out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
+                       out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS);
                        continue;
                }
 
                if (reg & INTSTS_ICERR) {
-                       out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
+                       out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS);
 
                        printk(KERN_WARNING "%s: Illegal Configuration\n", SCC_PATA_NAME);
                        out_be32((void __iomem *)intsts_port, INTSTS_ICERR|INTSTS_BMSINT);
@@ -553,14 +586,9 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev,
                                    const struct ide_port_info *d)
 {
        struct scc_ports *ports = pci_get_drvdata(dev);
-       ide_hwif_t *hwif = NULL;
-       hw_regs_t hw;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-       int i;
-
-       hwif = ide_find_port_slot(d);
-       if (hwif == NULL)
-               return -ENOMEM;
+       struct ide_host *host;
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+       int i, rc;
 
        memset(&hw, 0, sizeof(hw));
        for (i = 0; i <= 8; i++)
@@ -568,11 +596,12 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev,
        hw.irq = dev->irq;
        hw.dev = &dev->dev;
        hw.chipset = ide_pci;
-       ide_init_port_hw(hwif, &hw);
 
-       idx[0] = hwif->index;
+       rc = ide_host_add(d, hws, &host);
+       if (rc)
+               return rc;
 
-       ide_device_add(idx, d);
+       ports->host = host;
 
        return 0;
 }
@@ -701,6 +730,8 @@ static void scc_tf_read(ide_drive_t *drive, ide_task_t *task)
        /* be sure we're looking at the low order bits */
        scc_ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
 
+       if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
+               tf->feature = scc_ide_inb(io_ports->feature_addr);
        if (task->tf_flags & IDE_TFLAG_IN_NSECT)
                tf->nsect  = scc_ide_inb(io_ports->nsect_addr);
        if (task->tf_flags & IDE_TFLAG_IN_LBAL)
@@ -774,16 +805,6 @@ static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif)
 
        ide_set_hwifdata(hwif, ports);
 
-       hwif->tf_load = scc_tf_load;
-       hwif->tf_read = scc_tf_read;
-
-       hwif->input_data  = scc_input_data;
-       hwif->output_data = scc_output_data;
-
-       hwif->INB = scc_ide_inb;
-       hwif->OUTB = scc_ide_outb;
-       hwif->OUTBSYNC = scc_ide_outbsync;
-
        hwif->dma_base = dma_base;
        hwif->config_data = ports->ctl;
 }
@@ -824,11 +845,6 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
 {
        struct scc_ports *ports = ide_get_hwifdata(hwif);
 
-       ports->hwif = hwif;
-
-       hwif->dma_command = hwif->dma_base;
-       hwif->dma_status = hwif->dma_base + 0x04;
-
        /* PTERADD */
        out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma);
 
@@ -838,6 +854,21 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
                hwif->ultra_mask = ATA_UDMA5; /* 100MHz */
 }
 
+static const struct ide_tp_ops scc_tp_ops = {
+       .exec_command           = scc_exec_command,
+       .read_status            = scc_read_status,
+       .read_altstatus         = scc_read_altstatus,
+       .read_sff_dma_status    = scc_read_sff_dma_status,
+
+       .set_irq                = scc_set_irq,
+
+       .tf_load                = scc_tf_load,
+       .tf_read                = scc_tf_read,
+
+       .input_data             = scc_input_data,
+       .output_data            = scc_output_data,
+};
+
 static const struct ide_port_ops scc_port_ops = {
        .set_pio_mode           = scc_set_pio_mode,
        .set_dma_mode           = scc_set_dma_mode,
@@ -861,6 +892,7 @@ static const struct ide_dma_ops scc_dma_ops = {
       .name            = name_str,                     \
       .init_iops       = init_iops_scc,                \
       .init_hwif       = init_hwif_scc,                \
+      .tp_ops          = &scc_tp_ops,          \
       .port_ops                = &scc_port_ops,                \
       .dma_ops         = &scc_dma_ops,                 \
       .host_flags      = IDE_HFLAG_SINGLE,             \
@@ -895,7 +927,8 @@ static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_i
 static void __devexit scc_remove(struct pci_dev *dev)
 {
        struct scc_ports *ports = pci_get_drvdata(dev);
-       ide_hwif_t *hwif = ports->hwif;
+       struct ide_host *host = ports->host;
+       ide_hwif_t *hwif = host->ports[0];
 
        if (hwif->dmatable_cpu) {
                pci_free_consistent(dev, PRD_ENTRIES * PRD_BYTES,
@@ -903,7 +936,7 @@ static void __devexit scc_remove(struct pci_dev *dev)
                hwif->dmatable_cpu = NULL;
        }
 
-       ide_unregister(hwif);
+       ide_host_remove(host);
 
        iounmap((void*)ports->dma);
        iounmap((void*)ports->ctl);
index a1fb20826a5b817244d500db92c921a054c9ddee..127ccb45e261c23cb799bcb1e886141155f4b779 100644 (file)
@@ -349,9 +349,7 @@ static const struct ide_port_ops svwks_port_ops = {
        .cable_detect           = svwks_cable_detect,
 };
 
-#define IDE_HFLAGS_SVWKS \
-       (IDE_HFLAG_LEGACY_IRQS | \
-        IDE_HFLAG_ABUSE_SET_DMA_MODE)
+#define IDE_HFLAGS_SVWKS IDE_HFLAG_LEGACY_IRQS
 
 static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
        {       /* 0 */
index c79ff5b41088e40d09a124de94785cf1959408c1..42eef19a18f14f7c46611ffb2a7073e8d8cce6d4 100644 (file)
@@ -127,7 +127,7 @@ sgiioc4_checkirq(ide_hwif_t * hwif)
        return 0;
 }
 
-static u8 sgiioc4_INB(unsigned long);
+static u8 sgiioc4_read_status(ide_hwif_t *);
 
 static int
 sgiioc4_clearirq(ide_drive_t * drive)
@@ -141,18 +141,19 @@ sgiioc4_clearirq(ide_drive_t * drive)
        intr_reg = readl((void __iomem *)other_ir);
        if (intr_reg & 0x03) { /* Valid IOC4-IDE interrupt */
                /*
-                * Using sgiioc4_INB to read the Status register has a side
-                * effect of clearing the interrupt.  The first read should
+                * Using sgiioc4_read_status to read the Status register has a
+                * side effect of clearing the interrupt.  The first read should
                 * clear it if it is set.  The second read should return
                 * a "clear" status if it got cleared.  If not, then spin
                 * for a bit trying to clear it.
                 */
-               u8 stat = sgiioc4_INB(io_ports->status_addr);
+               u8 stat = sgiioc4_read_status(hwif);
                int count = 0;
-               stat = sgiioc4_INB(io_ports->status_addr);
+
+               stat = sgiioc4_read_status(hwif);
                while ((stat & 0x80) && (count++ < 100)) {
                        udelay(1);
-                       stat = sgiioc4_INB(io_ports->status_addr);
+                       stat = sgiioc4_read_status(hwif);
                }
 
                if (intr_reg & 0x02) {
@@ -304,9 +305,9 @@ sgiioc4_dma_lost_irq(ide_drive_t * drive)
        ide_dma_lost_irq(drive);
 }
 
-static u8
-sgiioc4_INB(unsigned long port)
+static u8 sgiioc4_read_status(ide_hwif_t *hwif)
 {
+       unsigned long port = hwif->io_ports.status_addr;
        u8 reg = (u8) readb((void __iomem *) port);
 
        if ((port & 0xFFF) == 0x11C) {  /* Status register of IOC4 */
@@ -549,6 +550,21 @@ static int sgiioc4_dma_setup(ide_drive_t *drive)
        return 0;
 }
 
+static const struct ide_tp_ops sgiioc4_tp_ops = {
+       .exec_command           = ide_exec_command,
+       .read_status            = sgiioc4_read_status,
+       .read_altstatus         = ide_read_altstatus,
+       .read_sff_dma_status    = ide_read_sff_dma_status,
+
+       .set_irq                = ide_set_irq,
+
+       .tf_load                = ide_tf_load,
+       .tf_read                = ide_tf_read,
+
+       .input_data             = ide_input_data,
+       .output_data            = ide_output_data,
+};
+
 static const struct ide_port_ops sgiioc4_port_ops = {
        .set_dma_mode           = sgiioc4_set_dma_mode,
        /* reset DMA engine, clear IRQs */
@@ -571,6 +587,7 @@ static const struct ide_port_info sgiioc4_port_info __devinitdata = {
        .name                   = DRV_NAME,
        .chipset                = ide_pci,
        .init_dma               = ide_dma_sgiioc4,
+       .tp_ops                 = &sgiioc4_tp_ops,
        .port_ops               = &sgiioc4_port_ops,
        .dma_ops                = &sgiioc4_dma_ops,
        .host_flags             = IDE_HFLAG_MMIO,
@@ -583,10 +600,10 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
        unsigned long cmd_base, irqport;
        unsigned long bar0, cmd_phys_base, ctl;
        void __iomem *virt_base;
-       ide_hwif_t *hwif;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-       hw_regs_t hw;
+       struct ide_host *host;
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
        struct ide_port_info d = sgiioc4_port_info;
+       int rc;
 
        /*  Get the CmdBlk and CtrlBlk Base Registers */
        bar0 = pci_resource_start(dev, 0);
@@ -618,30 +635,26 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
        hw.chipset = ide_pci;
        hw.dev = &dev->dev;
 
-       hwif = ide_find_port_slot(&d);
-       if (hwif == NULL)
-               goto err;
-
-       ide_init_port_hw(hwif, &hw);
-
-       /* The IOC4 uses MMIO rather than Port IO. */
-       default_hwif_mmiops(hwif);
-
        /* Initializing chipset IRQ Registers */
        writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));
 
-       hwif->INB = &sgiioc4_INB;
-
-       idx[0] = hwif->index;
+       host = ide_host_alloc(&d, hws);
+       if (host == NULL) {
+               rc = -ENOMEM;
+               goto err;
+       }
 
-       if (ide_device_add(idx, &d))
-               return -EIO;
+       rc = ide_host_register(host, &d, hws);
+       if (rc)
+               goto err_free;
 
        return 0;
+err_free:
+       ide_host_free(host);
 err:
        release_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE);
        iounmap(virt_base);
-       return -ENOMEM;
+       return rc;
 }
 
 static unsigned int __devinit
index 6e9d7655d89c02d1f6e426cd681428981fa66200..5965a35d94ae75a7c64c57fb0def8e5aed27ef0f 100644 (file)
@@ -334,7 +334,7 @@ static int siimage_io_dma_test_irq(ide_drive_t *drive)
        unsigned long addr      = siimage_selreg(hwif, 1);
 
        /* return 1 if INTR asserted */
-       if (hwif->INB(hwif->dma_status) & 4)
+       if (inb(hwif->dma_base + ATA_DMA_STATUS) & 4)
                return 1;
 
        /* return 1 if Device INTR asserted */
@@ -382,7 +382,7 @@ static int siimage_mmio_dma_test_irq(ide_drive_t *drive)
        }
 
        /* return 1 if INTR asserted */
-       if (readb((void __iomem *)hwif->dma_status) & 0x04)
+       if (readb((void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)) & 4)
                return 1;
 
        /* return 1 if Device INTR asserted */
@@ -601,7 +601,7 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
         *      Fill in the basic hwif bits
         */
        hwif->host_flags |= IDE_HFLAG_MMIO;
-       default_hwif_mmiops(hwif);
+
        hwif->hwif_data = addr;
 
        /*
index 6efbde297174b9b32a8405b227e9acf6abb69e77..f82a6502c1b721069bc1cadbeff89028dc97fc77 100644 (file)
@@ -157,9 +157,9 @@ static void sl82c105_dma_lost_irq(ide_drive_t *drive)
         * Was DMA enabled?  If so, disable it - we're resetting the
         * host.  The IDE layer will be handling the drive for us.
         */
-       dma_cmd = inb(hwif->dma_command);
+       dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
        if (dma_cmd & 1) {
-               outb(dma_cmd & ~1, hwif->dma_command);
+               outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
                printk("sl82c105: DMA was enabled\n");
        }
 
index 9b4b27a4c71121c30298052a30c653f5ccffee05..477e1979010230d4f1662af093b535520d9ccd95 100644 (file)
@@ -63,7 +63,7 @@ static int tc86c001_timer_expiry(ide_drive_t *drive)
        ide_hwif_t *hwif        = HWIF(drive);
        ide_expiry_t *expiry    = ide_get_hwifdata(hwif);
        ide_hwgroup_t *hwgroup  = HWGROUP(drive);
-       u8 dma_stat             = inb(hwif->dma_status);
+       u8 dma_stat             = inb(hwif->dma_base + ATA_DMA_STATUS);
 
        /* Restore a higher level driver's expiry handler first. */
        hwgroup->expiry = expiry;
@@ -71,21 +71,24 @@ static int tc86c001_timer_expiry(ide_drive_t *drive)
        if ((dma_stat & 5) == 1) {      /* DMA active and no interrupt */
                unsigned long sc_base   = hwif->config_data;
                unsigned long twcr_port = sc_base + (drive->dn ? 0x06 : 0x04);
-               u8 dma_cmd              = inb(hwif->dma_command);
+               u8 dma_cmd              = inb(hwif->dma_base + ATA_DMA_CMD);
 
                printk(KERN_WARNING "%s: DMA interrupt possibly stuck, "
                       "attempting recovery...\n", drive->name);
 
                /* Stop DMA */
-               outb(dma_cmd & ~0x01, hwif->dma_command);
+               outb(dma_cmd & ~0x01, hwif->dma_base + ATA_DMA_CMD);
 
                /* Setup the dummy DMA transfer */
                outw(0, sc_base + 0x0a);        /* Sector Count */
                outw(0, twcr_port);     /* Transfer Word Count 1 or 2 */
 
                /* Start the dummy DMA transfer */
-               outb(0x00, hwif->dma_command); /* clear R_OR_WCTR for write */
-               outb(0x01, hwif->dma_command); /* set START_STOPBM */
+
+               /* clear R_OR_WCTR for write */
+               outb(0x00, hwif->dma_base + ATA_DMA_CMD);
+               /* set START_STOPBM */
+               outb(0x01, hwif->dma_base + ATA_DMA_CMD);
 
                /*
                 * If an interrupt was pending, it should come thru shortly.
@@ -203,8 +206,7 @@ static const struct ide_port_info tc86c001_chipset __devinitdata = {
        .init_hwif      = init_hwif_tc86c001,
        .port_ops       = &tc86c001_port_ops,
        .dma_ops        = &tc86c001_dma_ops,
-       .host_flags     = IDE_HFLAG_SINGLE | IDE_HFLAG_OFF_BOARD |
-                         IDE_HFLAG_ABUSE_SET_DMA_MODE,
+       .host_flags     = IDE_HFLAG_SINGLE | IDE_HFLAG_OFF_BOARD,
        .pio_mask       = ATA_PIO4,
        .mwdma_mask     = ATA_MWDMA2,
        .udma_mask      = ATA_UDMA4,
index e47384c70c40bee808d79ef4fc2f127418bb8e47..09dc4803ef9d282c528240dee980f4d55f080a79 100644 (file)
@@ -425,7 +425,6 @@ static const struct ide_port_info via82cxxx_chipset __devinitdata = {
        .enablebits     = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
        .port_ops       = &via_port_ops,
        .host_flags     = IDE_HFLAG_PIO_NO_BLACKLIST |
-                         IDE_HFLAG_ABUSE_SET_DMA_MODE |
                          IDE_HFLAG_POST_SET_MODE |
                          IDE_HFLAG_IO_32BIT,
        .pio_mask       = ATA_PIO5,
index 93fb9067c0430f7add87b99fa41f39f31ba0d4c5..c521bf6e1bf2760f4034ac034fefe005ac5699ea 100644 (file)
@@ -48,6 +48,8 @@
 #include <asm/mediabay.h>
 #endif
 
+#define DRV_NAME "ide-pmac"
+
 #undef IDE_PMAC_DEBUG
 
 #define DMA_WAIT_TIMEOUT       50
@@ -424,7 +426,9 @@ static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
 static void
 pmac_ide_selectproc(ide_drive_t *drive)
 {
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+       ide_hwif_t *hwif = drive->hwif;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
 
        if (pmif == NULL)
                return;
@@ -444,7 +448,9 @@ pmac_ide_selectproc(ide_drive_t *drive)
 static void
 pmac_ide_kauai_selectproc(ide_drive_t *drive)
 {
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+       ide_hwif_t *hwif = drive->hwif;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
 
        if (pmif == NULL)
                return;
@@ -465,7 +471,9 @@ pmac_ide_kauai_selectproc(ide_drive_t *drive)
 static void
 pmac_ide_do_update_timings(ide_drive_t *drive)
 {
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+       ide_hwif_t *hwif = drive->hwif;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
 
        if (pmif == NULL)
                return;
@@ -478,12 +486,26 @@ pmac_ide_do_update_timings(ide_drive_t *drive)
                pmac_ide_selectproc(drive);
 }
 
-static void pmac_outbsync(ide_hwif_t *hwif, u8 value, unsigned long port)
+static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd)
 {
-       u32 tmp;
-       
-       writeb(value, (void __iomem *) port);
-       tmp = readl((void __iomem *)(hwif->io_ports.data_addr
+       writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
+       (void)readl((void __iomem *)(hwif->io_ports.data_addr
+                                    + IDE_TIMING_CONFIG));
+}
+
+static void pmac_set_irq(ide_hwif_t *hwif, int on)
+{
+       u8 ctl = ATA_DEVCTL_OBS;
+
+       if (on == 4) { /* hack for SRST */
+               ctl |= 4;
+               on &= ~4;
+       }
+
+       ctl |= on ? 0 : 2;
+
+       writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
+       (void)readl((void __iomem *)(hwif->io_ports.data_addr
                                     + IDE_TIMING_CONFIG));
 }
 
@@ -493,11 +515,13 @@ static void pmac_outbsync(ide_hwif_t *hwif, u8 value, unsigned long port)
 static void
 pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
+       ide_hwif_t *hwif = drive->hwif;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
        struct ide_timing *tim = ide_timing_find_mode(XFER_PIO_0 + pio);
        u32 *timings, t;
        unsigned accessTicks, recTicks;
        unsigned accessTime, recTime;
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
        unsigned int cycle_time;
 
        if (pmif == NULL)
@@ -778,9 +802,11 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
 
 static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
+       ide_hwif_t *hwif = drive->hwif;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
        int unit = (drive->select.b.unit & 0x01);
        int ret = 0;
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
        u32 *timings, *timings2, tl[2];
 
        timings = &pmif->timings[unit];
@@ -852,11 +878,8 @@ sanitize_timings(pmac_ide_hwif_t *pmif)
 /* Suspend call back, should be called after the child devices
  * have actually been suspended
  */
-static int
-pmac_ide_do_suspend(ide_hwif_t *hwif)
+static int pmac_ide_do_suspend(pmac_ide_hwif_t *pmif)
 {
-       pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
-       
        /* We clear the timings */
        pmif->timings[0] = 0;
        pmif->timings[1] = 0;
@@ -884,11 +907,8 @@ pmac_ide_do_suspend(ide_hwif_t *hwif)
 /* Resume call back, should be called before the child devices
  * are resumed
  */
-static int
-pmac_ide_do_resume(ide_hwif_t *hwif)
+static int pmac_ide_do_resume(pmac_ide_hwif_t *pmif)
 {
-       pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
-       
        /* Hard reset & re-enable controller (do we really need to reset ? -BenH) */
        if (!pmif->mediabay) {
                ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 1);
@@ -916,7 +936,8 @@ pmac_ide_do_resume(ide_hwif_t *hwif)
 
 static u8 pmac_ide_cable_detect(ide_hwif_t *hwif)
 {
-       pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)ide_get_hwifdata(hwif);
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
        struct device_node *np = pmif->node;
        const char *cable = of_get_property(np, "cable-type", NULL);
 
@@ -936,7 +957,40 @@ static u8 pmac_ide_cable_detect(ide_hwif_t *hwif)
        return ATA_CBL_PATA40;
 }
 
+static void pmac_ide_init_dev(ide_drive_t *drive)
+{
+       ide_hwif_t *hwif = drive->hwif;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+
+       if (pmif->mediabay) {
+#ifdef CONFIG_PMAC_MEDIABAY
+               if (check_media_bay_by_base(pmif->regbase, MB_CD) == 0) {
+                       drive->noprobe = 0;
+                       return;
+               }
+#endif
+               drive->noprobe = 1;
+       }
+}
+
+static const struct ide_tp_ops pmac_tp_ops = {
+       .exec_command           = pmac_exec_command,
+       .read_status            = ide_read_status,
+       .read_altstatus         = ide_read_altstatus,
+       .read_sff_dma_status    = ide_read_sff_dma_status,
+
+       .set_irq                = pmac_set_irq,
+
+       .tf_load                = ide_tf_load,
+       .tf_read                = ide_tf_read,
+
+       .input_data             = ide_input_data,
+       .output_data            = ide_output_data,
+};
+
 static const struct ide_port_ops pmac_ide_ata6_port_ops = {
+       .init_dev               = pmac_ide_init_dev,
        .set_pio_mode           = pmac_ide_set_pio_mode,
        .set_dma_mode           = pmac_ide_set_dma_mode,
        .selectproc             = pmac_ide_kauai_selectproc,
@@ -944,6 +998,7 @@ static const struct ide_port_ops pmac_ide_ata6_port_ops = {
 };
 
 static const struct ide_port_ops pmac_ide_ata4_port_ops = {
+       .init_dev               = pmac_ide_init_dev,
        .set_pio_mode           = pmac_ide_set_pio_mode,
        .set_dma_mode           = pmac_ide_set_dma_mode,
        .selectproc             = pmac_ide_selectproc,
@@ -951,6 +1006,7 @@ static const struct ide_port_ops pmac_ide_ata4_port_ops = {
 };
 
 static const struct ide_port_ops pmac_ide_port_ops = {
+       .init_dev               = pmac_ide_init_dev,
        .set_pio_mode           = pmac_ide_set_pio_mode,
        .set_dma_mode           = pmac_ide_set_dma_mode,
        .selectproc             = pmac_ide_selectproc,
@@ -959,12 +1015,14 @@ static const struct ide_port_ops pmac_ide_port_ops = {
 static const struct ide_dma_ops pmac_dma_ops;
 
 static const struct ide_port_info pmac_port_info = {
+       .name                   = DRV_NAME,
        .init_dma               = pmac_ide_init_dma,
        .chipset                = ide_pmac,
+       .tp_ops                 = &pmac_tp_ops,
+       .port_ops               = &pmac_ide_port_ops,
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
        .dma_ops                = &pmac_dma_ops,
 #endif
-       .port_ops               = &pmac_ide_port_ops,
        .host_flags             = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA |
                                  IDE_HFLAG_POST_SET_MODE |
                                  IDE_HFLAG_MMIO |
@@ -977,13 +1035,15 @@ static const struct ide_port_info pmac_port_info = {
  * Setup, register & probe an IDE channel driven by this driver, this is
  * called by one of the 2 probe functions (macio or PCI).
  */
-static int __devinit
-pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
+static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw)
 {
        struct device_node *np = pmif->node;
        const int *bidp;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+       struct ide_host *host;
+       ide_hwif_t *hwif;
+       hw_regs_t *hws[] = { hw, NULL, NULL, NULL };
        struct ide_port_info d = pmac_port_info;
+       int rc;
 
        pmif->broken_dma = pmif->broken_dma_warn = 0;
        if (of_device_is_compatible(np, "shasta-ata")) {
@@ -1054,31 +1114,16 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
                msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY));
        }
 
-       /* Setup MMIO ops */
-       default_hwif_mmiops(hwif);
-               hwif->OUTBSYNC = pmac_outbsync;
+       printk(KERN_INFO DRV_NAME ": Found Apple %s controller (%s), "
+                        "bus ID %d%s, irq %d\n", model_name[pmif->kind],
+                        pmif->mdev ? "macio" : "PCI", pmif->aapl_bus_id,
+                        pmif->mediabay ? " (mediabay)" : "", hw->irq);
 
-       hwif->hwif_data = pmif;
-       ide_init_port_hw(hwif, hw);
+       rc = ide_host_add(&d, hws, &host);
+       if (rc)
+               return rc;
 
-       printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n",
-              hwif->index, model_name[pmif->kind], pmif->aapl_bus_id,
-              pmif->mediabay ? " (mediabay)" : "", hwif->irq);
-
-       if (pmif->mediabay) {
-#ifdef CONFIG_PMAC_MEDIABAY
-               if (check_media_bay_by_base(pmif->regbase, MB_CD)) {
-#else
-               if (1) {
-#endif
-                       hwif->drives[0].noprobe = 1;
-                       hwif->drives[1].noprobe = 1;
-               }
-       }
-
-       idx[0] = hwif->index;
-
-       ide_device_add(idx, &d);
+       hwif = host->ports[0];
 
        return 0;
 }
@@ -1101,7 +1146,6 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
        void __iomem *base;
        unsigned long regbase;
-       ide_hwif_t *hwif;
        pmac_ide_hwif_t *pmif;
        int irq, rc;
        hw_regs_t hw;
@@ -1110,14 +1154,6 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
        if (pmif == NULL)
                return -ENOMEM;
 
-       hwif = ide_find_port();
-       if (hwif == NULL) {
-               printk(KERN_ERR "ide-pmac: MacIO interface attach with no slot\n");
-               printk(KERN_ERR "          %s\n", mdev->ofdev.node->full_name);
-               rc = -ENODEV;
-               goto out_free_pmif;
-       }
-
        if (macio_resource_count(mdev) == 0) {
                printk(KERN_WARNING "ide-pmac: no address for %s\n",
                                    mdev->ofdev.node->full_name);
@@ -1164,7 +1200,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
        } else
                pmif->dma_regs = NULL;
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
-       dev_set_drvdata(&mdev->ofdev.dev, hwif);
+       dev_set_drvdata(&mdev->ofdev.dev, pmif);
 
        memset(&hw, 0, sizeof(hw));
        pmac_ide_init_ports(&hw, pmif->regbase);
@@ -1172,7 +1208,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
        hw.dev = &mdev->bus->pdev->dev;
        hw.parent = &mdev->ofdev.dev;
 
-       rc = pmac_ide_setup_device(pmif, hwif, &hw);
+       rc = pmac_ide_setup_device(pmif, &hw);
        if (rc != 0) {
                /* The inteface is released to the common IDE layer */
                dev_set_drvdata(&mdev->ofdev.dev, NULL);
@@ -1195,12 +1231,13 @@ out_free_pmif:
 static int
 pmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t mesg)
 {
-       ide_hwif_t      *hwif = (ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
-       int             rc = 0;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
+       int rc = 0;
 
        if (mesg.event != mdev->ofdev.dev.power.power_state.event
                        && (mesg.event & PM_EVENT_SLEEP)) {
-               rc = pmac_ide_do_suspend(hwif);
+               rc = pmac_ide_do_suspend(pmif);
                if (rc == 0)
                        mdev->ofdev.dev.power.power_state = mesg;
        }
@@ -1211,11 +1248,12 @@ pmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t mesg)
 static int
 pmac_ide_macio_resume(struct macio_dev *mdev)
 {
-       ide_hwif_t      *hwif = (ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
-       int             rc = 0;
-       
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
+       int rc = 0;
+
        if (mdev->ofdev.dev.power.power_state.event != PM_EVENT_ON) {
-               rc = pmac_ide_do_resume(hwif);
+               rc = pmac_ide_do_resume(pmif);
                if (rc == 0)
                        mdev->ofdev.dev.power.power_state = PMSG_ON;
        }
@@ -1229,7 +1267,6 @@ pmac_ide_macio_resume(struct macio_dev *mdev)
 static int __devinit
 pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-       ide_hwif_t *hwif;
        struct device_node *np;
        pmac_ide_hwif_t *pmif;
        void __iomem *base;
@@ -1247,14 +1284,6 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
        if (pmif == NULL)
                return -ENOMEM;
 
-       hwif = ide_find_port();
-       if (hwif == NULL) {
-               printk(KERN_ERR "ide-pmac: PCI interface attach with no slot\n");
-               printk(KERN_ERR "          %s\n", np->full_name);
-               rc = -ENODEV;
-               goto out_free_pmif;
-       }
-
        if (pci_enable_device(pdev)) {
                printk(KERN_WARNING "ide-pmac: Can't enable PCI device for "
                                    "%s\n", np->full_name);
@@ -1284,14 +1313,14 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
        pmif->kauai_fcr = base;
        pmif->irq = pdev->irq;
 
-       pci_set_drvdata(pdev, hwif);
+       pci_set_drvdata(pdev, pmif);
 
        memset(&hw, 0, sizeof(hw));
        pmac_ide_init_ports(&hw, pmif->regbase);
        hw.irq = pdev->irq;
        hw.dev = &pdev->dev;
 
-       rc = pmac_ide_setup_device(pmif, hwif, &hw);
+       rc = pmac_ide_setup_device(pmif, &hw);
        if (rc != 0) {
                /* The inteface is released to the common IDE layer */
                pci_set_drvdata(pdev, NULL);
@@ -1310,12 +1339,12 @@ out_free_pmif:
 static int
 pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
-       ide_hwif_t      *hwif = (ide_hwif_t *)pci_get_drvdata(pdev);
-       int             rc = 0;
-       
+       pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)pci_get_drvdata(pdev);
+       int rc = 0;
+
        if (mesg.event != pdev->dev.power.power_state.event
                        && (mesg.event & PM_EVENT_SLEEP)) {
-               rc = pmac_ide_do_suspend(hwif);
+               rc = pmac_ide_do_suspend(pmif);
                if (rc == 0)
                        pdev->dev.power.power_state = mesg;
        }
@@ -1326,11 +1355,11 @@ pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
 static int
 pmac_ide_pci_resume(struct pci_dev *pdev)
 {
-       ide_hwif_t      *hwif = (ide_hwif_t *)pci_get_drvdata(pdev);
-       int             rc = 0;
-       
+       pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)pci_get_drvdata(pdev);
+       int rc = 0;
+
        if (pdev->dev.power.power_state.event != PM_EVENT_ON) {
-               rc = pmac_ide_do_resume(hwif);
+               rc = pmac_ide_do_resume(pmif);
                if (rc == 0)
                        pdev->dev.power.power_state = PMSG_ON;
        }
@@ -1421,10 +1450,11 @@ out:
 static int
 pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
 {
+       ide_hwif_t *hwif = drive->hwif;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
        struct dbdma_cmd *table;
        int i, count = 0;
-       ide_hwif_t *hwif = HWIF(drive);
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
        volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
        struct scatterlist *sg;
        int wr = (rq_data_dir(rq) == WRITE);
@@ -1520,7 +1550,8 @@ static int
 pmac_ide_dma_setup(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = HWIF(drive);
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
        struct request *rq = HWGROUP(drive)->rq;
        u8 unit = (drive->select.b.unit & 0x01);
        u8 ata4;
@@ -1560,7 +1591,9 @@ pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
 static void
 pmac_ide_dma_start(ide_drive_t *drive)
 {
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+       ide_hwif_t *hwif = drive->hwif;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
        volatile struct dbdma_regs __iomem *dma;
 
        dma = pmif->dma_regs;
@@ -1576,7 +1609,9 @@ pmac_ide_dma_start(ide_drive_t *drive)
 static int
 pmac_ide_dma_end (ide_drive_t *drive)
 {
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+       ide_hwif_t *hwif = drive->hwif;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
        volatile struct dbdma_regs __iomem *dma;
        u32 dstat;
        
@@ -1604,7 +1639,9 @@ pmac_ide_dma_end (ide_drive_t *drive)
 static int
 pmac_ide_dma_test_irq (ide_drive_t *drive)
 {
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+       ide_hwif_t *hwif = drive->hwif;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
        volatile struct dbdma_regs __iomem *dma;
        unsigned long status, timeout;
 
@@ -1664,7 +1701,9 @@ static void pmac_ide_dma_host_set(ide_drive_t *drive, int on)
 static void
 pmac_ide_dma_lost_irq (ide_drive_t *drive)
 {
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+       ide_hwif_t *hwif = drive->hwif;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
        volatile struct dbdma_regs __iomem *dma;
        unsigned long status;
 
@@ -1694,7 +1733,8 @@ static const struct ide_dma_ops pmac_dma_ops = {
 static int __devinit pmac_ide_init_dma(ide_hwif_t *hwif,
                                       const struct ide_port_info *d)
 {
-       pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
+       pmac_ide_hwif_t *pmif =
+               (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
        struct pci_dev *dev = to_pci_dev(hwif->dev);
 
        /* We won't need pci_dev if we switch to generic consistent
index 65fc08b6b6d0e813f4eed2e5594c1149a5233d7b..b15cad58dc81ea781b4ac7b366759d6ab3de20e8 100644 (file)
@@ -73,15 +73,12 @@ static void ide_pci_clear_simplex(unsigned long dma_base, const char *name)
  *     @d: IDE port info
  *
  *     Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space.
- *     Where a device has a partner that is already in DMA mode we check
- *     and enforce IDE simplex rules.
  */
 
 unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d)
 {
        struct pci_dev *dev = to_pci_dev(hwif->dev);
        unsigned long dma_base = 0;
-       u8 dma_stat = 0;
 
        if (hwif->host_flags & IDE_HFLAG_MMIO)
                return hwif->dma_base;
@@ -102,11 +99,19 @@ unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d)
        if (hwif->channel)
                dma_base += 8;
 
-       if (d->host_flags & IDE_HFLAG_CS5520)
+       return dma_base;
+}
+EXPORT_SYMBOL_GPL(ide_pci_dma_base);
+
+int ide_pci_check_simplex(ide_hwif_t *hwif, const struct ide_port_info *d)
+{
+       u8 dma_stat;
+
+       if (d->host_flags & (IDE_HFLAG_MMIO | IDE_HFLAG_CS5520))
                goto out;
 
        if (d->host_flags & IDE_HFLAG_CLEAR_SIMPLEX) {
-               ide_pci_clear_simplex(dma_base, d->name);
+               ide_pci_clear_simplex(hwif->dma_base, d->name);
                goto out;
        }
 
@@ -120,15 +125,15 @@ unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d)
         * we tune the drive then try to grab DMA ownership if we want to be
         * the DMA end.  This has to be become dynamic to handle hot-plug.
         */
-       dma_stat = hwif->INB(dma_base + 2);
+       dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
        if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) {
                printk(KERN_INFO "%s: simplex device: DMA disabled\n", d->name);
-               dma_base = 0;
+               return -1;
        }
 out:
-       return dma_base;
+       return 0;
 }
-EXPORT_SYMBOL_GPL(ide_pci_dma_base);
+EXPORT_SYMBOL_GPL(ide_pci_check_simplex);
 
 /*
  * Set up BM-DMA capability (PnP BIOS should have done this)
@@ -284,33 +289,31 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *
 }
 
 /**
- *     ide_hwif_configure      -       configure an IDE interface
+ *     ide_hw_configure        -       configure a hw_regs_t instance
  *     @dev: PCI device holding interface
  *     @d: IDE port info
  *     @port: port number
  *     @irq: PCI IRQ
+ *     @hw: hw_regs_t instance corresponding to this port
  *
  *     Perform the initial set up for the hardware interface structure. This
  *     is done per interface port rather than per PCI device. There may be
  *     more than one port per device.
  *
- *     Returns the new hardware interface structure, or NULL on a failure
+ *     Returns zero on success or an error code.
  */
 
-static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
-                                     const struct ide_port_info *d,
-                                     unsigned int port, int irq)
+static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d,
+                           unsigned int port, int irq, hw_regs_t *hw)
 {
        unsigned long ctl = 0, base = 0;
-       ide_hwif_t *hwif;
-       struct hw_regs_s hw;
 
        if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) {
                if (ide_pci_check_iomem(dev, d, 2 * port) ||
                    ide_pci_check_iomem(dev, d, 2 * port + 1)) {
                        printk(KERN_ERR "%s: I/O baseregs (BIOS) are reported "
                                        "as MEM for port %d!\n", d->name, port);
-                       return NULL;
+                       return -EINVAL;
                }
 
                ctl  = pci_resource_start(dev, 2*port+1);
@@ -324,22 +327,16 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
        if (!base || !ctl) {
                printk(KERN_ERR "%s: bad PCI BARs for port %d, skipping\n",
                                d->name, port);
-               return NULL;
+               return -EINVAL;
        }
 
-       hwif = ide_find_port_slot(d);
-       if (hwif == NULL)
-               return NULL;
-
-       memset(&hw, 0, sizeof(hw));
-       hw.irq = irq;
-       hw.dev = &dev->dev;
-       hw.chipset = d->chipset ? d->chipset : ide_pci;
-       ide_std_init_ports(&hw, base, ctl | 2);
-
-       ide_init_port_hw(hwif, &hw);
+       memset(hw, 0, sizeof(*hw));
+       hw->irq = irq;
+       hw->dev = &dev->dev;
+       hw->chipset = d->chipset ? d->chipset : ide_pci;
+       ide_std_init_ports(hw, base, ctl | 2);
 
-       return hwif;
+       return 0;
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
@@ -362,7 +359,15 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
             (dev->class & 0x80))) {
                unsigned long base = ide_pci_dma_base(hwif, d);
 
-               if (base == 0 || ide_pci_set_master(dev, d->name) < 0)
+               if (base == 0)
+                       return -1;
+
+               hwif->dma_base = base;
+
+               if (ide_pci_check_simplex(hwif, d) < 0)
+                       return -1;
+
+               if (ide_pci_set_master(dev, d->name) < 0)
                        return -1;
 
                if (hwif->host_flags & IDE_HFLAG_MMIO)
@@ -376,7 +381,7 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
                if (ide_allocate_dma_engine(hwif))
                        return -1;
 
-               ide_setup_dma(hwif, base);
+               hwif->dma_ops = &sff_dma_ops;
        }
 
        return 0;
@@ -429,7 +434,8 @@ out:
  *     @dev: PCI device
  *     @d: IDE port info
  *     @pciirq: IRQ line
- *     @idx: ATA index table to update
+ *     @hw: hw_regs_t instances corresponding to this PCI IDE device
+ *     @hws: hw_regs_t pointers table to update
  *
  *     Scan the interfaces attached to this device and do any
  *     necessary per port setup. Attach the devices and ask the
@@ -440,10 +446,10 @@ out:
  *     where the chipset setup is not the default PCI IDE one.
  */
 
-void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int pciirq, u8 *idx)
+void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d,
+                        int pciirq, hw_regs_t *hw, hw_regs_t **hws)
 {
        int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port;
-       ide_hwif_t *hwif;
        u8 tmp;
 
        /*
@@ -459,11 +465,10 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int
                        continue;       /* port not enabled */
                }
 
-               hwif = ide_hwif_configure(dev, d, port, pciirq);
-               if (hwif == NULL)
+               if (ide_hw_configure(dev, d, port, pciirq, hw + port))
                        continue;
 
-               *(idx + port) = hwif->index;
+               *(hws + port) = hw + port;
        }
 }
 EXPORT_SYMBOL_GPL(ide_pci_setup_ports);
@@ -480,7 +485,7 @@ EXPORT_SYMBOL_GPL(ide_pci_setup_ports);
  */
 static int do_ide_setup_pci_device(struct pci_dev *dev,
                                   const struct ide_port_info *d,
-                                  u8 *idx, u8 noisy)
+                                  u8 noisy)
 {
        int tried_config = 0;
        int pciirq, ret;
@@ -529,22 +534,24 @@ static int do_ide_setup_pci_device(struct pci_dev *dev,
                                d->name, pciirq);
        }
 
-       /* FIXME: silent failure can happen */
-
-       ide_pci_setup_ports(dev, d, pciirq, idx);
+       ret = pciirq;
 out:
        return ret;
 }
 
 int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d)
 {
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+       hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL };
        int ret;
 
-       ret = do_ide_setup_pci_device(dev, d, &idx[0], 1);
+       ret = do_ide_setup_pci_device(dev, d, 1);
+
+       if (ret >= 0) {
+               /* FIXME: silent failure can happen */
+               ide_pci_setup_ports(dev, d, ret, &hw[0], &hws[0]);
 
-       if (ret >= 0)
-               ide_device_add(idx, d);
+               ret = ide_host_add(d, hws, NULL);
+       }
 
        return ret;
 }
@@ -555,19 +562,23 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
 {
        struct pci_dev *pdev[] = { dev1, dev2 };
        int ret, i;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+       hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL };
 
        for (i = 0; i < 2; i++) {
-               ret = do_ide_setup_pci_device(pdev[i], d, &idx[i*2], !i);
+               ret = do_ide_setup_pci_device(pdev[i], d, !i);
+
                /*
                 * FIXME: Mom, mom, they stole me the helper function to undo
                 * do_ide_setup_pci_device() on the first device!
                 */
                if (ret < 0)
                        goto out;
+
+               /* FIXME: silent failure can happen */
+               ide_pci_setup_ports(pdev[i], d, ret, &hw[i*2], &hws[i*2]);
        }
 
-       ide_device_add(idx, d);
+       ret = ide_host_add(d, hws, NULL);
 out:
        return ret;
 }
index 9d19aec5820a303145d8b286e2d1ce2e72b4a586..b6eb2cf25914479667439fa51e181fca1e986fbd 100644 (file)
@@ -2296,9 +2296,10 @@ static void dv1394_add_host(struct hpsb_host *host)
 
        ohci = (struct ti_ohci *)host->hostdata;
 
-       device_create(hpsb_protocol_class, NULL, MKDEV(
-               IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
-               "dv1394-%d", id);
+       device_create_drvdata(hpsb_protocol_class, NULL,
+                             MKDEV(IEEE1394_MAJOR,
+                                   IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), NULL,
+                             "dv1394-%d", id);
 
        dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
        dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT);
index 05710c7c12206aa1a9fcca8bad4db2eac3be7697..994a21e5a0aa7e6d929e94b82f0f8f99efe5b72f 100644 (file)
@@ -754,7 +754,8 @@ static void nodemgr_remove_uds(struct node_entry *ne)
         */
        mutex_lock(&nodemgr_serialize_remove_uds);
        for (;;) {
-               dev = class_find_device(&nodemgr_ud_class, ne, __match_ne);
+               dev = class_find_device(&nodemgr_ud_class, NULL, ne,
+                                       __match_ne);
                if (!dev)
                        break;
                ud = container_of(dev, struct unit_directory, unit_dev);
@@ -901,7 +902,8 @@ static struct node_entry *find_entry_by_guid(u64 guid)
        struct device *dev;
        struct node_entry *ne;
 
-       dev = class_find_device(&nodemgr_ne_class, &guid, __match_ne_guid);
+       dev = class_find_device(&nodemgr_ne_class, NULL, &guid,
+                               __match_ne_guid);
        if (!dev)
                return NULL;
        ne = container_of(dev, struct node_entry, node_dev);
@@ -940,7 +942,8 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
        param.host = host;
        param.nodeid = nodeid;
 
-       dev = class_find_device(&nodemgr_ne_class, &param, __match_ne_nodeid);
+       dev = class_find_device(&nodemgr_ne_class, NULL, &param,
+                               __match_ne_nodeid);
        if (!dev)
                return NULL;
        ne = container_of(dev, struct node_entry, node_dev);
@@ -1453,7 +1456,8 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
        ne->in_limbo = 1;
        WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
 
-       class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_suspend);
+       class_for_each_device(&nodemgr_ud_class, NULL, ne,
+                             __nodemgr_driver_suspend);
 }
 
 
@@ -1462,7 +1466,8 @@ static void nodemgr_resume_ne(struct node_entry *ne)
        ne->in_limbo = 0;
        device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
 
-       class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_resume);
+       class_for_each_device(&nodemgr_ud_class, NULL, ne,
+                             __nodemgr_driver_resume);
        HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "]  GUID[%016Lx]",
                   NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
 }
@@ -1498,7 +1503,8 @@ static int __nodemgr_update_pdrv(struct device *dev, void *data)
 
 static void nodemgr_update_pdrv(struct node_entry *ne)
 {
-       class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_update_pdrv);
+       class_for_each_device(&nodemgr_ud_class, NULL, ne,
+                             __nodemgr_update_pdrv);
 }
 
 
@@ -1591,7 +1597,8 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
         * while probes are time-consuming. (Well, those probes need some
         * improvement...) */
 
-       class_for_each_device(&nodemgr_ne_class, &param, __nodemgr_node_probe);
+       class_for_each_device(&nodemgr_ne_class, NULL, &param,
+                             __nodemgr_node_probe);
 
        /* If we had a bus reset while we were scanning the bus, it is
         * possible that we did not probe all nodes.  In that case, we
@@ -1826,7 +1833,7 @@ int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *))
 
        hip.cb = cb;
        hip.data = data;
-       error = class_for_each_device(&hpsb_host_class, &hip,
+       error = class_for_each_device(&hpsb_host_class, NULL, &hip,
                                      __nodemgr_for_each_host);
 
        return error;
index 96f2847b0405e03ced5c4d3ec5b50a973caf6129..6fa9e4a21840b5f0cad2ce28b3754b293913e8fc 100644 (file)
@@ -3010,10 +3010,10 @@ static int __init init_raw1394(void)
        hpsb_register_highlevel(&raw1394_highlevel);
 
        if (IS_ERR
-           (device_create(
+           (device_create_drvdata(
              hpsb_protocol_class, NULL,
              MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
-             RAW1394_DEVICE_NAME))) {
+             NULL, RAW1394_DEVICE_NAME))) {
                ret = -EFAULT;
                goto out_unreg;
        }
index 069b9f6bf16dae8396d871673c8618eb544967a7..25db6e67fa4ea6d123f9a71df2e9c44616e84c3d 100644 (file)
@@ -1341,9 +1341,9 @@ static void video1394_add_host (struct hpsb_host *host)
        hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id);
 
        minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id;
-       device_create(hpsb_protocol_class, NULL,
-                     MKDEV(IEEE1394_MAJOR, minor),
-                     "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
+       device_create_drvdata(hpsb_protocol_class, NULL,
+                             MKDEV(IEEE1394_MAJOR, minor), NULL,
+                             "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
 }
 
 
index 55738eead3bf1ce009568b1028be83b0e7b7d283..922d35f4fc08aa07d69355a812577f9534e82567 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/spinlock.h>
 #include <linux/sysfs.h>
 #include <linux/workqueue.h>
+#include <linux/kdev_t.h>
 
 #include <rdma/ib_cache.h>
 #include <rdma/ib_cm.h>
@@ -162,8 +163,8 @@ struct cm_port {
 
 struct cm_device {
        struct list_head list;
-       struct ib_device *device;
-       struct kobject dev_obj;
+       struct ib_device *ib_device;
+       struct device *device;
        u8 ack_delay;
        struct cm_port *port[0];
 };
@@ -339,7 +340,7 @@ static void cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc,
 {
        av->port = port;
        av->pkey_index = wc->pkey_index;
-       ib_init_ah_from_wc(port->cm_dev->device, port->port_num, wc,
+       ib_init_ah_from_wc(port->cm_dev->ib_device, port->port_num, wc,
                           grh, &av->ah_attr);
 }
 
@@ -353,7 +354,7 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
 
        read_lock_irqsave(&cm.device_lock, flags);
        list_for_each_entry(cm_dev, &cm.device_list, list) {
-               if (!ib_find_cached_gid(cm_dev->device, &path->sgid,
+               if (!ib_find_cached_gid(cm_dev->ib_device, &path->sgid,
                                        &p, NULL)) {
                        port = cm_dev->port[p-1];
                        break;
@@ -364,13 +365,13 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
        if (!port)
                return -EINVAL;
 
-       ret = ib_find_cached_pkey(cm_dev->device, port->port_num,
+       ret = ib_find_cached_pkey(cm_dev->ib_device, port->port_num,
                                  be16_to_cpu(path->pkey), &av->pkey_index);
        if (ret)
                return ret;
 
        av->port = port;
-       ib_init_ah_from_path(cm_dev->device, port->port_num, path,
+       ib_init_ah_from_path(cm_dev->ib_device, port->port_num, path,
                             &av->ah_attr);
        av->timeout = path->packet_life_time + 1;
        return 0;
@@ -1515,7 +1516,7 @@ static int cm_req_handler(struct cm_work *work)
 
        req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
 
-       cm_id = ib_create_cm_id(work->port->cm_dev->device, NULL, NULL);
+       cm_id = ib_create_cm_id(work->port->cm_dev->ib_device, NULL, NULL);
        if (IS_ERR(cm_id))
                return PTR_ERR(cm_id);
 
@@ -1550,7 +1551,7 @@ static int cm_req_handler(struct cm_work *work)
        cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
        ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
        if (ret) {
-               ib_get_cached_gid(work->port->cm_dev->device,
+               ib_get_cached_gid(work->port->cm_dev->ib_device,
                                  work->port->port_num, 0, &work->path[0].sgid);
                ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_GID,
                               &work->path[0].sgid, sizeof work->path[0].sgid,
@@ -2950,7 +2951,7 @@ static int cm_sidr_req_handler(struct cm_work *work)
        struct cm_sidr_req_msg *sidr_req_msg;
        struct ib_wc *wc;
 
-       cm_id = ib_create_cm_id(work->port->cm_dev->device, NULL, NULL);
+       cm_id = ib_create_cm_id(work->port->cm_dev->ib_device, NULL, NULL);
        if (IS_ERR(cm_id))
                return PTR_ERR(cm_id);
        cm_id_priv = container_of(cm_id, struct cm_id_private, id);
@@ -3578,7 +3579,7 @@ static void cm_get_ack_delay(struct cm_device *cm_dev)
 {
        struct ib_device_attr attr;
 
-       if (ib_query_device(cm_dev->device, &attr))
+       if (ib_query_device(cm_dev->ib_device, &attr))
                cm_dev->ack_delay = 0; /* acks will rely on packet life time */
        else
                cm_dev->ack_delay = attr.local_ca_ack_delay;
@@ -3618,18 +3619,6 @@ static struct kobj_type cm_port_obj_type = {
        .release = cm_release_port_obj
 };
 
-static void cm_release_dev_obj(struct kobject *obj)
-{
-       struct cm_device *cm_dev;
-
-       cm_dev = container_of(obj, struct cm_device, dev_obj);
-       kfree(cm_dev);
-}
-
-static struct kobj_type cm_dev_obj_type = {
-       .release = cm_release_dev_obj
-};
-
 struct class cm_class = {
        .name    = "infiniband_cm",
 };
@@ -3640,7 +3629,7 @@ static int cm_create_port_fs(struct cm_port *port)
        int i, ret;
 
        ret = kobject_init_and_add(&port->port_obj, &cm_port_obj_type,
-                                  &port->cm_dev->dev_obj,
+                                  &port->cm_dev->device->kobj,
                                   "%d", port->port_num);
        if (ret) {
                kfree(port);
@@ -3676,7 +3665,7 @@ static void cm_remove_port_fs(struct cm_port *port)
        kobject_put(&port->port_obj);
 }
 
-static void cm_add_one(struct ib_device *device)
+static void cm_add_one(struct ib_device *ib_device)
 {
        struct cm_device *cm_dev;
        struct cm_port *port;
@@ -3691,26 +3680,27 @@ static void cm_add_one(struct ib_device *device)
        int ret;
        u8 i;
 
-       if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
+       if (rdma_node_get_transport(ib_device->node_type) != RDMA_TRANSPORT_IB)
                return;
 
        cm_dev = kzalloc(sizeof(*cm_dev) + sizeof(*port) *
-                        device->phys_port_cnt, GFP_KERNEL);
+                        ib_device->phys_port_cnt, GFP_KERNEL);
        if (!cm_dev)
                return;
 
-       cm_dev->device = device;
+       cm_dev->ib_device = ib_device;
        cm_get_ack_delay(cm_dev);
 
-       ret = kobject_init_and_add(&cm_dev->dev_obj, &cm_dev_obj_type,
-                                  &cm_class.subsys.kobj, "%s", device->name);
-       if (ret) {
+       cm_dev->device = device_create_drvdata(&cm_class, &ib_device->dev,
+                                              MKDEV(0, 0), NULL,
+                                              "%s", ib_device->name);
+       if (!cm_dev->device) {
                kfree(cm_dev);
                return;
        }
 
        set_bit(IB_MGMT_METHOD_SEND, reg_req.method_mask);
-       for (i = 1; i <= device->phys_port_cnt; i++) {
+       for (i = 1; i <= ib_device->phys_port_cnt; i++) {
                port = kzalloc(sizeof *port, GFP_KERNEL);
                if (!port)
                        goto error1;
@@ -3723,7 +3713,7 @@ static void cm_add_one(struct ib_device *device)
                if (ret)
                        goto error1;
 
-               port->mad_agent = ib_register_mad_agent(device, i,
+               port->mad_agent = ib_register_mad_agent(ib_device, i,
                                                        IB_QPT_GSI,
                                                        &reg_req,
                                                        0,
@@ -3733,11 +3723,11 @@ static void cm_add_one(struct ib_device *device)
                if (IS_ERR(port->mad_agent))
                        goto error2;
 
-               ret = ib_modify_port(device, i, 0, &port_modify);
+               ret = ib_modify_port(ib_device, i, 0, &port_modify);
                if (ret)
                        goto error3;
        }
-       ib_set_client_data(device, &cm_client, cm_dev);
+       ib_set_client_data(ib_device, &cm_client, cm_dev);
 
        write_lock_irqsave(&cm.device_lock, flags);
        list_add_tail(&cm_dev->list, &cm.device_list);
@@ -3753,14 +3743,14 @@ error1:
        port_modify.clr_port_cap_mask = IB_PORT_CM_SUP;
        while (--i) {
                port = cm_dev->port[i-1];
-               ib_modify_port(device, port->port_num, 0, &port_modify);
+               ib_modify_port(ib_device, port->port_num, 0, &port_modify);
                ib_unregister_mad_agent(port->mad_agent);
                cm_remove_port_fs(port);
        }
-       kobject_put(&cm_dev->dev_obj);
+       device_unregister(cm_dev->device);
 }
 
-static void cm_remove_one(struct ib_device *device)
+static void cm_remove_one(struct ib_device *ib_device)
 {
        struct cm_device *cm_dev;
        struct cm_port *port;
@@ -3770,7 +3760,7 @@ static void cm_remove_one(struct ib_device *device)
        unsigned long flags;
        int i;
 
-       cm_dev = ib_get_client_data(device, &cm_client);
+       cm_dev = ib_get_client_data(ib_device, &cm_client);
        if (!cm_dev)
                return;
 
@@ -3778,14 +3768,14 @@ static void cm_remove_one(struct ib_device *device)
        list_del(&cm_dev->list);
        write_unlock_irqrestore(&cm.device_lock, flags);
 
-       for (i = 1; i <= device->phys_port_cnt; i++) {
+       for (i = 1; i <= ib_device->phys_port_cnt; i++) {
                port = cm_dev->port[i-1];
-               ib_modify_port(device, port->port_num, 0, &port_modify);
+               ib_modify_port(ib_device, port->port_num, 0, &port_modify);
                ib_unregister_mad_agent(port->mad_agent);
                flush_workqueue(cm.wq);
                cm_remove_port_fs(port);
        }
-       kobject_put(&cm_dev->dev_obj);
+       device_unregister(cm_dev->device);
 }
 
 static int __init ib_cm_init(void)
index 35f301c88b57196d0098e5a7d86ef5adba157d8b..56c0eda3c0772816f09e9b975090707929b826f3 100644 (file)
@@ -2455,7 +2455,7 @@ static int init_cdev(int minor, char *name, const struct file_operations *fops,
                goto err_cdev;
        }
 
-       device = device_create(ipath_class, NULL, dev, name);
+       device = device_create_drvdata(ipath_class, NULL, dev, NULL, name);
 
        if (IS_ERR(device)) {
                ret = PTR_ERR(device);
index c21f2f1272345b6f56a79fb396af2d1e894ef90a..0353601ac3b575e9a7e968387ec22d10fb88c04e 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: evbug.c,v 1.10 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 
@@ -41,7 +39,7 @@ MODULE_LICENSE("GPL");
 static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
 {
        printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n",
-               handle->dev->phys, type, code, value);
+               handle->dev->dev.bus_id, type, code, value);
 }
 
 static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
@@ -66,7 +64,10 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
        if (error)
                goto err_unregister_handle;
 
-       printk(KERN_DEBUG "evbug.c: Connected device: \"%s\", %s\n", dev->name, dev->phys);
+       printk(KERN_DEBUG "evbug.c: Connected device: %s (%s at %s)\n",
+               dev->dev.bus_id,
+               dev->name ?: "unknown",
+               dev->phys ?: "unknown");
 
        return 0;
 
@@ -79,7 +80,8 @@ static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
 
 static void evbug_disconnect(struct input_handle *handle)
 {
-       printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys);
+       printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n",
+               handle->dev->dev.bus_id);
 
        input_close_device(handle);
        input_unregister_handle(handle);
index b32984bc516ff271cacbe72b56a60350bef63868..2d65411f6763499198ecc922e928b02481678e4b 100644 (file)
@@ -300,6 +300,35 @@ struct input_event_compat {
        __s32 value;
 };
 
+struct ff_periodic_effect_compat {
+       __u16 waveform;
+       __u16 period;
+       __s16 magnitude;
+       __s16 offset;
+       __u16 phase;
+
+       struct ff_envelope envelope;
+
+       __u32 custom_len;
+       compat_uptr_t custom_data;
+};
+
+struct ff_effect_compat {
+       __u16 type;
+       __s16 id;
+       __u16 direction;
+       struct ff_trigger trigger;
+       struct ff_replay replay;
+
+       union {
+               struct ff_constant_effect constant;
+               struct ff_ramp_effect ramp;
+               struct ff_periodic_effect_compat periodic;
+               struct ff_condition_effect condition[2]; /* One for each axis */
+               struct ff_rumble_effect rumble;
+       } u;
+};
+
 /* Note to the author of this code: did it ever occur to
    you why the ifdefs are needed? Think about it again. -AK */
 #ifdef CONFIG_X86_64
@@ -368,6 +397,42 @@ static int evdev_event_to_user(char __user *buffer,
        return 0;
 }
 
+static int evdev_ff_effect_from_user(const char __user *buffer, size_t size,
+                                    struct ff_effect *effect)
+{
+       if (COMPAT_TEST) {
+               struct ff_effect_compat *compat_effect;
+
+               if (size != sizeof(struct ff_effect_compat))
+                       return -EINVAL;
+
+               /*
+                * It so happens that the pointer which needs to be changed
+                * is the last field in the structure, so we can copy the
+                * whole thing and replace just the pointer.
+                */
+
+               compat_effect = (struct ff_effect_compat *)effect;
+
+               if (copy_from_user(compat_effect, buffer,
+                                  sizeof(struct ff_effect_compat)))
+                       return -EFAULT;
+
+               if (compat_effect->type == FF_PERIODIC &&
+                   compat_effect->u.periodic.waveform == FF_CUSTOM)
+                       effect->u.periodic.custom_data =
+                               compat_ptr(compat_effect->u.periodic.custom_data);
+       } else {
+               if (size != sizeof(struct ff_effect))
+                       return -EINVAL;
+
+               if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
+                       return -EFAULT;
+       }
+
+       return 0;
+}
+
 #else
 
 static inline size_t evdev_event_size(void)
@@ -393,6 +458,18 @@ static int evdev_event_to_user(char __user *buffer,
        return 0;
 }
 
+static int evdev_ff_effect_from_user(const char __user *buffer, size_t size,
+                                    struct ff_effect *effect)
+{
+       if (size != sizeof(struct ff_effect))
+               return -EINVAL;
+
+       if (copy_from_user(effect, buffer, sizeof(struct ff_effect)))
+               return -EFAULT;
+
+       return 0;
+}
+
 #endif /* CONFIG_COMPAT */
 
 static ssize_t evdev_write(struct file *file, const char __user *buffer,
@@ -633,17 +710,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 
                return input_set_keycode(dev, t, v);
 
-       case EVIOCSFF:
-               if (copy_from_user(&effect, p, sizeof(effect)))
-                       return -EFAULT;
-
-               error = input_ff_upload(dev, &effect, file);
-
-               if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
-                       return -EFAULT;
-
-               return error;
-
        case EVIOCRMFF:
                return input_ff_erase(dev, (int)(unsigned long) p, file);
 
@@ -733,6 +799,19 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 
                if (_IOC_DIR(cmd) == _IOC_WRITE) {
 
+                       if (_IOC_NR(cmd) == _IOC_NR(EVIOCSFF)) {
+
+                               if (evdev_ff_effect_from_user(p, _IOC_SIZE(cmd), &effect))
+                                       return -EFAULT;
+
+                               error = input_ff_upload(dev, &effect, file);
+
+                               if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
+                                       return -EFAULT;
+
+                               return error;
+                       }
+
                        if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
 
                                t = _IOC_NR(cmd) & ABS_MAX;
index d226d935b0dcd57afc9c0e3fb921c47f3005bf92..6790e975a98c327fd038198f535be9fc9059ab5b 100644 (file)
@@ -247,9 +247,9 @@ static void ml_combine_effects(struct ff_effect *effect,
                 * in s8, this should be changed to something more generic
                 */
                effect->u.ramp.start_level =
-                       max(min(effect->u.ramp.start_level + x, 0x7f), -0x80);
+                       clamp_val(effect->u.ramp.start_level + x, -0x80, 0x7f);
                effect->u.ramp.end_level =
-                       max(min(effect->u.ramp.end_level + y, 0x7f), -0x80);
+                       clamp_val(effect->u.ramp.end_level + y, -0x80, 0x7f);
                break;
 
        case FF_RUMBLE:
index 9793ac36d17f22bd34861e14c7af14ea48b06283..b04930f7ea7da88e36e65a9c9faa9f188778de93 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: emu10k1-gp.c,v 1.8 2002/01/22 20:40:46 vojtech Exp $
- *
  *  Copyright (c) 2001 Vojtech Pavlik
  */
 
index c5600ac5feb3aa6c99dba80628d501d515488ebf..078e4eed0894ba45a495184bb91b6518935663b9 100644 (file)
@@ -36,7 +36,6 @@ EXPORT_SYMBOL(__gameport_register_driver);
 EXPORT_SYMBOL(gameport_unregister_driver);
 EXPORT_SYMBOL(gameport_open);
 EXPORT_SYMBOL(gameport_close);
-EXPORT_SYMBOL(gameport_rescan);
 EXPORT_SYMBOL(gameport_set_phys);
 EXPORT_SYMBOL(gameport_start_polling);
 EXPORT_SYMBOL(gameport_stop_polling);
@@ -230,8 +229,6 @@ static void gameport_find_driver(struct gameport *gameport)
  */
 
 enum gameport_event_type {
-       GAMEPORT_RESCAN,
-       GAMEPORT_RECONNECT,
        GAMEPORT_REGISTER_PORT,
        GAMEPORT_REGISTER_DRIVER,
 };
@@ -365,15 +362,6 @@ static void gameport_handle_event(void)
                                gameport_add_port(event->object);
                                break;
 
-                       case GAMEPORT_RECONNECT:
-                               gameport_reconnect_port(event->object);
-                               break;
-
-                       case GAMEPORT_RESCAN:
-                               gameport_disconnect_port(event->object);
-                               gameport_find_driver(event->object);
-                               break;
-
                        case GAMEPORT_REGISTER_DRIVER:
                                gameport_add_driver(event->object);
                                break;
@@ -651,16 +639,6 @@ static void gameport_disconnect_port(struct gameport *gameport)
        device_release_driver(&gameport->dev);
 }
 
-void gameport_rescan(struct gameport *gameport)
-{
-       gameport_queue_event(gameport, NULL, GAMEPORT_RESCAN);
-}
-
-void gameport_reconnect(struct gameport *gameport)
-{
-       gameport_queue_event(gameport, NULL, GAMEPORT_RECONNECT);
-}
-
 /*
  * Submits register request to kgameportd for subsequent execution.
  * Note that port registration is always asynchronous.
index 6b4d4561d465bb133cb33d688c5fc4a4036f0de3..06ad36ed348329e9ff4d4dabb7141eb07cd61d56 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: lightning.c,v 1.20 2002/01/22 20:41:31 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  */
 
index 7b7a546323cfc1c2d65fea2663d1f3f50399f78e..2b282cde4b89bca7af7010f4127f6cfc93d81a8e 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: ns558.c,v 1.43 2002/01/24 19:23:21 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *  Copyright (c) 1999 Brian Gerst
  */
index 408df0bd6be50a0b17798b189506c266d0ba34bf..c13ced3e0d3dfe7d0db777776c1b51a2cf4f59e5 100644 (file)
@@ -242,7 +242,7 @@ static void input_handle_event(struct input_dev *dev,
                break;
        }
 
-       if (type != EV_SYN)
+       if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
                dev->sync = 0;
 
        if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
index 52ba16f487c793a36acc464dc4c0e3cc80e77fbc..92498d470b1f7de7323eed8b87dfcd8dffa72d7e 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: a3d.c,v 1.21 2002/01/22 20:11:50 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  */
 
index deb9f825f92c34e6caffa165b480b013bc6dea5f..05022f07ec77581e7f1537f49ee528d3f0fb4e21 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: amijoy.c,v 1.13 2002/01/22 20:26:32 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  */
 
index 55646a6d89f586de8f35616a947b41c84bd854c2..639b975a8ed7a6c64ecb06f315dffa45eb2b5a1a 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: cobra.c,v 1.19 2002/01/22 20:26:52 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 
index 960e501c60c8627315721118439a1b878a0694ab..523959484753fdabf3e9faa2dddb8ca45c8370c4 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: db9.c,v 1.13 2002/04/07 20:13:37 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:
index 1f6302c0eb3fd8e47c5f8e5a5edfdd95836d5fe8..cb6eef1f2d99f6d7b80a9f5e02d7411ececbd153 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: gf2k.c,v 1.19 2002/01/22 20:27:43 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  */
 
index fd3853ab1aad4db5499cea82c62872d720c16edc..684e07cfccc89a862d25897b9e0c760e5dd79965 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: grip.c,v 1.21 2002/01/22 20:27:57 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  */
 
index c57e21d68c003e2970949744120b3384b8fe98e6..8279481b16e7bbf038b70991dfe1d5ec6f16fff3 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: grip_mp.c,v 1.9 2002/07/20 19:28:45 bonnland Exp $
- *
  *  Driver for the Gravis Grip Multiport, a gamepad "hub" that
  *  connects up to four 9-pin digital gamepads/joysticks.
  *  Driver tested on SMP and UP kernel versions 2.4.18-4 and 2.4.18-5.
index aa6bfb3fb8cd2b135201e97b7ee7dc99d6263660..25ec3fad9f2798d5126cec44e6b570a819152270 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: guillemot.c,v 1.10 2002/01/22 20:28:12 vojtech Exp $
- *
  *  Copyright (c) 2001 Vojtech Pavlik
  */
 
index f2a4381d0ab80cf899672defc8779483118b0bca..7839b7b6fa9650c2d0b7650cef04b5a5177cda33 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: iforce-ff.c,v 1.9 2002/02/02 19:28:35 jdeneux Exp $
- *
  *  Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
  *  Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
  *
index a2517fa72eb8e06a15b47c1d9ae94a253258f30d..61ee6e38739dd3a84dd2244197e3060fd57102d4 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: iforce-main.c,v 1.19 2002/07/07 10:22:50 jdeneux Exp $
- *
  *  Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
  *  Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
  *
index 45c4939ced75ef45228075d8d5c9784d7bb5a486..015b50aa76fcf5f7fe752b2f63cf857bdf9c9a26 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: iforce-packets.c,v 1.16 2002/07/07 10:22:50 jdeneux Exp $
- *
  *  Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
  *  Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
  *
index 7b4bc19cef27c3bd3ea1cbfc5c0bfdd5d6a39066..46d5041d2d9dbbdf174d1ed66ac74c85c60f7c5b 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: iforce-serio.c,v 1.4 2002/01/28 22:45:00 jdeneux Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
  *  Copyright (c) 2001, 2007 Johann Deneux <johann.deneux@gmail.com>
  *
index 7fb3cf81cfbffcb234d5954b040d7ff9d24340fd..851cc4087c2fbdbb1cf75dec8619310df5b0f683 100644 (file)
@@ -1,6 +1,4 @@
  /*
- * $Id: iforce-usb.c,v 1.16 2002/06/09 11:08:04 jdeneux Exp $
- *
  *  Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
  *  Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
  *
@@ -89,10 +87,10 @@ static void iforce_usb_irq(struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d",
-                   __FUNCTION__, urb->status);
+                   __func__, urb->status);
                return;
        default:
-               dbg("%s - urb has status of: %d", __FUNCTION__, urb->status);
+               dbg("%s - urb has status of: %d", __func__, urb->status);
                goto exit;
        }
 
@@ -103,7 +101,7 @@ exit:
        status = usb_submit_urb (urb, GFP_ATOMIC);
        if (status)
                err ("%s - usb_submit_urb failed with result %d",
-                    __FUNCTION__, status);
+                    __func__, status);
 }
 
 static void iforce_usb_out(struct urb *urb)
index a964a7cfd210cdc29b4fac6fcd9ee4c2c230d60b..f2d91f4028cace50888876ef28685c3eff2cb44d 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: iforce.h,v 1.13 2002/07/07 10:22:50 jdeneux Exp $
- *
  *  Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
  *  Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
  *
index bc8ea95dfd0e8328736097ec4b1b132256d978ca..8c3290b68205b933f76223ab139ed5a71aaeb518 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: interact.c,v 1.16 2002/01/22 20:28:25 vojtech Exp $
- *
  *  Copyright (c) 2001 Vojtech Pavlik
  *
  *  Based on the work of:
index 88ec5a918f2e80ea980f7098075553f5a782f94f..2a1b82c8b31c155c8c698741317a200b90898dcd 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: joydump.c,v 1.1 2002/01/23 06:56:16 jsimmons Exp $
- *
  *  Copyright (c) 1996-2001 Vojtech Pavlik
  */
 
index 54e676948ebb1caa777dee0195f942fb876478e3..40e40780747d50d2536824045171370a61f667bb 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: magellan.c,v 1.16 2002/01/22 20:28:39 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 
index d4087fd496563367bea2c7894c1e4a71c8477853..0cd9b29356a8a5f06bb31885ef0581fa5c57f2dc 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: spaceball.c,v 1.17 2002/01/22 20:29:03 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:
index f7ce4004f4ba1baf036766e5af0f90d7ef14c8e1..a694bf8e557bbca7ec84e2101a0e895a226f5d34 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: spaceorb.c,v 1.15 2002/01/22 20:29:19 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:
index baa10b2f7ba1c74843b8d8bbf2060e3649b045f7..e0db9f5e4b413962baa220b37ee4640927e51882 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: stinger.c,v 1.10 2002/01/22 20:29:31 vojtech Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *  Copyright (c) 2000 Mark Fletcher
  */
index 0feeb8acb532a297a819d5713a3aa2bce3490af8..60c37bcb938d932d78bbd7a1065be2c6e335564f 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: tmdc.c,v 1.31 2002/01/22 20:29:52 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  *
  *   Based on the work of:
index 989483f5316008853912dd88c2717d5b32ef1ab5..b6f859869540d3b1995acc4c50b3edde52d9d4a1 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: turbografx.c,v 1.14 2002/01/22 20:30:39 vojtech Exp $
- *
  *  Copyright (c) 1998-2001 Vojtech Pavlik
  *
  *  Based on the work of:
index 1085c841fec48ca932263e898b0e759ca363fb62..3f4ec73c9553a2debeb52f2789b3e016a555b7cb 100644 (file)
@@ -1,8 +1,4 @@
 /*
- * $Id: twidjoy.c,v 1.5 2002/01/22 20:31:53 vojtech Exp $
- *
- *  derived from CVS-ID "stinger.c,v 1.5 2001/05/29 12:57:18 vojtech Exp"
- *
  *  Copyright (c) 2001 Arndt Schoenewald
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *  Copyright (c) 2000 Mark Fletcher
index e928b6e3724a528b632f1a3af472073eaf888419..f72c83e15e6020ddfa288558011ef8918efaa3d3 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: warrior.c,v 1.14 2002/01/22 20:32:10 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 
index b29e3affb805a97126ccee39dcc867cd6e40dfe3..87d3e7eabffd3e57b6b32714701b3cc7d65eb312 100644 (file)
@@ -418,11 +418,11 @@ static void xpad_irq_in(struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d",
-                       __FUNCTION__, status);
+                       __func__, status);
                return;
        default:
                dbg("%s - nonzero urb status received: %d",
-                       __FUNCTION__, status);
+                       __func__, status);
                goto exit;
        }
 
@@ -441,7 +441,7 @@ exit:
        retval = usb_submit_urb (urb, GFP_ATOMIC);
        if (retval)
                err ("%s - usb_submit_urb failed with result %d",
-                    __FUNCTION__, retval);
+                    __func__, retval);
 }
 
 static void xpad_bulk_out(struct urb *urb)
@@ -477,11 +477,11 @@ static void xpad_irq_out(struct urb *urb)
                case -ESHUTDOWN:
                        /* this urb is terminated, clean up */
                        dbg("%s - urb shutting down with status: %d",
-                               __FUNCTION__, status);
+                               __func__, status);
                        return;
                default:
                        dbg("%s - nonzero urb status received: %d",
-                               __FUNCTION__, status);
+                               __func__, status);
                        goto exit;
        }
 
@@ -489,7 +489,7 @@ exit:
        retval = usb_submit_urb(urb, GFP_ATOMIC);
        if (retval)
                err("%s - usb_submit_urb failed with result %d",
-                   __FUNCTION__, retval);
+                   __func__, retval);
 }
 
 static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
index 81bf7562aca0d94c65c7ec75278c240055692916..35149ec455a9fa3770a33ae2e1c61e2d6fb06a02 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: amikbd.c,v 1.13 2002/02/01 16:02:24 vojtech Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *
  *  Based on the work of:
index af58a6f1e898278b42bdd5980d51b10718fd807e..b1ce10f50bcfcf7a14eca2c8c4cd9606efaecd90 100644 (file)
@@ -68,7 +68,7 @@ MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and
  * are loadable via an userland utility.
  */
 
-static unsigned char atkbd_set2_keycode[512] = {
+static const unsigned short atkbd_set2_keycode[512] = {
 
 #ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES
 
@@ -99,7 +99,7 @@ static unsigned char atkbd_set2_keycode[512] = {
 #endif
 };
 
-static unsigned char atkbd_set3_keycode[512] = {
+static const unsigned short atkbd_set3_keycode[512] = {
 
          0,  0,  0,  0,  0,  0,  0, 59,  1,138,128,129,130, 15, 41, 60,
        131, 29, 42, 86, 58, 16,  2, 61,133, 56, 44, 31, 30, 17,  3, 62,
@@ -115,7 +115,7 @@ static unsigned char atkbd_set3_keycode[512] = {
        148,149,147,140
 };
 
-static unsigned char atkbd_unxlate_table[128] = {
+static const unsigned short atkbd_unxlate_table[128] = {
           0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
          21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
          35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
@@ -161,7 +161,7 @@ static unsigned char atkbd_unxlate_table[128] = {
 #define ATKBD_SCR_LEFT         249
 #define ATKBD_SCR_RIGHT                248
 
-#define ATKBD_SPECIAL          248
+#define ATKBD_SPECIAL          ATKBD_SCR_RIGHT
 
 #define ATKBD_LED_EVENT_BIT    0
 #define ATKBD_REP_EVENT_BIT    1
@@ -173,7 +173,7 @@ static unsigned char atkbd_unxlate_table[128] = {
 #define ATKBD_XL_HANGEUL       0x10
 #define ATKBD_XL_HANJA         0x20
 
-static struct {
+static const struct {
        unsigned char keycode;
        unsigned char set2;
 } atkbd_scroll_keys[] = {
@@ -200,7 +200,7 @@ struct atkbd {
        char phys[32];
 
        unsigned short id;
-       unsigned char keycode[512];
+       unsigned short keycode[512];
        DECLARE_BITMAP(force_release_mask, 512);
        unsigned char set;
        unsigned char translated;
@@ -357,7 +357,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
        unsigned int code = data;
        int scroll = 0, hscroll = 0, click = -1;
        int value;
-       unsigned char keycode;
+       unsigned short keycode;
 
 #ifdef ATKBD_DEBUG
        printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
@@ -850,6 +850,23 @@ static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd)
                                  atkbd->force_release_mask);
 }
 
+/*
+ * Perform fixup for HP system that doesn't generate release
+ * for its video switch
+ */
+static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)
+{
+       const unsigned int forced_release_keys[] = {
+               0x94,
+       };
+       int i;
+
+       if (atkbd->set == 2)
+               for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
+                       __set_bit(forced_release_keys[i],
+                                       atkbd->force_release_mask);
+}
+
 /*
  * atkbd_set_keycode_table() initializes keyboard's keycode table
  * according to the selected scancode set
@@ -961,16 +978,16 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
                input_dev->evbit[0] |= BIT_MASK(EV_REL);
                input_dev->relbit[0] = BIT_MASK(REL_WHEEL) |
                        BIT_MASK(REL_HWHEEL);
-               set_bit(BTN_MIDDLE, input_dev->keybit);
+               __set_bit(BTN_MIDDLE, input_dev->keybit);
        }
 
        input_dev->keycode = atkbd->keycode;
-       input_dev->keycodesize = sizeof(unsigned char);
+       input_dev->keycodesize = sizeof(unsigned short);
        input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
 
        for (i = 0; i < 512; i++)
                if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
-                       set_bit(atkbd->keycode[i], input_dev->keybit);
+                       __set_bit(atkbd->keycode[i], input_dev->keybit);
 }
 
 /*
@@ -1452,6 +1469,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
                .callback = atkbd_setup_fixup,
                .driver_data = atkbd_latitude_keymap_fixup,
        },
+       {
+               .ident = "HP 2133",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"),
+               },
+               .callback = atkbd_setup_fixup,
+               .driver_data = atkbd_hp_keymap_fixup,
+       },
        { }
 };
 
index bbd00c3fe98ca18999b19c011a8c0040f3e9fb9b..be58730e636a4323c1aca62d136e94ec40700bcf 100644 (file)
 
 #include <asm/gpio.h>
 
+struct gpio_button_data {
+       struct gpio_keys_button *button;
+       struct input_dev *input;
+       struct timer_list timer;
+};
+
+struct gpio_keys_drvdata {
+       struct input_dev *input;
+       struct gpio_button_data data[0];
+};
+
+static void gpio_keys_report_event(struct gpio_keys_button *button,
+                                  struct input_dev *input)
+{
+       unsigned int type = button->type ?: EV_KEY;
+       int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;
+
+       input_event(input, type, button->code, !!state);
+       input_sync(input);
+}
+
+static void gpio_check_button(unsigned long _data)
+{
+       struct gpio_button_data *data = (struct gpio_button_data *)_data;
+
+       gpio_keys_report_event(data->button, data->input);
+}
+
 static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
 {
-       int i;
        struct platform_device *pdev = dev_id;
        struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
-       struct input_dev *input = platform_get_drvdata(pdev);
+       struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
+       int i;
 
        for (i = 0; i < pdata->nbuttons; i++) {
                struct gpio_keys_button *button = &pdata->buttons[i];
-               int gpio = button->gpio;
 
-               if (irq == gpio_to_irq(gpio)) {
-                       unsigned int type = button->type ?: EV_KEY;
-                       int state = (gpio_get_value(gpio) ? 1 : 0) ^ button->active_low;
+               if (irq == gpio_to_irq(button->gpio)) {
+                       struct gpio_button_data *bdata = &ddata->data[i];
+
+                       if (button->debounce_interval)
+                               mod_timer(&bdata->timer,
+                                         jiffies +
+                                         msecs_to_jiffies(button->debounce_interval));
+                       else
+                               gpio_keys_report_event(button, bdata->input);
 
-                       input_event(input, type, button->code, !!state);
-                       input_sync(input);
                        return IRQ_HANDLED;
                }
        }
@@ -53,17 +84,21 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
 static int __devinit gpio_keys_probe(struct platform_device *pdev)
 {
        struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+       struct gpio_keys_drvdata *ddata;
        struct input_dev *input;
        int i, error;
        int wakeup = 0;
 
+       ddata = kzalloc(sizeof(struct gpio_keys_drvdata) +
+                       pdata->nbuttons * sizeof(struct gpio_button_data),
+                       GFP_KERNEL);
        input = input_allocate_device();
-       if (!input)
-               return -ENOMEM;
-
-       platform_set_drvdata(pdev, input);
+       if (!ddata || !input) {
+               error = -ENOMEM;
+               goto fail1;
+       }
 
-       input->evbit[0] = BIT_MASK(EV_KEY);
+       platform_set_drvdata(pdev, ddata);
 
        input->name = pdev->name;
        input->phys = "gpio-keys/input0";
@@ -74,16 +109,23 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
        input->id.product = 0x0001;
        input->id.version = 0x0100;
 
+       ddata->input = input;
+
        for (i = 0; i < pdata->nbuttons; i++) {
                struct gpio_keys_button *button = &pdata->buttons[i];
+               struct gpio_button_data *bdata = &ddata->data[i];
                int irq;
                unsigned int type = button->type ?: EV_KEY;
 
+               bdata->input = input;
+               setup_timer(&bdata->timer,
+                           gpio_check_button, (unsigned long)bdata);
+
                error = gpio_request(button->gpio, button->desc ?: "gpio_keys");
                if (error < 0) {
                        pr_err("gpio-keys: failed to request GPIO %d,"
                                " error %d\n", button->gpio, error);
-                       goto fail;
+                       goto fail2;
                }
 
                error = gpio_direction_input(button->gpio);
@@ -92,7 +134,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
                                " direction for GPIO %d, error %d\n",
                                button->gpio, error);
                        gpio_free(button->gpio);
-                       goto fail;
+                       goto fail2;
                }
 
                irq = gpio_to_irq(button->gpio);
@@ -102,7 +144,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
                                " for GPIO %d, error %d\n",
                                button->gpio, error);
                        gpio_free(button->gpio);
-                       goto fail;
+                       goto fail2;
                }
 
                error = request_irq(irq, gpio_keys_isr,
@@ -114,7 +156,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
                        pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
                                irq, error);
                        gpio_free(button->gpio);
-                       goto fail;
+                       goto fail2;
                }
 
                if (button->wakeup)
@@ -127,21 +169,25 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
        if (error) {
                pr_err("gpio-keys: Unable to register input device, "
                        "error: %d\n", error);
-               goto fail;
+               goto fail2;
        }
 
        device_init_wakeup(&pdev->dev, wakeup);
 
        return 0;
 
- fail:
+ fail2:
        while (--i >= 0) {
                free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev);
+               if (pdata->buttons[i].debounce_interval)
+                       del_timer_sync(&ddata->data[i].timer);
                gpio_free(pdata->buttons[i].gpio);
        }
 
        platform_set_drvdata(pdev, NULL);
+ fail1:
        input_free_device(input);
+       kfree(ddata);
 
        return error;
 }
@@ -149,7 +195,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
 static int __devexit gpio_keys_remove(struct platform_device *pdev)
 {
        struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
-       struct input_dev *input = platform_get_drvdata(pdev);
+       struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
+       struct input_dev *input = ddata->input;
        int i;
 
        device_init_wakeup(&pdev->dev, 0);
@@ -157,6 +204,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
        for (i = 0; i < pdata->nbuttons; i++) {
                int irq = gpio_to_irq(pdata->buttons[i].gpio);
                free_irq(irq, pdev);
+               if (pdata->buttons[i].debounce_interval)
+                       del_timer_sync(&ddata->data[i].timer);
                gpio_free(pdata->buttons[i].gpio);
        }
 
index 32e2c2605d95f3b8647136c2f6de6cba918353a7..4730ef35c732dbc1210fb2a5b0adc3e4551b6caf 100644 (file)
@@ -538,11 +538,11 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
                        switch (code) {
                                case SND_CLICK:
                                        if (value == 0) {
-                                               DBG ("%s: Deactivating key clicks\n", __FUNCTION__);
+                                               DBG ("%s: Deactivating key clicks\n", __func__);
                                                lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
                                                lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
                                        } else {
-                                               DBG ("%s: Activating key clicks\n", __FUNCTION__);
+                                               DBG ("%s: Activating key clicks\n", __func__);
                                                lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
                                                lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
                                                lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
@@ -560,7 +560,7 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
 
                default:
                        printk (KERN_ERR "%s (): Got unknown type %d, code %d, value %d\n",
-                                       __FUNCTION__, type, code, value);
+                                       __func__, type, code, value);
        }
 
        return -1;
index 45767e73f071e3859ffccebaa7a82d1578019530..6f1516f5075072ebde372743713e504685b8d990 100644 (file)
@@ -105,6 +105,8 @@ struct pxa27x_keypad {
        struct input_dev *input_dev;
        void __iomem *mmio_base;
 
+       int irq;
+
        /* matrix key code map */
        unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM];
 
@@ -392,6 +394,10 @@ static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t stat
        struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
 
        clk_disable(keypad->clk);
+
+       if (device_may_wakeup(&pdev->dev))
+               enable_irq_wake(keypad->irq);
+
        return 0;
 }
 
@@ -400,6 +406,9 @@ static int pxa27x_keypad_resume(struct platform_device *pdev)
        struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
        struct input_dev *input_dev = keypad->input_dev;
 
+       if (device_may_wakeup(&pdev->dev))
+               disable_irq_wake(keypad->irq);
+
        mutex_lock(&input_dev->mutex);
 
        if (input_dev->users) {
@@ -509,6 +518,8 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
                goto failed_free_dev;
        }
 
+       keypad->irq = irq;
+
        /* Register the input device */
        error = input_register_device(input_dev);
        if (error) {
@@ -516,6 +527,8 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
                goto failed_free_irq;
        }
 
+       device_init_wakeup(&pdev->dev, 1);
+
        return 0;
 
 failed_free_irq:
@@ -539,7 +552,7 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev)
        struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
        struct resource *res;
 
-       free_irq(platform_get_irq(pdev, 0), pdev);
+       free_irq(keypad->irq, pdev);
 
        clk_disable(keypad->clk);
        clk_put(keypad->clk);
index be0f5d19d0238590f2ffd219a5ef602e505fcb3c..9fce6d1e29b20bbc2e03f6e3e1a3d39f93c61b9d 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: sunkbd.c,v 1.14 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 
index 94e444b4ee1523c4539b687383eaa9c35a52fcfe..b12b7ee4b6aa304e9096e9b50afbaeca1beae24b 100644 (file)
@@ -215,8 +215,6 @@ static int tosakbd_suspend(struct platform_device *dev, pm_message_t state)
        unsigned long flags;
 
        spin_lock_irqsave(&tosakbd->lock, flags);
-       PGSR1 = (PGSR1 & ~TOSA_GPIO_LOW_STROBE_BIT);
-       PGSR2 = (PGSR2 & ~TOSA_GPIO_HIGH_STROBE_BIT);
        tosakbd->suspended = 1;
        spin_unlock_irqrestore(&tosakbd->lock, flags);
 
index 152a2c0705080f6432fcfb2f4fb4e27c7fa4d47e..37b01d777a4abc2ccf8652d91a15839bee41d334 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: xtkbd.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 
index 432699d61c58ed3e8b39d4d5d250b045a972abc4..e99b7882f3826e3d9f4563eb48ece92d8085fb03 100644 (file)
@@ -189,6 +189,16 @@ config INPUT_UINPUT
          To compile this driver as a module, choose M here: the
          module will be called uinput.
 
+config INPUT_SGI_BTNS
+       tristate "SGI Indy/O2 volume button interface"
+       depends on SGI_IP22 || SGI_IP32
+       select INPUT_POLLDEV
+       help
+         Say Y here if you want to support SGI Indy/O2 volume button interface.
+
+         To compile this driver as a module, choose M here: the
+         module will be called sgi_btns.
+
 config HP_SDC_RTC
        tristate "HP SDC Real Time Clock"
        depends on GSC || HP300
index ebd39f291d259b74325a719e56da7d193e75d4b5..f48009b52226ba94b69965daf1a9eaa968da5764 100644 (file)
@@ -19,3 +19,4 @@ obj-$(CONFIG_INPUT_YEALINK)           += yealink.o
 obj-$(CONFIG_HP_SDC_RTC)               += hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_UINPUT)             += uinput.o
 obj-$(CONFIG_INPUT_APANEL)             += apanel.o
+obj-$(CONFIG_INPUT_SGI_BTNS)           += sgi_btns.o
index f3b86c2b0797053c07dcc6a0f2166839bf889140..debfc1af9d95f91436a5e1e17430f20ff857e338 100644 (file)
@@ -330,7 +330,7 @@ static int ati_remote_open(struct input_dev *inputdev)
        ati_remote->irq_urb->dev = ati_remote->udev;
        if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) {
                dev_err(&ati_remote->interface->dev,
-                       "%s: usb_submit_urb failed!\n", __FUNCTION__);
+                       "%s: usb_submit_urb failed!\n", __func__);
                return -EIO;
        }
 
@@ -356,7 +356,7 @@ static void ati_remote_irq_out(struct urb *urb)
 
        if (urb->status) {
                dev_dbg(&ati_remote->interface->dev, "%s: status %d\n",
-                       __FUNCTION__, urb->status);
+                       __func__, urb->status);
                return;
        }
 
@@ -601,17 +601,17 @@ static void ati_remote_irq_in(struct urb *urb)
        case -ENOENT:
        case -ESHUTDOWN:
                dev_dbg(&ati_remote->interface->dev, "%s: urb error status, unlink? \n",
-                       __FUNCTION__);
+                       __func__);
                return;
        default:                /* error */
                dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n",
-                       __FUNCTION__, urb->status);
+                       __func__, urb->status);
        }
 
        retval = usb_submit_urb(urb, GFP_ATOMIC);
        if (retval)
                dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n",
-                       __FUNCTION__, retval);
+                       __func__, retval);
 }
 
 /*
@@ -734,7 +734,7 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
        int err = -ENOMEM;
 
        if (iface_host->desc.bNumEndpoints != 2) {
-               err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__);
+               err("%s: Unexpected desc.bNumEndpoints\n", __func__);
                return -ENODEV;
        }
 
@@ -742,11 +742,11 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
        endpoint_out = &iface_host->endpoint[1].desc;
 
        if (!usb_endpoint_is_int_in(endpoint_in)) {
-               err("%s: Unexpected endpoint_in\n", __FUNCTION__);
+               err("%s: Unexpected endpoint_in\n", __func__);
                return -ENODEV;
        }
        if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) {
-               err("%s: endpoint_in message size==0? \n", __FUNCTION__);
+               err("%s: endpoint_in message size==0? \n", __func__);
                return -ENODEV;
        }
 
@@ -814,7 +814,7 @@ static void ati_remote_disconnect(struct usb_interface *interface)
        ati_remote = usb_get_intfdata(interface);
        usb_set_intfdata(interface, NULL);
        if (!ati_remote) {
-               warn("%s - null device?\n", __FUNCTION__);
+               warn("%s - null device?\n", __func__);
                return;
        }
 
index f2709b82485c181067b8a8fccab942a83bd425ed..a7fabafbd94c6e9fe3691db3b18caea49a835b88 100644 (file)
@@ -137,14 +137,14 @@ static int ati_remote2_open(struct input_dev *idev)
        r = usb_submit_urb(ar2->urb[0], GFP_KERNEL);
        if (r) {
                dev_err(&ar2->intf[0]->dev,
-                       "%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
+                       "%s: usb_submit_urb() = %d\n", __func__, r);
                return r;
        }
        r = usb_submit_urb(ar2->urb[1], GFP_KERNEL);
        if (r) {
                usb_kill_urb(ar2->urb[0]);
                dev_err(&ar2->intf[1]->dev,
-                       "%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
+                       "%s: usb_submit_urb() = %d\n", __func__, r);
                return r;
        }
 
@@ -294,17 +294,17 @@ static void ati_remote2_complete_mouse(struct urb *urb)
        case -ECONNRESET:
        case -ESHUTDOWN:
                dev_dbg(&ar2->intf[0]->dev,
-                       "%s(): urb status = %d\n", __FUNCTION__, urb->status);
+                       "%s(): urb status = %d\n", __func__, urb->status);
                return;
        default:
                dev_err(&ar2->intf[0]->dev,
-                       "%s(): urb status = %d\n", __FUNCTION__, urb->status);
+                       "%s(): urb status = %d\n", __func__, urb->status);
        }
 
        r = usb_submit_urb(urb, GFP_ATOMIC);
        if (r)
                dev_err(&ar2->intf[0]->dev,
-                       "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
+                       "%s(): usb_submit_urb() = %d\n", __func__, r);
 }
 
 static void ati_remote2_complete_key(struct urb *urb)
@@ -321,17 +321,17 @@ static void ati_remote2_complete_key(struct urb *urb)
        case -ECONNRESET:
        case -ESHUTDOWN:
                dev_dbg(&ar2->intf[1]->dev,
-                       "%s(): urb status = %d\n", __FUNCTION__, urb->status);
+                       "%s(): urb status = %d\n", __func__, urb->status);
                return;
        default:
                dev_err(&ar2->intf[1]->dev,
-                       "%s(): urb status = %d\n", __FUNCTION__, urb->status);
+                       "%s(): urb status = %d\n", __func__, urb->status);
        }
 
        r = usb_submit_urb(urb, GFP_ATOMIC);
        if (r)
                dev_err(&ar2->intf[1]->dev,
-                       "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
+                       "%s(): usb_submit_urb() = %d\n", __func__, r);
 }
 
 static int ati_remote2_input_init(struct ati_remote2 *ar2)
@@ -438,7 +438,7 @@ static int ati_remote2_setup(struct ati_remote2 *ar2)
                            channel, 0x0, NULL, 0, USB_CTRL_SET_TIMEOUT);
        if (r) {
                dev_err(&ar2->udev->dev, "%s - failed to set channel due to error: %d\n",
-                       __FUNCTION__, r);
+                       __func__, r);
                return r;
        }
 
index 952938a8e99102e5b16aca929c3e85e6486eb87e..86afdd1fdf9dd1b787ac35f296425fdfee0c0739 100644 (file)
@@ -159,7 +159,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
        if (dev->data.pos >= dev->data.len) {
                dev_dbg(&dev->udev->dev,
                        "%s - Error ran out of data. pos: %d, len: %d\n",
-                       __FUNCTION__, dev->data.pos, dev->data.len);
+                       __func__, dev->data.pos, dev->data.len);
                return -1;
        }
 
@@ -267,7 +267,7 @@ static void keyspan_check_data(struct usb_keyspan *remote)
                                remote->data.tester = remote->data.tester >> 6;
                                remote->data.bits_left -= 6;
                        } else {
-                               err("%s - Unknown sequence found in system data.\n", __FUNCTION__);
+                               err("%s - Unknown sequence found in system data.\n", __func__);
                                remote->stage = 0;
                                return;
                        }
@@ -286,7 +286,7 @@ static void keyspan_check_data(struct usb_keyspan *remote)
                                remote->data.tester = remote->data.tester >> 6;
                                remote->data.bits_left -= 6;
                        } else {
-                               err("%s - Unknown sequence found in button data.\n", __FUNCTION__);
+                               err("%s - Unknown sequence found in button data.\n", __func__);
                                remote->stage = 0;
                                return;
                        }
@@ -302,7 +302,7 @@ static void keyspan_check_data(struct usb_keyspan *remote)
                        remote->data.tester = remote->data.tester >> 6;
                        remote->data.bits_left -= 6;
                } else {
-                       err("%s - Error in message, invalid toggle.\n", __FUNCTION__);
+                       err("%s - Error in message, invalid toggle.\n", __func__);
                        remote->stage = 0;
                        return;
                }
@@ -317,7 +317,7 @@ static void keyspan_check_data(struct usb_keyspan *remote)
 
                dev_dbg(&remote->udev->dev,
                        "%s found valid message: system: %d, button: %d, toggle: %d\n",
-                       __FUNCTION__, message.system, message.button, message.toggle);
+                       __func__, message.system, message.button, message.toggle);
 
                if (message.toggle != remote->toggle) {
                        keyspan_report_button(remote, message.button, 1);
@@ -341,7 +341,7 @@ static int keyspan_setup(struct usb_device* dev)
                                 0x11, 0x40, 0x5601, 0x0, NULL, 0, 0);
        if (retval) {
                dev_dbg(&dev->dev, "%s - failed to set bit rate due to error: %d\n",
-                       __FUNCTION__, retval);
+                       __func__, retval);
                return(retval);
        }
 
@@ -349,7 +349,7 @@ static int keyspan_setup(struct usb_device* dev)
                                 0x44, 0x40, 0x0, 0x0, NULL, 0, 0);
        if (retval) {
                dev_dbg(&dev->dev, "%s - failed to set resume sensitivity due to error: %d\n",
-                       __FUNCTION__, retval);
+                       __func__, retval);
                return(retval);
        }
 
@@ -357,11 +357,11 @@ static int keyspan_setup(struct usb_device* dev)
                                 0x22, 0x40, 0x0, 0x0, NULL, 0, 0);
        if (retval) {
                dev_dbg(&dev->dev, "%s - failed to turn receive on due to error: %d\n",
-                       __FUNCTION__, retval);
+                       __func__, retval);
                return(retval);
        }
 
-       dev_dbg(&dev->dev, "%s - Setup complete.\n", __FUNCTION__);
+       dev_dbg(&dev->dev, "%s - Setup complete.\n", __func__);
        return(retval);
 }
 
@@ -397,7 +397,7 @@ static void keyspan_irq_recv(struct urb *urb)
 resubmit:
        retval = usb_submit_urb(urb, GFP_ATOMIC);
        if (retval)
-               err ("%s - usb_submit_urb failed with result: %d", __FUNCTION__, retval);
+               err ("%s - usb_submit_urb failed with result: %d", __func__, retval);
 }
 
 static int keyspan_open(struct input_dev *dev)
index 7a7b8c7b96333b441bf9746b42e75d7a31f359d5..a53c4885fbadc96b3805625af212ed4ada1a64e4 100644 (file)
@@ -96,10 +96,10 @@ static void powermate_irq(struct urb *urb)
        case -ENOENT:
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
-               dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+               dbg("%s - urb shutting down with status: %d", __func__, urb->status);
                return;
        default:
-               dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+               dbg("%s - nonzero urb status received: %d", __func__, urb->status);
                goto exit;
        }
 
@@ -112,7 +112,7 @@ exit:
        retval = usb_submit_urb (urb, GFP_ATOMIC);
        if (retval)
                err ("%s - usb_submit_urb failed with result %d",
-                    __FUNCTION__, retval);
+                    __func__, retval);
 }
 
 /* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */
diff --git a/drivers/input/misc/sgi_btns.c b/drivers/input/misc/sgi_btns.c
new file mode 100644 (file)
index 0000000..ce238f5
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ *  SGI Volume Button interface driver
+ *
+ *  Copyright (C) 2008  Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/init.h>
+#include <linux/input-polldev.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#ifdef CONFIG_SGI_IP22
+#include <asm/sgi/ioc.h>
+
+static inline u8 button_status(void)
+{
+       u8 status;
+
+       status = readb(&sgioc->panel) ^ 0xa0;
+       return ((status & 0x80) >> 6) | ((status & 0x20) >> 5);
+}
+#endif
+
+#ifdef CONFIG_SGI_IP32
+#include <asm/ip32/mace.h>
+
+static inline u8 button_status(void)
+{
+       u64 status;
+
+       status = readq(&mace->perif.audio.control);
+       writeq(status & ~(3U << 23), &mace->perif.audio.control);
+
+       return (status >> 23) & 3;
+}
+#endif
+
+#define BUTTONS_POLL_INTERVAL  30      /* msec */
+#define BUTTONS_COUNT_THRESHOLD        3
+
+static const unsigned short sgi_map[] = {
+       KEY_VOLUMEDOWN,
+       KEY_VOLUMEUP
+};
+
+struct buttons_dev {
+       struct input_polled_dev *poll_dev;
+       unsigned short keymap[ARRAY_SIZE(sgi_map)];
+       int count[ARRAY_SIZE(sgi_map)];
+};
+
+static void handle_buttons(struct input_polled_dev *dev)
+{
+       struct buttons_dev *bdev = dev->private;
+       struct input_dev *input = dev->input;
+       u8 status;
+       int i;
+
+       status = button_status();
+
+       for (i = 0; i < ARRAY_SIZE(bdev->keymap); i++) {
+               if (status & (1U << i)) {
+                       if (++bdev->count[i] == BUTTONS_COUNT_THRESHOLD) {
+                               input_event(input, EV_MSC, MSC_SCAN, i);
+                               input_report_key(input, bdev->keymap[i], 1);
+                               input_sync(input);
+                       }
+               } else {
+                       if (bdev->count[i] >= BUTTONS_COUNT_THRESHOLD) {
+                               input_event(input, EV_MSC, MSC_SCAN, i);
+                               input_report_key(input, bdev->keymap[i], 0);
+                               input_sync(input);
+                       }
+                       bdev->count[i] = 0;
+               }
+       }
+}
+
+static int __devinit sgi_buttons_probe(struct platform_device *pdev)
+{
+       struct buttons_dev *bdev;
+       struct input_polled_dev *poll_dev;
+       struct input_dev *input;
+       int error, i;
+
+       bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL);
+       poll_dev = input_allocate_polled_device();
+       if (!bdev || !poll_dev) {
+               error = -ENOMEM;
+               goto err_free_mem;
+       }
+
+       memcpy(bdev->keymap, sgi_map, sizeof(bdev->keymap));
+
+       poll_dev->private = bdev;
+       poll_dev->poll = handle_buttons;
+       poll_dev->poll_interval = BUTTONS_POLL_INTERVAL;
+
+       input = poll_dev->input;
+       input->name = "SGI buttons";
+       input->phys = "sgi/input0";
+       input->id.bustype = BUS_HOST;
+       input->dev.parent = &pdev->dev;
+
+       input->keycode = bdev->keymap;
+       input->keycodemax = ARRAY_SIZE(bdev->keymap);
+       input->keycodesize = sizeof(unsigned short);
+
+       input_set_capability(input, EV_MSC, MSC_SCAN);
+       __set_bit(EV_KEY, input->evbit);
+       for (i = 0; i < ARRAY_SIZE(sgi_map); i++)
+               __set_bit(bdev->keymap[i], input->keybit);
+       __clear_bit(KEY_RESERVED, input->keybit);
+
+       bdev->poll_dev = poll_dev;
+       dev_set_drvdata(&pdev->dev, bdev);
+
+       error = input_register_polled_device(poll_dev);
+       if (error)
+               goto err_free_mem;
+
+       return 0;
+
+ err_free_mem:
+       input_free_polled_device(poll_dev);
+       kfree(bdev);
+       dev_set_drvdata(&pdev->dev, NULL);
+       return error;
+}
+
+static int __devexit sgi_buttons_remove(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct buttons_dev *bdev = dev_get_drvdata(dev);
+
+       input_unregister_polled_device(bdev->poll_dev);
+       input_free_polled_device(bdev->poll_dev);
+       kfree(bdev);
+       dev_set_drvdata(dev, NULL);
+
+       return 0;
+}
+
+static struct platform_driver sgi_buttons_driver = {
+       .probe  = sgi_buttons_probe,
+       .remove = __devexit_p(sgi_buttons_remove),
+       .driver = {
+               .name   = "sgibtns",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init sgi_buttons_init(void)
+{
+       return platform_driver_register(&sgi_buttons_driver);
+}
+
+static void __exit sgi_buttons_exit(void)
+{
+       platform_driver_unregister(&sgi_buttons_driver);
+}
+
+module_init(sgi_buttons_init);
+module_exit(sgi_buttons_exit);
index 72176f3d49cb3ad5e0c091c35fdcebff9047a984..fe268be3293b666e82b1e567bb645fb5847a3c5f 100644 (file)
@@ -1186,7 +1186,7 @@ static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode)
 
 static int __devinit setup_input_dev(void)
 {
-       const struct key_entry *key;
+       struct key_entry *key;
        struct input_dev *input_dev;
        int error;
 
@@ -1219,6 +1219,23 @@ static int __devinit setup_input_dev(void)
                                set_bit(key->sw.code, input_dev->swbit);
                                break;
 
+                       /* if wifi or bluetooth are not available, create normal keys */
+                       case KE_WIFI:
+                               if (!have_wifi) {
+                                       key->type = KE_KEY;
+                                       key->keycode = KEY_WLAN;
+                                       key--;
+                               }
+                               break;
+
+                       case KE_BLUETOOTH:
+                               if (!have_bluetooth) {
+                                       key->type = KE_KEY;
+                                       key->keycode = KEY_BLUETOOTH;
+                                       key--;
+                               }
+                               break;
+
                        default:
                                break;
                }
index 46279ef2b649b7f523006eeffa1bfd14e0173f77..facefd3dba29a1aab6c4428c6bdef9a2a3aa1b55 100644 (file)
@@ -119,6 +119,8 @@ struct yealink_dev {
        u8 lcdMap[ARRAY_SIZE(lcdMap)];  /* state of LCD, LED ... */
        int key_code;                   /* last reported key     */
 
+       unsigned int shutdown:1;
+
        int     stat_ix;
        union {
                struct yld_status s;
@@ -424,10 +426,10 @@ send_update:
 static void urb_irq_callback(struct urb *urb)
 {
        struct yealink_dev *yld = urb->context;
-       int ret;
+       int ret, status = urb->status;
 
-       if (urb->status)
-               err("%s - urb status %d", __FUNCTION__, urb->status);
+       if (status)
+               err("%s - urb status %d", __func__, status);
 
        switch (yld->irq_data->cmd) {
        case CMD_KEYPRESS:
@@ -447,33 +449,38 @@ static void urb_irq_callback(struct urb *urb)
 
        yealink_do_idle_tasks(yld);
 
-       ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
-       if (ret)
-               err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
+       if (!yld->shutdown) {
+               ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
+               if (ret && ret != -EPERM)
+                       err("%s - usb_submit_urb failed %d", __func__, ret);
+       }
 }
 
 static void urb_ctl_callback(struct urb *urb)
 {
        struct yealink_dev *yld = urb->context;
-       int ret;
+       int ret = 0, status = urb->status;
 
-       if (urb->status)
-               err("%s - urb status %d", __FUNCTION__, urb->status);
+       if (status)
+               err("%s - urb status %d", __func__, status);
 
        switch (yld->ctl_data->cmd) {
        case CMD_KEYPRESS:
        case CMD_SCANCODE:
                /* ask for a response */
-               ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
+               if (!yld->shutdown)
+                       ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
                break;
        default:
                /* send new command */
                yealink_do_idle_tasks(yld);
-               ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
+               if (!yld->shutdown)
+                       ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
+               break;
        }
 
-       if (ret)
-               err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
+       if (ret && ret != -EPERM)
+               err("%s - usb_submit_urb failed %d", __func__, ret);
 }
 
 /*******************************************************************************
@@ -505,7 +512,7 @@ static int input_open(struct input_dev *dev)
        struct yealink_dev *yld = input_get_drvdata(dev);
        int i, ret;
 
-       dbg("%s", __FUNCTION__);
+       dbg("%s", __func__);
 
        /* force updates to device */
        for (i = 0; i<sizeof(yld->master); i++)
@@ -521,7 +528,7 @@ static int input_open(struct input_dev *dev)
        yld->ctl_data->sum      = 0x100-CMD_INIT-10;
        if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) {
                dbg("%s - usb_submit_urb failed with result %d",
-                    __FUNCTION__, ret);
+                    __func__, ret);
                return ret;
        }
        return 0;
@@ -531,8 +538,18 @@ static void input_close(struct input_dev *dev)
 {
        struct yealink_dev *yld = input_get_drvdata(dev);
 
+       yld->shutdown = 1;
+       /*
+        * Make sure the flag is seen by other CPUs before we start
+        * killing URBs so new URBs won't be submitted
+        */
+       smp_wmb();
+
        usb_kill_urb(yld->urb_ctl);
        usb_kill_urb(yld->urb_irq);
+
+       yld->shutdown = 0;
+       smp_wmb();
 }
 
 /*******************************************************************************
@@ -809,9 +826,6 @@ static int usb_cleanup(struct yealink_dev *yld, int err)
        if (yld == NULL)
                return err;
 
-       usb_kill_urb(yld->urb_irq);     /* parameter validation in core/urb */
-       usb_kill_urb(yld->urb_ctl);     /* parameter validation in core/urb */
-
         if (yld->idev) {
                if (err)
                        input_free_device(yld->idev);
index ce6fdec19e148c0e250b9fb3f1e572197e31d120..1f41ae94f26bdf216a5f667e754b3c559831e7ed 100644 (file)
@@ -2,12 +2,13 @@
  * Apple USB Touchpad (for post-February 2005 PowerBooks and MacBooks) driver
  *
  * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2005      Johannes Berg (johannes@sipsolutions.net)
+ * Copyright (C) 2005-2008 Johannes Berg (johannes@sipsolutions.net)
  * Copyright (C) 2005      Stelian Pop (stelian@popies.net)
  * Copyright (C) 2005      Frank Arnold (frank@scirocco-5v-turbo.de)
  * Copyright (C) 2005      Peter Osterlund (petero2@telia.com)
  * Copyright (C) 2005      Michael Hanselmann (linux-kernel@hansmi.ch)
  * Copyright (C) 2006      Nicolas Boichat (nicolas@boichat.ch)
+ * Copyright (C) 2007-2008 Sven Anders (anders@anduras.de)
  *
  * Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
  *
 #include <linux/module.h>
 #include <linux/usb/input.h>
 
-/* Apple has powerbooks which have the keyboard with different Product IDs */
-#define APPLE_VENDOR_ID                0x05AC
-
-/* These names come from Info.plist in AppleUSBTrackpad.kext */
-#define FOUNTAIN_ANSI_PRODUCT_ID       0x020E
-#define FOUNTAIN_ISO_PRODUCT_ID                0x020F
-
-#define FOUNTAIN_TP_ONLY_PRODUCT_ID    0x030A
-
-#define GEYSER1_TP_ONLY_PRODUCT_ID     0x030B
-
-#define GEYSER_ANSI_PRODUCT_ID         0x0214
-#define GEYSER_ISO_PRODUCT_ID          0x0215
-#define GEYSER_JIS_PRODUCT_ID          0x0216
-
-/* MacBook devices */
-#define GEYSER3_ANSI_PRODUCT_ID                0x0217
-#define GEYSER3_ISO_PRODUCT_ID         0x0218
-#define GEYSER3_JIS_PRODUCT_ID         0x0219
-
-/*
- * Geyser IV: same as Geyser III according to Info.plist in AppleUSBTrackpad.kext
- * -> same IOClass (AppleUSBGrIIITrackpad), same acceleration tables
- */
-#define GEYSER4_ANSI_PRODUCT_ID        0x021A
-#define GEYSER4_ISO_PRODUCT_ID 0x021B
-#define GEYSER4_JIS_PRODUCT_ID 0x021C
-
-#define GEYSER4_HF_ANSI_PRODUCT_ID     0x0229
-#define GEYSER4_HF_ISO_PRODUCT_ID      0x022A
-#define GEYSER4_HF_JIS_PRODUCT_ID      0x022B
+/* Type of touchpad */
+enum atp_touchpad_type {
+       ATP_FOUNTAIN,
+       ATP_GEYSER1,
+       ATP_GEYSER2,
+       ATP_GEYSER3,
+       ATP_GEYSER4
+};
 
-#define ATP_DEVICE(prod)                                       \
+#define ATP_DEVICE(prod, type)                                 \
+{                                                              \
        .match_flags = USB_DEVICE_ID_MATCH_DEVICE |             \
                       USB_DEVICE_ID_MATCH_INT_CLASS |          \
                       USB_DEVICE_ID_MATCH_INT_PROTOCOL,        \
-       .idVendor = APPLE_VENDOR_ID,                            \
+       .idVendor = 0x05ac, /* Apple */                         \
        .idProduct = (prod),                                    \
        .bInterfaceClass = 0x03,                                \
-       .bInterfaceProtocol = 0x02
+       .bInterfaceProtocol = 0x02,                             \
+       .driver_info = ATP_ ## type,                            \
+}
+
+/*
+ * Table of devices (Product IDs) that work with this driver.
+ * (The names come from Info.plist in AppleUSBTrackpad.kext,
+ *  According to Info.plist Geyser IV is the same as Geyser III.)
+ */
 
-/* table of devices that work with this driver */
 static struct usb_device_id atp_table [] = {
-       { ATP_DEVICE(FOUNTAIN_ANSI_PRODUCT_ID) },
-       { ATP_DEVICE(FOUNTAIN_ISO_PRODUCT_ID) },
-       { ATP_DEVICE(FOUNTAIN_TP_ONLY_PRODUCT_ID) },
-       { ATP_DEVICE(GEYSER1_TP_ONLY_PRODUCT_ID) },
+       /* PowerBooks Feb 2005, iBooks G4 */
+       ATP_DEVICE(0x020e, FOUNTAIN),   /* FOUNTAIN ANSI */
+       ATP_DEVICE(0x020f, FOUNTAIN),   /* FOUNTAIN ISO */
+       ATP_DEVICE(0x030a, FOUNTAIN),   /* FOUNTAIN TP ONLY */
+       ATP_DEVICE(0x030b, GEYSER1),    /* GEYSER 1 TP ONLY */
 
        /* PowerBooks Oct 2005 */
-       { ATP_DEVICE(GEYSER_ANSI_PRODUCT_ID) },
-       { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) },
-       { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) },
+       ATP_DEVICE(0x0214, GEYSER2),    /* GEYSER 2 ANSI */
+       ATP_DEVICE(0x0215, GEYSER2),    /* GEYSER 2 ISO */
+       ATP_DEVICE(0x0216, GEYSER2),    /* GEYSER 2 JIS */
 
        /* Core Duo MacBook & MacBook Pro */
-       { ATP_DEVICE(GEYSER3_ANSI_PRODUCT_ID) },
-       { ATP_DEVICE(GEYSER3_ISO_PRODUCT_ID) },
-       { ATP_DEVICE(GEYSER3_JIS_PRODUCT_ID) },
+       ATP_DEVICE(0x0217, GEYSER3),    /* GEYSER 3 ANSI */
+       ATP_DEVICE(0x0218, GEYSER3),    /* GEYSER 3 ISO */
+       ATP_DEVICE(0x0219, GEYSER3),    /* GEYSER 3 JIS */
 
        /* Core2 Duo MacBook & MacBook Pro */
-       { ATP_DEVICE(GEYSER4_ANSI_PRODUCT_ID) },
-       { ATP_DEVICE(GEYSER4_ISO_PRODUCT_ID) },
-       { ATP_DEVICE(GEYSER4_JIS_PRODUCT_ID) },
+       ATP_DEVICE(0x021a, GEYSER4),    /* GEYSER 4 ANSI */
+       ATP_DEVICE(0x021b, GEYSER4),    /* GEYSER 4 ISO */
+       ATP_DEVICE(0x021c, GEYSER4),    /* GEYSER 4 JIS */
 
-       { ATP_DEVICE(GEYSER4_HF_ANSI_PRODUCT_ID) },
-       { ATP_DEVICE(GEYSER4_HF_ISO_PRODUCT_ID) },
-       { ATP_DEVICE(GEYSER4_HF_JIS_PRODUCT_ID) },
+       /* Core2 Duo MacBook3,1 */
+       ATP_DEVICE(0x0229, GEYSER4),    /* GEYSER 4 HF ANSI */
+       ATP_DEVICE(0x022a, GEYSER4),    /* GEYSER 4 HF ISO */
+       ATP_DEVICE(0x022b, GEYSER4),    /* GEYSER 4 HF JIS */
 
        /* Terminating entry */
        { }
 };
-MODULE_DEVICE_TABLE (usb, atp_table);
+MODULE_DEVICE_TABLE(usb, atp_table);
 
 /*
  * number of sensors. Note that only 16 instead of 26 X (horizontal)
@@ -124,9 +112,13 @@ MODULE_DEVICE_TABLE (usb, atp_table);
  * We try to keep the touchpad aspect ratio while still doing only simple
  * arithmetics.
  * The factors below give coordinates like:
- *     0 <= x <  960 on 12" and 15" Powerbooks
- *     0 <= x < 1600 on 17" Powerbooks
- *     0 <= y <  646
+ *
+ *      0 <= x <  960 on 12" and 15" Powerbooks
+ *      0 <= x < 1600 on 17" Powerbooks and 17" MacBook Pro
+ *      0 <= x < 1216 on MacBooks and 15" MacBook Pro
+ *
+ *      0 <= y <  646 on all Powerbooks
+ *      0 <= y <  774 on all MacBooks
  */
 #define ATP_XFACT      64
 #define ATP_YFACT      43
@@ -147,43 +139,46 @@ MODULE_DEVICE_TABLE (usb, atp_table);
 /* Structure to hold all of our device specific stuff */
 struct atp {
        char                    phys[64];
-       struct usb_device *     udev;           /* usb device */
-       struct urb *            urb;            /* usb request block */
-       signed char *           data;           /* transferred data */
-       struct input_dev *      input;          /* input dev */
-       unsigned char           open;           /* non-zero if opened */
-       unsigned char           valid;          /* are the sensors valid ? */
-       unsigned char           size_detect_done;
-       unsigned char           overflowwarn;   /* overflow warning printed? */
+       struct usb_device       *udev;          /* usb device */
+       struct urb              *urb;           /* usb request block */
+       signed char             *data;          /* transferred data */
+       struct input_dev        *input;         /* input dev */
+       enum atp_touchpad_type  type;           /* type of touchpad */
+       bool                    open;
+       bool                    valid;          /* are the samples valid? */
+       bool                    size_detect_done;
+       bool                    overflow_warned;
        int                     x_old;          /* last reported x/y, */
        int                     y_old;          /* used for smoothing */
-                                               /* current value of the sensors */
        signed char             xy_cur[ATP_XSENSORS + ATP_YSENSORS];
-                                               /* last value of the sensors */
        signed char             xy_old[ATP_XSENSORS + ATP_YSENSORS];
-                                               /* accumulated sensors */
        int                     xy_acc[ATP_XSENSORS + ATP_YSENSORS];
-       int                     datalen;        /* size of an USB urb transfer */
-       int                     idlecount;      /* number of empty packets */
-       struct work_struct      work;
+       int                     datalen;        /* size of USB transfer */
+       int                     idlecount;      /* number of empty packets */
+       struct work_struct      work;
 };
 
 #define dbg_dump(msg, tab) \
        if (debug > 1) {                                                \
-               int i;                                                  \
-               printk("appletouch: %s %lld", msg, (long long)jiffies); \
-               for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++)       \
-                       printk(" %02x", tab[i]);                        \
+               int __i;                                                \
+               printk(KERN_DEBUG "appletouch: %s", msg);               \
+               for (__i = 0; __i < ATP_XSENSORS + ATP_YSENSORS; __i++) \
+                       printk(" %02x", tab[__i]);                      \
                printk("\n");                                           \
        }
 
 #define dprintk(format, a...)                                          \
        do {                                                            \
-               if (debug) printk(KERN_DEBUG format, ##a);              \
+               if (debug)                                              \
+                       printk(KERN_DEBUG format, ##a);                 \
        } while (0)
 
-MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann");
-MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver");
+MODULE_AUTHOR("Johannes Berg");
+MODULE_AUTHOR("Stelian Pop");
+MODULE_AUTHOR("Frank Arnold");
+MODULE_AUTHOR("Michael Hanselmann");
+MODULE_AUTHOR("Sven Anders");
+MODULE_DESCRIPTION("Apple PowerBook and MacBook USB touchpad driver");
 MODULE_LICENSE("GPL");
 
 /*
@@ -191,46 +186,14 @@ MODULE_LICENSE("GPL");
  */
 static int threshold = ATP_THRESHOLD;
 module_param(threshold, int, 0644);
-MODULE_PARM_DESC(threshold, "Discards any change in data from a sensor (trackpad has hundreds of these sensors) less than this value");
+MODULE_PARM_DESC(threshold, "Discard any change in data from a sensor"
+                           " (the trackpad has many of these sensors)"
+                           " less than this value.");
 
-static int debug = 1;
+static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Activate debugging output");
 
-static inline int atp_is_fountain(struct atp *dev)
-{
-       u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
-
-       return productId == FOUNTAIN_ANSI_PRODUCT_ID ||
-              productId == FOUNTAIN_ISO_PRODUCT_ID ||
-              productId == FOUNTAIN_TP_ONLY_PRODUCT_ID;
-}
-
-/* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */
-static inline int atp_is_geyser_2(struct atp *dev)
-{
-       u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
-
-       return (productId == GEYSER_ANSI_PRODUCT_ID) ||
-               (productId == GEYSER_ISO_PRODUCT_ID) ||
-               (productId == GEYSER_JIS_PRODUCT_ID);
-}
-
-static inline int atp_is_geyser_3(struct atp *dev)
-{
-       u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
-
-       return (productId == GEYSER3_ANSI_PRODUCT_ID) ||
-               (productId == GEYSER3_ISO_PRODUCT_ID) ||
-               (productId == GEYSER3_JIS_PRODUCT_ID) ||
-               (productId == GEYSER4_ANSI_PRODUCT_ID) ||
-               (productId == GEYSER4_ISO_PRODUCT_ID) ||
-               (productId == GEYSER4_JIS_PRODUCT_ID) ||
-               (productId == GEYSER4_HF_ANSI_PRODUCT_ID) ||
-               (productId == GEYSER4_HF_ISO_PRODUCT_ID) ||
-               (productId == GEYSER4_HF_JIS_PRODUCT_ID);
-}
-
 /*
  * By default newer Geyser devices send standard USB HID mouse
  * packets (Report ID 2). This code changes device mode, so it
@@ -240,6 +203,7 @@ static int atp_geyser_init(struct usb_device *udev)
 {
        char data[8];
        int size;
+       int i;
 
        size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
                        ATP_GEYSER_MODE_READ_REQUEST_ID,
@@ -248,8 +212,11 @@ static int atp_geyser_init(struct usb_device *udev)
                        ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000);
 
        if (size != 8) {
-               err("Could not do mode read request from device"
-                   " (Geyser Raw mode)");
+               dprintk("atp_geyser_init: read error\n");
+               for (i = 0; i < 8; i++)
+                       dprintk("appletouch[%d]: %d\n", i, data[i]);
+
+               err("Failed to read mode from device.");
                return -EIO;
        }
 
@@ -263,8 +230,11 @@ static int atp_geyser_init(struct usb_device *udev)
                        ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000);
 
        if (size != 8) {
-               err("Could not do mode write request to device"
-                   " (Geyser Raw mode)");
+               dprintk("atp_geyser_init: write error\n");
+               for (i = 0; i < 8; i++)
+                       dprintk("appletouch[%d]: %d\n", i, data[i]);
+
+               err("Failed to request geyser raw mode");
                return -EIO;
        }
        return 0;
@@ -280,15 +250,15 @@ static void atp_reinit(struct work_struct *work)
        struct usb_device *udev = dev->udev;
        int retval;
 
+       dprintk("appletouch: putting appletouch to sleep (reinit)\n");
        dev->idlecount = 0;
 
        atp_geyser_init(udev);
 
        retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
-       if (retval) {
-               err("%s - usb_submit_urb failed with result %d",
-                   __FUNCTION__, retval);
-       }
+       if (retval)
+               err("atp_reinit: usb_submit_urb failed with error %d",
+                   retval);
 }
 
 static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
@@ -323,7 +293,8 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
                 *
                 * - Jason Parekh <jasonparekh@gmail.com>
                 */
-               if (i < 1 || (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) {
+               if (i < 1 ||
+                   (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) {
                        (*fingers)++;
                        is_increasing = 1;
                } else if (i > 0 && xy_sensors[i - 1] >= xy_sensors[i]) {
@@ -331,11 +302,11 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
                }
 
                /*
-                * Subtracts threshold so a high sensor that just passes the threshold
-                * won't skew the calculated absolute coordinate.  Fixes an issue
-                * where slowly moving the mouse would occassionaly jump a number of
-                * pixels (let me restate--slowly moving the mouse makes this issue
-                * most apparent).
+                * Subtracts threshold so a high sensor that just passes the
+                * threshold won't skew the calculated absolute coordinate.
+                * Fixes an issue where slowly moving the mouse would
+                * occasionally jump a number of pixels (slowly moving the
+                * finger makes this issue most apparent.)
                 */
                pcum += (xy_sensors[i] - threshold) * i;
                psum += (xy_sensors[i] - threshold);
@@ -356,7 +327,7 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers)
        input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);
 }
 
-static void atp_complete(struct urburb)
+static void atp_complete(struct urb *urb)
 {
        int x, y, x_z, y_z, x_f, y_f;
        int retval, i, j;
@@ -368,22 +339,22 @@ static void atp_complete(struct urb* urb)
                /* success */
                break;
        case -EOVERFLOW:
-               if(!dev->overflowwarn) {
+               if (!dev->overflow_warned) {
                        printk(KERN_WARNING "appletouch: OVERFLOW with data "
                                "length %d, actual length is %d\n",
                                dev->datalen, dev->urb->actual_length);
-                       dev->overflowwarn = 1;
+                       dev->overflow_warned = true;
                }
        case -ECONNRESET:
        case -ENOENT:
        case -ESHUTDOWN:
                /* This urb is terminated, clean up */
-               dbg("%s - urb shutting down with status: %d",
-                   __FUNCTION__, urb->status);
+               dbg("atp_complete: urb shutting down with status: %d",
+                   urb->status);
                return;
        default:
-               dbg("%s - nonzero urb status received: %d",
-                   __FUNCTION__, urb->status);
+               dbg("atp_complete: nonzero urb status received: %d",
+                   urb->status);
                goto exit;
        }
 
@@ -396,7 +367,7 @@ static void atp_complete(struct urb* urb)
        }
 
        /* reorder the sensors values */
-       if (atp_is_geyser_3(dev)) {
+       if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) {
                memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
 
                /*
@@ -415,7 +386,7 @@ static void atp_complete(struct urb* urb)
                        dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
                        dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
                }
-       } else if (atp_is_geyser_2(dev)) {
+       } else if (dev->type == ATP_GEYSER2) {
                memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
 
                /*
@@ -438,7 +409,7 @@ static void atp_complete(struct urb* urb)
        } else {
                for (i = 0; i < 8; i++) {
                        /* X values */
-                       dev->xy_cur[i     ] = dev->data[5 * i +  2];
+                       dev->xy_cur[i +  0] = dev->data[5 * i +  2];
                        dev->xy_cur[i +  8] = dev->data[5 * i +  4];
                        dev->xy_cur[i + 16] = dev->data[5 * i + 42];
                        if (i < 2)
@@ -454,21 +425,22 @@ static void atp_complete(struct urb* urb)
 
        if (!dev->valid) {
                /* first sample */
-               dev->valid = 1;
+               dev->valid = true;
                dev->x_old = dev->y_old = -1;
                memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
 
                if (dev->size_detect_done ||
-                   atp_is_geyser_3(dev)) /* No 17" Macbooks (yet) */
+                   dev->type == ATP_GEYSER3) /* No 17" Macbooks (yet) */
                        goto exit;
 
                /* 17" Powerbooks have extra X sensors */
-               for (i = (atp_is_geyser_2(dev) ? 15 : 16); i < ATP_XSENSORS; i++) {
+               for (i = (dev->type == ATP_GEYSER2 ? 15 : 16);
+                    i < ATP_XSENSORS; i++) {
                        if (!dev->xy_cur[i])
                                continue;
 
                        printk(KERN_INFO "appletouch: 17\" model detected.\n");
-                       if (atp_is_geyser_2(dev))
+                       if (dev->type == ATP_GEYSER2)
                                input_set_abs_params(dev->input, ABS_X, 0,
                                                     (20 - 1) *
                                                     ATP_XFACT - 1,
@@ -548,11 +520,15 @@ static void atp_complete(struct urb* urb)
         * several hundred times a second. Re-initialization does not
         * work on Fountain touchpads.
         */
-       if (!atp_is_fountain(dev)) {
+       if (dev->type != ATP_FOUNTAIN) {
+               /*
+                * Button must not be pressed when entering suspend,
+                * otherwise we will never release the button.
+                */
                if (!x && !y && !key) {
                        dev->idlecount++;
                        if (dev->idlecount == 10) {
-                               dev->valid = 0;
+                               dev->valid = false;
                                schedule_work(&dev->work);
                                /* Don't resubmit urb here, wait for reinit */
                                return;
@@ -561,12 +537,11 @@ static void atp_complete(struct urb* urb)
                        dev->idlecount = 0;
        }
 
-exit:
+ exit:
        retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
-       if (retval) {
-               err("%s - usb_submit_urb failed with result %d",
-                   __FUNCTION__, retval);
-       }
+       if (retval)
+               err("atp_complete: usb_submit_urb failed with result %d",
+                   retval);
 }
 
 static int atp_open(struct input_dev *input)
@@ -593,7 +568,7 @@ static int atp_handle_geyser(struct atp *dev)
 {
        struct usb_device *udev = dev->udev;
 
-       if (!atp_is_fountain(dev)) {
+       if (dev->type != ATP_FOUNTAIN) {
                /* switch to raw sensor mode */
                if (atp_geyser_init(udev))
                        return -EIO;
@@ -604,7 +579,8 @@ static int atp_handle_geyser(struct atp *dev)
        return 0;
 }
 
-static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
+static int atp_probe(struct usb_interface *iface,
+                    const struct usb_device_id *id)
 {
        struct atp *dev;
        struct input_dev *input_dev;
@@ -640,13 +616,12 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
 
        dev->udev = udev;
        dev->input = input_dev;
-       dev->overflowwarn = 0;
-       if (atp_is_geyser_3(dev))
-               dev->datalen = 64;
-       else if (atp_is_geyser_2(dev))
-               dev->datalen = 64;
-       else
+       dev->type = id->driver_info;
+       dev->overflow_warned = false;
+       if (dev->type == ATP_FOUNTAIN || dev->type == ATP_GEYSER1)
                dev->datalen = 81;
+       else
+               dev->datalen = 64;
 
        dev->urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!dev->urb)
@@ -680,7 +655,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
 
        set_bit(EV_ABS, input_dev->evbit);
 
-       if (atp_is_geyser_3(dev)) {
+       if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) {
                /*
                 * MacBook have 20 X sensors, 10 Y sensors
                 */
@@ -688,7 +663,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
                                     ((20 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0);
                input_set_abs_params(input_dev, ABS_Y, 0,
                                     ((10 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
-       } else if (atp_is_geyser_2(dev)) {
+       } else if (dev->type == ATP_GEYSER2) {
                /*
                 * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected
                 * later.
@@ -703,9 +678,11 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
                 * 17" models are detected later.
                 */
                input_set_abs_params(input_dev, ABS_X, 0,
-                                    (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
+                                    (16 - 1) * ATP_XFACT - 1,
+                                    ATP_FUZZ, 0);
                input_set_abs_params(input_dev, ABS_Y, 0,
-                                    (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
+                                    (ATP_YSENSORS - 1) * ATP_YFACT - 1,
+                                    ATP_FUZZ, 0);
        }
        input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
 
@@ -774,7 +751,7 @@ static int atp_suspend(struct usb_interface *iface, pm_message_t message)
        struct atp *dev = usb_get_intfdata(iface);
 
        usb_kill_urb(dev->urb);
-       dev->valid = 0;
+       dev->valid = false;
 
        return 0;
 }
index 98a3561d4b054f21633433b4f12d6e1367a94f44..adf45b3040e90f036c685e37c72f83965499b5bb 100644 (file)
@@ -57,15 +57,12 @@ MODULE_AUTHOR("Michael Schmitz <schmitz@biophys.uni-duesseldorf.de>");
 MODULE_DESCRIPTION("Atari mouse driver");
 MODULE_LICENSE("GPL");
 
-static int mouse_threshold[2] = {2,2};
+static int mouse_threshold[2] = {2, 2};
+module_param_array(mouse_threshold, int, NULL, 0);
 
-#ifdef __MODULE__
-MODULE_PARM(mouse_threshold, "2i");
-#endif
 #ifdef FIXED_ATARI_JOYSTICK
 extern int atari_mouse_buttons;
 #endif
-static int atamouse_used = 0;
 
 static struct input_dev *atamouse_dev;
 
@@ -97,9 +94,6 @@ static void atamouse_interrupt(char *buf)
 
 static int atamouse_open(struct input_dev *dev)
 {
-       if (atamouse_used++)
-               return 0;
-
 #ifdef FIXED_ATARI_JOYSTICK
        atari_mouse_buttons = 0;
 #endif
@@ -107,23 +101,24 @@ static int atamouse_open(struct input_dev *dev)
        ikbd_mouse_thresh(mouse_threshold[0], mouse_threshold[1]);
        ikbd_mouse_rel_pos();
        atari_input_mouse_interrupt_hook = atamouse_interrupt;
+
        return 0;
 }
 
 static void atamouse_close(struct input_dev *dev)
 {
-       if (!--atamouse_used) {
-               ikbd_mouse_disable();
-               atari_mouse_interrupt_hook = NULL;
-       }
+       ikbd_mouse_disable();
+       atari_mouse_interrupt_hook = NULL;
 }
 
 static int __init atamouse_init(void)
 {
+       int error;
+
        if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP))
                return -ENODEV;
 
-       if (!(atari_keyb_init()))
+       if (!atari_keyb_init())
                return -ENODEV;
 
        atamouse_dev = input_allocate_device();
@@ -141,12 +136,14 @@ static int __init atamouse_init(void)
        atamouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
        atamouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
                BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+
        atamouse_dev->open = atamouse_open;
        atamouse_dev->close = atamouse_close;
 
-       if (input_register_device(atamouse_dev)) {
+       error = input_register_device(atamouse_dev);
+       if (error) {
                input_free_device(atamouse_dev);
-               return -ENOMEM;
+               return error;
        }
 
        return 0;
index 27f88fbb7136c0a40f6257db82266f105fee0a7e..e532c48410ea63013b5d558ae3d150fd5e77fb44 100644 (file)
@@ -247,19 +247,24 @@ static void hil_ptr_disconnect(struct serio *serio)
 
 static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
 {
-       struct hil_ptr   *ptr;
-       const char       *txt;
-       unsigned int     i, naxsets, btntype;
-       uint8_t          did, *idd;
-
-       if (!(ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL)))
+       struct hil_ptr  *ptr;
+       const char      *txt;
+       unsigned int    i, naxsets, btntype;
+       uint8_t         did, *idd;
+       int             error;
+
+       ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL);
+       if (!ptr)
                return -ENOMEM;
 
        ptr->dev = input_allocate_device();
-       if (!ptr->dev)
+       if (!ptr->dev) {
+               error = -ENOMEM;
                goto bail0;
+       }
 
-       if (serio_open(serio, driver))
+       error = serio_open(serio, driver);
+       if (error)
                goto bail1;
 
        serio_set_drvdata(serio, ptr);
@@ -297,6 +302,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
        did = ptr->idd[0];
        idd = ptr->idd + 1;
        txt = "unknown";
+
        if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
                ptr->dev->evbit[0] = BIT_MASK(EV_REL);
                txt = "relative";
@@ -306,8 +312,11 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
                ptr->dev->evbit[0] = BIT_MASK(EV_ABS);
                txt = "absolute";
        }
-       if (!ptr->dev->evbit[0])
+
+       if (!ptr->dev->evbit[0]) {
+               error = -ENODEV;
                goto bail2;
+       }
 
        ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
        if (ptr->nbtn)
@@ -380,13 +389,19 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
        ptr->dev->id.version    = 0x0100; /* TODO: get from ptr->rsc */
        ptr->dev->dev.parent    = &serio->dev;
 
-       input_register_device(ptr->dev);
+       error = input_register_device(ptr->dev);
+       if (error) {
+               printk(KERN_INFO PREFIX "Unable to register input device\n");
+               goto bail2;
+       }
+
        printk(KERN_INFO "input: %s (%s), ID: %d\n",
                ptr->dev->name,
                (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad",
                did);
 
        return 0;
+
  bail2:
        serio_close(serio);
  bail1:
@@ -394,7 +409,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
  bail0:
        kfree(ptr);
        serio_set_drvdata(serio, NULL);
-       return -ENODEV;
+       return error;
 }
 
 static struct serio_device_id hil_ptr_ids[] = {
index 06c35fc553c0f5c8793a1f72c908ca5394b50e81..3827a22362deb97ae3b71c21370935350cfb09eb 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: inport.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:
index 9ea895593b277f344a8a85c294227943f219843f..e2413113df22a171e4c3d0eef73f70e98941c2bf 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: logibm.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:
index 61cff8374e6c0047f54779e358563745ee7b8226..fd09c8df81f2c2888490d971f684002dfc84b383 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: pc110pad.c,v 1.12 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *
  *  Based on the work of:
index ed917bfd086aa13dbafc56bf19a971ee906307e3..17ff137b9bd5ee2b3fedd916f752270c415f0299 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: sermouse.c,v 1.17 2002/03/13 10:03:43 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 
index ec4b6610f730ea7d18a1e5e924201be4ac0a1123..27d70d326ff3c3de7d3c4ef2683e6dbc3aae1969 100644 (file)
@@ -190,4 +190,14 @@ config SERIO_RAW
          To compile this driver as a module, choose M here: the
          module will be called serio_raw.
 
+config SERIO_XILINX_XPS_PS2
+       tristate "Xilinx XPS PS/2 Controller Support"
+       depends on PPC
+       help
+         This driver supports XPS PS/2 IP from the Xilinx EDK on
+         PowerPC platform.
+
+         To compile this driver as a module, choose M here: the
+         module will be called xilinx_ps2.
+
 endif
index 38b886887cbc2459aeae5d76c850b3031780061b..9b6c8135955f40ead77feceace47816cf56fe0c9 100644 (file)
@@ -21,3 +21,4 @@ obj-$(CONFIG_SERIO_PCIPS2)    += pcips2.o
 obj-$(CONFIG_SERIO_MACEPS2)    += maceps2.o
 obj-$(CONFIG_SERIO_LIBPS2)     += libps2.o
 obj-$(CONFIG_SERIO_RAW)                += serio_raw.o
+obj-$(CONFIG_SERIO_XILINX_XPS_PS2)     += xilinx_ps2.o
index 0d35018c23a96e450c9f652a30072b8e2860f33b..d1380fc72cc6ee5c81da9ecd093085de57fa0930 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: ct82c710.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  */
 
index 93a1a6ba216a8c13b08c2fca350509f9d2e56526..37586a68d3459935e8f034588aefb1a75718fa77 100644 (file)
@@ -76,7 +76,7 @@ static struct timer_list      hil_mlcs_kicker;
 static int                     hil_mlcs_probe;
 
 static void hil_mlcs_process(unsigned long unused);
-DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0);
+static DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0);
 
 
 /* #define HIL_MLC_DEBUG */
@@ -459,7 +459,7 @@ static int hilse_operate(hil_mlc *mlc, int repoll)
 #define OUT_LAST(pack) \
 { HILSE_OUT_LAST,      { .packet = pack }, 0, 0, 0, 0 },
 
-const struct hilse_node hil_mlc_se[HILSEN_END] = {
+static const struct hilse_node hil_mlc_se[HILSEN_END] = {
 
        /* 0  HILSEN_START */
        FUNC(hilse_init_lcv, 0, HILSEN_NEXT,    HILSEN_SLEEP,   0)
@@ -784,7 +784,7 @@ static void hil_mlcs_process(unsigned long unused)
 
 /************************* Keepalive timer task *********************/
 
-void hil_mlcs_timer(unsigned long data)
+static void hil_mlcs_timer(unsigned long data)
 {
        hil_mlcs_probe = 1;
        tasklet_schedule(&hil_mlcs_tasklet);
index edfedd9a166cef53a42d5c17846fe9adbb77bb21..7b233a492ad5165aa358f2f63b67831c54a09f7e 100644 (file)
@@ -105,6 +105,10 @@ EXPORT_SYMBOL(__hp_sdc_enqueue_transaction);
 EXPORT_SYMBOL(hp_sdc_enqueue_transaction);
 EXPORT_SYMBOL(hp_sdc_dequeue_transaction);
 
+static unsigned int hp_sdc_disabled;
+module_param_named(no_hpsdc, hp_sdc_disabled, bool, 0);
+MODULE_PARM_DESC(no_hpsdc, "Do not enable HP SDC driver.");
+
 static hp_i8042_sdc    hp_sdc; /* All driver state is kept in here. */
 
 /*************** primitives for use in any context *********************/
@@ -980,6 +984,11 @@ static int __init hp_sdc_register(void)
        unsigned char i;
 #endif
 
+       if (hp_sdc_disabled) {
+               printk(KERN_WARNING PREFIX "HP SDC driver disabled by no_hpsdc=1.\n");
+               return -ENODEV;
+       }
+
        hp_sdc.dev = NULL;
        hp_sdc.dev_err = 0;
 #if defined(__hppa__)
index 587398f5c9df30efd0a5735056ec0eac2eb7b227..b587e2d576ac2983393b5a49791c183250ceb28d 100644 (file)
@@ -50,7 +50,7 @@ MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
 MODULE_DESCRIPTION("Glue for onboard HIL MLC in HP-PARISC machines");
 MODULE_LICENSE("Dual BSD/GPL");
 
-struct hp_sdc_mlc_priv_s {
+static struct hp_sdc_mlc_priv_s {
        int emtestmode;
        hp_sdc_transaction trans;
        u8 tseq[16];
index 78eb7841174cbbbe7a1a2d8b88941aa195d76bbf..fe732a574ec2c5774d729248c1ba2a6e3470a00d 100644 (file)
@@ -63,11 +63,20 @@ static inline void i8042_write_command(int val)
        outb(val, I8042_COMMAND_REG);
 }
 
-#if defined(__i386__) || defined(__x86_64__)
+#ifdef CONFIG_X86
 
 #include <linux/dmi.h>
 
 static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
+       {
+               /* AUX LOOP command does not raise AUX IRQ */
+               .ident = "Arima-Rioworks HDAMB",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"),
+                       DMI_MATCH(DMI_BOARD_NAME, "HDAMB"),
+                       DMI_MATCH(DMI_BOARD_VERSION, "Rev E"),
+               },
+       },
        {
                /* AUX LOOP command does not raise AUX IRQ */
                .ident = "ASUS P65UP5",
@@ -118,6 +127,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
                },
        },
+       {
+               .ident = "Medion MAM 2070",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
+               },
+       },
        { }
 };
 
@@ -291,17 +308,36 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"),
                },
        },
+       {
+               .ident = "Acer Aspire 1360",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
+               },
+       },
+       {
+               .ident = "Gericom Bellagio",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
+               },
+       },
        { }
 };
 
-
-
+#ifdef CONFIG_PNP
+static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
+       {
+               .ident = "Intel MBO Desktop D845PESV",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "D845PESV"),
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+               },
+       },
+       { }
+};
 #endif
 
-#ifdef CONFIG_X86
-
-#include <linux/dmi.h>
-
 /*
  * Some Wistron based laptops need us to explicitly enable the 'Dritek
  * keyboard extension' to make their extra keys start generating scancodes.
@@ -330,6 +366,13 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
                },
        },
+       {
+               .ident = "Acer Aspire 5720",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
+               },
+       },
        {
                .ident = "Acer Aspire 9110",
                .matches = {
@@ -356,7 +399,6 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = {
 
 #endif /* CONFIG_X86 */
 
-
 #ifdef CONFIG_PNP
 #include <linux/pnp.h>
 
@@ -466,6 +508,11 @@ static int __init i8042_pnp_init(void)
        int pnp_data_busted = 0;
        int err;
 
+#ifdef CONFIG_X86
+       if (dmi_check_system(i8042_dmi_nopnp_table))
+               i8042_nopnp = 1;
+#endif
+
        if (i8042_nopnp) {
                printk(KERN_INFO "i8042: PNP detection disabled\n");
                return 0;
@@ -591,15 +638,13 @@ static int __init i8042_platform_init(void)
         i8042_reset = 1;
 #endif
 
-#if defined(__i386__) || defined(__x86_64__)
+#ifdef CONFIG_X86
        if (dmi_check_system(i8042_dmi_noloop_table))
                i8042_noloop = 1;
 
        if (dmi_check_system(i8042_dmi_nomux_table))
                i8042_nomux = 1;
-#endif
 
-#ifdef CONFIG_X86
        if (dmi_check_system(i8042_dmi_dritek_table))
                i8042_dritek = 1;
 #endif /* CONFIG_X86 */
index b819239d74dc15f0c7fa41fce8a8c9658b33fc1a..2b304c22c2008c41d6262acb3514b750fb862dcb 100644 (file)
@@ -26,15 +26,6 @@ MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
 MODULE_DESCRIPTION("PS/2 driver library");
 MODULE_LICENSE("GPL");
 
-/* Work structure to schedule execution of a command */
-struct ps2work {
-       struct work_struct work;
-       struct ps2dev *ps2dev;
-       int command;
-       unsigned char param[0];
-};
-
-
 /*
  * ps2_sendbyte() sends a byte to the device and waits for acknowledge.
  * It doesn't handle retransmission, though it could - because if there
@@ -245,49 +236,6 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
 }
 EXPORT_SYMBOL(ps2_command);
 
-/*
- * ps2_execute_scheduled_command() sends a command, previously scheduled by
- * ps2_schedule_command(), to a PS/2 device (keyboard, mouse, etc.)
- */
-
-static void ps2_execute_scheduled_command(struct work_struct *work)
-{
-       struct ps2work *ps2work = container_of(work, struct ps2work, work);
-
-       ps2_command(ps2work->ps2dev, ps2work->param, ps2work->command);
-       kfree(ps2work);
-}
-
-/*
- * ps2_schedule_command() allows to schedule delayed execution of a PS/2
- * command and can be used to issue a command from an interrupt or softirq
- * context.
- */
-
-int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command)
-{
-       struct ps2work *ps2work;
-       int send = (command >> 12) & 0xf;
-       int receive = (command >> 8) & 0xf;
-
-       if (!(ps2work = kmalloc(sizeof(struct ps2work) + max(send, receive), GFP_ATOMIC)))
-               return -1;
-
-       memset(ps2work, 0, sizeof(struct ps2work));
-       ps2work->ps2dev = ps2dev;
-       ps2work->command = command;
-       memcpy(ps2work->param, param, send);
-       INIT_WORK(&ps2work->work, ps2_execute_scheduled_command);
-
-       if (!schedule_work(&ps2work->work)) {
-               kfree(ps2work);
-               return -1;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(ps2_schedule_command);
-
 /*
  * ps2_init() initializes ps2dev structure
  */
index d962a8d78b144fc7ac3f17af6107d111f4fb31aa..e36a0901646cb2d2d91be060771946af9d60f75b 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: q40kbd.c,v 1.12 2002/02/02 22:26:44 vojtech Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *
  *  Based on the work of:
@@ -49,7 +47,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
 MODULE_LICENSE("GPL");
 
-DEFINE_SPINLOCK(q40kbd_lock);
+static DEFINE_SPINLOCK(q40kbd_lock);
 static struct serio *q40kbd_port;
 static struct platform_device *q40kbd_device;
 
index 34c59d9c6205b47cb06f7fbfd77d7efe0e0bcf5a..1567b778247851f6105f8693a6f0fae4623b0ea5 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: rpckbd.c,v 1.7 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *  Copyright (c) 2002 Russell King
  */
index 7f5293828fbff2e5325c612a93f3ff449cdfa958..78f2abb5c11be1ddf38bc812b5200b2ae20299b5 100644 (file)
@@ -331,9 +331,10 @@ static void serio_handle_event(void)
 }
 
 /*
- * Remove all events that have been submitted for a given serio port.
+ * Remove all events that have been submitted for a given
+ * object, be it serio port or driver.
  */
-static void serio_remove_pending_events(struct serio *serio)
+static void serio_remove_pending_events(void *object)
 {
        struct list_head *node, *next;
        struct serio_event *event;
@@ -343,7 +344,7 @@ static void serio_remove_pending_events(struct serio *serio)
 
        list_for_each_safe(node, next, &serio_event_list) {
                event = list_entry(node, struct serio_event, node);
-               if (event->object == serio) {
+               if (event->object == object) {
                        list_del_init(node);
                        serio_free_event(event);
                }
@@ -837,7 +838,9 @@ void serio_unregister_driver(struct serio_driver *drv)
        struct serio *serio;
 
        mutex_lock(&serio_mutex);
+
        drv->manual_bind = 1;   /* so serio_find_driver ignores it */
+       serio_remove_pending_events(drv);
 
 start_over:
        list_for_each_entry(serio, &serio_list, node) {
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c
new file mode 100644 (file)
index 0000000..0ed044d
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+ * Xilinx XPS PS/2 device driver
+ *
+ * (c) 2005 MontaVista Software, Inc.
+ * (c) 2008 Xilinx, 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.
+ *
+ * You should have received a copy of the 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/serio.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+
+#define DRIVER_NAME            "xilinx_ps2"
+
+/* Register offsets for the xps2 device */
+#define XPS2_SRST_OFFSET       0x00000000 /* Software Reset register */
+#define XPS2_STATUS_OFFSET     0x00000004 /* Status register */
+#define XPS2_RX_DATA_OFFSET    0x00000008 /* Receive Data register */
+#define XPS2_TX_DATA_OFFSET    0x0000000C /* Transmit Data register */
+#define XPS2_GIER_OFFSET       0x0000002C /* Global Interrupt Enable reg */
+#define XPS2_IPISR_OFFSET      0x00000030 /* Interrupt Status register */
+#define XPS2_IPIER_OFFSET      0x00000038 /* Interrupt Enable register */
+
+/* Reset Register Bit Definitions */
+#define XPS2_SRST_RESET                0x0000000A /* Software Reset  */
+
+/* Status Register Bit Positions */
+#define XPS2_STATUS_RX_FULL    0x00000001 /* Receive Full  */
+#define XPS2_STATUS_TX_FULL    0x00000002 /* Transmit Full  */
+
+/* Bit definitions for ISR/IER registers. Both the registers have the same bit
+ * definitions and are only defined once. */
+#define XPS2_IPIXR_WDT_TOUT    0x00000001 /* Watchdog Timeout Interrupt */
+#define XPS2_IPIXR_TX_NOACK    0x00000002 /* Transmit No ACK Interrupt */
+#define XPS2_IPIXR_TX_ACK      0x00000004 /* Transmit ACK (Data) Interrupt */
+#define XPS2_IPIXR_RX_OVF      0x00000008 /* Receive Overflow Interrupt */
+#define XPS2_IPIXR_RX_ERR      0x00000010 /* Receive Error Interrupt */
+#define XPS2_IPIXR_RX_FULL     0x00000020 /* Receive Data Interrupt */
+
+/* Mask for all the Transmit Interrupts */
+#define XPS2_IPIXR_TX_ALL      (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_TX_ACK)
+
+/* Mask for all the Receive Interrupts */
+#define XPS2_IPIXR_RX_ALL      (XPS2_IPIXR_RX_OVF | XPS2_IPIXR_RX_ERR |  \
+                                       XPS2_IPIXR_RX_FULL)
+
+/* Mask for all the Interrupts */
+#define XPS2_IPIXR_ALL         (XPS2_IPIXR_TX_ALL | XPS2_IPIXR_RX_ALL |  \
+                                       XPS2_IPIXR_WDT_TOUT)
+
+/* Global Interrupt Enable mask */
+#define XPS2_GIER_GIE_MASK     0x80000000
+
+struct xps2data {
+       int irq;
+       u32 phys_addr;
+       u32 remap_size;
+       spinlock_t lock;
+       u8 rxb;                         /* Rx buffer */
+       void __iomem *base_address;     /* virt. address of control registers */
+       unsigned int dfl;
+       struct serio serio;             /* serio */
+};
+
+/************************************/
+/* XPS PS/2 data transmission calls */
+/************************************/
+
+/*
+ * xps2_recv() will attempt to receive a byte of data from the PS/2 port.
+ */
+static int xps2_recv(struct xps2data *drvdata, u8 *byte)
+{
+       u32 sr;
+       int status = -1;
+
+       /* If there is data available in the PS/2 receiver, read it */
+       sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET);
+       if (sr & XPS2_STATUS_RX_FULL) {
+               *byte = in_be32(drvdata->base_address + XPS2_RX_DATA_OFFSET);
+               status = 0;
+       }
+
+       return status;
+}
+
+/*********************/
+/* Interrupt handler */
+/*********************/
+static irqreturn_t xps2_interrupt(int irq, void *dev_id)
+{
+       struct xps2data *drvdata = dev_id;
+       u32 intr_sr;
+       u8 c;
+       int status;
+
+       /* Get the PS/2 interrupts and clear them */
+       intr_sr = in_be32(drvdata->base_address + XPS2_IPISR_OFFSET);
+       out_be32(drvdata->base_address + XPS2_IPISR_OFFSET, intr_sr);
+
+       /* Check which interrupt is active */
+       if (intr_sr & XPS2_IPIXR_RX_OVF)
+               printk(KERN_WARNING "%s: receive overrun error\n",
+                       drvdata->serio.name);
+
+       if (intr_sr & XPS2_IPIXR_RX_ERR)
+               drvdata->dfl |= SERIO_PARITY;
+
+       if (intr_sr & (XPS2_IPIXR_TX_NOACK | XPS2_IPIXR_WDT_TOUT))
+               drvdata->dfl |= SERIO_TIMEOUT;
+
+       if (intr_sr & XPS2_IPIXR_RX_FULL) {
+               status = xps2_recv(drvdata, &drvdata->rxb);
+
+               /* Error, if a byte is not received */
+               if (status) {
+                       printk(KERN_ERR
+                               "%s: wrong rcvd byte count (%d)\n",
+                               drvdata->serio.name, status);
+               } else {
+                       c = drvdata->rxb;
+                       serio_interrupt(&drvdata->serio, c, drvdata->dfl);
+                       drvdata->dfl = 0;
+               }
+       }
+
+       if (intr_sr & XPS2_IPIXR_TX_ACK)
+               drvdata->dfl = 0;
+
+       return IRQ_HANDLED;
+}
+
+/*******************/
+/* serio callbacks */
+/*******************/
+
+/*
+ * sxps2_write() sends a byte out through the PS/2 interface.
+ */
+static int sxps2_write(struct serio *pserio, unsigned char c)
+{
+       struct xps2data *drvdata = pserio->port_data;
+       unsigned long flags;
+       u32 sr;
+       int status = -1;
+
+       spin_lock_irqsave(&drvdata->lock, flags);
+
+       /* If the PS/2 transmitter is empty send a byte of data */
+       sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET);
+       if (!(sr & XPS2_STATUS_TX_FULL)) {
+               out_be32(drvdata->base_address + XPS2_TX_DATA_OFFSET, c);
+               status = 0;
+       }
+
+       spin_unlock_irqrestore(&drvdata->lock, flags);
+
+       return status;
+}
+
+/*
+ * sxps2_open() is called when a port is open by the higher layer.
+ */
+static int sxps2_open(struct serio *pserio)
+{
+       struct xps2data *drvdata = pserio->port_data;
+       int retval;
+
+       retval = request_irq(drvdata->irq, &xps2_interrupt, 0,
+                               DRIVER_NAME, drvdata);
+       if (retval) {
+               printk(KERN_ERR
+                       "%s: Couldn't allocate interrupt %d\n",
+                       drvdata->serio.name, drvdata->irq);
+               return retval;
+       }
+
+       /* start reception by enabling the interrupts */
+       out_be32(drvdata->base_address + XPS2_GIER_OFFSET, XPS2_GIER_GIE_MASK);
+       out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, XPS2_IPIXR_RX_ALL);
+       (void)xps2_recv(drvdata, &drvdata->rxb);
+
+       return 0;               /* success */
+}
+
+/*
+ * sxps2_close() frees the interrupt.
+ */
+static void sxps2_close(struct serio *pserio)
+{
+       struct xps2data *drvdata = pserio->port_data;
+
+       /* Disable the PS2 interrupts */
+       out_be32(drvdata->base_address + XPS2_GIER_OFFSET, 0x00);
+       out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0x00);
+       free_irq(drvdata->irq, drvdata);
+}
+
+/*********************/
+/* Device setup code */
+/*********************/
+
+static int xps2_setup(struct device *dev, struct resource *regs_res,
+                     struct resource *irq_res)
+{
+       struct xps2data *drvdata;
+       struct serio *serio;
+       unsigned long remap_size;
+       int retval;
+
+       if (!dev)
+               return -EINVAL;
+
+       if (!regs_res || !irq_res) {
+               dev_err(dev, "IO resource(s) not found\n");
+               return -EINVAL;
+       }
+
+       drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
+       if (!drvdata) {
+               dev_err(dev, "Couldn't allocate device private record\n");
+               return -ENOMEM;
+       }
+
+       dev_set_drvdata(dev, drvdata);
+
+       spin_lock_init(&drvdata->lock);
+       drvdata->irq = irq_res->start;
+
+       remap_size = regs_res->end - regs_res->start + 1;
+       if (!request_mem_region(regs_res->start, remap_size, DRIVER_NAME)) {
+               dev_err(dev, "Couldn't lock memory region at 0x%08X\n",
+                       (unsigned int)regs_res->start);
+               retval = -EBUSY;
+               goto failed1;
+       }
+
+       /* Fill in configuration data and add them to the list */
+       drvdata->phys_addr = regs_res->start;
+       drvdata->remap_size = remap_size;
+       drvdata->base_address = ioremap(regs_res->start, remap_size);
+       if (drvdata->base_address == NULL) {
+               dev_err(dev, "Couldn't ioremap memory at 0x%08X\n",
+                       (unsigned int)regs_res->start);
+               retval = -EFAULT;
+               goto failed2;
+       }
+
+       /* Disable all the interrupts, just in case */
+       out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0);
+
+       /* Reset the PS2 device and abort any current transaction, to make sure
+        * we have the PS2 in a good state */
+       out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);
+
+       dev_info(dev, "Xilinx PS2 at 0x%08X mapped to 0x%08X, irq=%d\n",
+               drvdata->phys_addr, (u32)drvdata->base_address, drvdata->irq);
+
+       serio = &drvdata->serio;
+       serio->id.type = SERIO_8042;
+       serio->write = sxps2_write;
+       serio->open = sxps2_open;
+       serio->close = sxps2_close;
+       serio->port_data = drvdata;
+       serio->dev.parent = dev;
+       snprintf(serio->name, sizeof(serio->name),
+                "Xilinx XPS PS/2 at %08X", drvdata->phys_addr);
+       snprintf(serio->phys, sizeof(serio->phys),
+                "xilinxps2/serio at %08X", drvdata->phys_addr);
+       serio_register_port(serio);
+
+       return 0;               /* success */
+
+failed2:
+       release_mem_region(regs_res->start, remap_size);
+failed1:
+       kfree(drvdata);
+       dev_set_drvdata(dev, NULL);
+
+       return retval;
+}
+
+/***************************/
+/* OF Platform Bus Support */
+/***************************/
+
+static int __devinit xps2_of_probe(struct of_device *ofdev, const struct
+                                  of_device_id * match)
+{
+       struct resource r_irq; /* Interrupt resources */
+       struct resource r_mem; /* IO mem resources */
+       int rc = 0;
+
+       printk(KERN_INFO "Device Tree Probing \'%s\'\n",
+                       ofdev->node->name);
+
+       /* Get iospace for the device */
+       rc = of_address_to_resource(ofdev->node, 0, &r_mem);
+       if (rc) {
+               dev_err(&ofdev->dev, "invalid address\n");
+               return rc;
+       }
+
+       /* Get IRQ for the device */
+       rc = of_irq_to_resource(ofdev->node, 0, &r_irq);
+       if (rc == NO_IRQ) {
+               dev_err(&ofdev->dev, "no IRQ found\n");
+               return rc;
+       }
+
+       return xps2_setup(&ofdev->dev, &r_mem, &r_irq);
+}
+
+static int __devexit xps2_of_remove(struct of_device *of_dev)
+{
+       struct device *dev = &of_dev->dev;
+       struct xps2data *drvdata;
+
+       if (!dev)
+               return -EINVAL;
+
+       drvdata = dev_get_drvdata(dev);
+
+       serio_unregister_port(&drvdata->serio);
+       iounmap(drvdata->base_address);
+       release_mem_region(drvdata->phys_addr, drvdata->remap_size);
+       kfree(drvdata);
+
+       dev_set_drvdata(dev, NULL);
+
+       return 0;               /* success */
+}
+
+/* Match table for of_platform binding */
+static struct of_device_id xps2_of_match[] __devinitdata = {
+       { .compatible = "xlnx,xps-ps2-1.00.a", },
+       { /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, xps2_of_match);
+
+static struct of_platform_driver xps2_of_driver = {
+       .name           = DRIVER_NAME,
+       .match_table    = xps2_of_match,
+       .probe          = xps2_of_probe,
+       .remove         = __devexit_p(xps2_of_remove),
+};
+
+static int __init xps2_init(void)
+{
+       return of_register_platform_driver(&xps2_of_driver);
+}
+
+static void __exit xps2_cleanup(void)
+{
+       of_unregister_platform_driver(&xps2_of_driver);
+}
+
+module_init(xps2_init);
+module_exit(xps2_cleanup);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx XPS PS/2 driver");
+MODULE_LICENSE("GPL");
+
index b973d0ef6d16ae6d332838204a57a20bf184d575..570e0e83ac46c99644c05d7166a5318cea4f66cb 100644 (file)
@@ -73,10 +73,10 @@ static void usb_acecad_irq(struct urb *urb)
                case -ENOENT:
                case -ESHUTDOWN:
                        /* this urb is terminated, clean up */
-                       dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+                       dbg("%s - urb shutting down with status: %d", __func__, urb->status);
                        return;
                default:
-                       dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+                       dbg("%s - nonzero urb status received: %d", __func__, urb->status);
                        goto resubmit;
        }
 
index 55c1134d61372aaf2889bb93f6cc33aef8b656ee..8f037a1d44a63be7586b0ac5f6309522437b290b 100644 (file)
@@ -449,12 +449,12 @@ static void aiptek_irq(struct urb *urb)
        case -ESHUTDOWN:
                /* This urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d",
-                   __FUNCTION__, urb->status);
+                   __func__, urb->status);
                return;
 
        default:
                dbg("%s - nonzero urb status received: %d",
-                   __FUNCTION__, urb->status);
+                   __func__, urb->status);
                goto exit;
        }
 
@@ -813,7 +813,7 @@ exit:
        retval = usb_submit_urb(urb, GFP_ATOMIC);
        if (retval != 0) {
                err("%s - usb_submit_urb failed with result %d",
-                   __FUNCTION__, retval);
+                   __func__, retval);
        }
 }
 
index 1e748e46d12e1c68c9fc05972064941306659698..b9b7a98bc5a5b49a450d46b4a94fcc6f8037ee89 100644 (file)
@@ -863,7 +863,7 @@ static int gtco_probe(struct usb_interface *usbinterface,
        gtco->urbinfo = usb_alloc_urb(0, GFP_KERNEL);
        if (!gtco->urbinfo) {
                err("Failed to allocate URB");
-               return -ENOMEM;
+               error = -ENOMEM;
                goto err_free_buf;
        }
 
index f23f5a97fb3868e58f5f23c730d38fb5c4eabc8d..d89112fa6e6bcc3c09333591375ecdde84ce3bc3 100644 (file)
@@ -56,10 +56,10 @@ static void kbtab_irq(struct urb *urb)
        case -ENOENT:
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
-               dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+               dbg("%s - urb shutting down with status: %d", __func__, urb->status);
                return;
        default:
-               dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+               dbg("%s - nonzero urb status received: %d", __func__, urb->status);
                goto exit;
        }
 
@@ -88,7 +88,7 @@ static void kbtab_irq(struct urb *urb)
        retval = usb_submit_urb (urb, GFP_ATOMIC);
        if (retval)
                err ("%s - usb_submit_urb failed with result %d",
-                    __FUNCTION__, retval);
+                    __func__, retval);
 }
 
 static struct usb_device_id kbtab_ids[] = {
index 706619d06f71e6c596acb8419866ecca0146feb9..ca62ec639f8f8bee57783030f51c508fe8a4b96a 100644 (file)
@@ -105,7 +105,7 @@ struct wacom {
        struct urb *irq;
        struct wacom_wac * wacom_wac;
        struct mutex lock;
-       int open:1;
+       unsigned int open:1;
        char phys[32];
 };
 
index 71cc0c140790462f29b2e1513c38806bfa65d090..5fbc463baf5a007849052f6bc2139f9b56178eb2 100644 (file)
@@ -56,10 +56,10 @@ static void wacom_sys_irq(struct urb *urb)
        case -ENOENT:
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
-               dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+               dbg("%s - urb shutting down with status: %d", __func__, urb->status);
                return;
        default:
-               dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+               dbg("%s - nonzero urb status received: %d", __func__, urb->status);
                goto exit;
        }
 
@@ -74,7 +74,7 @@ static void wacom_sys_irq(struct urb *urb)
        retval = usb_submit_urb (urb, GFP_ATOMIC);
        if (retval)
                err ("%s - usb_submit_urb failed with result %d",
-                    __FUNCTION__, retval);
+                    __func__, retval);
 }
 
 void wacom_report_key(void *wcombo, unsigned int key_type, int key_data)
index 192513e1f04cdc71529eeae8d75663e4866ab39b..bf3d9a8b2c1be6bc6777ab681947cb280cf60149 100644 (file)
@@ -56,7 +56,7 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo)
 static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
 {
        unsigned char *data = wacom->data;
-       int prox, id, pressure;
+       int prox, pressure;
 
        if (data[0] != 2) {
                dbg("wacom_pl_irq: received unknown report #%d", data[0]);
@@ -65,7 +65,7 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
 
        prox = data[1] & 0x40;
 
-       id = ERASER_DEVICE_ID;
+       wacom->id[0] = ERASER_DEVICE_ID;
        if (prox) {
 
                pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
@@ -99,10 +99,10 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
                if (wacom->tool[1] != BTN_TOOL_RUBBER) {
                        /* Unknown tool selected default to pen tool */
                        wacom->tool[1] = BTN_TOOL_PEN;
-                       id = STYLUS_DEVICE_ID;
+                       wacom->id[0] = STYLUS_DEVICE_ID;
                }
                wacom_report_key(wcombo, wacom->tool[1], prox); /* report in proximity for tool */
-               wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
+               wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
                wacom_report_abs(wcombo, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
                wacom_report_abs(wcombo, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
                wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
@@ -127,7 +127,6 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
 static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo)
 {
        unsigned char *data = wacom->data;
-       int id;
 
        if (data[0] != 2) {
                printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
@@ -137,13 +136,13 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo)
        if (data[1] & 0x04) {
                wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20);
                wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x08);
-               id = ERASER_DEVICE_ID;
+               wacom->id[0] = ERASER_DEVICE_ID;
        } else {
                wacom_report_key(wcombo, BTN_TOOL_PEN, data[1] & 0x20);
                wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
-               id = STYLUS_DEVICE_ID;
+               wacom->id[0] = STYLUS_DEVICE_ID;
        }
-       wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
+       wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
        wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
        wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
        wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6]));
@@ -155,27 +154,26 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo)
 static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 {
        unsigned char *data = wacom->data;
-       int x, y, id, rw;
+       int x, y, rw;
 
        if (data[0] != 2) {
                dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
                return 0;
        }
 
-       id = STYLUS_DEVICE_ID;
-       if ((data[1] & 0x80) && ((data[1] & 0x07) || data[2] || data[3] || data[4]
-                       || data[5] || data[6] || (data[7] & 0x07))) {
+       if (data[1] & 0x80) {
                /* in prox and not a pad data */
 
                switch ((data[1] >> 5) & 3) {
 
                        case 0: /* Pen */
                                wacom->tool[0] = BTN_TOOL_PEN;
+                               wacom->id[0] = STYLUS_DEVICE_ID;
                                break;
 
                        case 1: /* Rubber */
                                wacom->tool[0] = BTN_TOOL_RUBBER;
-                               id = ERASER_DEVICE_ID;
+                               wacom->id[0] = ERASER_DEVICE_ID;
                                break;
 
                        case 2: /* Mouse with wheel */
@@ -190,7 +188,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 
                        case 3: /* Mouse without wheel */
                                wacom->tool[0] = BTN_TOOL_MOUSE;
-                               id = CURSOR_DEVICE_ID;
+                               wacom->id[0] = CURSOR_DEVICE_ID;
                                wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
                                wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
                                if (wacom->features->type == WACOM_G4 ||
@@ -210,9 +208,9 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
                        wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
                }
-               wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
+               wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
                wacom_report_key(wcombo, wacom->tool[0], 1);
-       } else if (!(data[1] & 0x90)) {
+       } else if (wacom->id[0]) {
                wacom_report_abs(wcombo, ABS_X, 0);
                wacom_report_abs(wcombo, ABS_Y, 0);
                if (wacom->tool[0] == BTN_TOOL_MOUSE) {
@@ -225,6 +223,7 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_STYLUS, 0);
                        wacom_report_key(wcombo, BTN_STYLUS2, 0);
                }
+               wacom->id[0] = 0;
                wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
                wacom_report_key(wcombo, wacom->tool[0], 0);
        }
@@ -234,13 +233,13 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
            case WACOM_G4:
                if (data[7] & 0xf8) {
                        wacom_input_sync(wcombo); /* sync last event */
-                       wacom->id[1] = 1;
+                       wacom->id[1] = PAD_DEVICE_ID;
                        wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
                        wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
                        rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
                        wacom_report_rel(wcombo, REL_WHEEL, rw);
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
-                       wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
+                       wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                } else if (wacom->id[1]) {
                        wacom_input_sync(wcombo); /* sync last event */
@@ -255,14 +254,14 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
            case WACOM_MO:
                if ((data[7] & 0xf8) || (data[8] & 0xff)) {
                        wacom_input_sync(wcombo); /* sync last event */
-                       wacom->id[1] = 1;
+                       wacom->id[1] = PAD_DEVICE_ID;
                        wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
                        wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
                        wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
                        wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
                        wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
-                       wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
+                       wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                } else if (wacom->id[1]) {
                        wacom_input_sync(wcombo); /* sync last event */
index 565ec711c2eefa6e5dc0f75dc4be5d1f6569a962..e5736652157269804fbbd3a512691be496257867 100644 (file)
@@ -103,6 +103,18 @@ config TOUCHSCREEN_MTOUCH
          To compile this driver as a module, choose M here: the
          module will be called mtouch.
 
+config TOUCHSCREEN_INEXIO
+       tristate "iNexio serial touchscreens"
+       select SERIO
+       help
+         Say Y here if you have an iNexio serial touchscreen connected to
+         your system.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called inexio.
+
 config TOUCHSCREEN_MK712
        tristate "ICS MicroClock MK712 touchscreen"
        help
@@ -134,6 +146,18 @@ config TOUCHSCREEN_HP7XX
          To compile this driver as a module, choose M here: the
          module will be called jornada720_ts.
 
+config TOUCHSCREEN_HTCPEN
+       tristate "HTC Shift X9500 touchscreen"
+       depends on ISA
+       help
+         Say Y here if you have an HTC Shift UMPC also known as HTC X9500
+         Clio / Shangrila and want to support the built-in touchscreen.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called htcpen.
+
 config TOUCHSCREEN_PENMOUNT
        tristate "Penmount serial touchscreen"
        select SERIO
@@ -146,6 +170,17 @@ config TOUCHSCREEN_PENMOUNT
          To compile this driver as a module, choose M here: the
          module will be called penmount.
 
+config TOUCHSCREEN_MIGOR
+       tristate "Renesas MIGO-R touchscreen"
+       depends on SH_MIGOR && I2C
+       help
+         Say Y here to enable MIGO-R touchscreen support.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called migor_ts.
+
 config TOUCHSCREEN_TOUCHRIGHT
        tristate "Touchright serial touchscreen"
        select SERIO
@@ -316,4 +351,15 @@ config TOUCHSCREEN_USB_GOTOP
        bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED
        depends on TOUCHSCREEN_USB_COMPOSITE
 
+config TOUCHSCREEN_TOUCHIT213
+       tristate "Sahara TouchIT-213 touchscreen"
+       select SERIO
+       help
+         Say Y here if you have a Sahara TouchIT-213 Tablet PC.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called touchit213.
+
 endif
index 3c096d75651d4eb2756e302f7d865c117da85078..39a804cd80f1428613bc929c7856ead0cdf12bc7 100644 (file)
@@ -12,12 +12,16 @@ obj-$(CONFIG_TOUCHSCREEN_CORGI)             += corgi_ts.o
 obj-$(CONFIG_TOUCHSCREEN_GUNZE)                += gunze.o
 obj-$(CONFIG_TOUCHSCREEN_ELO)          += elo.o
 obj-$(CONFIG_TOUCHSCREEN_FUJITSU)      += fujitsu_ts.o
+obj-$(CONFIG_TOUCHSCREEN_INEXIO)       += inexio.o
+obj-$(CONFIG_TOUCHSCREEN_MIGOR)                += migor_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MTOUCH)       += mtouch.o
 obj-$(CONFIG_TOUCHSCREEN_MK712)                += mk712.o
 obj-$(CONFIG_TOUCHSCREEN_HP600)                += hp680_ts_input.o
 obj-$(CONFIG_TOUCHSCREEN_HP7XX)                += jornada720_ts.o
+obj-$(CONFIG_TOUCHSCREEN_HTCPEN)       += htcpen.o
 obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE)        += usbtouchscreen.o
 obj-$(CONFIG_TOUCHSCREEN_PENMOUNT)     += penmount.o
+obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213)   += touchit213.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)   += touchright.o
 obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN)     += touchwin.o
 obj-$(CONFIG_TOUCHSCREEN_UCB1400)      += ucb1400_ts.o
index a48a15868c4ade3b1067a97f955d819df739c831..a54f90e02ab60b5f8ac2ab914872fcb270a9c914 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: gunze.c,v 1.12 2001/09/25 10:12:07 vojtech Exp $
- *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  */
 
index 28ae15ed12c57a81e5e92a1cda6e421efd3bb284..4f86081dc7fcb142602d86909628908422066b18 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: h3600_ts_input.c,v 1.4 2002/01/23 06:39:37 jsimmons Exp $
- *
  *  Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com
  *
  *  Sponsored by Transvirtual Technology.
diff --git a/drivers/input/touchscreen/htcpen.c b/drivers/input/touchscreen/htcpen.c
new file mode 100644 (file)
index 0000000..62811de
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * HTC Shift touchscreen driver
+ *
+ * Copyright (C) 2008 Pau Oliva Fora <pof@eslack.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/isa.h>
+#include <linux/ioport.h>
+#include <linux/dmi.h>
+
+MODULE_AUTHOR("Pau Oliva Fora <pau@eslack.org>");
+MODULE_DESCRIPTION("HTC Shift touchscreen driver");
+MODULE_LICENSE("GPL");
+
+#define HTCPEN_PORT_IRQ_CLEAR  0x068
+#define HTCPEN_PORT_INIT       0x06c
+#define HTCPEN_PORT_INDEX      0x0250
+#define HTCPEN_PORT_DATA       0x0251
+#define HTCPEN_IRQ             3
+
+#define DEVICE_ENABLE          0xa2
+#define DEVICE_DISABLE         0xa3
+
+#define X_INDEX                        3
+#define Y_INDEX                        5
+#define TOUCH_INDEX            0xb
+#define LSB_XY_INDEX           0xc
+#define X_AXIS_MAX             2040
+#define Y_AXIS_MAX             2040
+
+static int invert_x;
+module_param(invert_x, bool, 0644);
+MODULE_PARM_DESC(invert_x, "If set, X axis is inverted");
+static int invert_y;
+module_param(invert_y, bool, 0644);
+MODULE_PARM_DESC(invert_y, "If set, Y axis is inverted");
+
+static struct pnp_device_id pnp_ids[] = {
+       { .id = "PNP0cc0" },
+       { .id = "" }
+};
+MODULE_DEVICE_TABLE(pnp, pnp_ids);
+
+static irqreturn_t htcpen_interrupt(int irq, void *handle)
+{
+       struct input_dev *htcpen_dev = handle;
+       unsigned short x, y, xy;
+
+       /* 0 = press; 1 = release */
+       outb_p(TOUCH_INDEX, HTCPEN_PORT_INDEX);
+
+       if (inb_p(HTCPEN_PORT_DATA)) {
+               input_report_key(htcpen_dev, BTN_TOUCH, 0);
+       } else {
+               outb_p(X_INDEX, HTCPEN_PORT_INDEX);
+               x = inb_p(HTCPEN_PORT_DATA);
+
+               outb_p(Y_INDEX, HTCPEN_PORT_INDEX);
+               y = inb_p(HTCPEN_PORT_DATA);
+
+               outb_p(LSB_XY_INDEX, HTCPEN_PORT_INDEX);
+               xy = inb_p(HTCPEN_PORT_DATA);
+
+               /* get high resolution value of X and Y using LSB */
+               x = X_AXIS_MAX - ((x * 8) + ((xy >> 4) & 0xf));
+               y = (y * 8) + (xy & 0xf);
+               if (invert_x)
+                       x = X_AXIS_MAX - x;
+               if (invert_y)
+                       y = Y_AXIS_MAX - y;
+
+               if (x != X_AXIS_MAX && x != 0) {
+                       input_report_key(htcpen_dev, BTN_TOUCH, 1);
+                       input_report_abs(htcpen_dev, ABS_X, x);
+                       input_report_abs(htcpen_dev, ABS_Y, y);
+               }
+       }
+
+       input_sync(htcpen_dev);
+
+       inb_p(HTCPEN_PORT_IRQ_CLEAR);
+
+       return IRQ_HANDLED;
+}
+
+static int htcpen_open(struct input_dev *dev)
+{
+       outb_p(DEVICE_ENABLE, HTCPEN_PORT_INIT);
+
+       return 0;
+}
+
+static void htcpen_close(struct input_dev *dev)
+{
+       outb_p(DEVICE_DISABLE, HTCPEN_PORT_INIT);
+       synchronize_irq(HTCPEN_IRQ);
+}
+
+static int __devinit htcpen_isa_probe(struct device *dev, unsigned int id)
+{
+       struct input_dev *htcpen_dev;
+       int err = -EBUSY;
+
+       if (!request_region(HTCPEN_PORT_IRQ_CLEAR, 1, "htcpen")) {
+               printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n",
+                       HTCPEN_PORT_IRQ_CLEAR);
+               goto request_region1_failed;
+       }
+
+       if (!request_region(HTCPEN_PORT_INIT, 1, "htcpen")) {
+               printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n",
+                       HTCPEN_PORT_INIT);
+               goto request_region2_failed;
+       }
+
+       if (!request_region(HTCPEN_PORT_INDEX, 2, "htcpen")) {
+               printk(KERN_ERR "htcpen: unable to get IO region 0x%x\n",
+                       HTCPEN_PORT_INDEX);
+               goto request_region3_failed;
+       }
+
+       htcpen_dev = input_allocate_device();
+       if (!htcpen_dev) {
+               printk(KERN_ERR "htcpen: can't allocate device\n");
+               err = -ENOMEM;
+               goto input_alloc_failed;
+       }
+
+       htcpen_dev->name = "HTC Shift EC TouchScreen";
+       htcpen_dev->id.bustype = BUS_ISA;
+
+       htcpen_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
+       htcpen_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+       input_set_abs_params(htcpen_dev, ABS_X, 0, X_AXIS_MAX, 0, 0);
+       input_set_abs_params(htcpen_dev, ABS_Y, 0, Y_AXIS_MAX, 0, 0);
+
+       htcpen_dev->open = htcpen_open;
+       htcpen_dev->close = htcpen_close;
+
+       err = request_irq(HTCPEN_IRQ, htcpen_interrupt, 0, "htcpen",
+                       htcpen_dev);
+       if (err) {
+               printk(KERN_ERR "htcpen: irq busy\n");
+               goto request_irq_failed;
+       }
+
+       inb_p(HTCPEN_PORT_IRQ_CLEAR);
+
+       err = input_register_device(htcpen_dev);
+       if (err)
+               goto input_register_failed;
+
+       dev_set_drvdata(dev, htcpen_dev);
+
+       return 0;
+
+ input_register_failed:
+       free_irq(HTCPEN_IRQ, htcpen_dev);
+ request_irq_failed:
+       input_free_device(htcpen_dev);
+ input_alloc_failed:
+       release_region(HTCPEN_PORT_INDEX, 2);
+ request_region3_failed:
+       release_region(HTCPEN_PORT_INIT, 1);
+ request_region2_failed:
+       release_region(HTCPEN_PORT_IRQ_CLEAR, 1);
+ request_region1_failed:
+       return err;
+}
+
+static int __devexit htcpen_isa_remove(struct device *dev, unsigned int id)
+{
+       struct input_dev *htcpen_dev = dev_get_drvdata(dev);
+
+       input_unregister_device(htcpen_dev);
+
+       free_irq(HTCPEN_IRQ, htcpen_dev);
+
+       release_region(HTCPEN_PORT_INDEX, 2);
+       release_region(HTCPEN_PORT_INIT, 1);
+       release_region(HTCPEN_PORT_IRQ_CLEAR, 1);
+
+       dev_set_drvdata(dev, NULL);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int htcpen_isa_suspend(struct device *dev, unsigned int n,
+                               pm_message_t state)
+{
+       outb_p(DEVICE_DISABLE, HTCPEN_PORT_INIT);
+
+       return 0;
+}
+
+static int htcpen_isa_resume(struct device *dev, unsigned int n)
+{
+       outb_p(DEVICE_ENABLE, HTCPEN_PORT_INIT);
+
+       return 0;
+}
+#endif
+
+static struct isa_driver htcpen_isa_driver = {
+       .probe          = htcpen_isa_probe,
+       .remove         = __devexit_p(htcpen_isa_remove),
+#ifdef CONFIG_PM
+       .suspend        = htcpen_isa_suspend,
+       .resume         = htcpen_isa_resume,
+#endif
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = "htcpen",
+       }
+};
+
+static struct dmi_system_id __initdata htcshift_dmi_table[] = {
+       {
+               .ident = "Shift",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "High Tech Computer Corp"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Shift"),
+               },
+       },
+       { }
+};
+
+static int __init htcpen_isa_init(void)
+{
+       if (!dmi_check_system(htcshift_dmi_table))
+               return -ENODEV;
+
+       return isa_register_driver(&htcpen_isa_driver, 1);
+}
+
+static void __exit htcpen_isa_exit(void)
+{
+       isa_unregister_driver(&htcpen_isa_driver);
+}
+
+module_init(htcpen_isa_init);
+module_exit(htcpen_isa_exit);
diff --git a/drivers/input/touchscreen/inexio.c b/drivers/input/touchscreen/inexio.c
new file mode 100644 (file)
index 0000000..192ade0
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * iNexio serial touchscreen driver
+ *
+ * Copyright (c) 2008 Richard Lemon
+ * Based on the mtouch driver (c) Vojtech Pavlik and Dan Streetman
+ *
+ */
+
+/*
+ * 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.
+ */
+
+/*
+ * 2008/06/19 Richard Lemon <richard@codelemon.com>
+ *   Copied mtouch.c and edited for iNexio protocol
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC    "iNexio serial touchscreen driver"
+
+MODULE_AUTHOR("Richard Lemon <richard@codelemon.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+#define INEXIO_FORMAT_TOUCH_BIT 0x01
+#define INEXIO_FORMAT_LENGTH 5
+#define INEXIO_RESPONSE_BEGIN_BYTE 0x80
+
+/* todo: check specs for max length of all responses */
+#define INEXIO_MAX_LENGTH 16
+
+#define INEXIO_MIN_XC 0
+#define INEXIO_MAX_XC 0x3fff
+#define INEXIO_MIN_YC 0
+#define INEXIO_MAX_YC 0x3fff
+
+#define INEXIO_GET_XC(data) (((data[1])<<7) | data[2])
+#define INEXIO_GET_YC(data) (((data[3])<<7) | data[4])
+#define INEXIO_GET_TOUCHED(data) (INEXIO_FORMAT_TOUCH_BIT & data[0])
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct inexio {
+       struct input_dev *dev;
+       struct serio *serio;
+       int idx;
+       unsigned char data[INEXIO_MAX_LENGTH];
+       char phys[32];
+};
+
+static void inexio_process_data(struct inexio *pinexio)
+{
+       struct input_dev *dev = pinexio->dev;
+
+       if (INEXIO_FORMAT_LENGTH == ++pinexio->idx) {
+               input_report_abs(dev, ABS_X, INEXIO_GET_XC(pinexio->data));
+               input_report_abs(dev, ABS_Y, INEXIO_GET_YC(pinexio->data));
+               input_report_key(dev, BTN_TOUCH, INEXIO_GET_TOUCHED(pinexio->data));
+               input_sync(dev);
+
+               pinexio->idx = 0;
+       }
+}
+
+static irqreturn_t inexio_interrupt(struct serio *serio,
+               unsigned char data, unsigned int flags)
+{
+       struct inexio* pinexio = serio_get_drvdata(serio);
+
+       pinexio->data[pinexio->idx] = data;
+
+       if (INEXIO_RESPONSE_BEGIN_BYTE&pinexio->data[0])
+               inexio_process_data(pinexio);
+       else
+               printk(KERN_DEBUG "inexio.c: unknown/unsynchronized data from device, byte %x\n",pinexio->data[0]);
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * inexio_disconnect() is the opposite of inexio_connect()
+ */
+
+static void inexio_disconnect(struct serio *serio)
+{
+       struct inexio* pinexio = serio_get_drvdata(serio);
+
+       input_get_device(pinexio->dev);
+       input_unregister_device(pinexio->dev);
+       serio_close(serio);
+       serio_set_drvdata(serio, NULL);
+       input_put_device(pinexio->dev);
+       kfree(pinexio);
+}
+
+/*
+ * inexio_connect() is the routine that is called when someone adds a
+ * new serio device that supports iNexio protocol and registers it as
+ * an input device. This is usually accomplished using inputattach.
+ */
+
+static int inexio_connect(struct serio *serio, struct serio_driver *drv)
+{
+       struct inexio *pinexio;
+       struct input_dev *input_dev;
+       int err;
+
+       pinexio = kzalloc(sizeof(struct inexio), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!pinexio || !input_dev) {
+               err = -ENOMEM;
+               goto fail1;
+       }
+
+       pinexio->serio = serio;
+       pinexio->dev = input_dev;
+       snprintf(pinexio->phys, sizeof(pinexio->phys), "%s/input0", serio->phys);
+
+       input_dev->name = "iNexio Serial TouchScreen";
+       input_dev->phys = pinexio->phys;
+       input_dev->id.bustype = BUS_RS232;
+       input_dev->id.vendor = SERIO_INEXIO;
+       input_dev->id.product = 0;
+       input_dev->id.version = 0x0001;
+       input_dev->dev.parent = &serio->dev;
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+       input_set_abs_params(pinexio->dev, ABS_X, INEXIO_MIN_XC, INEXIO_MAX_XC, 0, 0);
+       input_set_abs_params(pinexio->dev, ABS_Y, INEXIO_MIN_YC, INEXIO_MAX_YC, 0, 0);
+
+       serio_set_drvdata(serio, pinexio);
+
+       err = serio_open(serio, drv);
+       if (err)
+               goto fail2;
+
+       err = input_register_device(pinexio->dev);
+       if (err)
+               goto fail3;
+
+       return 0;
+
+ fail3:        serio_close(serio);
+ fail2:        serio_set_drvdata(serio, NULL);
+ fail1:        input_free_device(input_dev);
+       kfree(pinexio);
+       return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id inexio_serio_ids[] = {
+       {
+               .type   = SERIO_RS232,
+               .proto  = SERIO_INEXIO,
+               .id     = SERIO_ANY,
+               .extra  = SERIO_ANY,
+       },
+       { 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, inexio_serio_ids);
+
+static struct serio_driver inexio_drv = {
+       .driver         = {
+               .name   = "inexio",
+       },
+       .description    = DRIVER_DESC,
+       .id_table       = inexio_serio_ids,
+       .interrupt      = inexio_interrupt,
+       .connect        = inexio_connect,
+       .disconnect     = inexio_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init inexio_init(void)
+{
+       return serio_register_driver(&inexio_drv);
+}
+
+static void __exit inexio_exit(void)
+{
+       serio_unregister_driver(&inexio_drv);
+}
+
+module_init(inexio_init);
+module_exit(inexio_exit);
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c
new file mode 100644 (file)
index 0000000..c1cd99d
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Touch Screen driver for Renesas MIGO-R Platform
+ *
+ * Copyright (c) 2008 Magnus Damm
+ * Copyright (c) 2007 Ujjwal Pande <ujjwal@kenati.com>,
+ *  Kenati Technologies Pvt Ltd.
+ *
+ * This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU  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 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <linux/i2c.h>
+#include <linux/timer.h>
+
+#define EVENT_PENDOWN 1
+#define EVENT_REPEAT  2
+#define EVENT_PENUP   3
+
+struct migor_ts_priv {
+       struct i2c_client *client;
+       struct input_dev *input;
+       struct delayed_work work;
+       int irq;
+};
+
+static const u_int8_t migor_ts_ena_seq[17] = { 0x33, 0x22, 0x11,
+                                              0x01, 0x06, 0x07, };
+static const u_int8_t migor_ts_dis_seq[17] = { };
+
+static void migor_ts_poscheck(struct work_struct *work)
+{
+       struct migor_ts_priv *priv = container_of(work,
+                                                 struct migor_ts_priv,
+                                                 work.work);
+       unsigned short xpos, ypos;
+       unsigned char event;
+       u_int8_t buf[16];
+
+       memset(buf, 0, sizeof(buf));
+
+       /* Set Index 0 */
+       buf[0] = 0;
+       if (i2c_master_send(priv->client, buf, 1) != 1) {
+               dev_err(&priv->client->dev, "Unable to write i2c index\n");
+               goto out;
+       }
+
+       /* Now do Page Read */
+       if (i2c_master_recv(priv->client, buf, sizeof(buf)) != sizeof(buf)) {
+               dev_err(&priv->client->dev, "Unable to read i2c page\n");
+               goto out;
+       }
+
+       ypos = ((buf[9] & 0x03) << 8 | buf[8]);
+       xpos = ((buf[11] & 0x03) << 8 | buf[10]);
+       event = buf[12];
+
+       if (event == EVENT_PENDOWN || event == EVENT_REPEAT) {
+               input_report_key(priv->input, BTN_TOUCH, 1);
+               input_report_abs(priv->input, ABS_X, ypos); /*X-Y swap*/
+               input_report_abs(priv->input, ABS_Y, xpos);
+               input_sync(priv->input);
+       } else if (event == EVENT_PENUP) {
+               input_report_key(priv->input, BTN_TOUCH, 0);
+               input_sync(priv->input);
+       }
+ out:
+       enable_irq(priv->irq);
+}
+
+static irqreturn_t migor_ts_isr(int irq, void *dev_id)
+{
+       struct migor_ts_priv *priv = dev_id;
+
+       /* the touch screen controller chip is hooked up to the cpu
+        * using i2c and a single interrupt line. the interrupt line
+        * is pulled low whenever someone taps the screen. to deassert
+        * the interrupt line we need to acknowledge the interrupt by
+        * communicating with the controller over the slow i2c bus.
+        *
+        * we can't acknowledge from interrupt context since the i2c
+        * bus controller may sleep, so we just disable the interrupt
+        * here and handle the acknowledge using delayed work.
+        */
+
+       disable_irq_nosync(irq);
+       schedule_delayed_work(&priv->work, HZ / 20);
+
+       return IRQ_HANDLED;
+}
+
+
+static int migor_ts_open(struct input_dev *dev)
+{
+       struct migor_ts_priv *priv = input_get_drvdata(dev);
+       struct i2c_client *client = priv->client;
+       int count;
+
+       /* enable controller */
+       count = i2c_master_send(client, migor_ts_ena_seq,
+                               sizeof(migor_ts_ena_seq));
+       if (count != sizeof(migor_ts_ena_seq)) {
+               dev_err(&client->dev, "Unable to enable touchscreen.\n");
+               return -ENXIO;
+       }
+
+       return 0;
+}
+
+static void migor_ts_close(struct input_dev *dev)
+{
+       struct migor_ts_priv *priv = input_get_drvdata(dev);
+       struct i2c_client *client = priv->client;
+
+       disable_irq(priv->irq);
+
+       /* cancel pending work and wait for migor_ts_poscheck() to finish */
+       if (cancel_delayed_work_sync(&priv->work)) {
+               /*
+                * if migor_ts_poscheck was canceled we need to enable IRQ
+                * here to balance disable done in migor_ts_isr.
+                */
+               enable_irq(priv->irq);
+       }
+
+       /* disable controller */
+       i2c_master_send(client, migor_ts_dis_seq, sizeof(migor_ts_dis_seq));
+
+       enable_irq(priv->irq);
+}
+
+static int migor_ts_probe(struct i2c_client *client,
+                         const struct i2c_device_id *idp)
+{
+       struct migor_ts_priv *priv;
+       struct input_dev *input;
+       int error;
+
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               dev_err(&client->dev, "failed to allocate driver data\n");
+               error = -ENOMEM;
+               goto err0;
+       }
+
+       dev_set_drvdata(&client->dev, priv);
+
+       input = input_allocate_device();
+       if (!input) {
+               dev_err(&client->dev, "Failed to allocate input device.\n");
+               error = -ENOMEM;
+               goto err1;
+       }
+
+       input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+
+       input_set_abs_params(input, ABS_X, 95, 955, 0, 0);
+       input_set_abs_params(input, ABS_Y, 85, 935, 0, 0);
+
+       input->name = client->driver_name;
+       input->id.bustype = BUS_I2C;
+       input->dev.parent = &client->dev;
+
+       input->open = migor_ts_open;
+       input->close = migor_ts_close;
+
+       input_set_drvdata(input, priv);
+
+       priv->client = client;
+       priv->input = input;
+       INIT_DELAYED_WORK(&priv->work, migor_ts_poscheck);
+       priv->irq = client->irq;
+
+       error = input_register_device(input);
+       if (error)
+               goto err1;
+
+       error = request_irq(priv->irq, migor_ts_isr, IRQF_TRIGGER_LOW,
+                           client->driver_name, priv);
+       if (error) {
+               dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
+               goto err2;
+       }
+
+       return 0;
+
+ err2:
+       input_unregister_device(input);
+       input = NULL; /* so we dont try to free it below */
+ err1:
+       input_free_device(input);
+       kfree(priv);
+ err0:
+       dev_set_drvdata(&client->dev, NULL);
+       return error;
+}
+
+static int migor_ts_remove(struct i2c_client *client)
+{
+       struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
+
+       free_irq(priv->irq, priv);
+       input_unregister_device(priv->input);
+       kfree(priv);
+
+       dev_set_drvdata(&client->dev, NULL);
+
+       return 0;
+}
+
+static struct i2c_driver migor_ts_driver = {
+       .driver = {
+               .name = "migor_ts",
+       },
+       .probe = migor_ts_probe,
+       .remove = migor_ts_remove,
+};
+
+static int __init migor_ts_init(void)
+{
+       return i2c_add_driver(&migor_ts_driver);
+}
+
+static void __exit migor_ts_exit(void)
+{
+       i2c_del_driver(&migor_ts_driver);
+}
+
+MODULE_DESCRIPTION("MigoR Touchscreen driver");
+MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
+MODULE_LICENSE("GPL");
+
+module_init(migor_ts_init);
+module_exit(migor_ts_exit);
diff --git a/drivers/input/touchscreen/touchit213.c b/drivers/input/touchscreen/touchit213.c
new file mode 100644 (file)
index 0000000..d1297ba
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Sahara TouchIT-213 serial touchscreen driver
+ *
+ * Copyright (c) 2007-2008 Claudio Nieder <private@claudio.ch>
+ *
+ * Based on Touchright driver (drivers/input/touchscreen/touchright.c)
+ * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
+ * Copyright (c) 2004 Vojtech Pavlik
+ * and Dan Streetman <ddstreet@ieee.org>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/init.h>
+
+#define DRIVER_DESC    "Sahara TouchIT-213 serial touchscreen driver"
+
+MODULE_AUTHOR("Claudio Nieder <private@claudio.ch>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/*
+ * Definitions & global arrays.
+ */
+
+/*
+ * Data is received through COM1 at 9600bit/s,8bit,no parity in packets
+ * of 5 byte each.
+ *
+ *   +--------+   +--------+   +--------+   +--------+   +--------+
+ *   |1000000p|   |0xxxxxxx|   |0xxxxxxx|   |0yyyyyyy|   |0yyyyyyy|
+ *   +--------+   +--------+   +--------+   +--------+   +--------+
+ *                    MSB          LSB          MSB          LSB
+ *
+ * The value of p is 1 as long as the screen is touched and 0 when
+ * reporting the location where touching stopped, e.g. where the pen was
+ * lifted from the screen.
+ *
+ * When holding the screen in landscape mode as the BIOS text output is
+ * presented, x is the horizontal axis with values growing from left to
+ * right and y is the vertical axis with values growing from top to
+ * bottom.
+ *
+ * When holding the screen in portrait mode with the Sahara logo in its
+ * correct position, x ist the vertical axis with values growing from
+ * top to bottom and y is the horizontal axis with values growing from
+ * right to left.
+ */
+
+#define T213_FORMAT_TOUCH_BIT  0x01
+#define T213_FORMAT_STATUS_BYTE        0x80
+#define T213_FORMAT_STATUS_MASK        ~T213_FORMAT_TOUCH_BIT
+
+/*
+ * On my Sahara Touch-IT 213 I have observed x values from 0 to 0x7f0
+ * and y values from 0x1d to 0x7e9, so the actual measurement is
+ * probably done with an 11 bit precision.
+ */
+#define T213_MIN_XC 0
+#define T213_MAX_XC 0x07ff
+#define T213_MIN_YC 0
+#define T213_MAX_YC 0x07ff
+
+/*
+ * Per-touchscreen data.
+ */
+
+struct touchit213 {
+       struct input_dev *dev;
+       struct serio *serio;
+       int idx;
+       unsigned char csum;
+       unsigned char data[5];
+       char phys[32];
+};
+
+static irqreturn_t touchit213_interrupt(struct serio *serio,
+               unsigned char data, unsigned int flags)
+{
+       struct touchit213 *touchit213 = serio_get_drvdata(serio);
+       struct input_dev *dev = touchit213->dev;
+
+       touchit213->data[touchit213->idx] = data;
+
+       switch (touchit213->idx++) {
+       case 0:
+               if ((touchit213->data[0] & T213_FORMAT_STATUS_MASK) !=
+                               T213_FORMAT_STATUS_BYTE) {
+                       pr_debug("unsynchronized data: 0x%02x\n", data);
+                       touchit213->idx = 0;
+               }
+               break;
+
+       case 4:
+               touchit213->idx = 0;
+               input_report_abs(dev, ABS_X,
+                       (touchit213->data[1] << 7) | touchit213->data[2]);
+               input_report_abs(dev, ABS_Y,
+                       (touchit213->data[3] << 7) | touchit213->data[4]);
+               input_report_key(dev, BTN_TOUCH,
+                       touchit213->data[0] & T213_FORMAT_TOUCH_BIT);
+               input_sync(dev);
+               break;
+       }
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * touchit213_disconnect() is the opposite of touchit213_connect()
+ */
+
+static void touchit213_disconnect(struct serio *serio)
+{
+       struct touchit213 *touchit213 = serio_get_drvdata(serio);
+
+       input_get_device(touchit213->dev);
+       input_unregister_device(touchit213->dev);
+       serio_close(serio);
+       serio_set_drvdata(serio, NULL);
+       input_put_device(touchit213->dev);
+       kfree(touchit213);
+}
+
+/*
+ * touchit213_connect() is the routine that is called when someone adds a
+ * new serio device that supports the Touchright protocol and registers it as
+ * an input device.
+ */
+
+static int touchit213_connect(struct serio *serio, struct serio_driver *drv)
+{
+       struct touchit213 *touchit213;
+       struct input_dev *input_dev;
+       int err;
+
+       touchit213 = kzalloc(sizeof(struct touchit213), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!touchit213 || !input_dev) {
+               err = -ENOMEM;
+               goto fail1;
+       }
+
+       touchit213->serio = serio;
+       touchit213->dev = input_dev;
+       snprintf(touchit213->phys, sizeof(touchit213->phys),
+                "%s/input0", serio->phys);
+
+       input_dev->name = "Sahara Touch-iT213 Serial TouchScreen";
+       input_dev->phys = touchit213->phys;
+       input_dev->id.bustype = BUS_RS232;
+       input_dev->id.vendor = SERIO_TOUCHIT213;
+       input_dev->id.product = 0;
+       input_dev->id.version = 0x0100;
+       input_dev->dev.parent = &serio->dev;
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+       input_set_abs_params(touchit213->dev, ABS_X,
+                            T213_MIN_XC, T213_MAX_XC, 0, 0);
+       input_set_abs_params(touchit213->dev, ABS_Y,
+                            T213_MIN_YC, T213_MAX_YC, 0, 0);
+
+       serio_set_drvdata(serio, touchit213);
+
+       err = serio_open(serio, drv);
+       if (err)
+               goto fail2;
+
+       err = input_register_device(touchit213->dev);
+       if (err)
+               goto fail3;
+
+       return 0;
+
+ fail3:        serio_close(serio);
+ fail2:        serio_set_drvdata(serio, NULL);
+ fail1:        input_free_device(input_dev);
+       kfree(touchit213);
+       return err;
+}
+
+/*
+ * The serio driver structure.
+ */
+
+static struct serio_device_id touchit213_serio_ids[] = {
+       {
+               .type   = SERIO_RS232,
+               .proto  = SERIO_TOUCHIT213,
+               .id     = SERIO_ANY,
+               .extra  = SERIO_ANY,
+       },
+       { 0 }
+};
+
+MODULE_DEVICE_TABLE(serio, touchit213_serio_ids);
+
+static struct serio_driver touchit213_drv = {
+       .driver         = {
+               .name   = "touchit213",
+       },
+       .description    = DRIVER_DESC,
+       .id_table       = touchit213_serio_ids,
+       .interrupt      = touchit213_interrupt,
+       .connect        = touchit213_connect,
+       .disconnect     = touchit213_disconnect,
+};
+
+/*
+ * The functions for inserting/removing us as a module.
+ */
+
+static int __init touchit213_init(void)
+{
+       return serio_register_driver(&touchit213_drv);
+}
+
+static void __exit touchit213_exit(void)
+{
+       serio_unregister_driver(&touchit213_drv);
+}
+
+module_init(touchit213_init);
+module_exit(touchit213_exit);
index 3a0a8ca570767000569ebab0befa31cec6d3b3c1..fdd645c214a2dce90dfd9fc89059b4a6d8ff4789 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/init.h>
 #include <linux/usb.h>
 #include <linux/usb/input.h>
+#include <linux/hid.h>
 
 
 #define DRIVER_VERSION         "v0.6"
@@ -101,7 +102,7 @@ struct usbtouch_usb {
 
 /* device types */
 enum {
-       DEVTPYE_DUMMY = -1,
+       DEVTYPE_IGNORE = -1,
        DEVTYPE_EGALAX,
        DEVTYPE_PANJIT,
        DEVTYPE_3M,
@@ -115,8 +116,21 @@ enum {
        DEVTYPE_GOTOP,
 };
 
+#define USB_DEVICE_HID_CLASS(vend, prod) \
+       .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \
+               | USB_DEVICE_ID_MATCH_DEVICE, \
+       .idVendor = (vend), \
+       .idProduct = (prod), \
+       .bInterfaceClass = USB_INTERFACE_CLASS_HID, \
+       .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE
+
 static struct usb_device_id usbtouch_devices[] = {
 #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX
+       /* ignore the HID capable devices, handled by usbhid */
+       {USB_DEVICE_HID_CLASS(0x0eef, 0x0001), .driver_info = DEVTYPE_IGNORE},
+       {USB_DEVICE_HID_CLASS(0x0eef, 0x0002), .driver_info = DEVTYPE_IGNORE},
+
+       /* normal device IDs */
        {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX},
        {USB_DEVICE(0x3823, 0x0002), .driver_info = DEVTYPE_EGALAX},
        {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX},
@@ -262,7 +276,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                              1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
        dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d",
-           __FUNCTION__, ret);
+           __func__, ret);
        if (ret < 0)
                return ret;
        msleep(150);
@@ -273,7 +287,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
                                      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                                      1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
                dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
-                   __FUNCTION__, ret);
+                   __func__, ret);
                if (ret >= 0)
                        break;
                if (ret != -EPIPE)
@@ -793,18 +807,18 @@ static void usbtouch_irq(struct urb *urb)
        case -ETIME:
                /* this urb is timing out */
                dbg("%s - urb timed out - was the device unplugged?",
-                   __FUNCTION__);
+                   __func__);
                return;
        case -ECONNRESET:
        case -ENOENT:
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d",
-                   __FUNCTION__, urb->status);
+                   __func__, urb->status);
                return;
        default:
                dbg("%s - nonzero urb status received: %d",
-                   __FUNCTION__, urb->status);
+                   __func__, urb->status);
                goto exit;
        }
 
@@ -814,7 +828,7 @@ exit:
        retval = usb_submit_urb(urb, GFP_ATOMIC);
        if (retval)
                err("%s - usb_submit_urb failed with result: %d",
-                   __FUNCTION__, retval);
+                   __func__, retval);
 }
 
 static int usbtouch_open(struct input_dev *input)
@@ -857,6 +871,10 @@ static int usbtouch_probe(struct usb_interface *intf,
        struct usbtouch_device_info *type;
        int err = -ENOMEM;
 
+       /* some devices are ignored */
+       if (id->driver_info == DEVTYPE_IGNORE)
+               return -ENODEV;
+
        interface = intf->cur_altsetting;
        endpoint = &interface->endpoint[0].desc;
 
@@ -883,7 +901,7 @@ static int usbtouch_probe(struct usb_interface *intf,
 
        usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
        if (!usbtouch->irq) {
-               dbg("%s - usb_alloc_urb failed: usbtouch->irq", __FUNCTION__);
+               dbg("%s - usb_alloc_urb failed: usbtouch->irq", __func__);
                goto out_free_buffers;
        }
 
@@ -939,14 +957,14 @@ static int usbtouch_probe(struct usb_interface *intf,
        if (type->init) {
                err = type->init(usbtouch);
                if (err) {
-                       dbg("%s - type->init() failed, err: %d", __FUNCTION__, err);
+                       dbg("%s - type->init() failed, err: %d", __func__, err);
                        goto out_free_buffers;
                }
        }
 
        err = input_register_device(usbtouch->input);
        if (err) {
-               dbg("%s - input_register_device failed, err: %d", __FUNCTION__, err);
+               dbg("%s - input_register_device failed, err: %d", __func__, err);
                goto out_free_buffers;
        }
 
@@ -966,12 +984,12 @@ static void usbtouch_disconnect(struct usb_interface *intf)
 {
        struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
 
-       dbg("%s - called", __FUNCTION__);
+       dbg("%s - called", __func__);
 
        if (!usbtouch)
                return;
 
-       dbg("%s - usbtouch is initialized, cleaning up", __FUNCTION__);
+       dbg("%s - usbtouch is initialized, cleaning up", __func__);
        usb_set_intfdata(intf, NULL);
        usb_kill_urb(usbtouch->irq);
        input_unregister_device(usbtouch->input);
index 0b6e4cfa6a218a8117599e9ff5af8e3f5863b0fa..4c5d85a249aeceb6edc7d59506618bbe5dc22807 100644 (file)
@@ -168,6 +168,18 @@ static void wm9712_phy_init(struct wm97xx *wm)
                        64000 / rpu);
        }
 
+       /* WM9712 five wire */
+       if (five_wire) {
+               dig2 |= WM9712_45W;
+               dev_dbg(wm->dev, "setting 5-wire touchscreen mode.");
+
+               if (pil) {
+                       dev_warn(wm->dev, "pressure measurement is not "
+                                "supported in 5-wire mode\n");
+                       pil = 0;
+               }
+       }
+
        /* touchpanel pressure current*/
        if (pil == 2) {
                dig2 |= WM9712_PIL;
@@ -179,12 +191,6 @@ static void wm9712_phy_init(struct wm97xx *wm)
        if (!pil)
                pressure = 0;
 
-       /* WM9712 five wire */
-       if (five_wire) {
-               dig2 |= WM9712_45W;
-               dev_dbg(wm->dev, "setting 5-wire touchscreen mode.");
-       }
-
        /* polling mode sample settling delay */
        if (delay < 0 || delay > 15) {
                dev_dbg(wm->dev, "supplied delay out of range.");
index 8a35029caca096d976c064967380037fff2a9cb2..871b0cbca5e4540299047294d02c40a20326345a 100644 (file)
@@ -1302,11 +1302,12 @@ static void capinc_tty_hangup(struct tty_struct *tty)
 #endif
 }
 
-static void capinc_tty_break_ctl(struct tty_struct *tty, int state)
+static int capinc_tty_break_ctl(struct tty_struct *tty, int state)
 {
 #ifdef _DEBUG_TTYFUNCS
        printk(KERN_DEBUG "capinc_tty_break_ctl(%d)\n", state);
 #endif
+       return 0;
 }
 
 static void capinc_tty_flush_buffer(struct tty_struct *tty)
@@ -1552,7 +1553,8 @@ static int __init capi_init(void)
                return PTR_ERR(capi_class);
        }
 
-       device_create(capi_class, NULL, MKDEV(capi_major, 0), "capi");
+       device_create_drvdata(capi_class, NULL, MKDEV(capi_major, 0), NULL,
+                             "capi");
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
        if (capinc_tty_init() < 0) {
index e5d446804d323e74880db5ff14130440a120f033..cae52485208aaf022bd57689dcf8a4b30173aa2e 100644 (file)
@@ -862,7 +862,8 @@ adbdev_init(void)
        adb_dev_class = class_create(THIS_MODULE, "adb");
        if (IS_ERR(adb_dev_class))
                return;
-       device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), "adb");
+       device_create_drvdata(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL,
+                             "adb");
 
        platform_device_register(&adb_pfdev);
        platform_driver_probe(&adb_pfdrv, adb_dummy_probe);
index 59ea520a5d7a3fa47b4eaa2abe90e0613b82ba82..5396c67ba0a45c9b7cc1196590d1cffe18b49f60 100644 (file)
@@ -219,11 +219,13 @@ struct adbhid {
        int flags;
 };
 
-#define FLAG_FN_KEY_PRESSED    0x00000001
-#define FLAG_POWER_FROM_FN     0x00000002
-#define FLAG_EMU_FWDEL_DOWN    0x00000004
-#define FLAG_CAPSLOCK_TRANSLATE        0x00000008
-#define FLAG_CAPSLOCK_DOWN     0x00000010
+#define FLAG_FN_KEY_PRESSED            0x00000001
+#define FLAG_POWER_FROM_FN             0x00000002
+#define FLAG_EMU_FWDEL_DOWN            0x00000004
+#define FLAG_CAPSLOCK_TRANSLATE                0x00000008
+#define FLAG_CAPSLOCK_DOWN             0x00000010
+#define FLAG_CAPSLOCK_IGNORE_NEXT      0x00000020
+#define FLAG_POWER_KEY_PRESSED         0x00000040
 
 static struct adbhid *adbhid[16];
 
@@ -291,11 +293,20 @@ adbhid_input_keycode(int id, int scancode, int repeat)
                if (keycode == ADB_KEY_CAPSLOCK && !up_flag) {
                        /* Key pressed, turning on the CapsLock LED.
                         * The next 0xff will be interpreted as a release. */
-                       ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
+                       if (ahid->flags & FLAG_CAPSLOCK_IGNORE_NEXT) {
+                               /* Throw away this key event if it happens
+                                * just after resume. */
+                               ahid->flags &= ~FLAG_CAPSLOCK_IGNORE_NEXT;
+                               return;
+                       } else {
+                               ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
                                        | FLAG_CAPSLOCK_DOWN;
-               } else if (scancode == 0xff) {
+                       }
+               } else if (scancode == 0xff &&
+                          !(ahid->flags & FLAG_POWER_KEY_PRESSED)) {
                        /* Scancode 0xff usually signifies that the capslock
-                        * key was either pressed or released. */
+                        * key was either pressed or released, or that the
+                        * power button was released. */
                        if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) {
                                keycode = ADB_KEY_CAPSLOCK;
                                if (ahid->flags & FLAG_CAPSLOCK_DOWN) {
@@ -309,7 +320,7 @@ adbhid_input_keycode(int id, int scancode, int repeat)
                                }
                        } else {
                                printk(KERN_INFO "Spurious caps lock event "
-                                               "(scancode 0xff).");
+                                                "(scancode 0xff).\n");
                        }
                }
        }
@@ -336,6 +347,12 @@ adbhid_input_keycode(int id, int scancode, int repeat)
                }
                break;
        case ADB_KEY_POWER:
+               /* Keep track of the power key state */
+               if (up_flag)
+                       ahid->flags &= ~FLAG_POWER_KEY_PRESSED;
+               else
+                       ahid->flags |= FLAG_POWER_KEY_PRESSED;
+
                /* Fn + Command will produce a bogus "power" keycode */
                if (ahid->flags & FLAG_FN_KEY_PRESSED) {
                        keycode = ADB_KEY_CMD;
@@ -681,6 +698,21 @@ static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned i
        return -1;
 }
 
+static void
+adbhid_kbd_capslock_remember(void)
+{
+       struct adbhid *ahid;
+       int i;
+
+       for (i = 1; i < 16; i++) {
+               ahid = adbhid[i];
+
+               if (ahid && ahid->id == ADB_KEYBOARD)
+                       if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE)
+                               ahid->flags |= FLAG_CAPSLOCK_IGNORE_NEXT;
+       }
+}
+
 static int
 adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
 {
@@ -697,8 +729,17 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
                }
 
                /* Stop pending led requests */
-               while(leds_req_pending)
+               while (leds_req_pending)
                        adb_poll();
+
+               /* After resume, and if the capslock LED is on, the PMU will
+                * send a "capslock down" key event. This confuses the
+                * restore_capslock_events logic. Remember if the capslock
+                * LED was on before suspend so the unwanted key event can
+                * be ignored after resume. */
+               if (restore_capslock_events)
+                       adbhid_kbd_capslock_remember();
+
                break;
 
        case ADB_MSG_POST_RESET:
index 67b8e9453b191a2c701970f4ccbdd4a5207dd1e3..ef2dbfe747141ee3940fa645e700d89d7a173981 100644 (file)
@@ -40,7 +40,7 @@ static struct mca_bus *mca_root_busses[MAX_MCA_BUSSES];
 
 struct mca_device_info {
        short pos_id;           /* the 2 byte pos id for this card */
-       char name[DEVICE_NAME_SIZE];
+       char name[50];
 };
 
 static int mca_bus_match (struct device *dev, struct device_driver *drv)
index b26927ce889cead2717db3f4d3896bbd9bacc4e2..621a272a2c7495b9cd8866ec6bb6d0454d5d1396 100644 (file)
@@ -225,7 +225,7 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
                    || test_bit(Faulty, &rdev->flags))
                        continue;
 
-               target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512);
+               target = rdev->sb_start + offset + index * (PAGE_SIZE/512);
 
                if (sync_page_io(rdev->bdev, target, PAGE_SIZE, page, READ)) {
                        page->index = index;
@@ -241,10 +241,10 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
 static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
 {
        mdk_rdev_t *rdev;
-       struct list_head *tmp;
        mddev_t *mddev = bitmap->mddev;
 
-       rdev_for_each(rdev, tmp, mddev)
+       rcu_read_lock();
+       rdev_for_each_rcu(rdev, mddev)
                if (test_bit(In_sync, &rdev->flags)
                    && !test_bit(Faulty, &rdev->flags)) {
                        int size = PAGE_SIZE;
@@ -260,32 +260,37 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
                                    + (long)(page->index * (PAGE_SIZE/512))
                                    + size/512 > 0)
                                        /* bitmap runs in to metadata */
-                                       return -EINVAL;
+                                       goto bad_alignment;
                                if (rdev->data_offset + mddev->size*2
-                                   > rdev->sb_offset*2 + bitmap->offset)
+                                   > rdev->sb_start + bitmap->offset)
                                        /* data runs in to bitmap */
-                                       return -EINVAL;
-                       } else if (rdev->sb_offset*2 < rdev->data_offset) {
+                                       goto bad_alignment;
+                       } else if (rdev->sb_start < rdev->data_offset) {
                                /* METADATA BITMAP DATA */
-                               if (rdev->sb_offset*2
+                               if (rdev->sb_start
                                    + bitmap->offset
                                    + page->index*(PAGE_SIZE/512) + size/512
                                    > rdev->data_offset)
                                        /* bitmap runs in to data */
-                                       return -EINVAL;
+                                       goto bad_alignment;
                        } else {
                                /* DATA METADATA BITMAP - no problems */
                        }
                        md_super_write(mddev, rdev,
-                                      (rdev->sb_offset<<1) + bitmap->offset
+                                      rdev->sb_start + bitmap->offset
                                       + page->index * (PAGE_SIZE/512),
                                       size,
                                       page);
                }
+       rcu_read_unlock();
 
        if (wait)
                md_super_wait(mddev);
        return 0;
+
+ bad_alignment:
+       rcu_read_unlock();
+       return -EINVAL;
 }
 
 static void bitmap_file_kick(struct bitmap *bitmap);
@@ -454,8 +459,11 @@ void bitmap_update_sb(struct bitmap *bitmap)
        spin_unlock_irqrestore(&bitmap->lock, flags);
        sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
        sb->events = cpu_to_le64(bitmap->mddev->events);
-       if (!bitmap->mddev->degraded)
-               sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
+       if (bitmap->mddev->events < bitmap->events_cleared) {
+               /* rocking back to read-only */
+               bitmap->events_cleared = bitmap->mddev->events;
+               sb->events_cleared = cpu_to_le64(bitmap->events_cleared);
+       }
        kunmap_atomic(sb, KM_USER0);
        write_page(bitmap, bitmap->sb_page, 1);
 }
@@ -1085,9 +1093,19 @@ void bitmap_daemon_work(struct bitmap *bitmap)
                        } else
                                spin_unlock_irqrestore(&bitmap->lock, flags);
                        lastpage = page;
-/*
-                       printk("bitmap clean at page %lu\n", j);
-*/
+
+                       /* We are possibly going to clear some bits, so make
+                        * sure that events_cleared is up-to-date.
+                        */
+                       if (bitmap->need_sync) {
+                               bitmap_super_t *sb;
+                               bitmap->need_sync = 0;
+                               sb = kmap_atomic(bitmap->sb_page, KM_USER0);
+                               sb->events_cleared =
+                                       cpu_to_le64(bitmap->events_cleared);
+                               kunmap_atomic(sb, KM_USER0);
+                               write_page(bitmap, bitmap->sb_page, 1);
+                       }
                        spin_lock_irqsave(&bitmap->lock, flags);
                        clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
                }
@@ -1257,6 +1275,12 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
                        return;
                }
 
+               if (success &&
+                   bitmap->events_cleared < bitmap->mddev->events) {
+                       bitmap->events_cleared = bitmap->mddev->events;
+                       bitmap->need_sync = 1;
+               }
+
                if (!success && ! (*bmc & NEEDED_MASK))
                        *bmc |= NEEDED_MASK;
 
index ab6a61db63ce2248b5553ec43678fab61642e9a7..13956437bc81888d38e89ba2abbaa8d62772fc52 100644 (file)
@@ -1216,9 +1216,24 @@ error:
        return -EINVAL;
 }
 
+static int crypt_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+                      struct bio_vec *biovec, int max_size)
+{
+       struct crypt_config *cc = ti->private;
+       struct request_queue *q = bdev_get_queue(cc->dev->bdev);
+
+       if (!q->merge_bvec_fn)
+               return max_size;
+
+       bvm->bi_bdev = cc->dev->bdev;
+       bvm->bi_sector = cc->start + bvm->bi_sector - ti->begin;
+
+       return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
+}
+
 static struct target_type crypt_target = {
        .name   = "crypt",
-       .version= {1, 5, 0},
+       .version= {1, 6, 0},
        .module = THIS_MODULE,
        .ctr    = crypt_ctr,
        .dtr    = crypt_dtr,
@@ -1228,6 +1243,7 @@ static struct target_type crypt_target = {
        .preresume = crypt_preresume,
        .resume = crypt_resume,
        .message = crypt_message,
+       .merge  = crypt_merge,
 };
 
 static int __init dm_crypt_init(void)
index 17753d80ad228022b2575e46ee28f867cfd93d6f..6449bcdf84ca47465673223fa3a27f88c44684ce 100644 (file)
@@ -69,13 +69,25 @@ static void linear_dtr(struct dm_target *ti)
        kfree(lc);
 }
 
-static int linear_map(struct dm_target *ti, struct bio *bio,
-                     union map_info *map_context)
+static sector_t linear_map_sector(struct dm_target *ti, sector_t bi_sector)
 {
-       struct linear_c *lc = (struct linear_c *) ti->private;
+       struct linear_c *lc = ti->private;
+
+       return lc->start + (bi_sector - ti->begin);
+}
+
+static void linear_map_bio(struct dm_target *ti, struct bio *bio)
+{
+       struct linear_c *lc = ti->private;
 
        bio->bi_bdev = lc->dev->bdev;
-       bio->bi_sector = lc->start + (bio->bi_sector - ti->begin);
+       bio->bi_sector = linear_map_sector(ti, bio->bi_sector);
+}
+
+static int linear_map(struct dm_target *ti, struct bio *bio,
+                     union map_info *map_context)
+{
+       linear_map_bio(ti, bio);
 
        return DM_MAPIO_REMAPPED;
 }
@@ -114,15 +126,31 @@ static int linear_ioctl(struct dm_target *ti, struct inode *inode,
        return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg);
 }
 
+static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+                       struct bio_vec *biovec, int max_size)
+{
+       struct linear_c *lc = ti->private;
+       struct request_queue *q = bdev_get_queue(lc->dev->bdev);
+
+       if (!q->merge_bvec_fn)
+               return max_size;
+
+       bvm->bi_bdev = lc->dev->bdev;
+       bvm->bi_sector = linear_map_sector(ti, bvm->bi_sector);
+
+       return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
+}
+
 static struct target_type linear_target = {
        .name   = "linear",
-       .version= {1, 0, 2},
+       .version= {1, 0, 3},
        .module = THIS_MODULE,
        .ctr    = linear_ctr,
        .dtr    = linear_dtr,
        .map    = linear_map,
        .status = linear_status,
        .ioctl  = linear_ioctl,
+       .merge  = linear_merge,
 };
 
 int __init dm_linear_init(void)
index 67a6f31b7fc3e2d39a3dfbf6813d6b163eae6707..5b48478c79f53037474579edf1930b4d103b160c 100644 (file)
@@ -831,7 +831,7 @@ static struct dm_dirty_log_type _disk_type = {
        .status = disk_status,
 };
 
-int __init dm_dirty_log_init(void)
+static int __init dm_dirty_log_init(void)
 {
        int r;
 
@@ -848,7 +848,7 @@ int __init dm_dirty_log_init(void)
        return r;
 }
 
-void __exit dm_dirty_log_exit(void)
+static void __exit dm_dirty_log_exit(void)
 {
        dm_dirty_log_type_unregister(&_disk_type);
        dm_dirty_log_type_unregister(&_core_type);
index 9f7302d4878d25e3baf43989d21bbbf97e5fea8c..fea966d66f9838c140176a7dbd0ed8223e908f44 100644 (file)
@@ -525,8 +525,10 @@ static int parse_path_selector(struct arg_set *as, struct priority_group *pg,
        }
 
        r = read_param(_params, shift(as), &ps_argc, &ti->error);
-       if (r)
+       if (r) {
+               dm_put_path_selector(pst);
                return -EINVAL;
+       }
 
        r = pst->create(&pg->ps, ps_argc, as->argv);
        if (r) {
@@ -623,8 +625,10 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
                struct pgpath *pgpath;
                struct arg_set path_args;
 
-               if (as->argc < nr_params)
+               if (as->argc < nr_params) {
+                       ti->error = "not enough path parameters";
                        goto bad;
+               }
 
                path_args.argc = nr_params;
                path_args.argv = as->argv;
@@ -867,7 +871,7 @@ static int reinstate_path(struct pgpath *pgpath)
        if (pgpath->path.is_active)
                goto out;
 
-       if (!pgpath->pg->ps.type) {
+       if (!pgpath->pg->ps.type->reinstate_path) {
                DMWARN("Reinstate path not supported by path selector %s",
                       pgpath->pg->ps.type->name);
                r = -EINVAL;
index 1ba8a47d61b116646c6ac8ef533cd5b8f64767a7..6e5528aecc98c38698a6d2a07a18e1e84164a7ab 100644 (file)
  */
 #define SNAPSHOT_PAGES (((1UL << 20) >> PAGE_SHIFT) ? : 1)
 
+/*
+ * The size of the mempool used to track chunks in use.
+ */
+#define MIN_IOS 256
+
 static struct workqueue_struct *ksnapd;
 static void flush_queued_bios(struct work_struct *work);
 
@@ -91,7 +96,63 @@ struct dm_snap_pending_exception {
  */
 static struct kmem_cache *exception_cache;
 static struct kmem_cache *pending_cache;
-static mempool_t *pending_pool;
+
+struct dm_snap_tracked_chunk {
+       struct hlist_node node;
+       chunk_t chunk;
+};
+
+static struct kmem_cache *tracked_chunk_cache;
+
+static struct dm_snap_tracked_chunk *track_chunk(struct dm_snapshot *s,
+                                                chunk_t chunk)
+{
+       struct dm_snap_tracked_chunk *c = mempool_alloc(s->tracked_chunk_pool,
+                                                       GFP_NOIO);
+       unsigned long flags;
+
+       c->chunk = chunk;
+
+       spin_lock_irqsave(&s->tracked_chunk_lock, flags);
+       hlist_add_head(&c->node,
+                      &s->tracked_chunk_hash[DM_TRACKED_CHUNK_HASH(chunk)]);
+       spin_unlock_irqrestore(&s->tracked_chunk_lock, flags);
+
+       return c;
+}
+
+static void stop_tracking_chunk(struct dm_snapshot *s,
+                               struct dm_snap_tracked_chunk *c)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&s->tracked_chunk_lock, flags);
+       hlist_del(&c->node);
+       spin_unlock_irqrestore(&s->tracked_chunk_lock, flags);
+
+       mempool_free(c, s->tracked_chunk_pool);
+}
+
+static int __chunk_is_tracked(struct dm_snapshot *s, chunk_t chunk)
+{
+       struct dm_snap_tracked_chunk *c;
+       struct hlist_node *hn;
+       int found = 0;
+
+       spin_lock_irq(&s->tracked_chunk_lock);
+
+       hlist_for_each_entry(c, hn,
+           &s->tracked_chunk_hash[DM_TRACKED_CHUNK_HASH(chunk)], node) {
+               if (c->chunk == chunk) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       spin_unlock_irq(&s->tracked_chunk_lock);
+
+       return found;
+}
 
 /*
  * One of these per registered origin, held in the snapshot_origins hash
@@ -302,14 +363,19 @@ static void free_exception(struct dm_snap_exception *e)
        kmem_cache_free(exception_cache, e);
 }
 
-static struct dm_snap_pending_exception *alloc_pending_exception(void)
+static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snapshot *s)
 {
-       return mempool_alloc(pending_pool, GFP_NOIO);
+       struct dm_snap_pending_exception *pe = mempool_alloc(s->pending_pool,
+                                                            GFP_NOIO);
+
+       pe->snap = s;
+
+       return pe;
 }
 
 static void free_pending_exception(struct dm_snap_pending_exception *pe)
 {
-       mempool_free(pe, pending_pool);
+       mempool_free(pe, pe->snap->pending_pool);
 }
 
 static void insert_completed_exception(struct dm_snapshot *s,
@@ -482,6 +548,7 @@ static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg,
 static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 {
        struct dm_snapshot *s;
+       int i;
        int r = -EINVAL;
        char persistent;
        char *origin_path;
@@ -564,11 +631,30 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                goto bad5;
        }
 
+       s->pending_pool = mempool_create_slab_pool(MIN_IOS, pending_cache);
+       if (!s->pending_pool) {
+               ti->error = "Could not allocate mempool for pending exceptions";
+               goto bad6;
+       }
+
+       s->tracked_chunk_pool = mempool_create_slab_pool(MIN_IOS,
+                                                        tracked_chunk_cache);
+       if (!s->tracked_chunk_pool) {
+               ti->error = "Could not allocate tracked_chunk mempool for "
+                           "tracking reads";
+               goto bad_tracked_chunk_pool;
+       }
+
+       for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++)
+               INIT_HLIST_HEAD(&s->tracked_chunk_hash[i]);
+
+       spin_lock_init(&s->tracked_chunk_lock);
+
        /* Metadata must only be loaded into one table at once */
        r = s->store.read_metadata(&s->store);
        if (r < 0) {
                ti->error = "Failed to read snapshot metadata";
-               goto bad6;
+               goto bad_load_and_register;
        } else if (r > 0) {
                s->valid = 0;
                DMWARN("Snapshot is marked invalid.");
@@ -582,7 +668,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        if (register_snapshot(s)) {
                r = -EINVAL;
                ti->error = "Cannot register snapshot origin";
-               goto bad6;
+               goto bad_load_and_register;
        }
 
        ti->private = s;
@@ -590,6 +676,12 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
        return 0;
 
+ bad_load_and_register:
+       mempool_destroy(s->tracked_chunk_pool);
+
+ bad_tracked_chunk_pool:
+       mempool_destroy(s->pending_pool);
+
  bad6:
        dm_kcopyd_client_destroy(s->kcopyd_client);
 
@@ -624,6 +716,9 @@ static void __free_exceptions(struct dm_snapshot *s)
 
 static void snapshot_dtr(struct dm_target *ti)
 {
+#ifdef CONFIG_DM_DEBUG
+       int i;
+#endif
        struct dm_snapshot *s = ti->private;
 
        flush_workqueue(ksnapd);
@@ -632,8 +727,17 @@ static void snapshot_dtr(struct dm_target *ti)
        /* After this returns there can be no new kcopyd jobs. */
        unregister_snapshot(s);
 
+#ifdef CONFIG_DM_DEBUG
+       for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++)
+               BUG_ON(!hlist_empty(&s->tracked_chunk_hash[i]));
+#endif
+
+       mempool_destroy(s->tracked_chunk_pool);
+
        __free_exceptions(s);
 
+       mempool_destroy(s->pending_pool);
+
        dm_put_device(ti, s->origin);
        dm_put_device(ti, s->cow);
 
@@ -771,6 +875,13 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success)
                goto out;
        }
 
+       /*
+        * Check for conflicting reads. This is extremely improbable,
+        * so yield() is sufficient and there is no need for a wait queue.
+        */
+       while (__chunk_is_tracked(s, pe->e.old_chunk))
+               yield();
+
        /*
         * Add a proper exception, and remove the
         * in-flight exception from the list.
@@ -873,7 +984,7 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
         * to hold the lock while we do this.
         */
        up_write(&s->lock);
-       pe = alloc_pending_exception();
+       pe = alloc_pending_exception(s);
        down_write(&s->lock);
 
        if (!s->valid) {
@@ -893,7 +1004,6 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
        bio_list_init(&pe->snapshot_bios);
        pe->primary_pe = NULL;
        atomic_set(&pe->ref_count, 0);
-       pe->snap = s;
        pe->started = 0;
 
        if (s->store.prepare_exception(&s->store, &pe->e)) {
@@ -974,14 +1084,10 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
                        start_copy(pe);
                        goto out;
                }
-       } else
-               /*
-                * FIXME: this read path scares me because we
-                * always use the origin when we have a pending
-                * exception.  However I can't think of a
-                * situation where this is wrong - ejt.
-                */
+       } else {
                bio->bi_bdev = s->origin->bdev;
+               map_context->ptr = track_chunk(s, chunk);
+       }
 
  out_unlock:
        up_write(&s->lock);
@@ -989,6 +1095,18 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
        return r;
 }
 
+static int snapshot_end_io(struct dm_target *ti, struct bio *bio,
+                          int error, union map_info *map_context)
+{
+       struct dm_snapshot *s = ti->private;
+       struct dm_snap_tracked_chunk *c = map_context->ptr;
+
+       if (c)
+               stop_tracking_chunk(s, c);
+
+       return 0;
+}
+
 static void snapshot_resume(struct dm_target *ti)
 {
        struct dm_snapshot *s = ti->private;
@@ -1266,6 +1384,7 @@ static struct target_type snapshot_target = {
        .ctr     = snapshot_ctr,
        .dtr     = snapshot_dtr,
        .map     = snapshot_map,
+       .end_io  = snapshot_end_io,
        .resume  = snapshot_resume,
        .status  = snapshot_status,
 };
@@ -1306,9 +1425,9 @@ static int __init dm_snapshot_init(void)
                goto bad4;
        }
 
-       pending_pool = mempool_create_slab_pool(128, pending_cache);
-       if (!pending_pool) {
-               DMERR("Couldn't create pending pool.");
+       tracked_chunk_cache = KMEM_CACHE(dm_snap_tracked_chunk, 0);
+       if (!tracked_chunk_cache) {
+               DMERR("Couldn't create cache to track chunks in use.");
                r = -ENOMEM;
                goto bad5;
        }
@@ -1317,13 +1436,13 @@ static int __init dm_snapshot_init(void)
        if (!ksnapd) {
                DMERR("Failed to create ksnapd workqueue.");
                r = -ENOMEM;
-               goto bad6;
+               goto bad_pending_pool;
        }
 
        return 0;
 
-      bad6:
-       mempool_destroy(pending_pool);
+      bad_pending_pool:
+       kmem_cache_destroy(tracked_chunk_cache);
       bad5:
        kmem_cache_destroy(pending_cache);
       bad4:
@@ -1352,9 +1471,9 @@ static void __exit dm_snapshot_exit(void)
                DMERR("origin unregister failed %d", r);
 
        exit_origin_hash();
-       mempool_destroy(pending_pool);
        kmem_cache_destroy(pending_cache);
        kmem_cache_destroy(exception_cache);
+       kmem_cache_destroy(tracked_chunk_cache);
 }
 
 /* Module hooks */
index 24f9fb73b982d0cd148ef15d56428ba6c7ce6877..292c15609ae362fc344a9c46811285319a3f1bec 100644 (file)
@@ -130,6 +130,10 @@ struct exception_store {
        void *context;
 };
 
+#define DM_TRACKED_CHUNK_HASH_SIZE     16
+#define DM_TRACKED_CHUNK_HASH(x)       ((unsigned long)(x) & \
+                                        (DM_TRACKED_CHUNK_HASH_SIZE - 1))
+
 struct dm_snapshot {
        struct rw_semaphore lock;
        struct dm_target *ti;
@@ -157,6 +161,8 @@ struct dm_snapshot {
        /* The last percentage we notified */
        int last_percent;
 
+       mempool_t *pending_pool;
+
        struct exception_table pending;
        struct exception_table complete;
 
@@ -174,6 +180,11 @@ struct dm_snapshot {
        /* Queue of snapshot writes for ksnapd to flush */
        struct bio_list queued_bios;
        struct work_struct queued_bios_work;
+
+       /* Chunks with outstanding reads */
+       mempool_t *tracked_chunk_pool;
+       spinlock_t tracked_chunk_lock;
+       struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
 };
 
 /*
index 94116eaf47099ccad9f8ca458afd3c4f1e835435..798e468103b879f7986842028709be8852aa3dca 100644 (file)
@@ -506,14 +506,13 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev)
        rs->max_sectors =
                min_not_zero(rs->max_sectors, q->max_sectors);
 
-       /* FIXME: Device-Mapper on top of RAID-0 breaks because DM
-        *        currently doesn't honor MD's merge_bvec_fn routine.
-        *        In this case, we'll force DM to use PAGE_SIZE or
-        *        smaller I/O, just to be safe. A better fix is in the
-        *        works, but add this for the time being so it will at
-        *        least operate correctly.
+       /*
+        * Check if merge fn is supported.
+        * If not we'll force DM to use PAGE_SIZE or
+        * smaller I/O, just to be safe.
         */
-       if (q->merge_bvec_fn)
+
+       if (q->merge_bvec_fn && !ti->type->merge)
                rs->max_sectors =
                        min_not_zero(rs->max_sectors,
                                     (unsigned int) (PAGE_SIZE >> 9));
index 372369b1cc2068c286964883638c2b3a9f2c11c4..bca448e118786a78a5e07b54f3cb3a7e3aca85d5 100644 (file)
@@ -37,8 +37,8 @@ static DEFINE_SPINLOCK(_minor_lock);
 struct dm_io {
        struct mapped_device *md;
        int error;
-       struct bio *bio;
        atomic_t io_count;
+       struct bio *bio;
        unsigned long start_time;
 };
 
@@ -829,6 +829,49 @@ static int __split_bio(struct mapped_device *md, struct bio *bio)
  * CRUD END
  *---------------------------------------------------------------*/
 
+static int dm_merge_bvec(struct request_queue *q,
+                        struct bvec_merge_data *bvm,
+                        struct bio_vec *biovec)
+{
+       struct mapped_device *md = q->queuedata;
+       struct dm_table *map = dm_get_table(md);
+       struct dm_target *ti;
+       sector_t max_sectors;
+       int max_size;
+
+       if (unlikely(!map))
+               return 0;
+
+       ti = dm_table_find_target(map, bvm->bi_sector);
+
+       /*
+        * Find maximum amount of I/O that won't need splitting
+        */
+       max_sectors = min(max_io_len(md, bvm->bi_sector, ti),
+                         (sector_t) BIO_MAX_SECTORS);
+       max_size = (max_sectors << SECTOR_SHIFT) - bvm->bi_size;
+       if (max_size < 0)
+               max_size = 0;
+
+       /*
+        * merge_bvec_fn() returns number of bytes
+        * it can accept at this offset
+        * max is precomputed maximal io size
+        */
+       if (max_size && ti->type->merge)
+               max_size = ti->type->merge(ti, bvm, biovec, max_size);
+
+       /*
+        * Always allow an entire first page
+        */
+       if (max_size <= biovec->bv_len && !(bvm->bi_size >> SECTOR_SHIFT))
+               max_size = biovec->bv_len;
+
+       dm_table_put(map);
+
+       return max_size;
+}
+
 /*
  * The request function that just remaps the bio built up by
  * dm_merge_bvec.
@@ -1032,6 +1075,7 @@ static struct mapped_device *alloc_dev(int minor)
        blk_queue_make_request(md->queue, dm_request);
        blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
        md->queue->unplug_fn = dm_unplug_all;
+       blk_queue_merge_bvec(md->queue, dm_merge_bvec);
 
        md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache);
        if (!md->io_pool)
index 8c03b634e62e4a8106980750fb9d948b2fb9327f..1e59a0b0a78a0428a3c515280908062272e094d5 100644 (file)
@@ -100,12 +100,6 @@ int dm_lock_for_deletion(struct mapped_device *md);
 
 void dm_kobject_uevent(struct mapped_device *md);
 
-/*
- * Dirty log
- */
-int dm_dirty_log_init(void);
-void dm_dirty_log_exit(void);
-
 int dm_kcopyd_init(void);
 void dm_kcopyd_exit(void);
 
index d107ddceefcd4651eabaca68f34cf608c4046a56..268547dbfbd30ce2942b3b5d92c9bbfab793d4b7 100644 (file)
@@ -297,7 +297,7 @@ static int run(mddev_t *mddev)
        rdev_for_each(rdev, tmp, mddev)
                conf->rdev = rdev;
 
-       mddev->array_size = mddev->size;
+       mddev->array_sectors = mddev->size * 2;
        mddev->private = conf;
 
        reconfig(mddev, mddev->layout, -1);
index 6a866d7c8ae5885e3a0f75970106b1e76efca652..b1eebf88c209a9abfb920eae921c1ec74459383c 100644 (file)
@@ -122,13 +122,13 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
                return NULL;
 
        cnt = 0;
-       conf->array_size = 0;
+       conf->array_sectors = 0;
 
        rdev_for_each(rdev, tmp, mddev) {
                int j = rdev->raid_disk;
                dev_info_t *disk = conf->disks + j;
 
-               if (j < 0 || j > raid_disks || disk->rdev) {
+               if (j < 0 || j >= raid_disks || disk->rdev) {
                        printk("linear: disk numbering problem. Aborting!\n");
                        goto out;
                }
@@ -146,7 +146,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
                        blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
                disk->size = rdev->size;
-               conf->array_size += rdev->size;
+               conf->array_sectors += rdev->size * 2;
 
                cnt++;
        }
@@ -155,7 +155,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
                goto out;
        }
 
-       min_spacing = conf->array_size;
+       min_spacing = conf->array_sectors / 2;
        sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *));
 
        /* min_spacing is the minimum spacing that will fit the hash
@@ -164,7 +164,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
         * that is larger than min_spacing as use the size of that as
         * the actual spacing
         */
-       conf->hash_spacing = conf->array_size;
+       conf->hash_spacing = conf->array_sectors / 2;
        for (i=0; i < cnt-1 ; i++) {
                sector_t sz = 0;
                int j;
@@ -194,7 +194,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
                unsigned round;
                unsigned long base;
 
-               sz = conf->array_size >> conf->preshift;
+               sz = conf->array_sectors >> (conf->preshift + 1);
                sz += 1; /* force round-up */
                base = conf->hash_spacing >> conf->preshift;
                round = sector_div(sz, base);
@@ -221,7 +221,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
        curr_offset = 0;
        i = 0;
        for (curr_offset = 0;
-            curr_offset < conf->array_size;
+            curr_offset < conf->array_sectors / 2;
             curr_offset += conf->hash_spacing) {
 
                while (i < raid_disks-1 &&
@@ -258,7 +258,7 @@ static int linear_run (mddev_t *mddev)
        if (!conf)
                return 1;
        mddev->private = conf;
-       mddev->array_size = conf->array_size;
+       mddev->array_sectors = conf->array_sectors;
 
        blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
        mddev->queue->unplug_fn = linear_unplug;
@@ -292,8 +292,8 @@ static int linear_add(mddev_t *mddev, mdk_rdev_t *rdev)
        newconf->prev = mddev_to_conf(mddev);
        mddev->private = newconf;
        mddev->raid_disks++;
-       mddev->array_size = newconf->array_size;
-       set_capacity(mddev->gendisk, mddev->array_size << 1);
+       mddev->array_sectors = newconf->array_sectors;
+       set_capacity(mddev->gendisk, mddev->array_sectors);
        return 0;
 }
 
index 2580ac1b9b0ff06f34d37f12ea829682017e5ef1..c2ff77ccec5079ded33ef9e440744fcd2eaff004 100644 (file)
@@ -169,7 +169,6 @@ void md_new_event(mddev_t *mddev)
 {
        atomic_inc(&md_event_count);
        wake_up(&md_event_waiters);
-       sysfs_notify(&mddev->kobj, NULL, "sync_action");
 }
 EXPORT_SYMBOL_GPL(md_new_event);
 
@@ -274,10 +273,12 @@ static mddev_t * mddev_find(dev_t unit)
        INIT_LIST_HEAD(&new->all_mddevs);
        init_timer(&new->safemode_timer);
        atomic_set(&new->active, 1);
+       atomic_set(&new->openers, 0);
        spin_lock_init(&new->write_lock);
        init_waitqueue_head(&new->sb_wait);
        init_waitqueue_head(&new->recovery_wait);
        new->reshape_position = MaxSector;
+       new->resync_min = 0;
        new->resync_max = MaxSector;
        new->level = LEVEL_NONE;
 
@@ -347,21 +348,20 @@ static struct mdk_personality *find_pers(int level, char *clevel)
        return NULL;
 }
 
+/* return the offset of the super block in 512byte sectors */
 static inline sector_t calc_dev_sboffset(struct block_device *bdev)
 {
-       sector_t size = bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
-       return MD_NEW_SIZE_BLOCKS(size);
+       sector_t num_sectors = bdev->bd_inode->i_size / 512;
+       return MD_NEW_SIZE_SECTORS(num_sectors);
 }
 
-static sector_t calc_dev_size(mdk_rdev_t *rdev, unsigned chunk_size)
+static sector_t calc_num_sectors(mdk_rdev_t *rdev, unsigned chunk_size)
 {
-       sector_t size;
-
-       size = rdev->sb_offset;
+       sector_t num_sectors = rdev->sb_start;
 
        if (chunk_size)
-               size &= ~((sector_t)chunk_size/1024 - 1);
-       return size;
+               num_sectors &= ~((sector_t)chunk_size/512 - 1);
+       return num_sectors;
 }
 
 static int alloc_disk_sb(mdk_rdev_t * rdev)
@@ -372,7 +372,7 @@ static int alloc_disk_sb(mdk_rdev_t * rdev)
        rdev->sb_page = alloc_page(GFP_KERNEL);
        if (!rdev->sb_page) {
                printk(KERN_ALERT "md: out of memory.\n");
-               return -EINVAL;
+               return -ENOMEM;
        }
 
        return 0;
@@ -384,7 +384,7 @@ static void free_disk_sb(mdk_rdev_t * rdev)
                put_page(rdev->sb_page);
                rdev->sb_loaded = 0;
                rdev->sb_page = NULL;
-               rdev->sb_offset = 0;
+               rdev->sb_start = 0;
                rdev->size = 0;
        }
 }
@@ -530,7 +530,7 @@ static int read_disk_sb(mdk_rdev_t * rdev, int size)
                return 0;
 
 
-       if (!sync_page_io(rdev->bdev, rdev->sb_offset<<1, size, rdev->sb_page, READ))
+       if (!sync_page_io(rdev->bdev, rdev->sb_start, size, rdev->sb_page, READ))
                goto fail;
        rdev->sb_loaded = 1;
        return 0;
@@ -543,17 +543,12 @@ fail:
 
 static int uuid_equal(mdp_super_t *sb1, mdp_super_t *sb2)
 {
-       if (    (sb1->set_uuid0 == sb2->set_uuid0) &&
-               (sb1->set_uuid1 == sb2->set_uuid1) &&
-               (sb1->set_uuid2 == sb2->set_uuid2) &&
-               (sb1->set_uuid3 == sb2->set_uuid3))
-
-               return 1;
-
-       return 0;
+       return  sb1->set_uuid0 == sb2->set_uuid0 &&
+               sb1->set_uuid1 == sb2->set_uuid1 &&
+               sb1->set_uuid2 == sb2->set_uuid2 &&
+               sb1->set_uuid3 == sb2->set_uuid3;
 }
 
-
 static int sb_equal(mdp_super_t *sb1, mdp_super_t *sb2)
 {
        int ret;
@@ -564,7 +559,7 @@ static int sb_equal(mdp_super_t *sb1, mdp_super_t *sb2)
 
        if (!tmp1 || !tmp2) {
                ret = 0;
-               printk(KERN_INFO "md.c: sb1 is not equal to sb2!\n");
+               printk(KERN_INFO "md.c sb_equal(): failed to allocate memory!\n");
                goto abort;
        }
 
@@ -577,11 +572,7 @@ static int sb_equal(mdp_super_t *sb1, mdp_super_t *sb2)
        tmp1->nr_disks = 0;
        tmp2->nr_disks = 0;
 
-       if (memcmp(tmp1, tmp2, MD_SB_GENERIC_CONSTANT_WORDS * 4))
-               ret = 0;
-       else
-               ret = 1;
-
+       ret = (memcmp(tmp1, tmp2, MD_SB_GENERIC_CONSTANT_WORDS * 4) == 0);
 abort:
        kfree(tmp1);
        kfree(tmp2);
@@ -658,11 +649,14 @@ static unsigned int calc_sb_csum(mdp_super_t * sb)
  */
 
 struct super_type  {
-       char            *name;
-       struct module   *owner;
-       int             (*load_super)(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version);
-       int             (*validate_super)(mddev_t *mddev, mdk_rdev_t *rdev);
-       void            (*sync_super)(mddev_t *mddev, mdk_rdev_t *rdev);
+       char                *name;
+       struct module       *owner;
+       int                 (*load_super)(mdk_rdev_t *rdev, mdk_rdev_t *refdev,
+                                         int minor_version);
+       int                 (*validate_super)(mddev_t *mddev, mdk_rdev_t *rdev);
+       void                (*sync_super)(mddev_t *mddev, mdk_rdev_t *rdev);
+       unsigned long long  (*rdev_size_change)(mdk_rdev_t *rdev,
+                                               sector_t num_sectors);
 };
 
 /*
@@ -673,16 +667,14 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version
        char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
        mdp_super_t *sb;
        int ret;
-       sector_t sb_offset;
 
        /*
-        * Calculate the position of the superblock,
+        * Calculate the position of the superblock (512byte sectors),
         * it's at the end of the disk.
         *
         * It also happens to be a multiple of 4Kb.
         */
-       sb_offset = calc_dev_sboffset(rdev->bdev);
-       rdev->sb_offset = sb_offset;
+       rdev->sb_start = calc_dev_sboffset(rdev->bdev);
 
        ret = read_disk_sb(rdev, MD_SB_BYTES);
        if (ret) return ret;
@@ -759,7 +751,7 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version
                else 
                        ret = 0;
        }
-       rdev->size = calc_dev_size(rdev, sb->chunk_size);
+       rdev->size = calc_num_sectors(rdev, sb->chunk_size) / 2;
 
        if (rdev->size < sb->size && sb->level > 1)
                /* "this cannot possibly happen" ... */
@@ -1003,6 +995,26 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
        sb->sb_csum = calc_sb_csum(sb);
 }
 
+/*
+ * rdev_size_change for 0.90.0
+ */
+static unsigned long long
+super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
+{
+       if (num_sectors && num_sectors < rdev->mddev->size * 2)
+               return 0; /* component must fit device */
+       if (rdev->mddev->bitmap_offset)
+               return 0; /* can't move bitmap */
+       rdev->sb_start = calc_dev_sboffset(rdev->bdev);
+       if (!num_sectors || num_sectors > rdev->sb_start)
+               num_sectors = rdev->sb_start;
+       md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
+                      rdev->sb_page);
+       md_super_wait(rdev->mddev);
+       return num_sectors / 2; /* kB for sysfs */
+}
+
+
 /*
  * version 1 superblock
  */
@@ -1034,12 +1046,12 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
 {
        struct mdp_superblock_1 *sb;
        int ret;
-       sector_t sb_offset;
+       sector_t sb_start;
        char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
        int bmask;
 
        /*
-        * Calculate the position of the superblock.
+        * Calculate the position of the superblock in 512byte sectors.
         * It is always aligned to a 4K boundary and
         * depeding on minor_version, it can be:
         * 0: At least 8K, but less than 12K, from end of device
@@ -1048,22 +1060,20 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
         */
        switch(minor_version) {
        case 0:
-               sb_offset = rdev->bdev->bd_inode->i_size >> 9;
-               sb_offset -= 8*2;
-               sb_offset &= ~(sector_t)(4*2-1);
-               /* convert from sectors to K */
-               sb_offset /= 2;
+               sb_start = rdev->bdev->bd_inode->i_size >> 9;
+               sb_start -= 8*2;
+               sb_start &= ~(sector_t)(4*2-1);
                break;
        case 1:
-               sb_offset = 0;
+               sb_start = 0;
                break;
        case 2:
-               sb_offset = 4;
+               sb_start = 8;
                break;
        default:
                return -EINVAL;
        }
-       rdev->sb_offset = sb_offset;
+       rdev->sb_start = sb_start;
 
        /* superblock is rarely larger than 1K, but it can be larger,
         * and it is safe to read 4k, so we do that
@@ -1077,7 +1087,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
        if (sb->magic != cpu_to_le32(MD_SB_MAGIC) ||
            sb->major_version != cpu_to_le32(1) ||
            le32_to_cpu(sb->max_dev) > (4096-256)/2 ||
-           le64_to_cpu(sb->super_offset) != (rdev->sb_offset<<1) ||
+           le64_to_cpu(sb->super_offset) != rdev->sb_start ||
            (le32_to_cpu(sb->feature_map) & ~MD_FEATURE_ALL) != 0)
                return -EINVAL;
 
@@ -1113,7 +1123,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
                rdev->sb_size = (rdev->sb_size | bmask) + 1;
 
        if (minor_version
-           && rdev->data_offset < sb_offset + (rdev->sb_size/512))
+           && rdev->data_offset < sb_start + (rdev->sb_size/512))
                return -EINVAL;
 
        if (sb->level == cpu_to_le32(LEVEL_MULTIPATH))
@@ -1149,7 +1159,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
        if (minor_version)
                rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2;
        else
-               rdev->size = rdev->sb_offset;
+               rdev->size = rdev->sb_start / 2;
        if (rdev->size < le64_to_cpu(sb->data_size)/2)
                return -EINVAL;
        rdev->size = le64_to_cpu(sb->data_size)/2;
@@ -1328,35 +1338,74 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
        sb->sb_csum = calc_sb_1_csum(sb);
 }
 
+static unsigned long long
+super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
+{
+       struct mdp_superblock_1 *sb;
+       sector_t max_sectors;
+       if (num_sectors && num_sectors < rdev->mddev->size * 2)
+               return 0; /* component must fit device */
+       if (rdev->sb_start < rdev->data_offset) {
+               /* minor versions 1 and 2; superblock before data */
+               max_sectors = rdev->bdev->bd_inode->i_size >> 9;
+               max_sectors -= rdev->data_offset;
+               if (!num_sectors || num_sectors > max_sectors)
+                       num_sectors = max_sectors;
+       } else if (rdev->mddev->bitmap_offset) {
+               /* minor version 0 with bitmap we can't move */
+               return 0;
+       } else {
+               /* minor version 0; superblock after data */
+               sector_t sb_start;
+               sb_start = (rdev->bdev->bd_inode->i_size >> 9) - 8*2;
+               sb_start &= ~(sector_t)(4*2 - 1);
+               max_sectors = rdev->size * 2 + sb_start - rdev->sb_start;
+               if (!num_sectors || num_sectors > max_sectors)
+                       num_sectors = max_sectors;
+               rdev->sb_start = sb_start;
+       }
+       sb = (struct mdp_superblock_1 *) page_address(rdev->sb_page);
+       sb->data_size = cpu_to_le64(num_sectors);
+       sb->super_offset = rdev->sb_start;
+       sb->sb_csum = calc_sb_1_csum(sb);
+       md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
+                      rdev->sb_page);
+       md_super_wait(rdev->mddev);
+       return num_sectors / 2; /* kB for sysfs */
+}
 
 static struct super_type super_types[] = {
        [0] = {
                .name   = "0.90.0",
                .owner  = THIS_MODULE,
-               .load_super     = super_90_load,
-               .validate_super = super_90_validate,
-               .sync_super     = super_90_sync,
+               .load_super         = super_90_load,
+               .validate_super     = super_90_validate,
+               .sync_super         = super_90_sync,
+               .rdev_size_change   = super_90_rdev_size_change,
        },
        [1] = {
                .name   = "md-1",
                .owner  = THIS_MODULE,
-               .load_super     = super_1_load,
-               .validate_super = super_1_validate,
-               .sync_super     = super_1_sync,
+               .load_super         = super_1_load,
+               .validate_super     = super_1_validate,
+               .sync_super         = super_1_sync,
+               .rdev_size_change   = super_1_rdev_size_change,
        },
 };
 
 static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
 {
-       struct list_head *tmp, *tmp2;
        mdk_rdev_t *rdev, *rdev2;
 
-       rdev_for_each(rdev, tmp, mddev1)
-               rdev_for_each(rdev2, tmp2, mddev2)
+       rcu_read_lock();
+       rdev_for_each_rcu(rdev, mddev1)
+               rdev_for_each_rcu(rdev2, mddev2)
                        if (rdev->bdev->bd_contains ==
-                           rdev2->bdev->bd_contains)
+                           rdev2->bdev->bd_contains) {
+                               rcu_read_unlock();
                                return 1;
-
+                       }
+       rcu_read_unlock();
        return 0;
 }
 
@@ -1423,7 +1472,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
                kobject_del(&rdev->kobj);
                goto fail;
        }
-       list_add(&rdev->same_set, &mddev->disks);
+       list_add_rcu(&rdev->same_set, &mddev->disks);
        bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk);
        return 0;
 
@@ -1448,14 +1497,16 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
                return;
        }
        bd_release_from_disk(rdev->bdev, rdev->mddev->gendisk);
-       list_del_init(&rdev->same_set);
+       list_del_rcu(&rdev->same_set);
        printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
        rdev->mddev = NULL;
        sysfs_remove_link(&rdev->kobj, "block");
 
        /* We need to delay this, otherwise we can deadlock when
-        * writing to 'remove' to "dev/state"
+        * writing to 'remove' to "dev/state".  We also need
+        * to delay it due to rcu usage.
         */
+       synchronize_rcu();
        INIT_WORK(&rdev->del_work, md_delayed_delete);
        kobject_get(&rdev->kobj);
        schedule_work(&rdev->del_work);
@@ -1511,7 +1562,6 @@ static void export_rdev(mdk_rdev_t * rdev)
        if (rdev->mddev)
                MD_BUG();
        free_disk_sb(rdev);
-       list_del_init(&rdev->same_set);
 #ifndef MODULE
        if (test_bit(AutoDetected, &rdev->flags))
                md_autodetect_dev(rdev->bdev->bd_dev);
@@ -1758,11 +1808,11 @@ repeat:
                dprintk("%s ", bdevname(rdev->bdev,b));
                if (!test_bit(Faulty, &rdev->flags)) {
                        md_super_write(mddev,rdev,
-                                      rdev->sb_offset<<1, rdev->sb_size,
+                                      rdev->sb_start, rdev->sb_size,
                                       rdev->sb_page);
                        dprintk(KERN_INFO "(write) %s's sb offset: %llu\n",
                                bdevname(rdev->bdev,b),
-                               (unsigned long long)rdev->sb_offset);
+                               (unsigned long long)rdev->sb_start);
                        rdev->sb_events = mddev->events;
 
                } else
@@ -1787,7 +1837,7 @@ repeat:
 
 }
 
-/* words written to sysfs files may, or my not, be \n terminated.
+/* words written to sysfs files may, or may not, be \n terminated.
  * We want to accept with case. For this we use cmd_match.
  */
 static int cmd_match(const char *cmd, const char *str)
@@ -1886,6 +1936,8 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
 
                err = 0;
        }
+       if (!err)
+               sysfs_notify(&rdev->kobj, NULL, "state");
        return err ? err : len;
 }
 static struct rdev_sysfs_entry rdev_state =
@@ -1931,7 +1983,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                slot = -1;
        else if (e==buf || (*e && *e!= '\n'))
                return -EINVAL;
-       if (rdev->mddev->pers) {
+       if (rdev->mddev->pers && slot == -1) {
                /* Setting 'slot' on an active array requires also
                 * updating the 'rd%d' link, and communicating
                 * with the personality with ->hot_*_disk.
@@ -1939,8 +1991,6 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                 * failed/spare devices.  This normally happens automatically,
                 * but not when the metadata is externally managed.
                 */
-               if (slot != -1)
-                       return -EBUSY;
                if (rdev->raid_disk == -1)
                        return -EEXIST;
                /* personality does all needed checks */
@@ -1954,6 +2004,43 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                sysfs_remove_link(&rdev->mddev->kobj, nm);
                set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery);
                md_wakeup_thread(rdev->mddev->thread);
+       } else if (rdev->mddev->pers) {
+               mdk_rdev_t *rdev2;
+               struct list_head *tmp;
+               /* Activating a spare .. or possibly reactivating
+                * if we every get bitmaps working here.
+                */
+
+               if (rdev->raid_disk != -1)
+                       return -EBUSY;
+
+               if (rdev->mddev->pers->hot_add_disk == NULL)
+                       return -EINVAL;
+
+               rdev_for_each(rdev2, tmp, rdev->mddev)
+                       if (rdev2->raid_disk == slot)
+                               return -EEXIST;
+
+               rdev->raid_disk = slot;
+               if (test_bit(In_sync, &rdev->flags))
+                       rdev->saved_raid_disk = slot;
+               else
+                       rdev->saved_raid_disk = -1;
+               err = rdev->mddev->pers->
+                       hot_add_disk(rdev->mddev, rdev);
+               if (err) {
+                       rdev->raid_disk = -1;
+                       return err;
+               } else
+                       sysfs_notify(&rdev->kobj, NULL, "state");
+               sprintf(nm, "rd%d", rdev->raid_disk);
+               if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm))
+                       printk(KERN_WARNING
+                              "md: cannot register "
+                              "%s for %s\n",
+                              nm, mdname(rdev->mddev));
+
+               /* don't wakeup anyone, leave that to userspace. */
        } else {
                if (slot >= rdev->mddev->raid_disks)
                        return -ENOSPC;
@@ -1962,6 +2049,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                clear_bit(Faulty, &rdev->flags);
                clear_bit(WriteMostly, &rdev->flags);
                set_bit(In_sync, &rdev->flags);
+               sysfs_notify(&rdev->kobj, NULL, "state");
        }
        return len;
 }
@@ -1983,7 +2071,7 @@ offset_store(mdk_rdev_t *rdev, const char *buf, size_t len)
        unsigned long long offset = simple_strtoull(buf, &e, 10);
        if (e==buf || (*e && *e != '\n'))
                return -EINVAL;
-       if (rdev->mddev->pers)
+       if (rdev->mddev->pers && rdev->raid_disk >= 0)
                return -EBUSY;
        if (rdev->size && rdev->mddev->external)
                /* Must set offset before size, so overlap checks
@@ -2015,17 +2103,30 @@ static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2)
 static ssize_t
 rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
 {
-       char *e;
-       unsigned long long size = simple_strtoull(buf, &e, 10);
+       unsigned long long size;
        unsigned long long oldsize = rdev->size;
        mddev_t *my_mddev = rdev->mddev;
 
-       if (e==buf || (*e && *e != '\n'))
+       if (strict_strtoull(buf, 10, &size) < 0)
                return -EINVAL;
-       if (my_mddev->pers)
-               return -EBUSY;
+       if (size < my_mddev->size)
+               return -EINVAL;
+       if (my_mddev->pers && rdev->raid_disk >= 0) {
+               if (my_mddev->persistent) {
+                       size = super_types[my_mddev->major_version].
+                               rdev_size_change(rdev, size * 2);
+                       if (!size)
+                               return -EBUSY;
+               } else if (!size) {
+                       size = (rdev->bdev->bd_inode->i_size >> 10);
+                       size -= rdev->data_offset/2;
+               }
+               if (size < my_mddev->size)
+                       return -EINVAL; /* component must fit device */
+       }
+
        rdev->size = size;
-       if (size > oldsize && rdev->mddev->external) {
+       if (size > oldsize && my_mddev->external) {
                /* need to check that all other rdevs with the same ->bdev
                 * do not overlap.  We need to unlock the mddev to avoid
                 * a deadlock.  We have already changed rdev->size, and if
@@ -2044,8 +2145,9 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                                if (test_bit(AllReserved, &rdev2->flags) ||
                                    (rdev->bdev == rdev2->bdev &&
                                     rdev != rdev2 &&
-                                    overlaps(rdev->data_offset, rdev->size,
-                                           rdev2->data_offset, rdev2->size))) {
+                                    overlaps(rdev->data_offset, rdev->size * 2,
+                                             rdev2->data_offset,
+                                             rdev2->size * 2))) {
                                        overlap = 1;
                                        break;
                                }
@@ -2067,8 +2169,6 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                        return -EBUSY;
                }
        }
-       if (size < my_mddev->size || my_mddev->size == 0)
-               my_mddev->size = size;
        return len;
 }
 
@@ -2512,7 +2612,7 @@ __ATTR(resync_start, S_IRUGO|S_IWUSR, resync_start_show, resync_start_store);
  *     When written, doesn't tear down array, but just stops it
  * suspended (not supported yet)
  *     All IO requests will block. The array can be reconfigured.
- *     Writing this, if accepted, will block until array is quiessent
+ *     Writing this, if accepted, will block until array is quiescent
  * readonly
  *     no resync can happen.  no superblocks get written.
  *     write requests fail
@@ -2585,7 +2685,7 @@ array_state_show(mddev_t *mddev, char *page)
        return sprintf(page, "%s\n", array_states[st]);
 }
 
-static int do_md_stop(mddev_t * mddev, int ro);
+static int do_md_stop(mddev_t * mddev, int ro, int is_open);
 static int do_md_run(mddev_t * mddev);
 static int restart_array(mddev_t *mddev);
 
@@ -2599,16 +2699,16 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
                break;
        case clear:
                /* stopping an active array */
-               if (atomic_read(&mddev->active) > 1)
+               if (atomic_read(&mddev->openers) > 0)
                        return -EBUSY;
-               err = do_md_stop(mddev, 0);
+               err = do_md_stop(mddev, 0, 0);
                break;
        case inactive:
                /* stopping an active array */
                if (mddev->pers) {
-                       if (atomic_read(&mddev->active) > 1)
+                       if (atomic_read(&mddev->openers) > 0)
                                return -EBUSY;
-                       err = do_md_stop(mddev, 2);
+                       err = do_md_stop(mddev, 2, 0);
                } else
                        err = 0; /* already inactive */
                break;
@@ -2616,7 +2716,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
                break; /* not supported yet */
        case readonly:
                if (mddev->pers)
-                       err = do_md_stop(mddev, 1);
+                       err = do_md_stop(mddev, 1, 0);
                else {
                        mddev->ro = 1;
                        set_disk_ro(mddev->gendisk, 1);
@@ -2626,7 +2726,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
        case read_auto:
                if (mddev->pers) {
                        if (mddev->ro != 1)
-                               err = do_md_stop(mddev, 1);
+                               err = do_md_stop(mddev, 1, 0);
                        else
                                err = restart_array(mddev);
                        if (err == 0) {
@@ -2681,8 +2781,10 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
        }
        if (err)
                return err;
-       else
+       else {
+               sysfs_notify(&mddev->kobj, NULL, "array_state");
                return len;
+       }
 }
 static struct md_sysfs_entry md_array_state =
 __ATTR(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store);
@@ -2785,7 +2887,7 @@ size_show(mddev_t *mddev, char *page)
        return sprintf(page, "%llu\n", (unsigned long long)mddev->size);
 }
 
-static int update_size(mddev_t *mddev, unsigned long size);
+static int update_size(mddev_t *mddev, sector_t num_sectors);
 
 static ssize_t
 size_store(mddev_t *mddev, const char *buf, size_t len)
@@ -2802,7 +2904,7 @@ size_store(mddev_t *mddev, const char *buf, size_t len)
                return -EINVAL;
 
        if (mddev->pers) {
-               err = update_size(mddev, size);
+               err = update_size(mddev, size * 2);
                md_update_sb(mddev, 1);
        } else {
                if (mddev->size == 0 ||
@@ -2899,7 +3001,7 @@ action_show(mddev_t *mddev, char *page)
                                type = "check";
                        else
                                type = "repair";
-               } else
+               } else if (test_bit(MD_RECOVERY_RECOVER, &mddev->recovery))
                        type = "recover";
        }
        return sprintf(page, "%s\n", type);
@@ -2921,15 +3023,19 @@ action_store(mddev_t *mddev, const char *page, size_t len)
        } else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
                   test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
                return -EBUSY;
-       else if (cmd_match(page, "resync") || cmd_match(page, "recover"))
+       else if (cmd_match(page, "resync"))
+               set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+       else if (cmd_match(page, "recover")) {
+               set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
                set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
-       else if (cmd_match(page, "reshape")) {
+       else if (cmd_match(page, "reshape")) {
                int err;
                if (mddev->pers->start_reshape == NULL)
                        return -EINVAL;
                err = mddev->pers->start_reshape(mddev);
                if (err)
                        return err;
+               sysfs_notify(&mddev->kobj, NULL, "degraded");
        } else {
                if (cmd_match(page, "check"))
                        set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
@@ -2940,6 +3046,7 @@ action_store(mddev_t *mddev, const char *page, size_t len)
        }
        set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
        md_wakeup_thread(mddev->thread);
+       sysfs_notify(&mddev->kobj, NULL, "sync_action");
        return len;
 }
 
@@ -3049,11 +3156,11 @@ static ssize_t
 sync_speed_show(mddev_t *mddev, char *page)
 {
        unsigned long resync, dt, db;
-       resync = (mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active));
-       dt = ((jiffies - mddev->resync_mark) / HZ);
+       resync = mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active);
+       dt = (jiffies - mddev->resync_mark) / HZ;
        if (!dt) dt++;
-       db = resync - (mddev->resync_mark_cnt);
-       return sprintf(page, "%ld\n", db/dt/2); /* K/sec */
+       db = resync - mddev->resync_mark_cnt;
+       return sprintf(page, "%lu\n", db/dt/2); /* K/sec */
 }
 
 static struct md_sysfs_entry md_sync_speed = __ATTR_RO(sync_speed);
@@ -3074,6 +3181,36 @@ sync_completed_show(mddev_t *mddev, char *page)
 
 static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed);
 
+static ssize_t
+min_sync_show(mddev_t *mddev, char *page)
+{
+       return sprintf(page, "%llu\n",
+                      (unsigned long long)mddev->resync_min);
+}
+static ssize_t
+min_sync_store(mddev_t *mddev, const char *buf, size_t len)
+{
+       unsigned long long min;
+       if (strict_strtoull(buf, 10, &min))
+               return -EINVAL;
+       if (min > mddev->resync_max)
+               return -EINVAL;
+       if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
+               return -EBUSY;
+
+       /* Must be a multiple of chunk_size */
+       if (mddev->chunk_size) {
+               if (min & (sector_t)((mddev->chunk_size>>9)-1))
+                       return -EINVAL;
+       }
+       mddev->resync_min = min;
+
+       return len;
+}
+
+static struct md_sysfs_entry md_min_sync =
+__ATTR(sync_min, S_IRUGO|S_IWUSR, min_sync_show, min_sync_store);
+
 static ssize_t
 max_sync_show(mddev_t *mddev, char *page)
 {
@@ -3089,9 +3226,10 @@ max_sync_store(mddev_t *mddev, const char *buf, size_t len)
        if (strncmp(buf, "max", 3) == 0)
                mddev->resync_max = MaxSector;
        else {
-               char *ep;
-               unsigned long long max = simple_strtoull(buf, &ep, 10);
-               if (ep == buf || (*ep != 0 && *ep != '\n'))
+               unsigned long long max;
+               if (strict_strtoull(buf, 10, &max))
+                       return -EINVAL;
+               if (max < mddev->resync_min)
                        return -EINVAL;
                if (max < mddev->resync_max &&
                    test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
@@ -3222,6 +3360,7 @@ static struct attribute *md_redundancy_attrs[] = {
        &md_sync_speed.attr,
        &md_sync_force_parallel.attr,
        &md_sync_completed.attr,
+       &md_min_sync.attr,
        &md_max_sync.attr,
        &md_suspend_lo.attr,
        &md_suspend_hi.attr,
@@ -3326,9 +3465,9 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
        disk->queue = mddev->queue;
        add_disk(disk);
        mddev->gendisk = disk;
-       mutex_unlock(&disks_mutex);
        error = kobject_init_and_add(&mddev->kobj, &md_ktype, &disk->dev.kobj,
                                     "%s", "md");
+       mutex_unlock(&disks_mutex);
        if (error)
                printk(KERN_WARNING "md: cannot register %s/md - name in use\n",
                       disk->disk_name);
@@ -3341,7 +3480,11 @@ static void md_safemode_timeout(unsigned long data)
 {
        mddev_t *mddev = (mddev_t *) data;
 
-       mddev->safemode = 1;
+       if (!atomic_read(&mddev->writes_pending)) {
+               mddev->safemode = 1;
+               if (mddev->external)
+                       sysfs_notify(&mddev->kobj, NULL, "array_state");
+       }
        md_wakeup_thread(mddev->thread);
 }
 
@@ -3432,22 +3575,23 @@ static int do_md_run(mddev_t * mddev)
                 * We don't want the data to overlap the metadata,
                 * Internal Bitmap issues has handled elsewhere.
                 */
-               if (rdev->data_offset < rdev->sb_offset) {
+               if (rdev->data_offset < rdev->sb_start) {
                        if (mddev->size &&
                            rdev->data_offset + mddev->size*2
-                           > rdev->sb_offset*2) {
+                           > rdev->sb_start) {
                                printk("md: %s: data overlaps metadata\n",
                                       mdname(mddev));
                                return -EINVAL;
                        }
                } else {
-                       if (rdev->sb_offset*2 + rdev->sb_size/512
+                       if (rdev->sb_start + rdev->sb_size/512
                            > rdev->data_offset) {
                                printk("md: %s: metadata overlaps data\n",
                                       mdname(mddev));
                                return -EINVAL;
                        }
                }
+               sysfs_notify(&rdev->kobj, NULL, "state");
        }
 
        md_probe(mddev->unit, NULL, NULL);
@@ -3519,7 +3663,9 @@ static int do_md_run(mddev_t * mddev)
                mddev->ro = 2; /* read-only, but switch on first write */
 
        err = mddev->pers->run(mddev);
-       if (!err && mddev->pers->sync_request) {
+       if (err)
+               printk(KERN_ERR "md: pers->run() failed ...\n");
+       else if (mddev->pers->sync_request) {
                err = bitmap_create(mddev);
                if (err) {
                        printk(KERN_ERR "%s: failed to create bitmap (%d)\n",
@@ -3528,7 +3674,6 @@ static int do_md_run(mddev_t * mddev)
                }
        }
        if (err) {
-               printk(KERN_ERR "md: pers->run() failed ...\n");
                module_put(mddev->pers->owner);
                mddev->pers = NULL;
                bitmap_destroy(mddev);
@@ -3563,7 +3708,7 @@ static int do_md_run(mddev_t * mddev)
        if (mddev->flags)
                md_update_sb(mddev, 0);
 
-       set_capacity(disk, mddev->array_size<<1);
+       set_capacity(disk, mddev->array_sectors);
 
        /* If we call blk_queue_make_request here, it will
         * re-initialise max_sectors etc which may have been
@@ -3608,6 +3753,9 @@ static int do_md_run(mddev_t * mddev)
 
        mddev->changed = 1;
        md_new_event(mddev);
+       sysfs_notify(&mddev->kobj, NULL, "array_state");
+       sysfs_notify(&mddev->kobj, NULL, "sync_action");
+       sysfs_notify(&mddev->kobj, NULL, "degraded");
        kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE);
        return 0;
 }
@@ -3615,38 +3763,25 @@ static int do_md_run(mddev_t * mddev)
 static int restart_array(mddev_t *mddev)
 {
        struct gendisk *disk = mddev->gendisk;
-       int err;
 
-       /*
-        * Complain if it has no devices
-        */
-       err = -ENXIO;
+       /* Complain if it has no devices */
        if (list_empty(&mddev->disks))
-               goto out;
-
-       if (mddev->pers) {
-               err = -EBUSY;
-               if (!mddev->ro)
-                       goto out;
-
-               mddev->safemode = 0;
-               mddev->ro = 0;
-               set_disk_ro(disk, 0);
-
-               printk(KERN_INFO "md: %s switched to read-write mode.\n",
-                       mdname(mddev));
-               /*
-                * Kick recovery or resync if necessary
-                */
-               set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
-               md_wakeup_thread(mddev->thread);
-               md_wakeup_thread(mddev->sync_thread);
-               err = 0;
-       } else
-               err = -EINVAL;
-
-out:
-       return err;
+               return -ENXIO;
+       if (!mddev->pers)
+               return -EINVAL;
+       if (!mddev->ro)
+               return -EBUSY;
+       mddev->safemode = 0;
+       mddev->ro = 0;
+       set_disk_ro(disk, 0);
+       printk(KERN_INFO "md: %s switched to read-write mode.\n",
+               mdname(mddev));
+       /* Kick recovery or resync if necessary */
+       set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+       md_wakeup_thread(mddev->thread);
+       md_wakeup_thread(mddev->sync_thread);
+       sysfs_notify(&mddev->kobj, NULL, "array_state");
+       return 0;
 }
 
 /* similar to deny_write_access, but accounts for our holding a reference
@@ -3680,16 +3815,17 @@ static void restore_bitmap_write_access(struct file *file)
  *   1 - switch to readonly
  *   2 - stop but do not disassemble array
  */
-static int do_md_stop(mddev_t * mddev, int mode)
+static int do_md_stop(mddev_t * mddev, int mode, int is_open)
 {
        int err = 0;
        struct gendisk *disk = mddev->gendisk;
 
+       if (atomic_read(&mddev->openers) > is_open) {
+               printk("md: %s still in use.\n",mdname(mddev));
+               return -EBUSY;
+       }
+
        if (mddev->pers) {
-               if (atomic_read(&mddev->active)>2) {
-                       printk("md: %s still in use.\n",mdname(mddev));
-                       return -EBUSY;
-               }
 
                if (mddev->sync_thread) {
                        set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
@@ -3773,10 +3909,11 @@ static int do_md_stop(mddev_t * mddev, int mode)
 
                export_array(mddev);
 
-               mddev->array_size = 0;
+               mddev->array_sectors = 0;
                mddev->size = 0;
                mddev->raid_disks = 0;
                mddev->recovery_cp = 0;
+               mddev->resync_min = 0;
                mddev->resync_max = MaxSector;
                mddev->reshape_position = MaxSector;
                mddev->external = 0;
@@ -3811,6 +3948,7 @@ static int do_md_stop(mddev_t * mddev, int mode)
                        mdname(mddev));
        err = 0;
        md_new_event(mddev);
+       sysfs_notify(&mddev->kobj, NULL, "array_state");
 out:
        return err;
 }
@@ -3836,7 +3974,7 @@ static void autorun_array(mddev_t *mddev)
        err = do_md_run (mddev);
        if (err) {
                printk(KERN_WARNING "md: do_md_run() returned %d\n", err);
-               do_md_stop (mddev, 0);
+               do_md_stop (mddev, 0, 0);
        }
 }
 
@@ -3927,8 +4065,10 @@ static void autorun_devices(int part)
                /* on success, candidates will be empty, on error
                 * it won't...
                 */
-               rdev_for_each_list(rdev, tmp, candidates)
+               rdev_for_each_list(rdev, tmp, candidates) {
+                       list_del_init(&rdev->same_set);
                        export_rdev(rdev);
+               }
                mddev_put(mddev);
        }
        printk(KERN_INFO "md: ... autorun DONE.\n");
@@ -4009,9 +4149,11 @@ static int get_bitmap_file(mddev_t * mddev, void __user * arg)
        char *ptr, *buf = NULL;
        int err = -ENOMEM;
 
-       md_allow_write(mddev);
+       if (md_allow_write(mddev))
+               file = kmalloc(sizeof(*file), GFP_NOIO);
+       else
+               file = kmalloc(sizeof(*file), GFP_KERNEL);
 
-       file = kmalloc(sizeof(*file), GFP_KERNEL);
        if (!file)
                goto out;
 
@@ -4044,15 +4186,12 @@ out:
 static int get_disk_info(mddev_t * mddev, void __user * arg)
 {
        mdu_disk_info_t info;
-       unsigned int nr;
        mdk_rdev_t *rdev;
 
        if (copy_from_user(&info, arg, sizeof(info)))
                return -EFAULT;
 
-       nr = info.number;
-
-       rdev = find_rdev_nr(mddev, nr);
+       rdev = find_rdev_nr(mddev, info.number);
        if (rdev) {
                info.major = MAJOR(rdev->bdev->bd_dev);
                info.minor = MINOR(rdev->bdev->bd_dev);
@@ -4172,8 +4311,12 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
                }
                if (err)
                        export_rdev(rdev);
+               else
+                       sysfs_notify(&rdev->kobj, NULL, "state");
 
                md_update_sb(mddev, 1);
+               if (mddev->degraded)
+                       set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
                set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                md_wakeup_thread(mddev->thread);
                return err;
@@ -4212,10 +4355,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
 
                if (!mddev->persistent) {
                        printk(KERN_INFO "md: nonpersistent superblock ...\n");
-                       rdev->sb_offset = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
+                       rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
                } else 
-                       rdev->sb_offset = calc_dev_sboffset(rdev->bdev);
-               rdev->size = calc_dev_size(rdev, mddev->chunk_size);
+                       rdev->sb_start = calc_dev_sboffset(rdev->bdev);
+               rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2;
 
                err = bind_rdev_to_array(rdev, mddev);
                if (err) {
@@ -4232,9 +4375,6 @@ static int hot_remove_disk(mddev_t * mddev, dev_t dev)
        char b[BDEVNAME_SIZE];
        mdk_rdev_t *rdev;
 
-       if (!mddev->pers)
-               return -ENODEV;
-
        rdev = find_rdev(mddev, dev);
        if (!rdev)
                return -ENXIO;
@@ -4257,7 +4397,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
 {
        char b[BDEVNAME_SIZE];
        int err;
-       unsigned int size;
        mdk_rdev_t *rdev;
 
        if (!mddev->pers)
@@ -4285,13 +4424,11 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
        }
 
        if (mddev->persistent)
-               rdev->sb_offset = calc_dev_sboffset(rdev->bdev);
+               rdev->sb_start = calc_dev_sboffset(rdev->bdev);
        else
-               rdev->sb_offset =
-                       rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
+               rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
 
-       size = calc_dev_size(rdev, mddev->chunk_size);
-       rdev->size = size;
+       rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2;
 
        if (test_bit(Faulty, &rdev->flags)) {
                printk(KERN_WARNING 
@@ -4476,24 +4613,24 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
        return 0;
 }
 
-static int update_size(mddev_t *mddev, unsigned long size)
+static int update_size(mddev_t *mddev, sector_t num_sectors)
 {
        mdk_rdev_t * rdev;
        int rv;
        struct list_head *tmp;
-       int fit = (size == 0);
+       int fit = (num_sectors == 0);
 
        if (mddev->pers->resize == NULL)
                return -EINVAL;
-       /* The "size" is the amount of each device that is used.
-        * This can only make sense for arrays with redundancy.
-        * linear and raid0 always use whatever space is available
-        * We can only consider changing the size if no resync
-        * or reconstruction is happening, and if the new size
-        * is acceptable. It must fit before the sb_offset or,
-        * if that is <data_offset, it must fit before the
-        * size of each device.
-        * If size is zero, we find the largest size that fits.
+       /* The "num_sectors" is the number of sectors of each device that
+        * is used.  This can only make sense for arrays with redundancy.
+        * linear and raid0 always use whatever space is available. We can only
+        * consider changing this number if no resync or reconstruction is
+        * happening, and if the new size is acceptable. It must fit before the
+        * sb_start or, if that is <data_offset, it must fit before the size
+        * of each device.  If num_sectors is zero, we find the largest size
+        * that fits.
+
         */
        if (mddev->sync_thread)
                return -EBUSY;
@@ -4501,19 +4638,20 @@ static int update_size(mddev_t *mddev, unsigned long size)
                sector_t avail;
                avail = rdev->size * 2;
 
-               if (fit && (size == 0 || size > avail/2))
-                       size = avail/2;
-               if (avail < ((sector_t)size << 1))
+               if (fit && (num_sectors == 0 || num_sectors > avail))
+                       num_sectors = avail;
+               if (avail < num_sectors)
                        return -ENOSPC;
        }
-       rv = mddev->pers->resize(mddev, (sector_t)size *2);
+       rv = mddev->pers->resize(mddev, num_sectors);
        if (!rv) {
                struct block_device *bdev;
 
                bdev = bdget_disk(mddev->gendisk, 0);
                if (bdev) {
                        mutex_lock(&bdev->bd_inode->i_mutex);
-                       i_size_write(bdev->bd_inode, (loff_t)mddev->array_size << 10);
+                       i_size_write(bdev->bd_inode,
+                                    (loff_t)mddev->array_sectors << 9);
                        mutex_unlock(&bdev->bd_inode->i_mutex);
                        bdput(bdev);
                }
@@ -4588,7 +4726,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
                        return mddev->pers->reconfig(mddev, info->layout, -1);
        }
        if (info->size >= 0 && mddev->size != info->size)
-               rv = update_size(mddev, info->size);
+               rv = update_size(mddev, (sector_t)info->size * 2);
 
        if (mddev->raid_disks    != info->raid_disks)
                rv = update_raid_disks(mddev, info->raid_disks);
@@ -4641,6 +4779,12 @@ static int set_disk_faulty(mddev_t *mddev, dev_t dev)
        return 0;
 }
 
+/*
+ * We have a problem here : there is no easy way to give a CHS
+ * virtual geometry. We currently pretend that we have a 2 heads
+ * 4 sectors (with a BIG number of cylinders...). This drives
+ * dosfs just mad... ;-)
+ */
 static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
        mddev_t *mddev = bdev->bd_disk->private_data;
@@ -4785,19 +4929,13 @@ static int md_ioctl(struct inode *inode, struct file *file,
                        goto done_unlock;
 
                case STOP_ARRAY:
-                       err = do_md_stop (mddev, 0);
+                       err = do_md_stop (mddev, 0, 1);
                        goto done_unlock;
 
                case STOP_ARRAY_RO:
-                       err = do_md_stop (mddev, 1);
+                       err = do_md_stop (mddev, 1, 1);
                        goto done_unlock;
 
-       /*
-        * We have a problem here : there is no easy way to give a CHS
-        * virtual geometry. We currently pretend that we have a 2 heads
-        * 4 sectors (with a BIG number of cylinders...). This drives
-        * dosfs just mad... ;-)
-        */
        }
 
        /*
@@ -4807,13 +4945,12 @@ static int md_ioctl(struct inode *inode, struct file *file,
         * here and hit the 'default' below, so only disallow
         * 'md' ioctls, and switch to rw mode if started auto-readonly.
         */
-       if (_IOC_TYPE(cmd) == MD_MAJOR &&
-           mddev->ro && mddev->pers) {
+       if (_IOC_TYPE(cmd) == MD_MAJOR && mddev->ro && mddev->pers) {
                if (mddev->ro == 2) {
                        mddev->ro = 0;
-               set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
-               md_wakeup_thread(mddev->thread);
-
+                       sysfs_notify(&mddev->kobj, NULL, "array_state");
+                       set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+                       md_wakeup_thread(mddev->thread);
                } else {
                        err = -EROFS;
                        goto abort_unlock;
@@ -4883,6 +5020,7 @@ static int md_open(struct inode *inode, struct file *file)
 
        err = 0;
        mddev_get(mddev);
+       atomic_inc(&mddev->openers);
        mddev_unlock(mddev);
 
        check_disk_change(inode->i_bdev);
@@ -4895,6 +5033,7 @@ static int md_release(struct inode *inode, struct file * file)
        mddev_t *mddev = inode->i_bdev->bd_disk->private_data;
 
        BUG_ON(!mddev);
+       atomic_dec(&mddev->openers);
        mddev_put(mddev);
 
        return 0;
@@ -5029,6 +5168,9 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
        if (!mddev->pers->error_handler)
                return;
        mddev->pers->error_handler(mddev,rdev);
+       if (mddev->degraded)
+               set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
+       set_bit(StateChanged, &rdev->flags);
        set_bit(MD_RECOVERY_INTR, &mddev->recovery);
        set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
        md_wakeup_thread(mddev->thread);
@@ -5258,10 +5400,11 @@ static int md_seq_show(struct seq_file *seq, void *v)
                if (!list_empty(&mddev->disks)) {
                        if (mddev->pers)
                                seq_printf(seq, "\n      %llu blocks",
-                                       (unsigned long long)mddev->array_size);
+                                          (unsigned long long)
+                                          mddev->array_sectors / 2);
                        else
                                seq_printf(seq, "\n      %llu blocks",
-                                       (unsigned long long)size);
+                                          (unsigned long long)size);
                }
                if (mddev->persistent) {
                        if (mddev->major_version != 0 ||
@@ -5391,12 +5534,12 @@ int unregister_md_personality(struct mdk_personality *p)
 static int is_mddev_idle(mddev_t *mddev)
 {
        mdk_rdev_t * rdev;
-       struct list_head *tmp;
        int idle;
        long curr_events;
 
        idle = 1;
-       rdev_for_each(rdev, tmp, mddev) {
+       rcu_read_lock();
+       rdev_for_each_rcu(rdev, mddev) {
                struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
                curr_events = disk_stat_read(disk, sectors[0]) + 
                                disk_stat_read(disk, sectors[1]) - 
@@ -5428,6 +5571,7 @@ static int is_mddev_idle(mddev_t *mddev)
                        idle = 0;
                }
        }
+       rcu_read_unlock();
        return idle;
 }
 
@@ -5451,6 +5595,7 @@ void md_done_sync(mddev_t *mddev, int blocks, int ok)
  */
 void md_write_start(mddev_t *mddev, struct bio *bi)
 {
+       int did_change = 0;
        if (bio_data_dir(bi) != WRITE)
                return;
 
@@ -5461,6 +5606,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
                set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                md_wakeup_thread(mddev->thread);
                md_wakeup_thread(mddev->sync_thread);
+               did_change = 1;
        }
        atomic_inc(&mddev->writes_pending);
        if (mddev->safemode == 1)
@@ -5471,10 +5617,12 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
                        mddev->in_sync = 0;
                        set_bit(MD_CHANGE_CLEAN, &mddev->flags);
                        md_wakeup_thread(mddev->thread);
+                       did_change = 1;
                }
                spin_unlock_irq(&mddev->write_lock);
-               sysfs_notify(&mddev->kobj, NULL, "array_state");
        }
+       if (did_change)
+               sysfs_notify(&mddev->kobj, NULL, "array_state");
        wait_event(mddev->sb_wait,
                   !test_bit(MD_CHANGE_CLEAN, &mddev->flags) &&
                   !test_bit(MD_CHANGE_PENDING, &mddev->flags));
@@ -5495,13 +5643,18 @@ void md_write_end(mddev_t *mddev)
  * may proceed without blocking.  It is important to call this before
  * attempting a GFP_KERNEL allocation while holding the mddev lock.
  * Must be called with mddev_lock held.
+ *
+ * In the ->external case MD_CHANGE_CLEAN can not be cleared until mddev->lock
+ * is dropped, so return -EAGAIN after notifying userspace.
  */
-void md_allow_write(mddev_t *mddev)
+int md_allow_write(mddev_t *mddev)
 {
        if (!mddev->pers)
-               return;
+               return 0;
        if (mddev->ro)
-               return;
+               return 0;
+       if (!mddev->pers->sync_request)
+               return 0;
 
        spin_lock_irq(&mddev->write_lock);
        if (mddev->in_sync) {
@@ -5512,14 +5665,14 @@ void md_allow_write(mddev_t *mddev)
                        mddev->safemode = 1;
                spin_unlock_irq(&mddev->write_lock);
                md_update_sb(mddev, 0);
-
                sysfs_notify(&mddev->kobj, NULL, "array_state");
-               /* wait for the dirty state to be recorded in the metadata */
-               wait_event(mddev->sb_wait,
-                          !test_bit(MD_CHANGE_CLEAN, &mddev->flags) &&
-                          !test_bit(MD_CHANGE_PENDING, &mddev->flags));
        } else
                spin_unlock_irq(&mddev->write_lock);
+
+       if (test_bit(MD_CHANGE_CLEAN, &mddev->flags))
+               return -EAGAIN;
+       else
+               return 0;
 }
 EXPORT_SYMBOL_GPL(md_allow_write);
 
@@ -5625,9 +5778,11 @@ void md_do_sync(mddev_t *mddev)
                max_sectors = mddev->resync_max_sectors;
                mddev->resync_mismatches = 0;
                /* we don't use the checkpoint if there's a bitmap */
-               if (!mddev->bitmap &&
-                   !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
+               if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
+                       j = mddev->resync_min;
+               else if (!mddev->bitmap)
                        j = mddev->recovery_cp;
+
        } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
                max_sectors = mddev->size << 1;
        else {
@@ -5796,6 +5951,7 @@ void md_do_sync(mddev_t *mddev)
 
  skip:
        mddev->curr_resync = 0;
+       mddev->resync_min = 0;
        mddev->resync_max = MaxSector;
        sysfs_notify(&mddev->kobj, NULL, "sync_completed");
        wake_up(&resync_wait);
@@ -5845,7 +6001,8 @@ static int remove_and_add_spares(mddev_t *mddev)
                        if (rdev->raid_disk < 0
                            && !test_bit(Faulty, &rdev->flags)) {
                                rdev->recovery_offset = 0;
-                               if (mddev->pers->hot_add_disk(mddev,rdev)) {
+                               if (mddev->pers->
+                                   hot_add_disk(mddev, rdev) == 0) {
                                        char nm[20];
                                        sprintf(nm, "rd%d", rdev->raid_disk);
                                        if (sysfs_create_link(&mddev->kobj,
@@ -5920,23 +6077,31 @@ void md_check_recovery(mddev_t *mddev)
                int spares = 0;
 
                if (!mddev->external) {
+                       int did_change = 0;
                        spin_lock_irq(&mddev->write_lock);
                        if (mddev->safemode &&
                            !atomic_read(&mddev->writes_pending) &&
                            !mddev->in_sync &&
                            mddev->recovery_cp == MaxSector) {
                                mddev->in_sync = 1;
+                               did_change = 1;
                                if (mddev->persistent)
                                        set_bit(MD_CHANGE_CLEAN, &mddev->flags);
                        }
                        if (mddev->safemode == 1)
                                mddev->safemode = 0;
                        spin_unlock_irq(&mddev->write_lock);
+                       if (did_change)
+                               sysfs_notify(&mddev->kobj, NULL, "array_state");
                }
 
                if (mddev->flags)
                        md_update_sb(mddev, 0);
 
+               rdev_for_each(rdev, rtmp, mddev)
+                       if (test_and_clear_bit(StateChanged, &rdev->flags))
+                               sysfs_notify(&rdev->kobj, NULL, "state");
+
 
                if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) &&
                    !test_bit(MD_RECOVERY_DONE, &mddev->recovery)) {
@@ -5951,7 +6116,9 @@ void md_check_recovery(mddev_t *mddev)
                        if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
                                /* success...*/
                                /* activate any spares */
-                               mddev->pers->spare_active(mddev);
+                               if (mddev->pers->spare_active(mddev))
+                                       sysfs_notify(&mddev->kobj, NULL,
+                                                    "degraded");
                        }
                        md_update_sb(mddev, 1);
 
@@ -5965,13 +6132,18 @@ void md_check_recovery(mddev_t *mddev)
                        mddev->recovery = 0;
                        /* flag recovery needed just to double check */
                        set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+                       sysfs_notify(&mddev->kobj, NULL, "sync_action");
                        md_new_event(mddev);
                        goto unlock;
                }
+               /* Set RUNNING before clearing NEEDED to avoid
+                * any transients in the value of "sync_action".
+                */
+               set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
+               clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                /* Clear some bits that don't mean anything, but
                 * might be left set
                 */
-               clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                clear_bit(MD_RECOVERY_INTR, &mddev->recovery);
                clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
 
@@ -5989,17 +6161,19 @@ void md_check_recovery(mddev_t *mddev)
                                /* Cannot proceed */
                                goto unlock;
                        set_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
+                       clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
                } else if ((spares = remove_and_add_spares(mddev))) {
                        clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
                        clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
+                       set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
                } else if (mddev->recovery_cp < MaxSector) {
                        set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
+                       clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
                } else if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
                        /* nothing to be done ... */
                        goto unlock;
 
                if (mddev->pers->sync_request) {
-                       set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
                        if (spares && mddev->bitmap && ! mddev->bitmap->file) {
                                /* We are adding a device or devices to an array
                                 * which has the bitmap stored on all devices.
@@ -6018,9 +6192,16 @@ void md_check_recovery(mddev_t *mddev)
                                mddev->recovery = 0;
                        } else
                                md_wakeup_thread(mddev->sync_thread);
+                       sysfs_notify(&mddev->kobj, NULL, "sync_action");
                        md_new_event(mddev);
                }
        unlock:
+               if (!mddev->sync_thread) {
+                       clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
+                       if (test_and_clear_bit(MD_RECOVERY_RECOVER,
+                                              &mddev->recovery))
+                               sysfs_notify(&mddev->kobj, NULL, "sync_action");
+               }
                mddev_unlock(mddev);
        }
 }
@@ -6047,7 +6228,7 @@ static int md_notify_reboot(struct notifier_block *this,
 
                for_each_mddev(mddev, tmp)
                        if (mddev_trylock(mddev)) {
-                               do_md_stop (mddev, 1);
+                               do_md_stop (mddev, 1, 0);
                                mddev_unlock(mddev);
                        }
                /*
index e968116e0de9699d2bef0f114ae79f638506bf1c..c4779ccba1c39bf1ab3f7454706868245f95ea0e 100644 (file)
@@ -281,13 +281,18 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
 {
        multipath_conf_t *conf = mddev->private;
        struct request_queue *q;
-       int found = 0;
+       int err = -EEXIST;
        int path;
        struct multipath_info *p;
+       int first = 0;
+       int last = mddev->raid_disks - 1;
+
+       if (rdev->raid_disk >= 0)
+               first = last = rdev->raid_disk;
 
        print_multipath_conf(conf);
 
-       for (path=0; path<mddev->raid_disks; path++) 
+       for (path = first; path <= last; path++)
                if ((p=conf->multipaths+path)->rdev == NULL) {
                        q = rdev->bdev->bd_disk->queue;
                        blk_queue_stack_limits(mddev->queue, q);
@@ -307,11 +312,13 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
                        rdev->raid_disk = path;
                        set_bit(In_sync, &rdev->flags);
                        rcu_assign_pointer(p->rdev, rdev);
-                       found = 1;
+                       err = 0;
+                       break;
                }
 
        print_multipath_conf(conf);
-       return found;
+
+       return err;
 }
 
 static int multipath_remove_disk(mddev_t *mddev, int number)
@@ -497,7 +504,7 @@ static int multipath_run (mddev_t *mddev)
        /*
         * Ok, everything is just fine now
         */
-       mddev->array_size = mddev->size;
+       mddev->array_sectors = mddev->size * 2;
 
        mddev->queue->unplug_fn = multipath_unplug;
        mddev->queue->backing_dev_info.congested_fn = multipath_congested;
index bcbb82594a193c275dd4db15fadc46fd4a6494d6..18361063566113ffb3eddfd3d85f20fdbf6d5109 100644 (file)
@@ -295,16 +295,16 @@ static int raid0_run (mddev_t *mddev)
                goto out_free_conf;
 
        /* calculate array device size */
-       mddev->array_size = 0;
+       mddev->array_sectors = 0;
        rdev_for_each(rdev, tmp, mddev)
-               mddev->array_size += rdev->size;
+               mddev->array_sectors += rdev->size * 2;
 
        printk("raid0 : md_size is %llu blocks.\n", 
-               (unsigned long long)mddev->array_size);
+               (unsigned long long)mddev->array_sectors / 2);
        printk("raid0 : conf->hash_spacing is %llu blocks.\n",
                (unsigned long long)conf->hash_spacing);
        {
-               sector_t s = mddev->array_size;
+               sector_t s = mddev->array_sectors / 2;
                sector_t space = conf->hash_spacing;
                int round;
                conf->preshift = 0;
index c610b947218afb73f49982d59dd178a7fdbd0959..03a5ab705c20dcb482a98472d88b9e4d9d0d0a5d 100644 (file)
@@ -1100,11 +1100,16 @@ static int raid1_spare_active(mddev_t *mddev)
 static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
 {
        conf_t *conf = mddev->private;
-       int found = 0;
+       int err = -EEXIST;
        int mirror = 0;
        mirror_info_t *p;
+       int first = 0;
+       int last = mddev->raid_disks - 1;
 
-       for (mirror=0; mirror < mddev->raid_disks; mirror++)
+       if (rdev->raid_disk >= 0)
+               first = last = rdev->raid_disk;
+
+       for (mirror = first; mirror <= last; mirror++)
                if ( !(p=conf->mirrors+mirror)->rdev) {
 
                        blk_queue_stack_limits(mddev->queue,
@@ -1119,7 +1124,7 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
 
                        p->head_position = 0;
                        rdev->raid_disk = mirror;
-                       found = 1;
+                       err = 0;
                        /* As all devices are equivalent, we don't need a full recovery
                         * if this was recently any drive of the array
                         */
@@ -1130,7 +1135,7 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
                }
 
        print_conf(conf);
-       return found;
+       return err;
 }
 
 static int raid1_remove_disk(mddev_t *mddev, int number)
@@ -2038,7 +2043,7 @@ static int run(mddev_t *mddev)
        /*
         * Ok, everything is just fine now
         */
-       mddev->array_size = mddev->size;
+       mddev->array_sectors = mddev->size * 2;
 
        mddev->queue->unplug_fn = raid1_unplug;
        mddev->queue->backing_dev_info.congested_fn = raid1_congested;
@@ -2100,14 +2105,15 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors)
         * any io in the removed space completes, but it hardly seems
         * worth it.
         */
-       mddev->array_size = sectors>>1;
-       set_capacity(mddev->gendisk, mddev->array_size << 1);
+       mddev->array_sectors = sectors;
+       set_capacity(mddev->gendisk, mddev->array_sectors);
        mddev->changed = 1;
-       if (mddev->array_size > mddev->size && mddev->recovery_cp == MaxSector) {
+       if (mddev->array_sectors / 2 > mddev->size &&
+           mddev->recovery_cp == MaxSector) {
                mddev->recovery_cp = mddev->size << 1;
                set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
        }
-       mddev->size = mddev->array_size;
+       mddev->size = mddev->array_sectors / 2;
        mddev->resync_max_sectors = sectors;
        return 0;
 }
@@ -2131,7 +2137,7 @@ static int raid1_reshape(mddev_t *mddev)
        conf_t *conf = mddev_to_conf(mddev);
        int cnt, raid_disks;
        unsigned long flags;
-       int d, d2;
+       int d, d2, err;
 
        /* Cannot change chunk_size, layout, or level */
        if (mddev->chunk_size != mddev->new_chunk ||
@@ -2143,7 +2149,9 @@ static int raid1_reshape(mddev_t *mddev)
                return -EINVAL;
        }
 
-       md_allow_write(mddev);
+       err = md_allow_write(mddev);
+       if (err)
+               return err;
 
        raid_disks = mddev->raid_disks + mddev->delta_disks;
 
index 22bb2b1b886d96887948f25fd8efbc199b3b3079..159535d735679ac977e5e428e80b61eb50d18fe2 100644 (file)
@@ -1114,24 +1114,30 @@ static int raid10_spare_active(mddev_t *mddev)
 static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
 {
        conf_t *conf = mddev->private;
-       int found = 0;
+       int err = -EEXIST;
        int mirror;
        mirror_info_t *p;
+       int first = 0;
+       int last = mddev->raid_disks - 1;
 
        if (mddev->recovery_cp < MaxSector)
                /* only hot-add to in-sync arrays, as recovery is
                 * very different from resync
                 */
-               return 0;
+               return -EBUSY;
        if (!enough(conf))
-               return 0;
+               return -EINVAL;
+
+       if (rdev->raid_disk)
+               first = last = rdev->raid_disk;
 
        if (rdev->saved_raid_disk >= 0 &&
+           rdev->saved_raid_disk >= first &&
            conf->mirrors[rdev->saved_raid_disk].rdev == NULL)
                mirror = rdev->saved_raid_disk;
        else
-               mirror = 0;
-       for ( ; mirror < mddev->raid_disks; mirror++)
+               mirror = first;
+       for ( ; mirror <= last ; mirror++)
                if ( !(p=conf->mirrors+mirror)->rdev) {
 
                        blk_queue_stack_limits(mddev->queue,
@@ -1146,7 +1152,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
 
                        p->head_position = 0;
                        rdev->raid_disk = mirror;
-                       found = 1;
+                       err = 0;
                        if (rdev->saved_raid_disk != mirror)
                                conf->fullsync = 1;
                        rcu_assign_pointer(p->rdev, rdev);
@@ -1154,7 +1160,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
                }
 
        print_conf(conf);
-       return found;
+       return err;
 }
 
 static int raid10_remove_disk(mddev_t *mddev, int number)
@@ -2159,7 +2165,7 @@ static int run(mddev_t *mddev)
        /*
         * Ok, everything is just fine now
         */
-       mddev->array_size = size << (conf->chunk_shift-1);
+       mddev->array_sectors = size << conf->chunk_shift;
        mddev->resync_max_sectors = size << conf->chunk_shift;
 
        mddev->queue->unplug_fn = raid10_unplug;
index 9ce7154845c67eb4acffc441462667b9a152f468..55e7c56045a0b4e48474f0cf9d507c22a73217b3 100644 (file)
@@ -115,15 +115,20 @@ static void return_io(struct bio *return_bi)
                return_bi = bi->bi_next;
                bi->bi_next = NULL;
                bi->bi_size = 0;
-               bi->bi_end_io(bi,
-                             test_bit(BIO_UPTODATE, &bi->bi_flags)
-                               ? 0 : -EIO);
+               bio_endio(bi, 0);
                bi = return_bi;
        }
 }
 
 static void print_raid5_conf (raid5_conf_t *conf);
 
+static int stripe_operations_active(struct stripe_head *sh)
+{
+       return sh->check_state || sh->reconstruct_state ||
+              test_bit(STRIPE_BIOFILL_RUN, &sh->state) ||
+              test_bit(STRIPE_COMPUTE_RUN, &sh->state);
+}
+
 static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh)
 {
        if (atomic_dec_and_test(&sh->count)) {
@@ -143,7 +148,7 @@ static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh)
                        }
                        md_wakeup_thread(conf->mddev->thread);
                } else {
-                       BUG_ON(sh->ops.pending);
+                       BUG_ON(stripe_operations_active(sh));
                        if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
                                atomic_dec(&conf->preread_active_stripes);
                                if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD)
@@ -245,7 +250,7 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int
 
        BUG_ON(atomic_read(&sh->count) != 0);
        BUG_ON(test_bit(STRIPE_HANDLE, &sh->state));
-       BUG_ON(sh->ops.pending || sh->ops.ack || sh->ops.complete);
+       BUG_ON(stripe_operations_active(sh));
 
        CHECK_DEVLOCK();
        pr_debug("init_stripe called, stripe %llu\n",
@@ -346,62 +351,18 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
        return sh;
 }
 
-/* test_and_ack_op() ensures that we only dequeue an operation once */
-#define test_and_ack_op(op, pend) \
-do {                                                   \
-       if (test_bit(op, &sh->ops.pending) &&           \
-               !test_bit(op, &sh->ops.complete)) {     \
-               if (test_and_set_bit(op, &sh->ops.ack)) \
-                       clear_bit(op, &pend);           \
-               else                                    \
-                       ack++;                          \
-       } else                                          \
-               clear_bit(op, &pend);                   \
-} while (0)
-
-/* find new work to run, do not resubmit work that is already
- * in flight
- */
-static unsigned long get_stripe_work(struct stripe_head *sh)
-{
-       unsigned long pending;
-       int ack = 0;
-
-       pending = sh->ops.pending;
-
-       test_and_ack_op(STRIPE_OP_BIOFILL, pending);
-       test_and_ack_op(STRIPE_OP_COMPUTE_BLK, pending);
-       test_and_ack_op(STRIPE_OP_PREXOR, pending);
-       test_and_ack_op(STRIPE_OP_BIODRAIN, pending);
-       test_and_ack_op(STRIPE_OP_POSTXOR, pending);
-       test_and_ack_op(STRIPE_OP_CHECK, pending);
-       if (test_and_clear_bit(STRIPE_OP_IO, &sh->ops.pending))
-               ack++;
-
-       sh->ops.count -= ack;
-       if (unlikely(sh->ops.count < 0)) {
-               printk(KERN_ERR "pending: %#lx ops.pending: %#lx ops.ack: %#lx "
-                       "ops.complete: %#lx\n", pending, sh->ops.pending,
-                       sh->ops.ack, sh->ops.complete);
-               BUG();
-       }
-
-       return pending;
-}
-
 static void
 raid5_end_read_request(struct bio *bi, int error);
 static void
 raid5_end_write_request(struct bio *bi, int error);
 
-static void ops_run_io(struct stripe_head *sh)
+static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
 {
        raid5_conf_t *conf = sh->raid_conf;
        int i, disks = sh->disks;
 
        might_sleep();
 
-       set_bit(STRIPE_IO_STARTED, &sh->state);
        for (i = disks; i--; ) {
                int rw;
                struct bio *bi;
@@ -430,11 +391,11 @@ static void ops_run_io(struct stripe_head *sh)
                rcu_read_unlock();
 
                if (rdev) {
-                       if (test_bit(STRIPE_SYNCING, &sh->state) ||
-                               test_bit(STRIPE_EXPAND_SOURCE, &sh->state) ||
-                               test_bit(STRIPE_EXPAND_READY, &sh->state))
+                       if (s->syncing || s->expanding || s->expanded)
                                md_sync_acct(rdev->bdev, STRIPE_SECTORS);
 
+                       set_bit(STRIPE_IO_STARTED, &sh->state);
+
                        bi->bi_bdev = rdev->bdev;
                        pr_debug("%s: for %llu schedule op %ld on disc %d\n",
                                __func__, (unsigned long long)sh->sector,
@@ -528,38 +489,34 @@ static void ops_complete_biofill(void *stripe_head_ref)
                (unsigned long long)sh->sector);
 
        /* clear completed biofills */
+       spin_lock_irq(&conf->device_lock);
        for (i = sh->disks; i--; ) {
                struct r5dev *dev = &sh->dev[i];
 
                /* acknowledge completion of a biofill operation */
                /* and check if we need to reply to a read request,
                 * new R5_Wantfill requests are held off until
-                * !test_bit(STRIPE_OP_BIOFILL, &sh->ops.pending)
+                * !STRIPE_BIOFILL_RUN
                 */
                if (test_and_clear_bit(R5_Wantfill, &dev->flags)) {
                        struct bio *rbi, *rbi2;
 
-                       /* The access to dev->read is outside of the
-                        * spin_lock_irq(&conf->device_lock), but is protected
-                        * by the STRIPE_OP_BIOFILL pending bit
-                        */
                        BUG_ON(!dev->read);
                        rbi = dev->read;
                        dev->read = NULL;
                        while (rbi && rbi->bi_sector <
                                dev->sector + STRIPE_SECTORS) {
                                rbi2 = r5_next_bio(rbi, dev->sector);
-                               spin_lock_irq(&conf->device_lock);
                                if (--rbi->bi_phys_segments == 0) {
                                        rbi->bi_next = return_bi;
                                        return_bi = rbi;
                                }
-                               spin_unlock_irq(&conf->device_lock);
                                rbi = rbi2;
                        }
                }
        }
-       set_bit(STRIPE_OP_BIOFILL, &sh->ops.complete);
+       spin_unlock_irq(&conf->device_lock);
+       clear_bit(STRIPE_BIOFILL_RUN, &sh->state);
 
        return_io(return_bi);
 
@@ -610,13 +567,14 @@ static void ops_complete_compute5(void *stripe_head_ref)
        set_bit(R5_UPTODATE, &tgt->flags);
        BUG_ON(!test_bit(R5_Wantcompute, &tgt->flags));
        clear_bit(R5_Wantcompute, &tgt->flags);
-       set_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete);
+       clear_bit(STRIPE_COMPUTE_RUN, &sh->state);
+       if (sh->check_state == check_state_compute_run)
+               sh->check_state = check_state_compute_result;
        set_bit(STRIPE_HANDLE, &sh->state);
        release_stripe(sh);
 }
 
-static struct dma_async_tx_descriptor *
-ops_run_compute5(struct stripe_head *sh, unsigned long pending)
+static struct dma_async_tx_descriptor *ops_run_compute5(struct stripe_head *sh)
 {
        /* kernel stack size limits the total number of disks */
        int disks = sh->disks;
@@ -646,10 +604,6 @@ ops_run_compute5(struct stripe_head *sh, unsigned long pending)
                        ASYNC_TX_XOR_ZERO_DST, NULL,
                        ops_complete_compute5, sh);
 
-       /* ack now if postxor is not set to be run */
-       if (tx && !test_bit(STRIPE_OP_POSTXOR, &pending))
-               async_tx_ack(tx);
-
        return tx;
 }
 
@@ -659,8 +613,6 @@ static void ops_complete_prexor(void *stripe_head_ref)
 
        pr_debug("%s: stripe %llu\n", __func__,
                (unsigned long long)sh->sector);
-
-       set_bit(STRIPE_OP_PREXOR, &sh->ops.complete);
 }
 
 static struct dma_async_tx_descriptor *
@@ -680,7 +632,7 @@ ops_run_prexor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
        for (i = disks; i--; ) {
                struct r5dev *dev = &sh->dev[i];
                /* Only process blocks that are known to be uptodate */
-               if (dev->towrite && test_bit(R5_Wantprexor, &dev->flags))
+               if (test_bit(R5_Wantdrain, &dev->flags))
                        xor_srcs[count++] = dev->page;
        }
 
@@ -692,16 +644,10 @@ ops_run_prexor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
 }
 
 static struct dma_async_tx_descriptor *
-ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx,
-                unsigned long pending)
+ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
 {
        int disks = sh->disks;
-       int pd_idx = sh->pd_idx, i;
-
-       /* check if prexor is active which means only process blocks
-        * that are part of a read-modify-write (Wantprexor)
-        */
-       int prexor = test_bit(STRIPE_OP_PREXOR, &pending);
+       int i;
 
        pr_debug("%s: stripe %llu\n", __func__,
                (unsigned long long)sh->sector);
@@ -709,20 +655,8 @@ ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx,
        for (i = disks; i--; ) {
                struct r5dev *dev = &sh->dev[i];
                struct bio *chosen;
-               int towrite;
-
-               towrite = 0;
-               if (prexor) { /* rmw */
-                       if (dev->towrite &&
-                           test_bit(R5_Wantprexor, &dev->flags))
-                               towrite = 1;
-               } else { /* rcw */
-                       if (i != pd_idx && dev->towrite &&
-                               test_bit(R5_LOCKED, &dev->flags))
-                               towrite = 1;
-               }
 
-               if (towrite) {
+               if (test_and_clear_bit(R5_Wantdrain, &dev->flags)) {
                        struct bio *wbi;
 
                        spin_lock(&sh->lock);
@@ -745,18 +679,6 @@ ops_run_biodrain(struct stripe_head *sh, struct dma_async_tx_descriptor *tx,
 }
 
 static void ops_complete_postxor(void *stripe_head_ref)
-{
-       struct stripe_head *sh = stripe_head_ref;
-
-       pr_debug("%s: stripe %llu\n", __func__,
-               (unsigned long long)sh->sector);
-
-       set_bit(STRIPE_OP_POSTXOR, &sh->ops.complete);
-       set_bit(STRIPE_HANDLE, &sh->state);
-       release_stripe(sh);
-}
-
-static void ops_complete_write(void *stripe_head_ref)
 {
        struct stripe_head *sh = stripe_head_ref;
        int disks = sh->disks, i, pd_idx = sh->pd_idx;
@@ -770,16 +692,21 @@ static void ops_complete_write(void *stripe_head_ref)
                        set_bit(R5_UPTODATE, &dev->flags);
        }
 
-       set_bit(STRIPE_OP_BIODRAIN, &sh->ops.complete);
-       set_bit(STRIPE_OP_POSTXOR, &sh->ops.complete);
+       if (sh->reconstruct_state == reconstruct_state_drain_run)
+               sh->reconstruct_state = reconstruct_state_drain_result;
+       else if (sh->reconstruct_state == reconstruct_state_prexor_drain_run)
+               sh->reconstruct_state = reconstruct_state_prexor_drain_result;
+       else {
+               BUG_ON(sh->reconstruct_state != reconstruct_state_run);
+               sh->reconstruct_state = reconstruct_state_result;
+       }
 
        set_bit(STRIPE_HANDLE, &sh->state);
        release_stripe(sh);
 }
 
 static void
-ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx,
-               unsigned long pending)
+ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx)
 {
        /* kernel stack size limits the total number of disks */
        int disks = sh->disks;
@@ -787,9 +714,8 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx,
 
        int count = 0, pd_idx = sh->pd_idx, i;
        struct page *xor_dest;
-       int prexor = test_bit(STRIPE_OP_PREXOR, &pending);
+       int prexor = 0;
        unsigned long flags;
-       dma_async_tx_callback callback;
 
        pr_debug("%s: stripe %llu\n", __func__,
                (unsigned long long)sh->sector);
@@ -797,7 +723,8 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx,
        /* check if prexor is active which means only process blocks
         * that are part of a read-modify-write (written)
         */
-       if (prexor) {
+       if (sh->reconstruct_state == reconstruct_state_prexor_drain_run) {
+               prexor = 1;
                xor_dest = xor_srcs[count++] = sh->dev[pd_idx].page;
                for (i = disks; i--; ) {
                        struct r5dev *dev = &sh->dev[i];
@@ -813,10 +740,6 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx,
                }
        }
 
-       /* check whether this postxor is part of a write */
-       callback = test_bit(STRIPE_OP_BIODRAIN, &pending) ?
-               ops_complete_write : ops_complete_postxor;
-
        /* 1/ if we prexor'd then the dest is reused as a source
         * 2/ if we did not prexor then we are redoing the parity
         * set ASYNC_TX_XOR_DROP_DST and ASYNC_TX_XOR_ZERO_DST
@@ -830,25 +753,20 @@ ops_run_postxor(struct stripe_head *sh, struct dma_async_tx_descriptor *tx,
        if (unlikely(count == 1)) {
                flags &= ~(ASYNC_TX_XOR_DROP_DST | ASYNC_TX_XOR_ZERO_DST);
                tx = async_memcpy(xor_dest, xor_srcs[0], 0, 0, STRIPE_SIZE,
-                       flags, tx, callback, sh);
+                       flags, tx, ops_complete_postxor, sh);
        } else
                tx = async_xor(xor_dest, xor_srcs, 0, count, STRIPE_SIZE,
-                       flags, tx, callback, sh);
+                       flags, tx, ops_complete_postxor, sh);
 }
 
 static void ops_complete_check(void *stripe_head_ref)
 {
        struct stripe_head *sh = stripe_head_ref;
-       int pd_idx = sh->pd_idx;
 
        pr_debug("%s: stripe %llu\n", __func__,
                (unsigned long long)sh->sector);
 
-       if (test_and_clear_bit(STRIPE_OP_MOD_DMA_CHECK, &sh->ops.pending) &&
-               sh->ops.zero_sum_result == 0)
-               set_bit(R5_UPTODATE, &sh->dev[pd_idx].flags);
-
-       set_bit(STRIPE_OP_CHECK, &sh->ops.complete);
+       sh->check_state = check_state_check_result;
        set_bit(STRIPE_HANDLE, &sh->state);
        release_stripe(sh);
 }
@@ -875,46 +793,42 @@ static void ops_run_check(struct stripe_head *sh)
        tx = async_xor_zero_sum(xor_dest, xor_srcs, 0, count, STRIPE_SIZE,
                &sh->ops.zero_sum_result, 0, NULL, NULL, NULL);
 
-       if (tx)
-               set_bit(STRIPE_OP_MOD_DMA_CHECK, &sh->ops.pending);
-       else
-               clear_bit(STRIPE_OP_MOD_DMA_CHECK, &sh->ops.pending);
-
        atomic_inc(&sh->count);
        tx = async_trigger_callback(ASYNC_TX_DEP_ACK | ASYNC_TX_ACK, tx,
                ops_complete_check, sh);
 }
 
-static void raid5_run_ops(struct stripe_head *sh, unsigned long pending)
+static void raid5_run_ops(struct stripe_head *sh, unsigned long ops_request)
 {
        int overlap_clear = 0, i, disks = sh->disks;
        struct dma_async_tx_descriptor *tx = NULL;
 
-       if (test_bit(STRIPE_OP_BIOFILL, &pending)) {
+       if (test_bit(STRIPE_OP_BIOFILL, &ops_request)) {
                ops_run_biofill(sh);
                overlap_clear++;
        }
 
-       if (test_bit(STRIPE_OP_COMPUTE_BLK, &pending))
-               tx = ops_run_compute5(sh, pending);
+       if (test_bit(STRIPE_OP_COMPUTE_BLK, &ops_request)) {
+               tx = ops_run_compute5(sh);
+               /* terminate the chain if postxor is not set to be run */
+               if (tx && !test_bit(STRIPE_OP_POSTXOR, &ops_request))
+                       async_tx_ack(tx);
+       }
 
-       if (test_bit(STRIPE_OP_PREXOR, &pending))
+       if (test_bit(STRIPE_OP_PREXOR, &ops_request))
                tx = ops_run_prexor(sh, tx);
 
-       if (test_bit(STRIPE_OP_BIODRAIN, &pending)) {
-               tx = ops_run_biodrain(sh, tx, pending);
+       if (test_bit(STRIPE_OP_BIODRAIN, &ops_request)) {
+               tx = ops_run_biodrain(sh, tx);
                overlap_clear++;
        }
 
-       if (test_bit(STRIPE_OP_POSTXOR, &pending))
-               ops_run_postxor(sh, tx, pending);
+       if (test_bit(STRIPE_OP_POSTXOR, &ops_request))
+               ops_run_postxor(sh, tx);
 
-       if (test_bit(STRIPE_OP_CHECK, &pending))
+       if (test_bit(STRIPE_OP_CHECK, &ops_request))
                ops_run_check(sh);
 
-       if (test_bit(STRIPE_OP_IO, &pending))
-               ops_run_io(sh);
-
        if (overlap_clear)
                for (i = disks; i--; ) {
                        struct r5dev *dev = &sh->dev[i];
@@ -997,14 +911,16 @@ static int resize_stripes(raid5_conf_t *conf, int newsize)
        struct stripe_head *osh, *nsh;
        LIST_HEAD(newstripes);
        struct disk_info *ndisks;
-       int err = 0;
+       int err;
        struct kmem_cache *sc;
        int i;
 
        if (newsize <= conf->pool_size)
                return 0; /* never bother to shrink */
 
-       md_allow_write(conf->mddev);
+       err = md_allow_write(conf->mddev);
+       if (err)
+               return err;
 
        /* Step 1 */
        sc = kmem_cache_create(conf->cache_name[1-conf->active_name],
@@ -1703,11 +1619,11 @@ static void compute_block_2(struct stripe_head *sh, int dd_idx1, int dd_idx2)
        }
 }
 
-static int
-handle_write_operations5(struct stripe_head *sh, int rcw, int expand)
+static void
+schedule_reconstruction5(struct stripe_head *sh, struct stripe_head_state *s,
+                        int rcw, int expand)
 {
        int i, pd_idx = sh->pd_idx, disks = sh->disks;
-       int locked = 0;
 
        if (rcw) {
                /* if we are not expanding this is a proper write request, and
@@ -1715,53 +1631,48 @@ handle_write_operations5(struct stripe_head *sh, int rcw, int expand)
                 * stripe cache
                 */
                if (!expand) {
-                       set_bit(STRIPE_OP_BIODRAIN, &sh->ops.pending);
-                       sh->ops.count++;
-               }
+                       sh->reconstruct_state = reconstruct_state_drain_run;
+                       set_bit(STRIPE_OP_BIODRAIN, &s->ops_request);
+               } else
+                       sh->reconstruct_state = reconstruct_state_run;
 
-               set_bit(STRIPE_OP_POSTXOR, &sh->ops.pending);
-               sh->ops.count++;
+               set_bit(STRIPE_OP_POSTXOR, &s->ops_request);
 
                for (i = disks; i--; ) {
                        struct r5dev *dev = &sh->dev[i];
 
                        if (dev->towrite) {
                                set_bit(R5_LOCKED, &dev->flags);
+                               set_bit(R5_Wantdrain, &dev->flags);
                                if (!expand)
                                        clear_bit(R5_UPTODATE, &dev->flags);
-                               locked++;
+                               s->locked++;
                        }
                }
-               if (locked + 1 == disks)
+               if (s->locked + 1 == disks)
                        if (!test_and_set_bit(STRIPE_FULL_WRITE, &sh->state))
                                atomic_inc(&sh->raid_conf->pending_full_writes);
        } else {
                BUG_ON(!(test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags) ||
                        test_bit(R5_Wantcompute, &sh->dev[pd_idx].flags)));
 
-               set_bit(STRIPE_OP_PREXOR, &sh->ops.pending);
-               set_bit(STRIPE_OP_BIODRAIN, &sh->ops.pending);
-               set_bit(STRIPE_OP_POSTXOR, &sh->ops.pending);
-
-               sh->ops.count += 3;
+               sh->reconstruct_state = reconstruct_state_prexor_drain_run;
+               set_bit(STRIPE_OP_PREXOR, &s->ops_request);
+               set_bit(STRIPE_OP_BIODRAIN, &s->ops_request);
+               set_bit(STRIPE_OP_POSTXOR, &s->ops_request);
 
                for (i = disks; i--; ) {
                        struct r5dev *dev = &sh->dev[i];
                        if (i == pd_idx)
                                continue;
 
-                       /* For a read-modify write there may be blocks that are
-                        * locked for reading while others are ready to be
-                        * written so we distinguish these blocks by the
-                        * R5_Wantprexor bit
-                        */
                        if (dev->towrite &&
                            (test_bit(R5_UPTODATE, &dev->flags) ||
-                           test_bit(R5_Wantcompute, &dev->flags))) {
-                               set_bit(R5_Wantprexor, &dev->flags);
+                            test_bit(R5_Wantcompute, &dev->flags))) {
+                               set_bit(R5_Wantdrain, &dev->flags);
                                set_bit(R5_LOCKED, &dev->flags);
                                clear_bit(R5_UPTODATE, &dev->flags);
-                               locked++;
+                               s->locked++;
                        }
                }
        }
@@ -1771,13 +1682,11 @@ handle_write_operations5(struct stripe_head *sh, int rcw, int expand)
         */
        set_bit(R5_LOCKED, &sh->dev[pd_idx].flags);
        clear_bit(R5_UPTODATE, &sh->dev[pd_idx].flags);
-       locked++;
+       s->locked++;
 
-       pr_debug("%s: stripe %llu locked: %d pending: %lx\n",
+       pr_debug("%s: stripe %llu locked: %d ops_request: %lx\n",
                __func__, (unsigned long long)sh->sector,
-               locked, sh->ops.pending);
-
-       return locked;
+               s->locked, s->ops_request);
 }
 
 /*
@@ -1876,7 +1785,7 @@ static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks)
 }
 
 static void
-handle_requests_to_failed_array(raid5_conf_t *conf, struct stripe_head *sh,
+handle_failed_stripe(raid5_conf_t *conf, struct stripe_head *sh,
                                struct stripe_head_state *s, int disks,
                                struct bio **return_bi)
 {
@@ -1967,48 +1876,38 @@ handle_requests_to_failed_array(raid5_conf_t *conf, struct stripe_head *sh,
                        md_wakeup_thread(conf->mddev->thread);
 }
 
-/* __handle_issuing_new_read_requests5 - returns 0 if there are no more disks
- * to process
+/* fetch_block5 - checks the given member device to see if its data needs
+ * to be read or computed to satisfy a request.
+ *
+ * Returns 1 when no more member devices need to be checked, otherwise returns
+ * 0 to tell the loop in handle_stripe_fill5 to continue
  */
-static int __handle_issuing_new_read_requests5(struct stripe_head *sh,
-                       struct stripe_head_state *s, int disk_idx, int disks)
+static int fetch_block5(struct stripe_head *sh, struct stripe_head_state *s,
+                       int disk_idx, int disks)
 {
        struct r5dev *dev = &sh->dev[disk_idx];
        struct r5dev *failed_dev = &sh->dev[s->failed_num];
 
-       /* don't schedule compute operations or reads on the parity block while
-        * a check is in flight
-        */
-       if ((disk_idx == sh->pd_idx) &&
-            test_bit(STRIPE_OP_CHECK, &sh->ops.pending))
-               return ~0;
-
        /* is the data in this block needed, and can we get it? */
        if (!test_bit(R5_LOCKED, &dev->flags) &&
-           !test_bit(R5_UPTODATE, &dev->flags) && (dev->toread ||
-           (dev->towrite && !test_bit(R5_OVERWRITE, &dev->flags)) ||
-            s->syncing || s->expanding || (s->failed &&
-            (failed_dev->toread || (failed_dev->towrite &&
-            !test_bit(R5_OVERWRITE, &failed_dev->flags)
-            ))))) {
-               /* 1/ We would like to get this block, possibly by computing it,
-                * but we might not be able to.
-                *
-                * 2/ Since parity check operations potentially make the parity
-                * block !uptodate it will need to be refreshed before any
-                * compute operations on data disks are scheduled.
-                *
-                * 3/ We hold off parity block re-reads until check operations
-                * have quiesced.
+           !test_bit(R5_UPTODATE, &dev->flags) &&
+           (dev->toread ||
+            (dev->towrite && !test_bit(R5_OVERWRITE, &dev->flags)) ||
+            s->syncing || s->expanding ||
+            (s->failed &&
+             (failed_dev->toread ||
+              (failed_dev->towrite &&
+               !test_bit(R5_OVERWRITE, &failed_dev->flags)))))) {
+               /* We would like to get this block, possibly by computing it,
+                * otherwise read it if the backing disk is insync
                 */
                if ((s->uptodate == disks - 1) &&
-                   (s->failed && disk_idx == s->failed_num) &&
-                   !test_bit(STRIPE_OP_CHECK, &sh->ops.pending)) {
-                       set_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending);
+                   (s->failed && disk_idx == s->failed_num)) {
+                       set_bit(STRIPE_COMPUTE_RUN, &sh->state);
+                       set_bit(STRIPE_OP_COMPUTE_BLK, &s->ops_request);
                        set_bit(R5_Wantcompute, &dev->flags);
                        sh->ops.target = disk_idx;
                        s->req_compute = 1;
-                       sh->ops.count++;
                        /* Careful: from this point on 'uptodate' is in the eye
                         * of raid5_run_ops which services 'compute' operations
                         * before writes. R5_Wantcompute flags a block that will
@@ -2016,53 +1915,40 @@ static int __handle_issuing_new_read_requests5(struct stripe_head *sh,
                         * subsequent operation.
                         */
                        s->uptodate++;
-                       return 0; /* uptodate + compute == disks */
+                       return 1; /* uptodate + compute == disks */
                } else if (test_bit(R5_Insync, &dev->flags)) {
                        set_bit(R5_LOCKED, &dev->flags);
                        set_bit(R5_Wantread, &dev->flags);
-                       if (!test_and_set_bit(STRIPE_OP_IO, &sh->ops.pending))
-                               sh->ops.count++;
                        s->locked++;
                        pr_debug("Reading block %d (sync=%d)\n", disk_idx,
                                s->syncing);
                }
        }
 
-       return ~0;
+       return 0;
 }
 
-static void handle_issuing_new_read_requests5(struct stripe_head *sh,
+/**
+ * handle_stripe_fill5 - read or compute data to satisfy pending requests.
+ */
+static void handle_stripe_fill5(struct stripe_head *sh,
                        struct stripe_head_state *s, int disks)
 {
        int i;
 
-       /* Clear completed compute operations.  Parity recovery
-        * (STRIPE_OP_MOD_REPAIR_PD) implies a write-back which is handled
-        * later on in this routine
-        */
-       if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) &&
-               !test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
-               clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete);
-               clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack);
-               clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending);
-       }
-
        /* look for blocks to read/compute, skip this if a compute
         * is already in flight, or if the stripe contents are in the
         * midst of changing due to a write
         */
-       if (!test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending) &&
-               !test_bit(STRIPE_OP_PREXOR, &sh->ops.pending) &&
-               !test_bit(STRIPE_OP_POSTXOR, &sh->ops.pending)) {
+       if (!test_bit(STRIPE_COMPUTE_RUN, &sh->state) && !sh->check_state &&
+           !sh->reconstruct_state)
                for (i = disks; i--; )
-                       if (__handle_issuing_new_read_requests5(
-                               sh, s, i, disks) == 0)
+                       if (fetch_block5(sh, s, i, disks))
                                break;
-       }
        set_bit(STRIPE_HANDLE, &sh->state);
 }
 
-static void handle_issuing_new_read_requests6(struct stripe_head *sh,
+static void handle_stripe_fill6(struct stripe_head *sh,
                        struct stripe_head_state *s, struct r6_state *r6s,
                        int disks)
 {
@@ -2121,12 +2007,12 @@ static void handle_issuing_new_read_requests6(struct stripe_head *sh,
 }
 
 
-/* handle_completed_write_requests
+/* handle_stripe_clean_event
  * any written block on an uptodate or failed drive can be returned.
  * Note that if we 'wrote' to a failed drive, it will be UPTODATE, but
  * never LOCKED, so we don't need to test 'failed' directly.
  */
-static void handle_completed_write_requests(raid5_conf_t *conf,
+static void handle_stripe_clean_event(raid5_conf_t *conf,
        struct stripe_head *sh, int disks, struct bio **return_bi)
 {
        int i;
@@ -2171,7 +2057,7 @@ static void handle_completed_write_requests(raid5_conf_t *conf,
                        md_wakeup_thread(conf->mddev->thread);
 }
 
-static void handle_issuing_new_write_requests5(raid5_conf_t *conf,
+static void handle_stripe_dirtying5(raid5_conf_t *conf,
                struct stripe_head *sh, struct stripe_head_state *s, int disks)
 {
        int rmw = 0, rcw = 0, i;
@@ -2215,9 +2101,6 @@ static void handle_issuing_new_write_requests5(raid5_conf_t *conf,
                                                "%d for r-m-w\n", i);
                                        set_bit(R5_LOCKED, &dev->flags);
                                        set_bit(R5_Wantread, &dev->flags);
-                                       if (!test_and_set_bit(
-                                               STRIPE_OP_IO, &sh->ops.pending))
-                                               sh->ops.count++;
                                        s->locked++;
                                } else {
                                        set_bit(STRIPE_DELAYED, &sh->state);
@@ -2241,9 +2124,6 @@ static void handle_issuing_new_write_requests5(raid5_conf_t *conf,
                                                "%d for Reconstruct\n", i);
                                        set_bit(R5_LOCKED, &dev->flags);
                                        set_bit(R5_Wantread, &dev->flags);
-                                       if (!test_and_set_bit(
-                                               STRIPE_OP_IO, &sh->ops.pending))
-                                               sh->ops.count++;
                                        s->locked++;
                                } else {
                                        set_bit(STRIPE_DELAYED, &sh->state);
@@ -2261,14 +2141,13 @@ static void handle_issuing_new_write_requests5(raid5_conf_t *conf,
         * simultaneously.  If this is not the case then new writes need to be
         * held off until the compute completes.
         */
-       if ((s->req_compute ||
-           !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) &&
-               (s->locked == 0 && (rcw == 0 || rmw == 0) &&
-               !test_bit(STRIPE_BIT_DELAY, &sh->state)))
-               s->locked += handle_write_operations5(sh, rcw == 0, 0);
+       if ((s->req_compute || !test_bit(STRIPE_COMPUTE_RUN, &sh->state)) &&
+           (s->locked == 0 && (rcw == 0 || rmw == 0) &&
+           !test_bit(STRIPE_BIT_DELAY, &sh->state)))
+               schedule_reconstruction5(sh, s, rcw == 0, 0);
 }
 
-static void handle_issuing_new_write_requests6(raid5_conf_t *conf,
+static void handle_stripe_dirtying6(raid5_conf_t *conf,
                struct stripe_head *sh, struct stripe_head_state *s,
                struct r6_state *r6s, int disks)
 {
@@ -2371,92 +2250,86 @@ static void handle_issuing_new_write_requests6(raid5_conf_t *conf,
 static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
                                struct stripe_head_state *s, int disks)
 {
-       int canceled_check = 0;
+       struct r5dev *dev = NULL;
 
        set_bit(STRIPE_HANDLE, &sh->state);
 
-       /* complete a check operation */
-       if (test_and_clear_bit(STRIPE_OP_CHECK, &sh->ops.complete)) {
-               clear_bit(STRIPE_OP_CHECK, &sh->ops.ack);
-               clear_bit(STRIPE_OP_CHECK, &sh->ops.pending);
+       switch (sh->check_state) {
+       case check_state_idle:
+               /* start a new check operation if there are no failures */
                if (s->failed == 0) {
-                       if (sh->ops.zero_sum_result == 0)
-                               /* parity is correct (on disc,
-                                * not in buffer any more)
-                                */
-                               set_bit(STRIPE_INSYNC, &sh->state);
-                       else {
-                               conf->mddev->resync_mismatches +=
-                                       STRIPE_SECTORS;
-                               if (test_bit(
-                                    MD_RECOVERY_CHECK, &conf->mddev->recovery))
-                                       /* don't try to repair!! */
-                                       set_bit(STRIPE_INSYNC, &sh->state);
-                               else {
-                                       set_bit(STRIPE_OP_COMPUTE_BLK,
-                                               &sh->ops.pending);
-                                       set_bit(STRIPE_OP_MOD_REPAIR_PD,
-                                               &sh->ops.pending);
-                                       set_bit(R5_Wantcompute,
-                                               &sh->dev[sh->pd_idx].flags);
-                                       sh->ops.target = sh->pd_idx;
-                                       sh->ops.count++;
-                                       s->uptodate++;
-                               }
-                       }
-               } else
-                       canceled_check = 1; /* STRIPE_INSYNC is not set */
-       }
-
-       /* start a new check operation if there are no failures, the stripe is
-        * not insync, and a repair is not in flight
-        */
-       if (s->failed == 0 &&
-           !test_bit(STRIPE_INSYNC, &sh->state) &&
-           !test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
-               if (!test_and_set_bit(STRIPE_OP_CHECK, &sh->ops.pending)) {
                        BUG_ON(s->uptodate != disks);
+                       sh->check_state = check_state_run;
+                       set_bit(STRIPE_OP_CHECK, &s->ops_request);
                        clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags);
-                       sh->ops.count++;
                        s->uptodate--;
+                       break;
                }
-       }
-
-       /* check if we can clear a parity disk reconstruct */
-       if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) &&
-           test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
-
-               clear_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending);
-               clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete);
-               clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack);
-               clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending);
-       }
-
+               dev = &sh->dev[s->failed_num];
+               /* fall through */
+       case check_state_compute_result:
+               sh->check_state = check_state_idle;
+               if (!dev)
+                       dev = &sh->dev[sh->pd_idx];
+
+               /* check that a write has not made the stripe insync */
+               if (test_bit(STRIPE_INSYNC, &sh->state))
+                       break;
 
-       /* Wait for check parity and compute block operations to complete
-        * before write-back.  If a failure occurred while the check operation
-        * was in flight we need to cycle this stripe through handle_stripe
-        * since the parity block may not be uptodate
-        */
-       if (!canceled_check && !test_bit(STRIPE_INSYNC, &sh->state) &&
-           !test_bit(STRIPE_OP_CHECK, &sh->ops.pending) &&
-           !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) {
-               struct r5dev *dev;
                /* either failed parity check, or recovery is happening */
-               if (s->failed == 0)
-                       s->failed_num = sh->pd_idx;
-               dev = &sh->dev[s->failed_num];
                BUG_ON(!test_bit(R5_UPTODATE, &dev->flags));
                BUG_ON(s->uptodate != disks);
 
                set_bit(R5_LOCKED, &dev->flags);
+               s->locked++;
                set_bit(R5_Wantwrite, &dev->flags);
-               if (!test_and_set_bit(STRIPE_OP_IO, &sh->ops.pending))
-                       sh->ops.count++;
 
                clear_bit(STRIPE_DEGRADED, &sh->state);
-               s->locked++;
                set_bit(STRIPE_INSYNC, &sh->state);
+               break;
+       case check_state_run:
+               break; /* we will be called again upon completion */
+       case check_state_check_result:
+               sh->check_state = check_state_idle;
+
+               /* if a failure occurred during the check operation, leave
+                * STRIPE_INSYNC not set and let the stripe be handled again
+                */
+               if (s->failed)
+                       break;
+
+               /* handle a successful check operation, if parity is correct
+                * we are done.  Otherwise update the mismatch count and repair
+                * parity if !MD_RECOVERY_CHECK
+                */
+               if (sh->ops.zero_sum_result == 0)
+                       /* parity is correct (on disc,
+                        * not in buffer any more)
+                        */
+                       set_bit(STRIPE_INSYNC, &sh->state);
+               else {
+                       conf->mddev->resync_mismatches += STRIPE_SECTORS;
+                       if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery))
+                               /* don't try to repair!! */
+                               set_bit(STRIPE_INSYNC, &sh->state);
+                       else {
+                               sh->check_state = check_state_compute_run;
+                               set_bit(STRIPE_COMPUTE_RUN, &sh->state);
+                               set_bit(STRIPE_OP_COMPUTE_BLK, &s->ops_request);
+                               set_bit(R5_Wantcompute,
+                                       &sh->dev[sh->pd_idx].flags);
+                               sh->ops.target = sh->pd_idx;
+                               s->uptodate++;
+                       }
+               }
+               break;
+       case check_state_compute_run:
+               break;
+       default:
+               printk(KERN_ERR "%s: unknown check_state: %d sector: %llu\n",
+                      __func__, sh->check_state,
+                      (unsigned long long) sh->sector);
+               BUG();
        }
 }
 
@@ -2641,15 +2514,14 @@ static void handle_stripe5(struct stripe_head *sh)
        struct bio *return_bi = NULL;
        struct stripe_head_state s;
        struct r5dev *dev;
-       unsigned long pending = 0;
        mdk_rdev_t *blocked_rdev = NULL;
        int prexor;
 
        memset(&s, 0, sizeof(s));
-       pr_debug("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d "
-               "ops=%lx:%lx:%lx\n", (unsigned long long)sh->sector, sh->state,
-               atomic_read(&sh->count), sh->pd_idx,
-               sh->ops.pending, sh->ops.ack, sh->ops.complete);
+       pr_debug("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d check:%d "
+                "reconstruct:%d\n", (unsigned long long)sh->sector, sh->state,
+                atomic_read(&sh->count), sh->pd_idx, sh->check_state,
+                sh->reconstruct_state);
 
        spin_lock(&sh->lock);
        clear_bit(STRIPE_HANDLE, &sh->state);
@@ -2658,15 +2530,8 @@ static void handle_stripe5(struct stripe_head *sh)
        s.syncing = test_bit(STRIPE_SYNCING, &sh->state);
        s.expanding = test_bit(STRIPE_EXPAND_SOURCE, &sh->state);
        s.expanded = test_bit(STRIPE_EXPAND_READY, &sh->state);
-       /* Now to look around and see what can be done */
-
-       /* clean-up completed biofill operations */
-       if (test_bit(STRIPE_OP_BIOFILL, &sh->ops.complete)) {
-               clear_bit(STRIPE_OP_BIOFILL, &sh->ops.pending);
-               clear_bit(STRIPE_OP_BIOFILL, &sh->ops.ack);
-               clear_bit(STRIPE_OP_BIOFILL, &sh->ops.complete);
-       }
 
+       /* Now to look around and see what can be done */
        rcu_read_lock();
        for (i=disks; i--; ) {
                mdk_rdev_t *rdev;
@@ -2680,10 +2545,10 @@ static void handle_stripe5(struct stripe_head *sh)
                /* maybe we can request a biofill operation
                 *
                 * new wantfill requests are only permitted while
-                * STRIPE_OP_BIOFILL is clear
+                * ops_complete_biofill is guaranteed to be inactive
                 */
                if (test_bit(R5_UPTODATE, &dev->flags) && dev->toread &&
-                       !test_bit(STRIPE_OP_BIOFILL, &sh->ops.pending))
+                   !test_bit(STRIPE_BIOFILL_RUN, &sh->state))
                        set_bit(R5_Wantfill, &dev->flags);
 
                /* now count some things */
@@ -2727,8 +2592,10 @@ static void handle_stripe5(struct stripe_head *sh)
                goto unlock;
        }
 
-       if (s.to_fill && !test_and_set_bit(STRIPE_OP_BIOFILL, &sh->ops.pending))
-               sh->ops.count++;
+       if (s.to_fill && !test_bit(STRIPE_BIOFILL_RUN, &sh->state)) {
+               set_bit(STRIPE_OP_BIOFILL, &s.ops_request);
+               set_bit(STRIPE_BIOFILL_RUN, &sh->state);
+       }
 
        pr_debug("locked=%d uptodate=%d to_read=%d"
                " to_write=%d failed=%d failed_num=%d\n",
@@ -2738,8 +2605,7 @@ static void handle_stripe5(struct stripe_head *sh)
         * need to be failed
         */
        if (s.failed > 1 && s.to_read+s.to_write+s.written)
-               handle_requests_to_failed_array(conf, sh, &s, disks,
-                                               &return_bi);
+               handle_failed_stripe(conf, sh, &s, disks, &return_bi);
        if (s.failed > 1 && s.syncing) {
                md_done_sync(conf->mddev, STRIPE_SECTORS,0);
                clear_bit(STRIPE_SYNCING, &sh->state);
@@ -2755,48 +2621,25 @@ static void handle_stripe5(struct stripe_head *sh)
               !test_bit(R5_LOCKED, &dev->flags) &&
               test_bit(R5_UPTODATE, &dev->flags)) ||
               (s.failed == 1 && s.failed_num == sh->pd_idx)))
-               handle_completed_write_requests(conf, sh, disks, &return_bi);
+               handle_stripe_clean_event(conf, sh, disks, &return_bi);
 
        /* Now we might consider reading some blocks, either to check/generate
         * parity, or to satisfy requests
         * or to load a block that is being partially written.
         */
        if (s.to_read || s.non_overwrite ||
-           (s.syncing && (s.uptodate + s.compute < disks)) || s.expanding ||
-           test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending))
-               handle_issuing_new_read_requests5(sh, &s, disks);
+           (s.syncing && (s.uptodate + s.compute < disks)) || s.expanding)
+               handle_stripe_fill5(sh, &s, disks);
 
        /* Now we check to see if any write operations have recently
         * completed
         */
-
-       /* leave prexor set until postxor is done, allows us to distinguish
-        * a rmw from a rcw during biodrain
-        */
        prexor = 0;
-       if (test_bit(STRIPE_OP_PREXOR, &sh->ops.complete) &&
-               test_bit(STRIPE_OP_POSTXOR, &sh->ops.complete)) {
-
+       if (sh->reconstruct_state == reconstruct_state_prexor_drain_result)
                prexor = 1;
-               clear_bit(STRIPE_OP_PREXOR, &sh->ops.complete);
-               clear_bit(STRIPE_OP_PREXOR, &sh->ops.ack);
-               clear_bit(STRIPE_OP_PREXOR, &sh->ops.pending);
-
-               for (i = disks; i--; )
-                       clear_bit(R5_Wantprexor, &sh->dev[i].flags);
-       }
-
-       /* if only POSTXOR is set then this is an 'expand' postxor */
-       if (test_bit(STRIPE_OP_BIODRAIN, &sh->ops.complete) &&
-               test_bit(STRIPE_OP_POSTXOR, &sh->ops.complete)) {
-
-               clear_bit(STRIPE_OP_BIODRAIN, &sh->ops.complete);
-               clear_bit(STRIPE_OP_BIODRAIN, &sh->ops.ack);
-               clear_bit(STRIPE_OP_BIODRAIN, &sh->ops.pending);
-
-               clear_bit(STRIPE_OP_POSTXOR, &sh->ops.complete);
-               clear_bit(STRIPE_OP_POSTXOR, &sh->ops.ack);
-               clear_bit(STRIPE_OP_POSTXOR, &sh->ops.pending);
+       if (sh->reconstruct_state == reconstruct_state_drain_result ||
+           sh->reconstruct_state == reconstruct_state_prexor_drain_result) {
+               sh->reconstruct_state = reconstruct_state_idle;
 
                /* All the 'written' buffers and the parity block are ready to
                 * be written back to disk
@@ -2808,9 +2651,6 @@ static void handle_stripe5(struct stripe_head *sh)
                                (i == sh->pd_idx || dev->written)) {
                                pr_debug("Writing block %d\n", i);
                                set_bit(R5_Wantwrite, &dev->flags);
-                               if (!test_and_set_bit(
-                                   STRIPE_OP_IO, &sh->ops.pending))
-                                       sh->ops.count++;
                                if (prexor)
                                        continue;
                                if (!test_bit(R5_Insync, &dev->flags) ||
@@ -2832,20 +2672,18 @@ static void handle_stripe5(struct stripe_head *sh)
         * 2/ A 'check' operation is in flight, as it may clobber the parity
         *    block.
         */
-       if (s.to_write && !test_bit(STRIPE_OP_POSTXOR, &sh->ops.pending) &&
-                         !test_bit(STRIPE_OP_CHECK, &sh->ops.pending))
-               handle_issuing_new_write_requests5(conf, sh, &s, disks);
+       if (s.to_write && !sh->reconstruct_state && !sh->check_state)
+               handle_stripe_dirtying5(conf, sh, &s, disks);
 
        /* maybe we need to check and possibly fix the parity for this stripe
         * Any reads will already have been scheduled, so we just see if enough
         * data is available.  The parity check is held off while parity
         * dependent operations are in flight.
         */
-       if ((s.syncing && s.locked == 0 &&
-            !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending) &&
-            !test_bit(STRIPE_INSYNC, &sh->state)) ||
-             test_bit(STRIPE_OP_CHECK, &sh->ops.pending) ||
-             test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending))
+       if (sh->check_state ||
+           (s.syncing && s.locked == 0 &&
+            !test_bit(STRIPE_COMPUTE_RUN, &sh->state) &&
+            !test_bit(STRIPE_INSYNC, &sh->state)))
                handle_parity_checks5(conf, sh, &s, disks);
 
        if (s.syncing && s.locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) {
@@ -2864,52 +2702,35 @@ static void handle_stripe5(struct stripe_head *sh)
                dev = &sh->dev[s.failed_num];
                if (!test_bit(R5_ReWrite, &dev->flags)) {
                        set_bit(R5_Wantwrite, &dev->flags);
-                       if (!test_and_set_bit(STRIPE_OP_IO, &sh->ops.pending))
-                               sh->ops.count++;
                        set_bit(R5_ReWrite, &dev->flags);
                        set_bit(R5_LOCKED, &dev->flags);
                        s.locked++;
                } else {
                        /* let's read it back */
                        set_bit(R5_Wantread, &dev->flags);
-                       if (!test_and_set_bit(STRIPE_OP_IO, &sh->ops.pending))
-                               sh->ops.count++;
                        set_bit(R5_LOCKED, &dev->flags);
                        s.locked++;
                }
        }
 
-       /* Finish postxor operations initiated by the expansion
-        * process
-        */
-       if (test_bit(STRIPE_OP_POSTXOR, &sh->ops.complete) &&
-               !test_bit(STRIPE_OP_BIODRAIN, &sh->ops.pending)) {
-
+       /* Finish reconstruct operations initiated by the expansion process */
+       if (sh->reconstruct_state == reconstruct_state_result) {
+               sh->reconstruct_state = reconstruct_state_idle;
                clear_bit(STRIPE_EXPANDING, &sh->state);
-
-               clear_bit(STRIPE_OP_POSTXOR, &sh->ops.pending);
-               clear_bit(STRIPE_OP_POSTXOR, &sh->ops.ack);
-               clear_bit(STRIPE_OP_POSTXOR, &sh->ops.complete);
-
-               for (i = conf->raid_disks; i--; ) {
+               for (i = conf->raid_disks; i--; )
                        set_bit(R5_Wantwrite, &sh->dev[i].flags);
                        set_bit(R5_LOCKED, &dev->flags);
                        s.locked++;
-                       if (!test_and_set_bit(STRIPE_OP_IO, &sh->ops.pending))
-                               sh->ops.count++;
-               }
        }
 
        if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state) &&
-               !test_bit(STRIPE_OP_POSTXOR, &sh->ops.pending)) {
+           !sh->reconstruct_state) {
                /* Need to write out all blocks after computing parity */
                sh->disks = conf->raid_disks;
                sh->pd_idx = stripe_to_pdidx(sh->sector, conf,
                        conf->raid_disks);
-               s.locked += handle_write_operations5(sh, 1, 1);
-       } else if (s.expanded &&
-                  s.locked == 0 &&
-               !test_bit(STRIPE_OP_POSTXOR, &sh->ops.pending)) {
+               schedule_reconstruction5(sh, &s, 1, 1);
+       } else if (s.expanded && !sh->reconstruct_state && s.locked == 0) {
                clear_bit(STRIPE_EXPAND_READY, &sh->state);
                atomic_dec(&conf->reshape_stripes);
                wake_up(&conf->wait_for_overlap);
@@ -2917,12 +2738,9 @@ static void handle_stripe5(struct stripe_head *sh)
        }
 
        if (s.expanding && s.locked == 0 &&
-           !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending))
+           !test_bit(STRIPE_COMPUTE_RUN, &sh->state))
                handle_stripe_expansion(conf, sh, NULL);
 
-       if (sh->ops.count)
-               pending = get_stripe_work(sh);
-
  unlock:
        spin_unlock(&sh->lock);
 
@@ -2930,11 +2748,12 @@ static void handle_stripe5(struct stripe_head *sh)
        if (unlikely(blocked_rdev))
                md_wait_for_blocked_rdev(blocked_rdev, conf->mddev);
 
-       if (pending)
-               raid5_run_ops(sh, pending);
+       if (s.ops_request)
+               raid5_run_ops(sh, s.ops_request);
 
-       return_io(return_bi);
+       ops_run_io(sh, &s);
 
+       return_io(return_bi);
 }
 
 static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
@@ -3042,8 +2861,7 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
         * might need to be failed
         */
        if (s.failed > 2 && s.to_read+s.to_write+s.written)
-               handle_requests_to_failed_array(conf, sh, &s, disks,
-                                               &return_bi);
+               handle_failed_stripe(conf, sh, &s, disks, &return_bi);
        if (s.failed > 2 && s.syncing) {
                md_done_sync(conf->mddev, STRIPE_SECTORS,0);
                clear_bit(STRIPE_SYNCING, &sh->state);
@@ -3068,7 +2886,7 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
             ( r6s.q_failed || ((test_bit(R5_Insync, &qdev->flags)
                             && !test_bit(R5_LOCKED, &qdev->flags)
                             && test_bit(R5_UPTODATE, &qdev->flags)))))
-               handle_completed_write_requests(conf, sh, disks, &return_bi);
+               handle_stripe_clean_event(conf, sh, disks, &return_bi);
 
        /* Now we might consider reading some blocks, either to check/generate
         * parity, or to satisfy requests
@@ -3076,11 +2894,11 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
         */
        if (s.to_read || s.non_overwrite || (s.to_write && s.failed) ||
            (s.syncing && (s.uptodate < disks)) || s.expanding)
-               handle_issuing_new_read_requests6(sh, &s, &r6s, disks);
+               handle_stripe_fill6(sh, &s, &r6s, disks);
 
        /* now to consider writing and what else, if anything should be read */
        if (s.to_write)
-               handle_issuing_new_write_requests6(conf, sh, &s, &r6s, disks);
+               handle_stripe_dirtying6(conf, sh, &s, &r6s, disks);
 
        /* maybe we need to check and possibly fix the parity for this stripe
         * Any reads will already have been scheduled, so we just see if enough
@@ -3136,7 +2954,7 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
        }
 
        if (s.expanding && s.locked == 0 &&
-           !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending))
+           !test_bit(STRIPE_COMPUTE_RUN, &sh->state))
                handle_stripe_expansion(conf, sh, &r6s);
 
  unlock:
@@ -3146,68 +2964,9 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
        if (unlikely(blocked_rdev))
                md_wait_for_blocked_rdev(blocked_rdev, conf->mddev);
 
-       return_io(return_bi);
-
-       for (i=disks; i-- ;) {
-               int rw;
-               struct bio *bi;
-               mdk_rdev_t *rdev;
-               if (test_and_clear_bit(R5_Wantwrite, &sh->dev[i].flags))
-                       rw = WRITE;
-               else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags))
-                       rw = READ;
-               else
-                       continue;
-
-               set_bit(STRIPE_IO_STARTED, &sh->state);
-
-               bi = &sh->dev[i].req;
-
-               bi->bi_rw = rw;
-               if (rw == WRITE)
-                       bi->bi_end_io = raid5_end_write_request;
-               else
-                       bi->bi_end_io = raid5_end_read_request;
-
-               rcu_read_lock();
-               rdev = rcu_dereference(conf->disks[i].rdev);
-               if (rdev && test_bit(Faulty, &rdev->flags))
-                       rdev = NULL;
-               if (rdev)
-                       atomic_inc(&rdev->nr_pending);
-               rcu_read_unlock();
+       ops_run_io(sh, &s);
 
-               if (rdev) {
-                       if (s.syncing || s.expanding || s.expanded)
-                               md_sync_acct(rdev->bdev, STRIPE_SECTORS);
-
-                       bi->bi_bdev = rdev->bdev;
-                       pr_debug("for %llu schedule op %ld on disc %d\n",
-                               (unsigned long long)sh->sector, bi->bi_rw, i);
-                       atomic_inc(&sh->count);
-                       bi->bi_sector = sh->sector + rdev->data_offset;
-                       bi->bi_flags = 1 << BIO_UPTODATE;
-                       bi->bi_vcnt = 1;
-                       bi->bi_max_vecs = 1;
-                       bi->bi_idx = 0;
-                       bi->bi_io_vec = &sh->dev[i].vec;
-                       bi->bi_io_vec[0].bv_len = STRIPE_SIZE;
-                       bi->bi_io_vec[0].bv_offset = 0;
-                       bi->bi_size = STRIPE_SIZE;
-                       bi->bi_next = NULL;
-                       if (rw == WRITE &&
-                           test_bit(R5_ReWrite, &sh->dev[i].flags))
-                               atomic_add(STRIPE_SECTORS, &rdev->corrected_errors);
-                       generic_make_request(bi);
-               } else {
-                       if (rw == WRITE)
-                               set_bit(STRIPE_DEGRADED, &sh->state);
-                       pr_debug("skip op %ld on disc %d for sector %llu\n",
-                               bi->bi_rw, i, (unsigned long long)sh->sector);
-                       clear_bit(R5_LOCKED, &sh->dev[i].flags);
-                       set_bit(STRIPE_HANDLE, &sh->state);
-               }
-       }
+       return_io(return_bi);
 }
 
 static void handle_stripe(struct stripe_head *sh, struct page *tmp_page)
@@ -3697,9 +3456,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
                if ( rw == WRITE )
                        md_write_end(mddev);
 
-               bi->bi_end_io(bi,
-                             test_bit(BIO_UPTODATE, &bi->bi_flags)
-                               ? 0 : -EIO);
+               bio_endio(bi, 0);
        }
        return 0;
 }
@@ -3785,7 +3542,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
                            j == raid6_next_disk(sh->pd_idx, sh->disks))
                                continue;
                        s = compute_blocknr(sh, j);
-                       if (s < (mddev->array_size<<1)) {
+                       if (s < mddev->array_sectors) {
                                skipped = 1;
                                continue;
                        }
@@ -4002,12 +3759,8 @@ static int  retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
        spin_lock_irq(&conf->device_lock);
        remaining = --raid_bio->bi_phys_segments;
        spin_unlock_irq(&conf->device_lock);
-       if (remaining == 0) {
-
-               raid_bio->bi_end_io(raid_bio,
-                             test_bit(BIO_UPTODATE, &raid_bio->bi_flags)
-                               ? 0 : -EIO);
-       }
+       if (remaining == 0)
+               bio_endio(raid_bio, 0);
        if (atomic_dec_and_test(&conf->active_aligned_reads))
                wake_up(&conf->wait_for_stripe);
        return handled;
@@ -4094,6 +3847,8 @@ raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len)
 {
        raid5_conf_t *conf = mddev_to_conf(mddev);
        unsigned long new;
+       int err;
+
        if (len >= PAGE_SIZE)
                return -EINVAL;
        if (!conf)
@@ -4109,7 +3864,9 @@ raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len)
                else
                        break;
        }
-       md_allow_write(mddev);
+       err = md_allow_write(mddev);
+       if (err)
+               return err;
        while (new > conf->max_nr_stripes) {
                if (grow_one_stripe(conf))
                        conf->max_nr_stripes++;
@@ -4434,7 +4191,7 @@ static int run(mddev_t *mddev)
        mddev->queue->backing_dev_info.congested_data = mddev;
        mddev->queue->backing_dev_info.congested_fn = raid5_congested;
 
-       mddev->array_size =  mddev->size * (conf->previous_raid_disks -
+       mddev->array_sectors = 2 * mddev->size * (conf->previous_raid_disks -
                                            conf->max_degraded);
 
        blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec);
@@ -4609,35 +4366,41 @@ abort:
 static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
 {
        raid5_conf_t *conf = mddev->private;
-       int found = 0;
+       int err = -EEXIST;
        int disk;
        struct disk_info *p;
+       int first = 0;
+       int last = conf->raid_disks - 1;
 
        if (mddev->degraded > conf->max_degraded)
                /* no point adding a device */
-               return 0;
+               return -EINVAL;
+
+       if (rdev->raid_disk >= 0)
+               first = last = rdev->raid_disk;
 
        /*
         * find the disk ... but prefer rdev->saved_raid_disk
         * if possible.
         */
        if (rdev->saved_raid_disk >= 0 &&
+           rdev->saved_raid_disk >= first &&
            conf->disks[rdev->saved_raid_disk].rdev == NULL)
                disk = rdev->saved_raid_disk;
        else
-               disk = 0;
-       for ( ; disk < conf->raid_disks; disk++)
+               disk = first;
+       for ( ; disk <= last ; disk++)
                if ((p=conf->disks + disk)->rdev == NULL) {
                        clear_bit(In_sync, &rdev->flags);
                        rdev->raid_disk = disk;
-                       found = 1;
+                       err = 0;
                        if (rdev->saved_raid_disk != disk)
                                conf->fullsync = 1;
                        rcu_assign_pointer(p->rdev, rdev);
                        break;
                }
        print_raid5_conf(conf);
-       return found;
+       return err;
 }
 
 static int raid5_resize(mddev_t *mddev, sector_t sectors)
@@ -4652,8 +4415,9 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors)
        raid5_conf_t *conf = mddev_to_conf(mddev);
 
        sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
-       mddev->array_size = (sectors * (mddev->raid_disks-conf->max_degraded))>>1;
-       set_capacity(mddev->gendisk, mddev->array_size << 1);
+       mddev->array_sectors = sectors * (mddev->raid_disks
+                                         - conf->max_degraded);
+       set_capacity(mddev->gendisk, mddev->array_sectors);
        mddev->changed = 1;
        if (sectors/2  > mddev->size && mddev->recovery_cp == MaxSector) {
                mddev->recovery_cp = mddev->size << 1;
@@ -4738,7 +4502,7 @@ static int raid5_start_reshape(mddev_t *mddev)
        rdev_for_each(rdev, rtmp, mddev)
                if (rdev->raid_disk < 0 &&
                    !test_bit(Faulty, &rdev->flags)) {
-                       if (raid5_add_disk(mddev, rdev)) {
+                       if (raid5_add_disk(mddev, rdev) == 0) {
                                char nm[20];
                                set_bit(In_sync, &rdev->flags);
                                added_devices++;
@@ -4786,15 +4550,16 @@ static void end_reshape(raid5_conf_t *conf)
        struct block_device *bdev;
 
        if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
-               conf->mddev->array_size = conf->mddev->size *
+               conf->mddev->array_sectors = 2 * conf->mddev->size *
                        (conf->raid_disks - conf->max_degraded);
-               set_capacity(conf->mddev->gendisk, conf->mddev->array_size << 1);
+               set_capacity(conf->mddev->gendisk, conf->mddev->array_sectors);
                conf->mddev->changed = 1;
 
                bdev = bdget_disk(conf->mddev->gendisk, 0);
                if (bdev) {
                        mutex_lock(&bdev->bd_inode->i_mutex);
-                       i_size_write(bdev->bd_inode, (loff_t)conf->mddev->array_size << 10);
+                       i_size_write(bdev->bd_inode,
+                                    (loff_t)conf->mddev->array_sectors << 9);
                        mutex_unlock(&bdev->bd_inode->i_mutex);
                        bdput(bdev);
                }
index e208a60c048ad930ebdade3ff274efdbf039fb1f..e7132770a3bfdd656117890d11ff4ee6c9195302 100644 (file)
@@ -233,9 +233,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 
        mutex_unlock(&dvbdev_register_lock);
 
-       clsdev = device_create(dvb_class, adap->device,
+       clsdev = device_create_drvdata(dvb_class, adap->device,
                               MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
-                              "dvb%d.%s%d", adap->num, dnames[type], id);
+                              NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
        if (IS_ERR(clsdev)) {
                printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
                       __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
index a054668eda16c93e2ad2389402c94a8b358bae27..4e3bfbcdf155d9cadfc2d1ea06c35911cd3c7c11 100644 (file)
@@ -51,7 +51,7 @@ struct jmb38x_ms_host {
        void __iomem            *addr;
        spinlock_t              lock;
        int                     id;
-       char                    host_id[DEVICE_ID_SIZE];
+       char                    host_id[32];
        int                     irq;
        unsigned int            block_pos;
        unsigned long           timeout_jiffies;
@@ -781,7 +781,7 @@ static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt)
 
        spin_lock_init(&host->lock);
        host->id = cnt;
-       snprintf(host->host_id, DEVICE_ID_SIZE, DRIVER_NAME ":slot%d",
+       snprintf(host->host_id, sizeof(host->host_id), DRIVER_NAME ":slot%d",
                 host->id);
        host->irq = jm->pdev->irq;
        host->timeout_jiffies = msecs_to_jiffies(1000);
index 75e599b85b645aba6d4de501f7f6c22e01dfa825..34402c47027e3951ac1d7de9387ec81a61227a2d 100644 (file)
@@ -1670,7 +1670,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
        INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
        spin_lock_init(&ioc->fault_reset_work_lock);
 
-       snprintf(ioc->reset_work_q_name, KOBJ_NAME_LEN, "mpt_poll_%d", ioc->id);
+       snprintf(ioc->reset_work_q_name, sizeof(ioc->reset_work_q_name),
+                "mpt_poll_%d", ioc->id);
        ioc->reset_work_q =
                create_singlethread_workqueue(ioc->reset_work_q_name);
        if (!ioc->reset_work_q) {
index 6adab648dbb91278076d0de0270018892c524ee4..dff048cfa101d78d09a878f1845d3480e88b5388 100644 (file)
@@ -707,12 +707,12 @@ typedef struct _MPT_ADAPTER
        u8                       fc_link_speed[2];
        spinlock_t               fc_rescan_work_lock;
        struct work_struct       fc_rescan_work;
-       char                     fc_rescan_work_q_name[KOBJ_NAME_LEN];
+       char                     fc_rescan_work_q_name[20];
        struct workqueue_struct *fc_rescan_work_q;
        struct scsi_cmnd        **ScsiLookup;
        spinlock_t                scsi_lookup_lock;
 
-       char                     reset_work_q_name[KOBJ_NAME_LEN];
+       char                     reset_work_q_name[20];
        struct workqueue_struct *reset_work_q;
        struct delayed_work      fault_reset_work;
        spinlock_t               fault_reset_work_lock;
index fc31ca6829d8d571d9c9da562c43bd7d2e94f73b..b36cae9ec6db6c81041f8dccd8b3ce59db466f2e 100644 (file)
@@ -1326,8 +1326,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        /* initialize workqueue */
 
-       snprintf(ioc->fc_rescan_work_q_name, KOBJ_NAME_LEN, "mptfc_wq_%d",
-               sh->host_no);
+       snprintf(ioc->fc_rescan_work_q_name, sizeof(ioc->fc_rescan_work_q_name),
+                "mptfc_wq_%d", sh->host_no);
        ioc->fc_rescan_work_q =
                create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
        if (!ioc->fc_rescan_work_q)
index 260bade0a5ec5041ef104afb35a5a68a57cb68f0..9f93c29fed355074cb443184da54343102c42625 100644 (file)
@@ -5,6 +5,10 @@
 menu "Multifunction device drivers"
        depends on HAS_IOMEM
 
+config MFD_CORE
+       tristate
+       default n
+
 config MFD_SM501
        tristate "Support for Silicon Motion SM501"
         ---help---
@@ -38,6 +42,13 @@ config HTC_PASIC3
          HTC Magician devices, respectively. Actual functionality is
          handled by the leds-pasic3 and ds1wm drivers.
 
+config MFD_TC6393XB
+       bool "Support Toshiba TC6393XB"
+       depends on HAVE_GPIO_LIB
+       select MFD_CORE
+       help
+         Support for Toshiba Mobile IO Controller TC6393XB
+
 endmenu
 
 menu "Multimedia Capabilities Port drivers"
index eef4e26807dfc38d37f62154f6fdf6aa6c407f80..33daa2f45dd8c7da6d6aba43a82467833d195239 100644 (file)
@@ -8,6 +8,10 @@ obj-$(CONFIG_MFD_ASIC3)                += asic3.o
 obj-$(CONFIG_HTC_EGPIO)                += htc-egpio.o
 obj-$(CONFIG_HTC_PASIC3)       += htc-pasic3.o
 
+obj-$(CONFIG_MFD_TC6393XB)     += tc6393xb.o
+
+obj-$(CONFIG_MFD_CORE)         += mfd-core.o
+
 obj-$(CONFIG_MCP)              += mcp-core.o
 obj-$(CONFIG_MCP_SA11X0)       += mcp-sa11x0.o
 obj-$(CONFIG_MCP_UCB1200)      += ucb1x00-core.o
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
new file mode 100644 (file)
index 0000000..d7d88ce
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * drivers/mfd/mfd-core.c
+ *
+ * core MFD support
+ * Copyright (c) 2006 Ian Molton
+ * Copyright (c) 2007,2008 Dmitry Baryshkov
+ *
+ * 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/platform_device.h>
+#include <linux/mfd/core.h>
+
+static int mfd_add_device(struct platform_device *parent,
+               const struct mfd_cell *cell,
+               struct resource *mem_base,
+               int irq_base)
+{
+       struct resource res[cell->num_resources];
+       struct platform_device *pdev;
+       int ret = -ENOMEM;
+       int r;
+
+       pdev = platform_device_alloc(cell->name, parent->id);
+       if (!pdev)
+               goto fail_alloc;
+
+       pdev->dev.parent = &parent->dev;
+
+       ret = platform_device_add_data(pdev,
+                       cell, sizeof(struct mfd_cell));
+       if (ret)
+               goto fail_device;
+
+       memzero(res, sizeof(res));
+       for (r = 0; r < cell->num_resources; r++) {
+               res[r].name = cell->resources[r].name;
+               res[r].flags = cell->resources[r].flags;
+
+               /* Find out base to use */
+               if (cell->resources[r].flags & IORESOURCE_MEM) {
+                       res[r].parent = mem_base;
+                       res[r].start = mem_base->start +
+                               cell->resources[r].start;
+                       res[r].end = mem_base->start +
+                               cell->resources[r].end;
+               } else if (cell->resources[r].flags & IORESOURCE_IRQ) {
+                       res[r].start = irq_base +
+                               cell->resources[r].start;
+                       res[r].end   = irq_base +
+                               cell->resources[r].end;
+               } else {
+                       res[r].parent = cell->resources[r].parent;
+                       res[r].start = cell->resources[r].start;
+                       res[r].end   = cell->resources[r].end;
+               }
+       }
+
+       platform_device_add_resources(pdev, res, cell->num_resources);
+
+       ret = platform_device_add(pdev);
+       if (ret)
+               goto fail_device;
+
+       return 0;
+
+/*     platform_device_del(pdev); */
+fail_device:
+       platform_device_put(pdev);
+fail_alloc:
+       return ret;
+}
+
+int mfd_add_devices(
+               struct platform_device *parent,
+               const struct mfd_cell *cells, int n_devs,
+               struct resource *mem_base,
+               int irq_base)
+{
+       int i;
+       int ret = 0;
+
+       for (i = 0; i < n_devs; i++) {
+               ret = mfd_add_device(parent, cells + i, mem_base, irq_base);
+               if (ret)
+                       break;
+       }
+
+       if (ret)
+               mfd_remove_devices(parent);
+
+       return ret;
+}
+EXPORT_SYMBOL(mfd_add_devices);
+
+static int mfd_remove_devices_fn(struct device *dev, void *unused)
+{
+       platform_device_unregister(
+                       container_of(dev, struct platform_device, dev));
+       return 0;
+}
+
+void mfd_remove_devices(struct platform_device *parent)
+{
+       device_for_each_child(&parent->dev, NULL, mfd_remove_devices_fn);
+}
+EXPORT_SYMBOL(mfd_remove_devices);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov");
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
new file mode 100644 (file)
index 0000000..2d87501
--- /dev/null
@@ -0,0 +1,600 @@
+/*
+ * Toshiba TC6393XB SoC support
+ *
+ * Copyright(c) 2005-2006 Chris Humbert
+ * Copyright(c) 2005 Dirk Opfer
+ * Copyright(c) 2005 Ian Molton <spyro@f2s.com>
+ * Copyright(c) 2007 Dmitry Baryshkov
+ *
+ * Based on code written by Sharp/Lineo for 2.4 kernels
+ * Based on locomo.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/clk.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mfd/tc6393xb.h>
+#include <linux/gpio.h>
+
+#define SCR_REVID      0x08            /* b Revision ID        */
+#define SCR_ISR                0x50            /* b Interrupt Status   */
+#define SCR_IMR                0x52            /* b Interrupt Mask     */
+#define SCR_IRR                0x54            /* b Interrupt Routing  */
+#define SCR_GPER       0x60            /* w GP Enable          */
+#define SCR_GPI_SR(i)  (0x64 + (i))    /* b3 GPI Status        */
+#define SCR_GPI_IMR(i) (0x68 + (i))    /* b3 GPI INT Mask      */
+#define SCR_GPI_EDER(i)        (0x6c + (i))    /* b3 GPI Edge Detect Enable */
+#define SCR_GPI_LIR(i) (0x70 + (i))    /* b3 GPI Level Invert  */
+#define SCR_GPO_DSR(i) (0x78 + (i))    /* b3 GPO Data Set      */
+#define SCR_GPO_DOECR(i) (0x7c + (i))  /* b3 GPO Data OE Control */
+#define SCR_GP_IARCR(i)        (0x80 + (i))    /* b3 GP Internal Active Register Control */
+#define SCR_GP_IARLCR(i) (0x84 + (i))  /* b3 GP INTERNAL Active Register Level Control */
+#define SCR_GPI_BCR(i) (0x88 + (i))    /* b3 GPI Buffer Control */
+#define SCR_GPA_IARCR  0x8c            /* w GPa Internal Active Register Control */
+#define SCR_GPA_IARLCR 0x90            /* w GPa Internal Active Register Level Control */
+#define SCR_GPA_BCR    0x94            /* w GPa Buffer Control */
+#define SCR_CCR                0x98            /* w Clock Control      */
+#define SCR_PLL2CR     0x9a            /* w PLL2 Control       */
+#define SCR_PLL1CR     0x9c            /* l PLL1 Control       */
+#define SCR_DIARCR     0xa0            /* b Device Internal Active Register Control */
+#define SCR_DBOCR      0xa1            /* b Device Buffer Off Control */
+#define SCR_FER                0xe0            /* b Function Enable    */
+#define SCR_MCR                0xe4            /* w Mode Control       */
+#define SCR_CONFIG     0xfc            /* b Configuration Control */
+#define SCR_DEBUG      0xff            /* b Debug              */
+
+#define SCR_CCR_CK32K  BIT(0)
+#define SCR_CCR_USBCK  BIT(1)
+#define SCR_CCR_UNK1   BIT(4)
+#define SCR_CCR_MCLK_MASK      (7 << 8)
+#define SCR_CCR_MCLK_OFF       (0 << 8)
+#define SCR_CCR_MCLK_12        (1 << 8)
+#define SCR_CCR_MCLK_24        (2 << 8)
+#define SCR_CCR_MCLK_48        (3 << 8)
+#define SCR_CCR_HCLK_MASK      (3 << 12)
+#define SCR_CCR_HCLK_24        (0 << 12)
+#define SCR_CCR_HCLK_48        (1 << 12)
+
+#define SCR_FER_USBEN          BIT(0)  /* USB host enable */
+#define SCR_FER_LCDCVEN                BIT(1)  /* polysilicon TFT enable */
+#define SCR_FER_SLCDEN         BIT(2)  /* SLCD enable */
+
+#define SCR_MCR_RDY_MASK               (3 << 0)
+#define SCR_MCR_RDY_OPENDRAIN  (0 << 0)
+#define SCR_MCR_RDY_TRISTATE   (1 << 0)
+#define SCR_MCR_RDY_PUSHPULL   (2 << 0)
+#define SCR_MCR_RDY_UNK                BIT(2)
+#define SCR_MCR_RDY_EN         BIT(3)
+#define SCR_MCR_INT_MASK               (3 << 4)
+#define SCR_MCR_INT_OPENDRAIN  (0 << 4)
+#define SCR_MCR_INT_TRISTATE   (1 << 4)
+#define SCR_MCR_INT_PUSHPULL   (2 << 4)
+#define SCR_MCR_INT_UNK                BIT(6)
+#define SCR_MCR_INT_EN         BIT(7)
+/* bits 8 - 16 are unknown */
+
+#define TC_GPIO_BIT(i)         (1 << (i & 0x7))
+
+/*--------------------------------------------------------------------------*/
+
+struct tc6393xb {
+       void __iomem            *scr;
+
+       struct gpio_chip        gpio;
+
+       struct clk              *clk; /* 3,6 Mhz */
+
+       spinlock_t              lock; /* protects RMW cycles */
+
+       struct {
+               u8              fer;
+               u16             ccr;
+               u8              gpi_bcr[3];
+               u8              gpo_dsr[3];
+               u8              gpo_doecr[3];
+       } suspend_state;
+
+       struct resource         rscr;
+       struct resource         *iomem;
+       int                     irq;
+       int                     irq_base;
+};
+
+enum {
+       TC6393XB_CELL_NAND,
+};
+
+/*--------------------------------------------------------------------------*/
+
+static int tc6393xb_nand_enable(struct platform_device *nand)
+{
+       struct platform_device *dev = to_platform_device(nand->dev.parent);
+       struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+       unsigned long flags;
+
+       spin_lock_irqsave(&tc6393xb->lock, flags);
+
+       /* SMD buffer on */
+       dev_dbg(&dev->dev, "SMD buffer on\n");
+       iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1));
+
+       spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+       return 0;
+}
+
+static struct resource __devinitdata tc6393xb_nand_resources[] = {
+       {
+               .name   = TMIO_NAND_CONFIG,
+               .start  = 0x0100,
+               .end    = 0x01ff,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .name   = TMIO_NAND_CONTROL,
+               .start  = 0x1000,
+               .end    = 0x1007,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .name   = TMIO_NAND_IRQ,
+               .start  = IRQ_TC6393_NAND,
+               .end    = IRQ_TC6393_NAND,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct mfd_cell __devinitdata tc6393xb_cells[] = {
+       [TC6393XB_CELL_NAND] = {
+               .name = "tmio-nand",
+               .enable = tc6393xb_nand_enable,
+               .num_resources = ARRAY_SIZE(tc6393xb_nand_resources),
+               .resources = tc6393xb_nand_resources,
+       },
+};
+
+/*--------------------------------------------------------------------------*/
+
+static int tc6393xb_gpio_get(struct gpio_chip *chip,
+               unsigned offset)
+{
+       struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
+
+       /* XXX: does dsr also represent inputs? */
+       return ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8))
+               & TC_GPIO_BIT(offset);
+}
+
+static void __tc6393xb_gpio_set(struct gpio_chip *chip,
+               unsigned offset, int value)
+{
+       struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
+       u8  dsr;
+
+       dsr = ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8));
+       if (value)
+               dsr |= TC_GPIO_BIT(offset);
+       else
+               dsr &= ~TC_GPIO_BIT(offset);
+
+       iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8));
+}
+
+static void tc6393xb_gpio_set(struct gpio_chip *chip,
+               unsigned offset, int value)
+{
+       struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
+       unsigned long flags;
+
+       spin_lock_irqsave(&tc6393xb->lock, flags);
+
+       __tc6393xb_gpio_set(chip, offset, value);
+
+       spin_unlock_irqrestore(&tc6393xb->lock, flags);
+}
+
+static int tc6393xb_gpio_direction_input(struct gpio_chip *chip,
+                       unsigned offset)
+{
+       struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
+       unsigned long flags;
+       u8 doecr;
+
+       spin_lock_irqsave(&tc6393xb->lock, flags);
+
+       doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
+       doecr &= ~TC_GPIO_BIT(offset);
+       iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
+
+       spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+       return 0;
+}
+
+static int tc6393xb_gpio_direction_output(struct gpio_chip *chip,
+                       unsigned offset, int value)
+{
+       struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
+       unsigned long flags;
+       u8 doecr;
+
+       spin_lock_irqsave(&tc6393xb->lock, flags);
+
+       __tc6393xb_gpio_set(chip, offset, value);
+
+       doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
+       doecr |= TC_GPIO_BIT(offset);
+       iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
+
+       spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+       return 0;
+}
+
+static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb, int gpio_base)
+{
+       tc6393xb->gpio.label = "tc6393xb";
+       tc6393xb->gpio.base = gpio_base;
+       tc6393xb->gpio.ngpio = 16;
+       tc6393xb->gpio.set = tc6393xb_gpio_set;
+       tc6393xb->gpio.get = tc6393xb_gpio_get;
+       tc6393xb->gpio.direction_input = tc6393xb_gpio_direction_input;
+       tc6393xb->gpio.direction_output = tc6393xb_gpio_direction_output;
+
+       return gpiochip_add(&tc6393xb->gpio);
+}
+
+/*--------------------------------------------------------------------------*/
+
+static void
+tc6393xb_irq(unsigned int irq, struct irq_desc *desc)
+{
+       struct tc6393xb *tc6393xb = get_irq_data(irq);
+       unsigned int isr;
+       unsigned int i, irq_base;
+
+       irq_base = tc6393xb->irq_base;
+
+       while ((isr = ioread8(tc6393xb->scr + SCR_ISR) &
+                               ~ioread8(tc6393xb->scr + SCR_IMR)))
+               for (i = 0; i < TC6393XB_NR_IRQS; i++) {
+                       if (isr & (1 << i))
+                               generic_handle_irq(irq_base + i);
+               }
+}
+
+static void tc6393xb_irq_ack(unsigned int irq)
+{
+}
+
+static void tc6393xb_irq_mask(unsigned int irq)
+{
+       struct tc6393xb *tc6393xb = get_irq_chip_data(irq);
+       unsigned long flags;
+       u8 imr;
+
+       spin_lock_irqsave(&tc6393xb->lock, flags);
+       imr = ioread8(tc6393xb->scr + SCR_IMR);
+       imr |= 1 << (irq - tc6393xb->irq_base);
+       iowrite8(imr, tc6393xb->scr + SCR_IMR);
+       spin_unlock_irqrestore(&tc6393xb->lock, flags);
+}
+
+static void tc6393xb_irq_unmask(unsigned int irq)
+{
+       struct tc6393xb *tc6393xb = get_irq_chip_data(irq);
+       unsigned long flags;
+       u8 imr;
+
+       spin_lock_irqsave(&tc6393xb->lock, flags);
+       imr = ioread8(tc6393xb->scr + SCR_IMR);
+       imr &= ~(1 << (irq - tc6393xb->irq_base));
+       iowrite8(imr, tc6393xb->scr + SCR_IMR);
+       spin_unlock_irqrestore(&tc6393xb->lock, flags);
+}
+
+static struct irq_chip tc6393xb_chip = {
+       .name   = "tc6393xb",
+       .ack    = tc6393xb_irq_ack,
+       .mask   = tc6393xb_irq_mask,
+       .unmask = tc6393xb_irq_unmask,
+};
+
+static void tc6393xb_attach_irq(struct platform_device *dev)
+{
+       struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+       unsigned int irq, irq_base;
+
+       irq_base = tc6393xb->irq_base;
+
+       for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
+               set_irq_chip(irq, &tc6393xb_chip);
+               set_irq_chip_data(irq, tc6393xb);
+               set_irq_handler(irq, handle_edge_irq);
+               set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+       }
+
+       set_irq_type(tc6393xb->irq, IRQT_FALLING);
+       set_irq_data(tc6393xb->irq, tc6393xb);
+       set_irq_chained_handler(tc6393xb->irq, tc6393xb_irq);
+}
+
+static void tc6393xb_detach_irq(struct platform_device *dev)
+{
+       struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+       unsigned int irq, irq_base;
+
+       set_irq_chained_handler(tc6393xb->irq, NULL);
+       set_irq_data(tc6393xb->irq, NULL);
+
+       irq_base = tc6393xb->irq_base;
+
+       for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
+               set_irq_flags(irq, 0);
+               set_irq_chip(irq, NULL);
+               set_irq_chip_data(irq, NULL);
+       }
+}
+
+/*--------------------------------------------------------------------------*/
+
+static int tc6393xb_hw_init(struct platform_device *dev)
+{
+       struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+       struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+       int i;
+
+       iowrite8(tc6393xb->suspend_state.fer,   tc6393xb->scr + SCR_FER);
+       iowrite16(tcpd->scr_pll2cr,             tc6393xb->scr + SCR_PLL2CR);
+       iowrite16(tc6393xb->suspend_state.ccr,  tc6393xb->scr + SCR_CCR);
+       iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN |
+                 SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN |
+                 BIT(15),                      tc6393xb->scr + SCR_MCR);
+       iowrite16(tcpd->scr_gper,               tc6393xb->scr + SCR_GPER);
+       iowrite8(0,                             tc6393xb->scr + SCR_IRR);
+       iowrite8(0xbf,                          tc6393xb->scr + SCR_IMR);
+
+       for (i = 0; i < 3; i++) {
+               iowrite8(tc6393xb->suspend_state.gpo_dsr[i],
+                                       tc6393xb->scr + SCR_GPO_DSR(i));
+               iowrite8(tc6393xb->suspend_state.gpo_doecr[i],
+                                       tc6393xb->scr + SCR_GPO_DOECR(i));
+               iowrite8(tc6393xb->suspend_state.gpi_bcr[i],
+                                       tc6393xb->scr + SCR_GPI_BCR(i));
+       }
+
+       return 0;
+}
+
+static int __devinit tc6393xb_probe(struct platform_device *dev)
+{
+       struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+       struct tc6393xb *tc6393xb;
+       struct resource *iomem;
+       struct resource *rscr;
+       int retval, temp;
+       int i;
+
+       iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       if (!iomem)
+               return -EINVAL;
+
+       tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL);
+       if (!tc6393xb) {
+               retval = -ENOMEM;
+               goto err_kzalloc;
+       }
+
+       spin_lock_init(&tc6393xb->lock);
+
+       platform_set_drvdata(dev, tc6393xb);
+       tc6393xb->iomem = iomem;
+       tc6393xb->irq = platform_get_irq(dev, 0);
+       tc6393xb->irq_base = tcpd->irq_base;
+
+       tc6393xb->clk = clk_get(&dev->dev, "GPIO27_CLK" /* "CK3P6MI" */);
+       if (IS_ERR(tc6393xb->clk)) {
+               retval = PTR_ERR(tc6393xb->clk);
+               goto err_clk_get;
+       }
+
+       rscr = &tc6393xb->rscr;
+       rscr->name = "tc6393xb-core";
+       rscr->start = iomem->start;
+       rscr->end = iomem->start + 0xff;
+       rscr->flags = IORESOURCE_MEM;
+
+       retval = request_resource(iomem, rscr);
+       if (retval)
+               goto err_request_scr;
+
+       tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1);
+       if (!tc6393xb->scr) {
+               retval = -ENOMEM;
+               goto err_ioremap;
+       }
+
+       retval = clk_enable(tc6393xb->clk);
+       if (retval)
+               goto err_clk_enable;
+
+       retval = tcpd->enable(dev);
+       if (retval)
+               goto err_enable;
+
+       tc6393xb->suspend_state.fer = 0;
+       for (i = 0; i < 3; i++) {
+               tc6393xb->suspend_state.gpo_dsr[i] =
+                       (tcpd->scr_gpo_dsr >> (8 * i)) & 0xff;
+               tc6393xb->suspend_state.gpo_doecr[i] =
+                       (tcpd->scr_gpo_doecr >> (8 * i)) & 0xff;
+       }
+       /*
+        * It may be necessary to change this back to
+        * platform-dependant code
+        */
+       tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 |
+                                       SCR_CCR_HCLK_48;
+
+       retval = tc6393xb_hw_init(dev);
+       if (retval)
+               goto err_hw_init;
+
+       printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n",
+                       ioread8(tc6393xb->scr + SCR_REVID),
+                       (unsigned long) iomem->start, tc6393xb->irq);
+
+       tc6393xb->gpio.base = -1;
+
+       if (tcpd->gpio_base >= 0) {
+               retval = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base);
+               if (retval)
+                       goto err_gpio_add;
+       }
+
+       if (tc6393xb->irq)
+               tc6393xb_attach_irq(dev);
+
+       tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data;
+
+       retval = mfd_add_devices(dev,
+                       tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
+                       iomem, tcpd->irq_base);
+
+       return 0;
+
+       if (tc6393xb->irq)
+               tc6393xb_detach_irq(dev);
+
+err_gpio_add:
+       if (tc6393xb->gpio.base != -1)
+               temp = gpiochip_remove(&tc6393xb->gpio);
+err_hw_init:
+       tcpd->disable(dev);
+err_clk_enable:
+       clk_disable(tc6393xb->clk);
+err_enable:
+       iounmap(tc6393xb->scr);
+err_ioremap:
+       release_resource(&tc6393xb->rscr);
+err_request_scr:
+       clk_put(tc6393xb->clk);
+err_clk_get:
+       kfree(tc6393xb);
+err_kzalloc:
+       return retval;
+}
+
+static int __devexit tc6393xb_remove(struct platform_device *dev)
+{
+       struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+       struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+       int ret;
+
+       mfd_remove_devices(dev);
+
+       if (tc6393xb->irq)
+               tc6393xb_detach_irq(dev);
+
+       if (tc6393xb->gpio.base != -1) {
+               ret = gpiochip_remove(&tc6393xb->gpio);
+               if (ret) {
+                       dev_err(&dev->dev, "Can't remove gpio chip: %d\n", ret);
+                       return ret;
+               }
+       }
+
+       ret = tcpd->disable(dev);
+
+       clk_disable(tc6393xb->clk);
+
+       iounmap(tc6393xb->scr);
+
+       release_resource(&tc6393xb->rscr);
+
+       platform_set_drvdata(dev, NULL);
+
+       clk_put(tc6393xb->clk);
+
+       kfree(tc6393xb);
+
+       return ret;
+}
+
+#ifdef CONFIG_PM
+static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
+{
+       struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+       struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+       int i;
+
+
+       tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR);
+       tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER);
+
+       for (i = 0; i < 3; i++) {
+               tc6393xb->suspend_state.gpo_dsr[i] =
+                       ioread8(tc6393xb->scr + SCR_GPO_DSR(i));
+               tc6393xb->suspend_state.gpo_doecr[i] =
+                       ioread8(tc6393xb->scr + SCR_GPO_DOECR(i));
+               tc6393xb->suspend_state.gpi_bcr[i] =
+                       ioread8(tc6393xb->scr + SCR_GPI_BCR(i));
+       }
+
+       return tcpd->suspend(dev);
+}
+
+static int tc6393xb_resume(struct platform_device *dev)
+{
+       struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+       int ret = tcpd->resume(dev);
+
+       if (ret)
+               return ret;
+
+       return tc6393xb_hw_init(dev);
+}
+#else
+#define tc6393xb_suspend NULL
+#define tc6393xb_resume NULL
+#endif
+
+static struct platform_driver tc6393xb_driver = {
+       .probe = tc6393xb_probe,
+       .remove = __devexit_p(tc6393xb_remove),
+       .suspend = tc6393xb_suspend,
+       .resume = tc6393xb_resume,
+
+       .driver = {
+               .name = "tc6393xb",
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init tc6393xb_init(void)
+{
+       return platform_driver_register(&tc6393xb_driver);
+}
+
+static void __exit tc6393xb_exit(void)
+{
+       platform_driver_unregister(&tc6393xb_driver);
+}
+
+subsys_initcall(tc6393xb_init);
+module_exit(tc6393xb_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer");
+MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller");
+MODULE_ALIAS("platform:tc6393xb");
index 1921b8dbb2427f94d1403c24e0330c6dbad7d70b..ce67d973d349df0f76ed5a5eccb9836fdc604469 100644 (file)
@@ -420,4 +420,17 @@ config SGI_XP
          this feature will allow for direct communication between SSIs
          based on a network adapter and DMA messaging.
 
+config HP_ILO
+       tristate "Channel interface driver for HP iLO/iLO2 processor"
+       default n
+       help
+         The channel interface driver allows applications to communicate
+         with iLO/iLO2 management processors present on HP ProLiant
+         servers.  Upon loading, the driver creates /dev/hpilo/dXccbN files,
+         which can be used to gather data from the management processor,
+         via read and write system calls.
+
+         To compile this driver as a module, choose M here: the
+         module will be called hpilo.
+
 endif # MISC_DEVICES
index a6dac6a2e7e59c485fcd5a65f9f4ed752768a2af..688fe76135e0eca608a8936edc324d37f91e4dea 100644 (file)
@@ -27,3 +27,4 @@ obj-$(CONFIG_INTEL_MENLOW)    += intel_menlow.o
 obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
 obj-$(CONFIG_KGDB_TESTS)       += kgdbts.o
 obj-$(CONFIG_SGI_XP)           += sgi-xp/
+obj-$(CONFIG_HP_ILO)           += hpilo.o
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
new file mode 100644 (file)
index 0000000..05e2982
--- /dev/null
@@ -0,0 +1,768 @@
+/*
+ * Driver for HP iLO/iLO2 management processor.
+ *
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ *     David Altobelli <david.altobelli@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/file.h>
+#include <linux/cdev.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include "hpilo.h"
+
+static struct class *ilo_class;
+static unsigned int ilo_major;
+static char ilo_hwdev[MAX_ILO_DEV];
+
+static inline int get_entry_id(int entry)
+{
+       return (entry & ENTRY_MASK_DESCRIPTOR) >> ENTRY_BITPOS_DESCRIPTOR;
+}
+
+static inline int get_entry_len(int entry)
+{
+       return ((entry & ENTRY_MASK_QWORDS) >> ENTRY_BITPOS_QWORDS) << 3;
+}
+
+static inline int mk_entry(int id, int len)
+{
+       int qlen = len & 7 ? (len >> 3) + 1 : len >> 3;
+       return id << ENTRY_BITPOS_DESCRIPTOR | qlen << ENTRY_BITPOS_QWORDS;
+}
+
+static inline int desc_mem_sz(int nr_entry)
+{
+       return nr_entry << L2_QENTRY_SZ;
+}
+
+/*
+ * FIFO queues, shared with hardware.
+ *
+ * If a queue has empty slots, an entry is added to the queue tail,
+ * and that entry is marked as occupied.
+ * Entries can be dequeued from the head of the list, when the device
+ * has marked the entry as consumed.
+ *
+ * Returns true on successful queue/dequeue, false on failure.
+ */
+static int fifo_enqueue(struct ilo_hwinfo *hw, char *fifobar, int entry)
+{
+       struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar);
+       int ret = 0;
+
+       spin_lock(&hw->fifo_lock);
+       if (!(fifo_q->fifobar[(fifo_q->tail + 1) & fifo_q->imask]
+             & ENTRY_MASK_O)) {
+               fifo_q->fifobar[fifo_q->tail & fifo_q->imask] |=
+                               (entry & ENTRY_MASK_NOSTATE) | fifo_q->merge;
+               fifo_q->tail += 1;
+               ret = 1;
+       }
+       spin_unlock(&hw->fifo_lock);
+
+       return ret;
+}
+
+static int fifo_dequeue(struct ilo_hwinfo *hw, char *fifobar, int *entry)
+{
+       struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar);
+       int ret = 0;
+       u64 c;
+
+       spin_lock(&hw->fifo_lock);
+       c = fifo_q->fifobar[fifo_q->head & fifo_q->imask];
+       if (c & ENTRY_MASK_C) {
+               if (entry)
+                       *entry = c & ENTRY_MASK_NOSTATE;
+
+               fifo_q->fifobar[fifo_q->head & fifo_q->imask] =
+                                                       (c | ENTRY_MASK) + 1;
+               fifo_q->head += 1;
+               ret = 1;
+       }
+       spin_unlock(&hw->fifo_lock);
+
+       return ret;
+}
+
+static int ilo_pkt_enqueue(struct ilo_hwinfo *hw, struct ccb *ccb,
+                          int dir, int id, int len)
+{
+       char *fifobar;
+       int entry;
+
+       if (dir == SENDQ)
+               fifobar = ccb->ccb_u1.send_fifobar;
+       else
+               fifobar = ccb->ccb_u3.recv_fifobar;
+
+       entry = mk_entry(id, len);
+       return fifo_enqueue(hw, fifobar, entry);
+}
+
+static int ilo_pkt_dequeue(struct ilo_hwinfo *hw, struct ccb *ccb,
+                          int dir, int *id, int *len, void **pkt)
+{
+       char *fifobar, *desc;
+       int entry = 0, pkt_id = 0;
+       int ret;
+
+       if (dir == SENDQ) {
+               fifobar = ccb->ccb_u1.send_fifobar;
+               desc = ccb->ccb_u2.send_desc;
+       } else {
+               fifobar = ccb->ccb_u3.recv_fifobar;
+               desc = ccb->ccb_u4.recv_desc;
+       }
+
+       ret = fifo_dequeue(hw, fifobar, &entry);
+       if (ret) {
+               pkt_id = get_entry_id(entry);
+               if (id)
+                       *id = pkt_id;
+               if (len)
+                       *len = get_entry_len(entry);
+               if (pkt)
+                       *pkt = (void *)(desc + desc_mem_sz(pkt_id));
+       }
+
+       return ret;
+}
+
+static inline void doorbell_set(struct ccb *ccb)
+{
+       iowrite8(1, ccb->ccb_u5.db_base);
+}
+
+static inline void doorbell_clr(struct ccb *ccb)
+{
+       iowrite8(2, ccb->ccb_u5.db_base);
+}
+static inline int ctrl_set(int l2sz, int idxmask, int desclim)
+{
+       int active = 0, go = 1;
+       return l2sz << CTRL_BITPOS_L2SZ |
+              idxmask << CTRL_BITPOS_FIFOINDEXMASK |
+              desclim << CTRL_BITPOS_DESCLIMIT |
+              active << CTRL_BITPOS_A |
+              go << CTRL_BITPOS_G;
+}
+static void ctrl_setup(struct ccb *ccb, int nr_desc, int l2desc_sz)
+{
+       /* for simplicity, use the same parameters for send and recv ctrls */
+       ccb->send_ctrl = ctrl_set(l2desc_sz, nr_desc-1, nr_desc-1);
+       ccb->recv_ctrl = ctrl_set(l2desc_sz, nr_desc-1, nr_desc-1);
+}
+
+static inline int fifo_sz(int nr_entry)
+{
+       /* size of a fifo is determined by the number of entries it contains */
+       return (nr_entry * sizeof(u64)) + FIFOHANDLESIZE;
+}
+
+static void fifo_setup(void *base_addr, int nr_entry)
+{
+       struct fifo *fifo_q = base_addr;
+       int i;
+
+       /* set up an empty fifo */
+       fifo_q->head = 0;
+       fifo_q->tail = 0;
+       fifo_q->reset = 0;
+       fifo_q->nrents = nr_entry;
+       fifo_q->imask = nr_entry - 1;
+       fifo_q->merge = ENTRY_MASK_O;
+
+       for (i = 0; i < nr_entry; i++)
+               fifo_q->fifobar[i] = 0;
+}
+
+static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data)
+{
+       struct ccb *driver_ccb;
+       struct ccb __iomem *device_ccb;
+       int retries;
+
+       driver_ccb = &data->driver_ccb;
+       device_ccb = data->mapped_ccb;
+
+       /* complicated dance to tell the hw we are stopping */
+       doorbell_clr(driver_ccb);
+       iowrite32(ioread32(&device_ccb->send_ctrl) & ~(1 << CTRL_BITPOS_G),
+                 &device_ccb->send_ctrl);
+       iowrite32(ioread32(&device_ccb->recv_ctrl) & ~(1 << CTRL_BITPOS_G),
+                 &device_ccb->recv_ctrl);
+
+       /* give iLO some time to process stop request */
+       for (retries = 1000; retries > 0; retries--) {
+               doorbell_set(driver_ccb);
+               udelay(1);
+               if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A))
+                   &&
+                   !(ioread32(&device_ccb->recv_ctrl) & (1 << CTRL_BITPOS_A)))
+                       break;
+       }
+       if (retries == 0)
+               dev_err(&pdev->dev, "Closing, but controller still active\n");
+
+       /* clear the hw ccb */
+       memset_io(device_ccb, 0, sizeof(struct ccb));
+
+       /* free resources used to back send/recv queues */
+       pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa);
+}
+
+static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
+{
+       char *dma_va, *dma_pa;
+       int pkt_id, pkt_sz, i, error;
+       struct ccb *driver_ccb, *ilo_ccb;
+       struct pci_dev *pdev;
+
+       driver_ccb = &data->driver_ccb;
+       ilo_ccb = &data->ilo_ccb;
+       pdev = hw->ilo_dev;
+
+       data->dma_size = 2 * fifo_sz(NR_QENTRY) +
+                        2 * desc_mem_sz(NR_QENTRY) +
+                        ILO_START_ALIGN + ILO_CACHE_SZ;
+
+       error = -ENOMEM;
+       data->dma_va = pci_alloc_consistent(pdev, data->dma_size,
+                                           &data->dma_pa);
+       if (!data->dma_va)
+               goto out;
+
+       dma_va = (char *)data->dma_va;
+       dma_pa = (char *)data->dma_pa;
+
+       memset(dma_va, 0, data->dma_size);
+
+       dma_va = (char *)roundup((unsigned long)dma_va, ILO_START_ALIGN);
+       dma_pa = (char *)roundup((unsigned long)dma_pa, ILO_START_ALIGN);
+
+       /*
+        * Create two ccb's, one with virt addrs, one with phys addrs.
+        * Copy the phys addr ccb to device shared mem.
+        */
+       ctrl_setup(driver_ccb, NR_QENTRY, L2_QENTRY_SZ);
+       ctrl_setup(ilo_ccb, NR_QENTRY, L2_QENTRY_SZ);
+
+       fifo_setup(dma_va, NR_QENTRY);
+       driver_ccb->ccb_u1.send_fifobar = dma_va + FIFOHANDLESIZE;
+       ilo_ccb->ccb_u1.send_fifobar = dma_pa + FIFOHANDLESIZE;
+       dma_va += fifo_sz(NR_QENTRY);
+       dma_pa += fifo_sz(NR_QENTRY);
+
+       dma_va = (char *)roundup((unsigned long)dma_va, ILO_CACHE_SZ);
+       dma_pa = (char *)roundup((unsigned long)dma_pa, ILO_CACHE_SZ);
+
+       fifo_setup(dma_va, NR_QENTRY);
+       driver_ccb->ccb_u3.recv_fifobar = dma_va + FIFOHANDLESIZE;
+       ilo_ccb->ccb_u3.recv_fifobar = dma_pa + FIFOHANDLESIZE;
+       dma_va += fifo_sz(NR_QENTRY);
+       dma_pa += fifo_sz(NR_QENTRY);
+
+       driver_ccb->ccb_u2.send_desc = dma_va;
+       ilo_ccb->ccb_u2.send_desc = dma_pa;
+       dma_pa += desc_mem_sz(NR_QENTRY);
+       dma_va += desc_mem_sz(NR_QENTRY);
+
+       driver_ccb->ccb_u4.recv_desc = dma_va;
+       ilo_ccb->ccb_u4.recv_desc = dma_pa;
+
+       driver_ccb->channel = slot;
+       ilo_ccb->channel = slot;
+
+       driver_ccb->ccb_u5.db_base = hw->db_vaddr + (slot << L2_DB_SIZE);
+       ilo_ccb->ccb_u5.db_base = NULL; /* hw ccb's doorbell is not used */
+
+       /* copy the ccb with physical addrs to device memory */
+       data->mapped_ccb = (struct ccb __iomem *)
+                               (hw->ram_vaddr + (slot * ILOHW_CCB_SZ));
+       memcpy_toio(data->mapped_ccb, ilo_ccb, sizeof(struct ccb));
+
+       /* put packets on the send and receive queues */
+       pkt_sz = 0;
+       for (pkt_id = 0; pkt_id < NR_QENTRY; pkt_id++) {
+               ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, pkt_sz);
+               doorbell_set(driver_ccb);
+       }
+
+       pkt_sz = desc_mem_sz(1);
+       for (pkt_id = 0; pkt_id < NR_QENTRY; pkt_id++)
+               ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, pkt_sz);
+
+       doorbell_clr(driver_ccb);
+
+       /* make sure iLO is really handling requests */
+       for (i = 1000; i > 0; i--) {
+               if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL))
+                       break;
+               udelay(1);
+       }
+
+       if (i) {
+               ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, 0);
+               doorbell_set(driver_ccb);
+       } else {
+               dev_err(&pdev->dev, "Open could not dequeue a packet\n");
+               error = -EBUSY;
+               goto free;
+       }
+
+       return 0;
+free:
+       pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa);
+out:
+       return error;
+}
+
+static inline int is_channel_reset(struct ccb *ccb)
+{
+       /* check for this particular channel needing a reset */
+       return FIFOBARTOHANDLE(ccb->ccb_u1.send_fifobar)->reset;
+}
+
+static inline void set_channel_reset(struct ccb *ccb)
+{
+       /* set a flag indicating this channel needs a reset */
+       FIFOBARTOHANDLE(ccb->ccb_u1.send_fifobar)->reset = 1;
+}
+
+static inline int is_device_reset(struct ilo_hwinfo *hw)
+{
+       /* check for global reset condition */
+       return ioread32(&hw->mmio_vaddr[DB_OUT]) & (1 << DB_RESET);
+}
+
+static inline void clear_device(struct ilo_hwinfo *hw)
+{
+       /* clear the device (reset bits, pending channel entries) */
+       iowrite32(-1, &hw->mmio_vaddr[DB_OUT]);
+}
+
+static void ilo_locked_reset(struct ilo_hwinfo *hw)
+{
+       int slot;
+
+       /*
+        * Mapped memory is zeroed on ilo reset, so set a per ccb flag
+        * to indicate that this ccb needs to be closed and reopened.
+        */
+       for (slot = 0; slot < MAX_CCB; slot++) {
+               if (!hw->ccb_alloc[slot])
+                       continue;
+               set_channel_reset(&hw->ccb_alloc[slot]->driver_ccb);
+       }
+
+       clear_device(hw);
+}
+
+static void ilo_reset(struct ilo_hwinfo *hw)
+{
+       spin_lock(&hw->alloc_lock);
+
+       /* reset might have been handled after lock was taken */
+       if (is_device_reset(hw))
+               ilo_locked_reset(hw);
+
+       spin_unlock(&hw->alloc_lock);
+}
+
+static ssize_t ilo_read(struct file *fp, char __user *buf,
+                       size_t len, loff_t *off)
+{
+       int err, found, cnt, pkt_id, pkt_len;
+       struct ccb_data *data;
+       struct ccb *driver_ccb;
+       struct ilo_hwinfo *hw;
+       void *pkt;
+
+       data = fp->private_data;
+       driver_ccb = &data->driver_ccb;
+       hw = data->ilo_hw;
+
+       if (is_device_reset(hw) || is_channel_reset(driver_ccb)) {
+               /*
+                * If the device has been reset, applications
+                * need to close and reopen all ccbs.
+                */
+               ilo_reset(hw);
+               return -ENODEV;
+       }
+
+       /*
+        * This function is to be called when data is expected
+        * in the channel, and will return an error if no packet is found
+        * during the loop below.  The sleep/retry logic is to allow
+        * applications to call read() immediately post write(),
+        * and give iLO some time to process the sent packet.
+        */
+       cnt = 20;
+       do {
+               /* look for a received packet */
+               found = ilo_pkt_dequeue(hw, driver_ccb, RECVQ, &pkt_id,
+                                       &pkt_len, &pkt);
+               if (found)
+                       break;
+               cnt--;
+               msleep(100);
+       } while (!found && cnt);
+
+       if (!found)
+               return -EAGAIN;
+
+       /* only copy the length of the received packet */
+       if (pkt_len < len)
+               len = pkt_len;
+
+       err = copy_to_user(buf, pkt, len);
+
+       /* return the received packet to the queue */
+       ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, desc_mem_sz(1));
+
+       return err ? -EFAULT : len;
+}
+
+static ssize_t ilo_write(struct file *fp, const char __user *buf,
+                        size_t len, loff_t *off)
+{
+       int err, pkt_id, pkt_len;
+       struct ccb_data *data;
+       struct ccb *driver_ccb;
+       struct ilo_hwinfo *hw;
+       void *pkt;
+
+       data = fp->private_data;
+       driver_ccb = &data->driver_ccb;
+       hw = data->ilo_hw;
+
+       if (is_device_reset(hw) || is_channel_reset(driver_ccb)) {
+               /*
+                * If the device has been reset, applications
+                * need to close and reopen all ccbs.
+                */
+               ilo_reset(hw);
+               return -ENODEV;
+       }
+
+       /* get a packet to send the user command */
+       if (!ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, &pkt_len, &pkt))
+               return -EBUSY;
+
+       /* limit the length to the length of the packet */
+       if (pkt_len < len)
+               len = pkt_len;
+
+       /* on failure, set the len to 0 to return empty packet to the device */
+       err = copy_from_user(pkt, buf, len);
+       if (err)
+               len = 0;
+
+       /* send the packet */
+       ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, len);
+       doorbell_set(driver_ccb);
+
+       return err ? -EFAULT : len;
+}
+
+static int ilo_close(struct inode *ip, struct file *fp)
+{
+       int slot;
+       struct ccb_data *data;
+       struct ilo_hwinfo *hw;
+
+       slot = iminor(ip) % MAX_CCB;
+       hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev);
+
+       spin_lock(&hw->alloc_lock);
+
+       if (is_device_reset(hw))
+               ilo_locked_reset(hw);
+
+       if (hw->ccb_alloc[slot]->ccb_cnt == 1) {
+
+               data = fp->private_data;
+
+               ilo_ccb_close(hw->ilo_dev, data);
+
+               kfree(data);
+               hw->ccb_alloc[slot] = NULL;
+       } else
+               hw->ccb_alloc[slot]->ccb_cnt--;
+
+       spin_unlock(&hw->alloc_lock);
+
+       return 0;
+}
+
+static int ilo_open(struct inode *ip, struct file *fp)
+{
+       int slot, error;
+       struct ccb_data *data;
+       struct ilo_hwinfo *hw;
+
+       slot = iminor(ip) % MAX_CCB;
+       hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev);
+
+       /* new ccb allocation */
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       spin_lock(&hw->alloc_lock);
+
+       if (is_device_reset(hw))
+               ilo_locked_reset(hw);
+
+       /* each fd private_data holds sw/hw view of ccb */
+       if (hw->ccb_alloc[slot] == NULL) {
+               /* create a channel control block for this minor */
+               error = ilo_ccb_open(hw, data, slot);
+               if (!error) {
+                       hw->ccb_alloc[slot] = data;
+                       hw->ccb_alloc[slot]->ccb_cnt = 1;
+                       hw->ccb_alloc[slot]->ccb_excl = fp->f_flags & O_EXCL;
+                       hw->ccb_alloc[slot]->ilo_hw = hw;
+               } else
+                       kfree(data);
+       } else {
+               kfree(data);
+               if (fp->f_flags & O_EXCL || hw->ccb_alloc[slot]->ccb_excl) {
+                       /*
+                        * The channel exists, and either this open
+                        * or a previous open of this channel wants
+                        * exclusive access.
+                        */
+                       error = -EBUSY;
+               } else {
+                       hw->ccb_alloc[slot]->ccb_cnt++;
+                       error = 0;
+               }
+       }
+       spin_unlock(&hw->alloc_lock);
+
+       if (!error)
+               fp->private_data = hw->ccb_alloc[slot];
+
+       return error;
+}
+
+static const struct file_operations ilo_fops = {
+       .owner          = THIS_MODULE,
+       .read           = ilo_read,
+       .write          = ilo_write,
+       .open           = ilo_open,
+       .release        = ilo_close,
+};
+
+static void ilo_unmap_device(struct pci_dev *pdev, struct ilo_hwinfo *hw)
+{
+       pci_iounmap(pdev, hw->db_vaddr);
+       pci_iounmap(pdev, hw->ram_vaddr);
+       pci_iounmap(pdev, hw->mmio_vaddr);
+}
+
+static int __devinit ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw)
+{
+       int error = -ENOMEM;
+
+       /* map the memory mapped i/o registers */
+       hw->mmio_vaddr = pci_iomap(pdev, 1, 0);
+       if (hw->mmio_vaddr == NULL) {
+               dev_err(&pdev->dev, "Error mapping mmio\n");
+               goto out;
+       }
+
+       /* map the adapter shared memory region */
+       hw->ram_vaddr = pci_iomap(pdev, 2, MAX_CCB * ILOHW_CCB_SZ);
+       if (hw->ram_vaddr == NULL) {
+               dev_err(&pdev->dev, "Error mapping shared mem\n");
+               goto mmio_free;
+       }
+
+       /* map the doorbell aperture */
+       hw->db_vaddr = pci_iomap(pdev, 3, MAX_CCB * ONE_DB_SIZE);
+       if (hw->db_vaddr == NULL) {
+               dev_err(&pdev->dev, "Error mapping doorbell\n");
+               goto ram_free;
+       }
+
+       return 0;
+ram_free:
+       pci_iounmap(pdev, hw->ram_vaddr);
+mmio_free:
+       pci_iounmap(pdev, hw->mmio_vaddr);
+out:
+       return error;
+}
+
+static void ilo_remove(struct pci_dev *pdev)
+{
+       int i, minor;
+       struct ilo_hwinfo *ilo_hw = pci_get_drvdata(pdev);
+
+       clear_device(ilo_hw);
+
+       minor = MINOR(ilo_hw->cdev.dev);
+       for (i = minor; i < minor + MAX_CCB; i++)
+               device_destroy(ilo_class, MKDEV(ilo_major, i));
+
+       cdev_del(&ilo_hw->cdev);
+       ilo_unmap_device(pdev, ilo_hw);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       kfree(ilo_hw);
+       ilo_hwdev[(minor / MAX_CCB)] = 0;
+}
+
+static int __devinit ilo_probe(struct pci_dev *pdev,
+                              const struct pci_device_id *ent)
+{
+       int devnum, minor, start, error;
+       struct ilo_hwinfo *ilo_hw;
+
+       /* find a free range for device files */
+       for (devnum = 0; devnum < MAX_ILO_DEV; devnum++) {
+               if (ilo_hwdev[devnum] == 0) {
+                       ilo_hwdev[devnum] = 1;
+                       break;
+               }
+       }
+
+       if (devnum == MAX_ILO_DEV) {
+               dev_err(&pdev->dev, "Error finding free device\n");
+               return -ENODEV;
+       }
+
+       /* track global allocations for this device */
+       error = -ENOMEM;
+       ilo_hw = kzalloc(sizeof(*ilo_hw), GFP_KERNEL);
+       if (!ilo_hw)
+               goto out;
+
+       ilo_hw->ilo_dev = pdev;
+       spin_lock_init(&ilo_hw->alloc_lock);
+       spin_lock_init(&ilo_hw->fifo_lock);
+
+       error = pci_enable_device(pdev);
+       if (error)
+               goto free;
+
+       pci_set_master(pdev);
+
+       error = pci_request_regions(pdev, ILO_NAME);
+       if (error)
+               goto disable;
+
+       error = ilo_map_device(pdev, ilo_hw);
+       if (error)
+               goto free_regions;
+
+       pci_set_drvdata(pdev, ilo_hw);
+       clear_device(ilo_hw);
+
+       cdev_init(&ilo_hw->cdev, &ilo_fops);
+       ilo_hw->cdev.owner = THIS_MODULE;
+       start = devnum * MAX_CCB;
+       error = cdev_add(&ilo_hw->cdev, MKDEV(ilo_major, start), MAX_CCB);
+       if (error) {
+               dev_err(&pdev->dev, "Could not add cdev\n");
+               goto unmap;
+       }
+
+       for (minor = 0 ; minor < MAX_CCB; minor++) {
+               struct device *dev;
+               dev = device_create(ilo_class, &pdev->dev,
+                                   MKDEV(ilo_major, minor), NULL,
+                                   "hpilo!d%dccb%d", devnum, minor);
+               if (IS_ERR(dev))
+                       dev_err(&pdev->dev, "Could not create files\n");
+       }
+
+       return 0;
+unmap:
+       ilo_unmap_device(pdev, ilo_hw);
+free_regions:
+       pci_release_regions(pdev);
+disable:
+       pci_disable_device(pdev);
+free:
+       kfree(ilo_hw);
+out:
+       ilo_hwdev[devnum] = 0;
+       return error;
+}
+
+static struct pci_device_id ilo_devices[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB204) },
+       { }
+};
+MODULE_DEVICE_TABLE(pci, ilo_devices);
+
+static struct pci_driver ilo_driver = {
+       .name     = ILO_NAME,
+       .id_table = ilo_devices,
+       .probe    = ilo_probe,
+       .remove   = __devexit_p(ilo_remove),
+};
+
+static int __init ilo_init(void)
+{
+       int error;
+       dev_t dev;
+
+       ilo_class = class_create(THIS_MODULE, "iLO");
+       if (IS_ERR(ilo_class)) {
+               error = PTR_ERR(ilo_class);
+               goto out;
+       }
+
+       error = alloc_chrdev_region(&dev, 0, MAX_OPEN, ILO_NAME);
+       if (error)
+               goto class_destroy;
+
+       ilo_major = MAJOR(dev);
+
+       error = pci_register_driver(&ilo_driver);
+       if (error)
+               goto chr_remove;
+
+       return 0;
+chr_remove:
+       unregister_chrdev_region(dev, MAX_OPEN);
+class_destroy:
+       class_destroy(ilo_class);
+out:
+       return error;
+}
+
+static void __exit ilo_exit(void)
+{
+       pci_unregister_driver(&ilo_driver);
+       unregister_chrdev_region(MKDEV(ilo_major, 0), MAX_OPEN);
+       class_destroy(ilo_class);
+}
+
+MODULE_VERSION("0.05");
+MODULE_ALIAS(ILO_NAME);
+MODULE_DESCRIPTION(ILO_NAME);
+MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>");
+MODULE_LICENSE("GPL v2");
+
+module_init(ilo_init);
+module_exit(ilo_exit);
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h
new file mode 100644 (file)
index 0000000..a281207
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * linux/drivers/char/hpilo.h
+ *
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ *     David Altobelli <david.altobelli@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __HPILO_H
+#define __HPILO_H
+
+#define ILO_NAME "hpilo"
+
+/* max number of open channel control blocks per device, hw limited to 32 */
+#define MAX_CCB                8
+/* max number of supported devices */
+#define MAX_ILO_DEV    1
+/* max number of files */
+#define MAX_OPEN       (MAX_CCB * MAX_ILO_DEV)
+
+/*
+ * Per device, used to track global memory allocations.
+ */
+struct ilo_hwinfo {
+       /* mmio registers on device */
+       char __iomem *mmio_vaddr;
+
+       /* doorbell registers on device */
+       char __iomem *db_vaddr;
+
+       /* shared memory on device used for channel control blocks */
+       char __iomem *ram_vaddr;
+
+       /* files corresponding to this device */
+       struct ccb_data *ccb_alloc[MAX_CCB];
+
+       struct pci_dev *ilo_dev;
+
+       spinlock_t alloc_lock;
+       spinlock_t fifo_lock;
+
+       struct cdev cdev;
+};
+
+/* offset from mmio_vaddr */
+#define DB_OUT         0xD4
+/* DB_OUT reset bit */
+#define DB_RESET       26
+
+/*
+ * Channel control block. Used to manage hardware queues.
+ * The format must match hw's version.  The hw ccb is 128 bytes,
+ * but the context area shouldn't be touched by the driver.
+ */
+#define ILOSW_CCB_SZ   64
+#define ILOHW_CCB_SZ   128
+struct ccb {
+       union {
+               char *send_fifobar;
+               u64 padding1;
+       } ccb_u1;
+       union {
+               char *send_desc;
+               u64 padding2;
+       } ccb_u2;
+       u64 send_ctrl;
+
+       union {
+               char *recv_fifobar;
+               u64 padding3;
+       } ccb_u3;
+       union {
+               char *recv_desc;
+               u64 padding4;
+       } ccb_u4;
+       u64 recv_ctrl;
+
+       union {
+               char __iomem *db_base;
+               u64 padding5;
+       } ccb_u5;
+
+       u64 channel;
+
+       /* unused context area (64 bytes) */
+};
+
+/* ccb queue parameters */
+#define SENDQ          1
+#define RECVQ          2
+#define NR_QENTRY      4
+#define L2_QENTRY_SZ   12
+
+/* ccb ctrl bitfields */
+#define CTRL_BITPOS_L2SZ             0
+#define CTRL_BITPOS_FIFOINDEXMASK    4
+#define CTRL_BITPOS_DESCLIMIT        18
+#define CTRL_BITPOS_A                30
+#define CTRL_BITPOS_G                31
+
+/* ccb doorbell macros */
+#define L2_DB_SIZE             14
+#define ONE_DB_SIZE            (1 << L2_DB_SIZE)
+
+/*
+ * Per fd structure used to track the ccb allocated to that dev file.
+ */
+struct ccb_data {
+       /* software version of ccb, using virtual addrs */
+       struct ccb  driver_ccb;
+
+       /* hardware version of ccb, using physical addrs */
+       struct ccb  ilo_ccb;
+
+       /* hardware ccb is written to this shared mapped device memory */
+       struct ccb __iomem *mapped_ccb;
+
+       /* dma'able memory used for send/recv queues */
+       void       *dma_va;
+       dma_addr_t  dma_pa;
+       size_t      dma_size;
+
+       /* pointer to hardware device info */
+       struct ilo_hwinfo *ilo_hw;
+
+       /* usage count, to allow for shared ccb's */
+       int         ccb_cnt;
+
+       /* open wanted exclusive access to this ccb */
+       int         ccb_excl;
+};
+
+/*
+ * FIFO queue structure, shared with hw.
+ */
+#define ILO_START_ALIGN        4096
+#define ILO_CACHE_SZ    128
+struct fifo {
+    u64 nrents;        /* user requested number of fifo entries */
+    u64 imask;  /* mask to extract valid fifo index */
+    u64 merge; /*  O/C bits to merge in during enqueue operation */
+    u64 reset; /* set to non-zero when the target device resets */
+    u8  pad_0[ILO_CACHE_SZ - (sizeof(u64) * 4)];
+
+    u64 head;
+    u8  pad_1[ILO_CACHE_SZ - (sizeof(u64))];
+
+    u64 tail;
+    u8  pad_2[ILO_CACHE_SZ - (sizeof(u64))];
+
+    u64 fifobar[1];
+};
+
+/* convert between struct fifo, and the fifobar, which is saved in the ccb */
+#define FIFOHANDLESIZE (sizeof(struct fifo) - sizeof(u64))
+#define FIFOBARTOHANDLE(_fifo) \
+       ((struct fifo *)(((char *)(_fifo)) - FIFOHANDLESIZE))
+
+/* the number of qwords to consume from the entry descriptor */
+#define ENTRY_BITPOS_QWORDS      0
+/* descriptor index number (within a specified queue) */
+#define ENTRY_BITPOS_DESCRIPTOR  10
+/* state bit, fifo entry consumed by consumer */
+#define ENTRY_BITPOS_C           22
+/* state bit, fifo entry is occupied */
+#define ENTRY_BITPOS_O           23
+
+#define ENTRY_BITS_QWORDS        10
+#define ENTRY_BITS_DESCRIPTOR    12
+#define ENTRY_BITS_C             1
+#define ENTRY_BITS_O             1
+#define ENTRY_BITS_TOTAL       \
+       (ENTRY_BITS_C + ENTRY_BITS_O + \
+        ENTRY_BITS_QWORDS + ENTRY_BITS_DESCRIPTOR)
+
+/* extract various entry fields */
+#define ENTRY_MASK ((1 << ENTRY_BITS_TOTAL) - 1)
+#define ENTRY_MASK_C (((1 << ENTRY_BITS_C) - 1) << ENTRY_BITPOS_C)
+#define ENTRY_MASK_O (((1 << ENTRY_BITS_O) - 1) << ENTRY_BITPOS_O)
+#define ENTRY_MASK_QWORDS \
+       (((1 << ENTRY_BITS_QWORDS) - 1) << ENTRY_BITPOS_QWORDS)
+#define ENTRY_MASK_DESCRIPTOR \
+       (((1 << ENTRY_BITS_DESCRIPTOR) - 1) << ENTRY_BITPOS_DESCRIPTOR)
+
+#define ENTRY_MASK_NOSTATE (ENTRY_MASK >> (ENTRY_BITS_C + ENTRY_BITS_O))
+
+#endif /* __HPILO_H */
index 1861624700905571ca777937ba005f64bcce3a89..4ce3bdc2f959b4081a27a30dc7f8486ee9611057 100644 (file)
@@ -399,8 +399,9 @@ static int __devinit phantom_probe(struct pci_dev *pdev,
                goto err_irq;
        }
 
-       if (IS_ERR(device_create(phantom_class, &pdev->dev, MKDEV(phantom_major,
-                       minor), "phantom%u", minor)))
+       if (IS_ERR(device_create_drvdata(phantom_class, &pdev->dev,
+                                        MKDEV(phantom_major, minor),
+                                        NULL, "phantom%u", minor)))
                dev_err(&pdev->dev, "can't create device\n");
 
        pci_set_drvdata(pdev, pht);
index d6b9b486417cc702acb18bba2fd413baedf592d9..a067fe436301d2853bcc50be9f8a7d09d79fbfe0 100644 (file)
 #define RESULT_UNSUP_HOST      2
 #define RESULT_UNSUP_CARD      3
 
-#define BUFFER_SIZE    (PAGE_SIZE * 4)
+#define BUFFER_ORDER           2
+#define BUFFER_SIZE            (PAGE_SIZE << BUFFER_ORDER)
 
 struct mmc_test_card {
        struct mmc_card *card;
 
        u8              scratch[BUFFER_SIZE];
        u8              *buffer;
+#ifdef CONFIG_HIGHMEM
+       struct page     *highmem;
+#endif
 };
 
 /*******************************************************************/
@@ -384,14 +388,16 @@ static int mmc_test_transfer(struct mmc_test_card *test,
        int ret, i;
        unsigned long flags;
 
+       BUG_ON(blocks * blksz > BUFFER_SIZE);
+
        if (write) {
                for (i = 0;i < blocks * blksz;i++)
                        test->scratch[i] = i;
        } else {
-               memset(test->scratch, 0, BUFFER_SIZE);
+               memset(test->scratch, 0, blocks * blksz);
        }
        local_irq_save(flags);
-       sg_copy_from_buffer(sg, sg_len, test->scratch, BUFFER_SIZE);
+       sg_copy_from_buffer(sg, sg_len, test->scratch, blocks * blksz);
        local_irq_restore(flags);
 
        ret = mmc_test_set_blksize(test, blksz);
@@ -438,7 +444,7 @@ static int mmc_test_transfer(struct mmc_test_card *test,
                }
        } else {
                local_irq_save(flags);
-               sg_copy_to_buffer(sg, sg_len, test->scratch, BUFFER_SIZE);
+               sg_copy_to_buffer(sg, sg_len, test->scratch, blocks * blksz);
                local_irq_restore(flags);
                for (i = 0;i < blocks * blksz;i++) {
                        if (test->scratch[i] != (u8)i)
@@ -799,6 +805,157 @@ static int mmc_test_multi_xfersize_read(struct mmc_test_card *test)
        return 0;
 }
 
+static int mmc_test_bigsg_write(struct mmc_test_card *test)
+{
+       int ret;
+       unsigned int size;
+       struct scatterlist sg;
+
+       if (test->card->host->max_blk_count == 1)
+               return RESULT_UNSUP_HOST;
+
+       size = PAGE_SIZE * 2;
+       size = min(size, test->card->host->max_req_size);
+       size = min(size, test->card->host->max_seg_size);
+       size = min(size, test->card->host->max_blk_count * 512);
+
+       memset(test->buffer, 0, BUFFER_SIZE);
+
+       if (size < 1024)
+               return RESULT_UNSUP_HOST;
+
+       sg_init_table(&sg, 1);
+       sg_init_one(&sg, test->buffer, BUFFER_SIZE);
+
+       ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int mmc_test_bigsg_read(struct mmc_test_card *test)
+{
+       int ret, i;
+       unsigned int size;
+       struct scatterlist sg;
+
+       if (test->card->host->max_blk_count == 1)
+               return RESULT_UNSUP_HOST;
+
+       size = PAGE_SIZE * 2;
+       size = min(size, test->card->host->max_req_size);
+       size = min(size, test->card->host->max_seg_size);
+       size = min(size, test->card->host->max_blk_count * 512);
+
+       if (size < 1024)
+               return RESULT_UNSUP_HOST;
+
+       memset(test->buffer, 0xCD, BUFFER_SIZE);
+
+       sg_init_table(&sg, 1);
+       sg_init_one(&sg, test->buffer, BUFFER_SIZE);
+       ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
+       if (ret)
+               return ret;
+
+       /* mmc_test_transfer() doesn't check for read overflows */
+       for (i = size;i < BUFFER_SIZE;i++) {
+               if (test->buffer[i] != 0xCD)
+                       return RESULT_FAIL;
+       }
+
+       return 0;
+}
+
+#ifdef CONFIG_HIGHMEM
+
+static int mmc_test_write_high(struct mmc_test_card *test)
+{
+       int ret;
+       struct scatterlist sg;
+
+       sg_init_table(&sg, 1);
+       sg_set_page(&sg, test->highmem, 512, 0);
+
+       ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int mmc_test_read_high(struct mmc_test_card *test)
+{
+       int ret;
+       struct scatterlist sg;
+
+       sg_init_table(&sg, 1);
+       sg_set_page(&sg, test->highmem, 512, 0);
+
+       ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int mmc_test_multi_write_high(struct mmc_test_card *test)
+{
+       int ret;
+       unsigned int size;
+       struct scatterlist sg;
+
+       if (test->card->host->max_blk_count == 1)
+               return RESULT_UNSUP_HOST;
+
+       size = PAGE_SIZE * 2;
+       size = min(size, test->card->host->max_req_size);
+       size = min(size, test->card->host->max_seg_size);
+       size = min(size, test->card->host->max_blk_count * 512);
+
+       if (size < 1024)
+               return RESULT_UNSUP_HOST;
+
+       sg_init_table(&sg, 1);
+       sg_set_page(&sg, test->highmem, size, 0);
+
+       ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int mmc_test_multi_read_high(struct mmc_test_card *test)
+{
+       int ret;
+       unsigned int size;
+       struct scatterlist sg;
+
+       if (test->card->host->max_blk_count == 1)
+               return RESULT_UNSUP_HOST;
+
+       size = PAGE_SIZE * 2;
+       size = min(size, test->card->host->max_req_size);
+       size = min(size, test->card->host->max_seg_size);
+       size = min(size, test->card->host->max_blk_count * 512);
+
+       if (size < 1024)
+               return RESULT_UNSUP_HOST;
+
+       sg_init_table(&sg, 1);
+       sg_set_page(&sg, test->highmem, size, 0);
+
+       ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+#endif /* CONFIG_HIGHMEM */
+
 static const struct mmc_test_case mmc_test_cases[] = {
        {
                .name = "Basic write (no data verification)",
@@ -913,6 +1070,53 @@ static const struct mmc_test_case mmc_test_cases[] = {
                .name = "Correct xfer_size at read (midway failure)",
                .run = mmc_test_multi_xfersize_read,
        },
+
+       {
+               .name = "Over-sized SG list write",
+               .prepare = mmc_test_prepare_write,
+               .run = mmc_test_bigsg_write,
+               .cleanup = mmc_test_cleanup,
+       },
+
+       {
+               .name = "Over-sized SG list read",
+               .prepare = mmc_test_prepare_read,
+               .run = mmc_test_bigsg_read,
+               .cleanup = mmc_test_cleanup,
+       },
+
+#ifdef CONFIG_HIGHMEM
+
+       {
+               .name = "Highmem write",
+               .prepare = mmc_test_prepare_write,
+               .run = mmc_test_write_high,
+               .cleanup = mmc_test_cleanup,
+       },
+
+       {
+               .name = "Highmem read",
+               .prepare = mmc_test_prepare_read,
+               .run = mmc_test_read_high,
+               .cleanup = mmc_test_cleanup,
+       },
+
+       {
+               .name = "Multi-block highmem write",
+               .prepare = mmc_test_prepare_write,
+               .run = mmc_test_multi_write_high,
+               .cleanup = mmc_test_cleanup,
+       },
+
+       {
+               .name = "Multi-block highmem read",
+               .prepare = mmc_test_prepare_read,
+               .run = mmc_test_multi_read_high,
+               .cleanup = mmc_test_cleanup,
+       },
+
+#endif /* CONFIG_HIGHMEM */
+
 };
 
 static struct mutex mmc_test_lock;
@@ -1014,12 +1218,23 @@ static ssize_t mmc_test_store(struct device *dev,
        test->card = card;
 
        test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL);
+#ifdef CONFIG_HIGHMEM
+       test->highmem = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, BUFFER_ORDER);
+#endif
+
+#ifdef CONFIG_HIGHMEM
+       if (test->buffer && test->highmem) {
+#else
        if (test->buffer) {
+#endif
                mutex_lock(&mmc_test_lock);
                mmc_test_run(test, testcase);
                mutex_unlock(&mmc_test_lock);
        }
 
+#ifdef CONFIG_HIGHMEM
+       __free_pages(test->highmem, BUFFER_ORDER);
+#endif
        kfree(test->buffer);
        kfree(test);
 
@@ -1041,6 +1256,8 @@ static int mmc_test_probe(struct mmc_card *card)
        if (ret)
                return ret;
 
+       dev_info(&card->dev, "Card claimed for testing.\n");
+
        return 0;
 }
 
index 7731ddefdc1b03c894ccaa7188da3af05067c24e..3dee97e7d165f3e64f3898b1fb84c335cc4a1f08 100644 (file)
@@ -148,7 +148,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
                        printk(KERN_WARNING "%s: unable to allocate "
                                "bounce buffer\n", mmc_card_name(card));
                } else {
-                       blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_HIGH);
+                       blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY);
                        blk_queue_max_sectors(mq->queue, bouncesz / 512);
                        blk_queue_max_phys_segments(mq->queue, bouncesz / 512);
                        blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
@@ -290,55 +290,15 @@ void mmc_queue_resume(struct mmc_queue *mq)
        }
 }
 
-static void copy_sg(struct scatterlist *dst, unsigned int dst_len,
-       struct scatterlist *src, unsigned int src_len)
-{
-       unsigned int chunk;
-       char *dst_buf, *src_buf;
-       unsigned int dst_size, src_size;
-
-       dst_buf = NULL;
-       src_buf = NULL;
-       dst_size = 0;
-       src_size = 0;
-
-       while (src_len) {
-               BUG_ON(dst_len == 0);
-
-               if (dst_size == 0) {
-                       dst_buf = sg_virt(dst);
-                       dst_size = dst->length;
-               }
-
-               if (src_size == 0) {
-                       src_buf = sg_virt(src);
-                       src_size = src->length;
-               }
-
-               chunk = min(dst_size, src_size);
-
-               memcpy(dst_buf, src_buf, chunk);
-
-               dst_buf += chunk;
-               src_buf += chunk;
-               dst_size -= chunk;
-               src_size -= chunk;
-
-               if (dst_size == 0) {
-                       dst++;
-                       dst_len--;
-               }
-
-               if (src_size == 0) {
-                       src++;
-                       src_len--;
-               }
-       }
-}
-
+/*
+ * Prepare the sg list(s) to be handed of to the host driver
+ */
 unsigned int mmc_queue_map_sg(struct mmc_queue *mq)
 {
        unsigned int sg_len;
+       size_t buflen;
+       struct scatterlist *sg;
+       int i;
 
        if (!mq->bounce_buf)
                return blk_rq_map_sg(mq->queue, mq->req, mq->sg);
@@ -349,47 +309,52 @@ unsigned int mmc_queue_map_sg(struct mmc_queue *mq)
 
        mq->bounce_sg_len = sg_len;
 
-       /*
-        * Shortcut in the event we only get a single entry.
-        */
-       if (sg_len == 1) {
-               memcpy(mq->sg, mq->bounce_sg, sizeof(struct scatterlist));
-               return 1;
-       }
+       buflen = 0;
+       for_each_sg(mq->bounce_sg, sg, sg_len, i)
+               buflen += sg->length;
 
-       sg_init_one(mq->sg, mq->bounce_buf, 0);
-
-       while (sg_len) {
-               mq->sg[0].length += mq->bounce_sg[sg_len - 1].length;
-               sg_len--;
-       }
+       sg_init_one(mq->sg, mq->bounce_buf, buflen);
 
        return 1;
 }
 
+/*
+ * If writing, bounce the data to the buffer before the request
+ * is sent to the host driver
+ */
 void mmc_queue_bounce_pre(struct mmc_queue *mq)
 {
+       unsigned long flags;
+
        if (!mq->bounce_buf)
                return;
 
-       if (mq->bounce_sg_len == 1)
-               return;
        if (rq_data_dir(mq->req) != WRITE)
                return;
 
-       copy_sg(mq->sg, 1, mq->bounce_sg, mq->bounce_sg_len);
+       local_irq_save(flags);
+       sg_copy_to_buffer(mq->bounce_sg, mq->bounce_sg_len,
+               mq->bounce_buf, mq->sg[0].length);
+       local_irq_restore(flags);
 }
 
+/*
+ * If reading, bounce the data from the buffer after the request
+ * has been handled by the host driver
+ */
 void mmc_queue_bounce_post(struct mmc_queue *mq)
 {
+       unsigned long flags;
+
        if (!mq->bounce_buf)
                return;
 
-       if (mq->bounce_sg_len == 1)
-               return;
        if (rq_data_dir(mq->req) != READ)
                return;
 
-       copy_sg(mq->bounce_sg, mq->bounce_sg_len, mq->sg, 1);
+       local_irq_save(flags);
+       sg_copy_from_buffer(mq->bounce_sg, mq->bounce_sg_len,
+               mq->bounce_buf, mq->sg[0].length);
+       local_irq_restore(flags);
 }
 
index 3f15eb204895f25cfaa75af21e8ee59dca16b8f2..99b20917cc0f9a677cfd414d27d70e01e183133d 100644 (file)
@@ -1043,7 +1043,7 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
                goto out6;
        }
 
-       platform_set_drvdata(pdev, mmc);
+       platform_set_drvdata(pdev, host);
 
        printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X"
                " (mode=%s)\n", pdev->id, host->iobase,
@@ -1087,13 +1087,10 @@ out0:
 
 static int __devexit au1xmmc_remove(struct platform_device *pdev)
 {
-       struct mmc_host *mmc = platform_get_drvdata(pdev);
-       struct au1xmmc_host *host;
-
-       if (mmc) {
-               host  = mmc_priv(mmc);
+       struct au1xmmc_host *host = platform_get_drvdata(pdev);
 
-               mmc_remove_host(mmc);
+       if (host) {
+               mmc_remove_host(host->mmc);
 
 #ifdef CONFIG_LEDS_CLASS
                if (host->platdata && host->platdata->led)
@@ -1101,8 +1098,8 @@ static int __devexit au1xmmc_remove(struct platform_device *pdev)
 #endif
 
                if (host->platdata && host->platdata->cd_setup &&
-                   !(mmc->caps & MMC_CAP_NEEDS_POLL))
-                       host->platdata->cd_setup(mmc, 0);
+                   !(host->mmc->caps & MMC_CAP_NEEDS_POLL))
+                       host->platdata->cd_setup(host->mmc, 0);
 
                au_writel(0, HOST_ENABLE(host));
                au_writel(0, HOST_CONFIG(host));
@@ -1122,16 +1119,49 @@ static int __devexit au1xmmc_remove(struct platform_device *pdev)
                release_resource(host->ioarea);
                kfree(host->ioarea);
 
-               mmc_free_host(mmc);
+               mmc_free_host(host->mmc);
+               platform_set_drvdata(pdev, NULL);
        }
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int au1xmmc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct au1xmmc_host *host = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = mmc_suspend_host(host->mmc, state);
+       if (ret)
+               return ret;
+
+       au_writel(0, HOST_CONFIG2(host));
+       au_writel(0, HOST_CONFIG(host));
+       au_writel(0xffffffff, HOST_STATUS(host));
+       au_writel(0, HOST_ENABLE(host));
+       au_sync();
+
+       return 0;
+}
+
+static int au1xmmc_resume(struct platform_device *pdev)
+{
+       struct au1xmmc_host *host = platform_get_drvdata(pdev);
+
+       au1xmmc_reset_controller(host);
+
+       return mmc_resume_host(host->mmc);
+}
+#else
+#define au1xmmc_suspend NULL
+#define au1xmmc_resume NULL
+#endif
+
 static struct platform_driver au1xmmc_driver = {
        .probe         = au1xmmc_probe,
        .remove        = au1xmmc_remove,
-       .suspend       = NULL,
-       .resume        = NULL,
+       .suspend       = au1xmmc_suspend,
+       .resume        = au1xmmc_resume,
        .driver        = {
                .name  = DRIVER_NAME,
                .owner = THIS_MODULE,
index d39f59738866c02e8712b9d3eb6cc686de808382..a8e18fe53077fee9023442745332706a9929888f 100644 (file)
@@ -177,7 +177,7 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
        if (dalgn)
                DALGN |= (1 << host->dma);
        else
-               DALGN &= (1 << host->dma);
+               DALGN &= ~(1 << host->dma);
        DDADR(host->dma) = host->sg_dma;
        DCSR(host->dma) = DCSR_RUN;
 }
index 6a1e4994b72465ee32314e10b8c3a1eae7927d51..be550c26da68d1cc82d2f25ac6880e84c6dae5b3 100644 (file)
@@ -1331,21 +1331,30 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
        return ret;
 }
 
+static void s3cmci_shutdown(struct platform_device *pdev)
+{
+       struct mmc_host *mmc = platform_get_drvdata(pdev);
+       struct s3cmci_host *host = mmc_priv(mmc);
+
+       if (host->irq_cd >= 0)
+               free_irq(host->irq_cd, host);
+
+       mmc_remove_host(mmc);
+       clk_disable(host->clk);
+}
+
 static int __devexit s3cmci_remove(struct platform_device *pdev)
 {
        struct mmc_host         *mmc  = platform_get_drvdata(pdev);
        struct s3cmci_host      *host = mmc_priv(mmc);
 
-       mmc_remove_host(mmc);
+       s3cmci_shutdown(pdev);
 
-       clk_disable(host->clk);
        clk_put(host->clk);
 
        tasklet_disable(&host->pio_tasklet);
        s3c2410_dma_free(S3CMCI_DMA, &s3cmci_dma_client);
 
-       if (host->irq_cd >= 0)
-               free_irq(host->irq_cd, host);
        free_irq(host->irq, host);
 
        iounmap(host->base);
@@ -1355,17 +1364,17 @@ static int __devexit s3cmci_remove(struct platform_device *pdev)
        return 0;
 }
 
-static int __devinit s3cmci_probe_2410(struct platform_device *dev)
+static int __devinit s3cmci_2410_probe(struct platform_device *dev)
 {
        return s3cmci_probe(dev, 0);
 }
 
-static int __devinit s3cmci_probe_2412(struct platform_device *dev)
+static int __devinit s3cmci_2412_probe(struct platform_device *dev)
 {
        return s3cmci_probe(dev, 1);
 }
 
-static int __devinit s3cmci_probe_2440(struct platform_device *dev)
+static int __devinit s3cmci_2440_probe(struct platform_device *dev)
 {
        return s3cmci_probe(dev, 1);
 }
@@ -1392,29 +1401,32 @@ static int s3cmci_resume(struct platform_device *dev)
 #endif /* CONFIG_PM */
 
 
-static struct platform_driver s3cmci_driver_2410 = {
+static struct platform_driver s3cmci_2410_driver = {
        .driver.name    = "s3c2410-sdi",
        .driver.owner   = THIS_MODULE,
-       .probe          = s3cmci_probe_2410,
+       .probe          = s3cmci_2410_probe,
        .remove         = __devexit_p(s3cmci_remove),
+       .shutdown       = s3cmci_shutdown,
        .suspend        = s3cmci_suspend,
        .resume         = s3cmci_resume,
 };
 
-static struct platform_driver s3cmci_driver_2412 = {
+static struct platform_driver s3cmci_2412_driver = {
        .driver.name    = "s3c2412-sdi",
        .driver.owner   = THIS_MODULE,
-       .probe          = s3cmci_probe_2412,
+       .probe          = s3cmci_2412_probe,
        .remove         = __devexit_p(s3cmci_remove),
+       .shutdown       = s3cmci_shutdown,
        .suspend        = s3cmci_suspend,
        .resume         = s3cmci_resume,
 };
 
-static struct platform_driver s3cmci_driver_2440 = {
+static struct platform_driver s3cmci_2440_driver = {
        .driver.name    = "s3c2440-sdi",
        .driver.owner   = THIS_MODULE,
-       .probe          = s3cmci_probe_2440,
+       .probe          = s3cmci_2440_probe,
        .remove         = __devexit_p(s3cmci_remove),
+       .shutdown       = s3cmci_shutdown,
        .suspend        = s3cmci_suspend,
        .resume         = s3cmci_resume,
 };
@@ -1422,17 +1434,17 @@ static struct platform_driver s3cmci_driver_2440 = {
 
 static int __init s3cmci_init(void)
 {
-       platform_driver_register(&s3cmci_driver_2410);
-       platform_driver_register(&s3cmci_driver_2412);
-       platform_driver_register(&s3cmci_driver_2440);
+       platform_driver_register(&s3cmci_2410_driver);
+       platform_driver_register(&s3cmci_2412_driver);
+       platform_driver_register(&s3cmci_2440_driver);
        return 0;
 }
 
 static void __exit s3cmci_exit(void)
 {
-       platform_driver_unregister(&s3cmci_driver_2410);
-       platform_driver_unregister(&s3cmci_driver_2412);
-       platform_driver_unregister(&s3cmci_driver_2440);
+       platform_driver_unregister(&s3cmci_2410_driver);
+       platform_driver_unregister(&s3cmci_2412_driver);
+       platform_driver_unregister(&s3cmci_2440_driver);
 }
 
 module_init(s3cmci_init);
index 17701c3da73326b9fa796086a617b253c506b1e5..c3a5db72ddd73b7fd48a29cd467c889ba36978a5 100644 (file)
@@ -173,119 +173,95 @@ static void sdhci_led_control(struct led_classdev *led,
  *                                                                           *
 \*****************************************************************************/
 
-static inline char* sdhci_sg_to_buffer(struct sdhci_host* host)
-{
-       return sg_virt(host->cur_sg);
-}
-
-static inline int sdhci_next_sg(struct sdhci_host* host)
-{
-       /*
-        * Skip to next SG entry.
-        */
-       host->cur_sg++;
-       host->num_sg--;
-
-       /*
-        * Any entries left?
-        */
-       if (host->num_sg > 0) {
-               host->offset = 0;
-               host->remain = host->cur_sg->length;
-       }
-
-       return host->num_sg;
-}
-
 static void sdhci_read_block_pio(struct sdhci_host *host)
 {
-       int blksize, chunk_remain;
-       u32 data;
-       char *buffer;
-       int size;
+       unsigned long flags;
+       size_t blksize, len, chunk;
+       u32 scratch;
+       u8 *buf;
 
        DBG("PIO reading\n");
 
        blksize = host->data->blksz;
-       chunk_remain = 0;
-       data = 0;
+       chunk = 0;
 
-       buffer = sdhci_sg_to_buffer(host) + host->offset;
+       local_irq_save(flags);
 
        while (blksize) {
-               if (chunk_remain == 0) {
-                       data = readl(host->ioaddr + SDHCI_BUFFER);
-                       chunk_remain = min(blksize, 4);
-               }
+               if (!sg_miter_next(&host->sg_miter))
+                       BUG();
 
-               size = min(host->remain, chunk_remain);
+               len = min(host->sg_miter.length, blksize);
 
-               chunk_remain -= size;
-               blksize -= size;
-               host->offset += size;
-               host->remain -= size;
+               blksize -= len;
+               host->sg_miter.consumed = len;
 
-               while (size) {
-                       *buffer = data & 0xFF;
-                       buffer++;
-                       data >>= 8;
-                       size--;
-               }
+               buf = host->sg_miter.addr;
 
-               if (host->remain == 0) {
-                       if (sdhci_next_sg(host) == 0) {
-                               BUG_ON(blksize != 0);
-                               return;
+               while (len) {
+                       if (chunk == 0) {
+                               scratch = readl(host->ioaddr + SDHCI_BUFFER);
+                               chunk = 4;
                        }
-                       buffer = sdhci_sg_to_buffer(host);
+
+                       *buf = scratch & 0xFF;
+
+                       buf++;
+                       scratch >>= 8;
+                       chunk--;
+                       len--;
                }
        }
+
+       sg_miter_stop(&host->sg_miter);
+
+       local_irq_restore(flags);
 }
 
 static void sdhci_write_block_pio(struct sdhci_host *host)
 {
-       int blksize, chunk_remain;
-       u32 data;
-       char *buffer;
-       int bytes, size;
+       unsigned long flags;
+       size_t blksize, len, chunk;
+       u32 scratch;
+       u8 *buf;
 
        DBG("PIO writing\n");
 
        blksize = host->data->blksz;
-       chunk_remain = 4;
-       data = 0;
+       chunk = 0;
+       scratch = 0;
 
-       bytes = 0;
-       buffer = sdhci_sg_to_buffer(host) + host->offset;
+       local_irq_save(flags);
 
        while (blksize) {
-               size = min(host->remain, chunk_remain);
-
-               chunk_remain -= size;
-               blksize -= size;
-               host->offset += size;
-               host->remain -= size;
-
-               while (size) {
-                       data >>= 8;
-                       data |= (u32)*buffer << 24;
-                       buffer++;
-                       size--;
-               }
+               if (!sg_miter_next(&host->sg_miter))
+                       BUG();
 
-               if (chunk_remain == 0) {
-                       writel(data, host->ioaddr + SDHCI_BUFFER);
-                       chunk_remain = min(blksize, 4);
-               }
+               len = min(host->sg_miter.length, blksize);
+
+               blksize -= len;
+               host->sg_miter.consumed = len;
+
+               buf = host->sg_miter.addr;
 
-               if (host->remain == 0) {
-                       if (sdhci_next_sg(host) == 0) {
-                               BUG_ON(blksize != 0);
-                               return;
+               while (len) {
+                       scratch |= (u32)*buf << (chunk * 8);
+
+                       buf++;
+                       chunk++;
+                       len--;
+
+                       if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
+                               writel(scratch, host->ioaddr + SDHCI_BUFFER);
+                               chunk = 0;
+                               scratch = 0;
                        }
-                       buffer = sdhci_sg_to_buffer(host);
                }
        }
+
+       sg_miter_stop(&host->sg_miter);
+
+       local_irq_restore(flags);
 }
 
 static void sdhci_transfer_pio(struct sdhci_host *host)
@@ -294,7 +270,7 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
 
        BUG_ON(!host->data);
 
-       if (host->num_sg == 0)
+       if (host->blocks == 0)
                return;
 
        if (host->data->flags & MMC_DATA_READ)
@@ -308,7 +284,8 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
                else
                        sdhci_write_block_pio(host);
 
-               if (host->num_sg == 0)
+               host->blocks--;
+               if (host->blocks == 0)
                        break;
        }
 
@@ -389,6 +366,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
                if (offset) {
                        if (data->flags & MMC_DATA_WRITE) {
                                buffer = sdhci_kmap_atomic(sg, &flags);
+                               WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
                                memcpy(align, buffer, offset);
                                sdhci_kunmap_atomic(buffer, &flags);
                        }
@@ -510,6 +488,7 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
                                size = 4 - (sg_dma_address(sg) & 0x3);
 
                                buffer = sdhci_kmap_atomic(sg, &flags);
+                               WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3));
                                memcpy(buffer, align, size);
                                sdhci_kunmap_atomic(buffer, &flags);
 
@@ -687,7 +666,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
                                WARN_ON(1);
                                host->flags &= ~SDHCI_USE_DMA;
                        } else {
-                               WARN_ON(count != 1);
+                               WARN_ON(sg_cnt != 1);
                                writel(sg_dma_address(data->sg),
                                        host->ioaddr + SDHCI_DMA_ADDRESS);
                        }
@@ -711,11 +690,9 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
        }
 
        if (!(host->flags & SDHCI_REQ_USE_DMA)) {
-               host->cur_sg = data->sg;
-               host->num_sg = data->sg_len;
-
-               host->offset = 0;
-               host->remain = host->cur_sg->length;
+               sg_miter_start(&host->sg_miter,
+                       data->sg, data->sg_len, SG_MITER_ATOMIC);
+               host->blocks = data->blocks;
        }
 
        /* We do not handle DMA boundaries, so set it to max (512 KiB) */
@@ -1581,9 +1558,15 @@ int sdhci_add_host(struct sdhci_host *host)
                }
        }
 
-       /* XXX: Hack to get MMC layer to avoid highmem */
-       if (!(host->flags & SDHCI_USE_DMA))
-               mmc_dev(host->mmc)->dma_mask = NULL;
+       /*
+        * If we use DMA, then it's up to the caller to set the DMA
+        * mask, but PIO does not need the hw shim so we set a new
+        * mask here in that case.
+        */
+       if (!(host->flags & SDHCI_USE_DMA)) {
+               host->dma_mask = DMA_BIT_MASK(64);
+               mmc_dev(host->mmc)->dma_mask = &host->dma_mask;
+       }
 
        host->max_clk =
                (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
index 5bb355281765daf7fa3ff2e8205cde8b23b9ad3c..a06bf8b89343f760ede4d573d8412d6bf0932957 100644 (file)
@@ -212,6 +212,7 @@ struct sdhci_host {
 
        /* Internal data */
        struct mmc_host         *mmc;           /* MMC structure */
+       u64                     dma_mask;       /* custom DMA mask */
 
 #ifdef CONFIG_LEDS_CLASS
        struct led_classdev     led;            /* LED control */
@@ -238,10 +239,8 @@ struct sdhci_host {
        struct mmc_data         *data;          /* Current data request */
        unsigned int            data_early:1;   /* Data finished before cmd */
 
-       struct scatterlist      *cur_sg;        /* We're working on this */
-       int                     num_sg;         /* Entries left */
-       int                     offset;         /* Offset into current sg */
-       int                     remain;         /* Bytes left in current */
+       struct sg_mapping_iter  sg_miter;       /* SG state for PIO */
+       unsigned int            blocks;         /* remaining PIO blocks */
 
        int                     sg_count;       /* Mapped sg entries */
 
index 519d942e7940c6167672c2d53829530e3e7d9fcc..7b72a1b36115f4b1bf4c581c6d67c1e6f6454566 100644 (file)
@@ -241,6 +241,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
 {
        struct block_device *bdev;
        struct block2mtd_dev *dev;
+       char *name;
 
        if (!devname)
                return NULL;
@@ -279,12 +280,13 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
 
        /* Setup the MTD structure */
        /* make the name contain the block device in */
-       dev->mtd.name = kmalloc(sizeof("block2mtd: ") + strlen(devname),
+       name = kmalloc(sizeof("block2mtd: ") + strlen(devname) + 1,
                        GFP_KERNEL);
-       if (!dev->mtd.name)
+       if (!name)
                goto devinit_err;
 
-       sprintf(dev->mtd.name, "block2mtd: %s", devname);
+       sprintf(name, "block2mtd: %s", devname);
+       dev->mtd.name = name;
 
        dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
        dev->mtd.erasesize = erase_size;
index 129d429cd2da5abc55ea1aa9c97a21041a5c85ff..aef9f4b687c9fdfafc7eb5fddfc6cdb98ea28cc1 100644 (file)
@@ -28,10 +28,13 @@ static void mtd_notify_add(struct mtd_info* mtd)
        if (!mtd)
                return;
 
-       device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), "mtd%d", mtd->index);
+       device_create_drvdata(mtd_class, NULL,
+                             MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
+                             NULL, "mtd%d", mtd->index);
 
-       device_create(mtd_class, NULL,
-                     MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), "mtd%dro", mtd->index);
+       device_create_drvdata(mtd_class, NULL,
+                             MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
+                             NULL, "mtd%dro", mtd->index);
 }
 
 static void mtd_notify_remove(struct mtd_info* mtd)
index cb663ef245d53cb5ec8e2c7212b76c0be7a156ab..fc8529bedfdf2076b6cc17b402d660d2d0d7d856 100644 (file)
 
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/gpio.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/mach-types.h>
 
 #include <asm/arch/hardware.h>
 #include <asm/arch/pxa-regs.h>
 #define GPIO_NAND_CS   (11)
 #define GPIO_NAND_RB   (89)
 
-/* This macro needed to ensure in-order operation of GPIO and local
- * bus. Without both asm command and dummy uncached read there're
- * states when NAND access is broken. I've looked for such macro(s) in
- * include/asm-arm but found nothing approptiate.
- * dmac_clean_range is close, but is makes cache invalidation
- * unnecessary here and it cannot be used in module
- */
-#define DRAIN_WB() \
-       do { \
-               unsigned char dummy; \
-               asm volatile ("mcr p15, 0, r0, c7, c10, 4":::"r0"); \
-               dummy=*((unsigned char*)UNCACHED_ADDR); \
-       } while(0)
-
 /* MTD structure for CM-X270 board */
 static struct mtd_info *cmx270_nand_mtd;
 
@@ -103,14 +91,14 @@ static int cmx270_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
 
 static inline void nand_cs_on(void)
 {
-       GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
+       gpio_set_value(GPIO_NAND_CS, 0);
 }
 
 static void nand_cs_off(void)
 {
-       DRAIN_WB();
+       dsb();
 
-       GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
+       gpio_set_value(GPIO_NAND_CS, 1);
 }
 
 /*
@@ -122,7 +110,7 @@ static void cmx270_hwcontrol(struct mtd_info *mtd, int dat,
        struct nand_chip* this = mtd->priv;
        unsigned int nandaddr = (unsigned int)this->IO_ADDR_W;
 
-       DRAIN_WB();
+       dsb();
 
        if (ctrl & NAND_CTRL_CHANGE) {
                if ( ctrl & NAND_ALE )
@@ -139,12 +127,12 @@ static void cmx270_hwcontrol(struct mtd_info *mtd, int dat,
                        nand_cs_off();
        }
 
-       DRAIN_WB();
+       dsb();
        this->IO_ADDR_W = (void __iomem*)nandaddr;
        if (dat != NAND_CMD_NONE)
                writel((dat << 16), this->IO_ADDR_W);
 
-       DRAIN_WB();
+       dsb();
 }
 
 /*
@@ -152,9 +140,9 @@ static void cmx270_hwcontrol(struct mtd_info *mtd, int dat,
  */
 static int cmx270_device_ready(struct mtd_info *mtd)
 {
-       DRAIN_WB();
+       dsb();
 
-       return (GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB));
+       return (gpio_get_value(GPIO_NAND_RB));
 }
 
 /*
@@ -168,20 +156,40 @@ static int cmx270_init(void)
        int mtd_parts_nb = 0;
        int ret;
 
+       if (!machine_is_armcore())
+               return -ENODEV;
+
+       ret = gpio_request(GPIO_NAND_CS, "NAND CS");
+       if (ret) {
+               pr_warning("CM-X270: failed to request NAND CS gpio\n");
+               return ret;
+       }
+
+       gpio_direction_output(GPIO_NAND_CS, 1);
+
+       ret = gpio_request(GPIO_NAND_RB, "NAND R/B");
+       if (ret) {
+               pr_warning("CM-X270: failed to request NAND R/B gpio\n");
+               goto err_gpio_request;
+       }
+
+       gpio_direction_input(GPIO_NAND_RB);
+
        /* Allocate memory for MTD device structure and private data */
        cmx270_nand_mtd = kzalloc(sizeof(struct mtd_info) +
                                  sizeof(struct nand_chip),
                                  GFP_KERNEL);
        if (!cmx270_nand_mtd) {
-               printk("Unable to allocate CM-X270 NAND MTD device structure.\n");
-               return -ENOMEM;
+               pr_debug("Unable to allocate CM-X270 NAND MTD device structure.\n");
+               ret = -ENOMEM;
+               goto err_kzalloc;
        }
 
        cmx270_nand_io = ioremap(PXA_CS1_PHYS, 12);
        if (!cmx270_nand_io) {
-               printk("Unable to ioremap NAND device\n");
+               pr_debug("Unable to ioremap NAND device\n");
                ret = -EINVAL;
-               goto err1;
+               goto err_ioremap;
        }
 
        /* Get pointer to private data */
@@ -209,9 +217,9 @@ static int cmx270_init(void)
 
        /* Scan to find existence of the device */
        if (nand_scan (cmx270_nand_mtd, 1)) {
-               printk(KERN_NOTICE "No NAND device\n");
+               pr_notice("No NAND device\n");
                ret = -ENXIO;
-               goto err2;
+               goto err_scan;
        }
 
 #ifdef CONFIG_MTD_CMDLINE_PARTS
@@ -229,18 +237,22 @@ static int cmx270_init(void)
        }
 
        /* Register the partitions */
-       printk(KERN_NOTICE "Using %s partition definition\n", part_type);
+       pr_notice("Using %s partition definition\n", part_type);
        ret = add_mtd_partitions(cmx270_nand_mtd, mtd_parts, mtd_parts_nb);
        if (ret)
-               goto err2;
+               goto err_scan;
 
        /* Return happy */
        return 0;
 
-err2:
+err_scan:
        iounmap(cmx270_nand_io);
-err1:
+err_ioremap:
        kfree(cmx270_nand_mtd);
+err_kzalloc:
+       gpio_free(GPIO_NAND_RB);
+err_gpio_request:
+       gpio_free(GPIO_NAND_CS);
 
        return ret;
 
@@ -255,6 +267,9 @@ static void cmx270_cleanup(void)
        /* Release resources, unregister device */
        nand_release(cmx270_nand_mtd);
 
+       gpio_free(GPIO_NAND_RB);
+       gpio_free(GPIO_NAND_CS);
+
        iounmap(cmx270_nand_io);
 
        /* Free the MTD device structure */
index aabad8ce7458c852a496422991c0683c0fe43d26..8db4e6b89482abc37c68c6cedf6396984b4f3a09 100644 (file)
@@ -1010,7 +1010,7 @@ static int __devinit vortex_probe1(struct device *gendev,
        static int printed_version;
        int retval, print_info;
        struct vortex_chip_info * const vci = &vortex_info_tbl[chip_idx];
-       char *print_name = "3c59x";
+       const char *print_name = "3c59x";
        struct pci_dev *pdev = NULL;
        struct eisa_device *edev = NULL;
        DECLARE_MAC_BUF(mac);
index 75317a14ad1cb26d6d3e030f48f0357dc6928789..8a5b0d293f7548dbcfaa0e6b9267c21a1d0cf4dc 100644 (file)
@@ -98,7 +98,6 @@
 #include <linux/compiler.h>
 #include <linux/pci.h>
 #include <linux/init.h>
-#include <linux/ioport.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
                                  NETIF_MSG_LINK)
 
 
-/* enable PIO instead of MMIO, if CONFIG_8139TOO_PIO is selected */
-#ifdef CONFIG_8139TOO_PIO
-#define USE_IO_OPS 1
-#endif
-
 /* define to 1, 2 or 3 to enable copious debugging info */
 #define RTL8139_DEBUG 0
 
 static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 
+/* Whether to use MMIO or PIO. Default to MMIO. */
+#ifdef CONFIG_8139TOO_PIO
+static int use_io = 1;
+#else
+static int use_io = 0;
+#endif
+
 /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
    The RTL chips use a 64 element hash table based on the Ethernet CRC.  */
 static int multicast_filter_limit = 32;
@@ -614,6 +615,8 @@ MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
+module_param(use_io, int, 0);
+MODULE_PARM_DESC(use_io, "Force use of I/O access mode. 0=MMIO 1=PIO");
 module_param(multicast_filter_limit, int, 0);
 module_param_array(media, int, NULL, 0);
 module_param_array(full_duplex, int, NULL, 0);
@@ -709,13 +712,8 @@ static void __rtl8139_cleanup_dev (struct net_device *dev)
        assert (tp->pci_dev != NULL);
        pdev = tp->pci_dev;
 
-#ifdef USE_IO_OPS
-       if (tp->mmio_addr)
-               ioport_unmap (tp->mmio_addr);
-#else
        if (tp->mmio_addr)
                pci_iounmap (pdev, tp->mmio_addr);
-#endif /* USE_IO_OPS */
 
        /* it's ok to call this even if we have no regions to free */
        pci_release_regions (pdev);
@@ -790,32 +788,33 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
        DPRINTK("PIO region size == 0x%02X\n", pio_len);
        DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
 
-#ifdef USE_IO_OPS
-       /* make sure PCI base addr 0 is PIO */
-       if (!(pio_flags & IORESOURCE_IO)) {
-               dev_err(&pdev->dev, "region #0 not a PIO resource, aborting\n");
-               rc = -ENODEV;
-               goto err_out;
-       }
-       /* check for weird/broken PCI region reporting */
-       if (pio_len < RTL_MIN_IO_SIZE) {
-               dev_err(&pdev->dev, "Invalid PCI I/O region size(s), aborting\n");
-               rc = -ENODEV;
-               goto err_out;
-       }
-#else
-       /* make sure PCI base addr 1 is MMIO */
-       if (!(mmio_flags & IORESOURCE_MEM)) {
-               dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n");
-               rc = -ENODEV;
-               goto err_out;
-       }
-       if (mmio_len < RTL_MIN_IO_SIZE) {
-               dev_err(&pdev->dev, "Invalid PCI mem region size(s), aborting\n");
-               rc = -ENODEV;
-               goto err_out;
+retry:
+       if (use_io) {
+               /* make sure PCI base addr 0 is PIO */
+               if (!(pio_flags & IORESOURCE_IO)) {
+                       dev_err(&pdev->dev, "region #0 not a PIO resource, aborting\n");
+                       rc = -ENODEV;
+                       goto err_out;
+               }
+               /* check for weird/broken PCI region reporting */
+               if (pio_len < RTL_MIN_IO_SIZE) {
+                       dev_err(&pdev->dev, "Invalid PCI I/O region size(s), aborting\n");
+                       rc = -ENODEV;
+                       goto err_out;
+               }
+       } else {
+               /* make sure PCI base addr 1 is MMIO */
+               if (!(mmio_flags & IORESOURCE_MEM)) {
+                       dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n");
+                       rc = -ENODEV;
+                       goto err_out;
+               }
+               if (mmio_len < RTL_MIN_IO_SIZE) {
+                       dev_err(&pdev->dev, "Invalid PCI mem region size(s), aborting\n");
+                       rc = -ENODEV;
+                       goto err_out;
+               }
        }
-#endif
 
        rc = pci_request_regions (pdev, DRV_NAME);
        if (rc)
@@ -825,28 +824,28 @@ static int __devinit rtl8139_init_board (struct pci_dev *pdev,
        /* enable PCI bus-mastering */
        pci_set_master (pdev);
 
-#ifdef USE_IO_OPS
-       ioaddr = ioport_map(pio_start, pio_len);
-       if (!ioaddr) {
-               dev_err(&pdev->dev, "cannot map PIO, aborting\n");
-               rc = -EIO;
-               goto err_out;
-       }
-       dev->base_addr = pio_start;
-       tp->mmio_addr = ioaddr;
-       tp->regs_len = pio_len;
-#else
-       /* ioremap MMIO region */
-       ioaddr = pci_iomap(pdev, 1, 0);
-       if (ioaddr == NULL) {
-               dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
-               rc = -EIO;
-               goto err_out;
+       if (use_io) {
+               ioaddr = pci_iomap(pdev, 0, 0);
+               if (!ioaddr) {
+                       dev_err(&pdev->dev, "cannot map PIO, aborting\n");
+                       rc = -EIO;
+                       goto err_out;
+               }
+               dev->base_addr = pio_start;
+               tp->regs_len = pio_len;
+       } else {
+               /* ioremap MMIO region */
+               ioaddr = pci_iomap(pdev, 1, 0);
+               if (ioaddr == NULL) {
+                       dev_err(&pdev->dev, "cannot remap MMIO, trying PIO\n");
+                       pci_release_regions(pdev);
+                       use_io = 1;
+                       goto retry;
+               }
+               dev->base_addr = (long) ioaddr;
+               tp->regs_len = mmio_len;
        }
-       dev->base_addr = (long) ioaddr;
        tp->mmio_addr = ioaddr;
-       tp->regs_len = mmio_len;
-#endif /* USE_IO_OPS */
 
        /* Bring old chips out of low-power mode. */
        RTL_W8 (HltClk, 'R');
@@ -952,6 +951,14 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
                           "Use the \"8139cp\" driver for improved performance and stability.\n");
        }
 
+       if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
+           pdev->device == PCI_DEVICE_ID_REALTEK_8139 &&
+           pdev->subsystem_vendor == PCI_VENDOR_ID_ATHEROS &&
+           pdev->subsystem_device == PCI_DEVICE_ID_REALTEK_8139) {
+               printk(KERN_INFO "8139too: OQO Model 2 detected. Forcing PIO\n");
+               use_io = 1;
+       }
+
        i = rtl8139_init_board (pdev, &dev);
        if (i < 0)
                return i;
@@ -2381,20 +2388,24 @@ static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
        np->msg_enable = datum;
 }
 
-/* TODO: we are too slack to do reg dumping for pio, for now */
-#ifdef CONFIG_8139TOO_PIO
-#define rtl8139_get_regs_len   NULL
-#define rtl8139_get_regs       NULL
-#else
 static int rtl8139_get_regs_len(struct net_device *dev)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
+       struct rtl8139_private *np;
+       /* TODO: we are too slack to do reg dumping for pio, for now */
+       if (use_io)
+               return 0;
+       np = netdev_priv(dev);
        return np->regs_len;
 }
 
 static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
+       struct rtl8139_private *np;
+
+       /* TODO: we are too slack to do reg dumping for pio, for now */
+       if (use_io)
+               return;
+       np = netdev_priv(dev);
 
        regs->version = RTL_REGS_VER;
 
@@ -2402,7 +2413,6 @@ static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs,
        memcpy_fromio(regbuf, np->mmio_addr, regs->len);
        spin_unlock_irq(&np->lock);
 }
-#endif /* CONFIG_8139TOO_MMIO */
 
 static int rtl8139_get_sset_count(struct net_device *dev, int sset)
 {
index 3e5e64c33e186779c8820959cd9a4f19ac769992..fa533c27052a727e757fea2687c1f3bbb93b0346 100644 (file)
@@ -1926,20 +1926,6 @@ config E1000
          To compile this driver as a module, choose M here. The module
          will be called e1000.
 
-config E1000_NAPI
-       bool "Use Rx Polling (NAPI)"
-       depends on E1000
-       help
-         NAPI is a new driver API designed to reduce CPU and interrupt load
-         when the driver is receiving lots of packets from the card. It is
-         still somewhat experimental and thus not yet enabled by default.
-
-         If your estimated Rx load is 10kpps or more, or if the card will be
-         deployed on potentially unfriendly networks (e.g. in a firewall),
-         then say Y here.
-
-         If in doubt, say N.
-
 config E1000_DISABLE_PACKET_SPLIT
        bool "Disable Packet Split for PCI express adapters"
        depends on E1000
@@ -2304,6 +2290,17 @@ config ATL1
          To compile this driver as a module, choose M here.  The module
          will be called atl1.
 
+config ATL1E
+       tristate "Atheros L1E Gigabit Ethernet support (EXPERIMENTAL)"
+       depends on PCI && EXPERIMENTAL
+       select CRC32
+       select MII
+       help
+         This driver supports the Atheros L1E gigabit ethernet adapter.
+
+         To compile this driver as a module, choose M here.  The module
+         will be called atl1e.
+
 endif # NETDEV_1000
 
 #
index 4b17a9ab7861a10551e98758ca91599319eb03ea..7629c9017215730dd7b30ed33343626eb43999b7 100644 (file)
@@ -15,6 +15,7 @@ obj-$(CONFIG_EHEA) += ehea/
 obj-$(CONFIG_CAN) += can/
 obj-$(CONFIG_BONDING) += bonding/
 obj-$(CONFIG_ATL1) += atlx/
+obj-$(CONFIG_ATL1E) += atl1e/
 obj-$(CONFIG_GIANFAR) += gianfar_driver.o
 obj-$(CONFIG_TEHUTI) += tehuti.o
 
index 1e39e78f1778c5228d7e6345005e900a347ccbff..ffae266e2d7fd66eac66d5a27200fcb411773ea2 100644 (file)
@@ -677,7 +677,7 @@ static void at91ether_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo
 {
        strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
        strlcpy(info->version, DRV_VERSION, sizeof(info->version));
-       strlcpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
+       strlcpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
 }
 
 static const struct ethtool_ops at91ether_ethtool_ops = {
@@ -820,7 +820,7 @@ static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
                lp->skb = skb;
                lp->skb_length = skb->len;
                lp->skb_physaddr = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE);
-               lp->stats.tx_bytes += skb->len;
+               dev->stats.tx_bytes += skb->len;
 
                /* Set address of the data in the Transmit Address register */
                at91_emac_write(AT91_EMAC_TAR, lp->skb_physaddr);
@@ -843,34 +843,33 @@ static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
  */
 static struct net_device_stats *at91ether_stats(struct net_device *dev)
 {
-       struct at91_private *lp = netdev_priv(dev);
        int ale, lenerr, seqe, lcol, ecol;
 
        if (netif_running(dev)) {
-               lp->stats.rx_packets += at91_emac_read(AT91_EMAC_OK);           /* Good frames received */
+               dev->stats.rx_packets += at91_emac_read(AT91_EMAC_OK);          /* Good frames received */
                ale = at91_emac_read(AT91_EMAC_ALE);
-               lp->stats.rx_frame_errors += ale;                               /* Alignment errors */
+               dev->stats.rx_frame_errors += ale;                              /* Alignment errors */
                lenerr = at91_emac_read(AT91_EMAC_ELR) + at91_emac_read(AT91_EMAC_USF);
-               lp->stats.rx_length_errors += lenerr;                           /* Excessive Length or Undersize Frame error */
+               dev->stats.rx_length_errors += lenerr;                          /* Excessive Length or Undersize Frame error */
                seqe = at91_emac_read(AT91_EMAC_SEQE);
-               lp->stats.rx_crc_errors += seqe;                                /* CRC error */
-               lp->stats.rx_fifo_errors += at91_emac_read(AT91_EMAC_DRFC);     /* Receive buffer not available */
-               lp->stats.rx_errors += (ale + lenerr + seqe
+               dev->stats.rx_crc_errors += seqe;                               /* CRC error */
+               dev->stats.rx_fifo_errors += at91_emac_read(AT91_EMAC_DRFC);    /* Receive buffer not available */
+               dev->stats.rx_errors += (ale + lenerr + seqe
                        + at91_emac_read(AT91_EMAC_CDE) + at91_emac_read(AT91_EMAC_RJB));
 
-               lp->stats.tx_packets += at91_emac_read(AT91_EMAC_FRA);          /* Frames successfully transmitted */
-               lp->stats.tx_fifo_errors += at91_emac_read(AT91_EMAC_TUE);      /* Transmit FIFO underruns */
-               lp->stats.tx_carrier_errors += at91_emac_read(AT91_EMAC_CSE);   /* Carrier Sense errors */
-               lp->stats.tx_heartbeat_errors += at91_emac_read(AT91_EMAC_SQEE);/* Heartbeat error */
+               dev->stats.tx_packets += at91_emac_read(AT91_EMAC_FRA);         /* Frames successfully transmitted */
+               dev->stats.tx_fifo_errors += at91_emac_read(AT91_EMAC_TUE);     /* Transmit FIFO underruns */
+               dev->stats.tx_carrier_errors += at91_emac_read(AT91_EMAC_CSE);  /* Carrier Sense errors */
+               dev->stats.tx_heartbeat_errors += at91_emac_read(AT91_EMAC_SQEE);/* Heartbeat error */
 
                lcol = at91_emac_read(AT91_EMAC_LCOL);
                ecol = at91_emac_read(AT91_EMAC_ECOL);
-               lp->stats.tx_window_errors += lcol;                     /* Late collisions */
-               lp->stats.tx_aborted_errors += ecol;                    /* 16 collisions */
+               dev->stats.tx_window_errors += lcol;                    /* Late collisions */
+               dev->stats.tx_aborted_errors += ecol;                   /* 16 collisions */
 
-               lp->stats.collisions += (at91_emac_read(AT91_EMAC_SCOL) + at91_emac_read(AT91_EMAC_MCOL) + lcol + ecol);
+               dev->stats.collisions += (at91_emac_read(AT91_EMAC_SCOL) + at91_emac_read(AT91_EMAC_MCOL) + lcol + ecol);
        }
-       return &lp->stats;
+       return &dev->stats;
 }
 
 /*
@@ -896,16 +895,16 @@ static void at91ether_rx(struct net_device *dev)
 
                        skb->protocol = eth_type_trans(skb, dev);
                        dev->last_rx = jiffies;
-                       lp->stats.rx_bytes += pktlen;
+                       dev->stats.rx_bytes += pktlen;
                        netif_rx(skb);
                }
                else {
-                       lp->stats.rx_dropped += 1;
+                       dev->stats.rx_dropped += 1;
                        printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
                }
 
                if (dlist->descriptors[lp->rxBuffIndex].size & EMAC_MULTICAST)
-                       lp->stats.multicast++;
+                       dev->stats.multicast++;
 
                dlist->descriptors[lp->rxBuffIndex].addr &= ~EMAC_DESC_DONE;    /* reset ownership bit */
                if (lp->rxBuffIndex == MAX_RX_DESCR-1)                          /* wrap after last buffer */
@@ -934,7 +933,7 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
        if (intstatus & AT91_EMAC_TCOM) {       /* Transmit complete */
                /* The TCOM bit is set even if the transmission failed. */
                if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY))
-                       lp->stats.tx_errors += 1;
+                       dev->stats.tx_errors += 1;
 
                if (lp->skb) {
                        dev_kfree_skb_irq(lp->skb);
index a38fd2d053a6171480972ca5f587bc7aa1538b54..353f4dab62be492b0310ec497a1b8481d9bb63ea 100644 (file)
@@ -84,7 +84,6 @@ struct recv_desc_bufs
 
 struct at91_private
 {
-       struct net_device_stats stats;
        struct mii_if_info mii;                 /* ethtool support */
        struct at91_eth_data board_data;        /* board-specific configuration */
        struct clk *ether_clk;                  /* clock */
index ecd8fc6146e9faa710351eb8765c8538807bcc51..7a14980f3472d133da546174cef0f6365ffb4772 100644 (file)
@@ -848,7 +848,7 @@ static int ep93xx_eth_probe(struct platform_device *pdev)
 
        ep->res = request_mem_region(pdev->resource[0].start,
                        pdev->resource[0].end - pdev->resource[0].start + 1,
-                       pdev->dev.bus_id);
+                       dev_name(&pdev->dev));
        if (ep->res == NULL) {
                dev_err(&pdev->dev, "Could not reserve memory region\n");
                err = -ENOMEM;
index e9d15eccad082cf91f72f8115ae27190a7a8c1b3..5c5f1e470d3c2d05fcc910fb97917cb487bf7533 100644 (file)
@@ -535,7 +535,7 @@ static int __init etherh_addr(char *addr, struct expansion_card *ec)
        
        if (!ecard_readchunk(&cd, ec, 0xf5, 0)) {
                printk(KERN_ERR "%s: unable to read podule description string\n",
-                      ec->dev.bus_id);
+                      dev_name(&ec->dev));
                goto no_addr;
        }
 
@@ -554,7 +554,7 @@ static int __init etherh_addr(char *addr, struct expansion_card *ec)
        }
 
        printk(KERN_ERR "%s: unable to parse MAC address: %s\n",
-              ec->dev.bus_id, cd.d.string);
+              dev_name(&ec->dev), cd.d.string);
 
  no_addr:
        return -ENODEV;
@@ -585,7 +585,7 @@ static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i
 {
        strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
        strlcpy(info->version, DRV_VERSION, sizeof(info->version));
-       strlcpy(info->bus_info, dev->dev.parent->bus_id,
+       strlcpy(info->bus_info, dev_name(dev->dev.parent),
                sizeof(info->bus_info));
 }
 
diff --git a/drivers/net/atl1e/Makefile b/drivers/net/atl1e/Makefile
new file mode 100644 (file)
index 0000000..bc11be8
--- /dev/null
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ATL1E)    += atl1e.o
+atl1e-objs             += atl1e_main.o atl1e_hw.o atl1e_ethtool.o atl1e_param.o
diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h
new file mode 100644 (file)
index 0000000..b645fa0
--- /dev/null
@@ -0,0 +1,503 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ * Copyright(c) 2007 xiong huang <xiong.huang@atheros.com>
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public 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 _ATL1E_H_
+#define _ATL1E_H_
+
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/udp.h>
+#include <linux/mii.h>
+#include <linux/io.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/tcp.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/workqueue.h>
+#include <net/checksum.h>
+#include <net/ip6_checksum.h>
+
+#include "atl1e_hw.h"
+
+#define PCI_REG_COMMAND         0x04    /* PCI Command Register */
+#define CMD_IO_SPACE    0x0001
+#define CMD_MEMORY_SPACE 0x0002
+#define CMD_BUS_MASTER   0x0004
+
+#define BAR_0   0
+#define BAR_1   1
+#define BAR_5   5
+
+/* Wake Up Filter Control */
+#define AT_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
+#define AT_WUFC_MAG  0x00000002 /* Magic Packet Wakeup Enable */
+#define AT_WUFC_EX   0x00000004 /* Directed Exact Wakeup Enable */
+#define AT_WUFC_MC   0x00000008 /* Multicast Wakeup Enable */
+#define AT_WUFC_BC   0x00000010 /* Broadcast Wakeup Enable */
+
+#define SPEED_0                   0xffff
+#define HALF_DUPLEX        1
+#define FULL_DUPLEX        2
+
+/* Error Codes */
+#define AT_ERR_EEPROM      1
+#define AT_ERR_PHY         2
+#define AT_ERR_CONFIG      3
+#define AT_ERR_PARAM       4
+#define AT_ERR_MAC_TYPE    5
+#define AT_ERR_PHY_TYPE    6
+#define AT_ERR_PHY_SPEED   7
+#define AT_ERR_PHY_RES     8
+#define AT_ERR_TIMEOUT     9
+
+#define MAX_JUMBO_FRAME_SIZE 0x2000
+
+#define AT_VLAN_TAG_TO_TPD_TAG(_vlan, _tpd)    \
+       _tpd = (((_vlan) << (4)) | (((_vlan) >> 13) & 7) |\
+                (((_vlan) >> 9) & 8))
+
+#define AT_TPD_TAG_TO_VLAN_TAG(_tpd, _vlan)    \
+       _vlan = (((_tpd) >> 8) | (((_tpd) & 0x77) << 9) |\
+                  (((_tdp) & 0x88) << 5))
+
+#define AT_MAX_RECEIVE_QUEUE    4
+#define AT_PAGE_NUM_PER_QUEUE   2
+
+#define AT_DMA_HI_ADDR_MASK     0xffffffff00000000ULL
+#define AT_DMA_LO_ADDR_MASK     0x00000000ffffffffULL
+
+#define AT_TX_WATCHDOG  (5 * HZ)
+#define AT_MAX_INT_WORK                10
+#define AT_TWSI_EEPROM_TIMEOUT         100
+#define AT_HW_MAX_IDLE_DELAY   10
+#define AT_SUSPEND_LINK_TIMEOUT 28
+
+#define AT_REGS_LEN    75
+#define AT_EEPROM_LEN  512
+#define AT_ADV_MASK    (ADVERTISE_10_HALF  |\
+                        ADVERTISE_10_FULL  |\
+                        ADVERTISE_100_HALF |\
+                        ADVERTISE_100_FULL |\
+                        ADVERTISE_1000_FULL)
+
+/* tpd word 2 */
+#define TPD_BUFLEN_MASK        0x3FFF
+#define TPD_BUFLEN_SHIFT        0
+#define TPD_DMAINT_MASK                0x0001
+#define TPD_DMAINT_SHIFT        14
+#define TPD_PKTNT_MASK          0x0001
+#define TPD_PKTINT_SHIFT        15
+#define TPD_VLANTAG_MASK        0xFFFF
+#define TPD_VLAN_SHIFT          16
+
+/* tpd word 3 bits 0:4 */
+#define TPD_EOP_MASK            0x0001
+#define TPD_EOP_SHIFT           0
+#define TPD_IP_VERSION_MASK    0x0001
+#define TPD_IP_VERSION_SHIFT   1       /* 0 : IPV4, 1 : IPV6 */
+#define TPD_INS_VL_TAG_MASK    0x0001
+#define TPD_INS_VL_TAG_SHIFT   2
+#define TPD_CC_SEGMENT_EN_MASK 0x0001
+#define TPD_CC_SEGMENT_EN_SHIFT        3
+#define TPD_SEGMENT_EN_MASK     0x0001
+#define TPD_SEGMENT_EN_SHIFT    4
+
+/* tdp word 3 bits 5:7 if ip version is 0 */
+#define TPD_IP_CSUM_MASK        0x0001
+#define TPD_IP_CSUM_SHIFT       5
+#define TPD_TCP_CSUM_MASK       0x0001
+#define TPD_TCP_CSUM_SHIFT      6
+#define TPD_UDP_CSUM_MASK       0x0001
+#define TPD_UDP_CSUM_SHIFT      7
+
+/* tdp word 3 bits 5:7 if ip version is 1 */
+#define TPD_V6_IPHLLO_MASK     0x0007
+#define TPD_V6_IPHLLO_SHIFT    7
+
+/* tpd word 3 bits 8:9 bit */
+#define TPD_VL_TAGGED_MASK      0x0001
+#define TPD_VL_TAGGED_SHIFT     8
+#define TPD_ETHTYPE_MASK        0x0001
+#define TPD_ETHTYPE_SHIFT       9
+
+/* tdp word 3 bits 10:13 if ip version is 0 */
+#define TDP_V4_IPHL_MASK       0x000F
+#define TPD_V4_IPHL_SHIFT      10
+
+/* tdp word 3 bits 10:13 if ip version is 1 */
+#define TPD_V6_IPHLHI_MASK     0x000F
+#define TPD_V6_IPHLHI_SHIFT    10
+
+/* tpd word 3 bit 14:31 if segment enabled */
+#define TPD_TCPHDRLEN_MASK      0x000F
+#define TPD_TCPHDRLEN_SHIFT     14
+#define TPD_HDRFLAG_MASK        0x0001
+#define TPD_HDRFLAG_SHIFT       18
+#define TPD_MSS_MASK            0x1FFF
+#define TPD_MSS_SHIFT           19
+
+/* tdp word 3 bit 16:31 if custom csum enabled */
+#define TPD_PLOADOFFSET_MASK    0x00FF
+#define TPD_PLOADOFFSET_SHIFT   16
+#define TPD_CCSUMOFFSET_MASK    0x00FF
+#define TPD_CCSUMOFFSET_SHIFT   24
+
+struct atl1e_tpd_desc {
+       __le64 buffer_addr;
+       __le32 word2;
+       __le32 word3;
+};
+
+/* how about 0x2000 */
+#define MAX_TX_BUF_LEN      0x2000
+#define MAX_TX_BUF_SHIFT    13
+/*#define MAX_TX_BUF_LEN  0x3000 */
+
+/* rrs word 1 bit 0:31 */
+#define RRS_RX_CSUM_MASK       0xFFFF
+#define RRS_RX_CSUM_SHIFT      0
+#define RRS_PKT_SIZE_MASK      0x3FFF
+#define RRS_PKT_SIZE_SHIFT     16
+#define RRS_CPU_NUM_MASK       0x0003
+#define        RRS_CPU_NUM_SHIFT       30
+
+#define        RRS_IS_RSS_IPV4         0x0001
+#define RRS_IS_RSS_IPV4_TCP    0x0002
+#define RRS_IS_RSS_IPV6                0x0004
+#define RRS_IS_RSS_IPV6_TCP    0x0008
+#define RRS_IS_IPV6            0x0010
+#define RRS_IS_IP_FRAG         0x0020
+#define RRS_IS_IP_DF           0x0040
+#define RRS_IS_802_3           0x0080
+#define RRS_IS_VLAN_TAG                0x0100
+#define RRS_IS_ERR_FRAME       0x0200
+#define RRS_IS_IPV4            0x0400
+#define RRS_IS_UDP             0x0800
+#define RRS_IS_TCP             0x1000
+#define RRS_IS_BCAST           0x2000
+#define RRS_IS_MCAST           0x4000
+#define RRS_IS_PAUSE           0x8000
+
+#define RRS_ERR_BAD_CRC                0x0001
+#define RRS_ERR_CODE           0x0002
+#define RRS_ERR_DRIBBLE                0x0004
+#define RRS_ERR_RUNT           0x0008
+#define RRS_ERR_RX_OVERFLOW    0x0010
+#define RRS_ERR_TRUNC          0x0020
+#define RRS_ERR_IP_CSUM                0x0040
+#define RRS_ERR_L4_CSUM                0x0080
+#define RRS_ERR_LENGTH         0x0100
+#define RRS_ERR_DES_ADDR       0x0200
+
+struct atl1e_recv_ret_status {
+       u16 seq_num;
+       u16 hash_lo;
+       __le32  word1;
+       u16 pkt_flag;
+       u16 err_flag;
+       u16 hash_hi;
+       u16 vtag;
+};
+
+enum atl1e_dma_req_block {
+       atl1e_dma_req_128 = 0,
+       atl1e_dma_req_256 = 1,
+       atl1e_dma_req_512 = 2,
+       atl1e_dma_req_1024 = 3,
+       atl1e_dma_req_2048 = 4,
+       atl1e_dma_req_4096 = 5
+};
+
+enum atl1e_rrs_type {
+       atl1e_rrs_disable = 0,
+       atl1e_rrs_ipv4 = 1,
+       atl1e_rrs_ipv4_tcp = 2,
+       atl1e_rrs_ipv6 = 4,
+       atl1e_rrs_ipv6_tcp = 8
+};
+
+enum atl1e_nic_type {
+       athr_l1e = 0,
+       athr_l2e_revA = 1,
+       athr_l2e_revB = 2
+};
+
+struct atl1e_hw_stats {
+       /* rx */
+       unsigned long rx_ok;          /* The number of good packet received. */
+       unsigned long rx_bcast;       /* The number of good broadcast packet received. */
+       unsigned long rx_mcast;       /* The number of good multicast packet received. */
+       unsigned long rx_pause;       /* The number of Pause packet received. */
+       unsigned long rx_ctrl;        /* The number of Control packet received other than Pause frame. */
+       unsigned long rx_fcs_err;     /* The number of packets with bad FCS. */
+       unsigned long rx_len_err;     /* The number of packets with mismatch of length field and actual size. */
+       unsigned long rx_byte_cnt;    /* The number of bytes of good packet received. FCS is NOT included. */
+       unsigned long rx_runt;        /* The number of packets received that are less than 64 byte long and with good FCS. */
+       unsigned long rx_frag;        /* The number of packets received that are less than 64 byte long and with bad FCS. */
+       unsigned long rx_sz_64;       /* The number of good and bad packets received that are 64 byte long. */
+       unsigned long rx_sz_65_127;   /* The number of good and bad packets received that are between 65 and 127-byte long. */
+       unsigned long rx_sz_128_255;  /* The number of good and bad packets received that are between 128 and 255-byte long. */
+       unsigned long rx_sz_256_511;  /* The number of good and bad packets received that are between 256 and 511-byte long. */
+       unsigned long rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */
+       unsigned long rx_sz_1024_1518;    /* The number of good and bad packets received that are between 1024 and 1518-byte long. */
+       unsigned long rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */
+       unsigned long rx_sz_ov;       /* The number of good and bad packets received that are more than MTU size truncated by Selene. */
+       unsigned long rx_rxf_ov;      /* The number of frame dropped due to occurrence of RX FIFO overflow. */
+       unsigned long rx_rrd_ov;      /* The number of frame dropped due to occurrence of RRD overflow. */
+       unsigned long rx_align_err;   /* Alignment Error */
+       unsigned long rx_bcast_byte_cnt;  /* The byte count of broadcast packet received, excluding FCS. */
+       unsigned long rx_mcast_byte_cnt;  /* The byte count of multicast packet received, excluding FCS. */
+       unsigned long rx_err_addr;    /* The number of packets dropped due to address filtering. */
+
+       /* tx */
+       unsigned long tx_ok;      /* The number of good packet transmitted. */
+       unsigned long tx_bcast;       /* The number of good broadcast packet transmitted. */
+       unsigned long tx_mcast;       /* The number of good multicast packet transmitted. */
+       unsigned long tx_pause;       /* The number of Pause packet transmitted. */
+       unsigned long tx_exc_defer;   /* The number of packets transmitted with excessive deferral. */
+       unsigned long tx_ctrl;        /* The number of packets transmitted is a control frame, excluding Pause frame. */
+       unsigned long tx_defer;       /* The number of packets transmitted that is deferred. */
+       unsigned long tx_byte_cnt;    /* The number of bytes of data transmitted. FCS is NOT included. */
+       unsigned long tx_sz_64;       /* The number of good and bad packets transmitted that are 64 byte long. */
+       unsigned long tx_sz_65_127;   /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */
+       unsigned long tx_sz_128_255;  /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */
+       unsigned long tx_sz_256_511;  /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */
+       unsigned long tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */
+       unsigned long tx_sz_1024_1518;    /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */
+       unsigned long tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */
+       unsigned long tx_1_col;       /* The number of packets subsequently transmitted successfully with a single prior collision. */
+       unsigned long tx_2_col;       /* The number of packets subsequently transmitted successfully with multiple prior collisions. */
+       unsigned long tx_late_col;    /* The number of packets transmitted with late collisions. */
+       unsigned long tx_abort_col;   /* The number of transmit packets aborted due to excessive collisions. */
+       unsigned long tx_underrun;    /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */
+       unsigned long tx_rd_eop;      /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */
+       unsigned long tx_len_err;     /* The number of transmit packets with length field does NOT match the actual frame size. */
+       unsigned long tx_trunc;       /* The number of transmit packets truncated due to size exceeding MTU. */
+       unsigned long tx_bcast_byte;  /* The byte count of broadcast packet transmitted, excluding FCS. */
+       unsigned long tx_mcast_byte;  /* The byte count of multicast packet transmitted, excluding FCS. */
+};
+
+struct atl1e_hw {
+       u8 __iomem      *hw_addr;            /* inner register address */
+       resource_size_t mem_rang;
+       struct atl1e_adapter *adapter;
+       enum atl1e_nic_type  nic_type;
+       u16 device_id;
+       u16 vendor_id;
+       u16 subsystem_id;
+       u16 subsystem_vendor_id;
+       u8  revision_id;
+       u16 pci_cmd_word;
+       u8 mac_addr[ETH_ALEN];
+       u8 perm_mac_addr[ETH_ALEN];
+       u8 preamble_len;
+       u16 max_frame_size;
+       u16 rx_jumbo_th;
+       u16 tx_jumbo_th;
+
+       u16 media_type;
+#define MEDIA_TYPE_AUTO_SENSOR  0
+#define MEDIA_TYPE_100M_FULL    1
+#define MEDIA_TYPE_100M_HALF    2
+#define MEDIA_TYPE_10M_FULL     3
+#define MEDIA_TYPE_10M_HALF     4
+
+       u16 autoneg_advertised;
+#define ADVERTISE_10_HALF               0x0001
+#define ADVERTISE_10_FULL               0x0002
+#define ADVERTISE_100_HALF              0x0004
+#define ADVERTISE_100_FULL              0x0008
+#define ADVERTISE_1000_HALF             0x0010 /* Not used, just FYI */
+#define ADVERTISE_1000_FULL             0x0020
+       u16 mii_autoneg_adv_reg;
+       u16 mii_1000t_ctrl_reg;
+
+       u16 imt;        /* Interrupt Moderator timer ( 2us resolution) */
+       u16 ict;        /* Interrupt Clear timer (2us resolution) */
+       u32 smb_timer;
+       u16 rrd_thresh; /* Threshold of number of RRD produced to trigger
+                         interrupt request */
+       u16 tpd_thresh;
+       u16 rx_count_down; /* 2us resolution */
+       u16 tx_count_down;
+
+       u8 tpd_burst;   /* Number of TPD to prefetch in cache-aligned burst. */
+       enum atl1e_rrs_type rrs_type;
+       u32 base_cpu;
+       u32 indirect_tab;
+
+       enum atl1e_dma_req_block dmar_block;
+       enum atl1e_dma_req_block dmaw_block;
+       u8 dmaw_dly_cnt;
+       u8 dmar_dly_cnt;
+
+       bool phy_configured;
+       bool re_autoneg;
+       bool emi_ca;
+};
+
+/*
+ * wrapper around a pointer to a socket buffer,
+ * so a DMA handle can be stored along with the buffer
+ */
+struct atl1e_tx_buffer {
+       struct sk_buff *skb;
+       u16 length;
+       dma_addr_t dma;
+};
+
+struct atl1e_rx_page {
+       dma_addr_t      dma;    /* receive rage DMA address */
+       u8              *addr;   /* receive rage virtual address */
+       dma_addr_t      write_offset_dma;  /* the DMA address which contain the
+                                             receive data offset in the page */
+       u32             *write_offset_addr; /* the virtaul address which contain
+                                            the receive data offset in the page */
+       u32             read_offset;       /* the offset where we have read */
+};
+
+struct atl1e_rx_page_desc {
+       struct atl1e_rx_page   rx_page[AT_PAGE_NUM_PER_QUEUE];
+       u8  rx_using;
+       u16 rx_nxseq;
+};
+
+/* transmit packet descriptor (tpd) ring */
+struct atl1e_tx_ring {
+       struct atl1e_tpd_desc *desc;  /* descriptor ring virtual address  */
+       dma_addr_t         dma;    /* descriptor ring physical address */
+       u16                count;  /* the count of transmit rings  */
+       rwlock_t           tx_lock;
+       u16                next_to_use;
+       atomic_t           next_to_clean;
+       struct atl1e_tx_buffer *tx_buffer;
+       dma_addr_t         cmb_dma;
+       u32                *cmb;
+};
+
+/* receive packet descriptor ring */
+struct atl1e_rx_ring {
+       void            *desc;
+       dma_addr_t      dma;
+       int             size;
+       u32             page_size; /* bytes length of rxf page */
+       u32             real_page_size; /* real_page_size = page_size + jumbo + aliagn */
+       struct atl1e_rx_page_desc       rx_page_desc[AT_MAX_RECEIVE_QUEUE];
+};
+
+/* board specific private data structure */
+struct atl1e_adapter {
+       struct net_device   *netdev;
+       struct pci_dev      *pdev;
+       struct vlan_group   *vlgrp;
+       struct napi_struct  napi;
+       struct mii_if_info  mii;    /* MII interface info */
+       struct atl1e_hw        hw;
+       struct atl1e_hw_stats  hw_stats;
+       struct net_device_stats net_stats;
+
+       bool have_msi;
+       u32 wol;
+       u16 link_speed;
+       u16 link_duplex;
+
+       spinlock_t mdio_lock;
+       spinlock_t tx_lock;
+       atomic_t irq_sem;
+
+       struct work_struct reset_task;
+       struct work_struct link_chg_task;
+       struct timer_list watchdog_timer;
+       struct timer_list phy_config_timer;
+
+       /* All Descriptor memory */
+       dma_addr_t      ring_dma;
+       void            *ring_vir_addr;
+       int             ring_size;
+
+       struct atl1e_tx_ring tx_ring;
+       struct atl1e_rx_ring rx_ring;
+       int num_rx_queues;
+       unsigned long flags;
+#define __AT_TESTING        0x0001
+#define __AT_RESETTING      0x0002
+#define __AT_DOWN           0x0003
+
+       u32 bd_number;     /* board number;*/
+       u32 pci_state[16];
+       u32 *config_space;
+};
+
+#define AT_WRITE_REG(a, reg, value) ( \
+               writel((value), ((a)->hw_addr + reg)))
+
+#define AT_WRITE_FLUSH(a) (\
+               readl((a)->hw_addr))
+
+#define AT_READ_REG(a, reg) ( \
+               readl((a)->hw_addr + reg))
+
+#define AT_WRITE_REGB(a, reg, value) (\
+               writeb((value), ((a)->hw_addr + reg)))
+
+#define AT_READ_REGB(a, reg) (\
+               readb((a)->hw_addr + reg))
+
+#define AT_WRITE_REGW(a, reg, value) (\
+               writew((value), ((a)->hw_addr + reg)))
+
+#define AT_READ_REGW(a, reg) (\
+               readw((a)->hw_addr + reg))
+
+#define AT_WRITE_REG_ARRAY(a, reg, offset, value) ( \
+               writel((value), (((a)->hw_addr + reg) + ((offset) << 2))))
+
+#define AT_READ_REG_ARRAY(a, reg, offset) ( \
+               readl(((a)->hw_addr + reg) + ((offset) << 2)))
+
+extern char atl1e_driver_name[];
+extern char atl1e_driver_version[];
+
+extern void atl1e_check_options(struct atl1e_adapter *adapter);
+extern int atl1e_up(struct atl1e_adapter *adapter);
+extern void atl1e_down(struct atl1e_adapter *adapter);
+extern void atl1e_reinit_locked(struct atl1e_adapter *adapter);
+extern s32 atl1e_reset_hw(struct atl1e_hw *hw);
+extern void atl1e_set_ethtool_ops(struct net_device *netdev);
+#endif /* _ATL1_E_H_ */
diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c
new file mode 100644 (file)
index 0000000..cdc3b85
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public 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/netdevice.h>
+#include <linux/ethtool.h>
+
+#include "atl1e.h"
+
+static int atl1e_get_settings(struct net_device *netdev,
+                             struct ethtool_cmd *ecmd)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+
+       ecmd->supported = (SUPPORTED_10baseT_Half  |
+                          SUPPORTED_10baseT_Full  |
+                          SUPPORTED_100baseT_Half |
+                          SUPPORTED_100baseT_Full |
+                          SUPPORTED_Autoneg       |
+                          SUPPORTED_TP);
+       if (hw->nic_type == athr_l1e)
+               ecmd->supported |= SUPPORTED_1000baseT_Full;
+
+       ecmd->advertising = ADVERTISED_TP;
+
+       ecmd->advertising |= ADVERTISED_Autoneg;
+       ecmd->advertising |= hw->autoneg_advertised;
+
+       ecmd->port = PORT_TP;
+       ecmd->phy_address = 0;
+       ecmd->transceiver = XCVR_INTERNAL;
+
+       if (adapter->link_speed != SPEED_0) {
+               ecmd->speed = adapter->link_speed;
+               if (adapter->link_duplex == FULL_DUPLEX)
+                       ecmd->duplex = DUPLEX_FULL;
+               else
+                       ecmd->duplex = DUPLEX_HALF;
+       } else {
+               ecmd->speed = -1;
+               ecmd->duplex = -1;
+       }
+
+       ecmd->autoneg = AUTONEG_ENABLE;
+       return 0;
+}
+
+static int atl1e_set_settings(struct net_device *netdev,
+                             struct ethtool_cmd *ecmd)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+
+       while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+               msleep(1);
+
+       if (ecmd->autoneg == AUTONEG_ENABLE) {
+               u16 adv4, adv9;
+
+               if ((ecmd->advertising&ADVERTISE_1000_FULL)) {
+                       if (hw->nic_type == athr_l1e) {
+                               hw->autoneg_advertised =
+                                       ecmd->advertising & AT_ADV_MASK;
+                       } else {
+                               clear_bit(__AT_RESETTING, &adapter->flags);
+                               return -EINVAL;
+                       }
+               } else if (ecmd->advertising&ADVERTISE_1000_HALF) {
+                       clear_bit(__AT_RESETTING, &adapter->flags);
+                       return -EINVAL;
+               } else {
+                       hw->autoneg_advertised =
+                               ecmd->advertising & AT_ADV_MASK;
+               }
+               ecmd->advertising = hw->autoneg_advertised |
+                                   ADVERTISED_TP | ADVERTISED_Autoneg;
+
+               adv4 = hw->mii_autoneg_adv_reg & ~MII_AR_SPEED_MASK;
+               adv9 = hw->mii_1000t_ctrl_reg & ~MII_AT001_CR_1000T_SPEED_MASK;
+               if (hw->autoneg_advertised & ADVERTISE_10_HALF)
+                       adv4 |= MII_AR_10T_HD_CAPS;
+               if (hw->autoneg_advertised & ADVERTISE_10_FULL)
+                       adv4 |= MII_AR_10T_FD_CAPS;
+               if (hw->autoneg_advertised & ADVERTISE_100_HALF)
+                       adv4 |= MII_AR_100TX_HD_CAPS;
+               if (hw->autoneg_advertised & ADVERTISE_100_FULL)
+                       adv4 |= MII_AR_100TX_FD_CAPS;
+               if (hw->autoneg_advertised & ADVERTISE_1000_FULL)
+                       adv9 |= MII_AT001_CR_1000T_FD_CAPS;
+
+               if (adv4 != hw->mii_autoneg_adv_reg ||
+                               adv9 != hw->mii_1000t_ctrl_reg) {
+                       hw->mii_autoneg_adv_reg = adv4;
+                       hw->mii_1000t_ctrl_reg = adv9;
+                       hw->re_autoneg = true;
+               }
+
+       } else {
+               clear_bit(__AT_RESETTING, &adapter->flags);
+               return -EINVAL;
+       }
+
+       /* reset the link */
+
+       if (netif_running(adapter->netdev)) {
+               atl1e_down(adapter);
+               atl1e_up(adapter);
+       } else
+               atl1e_reset_hw(&adapter->hw);
+
+       clear_bit(__AT_RESETTING, &adapter->flags);
+       return 0;
+}
+
+static u32 atl1e_get_tx_csum(struct net_device *netdev)
+{
+       return (netdev->features & NETIF_F_HW_CSUM) != 0;
+}
+
+static u32 atl1e_get_msglevel(struct net_device *netdev)
+{
+#ifdef DBG
+       return 1;
+#else
+       return 0;
+#endif
+}
+
+static void atl1e_set_msglevel(struct net_device *netdev, u32 data)
+{
+}
+
+static int atl1e_get_regs_len(struct net_device *netdev)
+{
+       return AT_REGS_LEN * sizeof(u32);
+}
+
+static void atl1e_get_regs(struct net_device *netdev,
+                          struct ethtool_regs *regs, void *p)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+       u32 *regs_buff = p;
+       u16 phy_data;
+
+       memset(p, 0, AT_REGS_LEN * sizeof(u32));
+
+       regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
+
+       regs_buff[0]  = AT_READ_REG(hw, REG_VPD_CAP);
+       regs_buff[1]  = AT_READ_REG(hw, REG_SPI_FLASH_CTRL);
+       regs_buff[2]  = AT_READ_REG(hw, REG_SPI_FLASH_CONFIG);
+       regs_buff[3]  = AT_READ_REG(hw, REG_TWSI_CTRL);
+       regs_buff[4]  = AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL);
+       regs_buff[5]  = AT_READ_REG(hw, REG_MASTER_CTRL);
+       regs_buff[6]  = AT_READ_REG(hw, REG_MANUAL_TIMER_INIT);
+       regs_buff[7]  = AT_READ_REG(hw, REG_IRQ_MODU_TIMER_INIT);
+       regs_buff[8]  = AT_READ_REG(hw, REG_GPHY_CTRL);
+       regs_buff[9]  = AT_READ_REG(hw, REG_CMBDISDMA_TIMER);
+       regs_buff[10] = AT_READ_REG(hw, REG_IDLE_STATUS);
+       regs_buff[11] = AT_READ_REG(hw, REG_MDIO_CTRL);
+       regs_buff[12] = AT_READ_REG(hw, REG_SERDES_LOCK);
+       regs_buff[13] = AT_READ_REG(hw, REG_MAC_CTRL);
+       regs_buff[14] = AT_READ_REG(hw, REG_MAC_IPG_IFG);
+       regs_buff[15] = AT_READ_REG(hw, REG_MAC_STA_ADDR);
+       regs_buff[16] = AT_READ_REG(hw, REG_MAC_STA_ADDR+4);
+       regs_buff[17] = AT_READ_REG(hw, REG_RX_HASH_TABLE);
+       regs_buff[18] = AT_READ_REG(hw, REG_RX_HASH_TABLE+4);
+       regs_buff[19] = AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL);
+       regs_buff[20] = AT_READ_REG(hw, REG_MTU);
+       regs_buff[21] = AT_READ_REG(hw, REG_WOL_CTRL);
+       regs_buff[22] = AT_READ_REG(hw, REG_SRAM_TRD_ADDR);
+       regs_buff[23] = AT_READ_REG(hw, REG_SRAM_TRD_LEN);
+       regs_buff[24] = AT_READ_REG(hw, REG_SRAM_RXF_ADDR);
+       regs_buff[25] = AT_READ_REG(hw, REG_SRAM_RXF_LEN);
+       regs_buff[26] = AT_READ_REG(hw, REG_SRAM_TXF_ADDR);
+       regs_buff[27] = AT_READ_REG(hw, REG_SRAM_TXF_LEN);
+       regs_buff[28] = AT_READ_REG(hw, REG_SRAM_TCPH_ADDR);
+       regs_buff[29] = AT_READ_REG(hw, REG_SRAM_PKTH_ADDR);
+
+       atl1e_read_phy_reg(hw, MII_BMCR, &phy_data);
+       regs_buff[73] = (u32)phy_data;
+       atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
+       regs_buff[74] = (u32)phy_data;
+}
+
+static int atl1e_get_eeprom_len(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       if (!atl1e_check_eeprom_exist(&adapter->hw))
+               return AT_EEPROM_LEN;
+       else
+               return 0;
+}
+
+static int atl1e_get_eeprom(struct net_device *netdev,
+               struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+       u32 *eeprom_buff;
+       int first_dword, last_dword;
+       int ret_val = 0;
+       int i;
+
+       if (eeprom->len == 0)
+               return -EINVAL;
+
+       if (atl1e_check_eeprom_exist(hw)) /* not exist */
+               return -EINVAL;
+
+       eeprom->magic = hw->vendor_id | (hw->device_id << 16);
+
+       first_dword = eeprom->offset >> 2;
+       last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
+
+       eeprom_buff = kmalloc(sizeof(u32) *
+                       (last_dword - first_dword + 1), GFP_KERNEL);
+       if (eeprom_buff == NULL)
+               return -ENOMEM;
+
+       for (i = first_dword; i < last_dword; i++) {
+               if (!atl1e_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) {
+                       kfree(eeprom_buff);
+                       return -EIO;
+               }
+       }
+
+       memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
+                       eeprom->len);
+       kfree(eeprom_buff);
+
+       return ret_val;
+}
+
+static int atl1e_set_eeprom(struct net_device *netdev,
+                           struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+       u32 *eeprom_buff;
+       u32 *ptr;
+       int first_dword, last_dword;
+       int ret_val = 0;
+       int i;
+
+       if (eeprom->len == 0)
+               return -EOPNOTSUPP;
+
+       if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
+               return -EINVAL;
+
+       first_dword = eeprom->offset >> 2;
+       last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
+       eeprom_buff = kmalloc(AT_EEPROM_LEN, GFP_KERNEL);
+       if (eeprom_buff == NULL)
+               return -ENOMEM;
+
+       ptr = (u32 *)eeprom_buff;
+
+       if (eeprom->offset & 3) {
+               /* need read/modify/write of first changed EEPROM word */
+               /* only the second byte of the word is being modified */
+               if (!atl1e_read_eeprom(hw, first_dword * 4, &(eeprom_buff[0]))) {
+                       ret_val = -EIO;
+                       goto out;
+               }
+               ptr++;
+       }
+       if (((eeprom->offset + eeprom->len) & 3)) {
+               /* need read/modify/write of last changed EEPROM word */
+               /* only the first byte of the word is being modified */
+
+               if (!atl1e_read_eeprom(hw, last_dword * 4,
+                               &(eeprom_buff[last_dword - first_dword]))) {
+                       ret_val = -EIO;
+                       goto out;
+               }
+       }
+
+       /* Device's eeprom is always little-endian, word addressable */
+       memcpy(ptr, bytes, eeprom->len);
+
+       for (i = 0; i < last_dword - first_dword + 1; i++) {
+               if (!atl1e_write_eeprom(hw, ((first_dword + i) * 4),
+                                 eeprom_buff[i])) {
+                       ret_val = -EIO;
+                       goto out;
+               }
+       }
+out:
+       kfree(eeprom_buff);
+       return ret_val;
+}
+
+static void atl1e_get_drvinfo(struct net_device *netdev,
+               struct ethtool_drvinfo *drvinfo)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       strncpy(drvinfo->driver,  atl1e_driver_name, 32);
+       strncpy(drvinfo->version, atl1e_driver_version, 32);
+       strncpy(drvinfo->fw_version, "L1e", 32);
+       strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+       drvinfo->n_stats = 0;
+       drvinfo->testinfo_len = 0;
+       drvinfo->regdump_len = atl1e_get_regs_len(netdev);
+       drvinfo->eedump_len = atl1e_get_eeprom_len(netdev);
+}
+
+static void atl1e_get_wol(struct net_device *netdev,
+                         struct ethtool_wolinfo *wol)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       wol->supported = WAKE_MAGIC | WAKE_PHY;
+       wol->wolopts = 0;
+
+       if (adapter->wol & AT_WUFC_EX)
+               wol->wolopts |= WAKE_UCAST;
+       if (adapter->wol & AT_WUFC_MC)
+               wol->wolopts |= WAKE_MCAST;
+       if (adapter->wol & AT_WUFC_BC)
+               wol->wolopts |= WAKE_BCAST;
+       if (adapter->wol & AT_WUFC_MAG)
+               wol->wolopts |= WAKE_MAGIC;
+       if (adapter->wol & AT_WUFC_LNKC)
+               wol->wolopts |= WAKE_PHY;
+
+       return;
+}
+
+static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
+                           WAKE_MCAST | WAKE_BCAST | WAKE_MCAST))
+               return -EOPNOTSUPP;
+       /* these settings will always override what we currently have */
+       adapter->wol = 0;
+
+       if (wol->wolopts & WAKE_MAGIC)
+               adapter->wol |= AT_WUFC_MAG;
+       if (wol->wolopts & WAKE_PHY)
+               adapter->wol |= AT_WUFC_LNKC;
+
+       return 0;
+}
+
+static int atl1e_nway_reset(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       if (netif_running(netdev))
+               atl1e_reinit_locked(adapter);
+       return 0;
+}
+
+static struct ethtool_ops atl1e_ethtool_ops = {
+       .get_settings           = atl1e_get_settings,
+       .set_settings           = atl1e_set_settings,
+       .get_drvinfo            = atl1e_get_drvinfo,
+       .get_regs_len           = atl1e_get_regs_len,
+       .get_regs               = atl1e_get_regs,
+       .get_wol                = atl1e_get_wol,
+       .set_wol                = atl1e_set_wol,
+       .get_msglevel           = atl1e_get_msglevel,
+       .set_msglevel           = atl1e_set_msglevel,
+       .nway_reset             = atl1e_nway_reset,
+       .get_link               = ethtool_op_get_link,
+       .get_eeprom_len         = atl1e_get_eeprom_len,
+       .get_eeprom             = atl1e_get_eeprom,
+       .set_eeprom             = atl1e_set_eeprom,
+       .get_tx_csum            = atl1e_get_tx_csum,
+       .get_sg                 = ethtool_op_get_sg,
+       .set_sg                 = ethtool_op_set_sg,
+#ifdef NETIF_F_TSO
+       .get_tso                = ethtool_op_get_tso,
+#endif
+};
+
+void atl1e_set_ethtool_ops(struct net_device *netdev)
+{
+       SET_ETHTOOL_OPS(netdev, &atl1e_ethtool_ops);
+}
diff --git a/drivers/net/atl1e/atl1e_hw.c b/drivers/net/atl1e/atl1e_hw.c
new file mode 100644 (file)
index 0000000..949e753
--- /dev/null
@@ -0,0 +1,664 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public 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/pci.h>
+#include <linux/delay.h>
+#include <linux/mii.h>
+#include <linux/crc32.h>
+
+#include "atl1e.h"
+
+/*
+ * check_eeprom_exist
+ * return 0 if eeprom exist
+ */
+int atl1e_check_eeprom_exist(struct atl1e_hw *hw)
+{
+       u32 value;
+
+       value = AT_READ_REG(hw, REG_SPI_FLASH_CTRL);
+       if (value & SPI_FLASH_CTRL_EN_VPD) {
+               value &= ~SPI_FLASH_CTRL_EN_VPD;
+               AT_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value);
+       }
+       value = AT_READ_REGW(hw, REG_PCIE_CAP_LIST);
+       return ((value & 0xFF00) == 0x6C00) ? 0 : 1;
+}
+
+void atl1e_hw_set_mac_addr(struct atl1e_hw *hw)
+{
+       u32 value;
+       /*
+        * 00-0B-6A-F6-00-DC
+        * 0:  6AF600DC 1: 000B
+        * low dword
+        */
+       value = (((u32)hw->mac_addr[2]) << 24) |
+               (((u32)hw->mac_addr[3]) << 16) |
+               (((u32)hw->mac_addr[4]) << 8)  |
+               (((u32)hw->mac_addr[5])) ;
+       AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
+       /* hight dword */
+       value = (((u32)hw->mac_addr[0]) << 8) |
+               (((u32)hw->mac_addr[1])) ;
+       AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
+}
+
+/*
+ * atl1e_get_permanent_address
+ * return 0 if get valid mac address,
+ */
+static int atl1e_get_permanent_address(struct atl1e_hw *hw)
+{
+       u32 addr[2];
+       u32 i;
+       u32 twsi_ctrl_data;
+       u8  eth_addr[ETH_ALEN];
+
+       if (is_valid_ether_addr(hw->perm_mac_addr))
+               return 0;
+
+       /* init */
+       addr[0] = addr[1] = 0;
+
+       if (!atl1e_check_eeprom_exist(hw)) {
+               /* eeprom exist */
+               twsi_ctrl_data = AT_READ_REG(hw, REG_TWSI_CTRL);
+               twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART;
+               AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data);
+               for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) {
+                       msleep(10);
+                       twsi_ctrl_data = AT_READ_REG(hw, REG_TWSI_CTRL);
+                       if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0)
+                               break;
+               }
+               if (i >= AT_TWSI_EEPROM_TIMEOUT)
+                       return AT_ERR_TIMEOUT;
+       }
+
+       /* maybe MAC-address is from BIOS */
+       addr[0] = AT_READ_REG(hw, REG_MAC_STA_ADDR);
+       addr[1] = AT_READ_REG(hw, REG_MAC_STA_ADDR + 4);
+       *(u32 *) &eth_addr[2] = swab32(addr[0]);
+       *(u16 *) &eth_addr[0] = swab16(*(u16 *)&addr[1]);
+
+       if (is_valid_ether_addr(eth_addr)) {
+               memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
+               return 0;
+       }
+
+       return AT_ERR_EEPROM;
+}
+
+bool atl1e_write_eeprom(struct atl1e_hw *hw, u32 offset, u32 value)
+{
+       return true;
+}
+
+bool atl1e_read_eeprom(struct atl1e_hw *hw, u32 offset, u32 *p_value)
+{
+       int i;
+       u32 control;
+
+       if (offset & 3)
+               return false; /* address do not align */
+
+       AT_WRITE_REG(hw, REG_VPD_DATA, 0);
+       control = (offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT;
+       AT_WRITE_REG(hw, REG_VPD_CAP, control);
+
+       for (i = 0; i < 10; i++) {
+               msleep(2);
+               control = AT_READ_REG(hw, REG_VPD_CAP);
+               if (control & VPD_CAP_VPD_FLAG)
+                       break;
+       }
+       if (control & VPD_CAP_VPD_FLAG) {
+               *p_value = AT_READ_REG(hw, REG_VPD_DATA);
+               return true;
+       }
+       return false; /* timeout */
+}
+
+void atl1e_force_ps(struct atl1e_hw *hw)
+{
+       AT_WRITE_REGW(hw, REG_GPHY_CTRL,
+                       GPHY_CTRL_PW_WOL_DIS | GPHY_CTRL_EXT_RESET);
+}
+
+/*
+ * Reads the adapter's MAC address from the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+int atl1e_read_mac_addr(struct atl1e_hw *hw)
+{
+       int err = 0;
+
+       err = atl1e_get_permanent_address(hw);
+       if (err)
+               return AT_ERR_EEPROM;
+       memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr));
+       return 0;
+}
+
+/*
+ * atl1e_hash_mc_addr
+ *  purpose
+ *      set hash value for a multicast address
+ *      hash calcu processing :
+ *          1. calcu 32bit CRC for multicast address
+ *          2. reverse crc with MSB to LSB
+ */
+u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr)
+{
+       u32 crc32;
+       u32 value = 0;
+       int i;
+
+       crc32 = ether_crc_le(6, mc_addr);
+       crc32 = ~crc32;
+       for (i = 0; i < 32; i++)
+               value |= (((crc32 >> i) & 1) << (31 - i));
+
+       return value;
+}
+
+/*
+ * Sets the bit in the multicast table corresponding to the hash value.
+ * hw - Struct containing variables accessed by shared code
+ * hash_value - Multicast address hash value
+ */
+void atl1e_hash_set(struct atl1e_hw *hw, u32 hash_value)
+{
+       u32 hash_bit, hash_reg;
+       u32 mta;
+
+       /*
+        * The HASH Table  is a register array of 2 32-bit registers.
+        * It is treated like an array of 64 bits.  We want to set
+        * bit BitArray[hash_value]. So we figure out what register
+        * the bit is in, read it, OR in the new bit, then write
+        * back the new value.  The register is determined by the
+        * upper 7 bits of the hash value and the bit within that
+        * register are determined by the lower 5 bits of the value.
+        */
+       hash_reg = (hash_value >> 31) & 0x1;
+       hash_bit = (hash_value >> 26) & 0x1F;
+
+       mta = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
+
+       mta |= (1 << hash_bit);
+
+       AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
+}
+/*
+ * Reads the value from a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to read
+ */
+int atl1e_read_phy_reg(struct atl1e_hw *hw, u16 reg_addr, u16 *phy_data)
+{
+       u32 val;
+       int i;
+
+       val = ((u32)(reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
+               MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW |
+               MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
+
+       AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+       wmb();
+
+       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+               udelay(2);
+               val = AT_READ_REG(hw, REG_MDIO_CTRL);
+               if (!(val & (MDIO_START | MDIO_BUSY)))
+                       break;
+               wmb();
+       }
+       if (!(val & (MDIO_START | MDIO_BUSY))) {
+               *phy_data = (u16)val;
+               return 0;
+       }
+
+       return AT_ERR_PHY;
+}
+
+/*
+ * Writes a value to a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to write
+ * data - data to write to the PHY
+ */
+int atl1e_write_phy_reg(struct atl1e_hw *hw, u32 reg_addr, u16 phy_data)
+{
+       int i;
+       u32 val;
+
+       val = ((u32)(phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT |
+              (reg_addr&MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT |
+              MDIO_SUP_PREAMBLE |
+              MDIO_START |
+              MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
+
+       AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+       wmb();
+
+       for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+               udelay(2);
+               val = AT_READ_REG(hw, REG_MDIO_CTRL);
+               if (!(val & (MDIO_START | MDIO_BUSY)))
+                       break;
+               wmb();
+       }
+
+       if (!(val & (MDIO_START | MDIO_BUSY)))
+               return 0;
+
+       return AT_ERR_PHY;
+}
+
+/*
+ * atl1e_init_pcie - init PCIE module
+ */
+static void atl1e_init_pcie(struct atl1e_hw *hw)
+{
+       u32 value;
+       /* comment 2lines below to save more power when sususpend
+          value = LTSSM_TEST_MODE_DEF;
+          AT_WRITE_REG(hw, REG_LTSSM_TEST_MODE, value);
+        */
+
+       /* pcie flow control mode change */
+       value = AT_READ_REG(hw, 0x1008);
+       value |= 0x8000;
+       AT_WRITE_REG(hw, 0x1008, value);
+}
+/*
+ * Configures PHY autoneg and flow control advertisement settings
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw)
+{
+       s32 ret_val;
+       u16 mii_autoneg_adv_reg;
+       u16 mii_1000t_ctrl_reg;
+
+       if (0 != hw->mii_autoneg_adv_reg)
+               return 0;
+       /* Read the MII Auto-Neg Advertisement Register (Address 4/9). */
+       mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK;
+       mii_1000t_ctrl_reg  = MII_AT001_CR_1000T_DEFAULT_CAP_MASK;
+
+       /*
+        * Need to parse autoneg_advertised  and set up
+        * the appropriate PHY registers.  First we will parse for
+        * autoneg_advertised software override.  Since we can advertise
+        * a plethora of combinations, we need to check each bit
+        * individually.
+        */
+
+       /*
+        * First we clear all the 10/100 mb speed bits in the Auto-Neg
+        * Advertisement Register (Address 4) and the 1000 mb speed bits in
+        * the  1000Base-T control Register (Address 9).
+        */
+       mii_autoneg_adv_reg &= ~MII_AR_SPEED_MASK;
+       mii_1000t_ctrl_reg  &= ~MII_AT001_CR_1000T_SPEED_MASK;
+
+       /*
+        * Need to parse MediaType and setup the
+        * appropriate PHY registers.
+        */
+       switch (hw->media_type) {
+       case MEDIA_TYPE_AUTO_SENSOR:
+               mii_autoneg_adv_reg |= (MII_AR_10T_HD_CAPS   |
+                                       MII_AR_10T_FD_CAPS   |
+                                       MII_AR_100TX_HD_CAPS |
+                                       MII_AR_100TX_FD_CAPS);
+               hw->autoneg_advertised = ADVERTISE_10_HALF  |
+                                        ADVERTISE_10_FULL  |
+                                        ADVERTISE_100_HALF |
+                                        ADVERTISE_100_FULL;
+               if (hw->nic_type == athr_l1e) {
+                       mii_1000t_ctrl_reg |=
+                               MII_AT001_CR_1000T_FD_CAPS;
+                       hw->autoneg_advertised |= ADVERTISE_1000_FULL;
+               }
+               break;
+
+       case MEDIA_TYPE_100M_FULL:
+               mii_autoneg_adv_reg   |= MII_AR_100TX_FD_CAPS;
+               hw->autoneg_advertised = ADVERTISE_100_FULL;
+               break;
+
+       case MEDIA_TYPE_100M_HALF:
+               mii_autoneg_adv_reg   |= MII_AR_100TX_HD_CAPS;
+               hw->autoneg_advertised = ADVERTISE_100_HALF;
+               break;
+
+       case MEDIA_TYPE_10M_FULL:
+               mii_autoneg_adv_reg   |= MII_AR_10T_FD_CAPS;
+               hw->autoneg_advertised = ADVERTISE_10_FULL;
+               break;
+
+       default:
+               mii_autoneg_adv_reg   |= MII_AR_10T_HD_CAPS;
+               hw->autoneg_advertised = ADVERTISE_10_HALF;
+               break;
+       }
+
+       /* flow control fixed to enable all */
+       mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE);
+
+       hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg;
+       hw->mii_1000t_ctrl_reg  = mii_1000t_ctrl_reg;
+
+       ret_val = atl1e_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg);
+       if (ret_val)
+               return ret_val;
+
+       if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) {
+               ret_val = atl1e_write_phy_reg(hw, MII_AT001_CR,
+                                          mii_1000t_ctrl_reg);
+               if (ret_val)
+                       return ret_val;
+       }
+
+       return 0;
+}
+
+
+/*
+ * Resets the PHY and make all config validate
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Sets bit 15 and 12 of the MII control regiser (for F001 bug)
+ */
+int atl1e_phy_commit(struct atl1e_hw *hw)
+{
+       struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter;
+       struct pci_dev *pdev = adapter->pdev;
+       int ret_val;
+       u16 phy_data;
+
+       phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG;
+
+       ret_val = atl1e_write_phy_reg(hw, MII_BMCR, phy_data);
+       if (ret_val) {
+               u32 val;
+               int i;
+               /**************************************
+                * pcie serdes link may be down !
+                **************************************/
+               for (i = 0; i < 25; i++) {
+                       msleep(1);
+                       val = AT_READ_REG(hw, REG_MDIO_CTRL);
+                       if (!(val & (MDIO_START | MDIO_BUSY)))
+                               break;
+               }
+
+               if (0 != (val & (MDIO_START | MDIO_BUSY))) {
+                       dev_err(&pdev->dev,
+                               "pcie linkdown at least for 25ms\n");
+                       return ret_val;
+               }
+
+               dev_err(&pdev->dev, "pcie linkup after %d ms\n", i);
+       }
+       return 0;
+}
+
+int atl1e_phy_init(struct atl1e_hw *hw)
+{
+       struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter;
+       struct pci_dev *pdev = adapter->pdev;
+       s32 ret_val;
+       u16 phy_val;
+
+       if (hw->phy_configured) {
+               if (hw->re_autoneg) {
+                       hw->re_autoneg = false;
+                       return atl1e_restart_autoneg(hw);
+               }
+               return 0;
+       }
+
+       /* RESET GPHY Core */
+       AT_WRITE_REGW(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT);
+       msleep(2);
+       AT_WRITE_REGW(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT |
+                     GPHY_CTRL_EXT_RESET);
+       msleep(2);
+
+       /* patches */
+       /* p1. eable hibernation mode */
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0xB);
+       if (ret_val)
+               return ret_val;
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0xBC00);
+       if (ret_val)
+               return ret_val;
+       /* p2. set Class A/B for all modes */
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0);
+       if (ret_val)
+               return ret_val;
+       phy_val = 0x02ef;
+       /* remove Class AB */
+       /* phy_val = hw->emi_ca ? 0x02ef : 0x02df; */
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, phy_val);
+       if (ret_val)
+               return ret_val;
+       /* p3. 10B ??? */
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x12);
+       if (ret_val)
+               return ret_val;
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x4C04);
+       if (ret_val)
+               return ret_val;
+       /* p4. 1000T power */
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x4);
+       if (ret_val)
+               return ret_val;
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x8BBB);
+       if (ret_val)
+               return ret_val;
+
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_ADDR, 0x5);
+       if (ret_val)
+               return ret_val;
+       ret_val = atl1e_write_phy_reg(hw, MII_DBG_DATA, 0x2C46);
+       if (ret_val)
+               return ret_val;
+
+       msleep(1);
+
+       /*Enable PHY LinkChange Interrupt */
+       ret_val = atl1e_write_phy_reg(hw, MII_INT_CTRL, 0xC00);
+       if (ret_val) {
+               dev_err(&pdev->dev, "Error enable PHY linkChange Interrupt\n");
+               return ret_val;
+       }
+       /* setup AutoNeg parameters */
+       ret_val = atl1e_phy_setup_autoneg_adv(hw);
+       if (ret_val) {
+               dev_err(&pdev->dev, "Error Setting up Auto-Negotiation\n");
+               return ret_val;
+       }
+       /* SW.Reset & En-Auto-Neg to restart Auto-Neg*/
+       dev_dbg(&pdev->dev, "Restarting Auto-Neg");
+       ret_val = atl1e_phy_commit(hw);
+       if (ret_val) {
+               dev_err(&pdev->dev, "Error Resetting the phy");
+               return ret_val;
+       }
+
+       hw->phy_configured = true;
+
+       return 0;
+}
+
+/*
+ * Reset the transmit and receive units; mask and clear all interrupts.
+ * hw - Struct containing variables accessed by shared code
+ * return : 0  or  idle status (if error)
+ */
+int atl1e_reset_hw(struct atl1e_hw *hw)
+{
+       struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter;
+       struct pci_dev *pdev = adapter->pdev;
+
+       u32 idle_status_data = 0;
+       u16 pci_cfg_cmd_word = 0;
+       int timeout = 0;
+
+       /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */
+       pci_read_config_word(pdev, PCI_REG_COMMAND, &pci_cfg_cmd_word);
+       if ((pci_cfg_cmd_word & (CMD_IO_SPACE |
+                               CMD_MEMORY_SPACE | CMD_BUS_MASTER))
+                       != (CMD_IO_SPACE | CMD_MEMORY_SPACE | CMD_BUS_MASTER)) {
+               pci_cfg_cmd_word |= (CMD_IO_SPACE |
+                                    CMD_MEMORY_SPACE | CMD_BUS_MASTER);
+               pci_write_config_word(pdev, PCI_REG_COMMAND, pci_cfg_cmd_word);
+       }
+
+       /*
+        * Issue Soft Reset to the MAC.  This will reset the chip's
+        * transmit, receive, DMA.  It will not effect
+        * the current PCI configuration.  The global reset bit is self-
+        * clearing, and should clear within a microsecond.
+        */
+       AT_WRITE_REG(hw, REG_MASTER_CTRL,
+                       MASTER_CTRL_LED_MODE | MASTER_CTRL_SOFT_RST);
+       wmb();
+       msleep(1);
+
+       /* Wait at least 10ms for All module to be Idle */
+       for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
+               idle_status_data = AT_READ_REG(hw, REG_IDLE_STATUS);
+               if (idle_status_data == 0)
+                       break;
+               msleep(1);
+               cpu_relax();
+       }
+
+       if (timeout >= AT_HW_MAX_IDLE_DELAY) {
+               dev_err(&pdev->dev,
+                       "MAC state machine cann't be idle since"
+                       " disabled for 10ms second\n");
+               return AT_ERR_TIMEOUT;
+       }
+
+       return 0;
+}
+
+
+/*
+ * Performs basic configuration of the adapter.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * Assumes that the controller has previously been reset and is in a
+ * post-reset uninitialized state. Initializes multicast table,
+ * and  Calls routines to setup link
+ * Leaves the transmit and receive units disabled and uninitialized.
+ */
+int atl1e_init_hw(struct atl1e_hw *hw)
+{
+       s32 ret_val = 0;
+
+       atl1e_init_pcie(hw);
+
+       /* Zero out the Multicast HASH table */
+       /* clear the old settings from the multicast hash table */
+       AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
+       AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
+
+       ret_val = atl1e_phy_init(hw);
+
+       return ret_val;
+}
+
+/*
+ * Detects the current speed and duplex settings of the hardware.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * speed - Speed of the connection
+ * duplex - Duplex setting of the connection
+ */
+int atl1e_get_speed_and_duplex(struct atl1e_hw *hw, u16 *speed, u16 *duplex)
+{
+       int err;
+       u16 phy_data;
+
+       /* Read   PHY Specific Status Register (17) */
+       err = atl1e_read_phy_reg(hw, MII_AT001_PSSR, &phy_data);
+       if (err)
+               return err;
+
+       if (!(phy_data & MII_AT001_PSSR_SPD_DPLX_RESOLVED))
+               return AT_ERR_PHY_RES;
+
+       switch (phy_data & MII_AT001_PSSR_SPEED) {
+       case MII_AT001_PSSR_1000MBS:
+               *speed = SPEED_1000;
+               break;
+       case MII_AT001_PSSR_100MBS:
+               *speed = SPEED_100;
+               break;
+       case MII_AT001_PSSR_10MBS:
+               *speed = SPEED_10;
+               break;
+       default:
+               return AT_ERR_PHY_SPEED;
+               break;
+       }
+
+       if (phy_data & MII_AT001_PSSR_DPLX)
+               *duplex = FULL_DUPLEX;
+       else
+               *duplex = HALF_DUPLEX;
+
+       return 0;
+}
+
+int atl1e_restart_autoneg(struct atl1e_hw *hw)
+{
+       int err = 0;
+
+       err = atl1e_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg);
+       if (err)
+               return err;
+
+       if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) {
+               err = atl1e_write_phy_reg(hw, MII_AT001_CR,
+                                      hw->mii_1000t_ctrl_reg);
+               if (err)
+                       return err;
+       }
+
+       err = atl1e_write_phy_reg(hw, MII_BMCR,
+                       MII_CR_RESET | MII_CR_AUTO_NEG_EN |
+                       MII_CR_RESTART_AUTO_NEG);
+       return err;
+}
+
diff --git a/drivers/net/atl1e/atl1e_hw.h b/drivers/net/atl1e/atl1e_hw.h
new file mode 100644 (file)
index 0000000..5ea2f4d
--- /dev/null
@@ -0,0 +1,793 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public 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 _ATHL1E_HW_H_
+#define _ATHL1E_HW_H_
+
+#include <linux/types.h>
+#include <linux/mii.h>
+
+struct atl1e_adapter;
+struct atl1e_hw;
+
+/* function prototype */
+s32 atl1e_reset_hw(struct atl1e_hw *hw);
+s32 atl1e_read_mac_addr(struct atl1e_hw *hw);
+s32 atl1e_init_hw(struct atl1e_hw *hw);
+s32 atl1e_phy_commit(struct atl1e_hw *hw);
+s32 atl1e_get_speed_and_duplex(struct atl1e_hw *hw, u16 *speed, u16 *duplex);
+u32 atl1e_auto_get_fc(struct atl1e_adapter *adapter, u16 duplex);
+u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr);
+void atl1e_hash_set(struct atl1e_hw *hw, u32 hash_value);
+s32 atl1e_read_phy_reg(struct atl1e_hw *hw, u16 reg_addr, u16 *phy_data);
+s32 atl1e_write_phy_reg(struct atl1e_hw *hw, u32 reg_addr, u16 phy_data);
+s32 atl1e_validate_mdi_setting(struct atl1e_hw *hw);
+void atl1e_hw_set_mac_addr(struct atl1e_hw *hw);
+bool atl1e_read_eeprom(struct atl1e_hw *hw, u32 offset, u32 *p_value);
+bool atl1e_write_eeprom(struct atl1e_hw *hw, u32 offset, u32 value);
+s32 atl1e_phy_enter_power_saving(struct atl1e_hw *hw);
+s32 atl1e_phy_leave_power_saving(struct atl1e_hw *hw);
+s32 atl1e_phy_init(struct atl1e_hw *hw);
+int atl1e_check_eeprom_exist(struct atl1e_hw *hw);
+void atl1e_force_ps(struct atl1e_hw *hw);
+s32 atl1e_restart_autoneg(struct atl1e_hw *hw);
+
+/* register definition */
+#define REG_PM_CTRLSTAT             0x44
+
+#define REG_PCIE_CAP_LIST           0x58
+
+#define REG_DEVICE_CAP              0x5C
+#define     DEVICE_CAP_MAX_PAYLOAD_MASK     0x7
+#define     DEVICE_CAP_MAX_PAYLOAD_SHIFT    0
+
+#define REG_DEVICE_CTRL             0x60
+#define     DEVICE_CTRL_MAX_PAYLOAD_MASK    0x7
+#define     DEVICE_CTRL_MAX_PAYLOAD_SHIFT   5
+#define     DEVICE_CTRL_MAX_RREQ_SZ_MASK    0x7
+#define     DEVICE_CTRL_MAX_RREQ_SZ_SHIFT   12
+
+#define REG_VPD_CAP                 0x6C
+#define     VPD_CAP_ID_MASK                 0xff
+#define     VPD_CAP_ID_SHIFT                0
+#define     VPD_CAP_NEXT_PTR_MASK           0xFF
+#define     VPD_CAP_NEXT_PTR_SHIFT          8
+#define     VPD_CAP_VPD_ADDR_MASK           0x7FFF
+#define     VPD_CAP_VPD_ADDR_SHIFT          16
+#define     VPD_CAP_VPD_FLAG                0x80000000
+
+#define REG_VPD_DATA                0x70
+
+#define REG_SPI_FLASH_CTRL          0x200
+#define     SPI_FLASH_CTRL_STS_NON_RDY      0x1
+#define     SPI_FLASH_CTRL_STS_WEN          0x2
+#define     SPI_FLASH_CTRL_STS_WPEN         0x80
+#define     SPI_FLASH_CTRL_DEV_STS_MASK     0xFF
+#define     SPI_FLASH_CTRL_DEV_STS_SHIFT    0
+#define     SPI_FLASH_CTRL_INS_MASK         0x7
+#define     SPI_FLASH_CTRL_INS_SHIFT        8
+#define     SPI_FLASH_CTRL_START            0x800
+#define     SPI_FLASH_CTRL_EN_VPD           0x2000
+#define     SPI_FLASH_CTRL_LDSTART          0x8000
+#define     SPI_FLASH_CTRL_CS_HI_MASK       0x3
+#define     SPI_FLASH_CTRL_CS_HI_SHIFT      16
+#define     SPI_FLASH_CTRL_CS_HOLD_MASK     0x3
+#define     SPI_FLASH_CTRL_CS_HOLD_SHIFT    18
+#define     SPI_FLASH_CTRL_CLK_LO_MASK      0x3
+#define     SPI_FLASH_CTRL_CLK_LO_SHIFT     20
+#define     SPI_FLASH_CTRL_CLK_HI_MASK      0x3
+#define     SPI_FLASH_CTRL_CLK_HI_SHIFT     22
+#define     SPI_FLASH_CTRL_CS_SETUP_MASK    0x3
+#define     SPI_FLASH_CTRL_CS_SETUP_SHIFT   24
+#define     SPI_FLASH_CTRL_EROM_PGSZ_MASK   0x3
+#define     SPI_FLASH_CTRL_EROM_PGSZ_SHIFT  26
+#define     SPI_FLASH_CTRL_WAIT_READY       0x10000000
+
+#define REG_SPI_ADDR                0x204
+
+#define REG_SPI_DATA                0x208
+
+#define REG_SPI_FLASH_CONFIG        0x20C
+#define     SPI_FLASH_CONFIG_LD_ADDR_MASK   0xFFFFFF
+#define     SPI_FLASH_CONFIG_LD_ADDR_SHIFT  0
+#define     SPI_FLASH_CONFIG_VPD_ADDR_MASK  0x3
+#define     SPI_FLASH_CONFIG_VPD_ADDR_SHIFT 24
+#define     SPI_FLASH_CONFIG_LD_EXIST       0x4000000
+
+
+#define REG_SPI_FLASH_OP_PROGRAM    0x210
+#define REG_SPI_FLASH_OP_SC_ERASE   0x211
+#define REG_SPI_FLASH_OP_CHIP_ERASE 0x212
+#define REG_SPI_FLASH_OP_RDID       0x213
+#define REG_SPI_FLASH_OP_WREN       0x214
+#define REG_SPI_FLASH_OP_RDSR       0x215
+#define REG_SPI_FLASH_OP_WRSR       0x216
+#define REG_SPI_FLASH_OP_READ       0x217
+
+#define REG_TWSI_CTRL               0x218
+#define     TWSI_CTRL_LD_OFFSET_MASK        0xFF
+#define     TWSI_CTRL_LD_OFFSET_SHIFT       0
+#define     TWSI_CTRL_LD_SLV_ADDR_MASK      0x7
+#define     TWSI_CTRL_LD_SLV_ADDR_SHIFT     8
+#define     TWSI_CTRL_SW_LDSTART            0x800
+#define     TWSI_CTRL_HW_LDSTART            0x1000
+#define     TWSI_CTRL_SMB_SLV_ADDR_MASK     0x0x7F
+#define     TWSI_CTRL_SMB_SLV_ADDR_SHIFT    15
+#define     TWSI_CTRL_LD_EXIST              0x400000
+#define     TWSI_CTRL_READ_FREQ_SEL_MASK    0x3
+#define     TWSI_CTRL_READ_FREQ_SEL_SHIFT   23
+#define     TWSI_CTRL_FREQ_SEL_100K         0
+#define     TWSI_CTRL_FREQ_SEL_200K         1
+#define     TWSI_CTRL_FREQ_SEL_300K         2
+#define     TWSI_CTRL_FREQ_SEL_400K         3
+#define     TWSI_CTRL_SMB_SLV_ADDR
+#define     TWSI_CTRL_WRITE_FREQ_SEL_MASK   0x3
+#define     TWSI_CTRL_WRITE_FREQ_SEL_SHIFT  24
+
+
+#define REG_PCIE_DEV_MISC_CTRL      0x21C
+#define     PCIE_DEV_MISC_CTRL_EXT_PIPE     0x2
+#define     PCIE_DEV_MISC_CTRL_RETRY_BUFDIS 0x1
+#define     PCIE_DEV_MISC_CTRL_SPIROM_EXIST 0x4
+#define     PCIE_DEV_MISC_CTRL_SERDES_ENDIAN    0x8
+#define     PCIE_DEV_MISC_CTRL_SERDES_SEL_DIN   0x10
+
+#define REG_PCIE_PHYMISC           0x1000
+#define PCIE_PHYMISC_FORCE_RCV_DET     0x4
+
+#define REG_LTSSM_TEST_MODE         0x12FC
+#define         LTSSM_TEST_MODE_DEF     0xE000
+
+/* Selene Master Control Register */
+#define REG_MASTER_CTRL             0x1400
+#define     MASTER_CTRL_SOFT_RST            0x1
+#define     MASTER_CTRL_MTIMER_EN           0x2
+#define     MASTER_CTRL_ITIMER_EN           0x4
+#define     MASTER_CTRL_MANUAL_INT          0x8
+#define     MASTER_CTRL_ITIMER2_EN          0x20
+#define     MASTER_CTRL_INT_RDCLR           0x40
+#define     MASTER_CTRL_LED_MODE           0x200
+#define     MASTER_CTRL_REV_NUM_SHIFT       16
+#define     MASTER_CTRL_REV_NUM_MASK        0xff
+#define     MASTER_CTRL_DEV_ID_SHIFT        24
+#define     MASTER_CTRL_DEV_ID_MASK         0xff
+
+/* Timer Initial Value Register */
+#define REG_MANUAL_TIMER_INIT       0x1404
+
+
+/* IRQ ModeratorTimer Initial Value Register */
+#define REG_IRQ_MODU_TIMER_INIT     0x1408   /* w */
+#define REG_IRQ_MODU_TIMER2_INIT    0x140A   /* w */
+
+
+#define REG_GPHY_CTRL               0x140C
+#define     GPHY_CTRL_EXT_RESET         1
+#define     GPHY_CTRL_PIPE_MOD          2
+#define     GPHY_CTRL_TEST_MODE_MASK    3
+#define     GPHY_CTRL_TEST_MODE_SHIFT   2
+#define     GPHY_CTRL_BERT_START        0x10
+#define     GPHY_CTRL_GATE_25M_EN       0x20
+#define     GPHY_CTRL_LPW_EXIT          0x40
+#define     GPHY_CTRL_PHY_IDDQ          0x80
+#define     GPHY_CTRL_PHY_IDDQ_DIS      0x100
+#define     GPHY_CTRL_PCLK_SEL_DIS      0x200
+#define     GPHY_CTRL_HIB_EN            0x400
+#define     GPHY_CTRL_HIB_PULSE         0x800
+#define     GPHY_CTRL_SEL_ANA_RST       0x1000
+#define     GPHY_CTRL_PHY_PLL_ON        0x2000
+#define     GPHY_CTRL_PWDOWN_HW                0x4000
+#define     GPHY_CTRL_DEFAULT (\
+               GPHY_CTRL_PHY_PLL_ON    |\
+               GPHY_CTRL_SEL_ANA_RST   |\
+               GPHY_CTRL_HIB_PULSE     |\
+               GPHY_CTRL_HIB_EN)
+
+#define     GPHY_CTRL_PW_WOL_DIS (\
+               GPHY_CTRL_PHY_PLL_ON    |\
+               GPHY_CTRL_SEL_ANA_RST   |\
+               GPHY_CTRL_HIB_PULSE     |\
+               GPHY_CTRL_HIB_EN        |\
+               GPHY_CTRL_PWDOWN_HW     |\
+               GPHY_CTRL_PCLK_SEL_DIS  |\
+               GPHY_CTRL_PHY_IDDQ)
+
+/* IRQ Anti-Lost Timer Initial Value Register */
+#define REG_CMBDISDMA_TIMER         0x140E
+
+
+/* Block IDLE Status Register */
+#define REG_IDLE_STATUS        0x1410
+#define     IDLE_STATUS_RXMAC       1    /* 1: RXMAC state machine is in non-IDLE state. 0: RXMAC is idling */
+#define     IDLE_STATUS_TXMAC       2    /* 1: TXMAC state machine is in non-IDLE state. 0: TXMAC is idling */
+#define     IDLE_STATUS_RXQ         4    /* 1: RXQ state machine is in non-IDLE state.   0: RXQ is idling   */
+#define     IDLE_STATUS_TXQ         8    /* 1: TXQ state machine is in non-IDLE state.   0: TXQ is idling   */
+#define     IDLE_STATUS_DMAR        0x10 /* 1: DMAR state machine is in non-IDLE state.  0: DMAR is idling  */
+#define     IDLE_STATUS_DMAW        0x20 /* 1: DMAW state machine is in non-IDLE state.  0: DMAW is idling  */
+#define     IDLE_STATUS_SMB         0x40 /* 1: SMB state machine is in non-IDLE state.   0: SMB is idling   */
+#define     IDLE_STATUS_CMB         0x80 /* 1: CMB state machine is in non-IDLE state.   0: CMB is idling   */
+
+/* MDIO Control Register */
+#define REG_MDIO_CTRL           0x1414
+#define     MDIO_DATA_MASK          0xffff  /* On MDIO write, the 16-bit control data to write to PHY MII management register */
+#define     MDIO_DATA_SHIFT         0       /* On MDIO read, the 16-bit status data that was read from the PHY MII management register*/
+#define     MDIO_REG_ADDR_MASK      0x1f    /* MDIO register address */
+#define     MDIO_REG_ADDR_SHIFT     16
+#define     MDIO_RW                 0x200000      /* 1: read, 0: write */
+#define     MDIO_SUP_PREAMBLE       0x400000      /* Suppress preamble */
+#define     MDIO_START              0x800000      /* Write 1 to initiate the MDIO master. And this bit is self cleared after one cycle*/
+#define     MDIO_CLK_SEL_SHIFT      24
+#define     MDIO_CLK_25_4           0
+#define     MDIO_CLK_25_6           2
+#define     MDIO_CLK_25_8           3
+#define     MDIO_CLK_25_10          4
+#define     MDIO_CLK_25_14          5
+#define     MDIO_CLK_25_20          6
+#define     MDIO_CLK_25_28          7
+#define     MDIO_BUSY               0x8000000
+#define     MDIO_AP_EN              0x10000000
+#define MDIO_WAIT_TIMES         10
+
+/* MII PHY Status Register */
+#define REG_PHY_STATUS           0x1418
+#define     PHY_STATUS_100M          0x20000
+#define     PHY_STATUS_EMI_CA        0x40000
+
+/* BIST Control and Status Register0 (for the Packet Memory) */
+#define REG_BIST0_CTRL              0x141c
+#define     BIST0_NOW                   0x1 /* 1: To trigger BIST0 logic. This bit stays high during the */
+/* BIST process and reset to zero when BIST is done */
+#define     BIST0_SRAM_FAIL             0x2 /* 1: The SRAM failure is un-repairable because it has address */
+/* decoder failure or more than 1 cell stuck-to-x failure */
+#define     BIST0_FUSE_FLAG             0x4 /* 1: Indicating one cell has been fixed */
+
+/* BIST Control and Status Register1(for the retry buffer of PCI Express) */
+#define REG_BIST1_CTRL              0x1420
+#define     BIST1_NOW                   0x1 /* 1: To trigger BIST0 logic. This bit stays high during the */
+/* BIST process and reset to zero when BIST is done */
+#define     BIST1_SRAM_FAIL             0x2 /* 1: The SRAM failure is un-repairable because it has address */
+/* decoder failure or more than 1 cell stuck-to-x failure.*/
+#define     BIST1_FUSE_FLAG             0x4
+
+/* SerDes Lock Detect Control and Status Register */
+#define REG_SERDES_LOCK             0x1424
+#define     SERDES_LOCK_DETECT          1  /* 1: SerDes lock detected . This signal comes from Analog SerDes */
+#define     SERDES_LOCK_DETECT_EN       2  /* 1: Enable SerDes Lock detect function */
+
+/* MAC Control Register  */
+#define REG_MAC_CTRL                0x1480
+#define     MAC_CTRL_TX_EN              1  /* 1: Transmit Enable */
+#define     MAC_CTRL_RX_EN              2  /* 1: Receive Enable */
+#define     MAC_CTRL_TX_FLOW            4  /* 1: Transmit Flow Control Enable */
+#define     MAC_CTRL_RX_FLOW            8  /* 1: Receive Flow Control Enable */
+#define     MAC_CTRL_LOOPBACK           0x10      /* 1: Loop back at G/MII Interface */
+#define     MAC_CTRL_DUPLX              0x20      /* 1: Full-duplex mode  0: Half-duplex mode */
+#define     MAC_CTRL_ADD_CRC            0x40      /* 1: Instruct MAC to attach CRC on all egress Ethernet frames */
+#define     MAC_CTRL_PAD                0x80      /* 1: Instruct MAC to pad short frames to 60-bytes, and then attach CRC. This bit has higher priority over CRC_EN */
+#define     MAC_CTRL_LENCHK             0x100     /* 1: Instruct MAC to check if length field matches the real packet length */
+#define     MAC_CTRL_HUGE_EN            0x200     /* 1: receive Jumbo frame enable */
+#define     MAC_CTRL_PRMLEN_SHIFT       10        /* Preamble length */
+#define     MAC_CTRL_PRMLEN_MASK        0xf
+#define     MAC_CTRL_RMV_VLAN           0x4000    /* 1: to remove VLAN Tag automatically from all receive packets */
+#define     MAC_CTRL_PROMIS_EN          0x8000    /* 1: Promiscuous Mode Enable */
+#define     MAC_CTRL_TX_PAUSE           0x10000   /* 1: transmit test pause */
+#define     MAC_CTRL_SCNT               0x20000   /* 1: shortcut slot time counter */
+#define     MAC_CTRL_SRST_TX            0x40000   /* 1: synchronized reset Transmit MAC module */
+#define     MAC_CTRL_TX_SIMURST         0x80000   /* 1: transmit simulation reset */
+#define     MAC_CTRL_SPEED_SHIFT        20        /* 10: gigabit 01:10M/100M */
+#define     MAC_CTRL_SPEED_MASK         0x300000
+#define     MAC_CTRL_SPEED_1000         2
+#define     MAC_CTRL_SPEED_10_100       1
+#define     MAC_CTRL_DBG_TX_BKPRESURE   0x400000  /* 1: transmit maximum backoff (half-duplex test bit) */
+#define     MAC_CTRL_TX_HUGE            0x800000  /* 1: transmit huge enable */
+#define     MAC_CTRL_RX_CHKSUM_EN       0x1000000 /* 1: RX checksum enable */
+#define     MAC_CTRL_MC_ALL_EN          0x2000000 /* 1: upload all multicast frame without error to system */
+#define     MAC_CTRL_BC_EN              0x4000000 /* 1: upload all broadcast frame without error to system */
+#define     MAC_CTRL_DBG                0x8000000 /* 1: upload all received frame to system (Debug Mode) */
+
+/* MAC IPG/IFG Control Register  */
+#define REG_MAC_IPG_IFG             0x1484
+#define     MAC_IPG_IFG_IPGT_SHIFT      0     /* Desired back to back inter-packet gap. The default is 96-bit time */
+#define     MAC_IPG_IFG_IPGT_MASK       0x7f
+#define     MAC_IPG_IFG_MIFG_SHIFT      8     /* Minimum number of IFG to enforce in between RX frames */
+#define     MAC_IPG_IFG_MIFG_MASK       0xff  /* Frame gap below such IFP is dropped */
+#define     MAC_IPG_IFG_IPGR1_SHIFT     16    /* 64bit Carrier-Sense window */
+#define     MAC_IPG_IFG_IPGR1_MASK      0x7f
+#define     MAC_IPG_IFG_IPGR2_SHIFT     24    /* 96-bit IPG window */
+#define     MAC_IPG_IFG_IPGR2_MASK      0x7f
+
+/* MAC STATION ADDRESS  */
+#define REG_MAC_STA_ADDR            0x1488
+
+/* Hash table for multicast address */
+#define REG_RX_HASH_TABLE           0x1490
+
+
+/* MAC Half-Duplex Control Register */
+#define REG_MAC_HALF_DUPLX_CTRL     0x1498
+#define     MAC_HALF_DUPLX_CTRL_LCOL_SHIFT   0      /* Collision Window */
+#define     MAC_HALF_DUPLX_CTRL_LCOL_MASK    0x3ff
+#define     MAC_HALF_DUPLX_CTRL_RETRY_SHIFT  12     /* Retransmission maximum, afterwards the packet will be discarded */
+#define     MAC_HALF_DUPLX_CTRL_RETRY_MASK   0xf
+#define     MAC_HALF_DUPLX_CTRL_EXC_DEF_EN   0x10000 /* 1: Allow the transmission of a packet which has been excessively deferred */
+#define     MAC_HALF_DUPLX_CTRL_NO_BACK_C    0x20000 /* 1: No back-off on collision, immediately start the retransmission */
+#define     MAC_HALF_DUPLX_CTRL_NO_BACK_P    0x40000 /* 1: No back-off on backpressure, immediately start the transmission after back pressure */
+#define     MAC_HALF_DUPLX_CTRL_ABEBE        0x80000 /* 1: Alternative Binary Exponential Back-off Enabled */
+#define     MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT  20      /* Maximum binary exponential number */
+#define     MAC_HALF_DUPLX_CTRL_ABEBT_MASK   0xf
+#define     MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24      /* IPG to start JAM for collision based flow control in half-duplex */
+#define     MAC_HALF_DUPLX_CTRL_JAMIPG_MASK  0xf     /* mode. In unit of 8-bit time */
+
+/* Maximum Frame Length Control Register   */
+#define REG_MTU                     0x149c
+
+/* Wake-On-Lan control register */
+#define REG_WOL_CTRL                0x14a0
+#define     WOL_PATTERN_EN                  0x00000001
+#define     WOL_PATTERN_PME_EN              0x00000002
+#define     WOL_MAGIC_EN                    0x00000004
+#define     WOL_MAGIC_PME_EN                0x00000008
+#define     WOL_LINK_CHG_EN                 0x00000010
+#define     WOL_LINK_CHG_PME_EN             0x00000020
+#define     WOL_PATTERN_ST                  0x00000100
+#define     WOL_MAGIC_ST                    0x00000200
+#define     WOL_LINKCHG_ST                  0x00000400
+#define     WOL_CLK_SWITCH_EN               0x00008000
+#define     WOL_PT0_EN                      0x00010000
+#define     WOL_PT1_EN                      0x00020000
+#define     WOL_PT2_EN                      0x00040000
+#define     WOL_PT3_EN                      0x00080000
+#define     WOL_PT4_EN                      0x00100000
+#define     WOL_PT5_EN                      0x00200000
+#define     WOL_PT6_EN                      0x00400000
+/* WOL Length ( 2 DWORD ) */
+#define REG_WOL_PATTERN_LEN         0x14a4
+#define     WOL_PT_LEN_MASK                 0x7f
+#define     WOL_PT0_LEN_SHIFT               0
+#define     WOL_PT1_LEN_SHIFT               8
+#define     WOL_PT2_LEN_SHIFT               16
+#define     WOL_PT3_LEN_SHIFT               24
+#define     WOL_PT4_LEN_SHIFT               0
+#define     WOL_PT5_LEN_SHIFT               8
+#define     WOL_PT6_LEN_SHIFT               16
+
+/* Internal SRAM Partition Register */
+#define REG_SRAM_TRD_ADDR           0x1518
+#define REG_SRAM_TRD_LEN            0x151C
+#define REG_SRAM_RXF_ADDR           0x1520
+#define REG_SRAM_RXF_LEN            0x1524
+#define REG_SRAM_TXF_ADDR           0x1528
+#define REG_SRAM_TXF_LEN            0x152C
+#define REG_SRAM_TCPH_ADDR          0x1530
+#define REG_SRAM_PKTH_ADDR          0x1532
+
+/* Load Ptr Register */
+#define REG_LOAD_PTR                0x1534  /* Software sets this bit after the initialization of the head and tail */
+
+/*
+ * addresses of all descriptors, as well as the following descriptor
+ * control register, which triggers each function block to load the head
+ * pointer to prepare for the operation. This bit is then self-cleared
+ * after one cycle.
+ */
+
+/* Descriptor Control register  */
+#define REG_RXF3_BASE_ADDR_HI           0x153C
+#define REG_DESC_BASE_ADDR_HI           0x1540
+#define REG_RXF0_BASE_ADDR_HI           0x1540 /* share with DESC BASE ADDR HI */
+#define REG_HOST_RXF0_PAGE0_LO          0x1544
+#define REG_HOST_RXF0_PAGE1_LO          0x1548
+#define REG_TPD_BASE_ADDR_LO            0x154C
+#define REG_RXF1_BASE_ADDR_HI           0x1550
+#define REG_RXF2_BASE_ADDR_HI           0x1554
+#define REG_HOST_RXFPAGE_SIZE           0x1558
+#define REG_TPD_RING_SIZE               0x155C
+/* RSS about */
+#define REG_RSS_KEY0                    0x14B0
+#define REG_RSS_KEY1                    0x14B4
+#define REG_RSS_KEY2                    0x14B8
+#define REG_RSS_KEY3                    0x14BC
+#define REG_RSS_KEY4                    0x14C0
+#define REG_RSS_KEY5                    0x14C4
+#define REG_RSS_KEY6                    0x14C8
+#define REG_RSS_KEY7                    0x14CC
+#define REG_RSS_KEY8                    0x14D0
+#define REG_RSS_KEY9                    0x14D4
+#define REG_IDT_TABLE4                  0x14E0
+#define REG_IDT_TABLE5                  0x14E4
+#define REG_IDT_TABLE6                  0x14E8
+#define REG_IDT_TABLE7                  0x14EC
+#define REG_IDT_TABLE0                  0x1560
+#define REG_IDT_TABLE1                  0x1564
+#define REG_IDT_TABLE2                  0x1568
+#define REG_IDT_TABLE3                  0x156C
+#define REG_IDT_TABLE                   REG_IDT_TABLE0
+#define REG_RSS_HASH_VALUE              0x1570
+#define REG_RSS_HASH_FLAG               0x1574
+#define REG_BASE_CPU_NUMBER             0x157C
+
+
+/* TXQ Control Register */
+#define REG_TXQ_CTRL                0x1580
+#define     TXQ_CTRL_NUM_TPD_BURST_MASK     0xF
+#define     TXQ_CTRL_NUM_TPD_BURST_SHIFT    0
+#define     TXQ_CTRL_EN                     0x20  /* 1: Enable TXQ */
+#define     TXQ_CTRL_ENH_MODE               0x40  /* Performance enhancement mode, in which up to two back-to-back DMA read commands might be dispatched. */
+#define     TXQ_CTRL_TXF_BURST_NUM_SHIFT    16    /* Number of data byte to read in a cache-aligned burst. Each SRAM entry is 8-byte in length. */
+#define     TXQ_CTRL_TXF_BURST_NUM_MASK     0xffff
+
+/* Jumbo packet Threshold for task offload */
+#define REG_TX_EARLY_TH                     0x1584 /* Jumbo frame threshold in QWORD unit. Packet greater than */
+/* JUMBO_TASK_OFFLOAD_THRESHOLD will not be task offloaded. */
+#define     TX_TX_EARLY_TH_MASK             0x7ff
+#define     TX_TX_EARLY_TH_SHIFT            0
+
+
+/* RXQ Control Register */
+#define REG_RXQ_CTRL                0x15A0
+#define         RXQ_CTRL_PBA_ALIGN_32                   0   /* rx-packet alignment */
+#define         RXQ_CTRL_PBA_ALIGN_64                   1
+#define         RXQ_CTRL_PBA_ALIGN_128                  2
+#define         RXQ_CTRL_PBA_ALIGN_256                  3
+#define         RXQ_CTRL_Q1_EN                         0x10
+#define         RXQ_CTRL_Q2_EN                         0x20
+#define         RXQ_CTRL_Q3_EN                         0x40
+#define         RXQ_CTRL_IPV6_XSUM_VERIFY_EN           0x80
+#define         RXQ_CTRL_HASH_TLEN_SHIFT                8
+#define         RXQ_CTRL_HASH_TLEN_MASK                 0xFF
+#define         RXQ_CTRL_HASH_TYPE_IPV4                 0x10000
+#define         RXQ_CTRL_HASH_TYPE_IPV4_TCP             0x20000
+#define         RXQ_CTRL_HASH_TYPE_IPV6                 0x40000
+#define         RXQ_CTRL_HASH_TYPE_IPV6_TCP             0x80000
+#define         RXQ_CTRL_RSS_MODE_DISABLE               0
+#define         RXQ_CTRL_RSS_MODE_SQSINT                0x4000000
+#define         RXQ_CTRL_RSS_MODE_MQUESINT              0x8000000
+#define         RXQ_CTRL_RSS_MODE_MQUEMINT              0xC000000
+#define         RXQ_CTRL_NIP_QUEUE_SEL_TBL              0x10000000
+#define         RXQ_CTRL_HASH_ENABLE                    0x20000000
+#define         RXQ_CTRL_CUT_THRU_EN                    0x40000000
+#define         RXQ_CTRL_EN                             0x80000000
+
+/* Rx jumbo packet threshold and rrd  retirement timer  */
+#define REG_RXQ_JMBOSZ_RRDTIM       0x15A4
+/*
+ * Jumbo packet threshold for non-VLAN packet, in QWORD (64-bit) unit.
+ * When the packet length greater than or equal to this value, RXQ
+ * shall start cut-through forwarding of the received packet.
+ */
+#define         RXQ_JMBOSZ_TH_MASK      0x7ff
+#define         RXQ_JMBOSZ_TH_SHIFT         0  /* RRD retirement timer. Decrement by 1 after every 512ns passes*/
+#define         RXQ_JMBO_LKAH_MASK          0xf
+#define         RXQ_JMBO_LKAH_SHIFT         11
+
+/* RXF flow control register */
+#define REG_RXQ_RXF_PAUSE_THRESH    0x15A8
+#define     RXQ_RXF_PAUSE_TH_HI_SHIFT       0
+#define     RXQ_RXF_PAUSE_TH_HI_MASK        0xfff
+#define     RXQ_RXF_PAUSE_TH_LO_SHIFT       16
+#define     RXQ_RXF_PAUSE_TH_LO_MASK        0xfff
+
+
+/* DMA Engine Control Register */
+#define REG_DMA_CTRL                0x15C0
+#define     DMA_CTRL_DMAR_IN_ORDER          0x1
+#define     DMA_CTRL_DMAR_ENH_ORDER         0x2
+#define     DMA_CTRL_DMAR_OUT_ORDER         0x4
+#define     DMA_CTRL_RCB_VALUE              0x8
+#define     DMA_CTRL_DMAR_BURST_LEN_SHIFT   4
+#define     DMA_CTRL_DMAR_BURST_LEN_MASK    7
+#define     DMA_CTRL_DMAW_BURST_LEN_SHIFT   7
+#define     DMA_CTRL_DMAW_BURST_LEN_MASK    7
+#define     DMA_CTRL_DMAR_REQ_PRI           0x400
+#define     DMA_CTRL_DMAR_DLY_CNT_MASK      0x1F
+#define     DMA_CTRL_DMAR_DLY_CNT_SHIFT     11
+#define     DMA_CTRL_DMAW_DLY_CNT_MASK      0xF
+#define     DMA_CTRL_DMAW_DLY_CNT_SHIFT     16
+#define     DMA_CTRL_TXCMB_EN               0x100000
+#define     DMA_CTRL_RXCMB_EN                          0x200000
+
+
+/* CMB/SMB Control Register */
+#define REG_SMB_STAT_TIMER                      0x15C4
+#define REG_TRIG_RRD_THRESH                     0x15CA
+#define REG_TRIG_TPD_THRESH                     0x15C8
+#define REG_TRIG_TXTIMER                        0x15CC
+#define REG_TRIG_RXTIMER                        0x15CE
+
+/* HOST RXF Page 1,2,3 address */
+#define REG_HOST_RXF1_PAGE0_LO                  0x15D0
+#define REG_HOST_RXF1_PAGE1_LO                  0x15D4
+#define REG_HOST_RXF2_PAGE0_LO                  0x15D8
+#define REG_HOST_RXF2_PAGE1_LO                  0x15DC
+#define REG_HOST_RXF3_PAGE0_LO                  0x15E0
+#define REG_HOST_RXF3_PAGE1_LO                  0x15E4
+
+/* Mail box */
+#define REG_MB_RXF1_RADDR                       0x15B4
+#define REG_MB_RXF2_RADDR                       0x15B8
+#define REG_MB_RXF3_RADDR                       0x15BC
+#define REG_MB_TPD_PROD_IDX                     0x15F0
+
+/* RXF-Page 0-3  PageNo & Valid bit */
+#define REG_HOST_RXF0_PAGE0_VLD     0x15F4
+#define     HOST_RXF_VALID              1
+#define     HOST_RXF_PAGENO_SHIFT       1
+#define     HOST_RXF_PAGENO_MASK        0x7F
+#define REG_HOST_RXF0_PAGE1_VLD     0x15F5
+#define REG_HOST_RXF1_PAGE0_VLD     0x15F6
+#define REG_HOST_RXF1_PAGE1_VLD     0x15F7
+#define REG_HOST_RXF2_PAGE0_VLD     0x15F8
+#define REG_HOST_RXF2_PAGE1_VLD     0x15F9
+#define REG_HOST_RXF3_PAGE0_VLD     0x15FA
+#define REG_HOST_RXF3_PAGE1_VLD     0x15FB
+
+/* Interrupt Status Register */
+#define REG_ISR    0x1600
+#define  ISR_SMB               1
+#define  ISR_TIMER             2       /* Interrupt when Timer is counted down to zero */
+/*
+ * Software manual interrupt, for debug. Set when SW_MAN_INT_EN is set
+ * in Table 51 Selene Master Control Register (Offset 0x1400).
+ */
+#define  ISR_MANUAL            4
+#define  ISR_HW_RXF_OV          8        /* RXF overflow interrupt */
+#define  ISR_HOST_RXF0_OV       0x10
+#define  ISR_HOST_RXF1_OV       0x20
+#define  ISR_HOST_RXF2_OV       0x40
+#define  ISR_HOST_RXF3_OV       0x80
+#define  ISR_TXF_UN             0x100
+#define  ISR_RX0_PAGE_FULL      0x200
+#define  ISR_DMAR_TO_RST        0x400
+#define  ISR_DMAW_TO_RST        0x800
+#define  ISR_GPHY               0x1000
+#define  ISR_TX_CREDIT          0x2000
+#define  ISR_GPHY_LPW           0x4000    /* GPHY low power state interrupt */
+#define  ISR_RX_PKT             0x10000   /* One packet received, triggered by RFD */
+#define  ISR_TX_PKT             0x20000   /* One packet transmitted, triggered by TPD */
+#define  ISR_TX_DMA             0x40000
+#define  ISR_RX_PKT_1           0x80000
+#define  ISR_RX_PKT_2           0x100000
+#define  ISR_RX_PKT_3           0x200000
+#define  ISR_MAC_RX             0x400000
+#define  ISR_MAC_TX             0x800000
+#define  ISR_UR_DETECTED        0x1000000
+#define  ISR_FERR_DETECTED      0x2000000
+#define  ISR_NFERR_DETECTED     0x4000000
+#define  ISR_CERR_DETECTED      0x8000000
+#define  ISR_PHY_LINKDOWN       0x10000000
+#define  ISR_DIS_INT            0x80000000
+
+
+/* Interrupt Mask Register */
+#define REG_IMR 0x1604
+
+
+#define IMR_NORMAL_MASK (\
+               ISR_SMB         |\
+               ISR_TXF_UN      |\
+               ISR_HW_RXF_OV   |\
+               ISR_HOST_RXF0_OV|\
+               ISR_MANUAL      |\
+               ISR_GPHY        |\
+               ISR_GPHY_LPW    |\
+               ISR_DMAR_TO_RST |\
+               ISR_DMAW_TO_RST |\
+               ISR_PHY_LINKDOWN|\
+               ISR_RX_PKT      |\
+               ISR_TX_PKT)
+
+#define ISR_TX_EVENT (ISR_TXF_UN | ISR_TX_PKT)
+#define ISR_RX_EVENT (ISR_HOST_RXF0_OV | ISR_HW_RXF_OV | ISR_RX_PKT)
+
+#define REG_MAC_RX_STATUS_BIN 0x1700
+#define REG_MAC_RX_STATUS_END 0x175c
+#define REG_MAC_TX_STATUS_BIN 0x1760
+#define REG_MAC_TX_STATUS_END 0x17c0
+
+/* Hardware Offset Register */
+#define REG_HOST_RXF0_PAGEOFF 0x1800
+#define REG_TPD_CONS_IDX      0x1804
+#define REG_HOST_RXF1_PAGEOFF 0x1808
+#define REG_HOST_RXF2_PAGEOFF 0x180C
+#define REG_HOST_RXF3_PAGEOFF 0x1810
+
+/* RXF-Page 0-3 Offset DMA Address */
+#define REG_HOST_RXF0_MB0_LO  0x1820
+#define REG_HOST_RXF0_MB1_LO  0x1824
+#define REG_HOST_RXF1_MB0_LO  0x1828
+#define REG_HOST_RXF1_MB1_LO  0x182C
+#define REG_HOST_RXF2_MB0_LO  0x1830
+#define REG_HOST_RXF2_MB1_LO  0x1834
+#define REG_HOST_RXF3_MB0_LO  0x1838
+#define REG_HOST_RXF3_MB1_LO  0x183C
+
+/* Tpd CMB DMA Address */
+#define REG_HOST_TX_CMB_LO    0x1840
+#define REG_HOST_SMB_ADDR_LO  0x1844
+
+/* DEBUG ADDR */
+#define REG_DEBUG_DATA0 0x1900
+#define REG_DEBUG_DATA1 0x1904
+
+/***************************** MII definition ***************************************/
+/* PHY Common Register */
+#define MII_BMCR                        0x00
+#define MII_BMSR                        0x01
+#define MII_PHYSID1                     0x02
+#define MII_PHYSID2                     0x03
+#define MII_ADVERTISE                   0x04
+#define MII_LPA                         0x05
+#define MII_EXPANSION                   0x06
+#define MII_AT001_CR                    0x09
+#define MII_AT001_SR                    0x0A
+#define MII_AT001_ESR                   0x0F
+#define MII_AT001_PSCR                  0x10
+#define MII_AT001_PSSR                  0x11
+#define MII_INT_CTRL                    0x12
+#define MII_INT_STATUS                  0x13
+#define MII_SMARTSPEED                  0x14
+#define MII_RERRCOUNTER                 0x15
+#define MII_SREVISION                   0x16
+#define MII_RESV1                       0x17
+#define MII_LBRERROR                    0x18
+#define MII_PHYADDR                     0x19
+#define MII_RESV2                       0x1a
+#define MII_TPISTATUS                   0x1b
+#define MII_NCONFIG                     0x1c
+
+#define MII_DBG_ADDR                   0x1D
+#define MII_DBG_DATA                   0x1E
+
+
+/* PHY Control Register */
+#define MII_CR_SPEED_SELECT_MSB                  0x0040  /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_COLL_TEST_ENABLE                  0x0080  /* Collision test enable */
+#define MII_CR_FULL_DUPLEX                       0x0100  /* FDX =1, half duplex =0 */
+#define MII_CR_RESTART_AUTO_NEG                  0x0200  /* Restart auto negotiation */
+#define MII_CR_ISOLATE                           0x0400  /* Isolate PHY from MII */
+#define MII_CR_POWER_DOWN                        0x0800  /* Power down */
+#define MII_CR_AUTO_NEG_EN                       0x1000  /* Auto Neg Enable */
+#define MII_CR_SPEED_SELECT_LSB                  0x2000  /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_LOOPBACK                          0x4000  /* 0 = normal, 1 = loopback */
+#define MII_CR_RESET                             0x8000  /* 0 = normal, 1 = PHY reset */
+#define MII_CR_SPEED_MASK                        0x2040
+#define MII_CR_SPEED_1000                        0x0040
+#define MII_CR_SPEED_100                         0x2000
+#define MII_CR_SPEED_10                          0x0000
+
+
+/* PHY Status Register */
+#define MII_SR_EXTENDED_CAPS                     0x0001  /* Extended register capabilities */
+#define MII_SR_JABBER_DETECT                     0x0002  /* Jabber Detected */
+#define MII_SR_LINK_STATUS                       0x0004  /* Link Status 1 = link */
+#define MII_SR_AUTONEG_CAPS                      0x0008  /* Auto Neg Capable */
+#define MII_SR_REMOTE_FAULT                      0x0010  /* Remote Fault Detect */
+#define MII_SR_AUTONEG_COMPLETE                  0x0020  /* Auto Neg Complete */
+#define MII_SR_PREAMBLE_SUPPRESS                 0x0040  /* Preamble may be suppressed */
+#define MII_SR_EXTENDED_STATUS                   0x0100  /* Ext. status info in Reg 0x0F */
+#define MII_SR_100T2_HD_CAPS                     0x0200  /* 100T2 Half Duplex Capable */
+#define MII_SR_100T2_FD_CAPS                     0x0400  /* 100T2 Full Duplex Capable */
+#define MII_SR_10T_HD_CAPS                       0x0800  /* 10T   Half Duplex Capable */
+#define MII_SR_10T_FD_CAPS                       0x1000  /* 10T   Full Duplex Capable */
+#define MII_SR_100X_HD_CAPS                      0x2000  /* 100X  Half Duplex Capable */
+#define MII_SR_100X_FD_CAPS                      0x4000  /* 100X  Full Duplex Capable */
+#define MII_SR_100T4_CAPS                        0x8000  /* 100T4 Capable */
+
+/* Link partner ability register. */
+#define MII_LPA_SLCT                             0x001f  /* Same as advertise selector  */
+#define MII_LPA_10HALF                           0x0020  /* Can do 10mbps half-duplex   */
+#define MII_LPA_10FULL                           0x0040  /* Can do 10mbps full-duplex   */
+#define MII_LPA_100HALF                          0x0080  /* Can do 100mbps half-duplex  */
+#define MII_LPA_100FULL                          0x0100  /* Can do 100mbps full-duplex  */
+#define MII_LPA_100BASE4                         0x0200  /* 100BASE-T4  */
+#define MII_LPA_PAUSE                            0x0400  /* PAUSE */
+#define MII_LPA_ASYPAUSE                         0x0800  /* Asymmetrical PAUSE */
+#define MII_LPA_RFAULT                           0x2000  /* Link partner faulted        */
+#define MII_LPA_LPACK                            0x4000  /* Link partner acked us       */
+#define MII_LPA_NPAGE                            0x8000  /* Next page bit               */
+
+/* Autoneg Advertisement Register */
+#define MII_AR_SELECTOR_FIELD                   0x0001  /* indicates IEEE 802.3 CSMA/CD */
+#define MII_AR_10T_HD_CAPS                      0x0020  /* 10T   Half Duplex Capable */
+#define MII_AR_10T_FD_CAPS                      0x0040  /* 10T   Full Duplex Capable */
+#define MII_AR_100TX_HD_CAPS                    0x0080  /* 100TX Half Duplex Capable */
+#define MII_AR_100TX_FD_CAPS                    0x0100  /* 100TX Full Duplex Capable */
+#define MII_AR_100T4_CAPS                       0x0200  /* 100T4 Capable */
+#define MII_AR_PAUSE                            0x0400  /* Pause operation desired */
+#define MII_AR_ASM_DIR                          0x0800  /* Asymmetric Pause Direction bit */
+#define MII_AR_REMOTE_FAULT                     0x2000  /* Remote Fault detected */
+#define MII_AR_NEXT_PAGE                        0x8000  /* Next Page ability supported */
+#define MII_AR_SPEED_MASK                       0x01E0
+#define MII_AR_DEFAULT_CAP_MASK                 0x0DE0
+
+/* 1000BASE-T Control Register */
+#define MII_AT001_CR_1000T_HD_CAPS              0x0100  /* Advertise 1000T HD capability */
+#define MII_AT001_CR_1000T_FD_CAPS              0x0200  /* Advertise 1000T FD capability  */
+#define MII_AT001_CR_1000T_REPEATER_DTE         0x0400  /* 1=Repeater/switch device port */
+/* 0=DTE device */
+#define MII_AT001_CR_1000T_MS_VALUE             0x0800  /* 1=Configure PHY as Master */
+/* 0=Configure PHY as Slave */
+#define MII_AT001_CR_1000T_MS_ENABLE            0x1000  /* 1=Master/Slave manual config value */
+/* 0=Automatic Master/Slave config */
+#define MII_AT001_CR_1000T_TEST_MODE_NORMAL     0x0000  /* Normal Operation */
+#define MII_AT001_CR_1000T_TEST_MODE_1          0x2000  /* Transmit Waveform test */
+#define MII_AT001_CR_1000T_TEST_MODE_2          0x4000  /* Master Transmit Jitter test */
+#define MII_AT001_CR_1000T_TEST_MODE_3          0x6000  /* Slave Transmit Jitter test */
+#define MII_AT001_CR_1000T_TEST_MODE_4          0x8000  /* Transmitter Distortion test */
+#define MII_AT001_CR_1000T_SPEED_MASK           0x0300
+#define MII_AT001_CR_1000T_DEFAULT_CAP_MASK     0x0300
+
+/* 1000BASE-T Status Register */
+#define MII_AT001_SR_1000T_LP_HD_CAPS           0x0400  /* LP is 1000T HD capable */
+#define MII_AT001_SR_1000T_LP_FD_CAPS           0x0800  /* LP is 1000T FD capable */
+#define MII_AT001_SR_1000T_REMOTE_RX_STATUS     0x1000  /* Remote receiver OK */
+#define MII_AT001_SR_1000T_LOCAL_RX_STATUS      0x2000  /* Local receiver OK */
+#define MII_AT001_SR_1000T_MS_CONFIG_RES        0x4000  /* 1=Local TX is Master, 0=Slave */
+#define MII_AT001_SR_1000T_MS_CONFIG_FAULT      0x8000  /* Master/Slave config fault */
+#define MII_AT001_SR_1000T_REMOTE_RX_STATUS_SHIFT   12
+#define MII_AT001_SR_1000T_LOCAL_RX_STATUS_SHIFT    13
+
+/* Extended Status Register */
+#define MII_AT001_ESR_1000T_HD_CAPS             0x1000  /* 1000T HD capable */
+#define MII_AT001_ESR_1000T_FD_CAPS             0x2000  /* 1000T FD capable */
+#define MII_AT001_ESR_1000X_HD_CAPS             0x4000  /* 1000X HD capable */
+#define MII_AT001_ESR_1000X_FD_CAPS             0x8000  /* 1000X FD capable */
+
+/* AT001 PHY Specific Control Register */
+#define MII_AT001_PSCR_JABBER_DISABLE           0x0001  /* 1=Jabber Function disabled */
+#define MII_AT001_PSCR_POLARITY_REVERSAL        0x0002  /* 1=Polarity Reversal enabled */
+#define MII_AT001_PSCR_SQE_TEST                 0x0004  /* 1=SQE Test enabled */
+#define MII_AT001_PSCR_MAC_POWERDOWN            0x0008
+#define MII_AT001_PSCR_CLK125_DISABLE           0x0010  /* 1=CLK125 low,
+                                                        * 0=CLK125 toggling
+                                                        */
+#define MII_AT001_PSCR_MDI_MANUAL_MODE          0x0000  /* MDI Crossover Mode bits 6:5 */
+/* Manual MDI configuration */
+#define MII_AT001_PSCR_MDIX_MANUAL_MODE         0x0020  /* Manual MDIX configuration */
+#define MII_AT001_PSCR_AUTO_X_1000T             0x0040  /* 1000BASE-T: Auto crossover,
+                                                        *  100BASE-TX/10BASE-T:
+                                                        *  MDI Mode
+                                                        */
+#define MII_AT001_PSCR_AUTO_X_MODE              0x0060  /* Auto crossover enabled
+                                                        * all speeds.
+                                                        */
+#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE     0x0080
+/* 1=Enable Extended 10BASE-T distance
+ * (Lower 10BASE-T RX Threshold)
+ * 0=Normal 10BASE-T RX Threshold */
+#define MII_AT001_PSCR_MII_5BIT_ENABLE          0x0100
+/* 1=5-Bit interface in 100BASE-TX
+ * 0=MII interface in 100BASE-TX */
+#define MII_AT001_PSCR_SCRAMBLER_DISABLE        0x0200  /* 1=Scrambler disable */
+#define MII_AT001_PSCR_FORCE_LINK_GOOD          0x0400  /* 1=Force link good */
+#define MII_AT001_PSCR_ASSERT_CRS_ON_TX         0x0800  /* 1=Assert CRS on Transmit */
+#define MII_AT001_PSCR_POLARITY_REVERSAL_SHIFT    1
+#define MII_AT001_PSCR_AUTO_X_MODE_SHIFT          5
+#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
+/* AT001 PHY Specific Status Register */
+#define MII_AT001_PSSR_SPD_DPLX_RESOLVED        0x0800  /* 1=Speed & Duplex resolved */
+#define MII_AT001_PSSR_DPLX                     0x2000  /* 1=Duplex 0=Half Duplex */
+#define MII_AT001_PSSR_SPEED                    0xC000  /* Speed, bits 14:15 */
+#define MII_AT001_PSSR_10MBS                    0x0000  /* 00=10Mbs */
+#define MII_AT001_PSSR_100MBS                   0x4000  /* 01=100Mbs */
+#define MII_AT001_PSSR_1000MBS                  0x8000  /* 10=1000Mbs */
+
+#endif /*_ATHL1E_HW_H_*/
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
new file mode 100644 (file)
index 0000000..35264c2
--- /dev/null
@@ -0,0 +1,2599 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public 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 "atl1e.h"
+
+#define DRV_VERSION "1.0.0.7-NAPI"
+
+char atl1e_driver_name[] = "ATL1E";
+char atl1e_driver_version[] = DRV_VERSION;
+#define PCI_DEVICE_ID_ATTANSIC_L1E      0x1026
+/*
+ * atl1e_pci_tbl - PCI Device ID Table
+ *
+ * Wildcard entries (PCI_ANY_ID) should come last
+ * Last entry must be all 0s
+ *
+ * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
+ *   Class, Class Mask, private data (not used) }
+ */
+static struct pci_device_id atl1e_pci_tbl[] = {
+       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1E)},
+       /* required last entry */
+       { 0 }
+};
+MODULE_DEVICE_TABLE(pci, atl1e_pci_tbl);
+
+MODULE_AUTHOR("Atheros Corporation, <xiong.huang@atheros.com>, Jie Yang <jie.yang@atheros.com>");
+MODULE_DESCRIPTION("Atheros 1000M Ethernet Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+static inline void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter);
+
+static const u16
+atl1e_rx_page_vld_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
+{
+       {REG_HOST_RXF0_PAGE0_VLD, REG_HOST_RXF0_PAGE1_VLD},
+       {REG_HOST_RXF1_PAGE0_VLD, REG_HOST_RXF1_PAGE1_VLD},
+       {REG_HOST_RXF2_PAGE0_VLD, REG_HOST_RXF2_PAGE1_VLD},
+       {REG_HOST_RXF3_PAGE0_VLD, REG_HOST_RXF3_PAGE1_VLD}
+};
+
+static const u16 atl1e_rx_page_hi_addr_regs[AT_MAX_RECEIVE_QUEUE] =
+{
+       REG_RXF0_BASE_ADDR_HI,
+       REG_RXF1_BASE_ADDR_HI,
+       REG_RXF2_BASE_ADDR_HI,
+       REG_RXF3_BASE_ADDR_HI
+};
+
+static const u16
+atl1e_rx_page_lo_addr_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
+{
+       {REG_HOST_RXF0_PAGE0_LO, REG_HOST_RXF0_PAGE1_LO},
+       {REG_HOST_RXF1_PAGE0_LO, REG_HOST_RXF1_PAGE1_LO},
+       {REG_HOST_RXF2_PAGE0_LO, REG_HOST_RXF2_PAGE1_LO},
+       {REG_HOST_RXF3_PAGE0_LO, REG_HOST_RXF3_PAGE1_LO}
+};
+
+static const u16
+atl1e_rx_page_write_offset_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
+{
+       {REG_HOST_RXF0_MB0_LO,  REG_HOST_RXF0_MB1_LO},
+       {REG_HOST_RXF1_MB0_LO,  REG_HOST_RXF1_MB1_LO},
+       {REG_HOST_RXF2_MB0_LO,  REG_HOST_RXF2_MB1_LO},
+       {REG_HOST_RXF3_MB0_LO,  REG_HOST_RXF3_MB1_LO}
+};
+
+static const u16 atl1e_pay_load_size[] = {
+       128, 256, 512, 1024, 2048, 4096,
+};
+
+/*
+ * atl1e_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ */
+static inline void atl1e_irq_enable(struct atl1e_adapter *adapter)
+{
+       if (likely(atomic_dec_and_test(&adapter->irq_sem))) {
+               AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
+               AT_WRITE_REG(&adapter->hw, REG_IMR, IMR_NORMAL_MASK);
+               AT_WRITE_FLUSH(&adapter->hw);
+       }
+}
+
+/*
+ * atl1e_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl1e_irq_disable(struct atl1e_adapter *adapter)
+{
+       atomic_inc(&adapter->irq_sem);
+       AT_WRITE_REG(&adapter->hw, REG_IMR, 0);
+       AT_WRITE_FLUSH(&adapter->hw);
+       synchronize_irq(adapter->pdev->irq);
+}
+
+/*
+ * atl1e_irq_reset - reset interrupt confiure on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl1e_irq_reset(struct atl1e_adapter *adapter)
+{
+       atomic_set(&adapter->irq_sem, 0);
+       AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
+       AT_WRITE_REG(&adapter->hw, REG_IMR, 0);
+       AT_WRITE_FLUSH(&adapter->hw);
+}
+
+/*
+ * atl1e_phy_config - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
+ */
+static void atl1e_phy_config(unsigned long data)
+{
+       struct atl1e_adapter *adapter = (struct atl1e_adapter *) data;
+       struct atl1e_hw *hw = &adapter->hw;
+       unsigned long flags;
+
+       spin_lock_irqsave(&adapter->mdio_lock, flags);
+       atl1e_restart_autoneg(hw);
+       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+}
+
+void atl1e_reinit_locked(struct atl1e_adapter *adapter)
+{
+
+       WARN_ON(in_interrupt());
+       while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+               msleep(1);
+       atl1e_down(adapter);
+       atl1e_up(adapter);
+       clear_bit(__AT_RESETTING, &adapter->flags);
+}
+
+static void atl1e_reset_task(struct work_struct *work)
+{
+       struct atl1e_adapter *adapter;
+       adapter = container_of(work, struct atl1e_adapter, reset_task);
+
+       atl1e_reinit_locked(adapter);
+}
+
+static int atl1e_check_link(struct atl1e_adapter *adapter)
+{
+       struct atl1e_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+       struct pci_dev    *pdev   = adapter->pdev;
+       int err = 0;
+       u16 speed, duplex, phy_data;
+
+       /* MII_BMSR must read twise */
+       atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
+       atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
+       if ((phy_data & BMSR_LSTATUS) == 0) {
+               /* link down */
+               if (netif_carrier_ok(netdev)) { /* old link state: Up */
+                       u32 value;
+                       /* disable rx */
+                       value = AT_READ_REG(hw, REG_MAC_CTRL);
+                       value &= ~MAC_CTRL_RX_EN;
+                       AT_WRITE_REG(hw, REG_MAC_CTRL, value);
+                       adapter->link_speed = SPEED_0;
+                       netif_carrier_off(netdev);
+                       netif_stop_queue(netdev);
+               }
+       } else {
+               /* Link Up */
+               err = atl1e_get_speed_and_duplex(hw, &speed, &duplex);
+               if (unlikely(err))
+                       return err;
+
+               /* link result is our setting */
+               if (adapter->link_speed != speed ||
+                   adapter->link_duplex != duplex) {
+                       adapter->link_speed  = speed;
+                       adapter->link_duplex = duplex;
+                       atl1e_setup_mac_ctrl(adapter);
+                       dev_info(&pdev->dev,
+                               "%s: %s NIC Link is Up<%d Mbps %s>\n",
+                               atl1e_driver_name, netdev->name,
+                               adapter->link_speed,
+                               adapter->link_duplex == FULL_DUPLEX ?
+                               "Full Duplex" : "Half Duplex");
+               }
+
+               if (!netif_carrier_ok(netdev)) {
+                       /* Link down -> Up */
+                       netif_carrier_on(netdev);
+                       netif_wake_queue(netdev);
+               }
+       }
+       return 0;
+}
+
+/*
+ * atl1e_link_chg_task - deal with link change event Out of interrupt context
+ * @netdev: network interface device structure
+ */
+static void atl1e_link_chg_task(struct work_struct *work)
+{
+       struct atl1e_adapter *adapter;
+       unsigned long flags;
+
+       adapter = container_of(work, struct atl1e_adapter, link_chg_task);
+       spin_lock_irqsave(&adapter->mdio_lock, flags);
+       atl1e_check_link(adapter);
+       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+}
+
+static void atl1e_link_chg_event(struct atl1e_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       struct pci_dev    *pdev   = adapter->pdev;
+       u16 phy_data = 0;
+       u16 link_up = 0;
+
+       spin_lock(&adapter->mdio_lock);
+       atl1e_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+       atl1e_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+       spin_unlock(&adapter->mdio_lock);
+       link_up = phy_data & BMSR_LSTATUS;
+       /* notify upper layer link down ASAP */
+       if (!link_up) {
+               if (netif_carrier_ok(netdev)) {
+                       /* old link state: Up */
+                       dev_info(&pdev->dev, "%s: %s NIC Link is Down\n",
+                                       atl1e_driver_name, netdev->name);
+                       adapter->link_speed = SPEED_0;
+                       netif_stop_queue(netdev);
+               }
+       }
+       schedule_work(&adapter->link_chg_task);
+}
+
+static void atl1e_del_timer(struct atl1e_adapter *adapter)
+{
+       del_timer_sync(&adapter->phy_config_timer);
+}
+
+static void atl1e_cancel_work(struct atl1e_adapter *adapter)
+{
+       cancel_work_sync(&adapter->reset_task);
+       cancel_work_sync(&adapter->link_chg_task);
+}
+
+/*
+ * atl1e_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ */
+static void atl1e_tx_timeout(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       /* Do the reset outside of interrupt context */
+       schedule_work(&adapter->reset_task);
+}
+
+/*
+ * atl1e_set_multi - Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_multi entry point is called whenever the multicast address
+ * list or the network interface flags are updated.  This routine is
+ * responsible for configuring the hardware for proper multicast,
+ * promiscuous mode, and all-multi behavior.
+ */
+static void atl1e_set_multi(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+       struct dev_mc_list *mc_ptr;
+       u32 mac_ctrl_data = 0;
+       u32 hash_value;
+
+       /* Check for Promiscuous and All Multicast modes */
+       mac_ctrl_data = AT_READ_REG(hw, REG_MAC_CTRL);
+
+       if (netdev->flags & IFF_PROMISC) {
+               mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
+       } else if (netdev->flags & IFF_ALLMULTI) {
+               mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
+               mac_ctrl_data &= ~MAC_CTRL_PROMIS_EN;
+       } else {
+               mac_ctrl_data &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
+       }
+
+       AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+
+       /* clear the old settings from the multicast hash table */
+       AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
+       AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
+
+       /* comoute mc addresses' hash value ,and put it into hash table */
+       for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
+               hash_value = atl1e_hash_mc_addr(hw, mc_ptr->dmi_addr);
+               atl1e_hash_set(hw, hash_value);
+       }
+}
+
+static void atl1e_vlan_rx_register(struct net_device *netdev,
+                                  struct vlan_group *grp)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct pci_dev *pdev = adapter->pdev;
+       u32 mac_ctrl_data = 0;
+
+       dev_dbg(&pdev->dev, "atl1e_vlan_rx_register\n");
+
+       atl1e_irq_disable(adapter);
+
+       adapter->vlgrp = grp;
+       mac_ctrl_data = AT_READ_REG(&adapter->hw, REG_MAC_CTRL);
+
+       if (grp) {
+               /* enable VLAN tag insert/strip */
+               mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
+       } else {
+               /* disable VLAN tag insert/strip */
+               mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN;
+       }
+
+       AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data);
+       atl1e_irq_enable(adapter);
+}
+
+static void atl1e_restore_vlan(struct atl1e_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+
+       dev_dbg(&pdev->dev, "atl1e_restore_vlan !");
+       atl1e_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+}
+/*
+ * atl1e_set_mac - Change the Ethernet Address of the NIC
+ * @netdev: network interface device structure
+ * @p: pointer to an address structure
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl1e_set_mac_addr(struct net_device *netdev, void *p)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct sockaddr *addr = p;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       if (netif_running(netdev))
+               return -EBUSY;
+
+       memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+       memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
+
+       atl1e_hw_set_mac_addr(&adapter->hw);
+
+       return 0;
+}
+
+/*
+ * atl1e_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl1e_change_mtu(struct net_device *netdev, int new_mtu)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       int old_mtu   = netdev->mtu;
+       int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+
+       if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
+                       (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+               dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
+               return -EINVAL;
+       }
+       /* set MTU */
+       if (old_mtu != new_mtu && netif_running(netdev)) {
+               while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+                       msleep(1);
+               netdev->mtu = new_mtu;
+               adapter->hw.max_frame_size = new_mtu;
+               adapter->hw.rx_jumbo_th = (max_frame + 7) >> 3;
+               atl1e_down(adapter);
+               atl1e_up(adapter);
+               clear_bit(__AT_RESETTING, &adapter->flags);
+       }
+       return 0;
+}
+
+/*
+ *  caller should hold mdio_lock
+ */
+static int atl1e_mdio_read(struct net_device *netdev, int phy_id, int reg_num)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       u16 result;
+
+       atl1e_read_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, &result);
+       return result;
+}
+
+static void atl1e_mdio_write(struct net_device *netdev, int phy_id,
+                            int reg_num, int val)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       atl1e_write_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, val);
+}
+
+/*
+ * atl1e_mii_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl1e_mii_ioctl(struct net_device *netdev,
+                          struct ifreq *ifr, int cmd)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct pci_dev *pdev = adapter->pdev;
+       struct mii_ioctl_data *data = if_mii(ifr);
+       unsigned long flags;
+       int retval = 0;
+
+       if (!netif_running(netdev))
+               return -EINVAL;
+
+       spin_lock_irqsave(&adapter->mdio_lock, flags);
+       switch (cmd) {
+       case SIOCGMIIPHY:
+               data->phy_id = 0;
+               break;
+
+       case SIOCGMIIREG:
+               if (!capable(CAP_NET_ADMIN)) {
+                       retval = -EPERM;
+                       goto out;
+               }
+               if (atl1e_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+                                   &data->val_out)) {
+                       retval = -EIO;
+                       goto out;
+               }
+               break;
+
+       case SIOCSMIIREG:
+               if (!capable(CAP_NET_ADMIN)) {
+                       retval = -EPERM;
+                       goto out;
+               }
+               if (data->reg_num & ~(0x1F)) {
+                       retval = -EFAULT;
+                       goto out;
+               }
+
+               dev_dbg(&pdev->dev, "<atl1e_mii_ioctl> write %x %x",
+                               data->reg_num, data->val_in);
+               if (atl1e_write_phy_reg(&adapter->hw,
+                                    data->reg_num, data->val_in)) {
+                       retval = -EIO;
+                       goto out;
+               }
+               break;
+
+       default:
+               retval = -EOPNOTSUPP;
+               break;
+       }
+out:
+       spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+       return retval;
+
+}
+
+/*
+ * atl1e_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl1e_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+       switch (cmd) {
+       case SIOCGMIIPHY:
+       case SIOCGMIIREG:
+       case SIOCSMIIREG:
+               return atl1e_mii_ioctl(netdev, ifr, cmd);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static void atl1e_setup_pcicmd(struct pci_dev *pdev)
+{
+       u16 cmd;
+
+       pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+       cmd &= ~(PCI_COMMAND_INTX_DISABLE | PCI_COMMAND_IO);
+       cmd |=  (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+       pci_write_config_word(pdev, PCI_COMMAND, cmd);
+
+       /*
+        * some motherboards BIOS(PXE/EFI) driver may set PME
+        * while they transfer control to OS (Windows/Linux)
+        * so we should clear this bit before NIC work normally
+        */
+       pci_write_config_dword(pdev, REG_PM_CTRLSTAT, 0);
+       msleep(1);
+}
+
+/*
+ * atl1e_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ *
+ */
+static int __devinit atl1e_alloc_queues(struct atl1e_adapter *adapter)
+{
+       return 0;
+}
+
+/*
+ * atl1e_sw_init - Initialize general software structures (struct atl1e_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * atl1e_sw_init initializes the Adapter private data structure.
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ */
+static int __devinit atl1e_sw_init(struct atl1e_adapter *adapter)
+{
+       struct atl1e_hw *hw   = &adapter->hw;
+       struct pci_dev  *pdev = adapter->pdev;
+       u32 phy_status_data = 0;
+
+       adapter->wol = 0;
+       adapter->link_speed = SPEED_0;   /* hardware init */
+       adapter->link_duplex = FULL_DUPLEX;
+       adapter->num_rx_queues = 1;
+
+       /* PCI config space info */
+       hw->vendor_id = pdev->vendor;
+       hw->device_id = pdev->device;
+       hw->subsystem_vendor_id = pdev->subsystem_vendor;
+       hw->subsystem_id = pdev->subsystem_device;
+
+       pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
+       pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
+
+       phy_status_data = AT_READ_REG(hw, REG_PHY_STATUS);
+       /* nic type */
+       if (hw->revision_id >= 0xF0) {
+               hw->nic_type = athr_l2e_revB;
+       } else {
+               if (phy_status_data & PHY_STATUS_100M)
+                       hw->nic_type = athr_l1e;
+               else
+                       hw->nic_type = athr_l2e_revA;
+       }
+
+       phy_status_data = AT_READ_REG(hw, REG_PHY_STATUS);
+
+       if (phy_status_data & PHY_STATUS_EMI_CA)
+               hw->emi_ca = true;
+       else
+               hw->emi_ca = false;
+
+       hw->phy_configured = false;
+       hw->preamble_len = 7;
+       hw->max_frame_size = adapter->netdev->mtu;
+       hw->rx_jumbo_th = (hw->max_frame_size + ETH_HLEN +
+                               VLAN_HLEN + ETH_FCS_LEN + 7) >> 3;
+
+       hw->rrs_type = atl1e_rrs_disable;
+       hw->indirect_tab = 0;
+       hw->base_cpu = 0;
+
+       /* need confirm */
+
+       hw->ict = 50000;                 /* 100ms */
+       hw->smb_timer = 200000;          /* 200ms  */
+       hw->tpd_burst = 5;
+       hw->rrd_thresh = 1;
+       hw->tpd_thresh = adapter->tx_ring.count / 2;
+       hw->rx_count_down = 4;  /* 2us resolution */
+       hw->tx_count_down = hw->imt * 4 / 3;
+       hw->dmar_block = atl1e_dma_req_1024;
+       hw->dmaw_block = atl1e_dma_req_1024;
+       hw->dmar_dly_cnt = 15;
+       hw->dmaw_dly_cnt = 4;
+
+       if (atl1e_alloc_queues(adapter)) {
+               dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
+               return -ENOMEM;
+       }
+
+       atomic_set(&adapter->irq_sem, 1);
+       spin_lock_init(&adapter->mdio_lock);
+       spin_lock_init(&adapter->tx_lock);
+
+       set_bit(__AT_DOWN, &adapter->flags);
+
+       return 0;
+}
+
+/*
+ * atl1e_clean_tx_ring - Free Tx-skb
+ * @adapter: board private structure
+ */
+static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter)
+{
+       struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *)
+                               &adapter->tx_ring;
+       struct atl1e_tx_buffer *tx_buffer = NULL;
+       struct pci_dev *pdev = adapter->pdev;
+       u16 index, ring_count;
+
+       if (tx_ring->desc == NULL || tx_ring->tx_buffer == NULL)
+               return;
+
+       ring_count = tx_ring->count;
+       /* first unmmap dma */
+       for (index = 0; index < ring_count; index++) {
+               tx_buffer = &tx_ring->tx_buffer[index];
+               if (tx_buffer->dma) {
+                       pci_unmap_page(pdev, tx_buffer->dma,
+                                       tx_buffer->length, PCI_DMA_TODEVICE);
+                       tx_buffer->dma = 0;
+               }
+       }
+       /* second free skb */
+       for (index = 0; index < ring_count; index++) {
+               tx_buffer = &tx_ring->tx_buffer[index];
+               if (tx_buffer->skb) {
+                       dev_kfree_skb_any(tx_buffer->skb);
+                       tx_buffer->skb = NULL;
+               }
+       }
+       /* Zero out Tx-buffers */
+       memset(tx_ring->desc, 0, sizeof(struct atl1e_tpd_desc) *
+                               ring_count);
+       memset(tx_ring->tx_buffer, 0, sizeof(struct atl1e_tx_buffer) *
+                               ring_count);
+}
+
+/*
+ * atl1e_clean_rx_ring - Free rx-reservation skbs
+ * @adapter: board private structure
+ */
+static void atl1e_clean_rx_ring(struct atl1e_adapter *adapter)
+{
+       struct atl1e_rx_ring *rx_ring =
+               (struct atl1e_rx_ring *)&adapter->rx_ring;
+       struct atl1e_rx_page_desc *rx_page_desc = rx_ring->rx_page_desc;
+       u16 i, j;
+
+
+       if (adapter->ring_vir_addr == NULL)
+               return;
+       /* Zero out the descriptor ring */
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
+                       if (rx_page_desc[i].rx_page[j].addr != NULL) {
+                               memset(rx_page_desc[i].rx_page[j].addr, 0,
+                                               rx_ring->real_page_size);
+                       }
+               }
+       }
+}
+
+static void atl1e_cal_ring_size(struct atl1e_adapter *adapter, u32 *ring_size)
+{
+       *ring_size = ((u32)(adapter->tx_ring.count *
+                    sizeof(struct atl1e_tpd_desc) + 7
+                       /* tx ring, qword align */
+                    + adapter->rx_ring.real_page_size * AT_PAGE_NUM_PER_QUEUE *
+                       adapter->num_rx_queues + 31
+                       /* rx ring,  32 bytes align */
+                    + (1 + AT_PAGE_NUM_PER_QUEUE * adapter->num_rx_queues) *
+                       sizeof(u32) + 3));
+                       /* tx, rx cmd, dword align   */
+}
+
+static void atl1e_init_ring_resources(struct atl1e_adapter *adapter)
+{
+       struct atl1e_tx_ring *tx_ring = NULL;
+       struct atl1e_rx_ring *rx_ring = NULL;
+
+       tx_ring = &adapter->tx_ring;
+       rx_ring = &adapter->rx_ring;
+
+       rx_ring->real_page_size = adapter->rx_ring.page_size
+                                + adapter->hw.max_frame_size
+                                + ETH_HLEN + VLAN_HLEN
+                                + ETH_FCS_LEN;
+       rx_ring->real_page_size = roundup(rx_ring->real_page_size, 32);
+       atl1e_cal_ring_size(adapter, &adapter->ring_size);
+
+       adapter->ring_vir_addr = NULL;
+       adapter->rx_ring.desc = NULL;
+       rwlock_init(&adapter->tx_ring.tx_lock);
+
+       return;
+}
+
+/*
+ * Read / Write Ptr Initialize:
+ */
+static void atl1e_init_ring_ptrs(struct atl1e_adapter *adapter)
+{
+       struct atl1e_tx_ring *tx_ring = NULL;
+       struct atl1e_rx_ring *rx_ring = NULL;
+       struct atl1e_rx_page_desc *rx_page_desc = NULL;
+       int i, j;
+
+       tx_ring = &adapter->tx_ring;
+       rx_ring = &adapter->rx_ring;
+       rx_page_desc = rx_ring->rx_page_desc;
+
+       tx_ring->next_to_use = 0;
+       atomic_set(&tx_ring->next_to_clean, 0);
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               rx_page_desc[i].rx_using  = 0;
+               rx_page_desc[i].rx_nxseq = 0;
+               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
+                       *rx_page_desc[i].rx_page[j].write_offset_addr = 0;
+                       rx_page_desc[i].rx_page[j].read_offset = 0;
+               }
+       }
+}
+
+/*
+ * atl1e_free_ring_resources - Free Tx / RX descriptor Resources
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ */
+static void atl1e_free_ring_resources(struct atl1e_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+
+       atl1e_clean_tx_ring(adapter);
+       atl1e_clean_rx_ring(adapter);
+
+       if (adapter->ring_vir_addr) {
+               pci_free_consistent(pdev, adapter->ring_size,
+                               adapter->ring_vir_addr, adapter->ring_dma);
+               adapter->ring_vir_addr = NULL;
+       }
+
+       if (adapter->tx_ring.tx_buffer) {
+               kfree(adapter->tx_ring.tx_buffer);
+               adapter->tx_ring.tx_buffer = NULL;
+       }
+}
+
+/*
+ * atl1e_setup_mem_resources - allocate Tx / RX descriptor resources
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ */
+static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       struct atl1e_tx_ring *tx_ring;
+       struct atl1e_rx_ring *rx_ring;
+       struct atl1e_rx_page_desc  *rx_page_desc;
+       int size, i, j;
+       u32 offset = 0;
+       int err = 0;
+
+       if (adapter->ring_vir_addr != NULL)
+               return 0; /* alloced already */
+
+       tx_ring = &adapter->tx_ring;
+       rx_ring = &adapter->rx_ring;
+
+       /* real ring DMA buffer */
+
+       size = adapter->ring_size;
+       adapter->ring_vir_addr = pci_alloc_consistent(pdev,
+                       adapter->ring_size, &adapter->ring_dma);
+
+       if (adapter->ring_vir_addr == NULL) {
+               dev_err(&pdev->dev, "pci_alloc_consistent failed, "
+                                   "size = D%d", size);
+               return -ENOMEM;
+       }
+
+       memset(adapter->ring_vir_addr, 0, adapter->ring_size);
+
+       rx_page_desc = rx_ring->rx_page_desc;
+
+       /* Init TPD Ring */
+       tx_ring->dma = roundup(adapter->ring_dma, 8);
+       offset = tx_ring->dma - adapter->ring_dma;
+       tx_ring->desc = (struct atl1e_tpd_desc *)
+                       (adapter->ring_vir_addr + offset);
+       size = sizeof(struct atl1e_tx_buffer) * (tx_ring->count);
+       tx_ring->tx_buffer = kzalloc(size, GFP_KERNEL);
+       if (tx_ring->tx_buffer == NULL) {
+               dev_err(&pdev->dev, "kzalloc failed , size = D%d", size);
+               err = -ENOMEM;
+               goto failed;
+       }
+
+       /* Init RXF-Pages */
+       offset += (sizeof(struct atl1e_tpd_desc) * tx_ring->count);
+       offset = roundup(offset, 32);
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
+                       rx_page_desc[i].rx_page[j].dma =
+                               adapter->ring_dma + offset;
+                       rx_page_desc[i].rx_page[j].addr =
+                               adapter->ring_vir_addr + offset;
+                       offset += rx_ring->real_page_size;
+               }
+       }
+
+       /* Init CMB dma address */
+       tx_ring->cmb_dma = adapter->ring_dma + offset;
+       tx_ring->cmb     = (u32 *)(adapter->ring_vir_addr + offset);
+       offset += sizeof(u32);
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
+                       rx_page_desc[i].rx_page[j].write_offset_dma =
+                               adapter->ring_dma + offset;
+                       rx_page_desc[i].rx_page[j].write_offset_addr =
+                               adapter->ring_vir_addr + offset;
+                       offset += sizeof(u32);
+               }
+       }
+
+       if (unlikely(offset > adapter->ring_size)) {
+               dev_err(&pdev->dev, "offset(%d) > ring size(%d) !!\n",
+                               offset, adapter->ring_size);
+               err = -1;
+               goto failed;
+       }
+
+       return 0;
+failed:
+       if (adapter->ring_vir_addr != NULL) {
+               pci_free_consistent(pdev, adapter->ring_size,
+                               adapter->ring_vir_addr, adapter->ring_dma);
+               adapter->ring_vir_addr = NULL;
+       }
+       return err;
+}
+
+static inline void atl1e_configure_des_ring(const struct atl1e_adapter *adapter)
+{
+
+       struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw;
+       struct atl1e_rx_ring *rx_ring =
+                       (struct atl1e_rx_ring *)&adapter->rx_ring;
+       struct atl1e_tx_ring *tx_ring =
+                       (struct atl1e_tx_ring *)&adapter->tx_ring;
+       struct atl1e_rx_page_desc *rx_page_desc = NULL;
+       int i, j;
+
+       AT_WRITE_REG(hw, REG_DESC_BASE_ADDR_HI,
+                       (u32)((adapter->ring_dma & AT_DMA_HI_ADDR_MASK) >> 32));
+       AT_WRITE_REG(hw, REG_TPD_BASE_ADDR_LO,
+                       (u32)((tx_ring->dma) & AT_DMA_LO_ADDR_MASK));
+       AT_WRITE_REG(hw, REG_TPD_RING_SIZE, (u16)(tx_ring->count));
+       AT_WRITE_REG(hw, REG_HOST_TX_CMB_LO,
+                       (u32)((tx_ring->cmb_dma) & AT_DMA_LO_ADDR_MASK));
+
+       rx_page_desc = rx_ring->rx_page_desc;
+       /* RXF Page Physical address / Page Length */
+       for (i = 0; i < AT_MAX_RECEIVE_QUEUE; i++) {
+               AT_WRITE_REG(hw, atl1e_rx_page_hi_addr_regs[i],
+                                (u32)((adapter->ring_dma &
+                                AT_DMA_HI_ADDR_MASK) >> 32));
+               for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
+                       u32 page_phy_addr;
+                       u32 offset_phy_addr;
+
+                       page_phy_addr = rx_page_desc[i].rx_page[j].dma;
+                       offset_phy_addr =
+                                  rx_page_desc[i].rx_page[j].write_offset_dma;
+
+                       AT_WRITE_REG(hw, atl1e_rx_page_lo_addr_regs[i][j],
+                                       page_phy_addr & AT_DMA_LO_ADDR_MASK);
+                       AT_WRITE_REG(hw, atl1e_rx_page_write_offset_regs[i][j],
+                                       offset_phy_addr & AT_DMA_LO_ADDR_MASK);
+                       AT_WRITE_REGB(hw, atl1e_rx_page_vld_regs[i][j], 1);
+               }
+       }
+       /* Page Length */
+       AT_WRITE_REG(hw, REG_HOST_RXFPAGE_SIZE, rx_ring->page_size);
+       /* Load all of base address above */
+       AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
+
+       return;
+}
+
+static inline void atl1e_configure_tx(struct atl1e_adapter *adapter)
+{
+       struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw;
+       u32 dev_ctrl_data = 0;
+       u32 max_pay_load = 0;
+       u32 jumbo_thresh = 0;
+       u32 extra_size = 0;     /* Jumbo frame threshold in QWORD unit */
+
+       /* configure TXQ param */
+       if (hw->nic_type != athr_l2e_revB) {
+               extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN;
+               if (hw->max_frame_size <= 1500) {
+                       jumbo_thresh = hw->max_frame_size + extra_size;
+               } else if (hw->max_frame_size < 6*1024) {
+                       jumbo_thresh =
+                               (hw->max_frame_size + extra_size) * 2 / 3;
+               } else {
+                       jumbo_thresh = (hw->max_frame_size + extra_size) / 2;
+               }
+               AT_WRITE_REG(hw, REG_TX_EARLY_TH, (jumbo_thresh + 7) >> 3);
+       }
+
+       dev_ctrl_data = AT_READ_REG(hw, REG_DEVICE_CTRL);
+
+       max_pay_load  = ((dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT)) &
+                       DEVICE_CTRL_MAX_PAYLOAD_MASK;
+
+       hw->dmaw_block = min(max_pay_load, hw->dmaw_block);
+
+       max_pay_load  = ((dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT)) &
+                       DEVICE_CTRL_MAX_RREQ_SZ_MASK;
+       hw->dmar_block = min(max_pay_load, hw->dmar_block);
+
+       if (hw->nic_type != athr_l2e_revB)
+               AT_WRITE_REGW(hw, REG_TXQ_CTRL + 2,
+                             atl1e_pay_load_size[hw->dmar_block]);
+       /* enable TXQ */
+       AT_WRITE_REGW(hw, REG_TXQ_CTRL,
+                       (((u16)hw->tpd_burst & TXQ_CTRL_NUM_TPD_BURST_MASK)
+                        << TXQ_CTRL_NUM_TPD_BURST_SHIFT)
+                       | TXQ_CTRL_ENH_MODE | TXQ_CTRL_EN);
+       return;
+}
+
+static inline void atl1e_configure_rx(struct atl1e_adapter *adapter)
+{
+       struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw;
+       u32 rxf_len  = 0;
+       u32 rxf_low  = 0;
+       u32 rxf_high = 0;
+       u32 rxf_thresh_data = 0;
+       u32 rxq_ctrl_data = 0;
+
+       if (hw->nic_type != athr_l2e_revB) {
+               AT_WRITE_REGW(hw, REG_RXQ_JMBOSZ_RRDTIM,
+                             (u16)((hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK) <<
+                             RXQ_JMBOSZ_TH_SHIFT |
+                             (1 & RXQ_JMBO_LKAH_MASK) <<
+                             RXQ_JMBO_LKAH_SHIFT));
+
+               rxf_len  = AT_READ_REG(hw, REG_SRAM_RXF_LEN);
+               rxf_high = rxf_len * 4 / 5;
+               rxf_low  = rxf_len / 5;
+               rxf_thresh_data = ((rxf_high  & RXQ_RXF_PAUSE_TH_HI_MASK)
+                                 << RXQ_RXF_PAUSE_TH_HI_SHIFT) |
+                                 ((rxf_low & RXQ_RXF_PAUSE_TH_LO_MASK)
+                                 << RXQ_RXF_PAUSE_TH_LO_SHIFT);
+
+               AT_WRITE_REG(hw, REG_RXQ_RXF_PAUSE_THRESH, rxf_thresh_data);
+       }
+
+       /* RRS */
+       AT_WRITE_REG(hw, REG_IDT_TABLE, hw->indirect_tab);
+       AT_WRITE_REG(hw, REG_BASE_CPU_NUMBER, hw->base_cpu);
+
+       if (hw->rrs_type & atl1e_rrs_ipv4)
+               rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV4;
+
+       if (hw->rrs_type & atl1e_rrs_ipv4_tcp)
+               rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV4_TCP;
+
+       if (hw->rrs_type & atl1e_rrs_ipv6)
+               rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV6;
+
+       if (hw->rrs_type & atl1e_rrs_ipv6_tcp)
+               rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV6_TCP;
+
+       if (hw->rrs_type != atl1e_rrs_disable)
+               rxq_ctrl_data |=
+                       (RXQ_CTRL_HASH_ENABLE | RXQ_CTRL_RSS_MODE_MQUESINT);
+
+       rxq_ctrl_data |= RXQ_CTRL_IPV6_XSUM_VERIFY_EN | RXQ_CTRL_PBA_ALIGN_32 |
+                        RXQ_CTRL_CUT_THRU_EN | RXQ_CTRL_EN;
+
+       AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data);
+       return;
+}
+
+static inline void atl1e_configure_dma(struct atl1e_adapter *adapter)
+{
+       struct atl1e_hw *hw = &adapter->hw;
+       u32 dma_ctrl_data = 0;
+
+       dma_ctrl_data = DMA_CTRL_RXCMB_EN;
+       dma_ctrl_data |= (((u32)hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
+               << DMA_CTRL_DMAR_BURST_LEN_SHIFT;
+       dma_ctrl_data |= (((u32)hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK)
+               << DMA_CTRL_DMAW_BURST_LEN_SHIFT;
+       dma_ctrl_data |= DMA_CTRL_DMAR_REQ_PRI | DMA_CTRL_DMAR_OUT_ORDER;
+       dma_ctrl_data |= (((u32)hw->dmar_dly_cnt) & DMA_CTRL_DMAR_DLY_CNT_MASK)
+               << DMA_CTRL_DMAR_DLY_CNT_SHIFT;
+       dma_ctrl_data |= (((u32)hw->dmaw_dly_cnt) & DMA_CTRL_DMAW_DLY_CNT_MASK)
+               << DMA_CTRL_DMAW_DLY_CNT_SHIFT;
+
+       AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data);
+       return;
+}
+
+static inline void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter)
+{
+       u32 value;
+       struct atl1e_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+
+       /* Config MAC CTRL Register */
+       value = MAC_CTRL_TX_EN |
+               MAC_CTRL_RX_EN ;
+
+       if (FULL_DUPLEX == adapter->link_duplex)
+               value |= MAC_CTRL_DUPLX;
+
+       value |= ((u32)((SPEED_1000 == adapter->link_speed) ?
+                         MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100) <<
+                         MAC_CTRL_SPEED_SHIFT);
+       value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
+
+       value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
+       value |= (((u32)adapter->hw.preamble_len &
+                 MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
+
+       if (adapter->vlgrp)
+               value |= MAC_CTRL_RMV_VLAN;
+
+       value |= MAC_CTRL_BC_EN;
+       if (netdev->flags & IFF_PROMISC)
+               value |= MAC_CTRL_PROMIS_EN;
+       if (netdev->flags & IFF_ALLMULTI)
+               value |= MAC_CTRL_MC_ALL_EN;
+
+       AT_WRITE_REG(hw, REG_MAC_CTRL, value);
+}
+
+/*
+ * atl1e_configure - Configure Transmit&Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx /Rx unit of the MAC after a reset.
+ */
+static int atl1e_configure(struct atl1e_adapter *adapter)
+{
+       struct atl1e_hw *hw = &adapter->hw;
+       struct pci_dev *pdev = adapter->pdev;
+
+       u32 intr_status_data = 0;
+
+       /* clear interrupt status */
+       AT_WRITE_REG(hw, REG_ISR, ~0);
+
+       /* 1. set MAC Address */
+       atl1e_hw_set_mac_addr(hw);
+
+       /* 2. Init the Multicast HASH table done by set_muti */
+
+       /* 3. Clear any WOL status */
+       AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+
+       /* 4. Descripter Ring BaseMem/Length/Read ptr/Write ptr
+        *    TPD Ring/SMB/RXF0 Page CMBs, they use the same
+        *    High 32bits memory */
+       atl1e_configure_des_ring(adapter);
+
+       /* 5. set Interrupt Moderator Timer */
+       AT_WRITE_REGW(hw, REG_IRQ_MODU_TIMER_INIT, hw->imt);
+       AT_WRITE_REGW(hw, REG_IRQ_MODU_TIMER2_INIT, hw->imt);
+       AT_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_LED_MODE |
+                       MASTER_CTRL_ITIMER_EN | MASTER_CTRL_ITIMER2_EN);
+
+       /* 6. rx/tx threshold to trig interrupt */
+       AT_WRITE_REGW(hw, REG_TRIG_RRD_THRESH, hw->rrd_thresh);
+       AT_WRITE_REGW(hw, REG_TRIG_TPD_THRESH, hw->tpd_thresh);
+       AT_WRITE_REGW(hw, REG_TRIG_RXTIMER, hw->rx_count_down);
+       AT_WRITE_REGW(hw, REG_TRIG_TXTIMER, hw->tx_count_down);
+
+       /* 7. set Interrupt Clear Timer */
+       AT_WRITE_REGW(hw, REG_CMBDISDMA_TIMER, hw->ict);
+
+       /* 8. set MTU */
+       AT_WRITE_REG(hw, REG_MTU, hw->max_frame_size + ETH_HLEN +
+                       VLAN_HLEN + ETH_FCS_LEN);
+
+       /* 9. config TXQ early tx threshold */
+       atl1e_configure_tx(adapter);
+
+       /* 10. config RXQ */
+       atl1e_configure_rx(adapter);
+
+       /* 11. config  DMA Engine */
+       atl1e_configure_dma(adapter);
+
+       /* 12. smb timer to trig interrupt */
+       AT_WRITE_REG(hw, REG_SMB_STAT_TIMER, hw->smb_timer);
+
+       intr_status_data = AT_READ_REG(hw, REG_ISR);
+       if (unlikely((intr_status_data & ISR_PHY_LINKDOWN) != 0)) {
+               dev_err(&pdev->dev, "atl1e_configure failed,"
+                               "PCIE phy link down\n");
+               return -1;
+       }
+
+       AT_WRITE_REG(hw, REG_ISR, 0x7fffffff);
+       return 0;
+}
+
+/*
+ * atl1e_get_stats - Get System Network Statistics
+ * @netdev: network interface device structure
+ *
+ * Returns the address of the device statistics structure.
+ * The statistics are actually updated from the timer callback.
+ */
+static struct net_device_stats *atl1e_get_stats(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw_stats  *hw_stats = &adapter->hw_stats;
+       struct net_device_stats *net_stats = &adapter->net_stats;
+
+       net_stats->rx_packets = hw_stats->rx_ok;
+       net_stats->tx_packets = hw_stats->tx_ok;
+       net_stats->rx_bytes   = hw_stats->rx_byte_cnt;
+       net_stats->tx_bytes   = hw_stats->tx_byte_cnt;
+       net_stats->multicast  = hw_stats->rx_mcast;
+       net_stats->collisions = hw_stats->tx_1_col +
+                               hw_stats->tx_2_col * 2 +
+                               hw_stats->tx_late_col + hw_stats->tx_abort_col;
+
+       net_stats->rx_errors  = hw_stats->rx_frag + hw_stats->rx_fcs_err +
+                               hw_stats->rx_len_err + hw_stats->rx_sz_ov +
+                               hw_stats->rx_rrd_ov + hw_stats->rx_align_err;
+       net_stats->rx_fifo_errors   = hw_stats->rx_rxf_ov;
+       net_stats->rx_length_errors = hw_stats->rx_len_err;
+       net_stats->rx_crc_errors    = hw_stats->rx_fcs_err;
+       net_stats->rx_frame_errors  = hw_stats->rx_align_err;
+       net_stats->rx_over_errors   = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
+
+       net_stats->rx_missed_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
+
+       net_stats->tx_errors = hw_stats->tx_late_col + hw_stats->tx_abort_col +
+                              hw_stats->tx_underrun + hw_stats->tx_trunc;
+       net_stats->tx_fifo_errors    = hw_stats->tx_underrun;
+       net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
+       net_stats->tx_window_errors  = hw_stats->tx_late_col;
+
+       return &adapter->net_stats;
+}
+
+static void atl1e_update_hw_stats(struct atl1e_adapter *adapter)
+{
+       u16 hw_reg_addr = 0;
+       unsigned long *stats_item = NULL;
+
+       /* update rx status */
+       hw_reg_addr = REG_MAC_RX_STATUS_BIN;
+       stats_item  = &adapter->hw_stats.rx_ok;
+       while (hw_reg_addr <= REG_MAC_RX_STATUS_END) {
+               *stats_item += AT_READ_REG(&adapter->hw, hw_reg_addr);
+               stats_item++;
+               hw_reg_addr += 4;
+       }
+       /* update tx status */
+       hw_reg_addr = REG_MAC_TX_STATUS_BIN;
+       stats_item  = &adapter->hw_stats.tx_ok;
+       while (hw_reg_addr <= REG_MAC_TX_STATUS_END) {
+               *stats_item += AT_READ_REG(&adapter->hw, hw_reg_addr);
+               stats_item++;
+               hw_reg_addr += 4;
+       }
+}
+
+static inline void atl1e_clear_phy_int(struct atl1e_adapter *adapter)
+{
+       u16 phy_data;
+
+       spin_lock(&adapter->mdio_lock);
+       atl1e_read_phy_reg(&adapter->hw, MII_INT_STATUS, &phy_data);
+       spin_unlock(&adapter->mdio_lock);
+}
+
+static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter)
+{
+       struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *)
+                                       &adapter->tx_ring;
+       struct atl1e_tx_buffer *tx_buffer = NULL;
+       u16 hw_next_to_clean = AT_READ_REGW(&adapter->hw, REG_TPD_CONS_IDX);
+       u16 next_to_clean = atomic_read(&tx_ring->next_to_clean);
+
+       while (next_to_clean != hw_next_to_clean) {
+               tx_buffer = &tx_ring->tx_buffer[next_to_clean];
+               if (tx_buffer->dma) {
+                       pci_unmap_page(adapter->pdev, tx_buffer->dma,
+                                       tx_buffer->length, PCI_DMA_TODEVICE);
+                       tx_buffer->dma = 0;
+               }
+
+               if (tx_buffer->skb) {
+                       dev_kfree_skb_irq(tx_buffer->skb);
+                       tx_buffer->skb = NULL;
+               }
+
+               if (++next_to_clean == tx_ring->count)
+                       next_to_clean = 0;
+       }
+
+       atomic_set(&tx_ring->next_to_clean, next_to_clean);
+
+       if (netif_queue_stopped(adapter->netdev) &&
+                       netif_carrier_ok(adapter->netdev)) {
+               netif_wake_queue(adapter->netdev);
+       }
+
+       return true;
+}
+
+/*
+ * atl1e_intr - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ * @pt_regs: CPU registers structure
+ */
+static irqreturn_t atl1e_intr(int irq, void *data)
+{
+       struct net_device *netdev  = data;
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct pci_dev *pdev = adapter->pdev;
+       struct atl1e_hw *hw = &adapter->hw;
+       int max_ints = AT_MAX_INT_WORK;
+       int handled = IRQ_NONE;
+       u32 status;
+
+       do {
+               status = AT_READ_REG(hw, REG_ISR);
+               if ((status & IMR_NORMAL_MASK) == 0 ||
+                               (status & ISR_DIS_INT) != 0) {
+                       if (max_ints != AT_MAX_INT_WORK)
+                               handled = IRQ_HANDLED;
+                       break;
+               }
+               /* link event */
+               if (status & ISR_GPHY)
+                       atl1e_clear_phy_int(adapter);
+               /* Ack ISR */
+               AT_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT);
+
+               handled = IRQ_HANDLED;
+               /* check if PCIE PHY Link down */
+               if (status & ISR_PHY_LINKDOWN) {
+                       dev_err(&pdev->dev,
+                               "pcie phy linkdown %x\n", status);
+                       if (netif_running(adapter->netdev)) {
+                               /* reset MAC */
+                               atl1e_irq_reset(adapter);
+                               schedule_work(&adapter->reset_task);
+                               break;
+                       }
+               }
+
+               /* check if DMA read/write error */
+               if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
+                       dev_err(&pdev->dev,
+                               "PCIE DMA RW error (status = 0x%x)\n",
+                               status);
+                       atl1e_irq_reset(adapter);
+                       schedule_work(&adapter->reset_task);
+                       break;
+               }
+
+               if (status & ISR_SMB)
+                       atl1e_update_hw_stats(adapter);
+
+               /* link event */
+               if (status & (ISR_GPHY | ISR_MANUAL)) {
+                       adapter->net_stats.tx_carrier_errors++;
+                       atl1e_link_chg_event(adapter);
+                       break;
+               }
+
+               /* transmit event */
+               if (status & ISR_TX_EVENT)
+                       atl1e_clean_tx_irq(adapter);
+
+               if (status & ISR_RX_EVENT) {
+                       /*
+                        * disable rx interrupts, without
+                        * the synchronize_irq bit
+                        */
+                       AT_WRITE_REG(hw, REG_IMR,
+                                    IMR_NORMAL_MASK & ~ISR_RX_EVENT);
+                       AT_WRITE_FLUSH(hw);
+                       if (likely(netif_rx_schedule_prep(netdev,
+                                  &adapter->napi)))
+                               __netif_rx_schedule(netdev, &adapter->napi);
+               }
+       } while (--max_ints > 0);
+       /* re-enable Interrupt*/
+       AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
+
+       return handled;
+}
+
+static inline void atl1e_rx_checksum(struct atl1e_adapter *adapter,
+                 struct sk_buff *skb, struct atl1e_recv_ret_status *prrs)
+{
+       u8 *packet = (u8 *)(prrs + 1);
+       struct iphdr *iph;
+       u16 head_len = ETH_HLEN;
+       u16 pkt_flags;
+       u16 err_flags;
+
+       skb->ip_summed = CHECKSUM_NONE;
+       pkt_flags = prrs->pkt_flag;
+       err_flags = prrs->err_flag;
+       if (((pkt_flags & RRS_IS_IPV4) || (pkt_flags & RRS_IS_IPV6)) &&
+               ((pkt_flags & RRS_IS_TCP) || (pkt_flags & RRS_IS_UDP))) {
+               if (pkt_flags & RRS_IS_IPV4) {
+                       if (pkt_flags & RRS_IS_802_3)
+                               head_len += 8;
+                       iph = (struct iphdr *) (packet + head_len);
+                       if (iph->frag_off != 0 && !(pkt_flags & RRS_IS_IP_DF))
+                               goto hw_xsum;
+               }
+               if (!(err_flags & (RRS_ERR_IP_CSUM | RRS_ERR_L4_CSUM))) {
+                       skb->ip_summed = CHECKSUM_UNNECESSARY;
+                       return;
+               }
+       }
+
+hw_xsum :
+       return;
+}
+
+static struct atl1e_rx_page *atl1e_get_rx_page(struct atl1e_adapter *adapter,
+                                              u8 que)
+{
+       struct atl1e_rx_page_desc *rx_page_desc =
+               (struct atl1e_rx_page_desc *) adapter->rx_ring.rx_page_desc;
+       u8 rx_using = rx_page_desc[que].rx_using;
+
+       return (struct atl1e_rx_page *)&(rx_page_desc[que].rx_page[rx_using]);
+}
+
+static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que,
+                  int *work_done, int work_to_do)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       struct net_device *netdev  = adapter->netdev;
+       struct atl1e_rx_ring *rx_ring = (struct atl1e_rx_ring *)
+                                        &adapter->rx_ring;
+       struct atl1e_rx_page_desc *rx_page_desc =
+               (struct atl1e_rx_page_desc *) rx_ring->rx_page_desc;
+       struct sk_buff *skb = NULL;
+       struct atl1e_rx_page *rx_page = atl1e_get_rx_page(adapter, que);
+       u32 packet_size, write_offset;
+       struct atl1e_recv_ret_status *prrs;
+
+       write_offset = *(rx_page->write_offset_addr);
+       if (likely(rx_page->read_offset < write_offset)) {
+               do {
+                       if (*work_done >= work_to_do)
+                               break;
+                       (*work_done)++;
+                       /* get new packet's  rrs */
+                       prrs = (struct atl1e_recv_ret_status *) (rx_page->addr +
+                                                rx_page->read_offset);
+                       /* check sequence number */
+                       if (prrs->seq_num != rx_page_desc[que].rx_nxseq) {
+                               dev_err(&pdev->dev,
+                                       "rx sequence number"
+                                       " error (rx=%d) (expect=%d)\n",
+                                       prrs->seq_num,
+                                       rx_page_desc[que].rx_nxseq);
+                               rx_page_desc[que].rx_nxseq++;
+                               /* just for debug use */
+                               AT_WRITE_REG(&adapter->hw, REG_DEBUG_DATA0,
+                                            (((u32)prrs->seq_num) << 16) |
+                                            rx_page_desc[que].rx_nxseq);
+                               goto fatal_err;
+                       }
+                       rx_page_desc[que].rx_nxseq++;
+
+                       /* error packet */
+                       if (prrs->pkt_flag & RRS_IS_ERR_FRAME) {
+                               if (prrs->err_flag & (RRS_ERR_BAD_CRC |
+                                       RRS_ERR_DRIBBLE | RRS_ERR_CODE |
+                                       RRS_ERR_TRUNC)) {
+                               /* hardware error, discard this packet*/
+                                       dev_err(&pdev->dev,
+                                               "rx packet desc error %x\n",
+                                               *((u32 *)prrs + 1));
+                                       goto skip_pkt;
+                               }
+                       }
+
+                       packet_size = ((prrs->word1 >> RRS_PKT_SIZE_SHIFT) &
+                                       RRS_PKT_SIZE_MASK) - 4; /* CRC */
+                       skb = netdev_alloc_skb(netdev,
+                                              packet_size + NET_IP_ALIGN);
+                       if (skb == NULL) {
+                               dev_warn(&pdev->dev, "%s: Memory squeeze,"
+                                       "deferring packet.\n", netdev->name);
+                               goto skip_pkt;
+                       }
+                       skb_reserve(skb, NET_IP_ALIGN);
+                       skb->dev = netdev;
+                       memcpy(skb->data, (u8 *)(prrs + 1), packet_size);
+                       skb_put(skb, packet_size);
+                       skb->protocol = eth_type_trans(skb, netdev);
+                       atl1e_rx_checksum(adapter, skb, prrs);
+
+                       if (unlikely(adapter->vlgrp &&
+                               (prrs->pkt_flag & RRS_IS_VLAN_TAG))) {
+                               u16 vlan_tag = (prrs->vtag >> 4) |
+                                              ((prrs->vtag & 7) << 13) |
+                                              ((prrs->vtag & 8) << 9);
+                               dev_dbg(&pdev->dev,
+                                       "RXD VLAN TAG<RRD>=0x%04x\n",
+                                       prrs->vtag);
+                               vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+                                                        vlan_tag);
+                       } else {
+                               netif_receive_skb(skb);
+                       }
+
+                       netdev->last_rx = jiffies;
+skip_pkt:
+       /* skip current packet whether it's ok or not. */
+                       rx_page->read_offset +=
+                               (((u32)((prrs->word1 >> RRS_PKT_SIZE_SHIFT) &
+                               RRS_PKT_SIZE_MASK) +
+                               sizeof(struct atl1e_recv_ret_status) + 31) &
+                                               0xFFFFFFE0);
+
+                       if (rx_page->read_offset >= rx_ring->page_size) {
+                               /* mark this page clean */
+                               u16 reg_addr;
+                               u8  rx_using;
+
+                               rx_page->read_offset =
+                                       *(rx_page->write_offset_addr) = 0;
+                               rx_using = rx_page_desc[que].rx_using;
+                               reg_addr =
+                                       atl1e_rx_page_vld_regs[que][rx_using];
+                               AT_WRITE_REGB(&adapter->hw, reg_addr, 1);
+                               rx_page_desc[que].rx_using ^= 1;
+                               rx_page = atl1e_get_rx_page(adapter, que);
+                       }
+                       write_offset = *(rx_page->write_offset_addr);
+               } while (rx_page->read_offset < write_offset);
+       }
+
+       return;
+
+fatal_err:
+       if (!test_bit(__AT_DOWN, &adapter->flags))
+               schedule_work(&adapter->reset_task);
+}
+
+/*
+ * atl1e_clean - NAPI Rx polling callback
+ * @adapter: board private structure
+ */
+static int atl1e_clean(struct napi_struct *napi, int budget)
+{
+       struct atl1e_adapter *adapter =
+                       container_of(napi, struct atl1e_adapter, napi);
+       struct net_device *netdev  = adapter->netdev;
+       struct pci_dev    *pdev    = adapter->pdev;
+       u32 imr_data;
+       int work_done = 0;
+
+       /* Keep link state information with original netdev */
+       if (!netif_carrier_ok(adapter->netdev))
+               goto quit_polling;
+
+       atl1e_clean_rx_irq(adapter, 0, &work_done, budget);
+
+       /* If no Tx and not enough Rx work done, exit the polling mode */
+       if (work_done < budget) {
+quit_polling:
+               netif_rx_complete(netdev, napi);
+               imr_data = AT_READ_REG(&adapter->hw, REG_IMR);
+               AT_WRITE_REG(&adapter->hw, REG_IMR, imr_data | ISR_RX_EVENT);
+               /* test debug */
+               if (test_bit(__AT_DOWN, &adapter->flags)) {
+                       atomic_dec(&adapter->irq_sem);
+                       dev_err(&pdev->dev,
+                               "atl1e_clean is called when AT_DOWN\n");
+               }
+               /* reenable RX intr */
+               /*atl1e_irq_enable(adapter); */
+
+       }
+       return work_done;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void atl1e_netpoll(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       disable_irq(adapter->pdev->irq);
+       atl1e_intr(adapter->pdev->irq, netdev);
+       enable_irq(adapter->pdev->irq);
+}
+#endif
+
+static inline u16 atl1e_tpd_avail(struct atl1e_adapter *adapter)
+{
+       struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
+       u16 next_to_use = 0;
+       u16 next_to_clean = 0;
+
+       next_to_clean = atomic_read(&tx_ring->next_to_clean);
+       next_to_use   = tx_ring->next_to_use;
+
+       return (u16)(next_to_clean > next_to_use) ?
+               (next_to_clean - next_to_use - 1) :
+               (tx_ring->count + next_to_clean - next_to_use - 1);
+}
+
+/*
+ * get next usable tpd
+ * Note: should call atl1e_tdp_avail to make sure
+ * there is enough tpd to use
+ */
+static struct atl1e_tpd_desc *atl1e_get_tpd(struct atl1e_adapter *adapter)
+{
+       struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
+       u16 next_to_use = 0;
+
+       next_to_use = tx_ring->next_to_use;
+       if (++tx_ring->next_to_use == tx_ring->count)
+               tx_ring->next_to_use = 0;
+
+       memset(&tx_ring->desc[next_to_use], 0, sizeof(struct atl1e_tpd_desc));
+       return (struct atl1e_tpd_desc *)&tx_ring->desc[next_to_use];
+}
+
+static struct atl1e_tx_buffer *
+atl1e_get_tx_buffer(struct atl1e_adapter *adapter, struct atl1e_tpd_desc *tpd)
+{
+       struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
+
+       return &tx_ring->tx_buffer[tpd - tx_ring->desc];
+}
+
+/* Calculate the transmit packet descript needed*/
+static u16 atl1e_cal_tdp_req(const struct sk_buff *skb)
+{
+       int i = 0;
+       u16 tpd_req = 1;
+       u16 fg_size = 0;
+       u16 proto_hdr_len = 0;
+
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+               fg_size = skb_shinfo(skb)->frags[i].size;
+               tpd_req += ((fg_size + MAX_TX_BUF_LEN - 1) >> MAX_TX_BUF_SHIFT);
+       }
+
+       if (skb_is_gso(skb)) {
+               if (skb->protocol == ntohs(ETH_P_IP) ||
+                  (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6)) {
+                       proto_hdr_len = skb_transport_offset(skb) +
+                                       tcp_hdrlen(skb);
+                       if (proto_hdr_len < skb_headlen(skb)) {
+                               tpd_req += ((skb_headlen(skb) - proto_hdr_len +
+                                          MAX_TX_BUF_LEN - 1) >>
+                                          MAX_TX_BUF_SHIFT);
+                       }
+               }
+
+       }
+       return tpd_req;
+}
+
+static int atl1e_tso_csum(struct atl1e_adapter *adapter,
+                      struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       u8 hdr_len;
+       u32 real_len;
+       unsigned short offload_type;
+       int err;
+
+       if (skb_is_gso(skb)) {
+               if (skb_header_cloned(skb)) {
+                       err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+                       if (unlikely(err))
+                               return -1;
+               }
+               offload_type = skb_shinfo(skb)->gso_type;
+
+               if (offload_type & SKB_GSO_TCPV4) {
+                       real_len = (((unsigned char *)ip_hdr(skb) - skb->data)
+                                       + ntohs(ip_hdr(skb)->tot_len));
+
+                       if (real_len < skb->len)
+                               pskb_trim(skb, real_len);
+
+                       hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+                       if (unlikely(skb->len == hdr_len)) {
+                               /* only xsum need */
+                               dev_warn(&pdev->dev,
+                                     "IPV4 tso with zero data??\n");
+                               goto check_sum;
+                       } else {
+                               ip_hdr(skb)->check = 0;
+                               ip_hdr(skb)->tot_len = 0;
+                               tcp_hdr(skb)->check = ~csum_tcpudp_magic(
+                                                       ip_hdr(skb)->saddr,
+                                                       ip_hdr(skb)->daddr,
+                                                       0, IPPROTO_TCP, 0);
+                               tpd->word3 |= (ip_hdr(skb)->ihl &
+                                       TDP_V4_IPHL_MASK) <<
+                                       TPD_V4_IPHL_SHIFT;
+                               tpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
+                                       TPD_TCPHDRLEN_MASK) <<
+                                       TPD_TCPHDRLEN_SHIFT;
+                               tpd->word3 |= ((skb_shinfo(skb)->gso_size) &
+                                       TPD_MSS_MASK) << TPD_MSS_SHIFT;
+                               tpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
+                       }
+                       return 0;
+               }
+
+               if (offload_type & SKB_GSO_TCPV6) {
+                       real_len = (((unsigned char *)ipv6_hdr(skb) - skb->data)
+                                       + ntohs(ipv6_hdr(skb)->payload_len));
+                       if (real_len < skb->len)
+                               pskb_trim(skb, real_len);
+
+                       /* check payload == 0 byte ? */
+                       hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+                       if (unlikely(skb->len == hdr_len)) {
+                               /* only xsum need */
+                               dev_warn(&pdev->dev,
+                                       "IPV6 tso with zero data??\n");
+                               goto check_sum;
+                       } else {
+                               tcp_hdr(skb)->check = ~csum_ipv6_magic(
+                                               &ipv6_hdr(skb)->saddr,
+                                               &ipv6_hdr(skb)->daddr,
+                                               0, IPPROTO_TCP, 0);
+                               tpd->word3 |= 1 << TPD_IP_VERSION_SHIFT;
+                               hdr_len >>= 1;
+                               tpd->word3 |= (hdr_len & TPD_V6_IPHLLO_MASK) <<
+                                       TPD_V6_IPHLLO_SHIFT;
+                               tpd->word3 |= ((hdr_len >> 3) &
+                                       TPD_V6_IPHLHI_MASK) <<
+                                       TPD_V6_IPHLHI_SHIFT;
+                               tpd->word3 |= (tcp_hdrlen(skb) >> 2 &
+                                       TPD_TCPHDRLEN_MASK) <<
+                                       TPD_TCPHDRLEN_SHIFT;
+                               tpd->word3 |= ((skb_shinfo(skb)->gso_size) &
+                                       TPD_MSS_MASK) << TPD_MSS_SHIFT;
+                                       tpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
+                       }
+               }
+               return 0;
+       }
+
+check_sum:
+       if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
+               u8 css, cso;
+
+               cso = skb_transport_offset(skb);
+               if (unlikely(cso & 0x1)) {
+                       dev_err(&adapter->pdev->dev,
+                          "pay load offset should not ant event number\n");
+                       return -1;
+               } else {
+                       css = cso + skb->csum_offset;
+                       tpd->word3 |= (cso & TPD_PLOADOFFSET_MASK) <<
+                                       TPD_PLOADOFFSET_SHIFT;
+                       tpd->word3 |= (css & TPD_CCSUMOFFSET_MASK) <<
+                                       TPD_CCSUMOFFSET_SHIFT;
+                       tpd->word3 |= 1 << TPD_CC_SEGMENT_EN_SHIFT;
+               }
+       }
+
+       return 0;
+}
+
+static void atl1e_tx_map(struct atl1e_adapter *adapter,
+                     struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
+{
+       struct atl1e_tpd_desc *use_tpd = NULL;
+       struct atl1e_tx_buffer *tx_buffer = NULL;
+       u16 buf_len = skb->len - skb->data_len;
+       u16 map_len = 0;
+       u16 mapped_len = 0;
+       u16 hdr_len = 0;
+       u16 nr_frags;
+       u16 f;
+       int segment;
+
+       nr_frags = skb_shinfo(skb)->nr_frags;
+       segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK;
+       if (segment) {
+               /* TSO */
+               map_len = hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+               use_tpd = tpd;
+
+               tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
+               tx_buffer->length = map_len;
+               tx_buffer->dma = pci_map_single(adapter->pdev,
+                                       skb->data, hdr_len, PCI_DMA_TODEVICE);
+               mapped_len += map_len;
+               use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
+               use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
+                       ((cpu_to_le32(tx_buffer->length) &
+                       TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT);
+       }
+
+       while (mapped_len < buf_len) {
+               /* mapped_len == 0, means we should use the first tpd,
+                  which is given by caller  */
+               if (mapped_len == 0) {
+                       use_tpd = tpd;
+               } else {
+                       use_tpd = atl1e_get_tpd(adapter);
+                       memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
+               }
+               tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
+               tx_buffer->skb = NULL;
+
+               tx_buffer->length = map_len =
+                       ((buf_len - mapped_len) >= MAX_TX_BUF_LEN) ?
+                       MAX_TX_BUF_LEN : (buf_len - mapped_len);
+               tx_buffer->dma =
+                       pci_map_single(adapter->pdev, skb->data + mapped_len,
+                                       map_len, PCI_DMA_TODEVICE);
+               mapped_len  += map_len;
+               use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
+               use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
+                       ((cpu_to_le32(tx_buffer->length) &
+                       TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT);
+       }
+
+       for (f = 0; f < nr_frags; f++) {
+               struct skb_frag_struct *frag;
+               u16 i;
+               u16 seg_num;
+
+               frag = &skb_shinfo(skb)->frags[f];
+               buf_len = frag->size;
+
+               seg_num = (buf_len + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN;
+               for (i = 0; i < seg_num; i++) {
+                       use_tpd = atl1e_get_tpd(adapter);
+                       memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
+
+                       tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
+                       if (tx_buffer->skb)
+                               BUG();
+
+                       tx_buffer->skb = NULL;
+                       tx_buffer->length =
+                               (buf_len > MAX_TX_BUF_LEN) ?
+                               MAX_TX_BUF_LEN : buf_len;
+                       buf_len -= tx_buffer->length;
+
+                       tx_buffer->dma =
+                               pci_map_page(adapter->pdev, frag->page,
+                                               frag->page_offset +
+                                               (i * MAX_TX_BUF_LEN),
+                                               tx_buffer->length,
+                                               PCI_DMA_TODEVICE);
+                       use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
+                       use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
+                                       ((cpu_to_le32(tx_buffer->length) &
+                                       TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT);
+               }
+       }
+
+       if ((tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK)
+               /* note this one is a tcp header */
+               tpd->word3 |= 1 << TPD_HDRFLAG_SHIFT;
+       /* The last tpd */
+
+       use_tpd->word3 |= 1 << TPD_EOP_SHIFT;
+       /* The last buffer info contain the skb address,
+          so it will be free after unmap */
+       tx_buffer->skb = skb;
+}
+
+static void atl1e_tx_queue(struct atl1e_adapter *adapter, u16 count,
+                          struct atl1e_tpd_desc *tpd)
+{
+       struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
+       /* Force memory writes to complete before letting h/w
+        * know there are new descriptors to fetch.  (Only
+        * applicable for weak-ordered memory model archs,
+        * such as IA-64). */
+       wmb();
+       AT_WRITE_REG(&adapter->hw, REG_MB_TPD_PROD_IDX, tx_ring->next_to_use);
+}
+
+static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       unsigned long flags;
+       u16 tpd_req = 1;
+       struct atl1e_tpd_desc *tpd;
+
+       if (test_bit(__AT_DOWN, &adapter->flags)) {
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       if (unlikely(skb->len <= 0)) {
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+       tpd_req = atl1e_cal_tdp_req(skb);
+       if (!spin_trylock_irqsave(&adapter->tx_lock, flags))
+               return NETDEV_TX_LOCKED;
+
+       if (atl1e_tpd_avail(adapter) < tpd_req) {
+               /* no enough descriptor, just stop queue */
+               netif_stop_queue(netdev);
+               spin_unlock_irqrestore(&adapter->tx_lock, flags);
+               return NETDEV_TX_BUSY;
+       }
+
+       tpd = atl1e_get_tpd(adapter);
+
+       if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
+               u16 vlan_tag = vlan_tx_tag_get(skb);
+               u16 atl1e_vlan_tag;
+
+               tpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT;
+               AT_VLAN_TAG_TO_TPD_TAG(vlan_tag, atl1e_vlan_tag);
+               tpd->word2 |= (atl1e_vlan_tag & TPD_VLANTAG_MASK) <<
+                               TPD_VLAN_SHIFT;
+       }
+
+       if (skb->protocol == ntohs(ETH_P_8021Q))
+               tpd->word3 |= 1 << TPD_VL_TAGGED_SHIFT;
+
+       if (skb_network_offset(skb) != ETH_HLEN)
+               tpd->word3 |= 1 << TPD_ETHTYPE_SHIFT; /* 802.3 frame */
+
+       /* do TSO and check sum */
+       if (atl1e_tso_csum(adapter, skb, tpd) != 0) {
+               spin_unlock_irqrestore(&adapter->tx_lock, flags);
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       atl1e_tx_map(adapter, skb, tpd);
+       atl1e_tx_queue(adapter, tpd_req, tpd);
+
+       netdev->trans_start = jiffies;
+       spin_unlock_irqrestore(&adapter->tx_lock, flags);
+       return NETDEV_TX_OK;
+}
+
+static void atl1e_free_irq(struct atl1e_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+
+       free_irq(adapter->pdev->irq, netdev);
+
+       if (adapter->have_msi)
+               pci_disable_msi(adapter->pdev);
+}
+
+static int atl1e_request_irq(struct atl1e_adapter *adapter)
+{
+       struct pci_dev    *pdev   = adapter->pdev;
+       struct net_device *netdev = adapter->netdev;
+       int flags = 0;
+       int err = 0;
+
+       adapter->have_msi = true;
+       err = pci_enable_msi(adapter->pdev);
+       if (err) {
+               dev_dbg(&pdev->dev,
+                       "Unable to allocate MSI interrupt Error: %d\n", err);
+               adapter->have_msi = false;
+       } else
+               netdev->irq = pdev->irq;
+
+
+       if (!adapter->have_msi)
+               flags |= IRQF_SHARED;
+       err = request_irq(adapter->pdev->irq, &atl1e_intr, flags,
+                       netdev->name, netdev);
+       if (err) {
+               dev_dbg(&pdev->dev,
+                       "Unable to allocate interrupt Error: %d\n", err);
+               if (adapter->have_msi)
+                       pci_disable_msi(adapter->pdev);
+               return err;
+       }
+       dev_dbg(&pdev->dev, "atl1e_request_irq OK\n");
+       return err;
+}
+
+int atl1e_up(struct atl1e_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       int err = 0;
+       u32 val;
+
+       /* hardware has been reset, we need to reload some things */
+       err = atl1e_init_hw(&adapter->hw);
+       if (err) {
+               err = -EIO;
+               return err;
+       }
+       atl1e_init_ring_ptrs(adapter);
+       atl1e_set_multi(netdev);
+       atl1e_restore_vlan(adapter);
+
+       if (atl1e_configure(adapter)) {
+               err = -EIO;
+               goto err_up;
+       }
+
+       clear_bit(__AT_DOWN, &adapter->flags);
+       napi_enable(&adapter->napi);
+       atl1e_irq_enable(adapter);
+       val = AT_READ_REG(&adapter->hw, REG_MASTER_CTRL);
+       AT_WRITE_REG(&adapter->hw, REG_MASTER_CTRL,
+                     val | MASTER_CTRL_MANUAL_INT);
+
+err_up:
+       return err;
+}
+
+void atl1e_down(struct atl1e_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+
+       /* signal that we're down so the interrupt handler does not
+        * reschedule our watchdog timer */
+       set_bit(__AT_DOWN, &adapter->flags);
+
+#ifdef NETIF_F_LLTX
+       netif_stop_queue(netdev);
+#else
+       netif_tx_disable(netdev);
+#endif
+
+       /* reset MAC to disable all RX/TX */
+       atl1e_reset_hw(&adapter->hw);
+       msleep(1);
+
+       napi_disable(&adapter->napi);
+       atl1e_del_timer(adapter);
+       atl1e_irq_disable(adapter);
+
+       netif_carrier_off(netdev);
+       adapter->link_speed = SPEED_0;
+       adapter->link_duplex = -1;
+       atl1e_clean_tx_ring(adapter);
+       atl1e_clean_rx_ring(adapter);
+}
+
+/*
+ * atl1e_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * The open entry point is called when a network interface is made
+ * active by the system (IFF_UP).  At this point all resources needed
+ * for transmit and receive operations are allocated, the interrupt
+ * handler is registered with the OS, the watchdog timer is started,
+ * and the stack is notified that the interface is ready.
+ */
+static int atl1e_open(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       int err;
+
+       /* disallow open during test */
+       if (test_bit(__AT_TESTING, &adapter->flags))
+               return -EBUSY;
+
+       /* allocate rx/tx dma buffer & descriptors */
+       atl1e_init_ring_resources(adapter);
+       err = atl1e_setup_ring_resources(adapter);
+       if (unlikely(err))
+               return err;
+
+       err = atl1e_request_irq(adapter);
+       if (unlikely(err))
+               goto err_req_irq;
+
+       err = atl1e_up(adapter);
+       if (unlikely(err))
+               goto err_up;
+
+       return 0;
+
+err_up:
+       atl1e_free_irq(adapter);
+err_req_irq:
+       atl1e_free_ring_resources(adapter);
+       atl1e_reset_hw(&adapter->hw);
+
+       return err;
+}
+
+/*
+ * atl1e_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * The close entry point is called when an interface is de-activated
+ * by the OS.  The hardware is still under the drivers control, but
+ * needs to be disabled.  A global MAC reset is issued to stop the
+ * hardware, and all transmit and receive resources are freed.
+ */
+static int atl1e_close(struct net_device *netdev)
+{
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
+       atl1e_down(adapter);
+       atl1e_free_irq(adapter);
+       atl1e_free_ring_resources(adapter);
+
+       return 0;
+}
+
+static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       struct atl1e_hw *hw = &adapter->hw;
+       u32 ctrl = 0;
+       u32 mac_ctrl_data = 0;
+       u32 wol_ctrl_data = 0;
+       u16 mii_advertise_data = 0;
+       u16 mii_bmsr_data = 0;
+       u16 mii_intr_status_data = 0;
+       u32 wufc = adapter->wol;
+       u32 i;
+#ifdef CONFIG_PM
+       int retval = 0;
+#endif
+
+       if (netif_running(netdev)) {
+               WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
+               atl1e_down(adapter);
+       }
+       netif_device_detach(netdev);
+
+#ifdef CONFIG_PM
+       retval = pci_save_state(pdev);
+       if (retval)
+               return retval;
+#endif
+
+       if (wufc) {
+               /* get link status */
+               atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data);
+               atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data);
+
+               mii_advertise_data = MII_AR_10T_HD_CAPS;
+
+               if ((atl1e_write_phy_reg(hw, MII_AT001_CR, 0) != 0) ||
+                   (atl1e_write_phy_reg(hw,
+                          MII_ADVERTISE, mii_advertise_data) != 0) ||
+                   (atl1e_phy_commit(hw)) != 0) {
+                       dev_dbg(&pdev->dev, "set phy register failed\n");
+                       goto wol_dis;
+               }
+
+               hw->phy_configured = false; /* re-init PHY when resume */
+
+               /* turn on magic packet wol */
+               if (wufc & AT_WUFC_MAG)
+                       wol_ctrl_data |= WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
+
+               if (wufc & AT_WUFC_LNKC) {
+               /* if orignal link status is link, just wait for retrive link */
+                       if (mii_bmsr_data & BMSR_LSTATUS) {
+                               for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) {
+                                       msleep(100);
+                                       atl1e_read_phy_reg(hw, MII_BMSR,
+                                                       (u16 *)&mii_bmsr_data);
+                                       if (mii_bmsr_data & BMSR_LSTATUS)
+                                               break;
+                               }
+
+                               if ((mii_bmsr_data & BMSR_LSTATUS) == 0)
+                                       dev_dbg(&pdev->dev,
+                                               "%s: Link may change"
+                                               "when suspend\n",
+                                               atl1e_driver_name);
+                       }
+                       wol_ctrl_data |=  WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
+                       /* only link up can wake up */
+                       if (atl1e_write_phy_reg(hw, MII_INT_CTRL, 0x400) != 0) {
+                               dev_dbg(&pdev->dev, "%s: read write phy "
+                                                 "register failed.\n",
+                                                 atl1e_driver_name);
+                               goto wol_dis;
+                       }
+               }
+               /* clear phy interrupt */
+               atl1e_read_phy_reg(hw, MII_INT_STATUS, &mii_intr_status_data);
+               /* Config MAC Ctrl register */
+               mac_ctrl_data = MAC_CTRL_RX_EN;
+               /* set to 10/100M halt duplex */
+               mac_ctrl_data |= MAC_CTRL_SPEED_10_100 << MAC_CTRL_SPEED_SHIFT;
+               mac_ctrl_data |= (((u32)adapter->hw.preamble_len &
+                                MAC_CTRL_PRMLEN_MASK) <<
+                                MAC_CTRL_PRMLEN_SHIFT);
+
+               if (adapter->vlgrp)
+                       mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
+
+               /* magic packet maybe Broadcast&multicast&Unicast frame */
+               if (wufc & AT_WUFC_MAG)
+                       mac_ctrl_data |= MAC_CTRL_BC_EN;
+
+               dev_dbg(&pdev->dev,
+                       "%s: suspend MAC=0x%x\n",
+                       atl1e_driver_name, mac_ctrl_data);
+
+               AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data);
+               AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+               /* pcie patch */
+               ctrl = AT_READ_REG(hw, REG_PCIE_PHYMISC);
+               ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+               AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+               pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+               goto suspend_exit;
+       }
+wol_dis:
+
+       /* WOL disabled */
+       AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+
+       /* pcie patch */
+       ctrl = AT_READ_REG(hw, REG_PCIE_PHYMISC);
+       ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+       AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+
+       atl1e_force_ps(hw);
+       hw->phy_configured = false; /* re-init PHY when resume */
+
+       pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
+
+suspend_exit:
+
+       if (netif_running(netdev))
+               atl1e_free_irq(adapter);
+
+       pci_disable_device(pdev);
+
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int atl1e_resume(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+       u32 err;
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               dev_err(&pdev->dev, "ATL1e: Cannot enable PCI"
+                               " device from suspend\n");
+               return err;
+       }
+
+       pci_set_master(pdev);
+
+       AT_READ_REG(&adapter->hw, REG_WOL_CTRL); /* clear WOL status */
+
+       pci_enable_wake(pdev, PCI_D3hot, 0);
+       pci_enable_wake(pdev, PCI_D3cold, 0);
+
+       AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
+
+       if (netif_running(netdev))
+               err = atl1e_request_irq(adapter);
+               if (err)
+                       return err;
+
+       atl1e_reset_hw(&adapter->hw);
+
+       if (netif_running(netdev))
+               atl1e_up(adapter);
+
+       netif_device_attach(netdev);
+
+       return 0;
+}
+#endif
+
+static void atl1e_shutdown(struct pci_dev *pdev)
+{
+       atl1e_suspend(pdev, PMSG_SUSPEND);
+}
+
+static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
+{
+       SET_NETDEV_DEV(netdev, &pdev->dev);
+       pci_set_drvdata(pdev, netdev);
+
+       netdev->irq  = pdev->irq;
+       netdev->open = &atl1e_open;
+       netdev->stop = &atl1e_close;
+       netdev->hard_start_xmit = &atl1e_xmit_frame;
+       netdev->get_stats = &atl1e_get_stats;
+       netdev->set_multicast_list = &atl1e_set_multi;
+       netdev->set_mac_address = &atl1e_set_mac_addr;
+       netdev->change_mtu = &atl1e_change_mtu;
+       netdev->do_ioctl = &atl1e_ioctl;
+       netdev->tx_timeout = &atl1e_tx_timeout;
+       netdev->watchdog_timeo = AT_TX_WATCHDOG;
+       netdev->vlan_rx_register = atl1e_vlan_rx_register;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       netdev->poll_controller = atl1e_netpoll;
+#endif
+       atl1e_set_ethtool_ops(netdev);
+
+       netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
+               NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+       netdev->features |= NETIF_F_LLTX;
+       netdev->features |= NETIF_F_TSO;
+       netdev->features |= NETIF_F_TSO6;
+
+       return 0;
+}
+
+/*
+ * atl1e_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in atl1e_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * atl1e_probe initializes an adapter identified by a pci_dev structure.
+ * The OS initialization, configuring of the adapter private structure,
+ * and a hardware reset occur.
+ */
+static int __devinit atl1e_probe(struct pci_dev *pdev,
+                                const struct pci_device_id *ent)
+{
+       struct net_device *netdev;
+       struct atl1e_adapter *adapter = NULL;
+       static int cards_found;
+
+       int err = 0;
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               dev_err(&pdev->dev, "cannot enable PCI device\n");
+               return err;
+       }
+
+       /*
+        * The atl1e chip can DMA to 64-bit addresses, but it uses a single
+        * shared register for the high 32 bits, so only a single, aligned,
+        * 4 GB physical address range can be used at a time.
+        *
+        * Supporting 64-bit DMA on this hardware is more trouble than it's
+        * worth.  It is far easier to limit to 32-bit DMA than update
+        * various kernel subsystems to support the mechanics required by a
+        * fixed-high-32-bit system.
+        */
+       if ((pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) ||
+           (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) != 0)) {
+               dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
+               goto err_dma;
+       }
+
+       err = pci_request_regions(pdev, atl1e_driver_name);
+       if (err) {
+               dev_err(&pdev->dev, "cannot obtain PCI resources\n");
+               goto err_pci_reg;
+       }
+
+       pci_set_master(pdev);
+
+       netdev = alloc_etherdev(sizeof(struct atl1e_adapter));
+       if (netdev == NULL) {
+               err = -ENOMEM;
+               dev_err(&pdev->dev, "etherdev alloc failed\n");
+               goto err_alloc_etherdev;
+       }
+
+       err = atl1e_init_netdev(netdev, pdev);
+       if (err) {
+               dev_err(&pdev->dev, "init netdevice failed\n");
+               goto err_init_netdev;
+       }
+       adapter = netdev_priv(netdev);
+       adapter->bd_number = cards_found;
+       adapter->netdev = netdev;
+       adapter->pdev = pdev;
+       adapter->hw.adapter = adapter;
+       adapter->hw.hw_addr = pci_iomap(pdev, BAR_0, 0);
+       if (!adapter->hw.hw_addr) {
+               err = -EIO;
+               dev_err(&pdev->dev, "cannot map device registers\n");
+               goto err_ioremap;
+       }
+       netdev->base_addr = (unsigned long)adapter->hw.hw_addr;
+
+       /* init mii data */
+       adapter->mii.dev = netdev;
+       adapter->mii.mdio_read  = atl1e_mdio_read;
+       adapter->mii.mdio_write = atl1e_mdio_write;
+       adapter->mii.phy_id_mask = 0x1f;
+       adapter->mii.reg_num_mask = MDIO_REG_ADDR_MASK;
+
+       netif_napi_add(netdev, &adapter->napi, atl1e_clean, 64);
+
+       init_timer(&adapter->phy_config_timer);
+       adapter->phy_config_timer.function = &atl1e_phy_config;
+       adapter->phy_config_timer.data = (unsigned long) adapter;
+
+       /* get user settings */
+       atl1e_check_options(adapter);
+       /*
+        * Mark all PCI regions associated with PCI device
+        * pdev as being reserved by owner atl1e_driver_name
+        * Enables bus-mastering on the device and calls
+        * pcibios_set_master to do the needed arch specific settings
+        */
+       atl1e_setup_pcicmd(pdev);
+       /* setup the private structure */
+       err = atl1e_sw_init(adapter);
+       if (err) {
+               dev_err(&pdev->dev, "net device private data init failed\n");
+               goto err_sw_init;
+       }
+
+       /* Init GPHY as early as possible due to power saving issue  */
+       spin_lock(&adapter->mdio_lock);
+       atl1e_phy_init(&adapter->hw);
+       spin_unlock(&adapter->mdio_lock);
+       /* reset the controller to
+        * put the device in a known good starting state */
+       err = atl1e_reset_hw(&adapter->hw);
+       if (err) {
+               err = -EIO;
+               goto err_reset;
+       }
+
+       if (atl1e_read_mac_addr(&adapter->hw) != 0) {
+               err = -EIO;
+               dev_err(&pdev->dev, "get mac address failed\n");
+               goto err_eeprom;
+       }
+
+       memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
+       memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
+       dev_dbg(&pdev->dev, "mac address : %02x-%02x-%02x-%02x-%02x-%02x\n",
+                       adapter->hw.mac_addr[0], adapter->hw.mac_addr[1],
+                       adapter->hw.mac_addr[2], adapter->hw.mac_addr[3],
+                       adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]);
+
+       INIT_WORK(&adapter->reset_task, atl1e_reset_task);
+       INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task);
+       err = register_netdev(netdev);
+       if (err) {
+               dev_err(&pdev->dev, "register netdevice failed\n");
+               goto err_register;
+       }
+
+       /* assume we have no link for now */
+       netif_stop_queue(netdev);
+       netif_carrier_off(netdev);
+
+       cards_found++;
+
+       return 0;
+
+err_reset:
+err_register:
+err_sw_init:
+err_eeprom:
+       iounmap(adapter->hw.hw_addr);
+err_init_netdev:
+err_ioremap:
+       free_netdev(netdev);
+err_alloc_etherdev:
+       pci_release_regions(pdev);
+err_pci_reg:
+err_dma:
+       pci_disable_device(pdev);
+       return err;
+}
+
+/*
+ * atl1e_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * atl1e_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device.  The could be caused by a
+ * Hot-Plug event, or because the driver is going to be removed from
+ * memory.
+ */
+static void __devexit atl1e_remove(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
+
+       /*
+        * flush_scheduled work may reschedule our watchdog task, so
+        * explicitly disable watchdog tasks from being rescheduled
+        */
+       set_bit(__AT_DOWN, &adapter->flags);
+
+       atl1e_del_timer(adapter);
+       atl1e_cancel_work(adapter);
+
+       unregister_netdev(netdev);
+       atl1e_free_ring_resources(adapter);
+       atl1e_force_ps(&adapter->hw);
+       iounmap(adapter->hw.hw_addr);
+       pci_release_regions(pdev);
+       free_netdev(netdev);
+       pci_disable_device(pdev);
+}
+
+/*
+ * atl1e_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t
+atl1e_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1e_adapter *adapter = netdev->priv;
+
+       netif_device_detach(netdev);
+
+       if (netif_running(netdev))
+               atl1e_down(adapter);
+
+       pci_disable_device(pdev);
+
+       /* Request a slot slot reset. */
+       return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/*
+ * atl1e_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot. Implementation
+ * resembles the first-half of the e1000_resume routine.
+ */
+static pci_ers_result_t atl1e_io_slot_reset(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1e_adapter *adapter = netdev->priv;
+
+       if (pci_enable_device(pdev)) {
+               dev_err(&pdev->dev,
+                      "ATL1e: Cannot re-enable PCI device after reset.\n");
+               return PCI_ERS_RESULT_DISCONNECT;
+       }
+       pci_set_master(pdev);
+
+       pci_enable_wake(pdev, PCI_D3hot, 0);
+       pci_enable_wake(pdev, PCI_D3cold, 0);
+
+       atl1e_reset_hw(&adapter->hw);
+
+       return PCI_ERS_RESULT_RECOVERED;
+}
+
+/*
+ * atl1e_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation. Implementation resembles the
+ * second-half of the atl1e_resume routine.
+ */
+static void atl1e_io_resume(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct atl1e_adapter *adapter = netdev->priv;
+
+       if (netif_running(netdev)) {
+               if (atl1e_up(adapter)) {
+                       dev_err(&pdev->dev,
+                         "ATL1e: can't bring device back up after reset\n");
+                       return;
+               }
+       }
+
+       netif_device_attach(netdev);
+}
+
+static struct pci_error_handlers atl1e_err_handler = {
+       .error_detected = atl1e_io_error_detected,
+       .slot_reset = atl1e_io_slot_reset,
+       .resume = atl1e_io_resume,
+};
+
+static struct pci_driver atl1e_driver = {
+       .name     = atl1e_driver_name,
+       .id_table = atl1e_pci_tbl,
+       .probe    = atl1e_probe,
+       .remove   = __devexit_p(atl1e_remove),
+       /* Power Managment Hooks */
+#ifdef CONFIG_PM
+       .suspend  = atl1e_suspend,
+       .resume   = atl1e_resume,
+#endif
+       .shutdown = atl1e_shutdown,
+       .err_handler = &atl1e_err_handler
+};
+
+/*
+ * atl1e_init_module - Driver Registration Routine
+ *
+ * atl1e_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ */
+static int __init atl1e_init_module(void)
+{
+       return pci_register_driver(&atl1e_driver);
+}
+
+/*
+ * atl1e_exit_module - Driver Exit Cleanup Routine
+ *
+ * atl1e_exit_module is called just before the driver is removed
+ * from memory.
+ */
+static void __exit atl1e_exit_module(void)
+{
+       pci_unregister_driver(&atl1e_driver);
+}
+
+module_init(atl1e_init_module);
+module_exit(atl1e_exit_module);
diff --git a/drivers/net/atl1e/atl1e_param.c b/drivers/net/atl1e/atl1e_param.c
new file mode 100644 (file)
index 0000000..f72abb3
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public 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/netdevice.h>
+
+#include "atl1e.h"
+
+/* This is the only thing that needs to be changed to adjust the
+ * maximum number of ports that the driver can manage.
+ */
+
+#define ATL1E_MAX_NIC 32
+
+#define OPTION_UNSET    -1
+#define OPTION_DISABLED 0
+#define OPTION_ENABLED  1
+
+/* All parameters are treated the same, as an integer array of values.
+ * This macro just reduces the need to repeat the same declaration code
+ * over and over (plus this helps to avoid typo bugs).
+ */
+#define ATL1E_PARAM_INIT { [0 ... ATL1E_MAX_NIC] = OPTION_UNSET }
+
+#define ATL1E_PARAM(x, desc) \
+       static int __devinitdata x[ATL1E_MAX_NIC + 1] = ATL1E_PARAM_INIT; \
+       static int num_##x; \
+       module_param_array_named(x, x, int, &num_##x, 0); \
+       MODULE_PARM_DESC(x, desc);
+
+/* Transmit Memory count
+ *
+ * Valid Range: 64-2048
+ *
+ * Default Value: 128
+ */
+#define ATL1E_MIN_TX_DESC_CNT          32
+#define ATL1E_MAX_TX_DESC_CNT          1020
+#define ATL1E_DEFAULT_TX_DESC_CNT      128
+ATL1E_PARAM(tx_desc_cnt, "Transmit description count");
+
+/* Receive Memory Block Count
+ *
+ * Valid Range: 16-512
+ *
+ * Default Value: 128
+ */
+#define ATL1E_MIN_RX_MEM_SIZE          8    /* 8KB   */
+#define ATL1E_MAX_RX_MEM_SIZE          1024 /* 1MB   */
+#define ATL1E_DEFAULT_RX_MEM_SIZE      256  /* 128KB */
+ATL1E_PARAM(rx_mem_size, "memory size of rx buffer(KB)");
+
+/* User Specified MediaType Override
+ *
+ * Valid Range: 0-5
+ *  - 0    - auto-negotiate at all supported speeds
+ *  - 1    - only link at 100Mbps Full Duplex
+ *  - 2    - only link at 100Mbps Half Duplex
+ *  - 3    - only link at 10Mbps Full Duplex
+ *  - 4    - only link at 10Mbps Half Duplex
+ * Default Value: 0
+ */
+
+ATL1E_PARAM(media_type, "MediaType Select");
+
+/* Interrupt Moderate Timer in units of 2 us
+ *
+ * Valid Range: 10-65535
+ *
+ * Default Value: 45000(90ms)
+ */
+#define INT_MOD_DEFAULT_CNT             100 /* 200us */
+#define INT_MOD_MAX_CNT                 65000
+#define INT_MOD_MIN_CNT                 50
+ATL1E_PARAM(int_mod_timer, "Interrupt Moderator Timer");
+
+#define AUTONEG_ADV_DEFAULT  0x2F
+#define AUTONEG_ADV_MASK     0x2F
+#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
+
+#define FLASH_VENDOR_DEFAULT    0
+#define FLASH_VENDOR_MIN        0
+#define FLASH_VENDOR_MAX        2
+
+struct atl1e_option {
+       enum { enable_option, range_option, list_option } type;
+       char *name;
+       char *err;
+       int  def;
+       union {
+               struct { /* range_option info */
+                       int min;
+                       int max;
+               } r;
+               struct { /* list_option info */
+                       int nr;
+                       struct atl1e_opt_list { int i; char *str; } *p;
+               } l;
+       } arg;
+};
+
+static int __devinit atl1e_validate_option(int *value, struct atl1e_option *opt, struct pci_dev *pdev)
+{
+       if (*value == OPTION_UNSET) {
+               *value = opt->def;
+               return 0;
+       }
+
+       switch (opt->type) {
+       case enable_option:
+               switch (*value) {
+               case OPTION_ENABLED:
+                       dev_info(&pdev->dev, "%s Enabled\n", opt->name);
+                       return 0;
+               case OPTION_DISABLED:
+                       dev_info(&pdev->dev, "%s Disabled\n", opt->name);
+                       return 0;
+               }
+               break;
+       case range_option:
+               if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+                       dev_info(&pdev->dev, "%s set to %i\n", opt->name, *value);
+                       return 0;
+               }
+               break;
+       case list_option:{
+                       int i;
+                       struct atl1e_opt_list *ent;
+
+                       for (i = 0; i < opt->arg.l.nr; i++) {
+                               ent = &opt->arg.l.p[i];
+                               if (*value == ent->i) {
+                                       if (ent->str[0] != '\0')
+                                               dev_info(&pdev->dev, "%s\n",
+                                                       ent->str);
+                                       return 0;
+                               }
+                       }
+                       break;
+               }
+       default:
+               BUG();
+       }
+
+       dev_info(&pdev->dev, "Invalid %s specified (%i) %s\n",
+                       opt->name, *value, opt->err);
+       *value = opt->def;
+       return -1;
+}
+
+/*
+ * atl1e_check_options - Range Checking for Command Line Parameters
+ * @adapter: board private structure
+ *
+ * This routine checks all command line parameters for valid user
+ * input.  If an invalid value is given, or if no user specified
+ * value exists, a default value is used.  The final value is stored
+ * in a variable in the adapter structure.
+ */
+void __devinit atl1e_check_options(struct atl1e_adapter *adapter)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       int bd = adapter->bd_number;
+       if (bd >= ATL1E_MAX_NIC) {
+               dev_notice(&pdev->dev, "no configuration for board #%i\n", bd);
+               dev_notice(&pdev->dev, "Using defaults for all values\n");
+       }
+
+       {               /* Transmit Ring Size */
+               struct atl1e_option opt = {
+                       .type = range_option,
+                       .name = "Transmit Ddescription Count",
+                       .err  = "using default of "
+                               __MODULE_STRING(ATL1E_DEFAULT_TX_DESC_CNT),
+                       .def  = ATL1E_DEFAULT_TX_DESC_CNT,
+                       .arg  = { .r = { .min = ATL1E_MIN_TX_DESC_CNT,
+                                        .max = ATL1E_MAX_TX_DESC_CNT} }
+               };
+               int val;
+               if (num_tx_desc_cnt > bd) {
+                       val = tx_desc_cnt[bd];
+                       atl1e_validate_option(&val, &opt, pdev);
+                       adapter->tx_ring.count = (u16) val & 0xFFFC;
+               } else
+                       adapter->tx_ring.count = (u16)opt.def;
+       }
+
+       {               /* Receive Memory Block Count */
+               struct atl1e_option opt = {
+                       .type = range_option,
+                       .name = "Memory size of rx buffer(KB)",
+                       .err  = "using default of "
+                               __MODULE_STRING(ATL1E_DEFAULT_RX_MEM_SIZE),
+                       .def  = ATL1E_DEFAULT_RX_MEM_SIZE,
+                       .arg  = { .r = { .min = ATL1E_MIN_RX_MEM_SIZE,
+                                        .max = ATL1E_MAX_RX_MEM_SIZE} }
+               };
+               int val;
+               if (num_rx_mem_size > bd) {
+                       val = rx_mem_size[bd];
+                       atl1e_validate_option(&val, &opt, pdev);
+                       adapter->rx_ring.page_size = (u32)val * 1024;
+               } else {
+                       adapter->rx_ring.page_size = (u32)opt.def * 1024;
+               }
+       }
+
+       {               /* Interrupt Moderate Timer */
+               struct atl1e_option opt = {
+                       .type = range_option,
+                       .name = "Interrupt Moderate Timer",
+                       .err  = "using default of "
+                               __MODULE_STRING(INT_MOD_DEFAULT_CNT),
+                       .def  = INT_MOD_DEFAULT_CNT,
+                       .arg  = { .r = { .min = INT_MOD_MIN_CNT,
+                                        .max = INT_MOD_MAX_CNT} }
+               } ;
+               int val;
+               if (num_int_mod_timer > bd) {
+                       val = int_mod_timer[bd];
+                       atl1e_validate_option(&val, &opt, pdev);
+                       adapter->hw.imt = (u16) val;
+               } else
+                       adapter->hw.imt = (u16)(opt.def);
+       }
+
+       {               /* MediaType */
+               struct atl1e_option opt = {
+                       .type = range_option,
+                       .name = "Speed/Duplex Selection",
+                       .err  = "using default of "
+                               __MODULE_STRING(MEDIA_TYPE_AUTO_SENSOR),
+                       .def  = MEDIA_TYPE_AUTO_SENSOR,
+                       .arg  = { .r = { .min = MEDIA_TYPE_AUTO_SENSOR,
+                                        .max = MEDIA_TYPE_10M_HALF} }
+               } ;
+               int val;
+               if (num_media_type > bd) {
+                       val = media_type[bd];
+                       atl1e_validate_option(&val, &opt, pdev);
+                       adapter->hw.media_type = (u16) val;
+               } else
+                       adapter->hw.media_type = (u16)(opt.def);
+
+       }
+}
index 3e22e7817bc34bb53f5ff7d1f20e5fa47677a5c6..f12e3d12474b0701a5a72baaf0d4213d5f36203d 100644 (file)
@@ -1308,7 +1308,6 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
                                dev_info(&adapter->pdev->dev, "link is down\n");
                        adapter->link_speed = SPEED_0;
                        netif_carrier_off(netdev);
-                       netif_stop_queue(netdev);
                }
                return 0;
        }
@@ -1358,7 +1357,6 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
                if (!netif_carrier_ok(netdev)) {
                        /* Link down -> Up */
                        netif_carrier_on(netdev);
-                       netif_wake_queue(netdev);
                }
                return 0;
        }
@@ -2627,6 +2625,7 @@ static s32 atl1_up(struct atl1_adapter *adapter)
        mod_timer(&adapter->watchdog_timer, jiffies);
        atlx_irq_enable(adapter);
        atl1_check_link(adapter);
+       netif_start_queue(netdev);
        return 0;
 
 err_up:
index 3ab61e40e86aa833e32d1acc82b8ae9985ef433d..cb8be490e5aed1f9f7afd7f9a68522ee2d6192ba 100644 (file)
@@ -911,9 +911,8 @@ au1000_adjust_link(struct net_device *dev)
        if(phydev->link != aup->old_link) {
                // link state changed
 
-               if (phydev->link) // link went up
-                       netif_tx_schedule_all(dev);
-               else { // link went down
+               if (!phydev->link) {
+                       /* link went down */
                        aup->old_speed = 0;
                        aup->old_duplex = -1;
                }
index a6a3da89f590138eea9e563674bde2a5cf786de1..a8ec60e1ed7573224c5c5a5147399dadef142469 100644 (file)
@@ -357,7 +357,6 @@ static void bfin_mac_adjust_link(struct net_device *dev)
                if (!lp->old_link) {
                        new_state = 1;
                        lp->old_link = 1;
-                       netif_tx_schedule_all(dev);
                }
        } else if (lp->old_link) {
                new_state = 1;
index 9737c06045d6e7103193a82e6d9330321e34d11e..a641eeaa2a2f488bdef9a074e431c187321135f7 100644 (file)
@@ -5041,6 +5041,7 @@ static int bond_check_params(struct bond_params *params)
 }
 
 static struct lock_class_key bonding_netdev_xmit_lock_key;
+static struct lock_class_key bonding_netdev_addr_lock_key;
 
 static void bond_set_lockdep_class_one(struct net_device *dev,
                                       struct netdev_queue *txq,
@@ -5052,6 +5053,8 @@ static void bond_set_lockdep_class_one(struct net_device *dev,
 
 static void bond_set_lockdep_class(struct net_device *dev)
 {
+       lockdep_set_class(&dev->addr_list_lock,
+                         &bonding_netdev_addr_lock_key);
        netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL);
 }
 
index fbd4280c102c219a60ef9ca5918d19cf9f886a3b..a7800e55909099d07594c4e13c05c09c040d380d 100644 (file)
@@ -945,10 +945,8 @@ static void cpmac_adjust_link(struct net_device *dev)
                if (!priv->oldlink) {
                        new_state = 1;
                        priv->oldlink = 1;
-                       netif_tx_schedule_all(dev);
                }
        } else if (priv->oldlink) {
-               netif_tx_stop_all_queues(dev);
                new_state = 1;
                priv->oldlink = 0;
                priv->oldspeed = 0;
index 952e10d686ec2f7508e716d450b7d583f022c1f6..0b0f1c407a7e87568c3f1f6f807208fe64ab4f46 100644 (file)
@@ -888,19 +888,22 @@ dm9000_rx(struct net_device *dev)
                        dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen);
                }
 
-               if (rxhdr.RxStatus & 0xbf) {
+               /* rxhdr.RxStatus is identical to RSR register. */
+               if (rxhdr.RxStatus & (RSR_FOE | RSR_CE | RSR_AE |
+                                     RSR_PLE | RSR_RWTO |
+                                     RSR_LCS | RSR_RF)) {
                        GoodPacket = false;
-                       if (rxhdr.RxStatus & 0x01) {
+                       if (rxhdr.RxStatus & RSR_FOE) {
                                if (netif_msg_rx_err(db))
                                        dev_dbg(db->dev, "fifo error\n");
                                dev->stats.rx_fifo_errors++;
                        }
-                       if (rxhdr.RxStatus & 0x02) {
+                       if (rxhdr.RxStatus & RSR_CE) {
                                if (netif_msg_rx_err(db))
                                        dev_dbg(db->dev, "crc error\n");
                                dev->stats.rx_crc_errors++;
                        }
-                       if (rxhdr.RxStatus & 0x80) {
+                       if (rxhdr.RxStatus & RSR_RF) {
                                if (netif_msg_rx_err(db))
                                        dev_dbg(db->dev, "length error\n");
                                dev->stats.rx_length_errors++;
@@ -1067,7 +1070,7 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
        /* Fill the phyxcer register into REG_0C */
        iow(db, DM9000_EPAR, DM9000_PHY | reg);
 
-       iow(db, DM9000_EPCR, 0xc);      /* Issue phyxcer read command */
+       iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);   /* Issue phyxcer read command */
 
        writeb(reg_save, db->io_addr);
        spin_unlock_irqrestore(&db->lock,flags);
@@ -1118,7 +1121,7 @@ dm9000_phy_write(struct net_device *dev,
        iow(db, DM9000_EPDRL, value);
        iow(db, DM9000_EPDRH, value >> 8);
 
-       iow(db, DM9000_EPCR, 0xa);      /* Issue phyxcer write command */
+       iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);   /* Issue phyxcer write command */
 
        writeb(reg_save, db->io_addr);
        spin_unlock_irqrestore(&db->lock, flags);
index 31feae1ea390368be941fc8f7250b277051558ce..19e317eaf5bc4582adb3279df31247368ad13da3 100644 (file)
@@ -90,10 +90,13 @@ struct e1000_adapter;
 #define E1000_ERR(args...) printk(KERN_ERR "e1000: " args)
 
 #define PFX "e1000: "
-#define DPRINTK(nlevel, klevel, fmt, args...) \
-       (void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
-       printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
-               __FUNCTION__ , ## args))
+
+#define DPRINTK(nlevel, klevel, fmt, args...)                          \
+do {                                                                   \
+       if (NETIF_MSG_##nlevel & adapter->msg_enable)                   \
+               printk(KERN_##klevel PFX "%s: %s: " fmt,                \
+                      adapter->netdev->name, __func__, ##args);        \
+} while (0)
 
 #define E1000_MAX_INTR 10
 
@@ -151,9 +154,9 @@ struct e1000_adapter;
 #define E1000_MASTER_SLAVE     e1000_ms_hw_default
 #endif
 
-#define E1000_MNG_VLAN_NONE -1
+#define E1000_MNG_VLAN_NONE (-1)
 /* Number of packet split data buffers (not including the header buffer) */
-#define PS_PAGE_BUFFERS MAX_PS_BUFFERS-1
+#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
 
 /* wrapper around a pointer to a socket buffer,
  * so a DMA handle can be stored along with the buffer */
@@ -165,9 +168,13 @@ struct e1000_buffer {
        u16 next_to_watch;
 };
 
+struct e1000_ps_page {
+       struct page *ps_page[PS_PAGE_BUFFERS];
+};
 
-struct e1000_ps_page { struct page *ps_page[PS_PAGE_BUFFERS]; };
-struct e1000_ps_page_dma { u64 ps_page_dma[PS_PAGE_BUFFERS]; };
+struct e1000_ps_page_dma {
+       u64 ps_page_dma[PS_PAGE_BUFFERS];
+};
 
 struct e1000_tx_ring {
        /* pointer to the descriptor ring memory */
@@ -217,13 +224,13 @@ struct e1000_rx_ring {
        u16 rdt;
 };
 
-#define E1000_DESC_UNUSED(R) \
-       ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
-       (R)->next_to_clean - (R)->next_to_use - 1)
+#define E1000_DESC_UNUSED(R)                                           \
+       ((((R)->next_to_clean > (R)->next_to_use)                       \
+         ? 0 : (R)->count) + (R)->next_to_clean - (R)->next_to_use - 1)
 
-#define E1000_RX_DESC_PS(R, i)     \
+#define E1000_RX_DESC_PS(R, i)                                         \
        (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
-#define E1000_RX_DESC_EXT(R, i)            \
+#define E1000_RX_DESC_EXT(R, i)                                                \
        (&(((union e1000_rx_desc_extended *)((R).desc))[i]))
 #define E1000_GET_DESC(R, i, type)     (&(((struct type *)((R).desc))[i]))
 #define E1000_RX_DESC(R, i)            E1000_GET_DESC(R, i, e1000_rx_desc)
@@ -246,9 +253,7 @@ struct e1000_adapter {
        u16 link_speed;
        u16 link_duplex;
        spinlock_t stats_lock;
-#ifdef CONFIG_E1000_NAPI
        spinlock_t tx_queue_lock;
-#endif
        unsigned int total_tx_bytes;
        unsigned int total_tx_packets;
        unsigned int total_rx_bytes;
@@ -286,22 +291,16 @@ struct e1000_adapter {
        bool detect_tx_hung;
 
        /* RX */
-#ifdef CONFIG_E1000_NAPI
-       bool (*clean_rx) (struct e1000_adapter *adapter,
-                         struct e1000_rx_ring *rx_ring,
-                         int *work_done, int work_to_do);
-#else
-       bool (*clean_rx) (struct e1000_adapter *adapter,
-                         struct e1000_rx_ring *rx_ring);
-#endif
-       void (*alloc_rx_buf) (struct e1000_adapter *adapter,
-                             struct e1000_rx_ring *rx_ring,
-                               int cleaned_count);
+       bool (*clean_rx)(struct e1000_adapter *adapter,
+                        struct e1000_rx_ring *rx_ring,
+                        int *work_done, int work_to_do);
+       void (*alloc_rx_buf)(struct e1000_adapter *adapter,
+                            struct e1000_rx_ring *rx_ring,
+                            int cleaned_count);
        struct e1000_rx_ring *rx_ring;      /* One per active queue */
-#ifdef CONFIG_E1000_NAPI
        struct napi_struct napi;
        struct net_device *polling_netdev;  /* One per active queue */
-#endif
+
        int num_tx_queues;
        int num_rx_queues;
 
@@ -317,7 +316,6 @@ struct e1000_adapter {
        u64 gorcl_old;
        u16 rx_ps_bsize0;
 
-
        /* OS defined structs */
        struct net_device *netdev;
        struct pci_dev *pdev;
@@ -342,6 +340,10 @@ struct e1000_adapter {
        bool quad_port_a;
        unsigned long flags;
        u32 eeprom_wol;
+
+       /* for ioport free */
+       int bars;
+       int need_ioport;
 };
 
 enum e1000_state_t {
@@ -353,9 +355,18 @@ enum e1000_state_t {
 extern char e1000_driver_name[];
 extern const char e1000_driver_version[];
 
+extern int e1000_up(struct e1000_adapter *adapter);
+extern void e1000_down(struct e1000_adapter *adapter);
+extern void e1000_reinit_locked(struct e1000_adapter *adapter);
+extern void e1000_reset(struct e1000_adapter *adapter);
+extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
+extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_update_stats(struct e1000_adapter *adapter);
 extern void e1000_power_up_phy(struct e1000_adapter *);
 extern void e1000_set_ethtool_ops(struct net_device *netdev);
 extern void e1000_check_options(struct e1000_adapter *adapter);
 
-
 #endif /* _E1000_H_ */
index a3f6a9c72ec8546b11ab987b27ea330ca1fba5e2..6a3893acfe04e3f963b231a373446fe8d8615863 100644 (file)
 /* ethtool support for e1000 */
 
 #include "e1000.h"
-
 #include <asm/uaccess.h>
 
-extern int e1000_up(struct e1000_adapter *adapter);
-extern void e1000_down(struct e1000_adapter *adapter);
-extern void e1000_reinit_locked(struct e1000_adapter *adapter);
-extern void e1000_reset(struct e1000_adapter *adapter);
-extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
-extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
-extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
-extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
-extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
-extern void e1000_update_stats(struct e1000_adapter *adapter);
-
-
 struct e1000_stats {
        char stat_string[ETH_GSTRING_LEN];
        int sizeof_stat;
@@ -112,8 +99,8 @@ static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
 };
 #define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test)
 
-static int
-e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+static int e1000_get_settings(struct net_device *netdev,
+                             struct ethtool_cmd *ecmd)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
@@ -162,7 +149,7 @@ e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
                        ecmd->transceiver = XCVR_EXTERNAL;
        }
 
-       if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU) {
+       if (er32(STATUS) & E1000_STATUS_LU) {
 
                e1000_get_speed_and_duplex(hw, &adapter->link_speed,
                                                   &adapter->link_duplex);
@@ -185,8 +172,8 @@ e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
        return 0;
 }
 
-static int
-e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+static int e1000_set_settings(struct net_device *netdev,
+                             struct ethtool_cmd *ecmd)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
@@ -231,9 +218,8 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
        return 0;
 }
 
-static void
-e1000_get_pauseparam(struct net_device *netdev,
-                     struct ethtool_pauseparam *pause)
+static void e1000_get_pauseparam(struct net_device *netdev,
+                                struct ethtool_pauseparam *pause)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
@@ -251,9 +237,8 @@ e1000_get_pauseparam(struct net_device *netdev,
        }
 }
 
-static int
-e1000_set_pauseparam(struct net_device *netdev,
-                     struct ethtool_pauseparam *pause)
+static int e1000_set_pauseparam(struct net_device *netdev,
+                               struct ethtool_pauseparam *pause)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
@@ -289,15 +274,13 @@ e1000_set_pauseparam(struct net_device *netdev,
        return retval;
 }
 
-static u32
-e1000_get_rx_csum(struct net_device *netdev)
+static u32 e1000_get_rx_csum(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        return adapter->rx_csum;
 }
 
-static int
-e1000_set_rx_csum(struct net_device *netdev, u32 data)
+static int e1000_set_rx_csum(struct net_device *netdev, u32 data)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        adapter->rx_csum = data;
@@ -309,18 +292,17 @@ e1000_set_rx_csum(struct net_device *netdev, u32 data)
        return 0;
 }
 
-static u32
-e1000_get_tx_csum(struct net_device *netdev)
+static u32 e1000_get_tx_csum(struct net_device *netdev)
 {
        return (netdev->features & NETIF_F_HW_CSUM) != 0;
 }
 
-static int
-e1000_set_tx_csum(struct net_device *netdev, u32 data)
+static int e1000_set_tx_csum(struct net_device *netdev, u32 data)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
 
-       if (adapter->hw.mac_type < e1000_82543) {
+       if (hw->mac_type < e1000_82543) {
                if (!data)
                        return -EINVAL;
                return 0;
@@ -334,12 +316,13 @@ e1000_set_tx_csum(struct net_device *netdev, u32 data)
        return 0;
 }
 
-static int
-e1000_set_tso(struct net_device *netdev, u32 data)
+static int e1000_set_tso(struct net_device *netdev, u32 data)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
-       if ((adapter->hw.mac_type < e1000_82544) ||
-           (adapter->hw.mac_type == e1000_82547))
+       struct e1000_hw *hw = &adapter->hw;
+
+       if ((hw->mac_type < e1000_82544) ||
+           (hw->mac_type == e1000_82547))
                return data ? -EINVAL : 0;
 
        if (data)
@@ -357,30 +340,26 @@ e1000_set_tso(struct net_device *netdev, u32 data)
        return 0;
 }
 
-static u32
-e1000_get_msglevel(struct net_device *netdev)
+static u32 e1000_get_msglevel(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        return adapter->msg_enable;
 }
 
-static void
-e1000_set_msglevel(struct net_device *netdev, u32 data)
+static void e1000_set_msglevel(struct net_device *netdev, u32 data)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        adapter->msg_enable = data;
 }
 
-static int
-e1000_get_regs_len(struct net_device *netdev)
+static int e1000_get_regs_len(struct net_device *netdev)
 {
 #define E1000_REGS_LEN 32
        return E1000_REGS_LEN * sizeof(u32);
 }
 
-static void
-e1000_get_regs(struct net_device *netdev,
-              struct ethtool_regs *regs, void *p)
+static void e1000_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
+                          void *p)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
@@ -391,22 +370,22 @@ e1000_get_regs(struct net_device *netdev,
 
        regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
 
-       regs_buff[0]  = E1000_READ_REG(hw, CTRL);
-       regs_buff[1]  = E1000_READ_REG(hw, STATUS);
+       regs_buff[0]  = er32(CTRL);
+       regs_buff[1]  = er32(STATUS);
 
-       regs_buff[2]  = E1000_READ_REG(hw, RCTL);
-       regs_buff[3]  = E1000_READ_REG(hw, RDLEN);
-       regs_buff[4]  = E1000_READ_REG(hw, RDH);
-       regs_buff[5]  = E1000_READ_REG(hw, RDT);
-       regs_buff[6]  = E1000_READ_REG(hw, RDTR);
+       regs_buff[2]  = er32(RCTL);
+       regs_buff[3]  = er32(RDLEN);
+       regs_buff[4]  = er32(RDH);
+       regs_buff[5]  = er32(RDT);
+       regs_buff[6]  = er32(RDTR);
 
-       regs_buff[7]  = E1000_READ_REG(hw, TCTL);
-       regs_buff[8]  = E1000_READ_REG(hw, TDLEN);
-       regs_buff[9]  = E1000_READ_REG(hw, TDH);
-       regs_buff[10] = E1000_READ_REG(hw, TDT);
-       regs_buff[11] = E1000_READ_REG(hw, TIDV);
+       regs_buff[7]  = er32(TCTL);
+       regs_buff[8]  = er32(TDLEN);
+       regs_buff[9]  = er32(TDH);
+       regs_buff[10] = er32(TDT);
+       regs_buff[11] = er32(TIDV);
 
-       regs_buff[12] = adapter->hw.phy_type;  /* PHY type (IGP=1, M88=0) */
+       regs_buff[12] = hw->phy_type;  /* PHY type (IGP=1, M88=0) */
        if (hw->phy_type == e1000_phy_igp) {
                e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
                                    IGP01E1000_PHY_AGC_A);
@@ -464,20 +443,20 @@ e1000_get_regs(struct net_device *netdev,
        if (hw->mac_type >= e1000_82540 &&
            hw->mac_type < e1000_82571 &&
            hw->media_type == e1000_media_type_copper) {
-               regs_buff[26] = E1000_READ_REG(hw, MANC);
+               regs_buff[26] = er32(MANC);
        }
 }
 
-static int
-e1000_get_eeprom_len(struct net_device *netdev)
+static int e1000_get_eeprom_len(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
-       return adapter->hw.eeprom.word_size * 2;
+       struct e1000_hw *hw = &adapter->hw;
+
+       return hw->eeprom.word_size * 2;
 }
 
-static int
-e1000_get_eeprom(struct net_device *netdev,
-                      struct ethtool_eeprom *eeprom, u8 *bytes)
+static int e1000_get_eeprom(struct net_device *netdev,
+                           struct ethtool_eeprom *eeprom, u8 *bytes)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
@@ -504,10 +483,12 @@ e1000_get_eeprom(struct net_device *netdev,
                                            last_word - first_word + 1,
                                            eeprom_buff);
        else {
-               for (i = 0; i < last_word - first_word + 1; i++)
-                       if ((ret_val = e1000_read_eeprom(hw, first_word + i, 1,
-                                                       &eeprom_buff[i])))
+               for (i = 0; i < last_word - first_word + 1; i++) {
+                       ret_val = e1000_read_eeprom(hw, first_word + i, 1,
+                                                   &eeprom_buff[i]);
+                       if (ret_val)
                                break;
+               }
        }
 
        /* Device's eeprom is always little-endian, word addressable */
@@ -521,9 +502,8 @@ e1000_get_eeprom(struct net_device *netdev,
        return ret_val;
 }
 
-static int
-e1000_set_eeprom(struct net_device *netdev,
-                      struct ethtool_eeprom *eeprom, u8 *bytes)
+static int e1000_set_eeprom(struct net_device *netdev,
+                           struct ethtool_eeprom *eeprom, u8 *bytes)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
@@ -584,11 +564,11 @@ e1000_set_eeprom(struct net_device *netdev,
        return ret_val;
 }
 
-static void
-e1000_get_drvinfo(struct net_device *netdev,
-                       struct ethtool_drvinfo *drvinfo)
+static void e1000_get_drvinfo(struct net_device *netdev,
+                             struct ethtool_drvinfo *drvinfo)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
        char firmware_version[32];
        u16 eeprom_data;
 
@@ -597,8 +577,8 @@ e1000_get_drvinfo(struct net_device *netdev,
 
        /* EEPROM image version # is reported as firmware version # for
         * 8257{1|2|3} controllers */
-       e1000_read_eeprom(&adapter->hw, 5, 1, &eeprom_data);
-       switch (adapter->hw.mac_type) {
+       e1000_read_eeprom(hw, 5, 1, &eeprom_data);
+       switch (hw->mac_type) {
        case e1000_82571:
        case e1000_82572:
        case e1000_82573:
@@ -619,12 +599,12 @@ e1000_get_drvinfo(struct net_device *netdev,
        drvinfo->eedump_len = e1000_get_eeprom_len(netdev);
 }
 
-static void
-e1000_get_ringparam(struct net_device *netdev,
-                    struct ethtool_ringparam *ring)
+static void e1000_get_ringparam(struct net_device *netdev,
+                               struct ethtool_ringparam *ring)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
-       e1000_mac_type mac_type = adapter->hw.mac_type;
+       struct e1000_hw *hw = &adapter->hw;
+       e1000_mac_type mac_type = hw->mac_type;
        struct e1000_tx_ring *txdr = adapter->tx_ring;
        struct e1000_rx_ring *rxdr = adapter->rx_ring;
 
@@ -640,12 +620,12 @@ e1000_get_ringparam(struct net_device *netdev,
        ring->rx_jumbo_pending = 0;
 }
 
-static int
-e1000_set_ringparam(struct net_device *netdev,
-                    struct ethtool_ringparam *ring)
+static int e1000_set_ringparam(struct net_device *netdev,
+                              struct ethtool_ringparam *ring)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
-       e1000_mac_type mac_type = adapter->hw.mac_type;
+       struct e1000_hw *hw = &adapter->hw;
+       e1000_mac_type mac_type = hw->mac_type;
        struct e1000_tx_ring *txdr, *tx_old;
        struct e1000_rx_ring *rxdr, *rx_old;
        int i, err;
@@ -691,9 +671,11 @@ e1000_set_ringparam(struct net_device *netdev,
 
        if (netif_running(adapter->netdev)) {
                /* Try to get new resources before deleting old */
-               if ((err = e1000_setup_all_rx_resources(adapter)))
+               err = e1000_setup_all_rx_resources(adapter);
+               if (err)
                        goto err_setup_rx;
-               if ((err = e1000_setup_all_tx_resources(adapter)))
+               err = e1000_setup_all_tx_resources(adapter);
+               if (err)
                        goto err_setup_tx;
 
                /* save the new, restore the old in order to free it,
@@ -707,7 +689,8 @@ e1000_set_ringparam(struct net_device *netdev,
                kfree(rx_old);
                adapter->rx_ring = rxdr;
                adapter->tx_ring = txdr;
-               if ((err = e1000_up(adapter)))
+               err = e1000_up(adapter);
+               if (err)
                        goto err_setup;
        }
 
@@ -728,12 +711,13 @@ err_setup:
        return err;
 }
 
-static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data,
-                            int reg, u32 mask, u32 write)
+static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data, int reg,
+                            u32 mask, u32 write)
 {
+       struct e1000_hw *hw = &adapter->hw;
        static const u32 test[] =
                {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
-       u8 __iomem *address = adapter->hw.hw_addr + reg;
+       u8 __iomem *address = hw->hw_addr + reg;
        u32 read;
        int i;
 
@@ -751,10 +735,11 @@ static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data,
        return false;
 }
 
-static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data,
-                             int reg, u32 mask, u32 write)
+static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data, int reg,
+                             u32 mask, u32 write)
 {
-       u8 __iomem *address = adapter->hw.hw_addr + reg;
+       struct e1000_hw *hw = &adapter->hw;
+       u8 __iomem *address = hw->hw_addr + reg;
        u32 read;
 
        writel(write & mask, address);
@@ -772,7 +757,7 @@ static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data,
 #define REG_PATTERN_TEST(reg, mask, write)                          \
        do {                                                         \
                if (reg_pattern_test(adapter, data,                  \
-                            (adapter->hw.mac_type >= e1000_82543)   \
+                            (hw->mac_type >= e1000_82543)   \
                             ? E1000_##reg : E1000_82542_##reg,      \
                             mask, write))                           \
                        return 1;                                    \
@@ -781,22 +766,22 @@ static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data,
 #define REG_SET_AND_CHECK(reg, mask, write)                         \
        do {                                                         \
                if (reg_set_and_check(adapter, data,                 \
-                             (adapter->hw.mac_type >= e1000_82543)  \
+                             (hw->mac_type >= e1000_82543)  \
                              ? E1000_##reg : E1000_82542_##reg,     \
                              mask, write))                          \
                        return 1;                                    \
        } while (0)
 
-static int
-e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
+static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
 {
        u32 value, before, after;
        u32 i, toggle;
+       struct e1000_hw *hw = &adapter->hw;
 
        /* The status register is Read Only, so a write should fail.
         * Some bits that get toggled are ignored.
         */
-       switch (adapter->hw.mac_type) {
+       switch (hw->mac_type) {
        /* there are several bits on newer hardware that are r/w */
        case e1000_82571:
        case e1000_82572:
@@ -812,10 +797,10 @@ e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
                break;
        }
 
-       before = E1000_READ_REG(&adapter->hw, STATUS);
-       value = (E1000_READ_REG(&adapter->hw, STATUS) & toggle);
-       E1000_WRITE_REG(&adapter->hw, STATUS, toggle);
-       after = E1000_READ_REG(&adapter->hw, STATUS) & toggle;
+       before = er32(STATUS);
+       value = (er32(STATUS) & toggle);
+       ew32(STATUS, toggle);
+       after = er32(STATUS) & toggle;
        if (value != after) {
                DPRINTK(DRV, ERR, "failed STATUS register test got: "
                        "0x%08X expected: 0x%08X\n", after, value);
@@ -823,9 +808,9 @@ e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
                return 1;
        }
        /* restore previous status */
-       E1000_WRITE_REG(&adapter->hw, STATUS, before);
+       ew32(STATUS, before);
 
-       if (adapter->hw.mac_type != e1000_ich8lan) {
+       if (hw->mac_type != e1000_ich8lan) {
                REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
                REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF);
                REG_PATTERN_TEST(FCT, 0x0000FFFF, 0xFFFFFFFF);
@@ -845,20 +830,20 @@ e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
 
        REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x00000000);
 
-       before = (adapter->hw.mac_type == e1000_ich8lan ?
+       before = (hw->mac_type == e1000_ich8lan ?
                  0x06C3B33E : 0x06DFB3FE);
        REG_SET_AND_CHECK(RCTL, before, 0x003FFFFB);
        REG_SET_AND_CHECK(TCTL, 0xFFFFFFFF, 0x00000000);
 
-       if (adapter->hw.mac_type >= e1000_82543) {
+       if (hw->mac_type >= e1000_82543) {
 
                REG_SET_AND_CHECK(RCTL, before, 0xFFFFFFFF);
                REG_PATTERN_TEST(RDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
-               if (adapter->hw.mac_type != e1000_ich8lan)
+               if (hw->mac_type != e1000_ich8lan)
                        REG_PATTERN_TEST(TXCW, 0xC000FFFF, 0x0000FFFF);
                REG_PATTERN_TEST(TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
                REG_PATTERN_TEST(TIDV, 0x0000FFFF, 0x0000FFFF);
-               value = (adapter->hw.mac_type == e1000_ich8lan ?
+               value = (hw->mac_type == e1000_ich8lan ?
                         E1000_RAR_ENTRIES_ICH8LAN : E1000_RAR_ENTRIES);
                for (i = 0; i < value; i++) {
                        REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2), 0x8003FFFF,
@@ -874,7 +859,7 @@ e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
 
        }
 
-       value = (adapter->hw.mac_type == e1000_ich8lan ?
+       value = (hw->mac_type == e1000_ich8lan ?
                        E1000_MC_TBL_SIZE_ICH8LAN : E1000_MC_TBL_SIZE);
        for (i = 0; i < value; i++)
                REG_PATTERN_TEST(MTA + (i << 2), 0xFFFFFFFF, 0xFFFFFFFF);
@@ -883,9 +868,9 @@ e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
        return 0;
 }
 
-static int
-e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data)
+static int e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data)
 {
+       struct e1000_hw *hw = &adapter->hw;
        u16 temp;
        u16 checksum = 0;
        u16 i;
@@ -893,7 +878,7 @@ e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data)
        *data = 0;
        /* Read and add up the contents of the EEPROM */
        for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
-               if ((e1000_read_eeprom(&adapter->hw, i, 1, &temp)) < 0) {
+               if ((e1000_read_eeprom(hw, i, 1, &temp)) < 0) {
                        *data = 1;
                        break;
                }
@@ -901,30 +886,30 @@ e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data)
        }
 
        /* If Checksum is not Correct return error else test passed */
-       if ((checksum != (u16) EEPROM_SUM) && !(*data))
+       if ((checksum != (u16)EEPROM_SUM) && !(*data))
                *data = 2;
 
        return *data;
 }
 
-static irqreturn_t
-e1000_test_intr(int irq, void *data)
+static irqreturn_t e1000_test_intr(int irq, void *data)
 {
-       struct net_device *netdev = (struct net_device *) data;
+       struct net_device *netdev = (struct net_device *)data;
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
 
-       adapter->test_icr |= E1000_READ_REG(&adapter->hw, ICR);
+       adapter->test_icr |= er32(ICR);
 
        return IRQ_HANDLED;
 }
 
-static int
-e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
+static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
 {
        struct net_device *netdev = adapter->netdev;
        u32 mask, i = 0;
        bool shared_int = true;
        u32 irq = adapter->pdev->irq;
+       struct e1000_hw *hw = &adapter->hw;
 
        *data = 0;
 
@@ -942,13 +927,13 @@ e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
                (shared_int ? "shared" : "unshared"));
 
        /* Disable all the interrupts */
-       E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF);
+       ew32(IMC, 0xFFFFFFFF);
        msleep(10);
 
        /* Test each interrupt */
        for (; i < 10; i++) {
 
-               if (adapter->hw.mac_type == e1000_ich8lan && i == 8)
+               if (hw->mac_type == e1000_ich8lan && i == 8)
                        continue;
 
                /* Interrupt to test */
@@ -962,8 +947,8 @@ e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
                         * test failed.
                         */
                        adapter->test_icr = 0;
-                       E1000_WRITE_REG(&adapter->hw, IMC, mask);
-                       E1000_WRITE_REG(&adapter->hw, ICS, mask);
+                       ew32(IMC, mask);
+                       ew32(ICS, mask);
                        msleep(10);
 
                        if (adapter->test_icr & mask) {
@@ -979,8 +964,8 @@ e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
                 * test failed.
                 */
                adapter->test_icr = 0;
-               E1000_WRITE_REG(&adapter->hw, IMS, mask);
-               E1000_WRITE_REG(&adapter->hw, ICS, mask);
+               ew32(IMS, mask);
+               ew32(ICS, mask);
                msleep(10);
 
                if (!(adapter->test_icr & mask)) {
@@ -996,8 +981,8 @@ e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
                         * test failed.
                         */
                        adapter->test_icr = 0;
-                       E1000_WRITE_REG(&adapter->hw, IMC, ~mask & 0x00007FFF);
-                       E1000_WRITE_REG(&adapter->hw, ICS, ~mask & 0x00007FFF);
+                       ew32(IMC, ~mask & 0x00007FFF);
+                       ew32(ICS, ~mask & 0x00007FFF);
                        msleep(10);
 
                        if (adapter->test_icr) {
@@ -1008,7 +993,7 @@ e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
        }
 
        /* Disable all the interrupts */
-       E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF);
+       ew32(IMC, 0xFFFFFFFF);
        msleep(10);
 
        /* Unhook test interrupt handler */
@@ -1017,8 +1002,7 @@ e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
        return *data;
 }
 
-static void
-e1000_free_desc_rings(struct e1000_adapter *adapter)
+static void e1000_free_desc_rings(struct e1000_adapter *adapter)
 {
        struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
        struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
@@ -1064,9 +1048,9 @@ e1000_free_desc_rings(struct e1000_adapter *adapter)
        return;
 }
 
-static int
-e1000_setup_desc_rings(struct e1000_adapter *adapter)
+static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
        struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
        struct pci_dev *pdev = adapter->pdev;
@@ -1078,41 +1062,39 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter)
        if (!txdr->count)
                txdr->count = E1000_DEFAULT_TXD;
 
-       if (!(txdr->buffer_info = kcalloc(txdr->count,
-                                         sizeof(struct e1000_buffer),
-                                         GFP_KERNEL))) {
+       txdr->buffer_info = kcalloc(txdr->count, sizeof(struct e1000_buffer),
+                                   GFP_KERNEL);
+       if (!txdr->buffer_info) {
                ret_val = 1;
                goto err_nomem;
        }
 
        txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
        txdr->size = ALIGN(txdr->size, 4096);
-       if (!(txdr->desc = pci_alloc_consistent(pdev, txdr->size,
-                                               &txdr->dma))) {
+       txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
+       if (!txdr->desc) {
                ret_val = 2;
                goto err_nomem;
        }
        memset(txdr->desc, 0, txdr->size);
        txdr->next_to_use = txdr->next_to_clean = 0;
 
-       E1000_WRITE_REG(&adapter->hw, TDBAL,
-                       ((u64) txdr->dma & 0x00000000FFFFFFFF));
-       E1000_WRITE_REG(&adapter->hw, TDBAH, ((u64) txdr->dma >> 32));
-       E1000_WRITE_REG(&adapter->hw, TDLEN,
-                       txdr->count * sizeof(struct e1000_tx_desc));
-       E1000_WRITE_REG(&adapter->hw, TDH, 0);
-       E1000_WRITE_REG(&adapter->hw, TDT, 0);
-       E1000_WRITE_REG(&adapter->hw, TCTL,
-                       E1000_TCTL_PSP | E1000_TCTL_EN |
-                       E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT |
-                       E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT);
+       ew32(TDBAL, ((u64)txdr->dma & 0x00000000FFFFFFFF));
+       ew32(TDBAH, ((u64)txdr->dma >> 32));
+       ew32(TDLEN, txdr->count * sizeof(struct e1000_tx_desc));
+       ew32(TDH, 0);
+       ew32(TDT, 0);
+       ew32(TCTL, E1000_TCTL_PSP | E1000_TCTL_EN |
+            E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT |
+            E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT);
 
        for (i = 0; i < txdr->count; i++) {
                struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*txdr, i);
                struct sk_buff *skb;
                unsigned int size = 1024;
 
-               if (!(skb = alloc_skb(size, GFP_KERNEL))) {
+               skb = alloc_skb(size, GFP_KERNEL);
+               if (!skb) {
                        ret_val = 3;
                        goto err_nomem;
                }
@@ -1135,40 +1117,40 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter)
        if (!rxdr->count)
                rxdr->count = E1000_DEFAULT_RXD;
 
-       if (!(rxdr->buffer_info = kcalloc(rxdr->count,
-                                         sizeof(struct e1000_buffer),
-                                         GFP_KERNEL))) {
+       rxdr->buffer_info = kcalloc(rxdr->count, sizeof(struct e1000_buffer),
+                                   GFP_KERNEL);
+       if (!rxdr->buffer_info) {
                ret_val = 4;
                goto err_nomem;
        }
 
        rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc);
-       if (!(rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma))) {
+       rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
+       if (!rxdr->desc) {
                ret_val = 5;
                goto err_nomem;
        }
        memset(rxdr->desc, 0, rxdr->size);
        rxdr->next_to_use = rxdr->next_to_clean = 0;
 
-       rctl = E1000_READ_REG(&adapter->hw, RCTL);
-       E1000_WRITE_REG(&adapter->hw, RCTL, rctl & ~E1000_RCTL_EN);
-       E1000_WRITE_REG(&adapter->hw, RDBAL,
-                       ((u64) rxdr->dma & 0xFFFFFFFF));
-       E1000_WRITE_REG(&adapter->hw, RDBAH, ((u64) rxdr->dma >> 32));
-       E1000_WRITE_REG(&adapter->hw, RDLEN, rxdr->size);
-       E1000_WRITE_REG(&adapter->hw, RDH, 0);
-       E1000_WRITE_REG(&adapter->hw, RDT, 0);
+       rctl = er32(RCTL);
+       ew32(RCTL, rctl & ~E1000_RCTL_EN);
+       ew32(RDBAL, ((u64)rxdr->dma & 0xFFFFFFFF));
+       ew32(RDBAH, ((u64)rxdr->dma >> 32));
+       ew32(RDLEN, rxdr->size);
+       ew32(RDH, 0);
+       ew32(RDT, 0);
        rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 |
                E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
-               (adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
-       E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+               (hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
+       ew32(RCTL, rctl);
 
        for (i = 0; i < rxdr->count; i++) {
                struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i);
                struct sk_buff *skb;
 
-               if (!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN,
-                               GFP_KERNEL))) {
+               skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL);
+               if (!skb) {
                        ret_val = 6;
                        goto err_nomem;
                }
@@ -1189,73 +1171,74 @@ err_nomem:
        return ret_val;
 }
 
-static void
-e1000_phy_disable_receiver(struct e1000_adapter *adapter)
+static void e1000_phy_disable_receiver(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
+
        /* Write out to PHY registers 29 and 30 to disable the Receiver. */
-       e1000_write_phy_reg(&adapter->hw, 29, 0x001F);
-       e1000_write_phy_reg(&adapter->hw, 30, 0x8FFC);
-       e1000_write_phy_reg(&adapter->hw, 29, 0x001A);
-       e1000_write_phy_reg(&adapter->hw, 30, 0x8FF0);
+       e1000_write_phy_reg(hw, 29, 0x001F);
+       e1000_write_phy_reg(hw, 30, 0x8FFC);
+       e1000_write_phy_reg(hw, 29, 0x001A);
+       e1000_write_phy_reg(hw, 30, 0x8FF0);
 }
 
-static void
-e1000_phy_reset_clk_and_crs(struct e1000_adapter *adapter)
+static void e1000_phy_reset_clk_and_crs(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        u16 phy_reg;
 
        /* Because we reset the PHY above, we need to re-force TX_CLK in the
         * Extended PHY Specific Control Register to 25MHz clock.  This
         * value defaults back to a 2.5MHz clock when the PHY is reset.
         */
-       e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);
+       e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);
        phy_reg |= M88E1000_EPSCR_TX_CLK_25;
-       e1000_write_phy_reg(&adapter->hw,
+       e1000_write_phy_reg(hw,
                M88E1000_EXT_PHY_SPEC_CTRL, phy_reg);
 
        /* In addition, because of the s/w reset above, we need to enable
         * CRS on TX.  This must be set for both full and half duplex
         * operation.
         */
-       e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, &phy_reg);
+       e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_reg);
        phy_reg |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
-       e1000_write_phy_reg(&adapter->hw,
+       e1000_write_phy_reg(hw,
                M88E1000_PHY_SPEC_CTRL, phy_reg);
 }
 
-static int
-e1000_nonintegrated_phy_loopback(struct e1000_adapter *adapter)
+static int e1000_nonintegrated_phy_loopback(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        u32 ctrl_reg;
        u16 phy_reg;
 
        /* Setup the Device Control Register for PHY loopback test. */
 
-       ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL);
+       ctrl_reg = er32(CTRL);
        ctrl_reg |= (E1000_CTRL_ILOS |          /* Invert Loss-Of-Signal */
                     E1000_CTRL_FRCSPD |        /* Set the Force Speed Bit */
                     E1000_CTRL_FRCDPX |        /* Set the Force Duplex Bit */
                     E1000_CTRL_SPD_1000 |      /* Force Speed to 1000 */
                     E1000_CTRL_FD);            /* Force Duplex to FULL */
 
-       E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg);
+       ew32(CTRL, ctrl_reg);
 
        /* Read the PHY Specific Control Register (0x10) */
-       e1000_read_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, &phy_reg);
+       e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_reg);
 
        /* Clear Auto-Crossover bits in PHY Specific Control Register
         * (bits 6:5).
         */
        phy_reg &= ~M88E1000_PSCR_AUTO_X_MODE;
-       e1000_write_phy_reg(&adapter->hw, M88E1000_PHY_SPEC_CTRL, phy_reg);
+       e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_reg);
 
        /* Perform software reset on the PHY */
-       e1000_phy_reset(&adapter->hw);
+       e1000_phy_reset(hw);
 
        /* Have to setup TX_CLK and TX_CRS after software reset */
        e1000_phy_reset_clk_and_crs(adapter);
 
-       e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8100);
+       e1000_write_phy_reg(hw, PHY_CTRL, 0x8100);
 
        /* Wait for reset to complete. */
        udelay(500);
@@ -1267,55 +1250,55 @@ e1000_nonintegrated_phy_loopback(struct e1000_adapter *adapter)
        e1000_phy_disable_receiver(adapter);
 
        /* Set the loopback bit in the PHY control register. */
-       e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
+       e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg);
        phy_reg |= MII_CR_LOOPBACK;
-       e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg);
+       e1000_write_phy_reg(hw, PHY_CTRL, phy_reg);
 
        /* Setup TX_CLK and TX_CRS one more time. */
        e1000_phy_reset_clk_and_crs(adapter);
 
        /* Check Phy Configuration */
-       e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
+       e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg);
        if (phy_reg != 0x4100)
                 return 9;
 
-       e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);
+       e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);
        if (phy_reg != 0x0070)
                return 10;
 
-       e1000_read_phy_reg(&adapter->hw, 29, &phy_reg);
+       e1000_read_phy_reg(hw, 29, &phy_reg);
        if (phy_reg != 0x001A)
                return 11;
 
        return 0;
 }
 
-static int
-e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
+static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        u32 ctrl_reg = 0;
        u32 stat_reg = 0;
 
-       adapter->hw.autoneg = false;
+       hw->autoneg = false;
 
-       if (adapter->hw.phy_type == e1000_phy_m88) {
+       if (hw->phy_type == e1000_phy_m88) {
                /* Auto-MDI/MDIX Off */
-               e1000_write_phy_reg(&adapter->hw,
+               e1000_write_phy_reg(hw,
                                    M88E1000_PHY_SPEC_CTRL, 0x0808);
                /* reset to update Auto-MDI/MDIX */
-               e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140);
+               e1000_write_phy_reg(hw, PHY_CTRL, 0x9140);
                /* autoneg off */
-               e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140);
-       } else if (adapter->hw.phy_type == e1000_phy_gg82563)
-               e1000_write_phy_reg(&adapter->hw,
+               e1000_write_phy_reg(hw, PHY_CTRL, 0x8140);
+       } else if (hw->phy_type == e1000_phy_gg82563)
+               e1000_write_phy_reg(hw,
                                    GG82563_PHY_KMRN_MODE_CTRL,
                                    0x1CC);
 
-       ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL);
+       ctrl_reg = er32(CTRL);
 
-       if (adapter->hw.phy_type == e1000_phy_ife) {
+       if (hw->phy_type == e1000_phy_ife) {
                /* force 100, set loopback */
-               e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x6100);
+               e1000_write_phy_reg(hw, PHY_CTRL, 0x6100);
 
                /* Now set up the MAC to the same speed/duplex as the PHY. */
                ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
@@ -1325,10 +1308,10 @@ e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
                             E1000_CTRL_FD);     /* Force Duplex to FULL */
        } else {
                /* force 1000, set loopback */
-               e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x4140);
+               e1000_write_phy_reg(hw, PHY_CTRL, 0x4140);
 
                /* Now set up the MAC to the same speed/duplex as the PHY. */
-               ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL);
+               ctrl_reg = er32(CTRL);
                ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
                ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
                             E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
@@ -1336,23 +1319,23 @@ e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
                             E1000_CTRL_FD);     /* Force Duplex to FULL */
        }
 
-       if (adapter->hw.media_type == e1000_media_type_copper &&
-          adapter->hw.phy_type == e1000_phy_m88)
+       if (hw->media_type == e1000_media_type_copper &&
+          hw->phy_type == e1000_phy_m88)
                ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */
        else {
                /* Set the ILOS bit on the fiber Nic is half
                 * duplex link is detected. */
-               stat_reg = E1000_READ_REG(&adapter->hw, STATUS);
+               stat_reg = er32(STATUS);
                if ((stat_reg & E1000_STATUS_FD) == 0)
                        ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU);
        }
 
-       E1000_WRITE_REG(&adapter->hw, CTRL, ctrl_reg);
+       ew32(CTRL, ctrl_reg);
 
        /* Disable the receiver on the PHY so when a cable is plugged in, the
         * PHY does not begin to autoneg when a cable is reconnected to the NIC.
         */
-       if (adapter->hw.phy_type == e1000_phy_m88)
+       if (hw->phy_type == e1000_phy_m88)
                e1000_phy_disable_receiver(adapter);
 
        udelay(500);
@@ -1360,15 +1343,15 @@ e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
        return 0;
 }
 
-static int
-e1000_set_phy_loopback(struct e1000_adapter *adapter)
+static int e1000_set_phy_loopback(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        u16 phy_reg = 0;
        u16 count = 0;
 
-       switch (adapter->hw.mac_type) {
+       switch (hw->mac_type) {
        case e1000_82543:
-               if (adapter->hw.media_type == e1000_media_type_copper) {
+               if (hw->media_type == e1000_media_type_copper) {
                        /* Attempt to setup Loopback mode on Non-integrated PHY.
                         * Some PHY registers get corrupted at random, so
                         * attempt this 10 times.
@@ -1402,9 +1385,9 @@ e1000_set_phy_loopback(struct e1000_adapter *adapter)
                /* Default PHY loopback work is to read the MII
                 * control register and assert bit 14 (loopback mode).
                 */
-               e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
+               e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg);
                phy_reg |= MII_CR_LOOPBACK;
-               e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg);
+               e1000_write_phy_reg(hw, PHY_CTRL, phy_reg);
                return 0;
                break;
        }
@@ -1412,8 +1395,7 @@ e1000_set_phy_loopback(struct e1000_adapter *adapter)
        return 8;
 }
 
-static int
-e1000_setup_loopback_test(struct e1000_adapter *adapter)
+static int e1000_setup_loopback_test(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
        u32 rctl;
@@ -1431,14 +1413,14 @@ e1000_setup_loopback_test(struct e1000_adapter *adapter)
                case e1000_82572:
 #define E1000_SERDES_LB_ON 0x410
                        e1000_set_phy_loopback(adapter);
-                       E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_ON);
+                       ew32(SCTL, E1000_SERDES_LB_ON);
                        msleep(10);
                        return 0;
                        break;
                default:
-                       rctl = E1000_READ_REG(hw, RCTL);
+                       rctl = er32(RCTL);
                        rctl |= E1000_RCTL_LBM_TCVR;
-                       E1000_WRITE_REG(hw, RCTL, rctl);
+                       ew32(RCTL, rctl);
                        return 0;
                }
        } else if (hw->media_type == e1000_media_type_copper)
@@ -1447,16 +1429,15 @@ e1000_setup_loopback_test(struct e1000_adapter *adapter)
        return 7;
 }
 
-static void
-e1000_loopback_cleanup(struct e1000_adapter *adapter)
+static void e1000_loopback_cleanup(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
        u32 rctl;
        u16 phy_reg;
 
-       rctl = E1000_READ_REG(hw, RCTL);
+       rctl = er32(RCTL);
        rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
-       E1000_WRITE_REG(hw, RCTL, rctl);
+       ew32(RCTL, rctl);
 
        switch (hw->mac_type) {
        case e1000_82571:
@@ -1464,7 +1445,7 @@ e1000_loopback_cleanup(struct e1000_adapter *adapter)
                if (hw->media_type == e1000_media_type_fiber ||
                    hw->media_type == e1000_media_type_internal_serdes) {
 #define E1000_SERDES_LB_OFF 0x400
-                       E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_OFF);
+                       ew32(SCTL, E1000_SERDES_LB_OFF);
                        msleep(10);
                        break;
                }
@@ -1489,8 +1470,8 @@ e1000_loopback_cleanup(struct e1000_adapter *adapter)
        }
 }
 
-static void
-e1000_create_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
+static void e1000_create_lbtest_frame(struct sk_buff *skb,
+                                     unsigned int frame_size)
 {
        memset(skb->data, 0xFF, frame_size);
        frame_size &= ~1;
@@ -1499,8 +1480,8 @@ e1000_create_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
        memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
 }
 
-static int
-e1000_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
+static int e1000_check_lbtest_frame(struct sk_buff *skb,
+                                   unsigned int frame_size)
 {
        frame_size &= ~1;
        if (*(skb->data + 3) == 0xFF) {
@@ -1512,16 +1493,16 @@ e1000_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
        return 13;
 }
 
-static int
-e1000_run_loopback_test(struct e1000_adapter *adapter)
+static int e1000_run_loopback_test(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
        struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
        struct pci_dev *pdev = adapter->pdev;
        int i, j, k, l, lc, good_cnt, ret_val=0;
        unsigned long time;
 
-       E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1);
+       ew32(RDT, rxdr->count - 1);
 
        /* Calculate the loop count based on the largest descriptor ring
         * The idea is to wrap the largest ring a number of times using 64
@@ -1544,7 +1525,7 @@ e1000_run_loopback_test(struct e1000_adapter *adapter)
                                        PCI_DMA_TODEVICE);
                        if (unlikely(++k == txdr->count)) k = 0;
                }
-               E1000_WRITE_REG(&adapter->hw, TDT, k);
+               ew32(TDT, k);
                msleep(200);
                time = jiffies; /* set the start time for the receive */
                good_cnt = 0;
@@ -1577,21 +1558,24 @@ e1000_run_loopback_test(struct e1000_adapter *adapter)
        return ret_val;
 }
 
-static int
-e1000_loopback_test(struct e1000_adapter *adapter, u64 *data)
+static int e1000_loopback_test(struct e1000_adapter *adapter, u64 *data)
 {
+       struct e1000_hw *hw = &adapter->hw;
+
        /* PHY loopback cannot be performed if SoL/IDER
         * sessions are active */
-       if (e1000_check_phy_reset_block(&adapter->hw)) {
+       if (e1000_check_phy_reset_block(hw)) {
                DPRINTK(DRV, ERR, "Cannot do PHY loopback test "
                        "when SoL/IDER is active.\n");
                *data = 0;
                goto out;
        }
 
-       if ((*data = e1000_setup_desc_rings(adapter)))
+       *data = e1000_setup_desc_rings(adapter);
+       if (*data)
                goto out;
-       if ((*data = e1000_setup_loopback_test(adapter)))
+       *data = e1000_setup_loopback_test(adapter);
+       if (*data)
                goto err_loopback;
        *data = e1000_run_loopback_test(adapter);
        e1000_loopback_cleanup(adapter);
@@ -1602,38 +1586,37 @@ out:
        return *data;
 }
 
-static int
-e1000_link_test(struct e1000_adapter *adapter, u64 *data)
+static int e1000_link_test(struct e1000_adapter *adapter, u64 *data)
 {
+       struct e1000_hw *hw = &adapter->hw;
        *data = 0;
-       if (adapter->hw.media_type == e1000_media_type_internal_serdes) {
+       if (hw->media_type == e1000_media_type_internal_serdes) {
                int i = 0;
-               adapter->hw.serdes_link_down = true;
+               hw->serdes_link_down = true;
 
                /* On some blade server designs, link establishment
                 * could take as long as 2-3 minutes */
                do {
-                       e1000_check_for_link(&adapter->hw);
-                       if (!adapter->hw.serdes_link_down)
+                       e1000_check_for_link(hw);
+                       if (!hw->serdes_link_down)
                                return *data;
                        msleep(20);
                } while (i++ < 3750);
 
                *data = 1;
        } else {
-               e1000_check_for_link(&adapter->hw);
-               if (adapter->hw.autoneg)  /* if auto_neg is set wait for it */
+               e1000_check_for_link(hw);
+               if (hw->autoneg)  /* if auto_neg is set wait for it */
                        msleep(4000);
 
-               if (!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
+               if (!(er32(STATUS) & E1000_STATUS_LU)) {
                        *data = 1;
                }
        }
        return *data;
 }
 
-static int
-e1000_get_sset_count(struct net_device *netdev, int sset)
+static int e1000_get_sset_count(struct net_device *netdev, int sset)
 {
        switch (sset) {
        case ETH_SS_TEST:
@@ -1645,11 +1628,11 @@ e1000_get_sset_count(struct net_device *netdev, int sset)
        }
 }
 
-static void
-e1000_diag_test(struct net_device *netdev,
-                  struct ethtool_test *eth_test, u64 *data)
+static void e1000_diag_test(struct net_device *netdev,
+                           struct ethtool_test *eth_test, u64 *data)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
        bool if_running = netif_running(netdev);
 
        set_bit(__E1000_TESTING, &adapter->flags);
@@ -1657,9 +1640,9 @@ e1000_diag_test(struct net_device *netdev,
                /* Offline tests */
 
                /* save speed, duplex, autoneg settings */
-               u16 autoneg_advertised = adapter->hw.autoneg_advertised;
-               u8 forced_speed_duplex = adapter->hw.forced_speed_duplex;
-               u8 autoneg = adapter->hw.autoneg;
+               u16 autoneg_advertised = hw->autoneg_advertised;
+               u8 forced_speed_duplex = hw->forced_speed_duplex;
+               u8 autoneg = hw->autoneg;
 
                DPRINTK(HW, INFO, "offline testing starting\n");
 
@@ -1692,9 +1675,9 @@ e1000_diag_test(struct net_device *netdev,
                        eth_test->flags |= ETH_TEST_FL_FAILED;
 
                /* restore speed, duplex, autoneg settings */
-               adapter->hw.autoneg_advertised = autoneg_advertised;
-               adapter->hw.forced_speed_duplex = forced_speed_duplex;
-               adapter->hw.autoneg = autoneg;
+               hw->autoneg_advertised = autoneg_advertised;
+               hw->forced_speed_duplex = forced_speed_duplex;
+               hw->autoneg = autoneg;
 
                e1000_reset(adapter);
                clear_bit(__E1000_TESTING, &adapter->flags);
@@ -1717,7 +1700,8 @@ e1000_diag_test(struct net_device *netdev,
        msleep_interruptible(4 * 1000);
 }
 
-static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
+static int e1000_wol_exclusion(struct e1000_adapter *adapter,
+                              struct ethtool_wolinfo *wol)
 {
        struct e1000_hw *hw = &adapter->hw;
        int retval = 1; /* fail by default */
@@ -1742,7 +1726,7 @@ static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wol
        case E1000_DEV_ID_82571EB_SERDES:
        case E1000_DEV_ID_82571EB_COPPER:
                /* Wake events not supported on port B */
-               if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) {
+               if (er32(STATUS) & E1000_STATUS_FUNC_1) {
                        wol->supported = 0;
                        break;
                }
@@ -1766,7 +1750,7 @@ static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wol
                /* dual port cards only support WoL on port A from now on
                 * unless it was enabled in the eeprom for port B
                 * so exclude FUNC_1 ports from having WoL enabled */
-               if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1 &&
+               if (er32(STATUS) & E1000_STATUS_FUNC_1 &&
                    !adapter->eeprom_wol) {
                        wol->supported = 0;
                        break;
@@ -1778,10 +1762,11 @@ static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wol
        return retval;
 }
 
-static void
-e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+static void e1000_get_wol(struct net_device *netdev,
+                         struct ethtool_wolinfo *wol)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
 
        wol->supported = WAKE_UCAST | WAKE_MCAST |
                         WAKE_BCAST | WAKE_MAGIC;
@@ -1793,7 +1778,7 @@ e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
                return;
 
        /* apply any specific unsupported masks here */
-       switch (adapter->hw.device_id) {
+       switch (hw->device_id) {
        case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
                /* KSP3 does not suppport UCAST wake-ups */
                wol->supported &= ~WAKE_UCAST;
@@ -1818,8 +1803,7 @@ e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
        return;
 }
 
-static int
-e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
@@ -1863,61 +1847,60 @@ e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 /* bit defines for adapter->led_status */
 #define E1000_LED_ON           0
 
-static void
-e1000_led_blink_callback(unsigned long data)
+static void e1000_led_blink_callback(unsigned long data)
 {
        struct e1000_adapter *adapter = (struct e1000_adapter *) data;
+       struct e1000_hw *hw = &adapter->hw;
 
        if (test_and_change_bit(E1000_LED_ON, &adapter->led_status))
-               e1000_led_off(&adapter->hw);
+               e1000_led_off(hw);
        else
-               e1000_led_on(&adapter->hw);
+               e1000_led_on(hw);
 
        mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL);
 }
 
-static int
-e1000_phys_id(struct net_device *netdev, u32 data)
+static int e1000_phys_id(struct net_device *netdev, u32 data)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
 
        if (!data)
                data = INT_MAX;
 
-       if (adapter->hw.mac_type < e1000_82571) {
+       if (hw->mac_type < e1000_82571) {
                if (!adapter->blink_timer.function) {
                        init_timer(&adapter->blink_timer);
                        adapter->blink_timer.function = e1000_led_blink_callback;
-                       adapter->blink_timer.data = (unsigned long) adapter;
+                       adapter->blink_timer.data = (unsigned long)adapter;
                }
-               e1000_setup_led(&adapter->hw);
+               e1000_setup_led(hw);
                mod_timer(&adapter->blink_timer, jiffies);
                msleep_interruptible(data * 1000);
                del_timer_sync(&adapter->blink_timer);
-       } else if (adapter->hw.phy_type == e1000_phy_ife) {
+       } else if (hw->phy_type == e1000_phy_ife) {
                if (!adapter->blink_timer.function) {
                        init_timer(&adapter->blink_timer);
                        adapter->blink_timer.function = e1000_led_blink_callback;
-                       adapter->blink_timer.data = (unsigned long) adapter;
+                       adapter->blink_timer.data = (unsigned long)adapter;
                }
                mod_timer(&adapter->blink_timer, jiffies);
                msleep_interruptible(data * 1000);
                del_timer_sync(&adapter->blink_timer);
                e1000_write_phy_reg(&(adapter->hw), IFE_PHY_SPECIAL_CONTROL_LED, 0);
        } else {
-               e1000_blink_led_start(&adapter->hw);
+               e1000_blink_led_start(hw);
                msleep_interruptible(data * 1000);
        }
 
-       e1000_led_off(&adapter->hw);
+       e1000_led_off(hw);
        clear_bit(E1000_LED_ON, &adapter->led_status);
-       e1000_cleanup_led(&adapter->hw);
+       e1000_cleanup_led(hw);
 
        return 0;
 }
 
-static int
-e1000_nway_reset(struct net_device *netdev)
+static int e1000_nway_reset(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        if (netif_running(netdev))
@@ -1925,9 +1908,8 @@ e1000_nway_reset(struct net_device *netdev)
        return 0;
 }
 
-static void
-e1000_get_ethtool_stats(struct net_device *netdev,
-               struct ethtool_stats *stats, u64 *data)
+static void e1000_get_ethtool_stats(struct net_device *netdev,
+                                   struct ethtool_stats *stats, u64 *data)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        int i;
@@ -1941,8 +1923,8 @@ e1000_get_ethtool_stats(struct net_device *netdev,
 /*     BUG_ON(i != E1000_STATS_LEN); */
 }
 
-static void
-e1000_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
+static void e1000_get_strings(struct net_device *netdev, u32 stringset,
+                             u8 *data)
 {
        u8 *p = data;
        int i;
index 9a4b6cbddf2cbdba6544c38a6fced642a6231b34..9d6edf3e73f92998d8fb4f19ddbbfe64cd2ca4ac 100644 (file)
@@ -42,48 +42,65 @@ static void e1000_release_software_semaphore(struct e1000_hw *hw);
 
 static u8 e1000_arc_subsystem_valid(struct e1000_hw *hw);
 static s32 e1000_check_downshift(struct e1000_hw *hw);
-static s32 e1000_check_polarity(struct e1000_hw *hw, e1000_rev_polarity *polarity);
+static s32 e1000_check_polarity(struct e1000_hw *hw,
+                               e1000_rev_polarity *polarity);
 static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
 static void e1000_clear_vfta(struct e1000_hw *hw);
 static s32 e1000_commit_shadow_ram(struct e1000_hw *hw);
 static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw,
-                                                 bool link_up);
+                                             bool link_up);
 static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw);
 static s32 e1000_detect_gig_phy(struct e1000_hw *hw);
 static s32 e1000_erase_ich8_4k_segment(struct e1000_hw *hw, u32 bank);
 static s32 e1000_get_auto_rd_done(struct e1000_hw *hw);
-static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length, u16 *max_length);
+static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
+                                 u16 *max_length);
 static s32 e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
 static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
 static s32 e1000_get_software_flag(struct e1000_hw *hw);
 static s32 e1000_ich8_cycle_init(struct e1000_hw *hw);
 static s32 e1000_ich8_flash_cycle(struct e1000_hw *hw, u32 timeout);
 static s32 e1000_id_led_init(struct e1000_hw *hw);
-static s32 e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw, u32 cnf_base_addr, u32 cnf_size);
+static s32 e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
+                                                u32 cnf_base_addr,
+                                                u32 cnf_size);
 static s32 e1000_init_lcd_from_nvm(struct e1000_hw *hw);
 static void e1000_init_rx_addrs(struct e1000_hw *hw);
 static void e1000_initialize_hardware_bits(struct e1000_hw *hw);
 static bool e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
 static s32 e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw);
 static s32 e1000_mng_enable_host_if(struct e1000_hw *hw);
-static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length, u16 offset, u8 *sum);
-static s32 e1000_mng_write_cmd_header(struct e1000_hw* hw, struct e1000_host_mng_command_header* hdr);
+static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
+                                  u16 offset, u8 *sum);
+static s32 e1000_mng_write_cmd_header(struct e1000_hw* hw,
+                                     struct e1000_host_mng_command_header
+                                     *hdr);
 static s32 e1000_mng_write_commit(struct e1000_hw *hw);
-static s32 e1000_phy_ife_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
-static s32 e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
-static s32 e1000_read_eeprom_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
-static s32 e1000_write_eeprom_eewr(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
+static s32 e1000_phy_ife_get_info(struct e1000_hw *hw,
+                                 struct e1000_phy_info *phy_info);
+static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
+                                 struct e1000_phy_info *phy_info);
+static s32 e1000_read_eeprom_eerd(struct e1000_hw *hw, u16 offset, u16 words,
+                                 u16 *data);
+static s32 e1000_write_eeprom_eewr(struct e1000_hw *hw, u16 offset, u16 words,
+                                  u16 *data);
 static s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
-static s32 e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
+static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
+                                 struct e1000_phy_info *phy_info);
 static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
 static s32 e1000_read_ich8_byte(struct e1000_hw *hw, u32 index, u8 *data);
-static s32 e1000_verify_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 byte);
+static s32 e1000_verify_write_ich8_byte(struct e1000_hw *hw, u32 index,
+                                       u8 byte);
 static s32 e1000_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 byte);
 static s32 e1000_read_ich8_word(struct e1000_hw *hw, u32 index, u16 *data);
-static s32 e1000_read_ich8_data(struct e1000_hw *hw, u32 index, u32 size, u16 *data);
-static s32 e1000_write_ich8_data(struct e1000_hw *hw, u32 index, u32 size, u16 data);
-static s32 e1000_read_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
-static s32 e1000_write_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
+static s32 e1000_read_ich8_data(struct e1000_hw *hw, u32 index, u32 size,
+                               u16 *data);
+static s32 e1000_write_ich8_data(struct e1000_hw *hw, u32 index, u32 size,
+                                u16 data);
+static s32 e1000_read_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
+                                 u16 *data);
+static s32 e1000_write_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
+                                  u16 *data);
 static void e1000_release_software_flag(struct e1000_hw *hw);
 static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
 static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
@@ -101,23 +118,21 @@ static s32 e1000_config_mac_to_phy(struct e1000_hw *hw);
 static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
 static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
 static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, u32 data,
-                                     u16 count);
+                                    u16 count);
 static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw);
 static s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
 static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset,
                                       u16 words, u16 *data);
-static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw,
-                                            u16 offset, u16 words,
-                                            u16 *data);
+static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
+                                       u16 words, u16 *data);
 static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw);
 static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd);
 static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd);
-static void e1000_shift_out_ee_bits(struct e1000_hw *hw, u16 data,
-                                    u16 count);
+static void e1000_shift_out_ee_bits(struct e1000_hw *hw, u16 data, u16 count);
 static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
-                                      u16 phy_data);
+                                 u16 phy_data);
 static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw,u32 reg_addr,
-                                     u16 *phy_data);
+                                u16 *phy_data);
 static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count);
 static s32 e1000_acquire_eeprom(struct e1000_hw *hw);
 static void e1000_release_eeprom(struct e1000_hw *hw);
@@ -127,8 +142,7 @@ static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw);
 static s32 e1000_set_phy_mode(struct e1000_hw *hw);
 static s32 e1000_host_if_read_cookie(struct e1000_hw *hw, u8 *buffer);
 static u8 e1000_calculate_mng_checksum(char *buffer, u32 length);
-static s32 e1000_configure_kmrn_for_10_100(struct e1000_hw *hw,
-                                               u16 duplex);
+static s32 e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, u16 duplex);
 static s32 e1000_configure_kmrn_for_1000(struct e1000_hw *hw);
 
 /* IGP cable length table */
@@ -159,8 +173,7 @@ u16 e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static s32
-e1000_set_phy_type(struct e1000_hw *hw)
+static s32 e1000_set_phy_type(struct e1000_hw *hw)
 {
     DEBUGFUNC("e1000_set_phy_type");
 
@@ -210,8 +223,7 @@ e1000_set_phy_type(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void
-e1000_phy_init_script(struct e1000_hw *hw)
+static void e1000_phy_init_script(struct e1000_hw *hw)
 {
     u32 ret_val;
     u16 phy_saved_data;
@@ -306,8 +318,7 @@ e1000_phy_init_script(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-s32
-e1000_set_mac_type(struct e1000_hw *hw)
+s32 e1000_set_mac_type(struct e1000_hw *hw)
 {
        DEBUGFUNC("e1000_set_mac_type");
 
@@ -474,8 +485,7 @@ e1000_set_mac_type(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  * **************************************************************************/
-void
-e1000_set_media_type(struct e1000_hw *hw)
+void e1000_set_media_type(struct e1000_hw *hw)
 {
     u32 status;
 
@@ -510,7 +520,7 @@ e1000_set_media_type(struct e1000_hw *hw)
             hw->media_type = e1000_media_type_copper;
             break;
         default:
-            status = E1000_READ_REG(hw, STATUS);
+            status = er32(STATUS);
             if (status & E1000_STATUS_TBIMODE) {
                 hw->media_type = e1000_media_type_fiber;
                 /* tbi_compatibility not valid on fiber */
@@ -528,8 +538,7 @@ e1000_set_media_type(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-s32
-e1000_reset_hw(struct e1000_hw *hw)
+s32 e1000_reset_hw(struct e1000_hw *hw)
 {
     u32 ctrl;
     u32 ctrl_ext;
@@ -559,15 +568,15 @@ e1000_reset_hw(struct e1000_hw *hw)
 
     /* Clear interrupt mask to stop board from generating interrupts */
     DEBUGOUT("Masking off all interrupts\n");
-    E1000_WRITE_REG(hw, IMC, 0xffffffff);
+    ew32(IMC, 0xffffffff);
 
     /* Disable the Transmit and Receive units.  Then delay to allow
      * any pending transactions to complete before we hit the MAC with
      * the global reset.
      */
-    E1000_WRITE_REG(hw, RCTL, 0);
-    E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
-    E1000_WRITE_FLUSH(hw);
+    ew32(RCTL, 0);
+    ew32(TCTL, E1000_TCTL_PSP);
+    E1000_WRITE_FLUSH();
 
     /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
     hw->tbi_compatibility_on = false;
@@ -577,11 +586,11 @@ e1000_reset_hw(struct e1000_hw *hw)
      */
     msleep(10);
 
-    ctrl = E1000_READ_REG(hw, CTRL);
+    ctrl = er32(CTRL);
 
     /* Must reset the PHY before resetting the MAC */
     if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
-        E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
+        ew32(CTRL, (ctrl | E1000_CTRL_PHY_RST));
         msleep(5);
     }
 
@@ -590,12 +599,12 @@ e1000_reset_hw(struct e1000_hw *hw)
     if (hw->mac_type == e1000_82573) {
         timeout = 10;
 
-        extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
+        extcnf_ctrl = er32(EXTCNF_CTRL);
         extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
 
         do {
-            E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);
-            extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
+            ew32(EXTCNF_CTRL, extcnf_ctrl);
+            extcnf_ctrl = er32(EXTCNF_CTRL);
 
             if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
                 break;
@@ -610,9 +619,9 @@ e1000_reset_hw(struct e1000_hw *hw)
     /* Workaround for ICH8 bit corruption issue in FIFO memory */
     if (hw->mac_type == e1000_ich8lan) {
         /* Set Tx and Rx buffer allocation to 8k apiece. */
-        E1000_WRITE_REG(hw, PBA, E1000_PBA_8K);
+        ew32(PBA, E1000_PBA_8K);
         /* Set Packet Buffer Size to 16k. */
-        E1000_WRITE_REG(hw, PBS, E1000_PBS_16K);
+        ew32(PBS, E1000_PBS_16K);
     }
 
     /* Issue a global reset to the MAC.  This will reset the chip's
@@ -636,7 +645,7 @@ e1000_reset_hw(struct e1000_hw *hw)
         case e1000_82545_rev_3:
         case e1000_82546_rev_3:
             /* Reset is performed on a shadow of the control register */
-            E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST));
+            ew32(CTRL_DUP, (ctrl | E1000_CTRL_RST));
             break;
         case e1000_ich8lan:
             if (!hw->phy_reset_disable &&
@@ -649,11 +658,11 @@ e1000_reset_hw(struct e1000_hw *hw)
             }
 
             e1000_get_software_flag(hw);
-            E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
+            ew32(CTRL, (ctrl | E1000_CTRL_RST));
             msleep(5);
             break;
         default:
-            E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
+            ew32(CTRL, (ctrl | E1000_CTRL_RST));
             break;
     }
 
@@ -668,10 +677,10 @@ e1000_reset_hw(struct e1000_hw *hw)
         case e1000_82544:
             /* Wait for reset to complete */
             udelay(10);
-            ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+            ctrl_ext = er32(CTRL_EXT);
             ctrl_ext |= E1000_CTRL_EXT_EE_RST;
-            E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-            E1000_WRITE_FLUSH(hw);
+            ew32(CTRL_EXT, ctrl_ext);
+            E1000_WRITE_FLUSH();
             /* Wait for EEPROM reload */
             msleep(2);
             break;
@@ -685,10 +694,10 @@ e1000_reset_hw(struct e1000_hw *hw)
         case e1000_82573:
             if (!e1000_is_onboard_nvm_eeprom(hw)) {
                 udelay(10);
-                ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+                ctrl_ext = er32(CTRL_EXT);
                 ctrl_ext |= E1000_CTRL_EXT_EE_RST;
-                E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-                E1000_WRITE_FLUSH(hw);
+                ew32(CTRL_EXT, ctrl_ext);
+                E1000_WRITE_FLUSH();
             }
             /* fall through */
         default:
@@ -701,27 +710,27 @@ e1000_reset_hw(struct e1000_hw *hw)
 
     /* Disable HW ARPs on ASF enabled adapters */
     if (hw->mac_type >= e1000_82540 && hw->mac_type <= e1000_82547_rev_2) {
-        manc = E1000_READ_REG(hw, MANC);
+        manc = er32(MANC);
         manc &= ~(E1000_MANC_ARP_EN);
-        E1000_WRITE_REG(hw, MANC, manc);
+        ew32(MANC, manc);
     }
 
     if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
         e1000_phy_init_script(hw);
 
         /* Configure activity LED after PHY reset */
-        led_ctrl = E1000_READ_REG(hw, LEDCTL);
+        led_ctrl = er32(LEDCTL);
         led_ctrl &= IGP_ACTIVITY_LED_MASK;
         led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
-        E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
+        ew32(LEDCTL, led_ctrl);
     }
 
     /* Clear interrupt mask to stop board from generating interrupts */
     DEBUGOUT("Masking off all interrupts\n");
-    E1000_WRITE_REG(hw, IMC, 0xffffffff);
+    ew32(IMC, 0xffffffff);
 
     /* Clear any pending interrupt events. */
-    icr = E1000_READ_REG(hw, ICR);
+    icr = er32(ICR);
 
     /* If MWI was previously enabled, reenable it. */
     if (hw->mac_type == e1000_82542_rev2_0) {
@@ -730,9 +739,9 @@ e1000_reset_hw(struct e1000_hw *hw)
     }
 
     if (hw->mac_type == e1000_ich8lan) {
-        u32 kab = E1000_READ_REG(hw, KABGTXD);
+        u32 kab = er32(KABGTXD);
         kab |= E1000_KABGTXD_BGSQLBIAS;
-        E1000_WRITE_REG(hw, KABGTXD, kab);
+        ew32(KABGTXD, kab);
     }
 
     return E1000_SUCCESS;
@@ -747,8 +756,7 @@ e1000_reset_hw(struct e1000_hw *hw)
  * This function contains hardware limitation workarounds for PCI-E adapters
  *
  *****************************************************************************/
-static void
-e1000_initialize_hardware_bits(struct e1000_hw *hw)
+static void e1000_initialize_hardware_bits(struct e1000_hw *hw)
 {
     if ((hw->mac_type >= e1000_82571) && (!hw->initialize_hw_bits_disable)) {
         /* Settings common to all PCI-express silicon */
@@ -758,22 +766,22 @@ e1000_initialize_hardware_bits(struct e1000_hw *hw)
         u32 reg_txdctl, reg_txdctl1;
 
         /* link autonegotiation/sync workarounds */
-        reg_tarc0 = E1000_READ_REG(hw, TARC0);
+        reg_tarc0 = er32(TARC0);
         reg_tarc0 &= ~((1 << 30)|(1 << 29)|(1 << 28)|(1 << 27));
 
         /* Enable not-done TX descriptor counting */
-        reg_txdctl = E1000_READ_REG(hw, TXDCTL);
+        reg_txdctl = er32(TXDCTL);
         reg_txdctl |= E1000_TXDCTL_COUNT_DESC;
-        E1000_WRITE_REG(hw, TXDCTL, reg_txdctl);
-        reg_txdctl1 = E1000_READ_REG(hw, TXDCTL1);
+        ew32(TXDCTL, reg_txdctl);
+        reg_txdctl1 = er32(TXDCTL1);
         reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC;
-        E1000_WRITE_REG(hw, TXDCTL1, reg_txdctl1);
+        ew32(TXDCTL1, reg_txdctl1);
 
         switch (hw->mac_type) {
             case e1000_82571:
             case e1000_82572:
                 /* Clear PHY TX compatible mode bits */
-                reg_tarc1 = E1000_READ_REG(hw, TARC1);
+                reg_tarc1 = er32(TARC1);
                 reg_tarc1 &= ~((1 << 30)|(1 << 29));
 
                 /* link autonegotiation/sync workarounds */
@@ -783,25 +791,25 @@ e1000_initialize_hardware_bits(struct e1000_hw *hw)
                 reg_tarc1 |= ((1 << 26)|(1 << 25)|(1 << 24));
 
                 /* Multiple read bit is reversed polarity */
-                reg_tctl = E1000_READ_REG(hw, TCTL);
+                reg_tctl = er32(TCTL);
                 if (reg_tctl & E1000_TCTL_MULR)
                     reg_tarc1 &= ~(1 << 28);
                 else
                     reg_tarc1 |= (1 << 28);
 
-                E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+                ew32(TARC1, reg_tarc1);
                 break;
             case e1000_82573:
-                reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+                reg_ctrl_ext = er32(CTRL_EXT);
                 reg_ctrl_ext &= ~(1 << 23);
                 reg_ctrl_ext |= (1 << 22);
 
                 /* TX byte count fix */
-                reg_ctrl = E1000_READ_REG(hw, CTRL);
+                reg_ctrl = er32(CTRL);
                 reg_ctrl &= ~(1 << 29);
 
-                E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);
-                E1000_WRITE_REG(hw, CTRL, reg_ctrl);
+                ew32(CTRL_EXT, reg_ctrl_ext);
+                ew32(CTRL, reg_ctrl);
                 break;
             case e1000_80003es2lan:
                 /* improve small packet performace for fiber/serdes */
@@ -811,14 +819,14 @@ e1000_initialize_hardware_bits(struct e1000_hw *hw)
                 }
 
                 /* Multiple read bit is reversed polarity */
-                reg_tctl = E1000_READ_REG(hw, TCTL);
-                reg_tarc1 = E1000_READ_REG(hw, TARC1);
+                reg_tctl = er32(TCTL);
+                reg_tarc1 = er32(TARC1);
                 if (reg_tctl & E1000_TCTL_MULR)
                     reg_tarc1 &= ~(1 << 28);
                 else
                     reg_tarc1 |= (1 << 28);
 
-                E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+                ew32(TARC1, reg_tarc1);
                 break;
             case e1000_ich8lan:
                 /* Reduce concurrent DMA requests to 3 from 4 */
@@ -827,16 +835,16 @@ e1000_initialize_hardware_bits(struct e1000_hw *hw)
                      (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))
                     reg_tarc0 |= ((1 << 29)|(1 << 28));
 
-                reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+                reg_ctrl_ext = er32(CTRL_EXT);
                 reg_ctrl_ext |= (1 << 22);
-                E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext);
+                ew32(CTRL_EXT, reg_ctrl_ext);
 
                 /* workaround TX hang with TSO=on */
                 reg_tarc0 |= ((1 << 27)|(1 << 26)|(1 << 24)|(1 << 23));
 
                 /* Multiple read bit is reversed polarity */
-                reg_tctl = E1000_READ_REG(hw, TCTL);
-                reg_tarc1 = E1000_READ_REG(hw, TARC1);
+                reg_tctl = er32(TCTL);
+                reg_tarc1 = er32(TARC1);
                 if (reg_tctl & E1000_TCTL_MULR)
                     reg_tarc1 &= ~(1 << 28);
                 else
@@ -845,13 +853,13 @@ e1000_initialize_hardware_bits(struct e1000_hw *hw)
                 /* workaround TX hang with TSO=on */
                 reg_tarc1 |= ((1 << 30)|(1 << 26)|(1 << 24));
 
-                E1000_WRITE_REG(hw, TARC1, reg_tarc1);
+                ew32(TARC1, reg_tarc1);
                 break;
             default:
                 break;
         }
 
-        E1000_WRITE_REG(hw, TARC0, reg_tarc0);
+        ew32(TARC0, reg_tarc0);
     }
 }
 
@@ -866,8 +874,7 @@ e1000_initialize_hardware_bits(struct e1000_hw *hw)
  * configuration and flow control settings. Clears all on-chip counters. Leaves
  * the transmit and receive units disabled and uninitialized.
  *****************************************************************************/
-s32
-e1000_init_hw(struct e1000_hw *hw)
+s32 e1000_init_hw(struct e1000_hw *hw)
 {
     u32 ctrl;
     u32 i;
@@ -883,9 +890,9 @@ e1000_init_hw(struct e1000_hw *hw)
         ((hw->revision_id < 3) ||
          ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
           (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))) {
-            reg_data = E1000_READ_REG(hw, STATUS);
+            reg_data = er32(STATUS);
             reg_data &= ~0x80000000;
-            E1000_WRITE_REG(hw, STATUS, reg_data);
+            ew32(STATUS, reg_data);
     }
 
     /* Initialize Identification LED */
@@ -906,7 +913,7 @@ e1000_init_hw(struct e1000_hw *hw)
     /* VET hardcoded to standard value and VFTA removed in ICH8 LAN */
     if (hw->mac_type != e1000_ich8lan) {
         if (hw->mac_type < e1000_82545_rev_3)
-            E1000_WRITE_REG(hw, VET, 0);
+            ew32(VET, 0);
         e1000_clear_vfta(hw);
     }
 
@@ -914,8 +921,8 @@ e1000_init_hw(struct e1000_hw *hw)
     if (hw->mac_type == e1000_82542_rev2_0) {
         DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
         e1000_pci_clear_mwi(hw);
-        E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
-        E1000_WRITE_FLUSH(hw);
+        ew32(RCTL, E1000_RCTL_RST);
+        E1000_WRITE_FLUSH();
         msleep(5);
     }
 
@@ -926,8 +933,8 @@ e1000_init_hw(struct e1000_hw *hw)
 
     /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
     if (hw->mac_type == e1000_82542_rev2_0) {
-        E1000_WRITE_REG(hw, RCTL, 0);
-        E1000_WRITE_FLUSH(hw);
+        ew32(RCTL, 0);
+        E1000_WRITE_FLUSH();
         msleep(1);
         if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
             e1000_pci_set_mwi(hw);
@@ -942,7 +949,7 @@ e1000_init_hw(struct e1000_hw *hw)
         E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
         /* use write flush to prevent Memory Write Block (MWB) from
          * occuring when accessing our register space */
-        E1000_WRITE_FLUSH(hw);
+        E1000_WRITE_FLUSH();
     }
 
     /* Set the PCI priority bit correctly in the CTRL register.  This
@@ -951,8 +958,8 @@ e1000_init_hw(struct e1000_hw *hw)
      * 82542 and 82543 silicon.
      */
     if (hw->dma_fairness && hw->mac_type <= e1000_82543) {
-        ctrl = E1000_READ_REG(hw, CTRL);
-        E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
+        ctrl = er32(CTRL);
+        ew32(CTRL, ctrl | E1000_CTRL_PRIOR);
     }
 
     switch (hw->mac_type) {
@@ -975,9 +982,9 @@ e1000_init_hw(struct e1000_hw *hw)
 
     /* Set the transmit descriptor write-back policy */
     if (hw->mac_type > e1000_82544) {
-        ctrl = E1000_READ_REG(hw, TXDCTL);
+        ctrl = er32(TXDCTL);
         ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
-        E1000_WRITE_REG(hw, TXDCTL, ctrl);
+        ew32(TXDCTL, ctrl);
     }
 
     if (hw->mac_type == e1000_82573) {
@@ -989,21 +996,21 @@ e1000_init_hw(struct e1000_hw *hw)
         break;
     case e1000_80003es2lan:
         /* Enable retransmit on late collisions */
-        reg_data = E1000_READ_REG(hw, TCTL);
+        reg_data = er32(TCTL);
         reg_data |= E1000_TCTL_RTLC;
-        E1000_WRITE_REG(hw, TCTL, reg_data);
+        ew32(TCTL, reg_data);
 
         /* Configure Gigabit Carry Extend Padding */
-        reg_data = E1000_READ_REG(hw, TCTL_EXT);
+        reg_data = er32(TCTL_EXT);
         reg_data &= ~E1000_TCTL_EXT_GCEX_MASK;
         reg_data |= DEFAULT_80003ES2LAN_TCTL_EXT_GCEX;
-        E1000_WRITE_REG(hw, TCTL_EXT, reg_data);
+        ew32(TCTL_EXT, reg_data);
 
         /* Configure Transmit Inter-Packet Gap */
-        reg_data = E1000_READ_REG(hw, TIPG);
+        reg_data = er32(TIPG);
         reg_data &= ~E1000_TIPG_IPGT_MASK;
         reg_data |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000;
-        E1000_WRITE_REG(hw, TIPG, reg_data);
+        ew32(TIPG, reg_data);
 
         reg_data = E1000_READ_REG_ARRAY(hw, FFLT, 0x0001);
         reg_data &= ~0x00100000;
@@ -1012,17 +1019,17 @@ e1000_init_hw(struct e1000_hw *hw)
     case e1000_82571:
     case e1000_82572:
     case e1000_ich8lan:
-        ctrl = E1000_READ_REG(hw, TXDCTL1);
+        ctrl = er32(TXDCTL1);
         ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
-        E1000_WRITE_REG(hw, TXDCTL1, ctrl);
+        ew32(TXDCTL1, ctrl);
         break;
     }
 
 
     if (hw->mac_type == e1000_82573) {
-        u32 gcr = E1000_READ_REG(hw, GCR);
+        u32 gcr = er32(GCR);
         gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
-        E1000_WRITE_REG(hw, GCR, gcr);
+        ew32(GCR, gcr);
     }
 
     /* Clear all of the statistics registers (clear on read).  It is
@@ -1039,11 +1046,11 @@ e1000_init_hw(struct e1000_hw *hw)
 
     if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER ||
         hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) {
-        ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+        ctrl_ext = er32(CTRL_EXT);
         /* Relaxed ordering must be disabled to avoid a parity
          * error crash in a PCI slot. */
         ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
-        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+        ew32(CTRL_EXT, ctrl_ext);
     }
 
     return ret_val;
@@ -1054,8 +1061,7 @@ e1000_init_hw(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code.
  *****************************************************************************/
-static s32
-e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
+static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
 {
     u16 eeprom_data;
     s32  ret_val;
@@ -1100,8 +1106,7 @@ e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
  * established. Assumes the hardware has previously been reset and the
  * transmitter and receiver are not enabled.
  *****************************************************************************/
-s32
-e1000_setup_link(struct e1000_hw *hw)
+s32 e1000_setup_link(struct e1000_hw *hw)
 {
     u32 ctrl_ext;
     s32 ret_val;
@@ -1176,7 +1181,7 @@ e1000_setup_link(struct e1000_hw *hw)
         }
         ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
                     SWDPIO__EXT_SHIFT);
-        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+        ew32(CTRL_EXT, ctrl_ext);
     }
 
     /* Call the necessary subroutine to configure the link. */
@@ -1193,12 +1198,12 @@ e1000_setup_link(struct e1000_hw *hw)
 
     /* FCAL/H and FCT are hardcoded to standard values in e1000_ich8lan. */
     if (hw->mac_type != e1000_ich8lan) {
-        E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE);
-        E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH);
-        E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW);
+        ew32(FCT, FLOW_CONTROL_TYPE);
+        ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
+        ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
     }
 
-    E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time);
+    ew32(FCTTV, hw->fc_pause_time);
 
     /* Set the flow control receive threshold registers.  Normally,
      * these registers will be set to a default threshold that may be
@@ -1207,18 +1212,18 @@ e1000_setup_link(struct e1000_hw *hw)
      * registers will be set to 0.
      */
     if (!(hw->fc & E1000_FC_TX_PAUSE)) {
-        E1000_WRITE_REG(hw, FCRTL, 0);
-        E1000_WRITE_REG(hw, FCRTH, 0);
+        ew32(FCRTL, 0);
+        ew32(FCRTH, 0);
     } else {
         /* We need to set up the Receive Threshold high and low water marks
          * as well as (optionally) enabling the transmission of XON frames.
          */
         if (hw->fc_send_xon) {
-            E1000_WRITE_REG(hw, FCRTL, (hw->fc_low_water | E1000_FCRTL_XONE));
-            E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
+            ew32(FCRTL, (hw->fc_low_water | E1000_FCRTL_XONE));
+            ew32(FCRTH, hw->fc_high_water);
         } else {
-            E1000_WRITE_REG(hw, FCRTL, hw->fc_low_water);
-            E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
+            ew32(FCRTL, hw->fc_low_water);
+            ew32(FCRTH, hw->fc_high_water);
         }
     }
     return ret_val;
@@ -1233,8 +1238,7 @@ e1000_setup_link(struct e1000_hw *hw)
  * link. Assumes the hardware has been previously reset and the transmitter
  * and receiver are not enabled.
  *****************************************************************************/
-static s32
-e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
+static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
 {
     u32 ctrl;
     u32 status;
@@ -1251,7 +1255,7 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
      * loopback mode is disabled during initialization.
      */
     if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572)
-        E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK);
+        ew32(SCTL, E1000_DISABLE_SERDES_LOOPBACK);
 
     /* On adapters with a MAC newer than 82544, SWDP 1 will be
      * set when the optics detect a signal. On older adapters, it will be
@@ -1259,7 +1263,7 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
      * If we're on serdes media, adjust the output amplitude to value
      * set in the EEPROM.
      */
-    ctrl = E1000_READ_REG(hw, CTRL);
+    ctrl = er32(CTRL);
     if (hw->media_type == e1000_media_type_fiber)
         signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
 
@@ -1330,9 +1334,9 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
      */
     DEBUGOUT("Auto-negotiation enabled\n");
 
-    E1000_WRITE_REG(hw, TXCW, txcw);
-    E1000_WRITE_REG(hw, CTRL, ctrl);
-    E1000_WRITE_FLUSH(hw);
+    ew32(TXCW, txcw);
+    ew32(CTRL, ctrl);
+    E1000_WRITE_FLUSH();
 
     hw->txcw = txcw;
     msleep(1);
@@ -1344,11 +1348,11 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
      * For internal serdes, we just assume a signal is present, then poll.
      */
     if (hw->media_type == e1000_media_type_internal_serdes ||
-       (E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
+       (er32(CTRL) & E1000_CTRL_SWDPIN1) == signal) {
         DEBUGOUT("Looking for Link\n");
         for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
             msleep(10);
-            status = E1000_READ_REG(hw, STATUS);
+            status = er32(STATUS);
             if (status & E1000_STATUS_LU) break;
         }
         if (i == (LINK_UP_TIMEOUT / 10)) {
@@ -1380,8 +1384,7 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-static s32
-e1000_copper_link_preconfig(struct e1000_hw *hw)
+static s32 e1000_copper_link_preconfig(struct e1000_hw *hw)
 {
     u32 ctrl;
     s32 ret_val;
@@ -1389,7 +1392,7 @@ e1000_copper_link_preconfig(struct e1000_hw *hw)
 
     DEBUGFUNC("e1000_copper_link_preconfig");
 
-    ctrl = E1000_READ_REG(hw, CTRL);
+    ctrl = er32(CTRL);
     /* With 82543, we need to force speed and duplex on the MAC equal to what
      * the PHY speed and duplex configuration is. In addition, we need to
      * perform a hardware reset on the PHY to take it out of reset.
@@ -1397,10 +1400,10 @@ e1000_copper_link_preconfig(struct e1000_hw *hw)
     if (hw->mac_type > e1000_82543) {
         ctrl |= E1000_CTRL_SLU;
         ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
-        E1000_WRITE_REG(hw, CTRL, ctrl);
+        ew32(CTRL, ctrl);
     } else {
         ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
-        E1000_WRITE_REG(hw, CTRL, ctrl);
+        ew32(CTRL, ctrl);
         ret_val = e1000_phy_hw_reset(hw);
         if (ret_val)
             return ret_val;
@@ -1440,8 +1443,7 @@ e1000_copper_link_preconfig(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 *********************************************************************/
-static s32
-e1000_copper_link_igp_setup(struct e1000_hw *hw)
+static s32 e1000_copper_link_igp_setup(struct e1000_hw *hw)
 {
     u32 led_ctrl;
     s32 ret_val;
@@ -1462,10 +1464,10 @@ e1000_copper_link_igp_setup(struct e1000_hw *hw)
     msleep(15);
     if (hw->mac_type != e1000_ich8lan) {
     /* Configure activity LED after PHY reset */
-    led_ctrl = E1000_READ_REG(hw, LEDCTL);
+    led_ctrl = er32(LEDCTL);
     led_ctrl &= IGP_ACTIVITY_LED_MASK;
     led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
-    E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
+    ew32(LEDCTL, led_ctrl);
     }
 
     /* The NVM settings will configure LPLU in D3 for IGP2 and IGP3 PHYs */
@@ -1587,8 +1589,7 @@ e1000_copper_link_igp_setup(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 *********************************************************************/
-static s32
-e1000_copper_link_ggp_setup(struct e1000_hw *hw)
+static s32 e1000_copper_link_ggp_setup(struct e1000_hw *hw)
 {
     s32 ret_val;
     u16 phy_data;
@@ -1679,9 +1680,9 @@ e1000_copper_link_ggp_setup(struct e1000_hw *hw)
         if (ret_val)
             return ret_val;
 
-        reg_data = E1000_READ_REG(hw, CTRL_EXT);
+        reg_data = er32(CTRL_EXT);
         reg_data &= ~(E1000_CTRL_EXT_LINK_MODE_MASK);
-        E1000_WRITE_REG(hw, CTRL_EXT, reg_data);
+        ew32(CTRL_EXT, reg_data);
 
         ret_val = e1000_read_phy_reg(hw, GG82563_PHY_PWR_MGMT_CTRL,
                                           &phy_data);
@@ -1735,8 +1736,7 @@ e1000_copper_link_ggp_setup(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 *********************************************************************/
-static s32
-e1000_copper_link_mgp_setup(struct e1000_hw *hw)
+static s32 e1000_copper_link_mgp_setup(struct e1000_hw *hw)
 {
     s32 ret_val;
     u16 phy_data;
@@ -1839,8 +1839,7 @@ e1000_copper_link_mgp_setup(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 *********************************************************************/
-static s32
-e1000_copper_link_autoneg(struct e1000_hw *hw)
+static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
 {
     s32 ret_val;
     u16 phy_data;
@@ -1910,8 +1909,7 @@ e1000_copper_link_autoneg(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-static s32
-e1000_copper_link_postconfig(struct e1000_hw *hw)
+static s32 e1000_copper_link_postconfig(struct e1000_hw *hw)
 {
     s32 ret_val;
     DEBUGFUNC("e1000_copper_link_postconfig");
@@ -1948,8 +1946,7 @@ e1000_copper_link_postconfig(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-static s32
-e1000_setup_copper_link(struct e1000_hw *hw)
+static s32 e1000_setup_copper_link(struct e1000_hw *hw)
 {
     s32 ret_val;
     u16 i;
@@ -2062,8 +2059,7 @@ e1000_setup_copper_link(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-static s32
-e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, u16 duplex)
+static s32 e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, u16 duplex)
 {
     s32 ret_val = E1000_SUCCESS;
     u32 tipg;
@@ -2078,10 +2074,10 @@ e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, u16 duplex)
         return ret_val;
 
     /* Configure Transmit Inter-Packet Gap */
-    tipg = E1000_READ_REG(hw, TIPG);
+    tipg = er32(TIPG);
     tipg &= ~E1000_TIPG_IPGT_MASK;
     tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_10_100;
-    E1000_WRITE_REG(hw, TIPG, tipg);
+    ew32(TIPG, tipg);
 
     ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
 
@@ -2098,8 +2094,7 @@ e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, u16 duplex)
     return ret_val;
 }
 
-static s32
-e1000_configure_kmrn_for_1000(struct e1000_hw *hw)
+static s32 e1000_configure_kmrn_for_1000(struct e1000_hw *hw)
 {
     s32 ret_val = E1000_SUCCESS;
     u16 reg_data;
@@ -2114,10 +2109,10 @@ e1000_configure_kmrn_for_1000(struct e1000_hw *hw)
         return ret_val;
 
     /* Configure Transmit Inter-Packet Gap */
-    tipg = E1000_READ_REG(hw, TIPG);
+    tipg = er32(TIPG);
     tipg &= ~E1000_TIPG_IPGT_MASK;
     tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000;
-    E1000_WRITE_REG(hw, TIPG, tipg);
+    ew32(TIPG, tipg);
 
     ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
 
@@ -2135,8 +2130,7 @@ e1000_configure_kmrn_for_1000(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-s32
-e1000_phy_setup_autoneg(struct e1000_hw *hw)
+s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
 {
     s32 ret_val;
     u16 mii_autoneg_adv_reg;
@@ -2284,8 +2278,7 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-static s32
-e1000_phy_force_speed_duplex(struct e1000_hw *hw)
+static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
 {
     u32 ctrl;
     s32 ret_val;
@@ -2302,7 +2295,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
     DEBUGOUT1("hw->fc = %d\n", hw->fc);
 
     /* Read the Device Control Register. */
-    ctrl = E1000_READ_REG(hw, CTRL);
+    ctrl = er32(CTRL);
 
     /* Set the bits to Force Speed and Duplex in the Device Ctrl Reg. */
     ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
@@ -2357,7 +2350,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
     e1000_config_collision_dist(hw);
 
     /* Write the configured values back to the Device Control Reg. */
-    E1000_WRITE_REG(hw, CTRL, ctrl);
+    ew32(CTRL, ctrl);
 
     if ((hw->phy_type == e1000_phy_m88) ||
         (hw->phy_type == e1000_phy_gg82563)) {
@@ -2535,8 +2528,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw)
 * Link should have been established previously. Reads the speed and duplex
 * information from the Device Status register.
 ******************************************************************************/
-void
-e1000_config_collision_dist(struct e1000_hw *hw)
+void e1000_config_collision_dist(struct e1000_hw *hw)
 {
     u32 tctl, coll_dist;
 
@@ -2547,13 +2539,13 @@ e1000_config_collision_dist(struct e1000_hw *hw)
     else
         coll_dist = E1000_COLLISION_DISTANCE;
 
-    tctl = E1000_READ_REG(hw, TCTL);
+    tctl = er32(TCTL);
 
     tctl &= ~E1000_TCTL_COLD;
     tctl |= coll_dist << E1000_COLD_SHIFT;
 
-    E1000_WRITE_REG(hw, TCTL, tctl);
-    E1000_WRITE_FLUSH(hw);
+    ew32(TCTL, tctl);
+    E1000_WRITE_FLUSH();
 }
 
 /******************************************************************************
@@ -2565,8 +2557,7 @@ e1000_config_collision_dist(struct e1000_hw *hw)
 * The contents of the PHY register containing the needed information need to
 * be passed in.
 ******************************************************************************/
-static s32
-e1000_config_mac_to_phy(struct e1000_hw *hw)
+static s32 e1000_config_mac_to_phy(struct e1000_hw *hw)
 {
     u32 ctrl;
     s32 ret_val;
@@ -2582,7 +2573,7 @@ e1000_config_mac_to_phy(struct e1000_hw *hw)
     /* Read the Device Control Register and set the bits to Force Speed
      * and Duplex.
      */
-    ctrl = E1000_READ_REG(hw, CTRL);
+    ctrl = er32(CTRL);
     ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
     ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
 
@@ -2609,7 +2600,7 @@ e1000_config_mac_to_phy(struct e1000_hw *hw)
         ctrl |= E1000_CTRL_SPD_100;
 
     /* Write the configured values back to the Device Control Reg. */
-    E1000_WRITE_REG(hw, CTRL, ctrl);
+    ew32(CTRL, ctrl);
     return E1000_SUCCESS;
 }
 
@@ -2624,15 +2615,14 @@ e1000_config_mac_to_phy(struct e1000_hw *hw)
  * by the PHY rather than the MAC. Software must also configure these
  * bits when link is forced on a fiber connection.
  *****************************************************************************/
-s32
-e1000_force_mac_fc(struct e1000_hw *hw)
+s32 e1000_force_mac_fc(struct e1000_hw *hw)
 {
     u32 ctrl;
 
     DEBUGFUNC("e1000_force_mac_fc");
 
     /* Get the current configuration of the Device Control Register */
-    ctrl = E1000_READ_REG(hw, CTRL);
+    ctrl = er32(CTRL);
 
     /* Because we didn't get link via the internal auto-negotiation
      * mechanism (we either forced link or we got link via PHY
@@ -2676,7 +2666,7 @@ e1000_force_mac_fc(struct e1000_hw *hw)
     if (hw->mac_type == e1000_82542_rev2_0)
         ctrl &= (~E1000_CTRL_TFCE);
 
-    E1000_WRITE_REG(hw, CTRL, ctrl);
+    ew32(CTRL, ctrl);
     return E1000_SUCCESS;
 }
 
@@ -2691,8 +2681,7 @@ e1000_force_mac_fc(struct e1000_hw *hw)
  * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
  * and RFCE bits will be automaticaly set to the negotiated flow control mode.
  *****************************************************************************/
-static s32
-e1000_config_fc_after_link_up(struct e1000_hw *hw)
+static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw)
 {
     s32 ret_val;
     u16 mii_status_reg;
@@ -2896,8 +2885,7 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
  *
  * Called by any function that needs to check the link status of the adapter.
  *****************************************************************************/
-s32
-e1000_check_for_link(struct e1000_hw *hw)
+s32 e1000_check_for_link(struct e1000_hw *hw)
 {
     u32 rxcw = 0;
     u32 ctrl;
@@ -2910,8 +2898,8 @@ e1000_check_for_link(struct e1000_hw *hw)
 
     DEBUGFUNC("e1000_check_for_link");
 
-    ctrl = E1000_READ_REG(hw, CTRL);
-    status = E1000_READ_REG(hw, STATUS);
+    ctrl = er32(CTRL);
+    status = er32(STATUS);
 
     /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
      * set when the optics detect a signal. On older adapters, it will be
@@ -2919,7 +2907,7 @@ e1000_check_for_link(struct e1000_hw *hw)
      */
     if ((hw->media_type == e1000_media_type_fiber) ||
         (hw->media_type == e1000_media_type_internal_serdes)) {
-        rxcw = E1000_READ_REG(hw, RXCW);
+        rxcw = er32(RXCW);
 
         if (hw->media_type == e1000_media_type_fiber) {
             signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
@@ -2965,11 +2953,11 @@ e1000_check_for_link(struct e1000_hw *hw)
                 (!hw->autoneg) &&
                 (hw->forced_speed_duplex == e1000_10_full ||
                  hw->forced_speed_duplex == e1000_10_half)) {
-                E1000_WRITE_REG(hw, IMC, 0xffffffff);
+                ew32(IMC, 0xffffffff);
                 ret_val = e1000_polarity_reversal_workaround(hw);
-                icr = E1000_READ_REG(hw, ICR);
-                E1000_WRITE_REG(hw, ICS, (icr & ~E1000_ICS_LSC));
-                E1000_WRITE_REG(hw, IMS, IMS_ENABLE_MASK);
+                icr = er32(ICR);
+                ew32(ICS, (icr & ~E1000_ICS_LSC));
+                ew32(IMS, IMS_ENABLE_MASK);
             }
 
         } else {
@@ -3034,9 +3022,9 @@ e1000_check_for_link(struct e1000_hw *hw)
                  */
                 if (hw->tbi_compatibility_on) {
                     /* If we previously were in the mode, turn it off. */
-                    rctl = E1000_READ_REG(hw, RCTL);
+                    rctl = er32(RCTL);
                     rctl &= ~E1000_RCTL_SBP;
-                    E1000_WRITE_REG(hw, RCTL, rctl);
+                    ew32(RCTL, rctl);
                     hw->tbi_compatibility_on = false;
                 }
             } else {
@@ -3047,9 +3035,9 @@ e1000_check_for_link(struct e1000_hw *hw)
                  */
                 if (!hw->tbi_compatibility_on) {
                     hw->tbi_compatibility_on = true;
-                    rctl = E1000_READ_REG(hw, RCTL);
+                    rctl = er32(RCTL);
                     rctl |= E1000_RCTL_SBP;
-                    E1000_WRITE_REG(hw, RCTL, rctl);
+                    ew32(RCTL, rctl);
                 }
             }
         }
@@ -3073,12 +3061,12 @@ e1000_check_for_link(struct e1000_hw *hw)
         DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n");
 
         /* Disable auto-negotiation in the TXCW register */
-        E1000_WRITE_REG(hw, TXCW, (hw->txcw & ~E1000_TXCW_ANE));
+        ew32(TXCW, (hw->txcw & ~E1000_TXCW_ANE));
 
         /* Force link-up and also force full-duplex. */
-        ctrl = E1000_READ_REG(hw, CTRL);
+        ctrl = er32(CTRL);
         ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
-        E1000_WRITE_REG(hw, CTRL, ctrl);
+        ew32(CTRL, ctrl);
 
         /* Configure Flow Control after forcing link up. */
         ret_val = e1000_config_fc_after_link_up(hw);
@@ -3096,8 +3084,8 @@ e1000_check_for_link(struct e1000_hw *hw)
               (hw->media_type == e1000_media_type_internal_serdes)) &&
               (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
         DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n");
-        E1000_WRITE_REG(hw, TXCW, hw->txcw);
-        E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
+        ew32(TXCW, hw->txcw);
+        ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
 
         hw->serdes_link_down = false;
     }
@@ -3105,10 +3093,10 @@ e1000_check_for_link(struct e1000_hw *hw)
      * based on MAC synchronization for internal serdes media type.
      */
     else if ((hw->media_type == e1000_media_type_internal_serdes) &&
-             !(E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
+             !(E1000_TXCW_ANE & er32(TXCW))) {
         /* SYNCH bit and IV bit are sticky. */
         udelay(10);
-        if (E1000_RXCW_SYNCH & E1000_READ_REG(hw, RXCW)) {
+        if (E1000_RXCW_SYNCH & er32(RXCW)) {
             if (!(rxcw & E1000_RXCW_IV)) {
                 hw->serdes_link_down = false;
                 DEBUGOUT("SERDES: Link is up.\n");
@@ -3119,8 +3107,8 @@ e1000_check_for_link(struct e1000_hw *hw)
         }
     }
     if ((hw->media_type == e1000_media_type_internal_serdes) &&
-        (E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
-        hw->serdes_link_down = !(E1000_STATUS_LU & E1000_READ_REG(hw, STATUS));
+        (E1000_TXCW_ANE & er32(TXCW))) {
+        hw->serdes_link_down = !(E1000_STATUS_LU & er32(STATUS));
     }
     return E1000_SUCCESS;
 }
@@ -3132,10 +3120,7 @@ e1000_check_for_link(struct e1000_hw *hw)
  * speed - Speed of the connection
  * duplex - Duplex setting of the connection
  *****************************************************************************/
-s32
-e1000_get_speed_and_duplex(struct e1000_hw *hw,
-                           u16 *speed,
-                           u16 *duplex)
+s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)
 {
     u32 status;
     s32 ret_val;
@@ -3144,7 +3129,7 @@ e1000_get_speed_and_duplex(struct e1000_hw *hw,
     DEBUGFUNC("e1000_get_speed_and_duplex");
 
     if (hw->mac_type >= e1000_82543) {
-        status = E1000_READ_REG(hw, STATUS);
+        status = er32(STATUS);
         if (status & E1000_STATUS_SPEED_1000) {
             *speed = SPEED_1000;
             DEBUGOUT("1000 Mbs, ");
@@ -3214,8 +3199,7 @@ e1000_get_speed_and_duplex(struct e1000_hw *hw,
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-static s32
-e1000_wait_autoneg(struct e1000_hw *hw)
+static s32 e1000_wait_autoneg(struct e1000_hw *hw)
 {
     s32 ret_val;
     u16 i;
@@ -3249,15 +3233,13 @@ e1000_wait_autoneg(struct e1000_hw *hw)
 * hw - Struct containing variables accessed by shared code
 * ctrl - Device control register's current value
 ******************************************************************************/
-static void
-e1000_raise_mdi_clk(struct e1000_hw *hw,
-                    u32 *ctrl)
+static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
 {
     /* Raise the clock input to the Management Data Clock (by setting the MDC
      * bit), and then delay 10 microseconds.
      */
-    E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
-    E1000_WRITE_FLUSH(hw);
+    ew32(CTRL, (*ctrl | E1000_CTRL_MDC));
+    E1000_WRITE_FLUSH();
     udelay(10);
 }
 
@@ -3267,15 +3249,13 @@ e1000_raise_mdi_clk(struct e1000_hw *hw,
 * hw - Struct containing variables accessed by shared code
 * ctrl - Device control register's current value
 ******************************************************************************/
-static void
-e1000_lower_mdi_clk(struct e1000_hw *hw,
-                    u32 *ctrl)
+static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
 {
     /* Lower the clock input to the Management Data Clock (by clearing the MDC
      * bit), and then delay 10 microseconds.
      */
-    E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
-    E1000_WRITE_FLUSH(hw);
+    ew32(CTRL, (*ctrl & ~E1000_CTRL_MDC));
+    E1000_WRITE_FLUSH();
     udelay(10);
 }
 
@@ -3288,10 +3268,7 @@ e1000_lower_mdi_clk(struct e1000_hw *hw,
 *
 * Bits are shifted out in MSB to LSB order.
 ******************************************************************************/
-static void
-e1000_shift_out_mdi_bits(struct e1000_hw *hw,
-                         u32 data,
-                         u16 count)
+static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, u32 data, u16 count)
 {
     u32 ctrl;
     u32 mask;
@@ -3303,7 +3280,7 @@ e1000_shift_out_mdi_bits(struct e1000_hw *hw,
     mask = 0x01;
     mask <<= (count - 1);
 
-    ctrl = E1000_READ_REG(hw, CTRL);
+    ctrl = er32(CTRL);
 
     /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
     ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
@@ -3319,8 +3296,8 @@ e1000_shift_out_mdi_bits(struct e1000_hw *hw,
         else
             ctrl &= ~E1000_CTRL_MDIO;
 
-        E1000_WRITE_REG(hw, CTRL, ctrl);
-        E1000_WRITE_FLUSH(hw);
+        ew32(CTRL, ctrl);
+        E1000_WRITE_FLUSH();
 
         udelay(10);
 
@@ -3338,8 +3315,7 @@ e1000_shift_out_mdi_bits(struct e1000_hw *hw,
 *
 * Bits are shifted in in MSB to LSB order.
 ******************************************************************************/
-static u16
-e1000_shift_in_mdi_bits(struct e1000_hw *hw)
+static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw)
 {
     u32 ctrl;
     u16 data = 0;
@@ -3352,14 +3328,14 @@ e1000_shift_in_mdi_bits(struct e1000_hw *hw)
      * by raising the input to the Management Data Clock (setting the MDC bit),
      * and then reading the value of the MDIO bit.
      */
-    ctrl = E1000_READ_REG(hw, CTRL);
+    ctrl = er32(CTRL);
 
     /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
     ctrl &= ~E1000_CTRL_MDIO_DIR;
     ctrl &= ~E1000_CTRL_MDIO;
 
-    E1000_WRITE_REG(hw, CTRL, ctrl);
-    E1000_WRITE_FLUSH(hw);
+    ew32(CTRL, ctrl);
+    E1000_WRITE_FLUSH();
 
     /* Raise and Lower the clock before reading in the data. This accounts for
      * the turnaround bits. The first clock occurred when we clocked out the
@@ -3371,7 +3347,7 @@ e1000_shift_in_mdi_bits(struct e1000_hw *hw)
     for (data = 0, i = 0; i < 16; i++) {
         data = data << 1;
         e1000_raise_mdi_clk(hw, &ctrl);
-        ctrl = E1000_READ_REG(hw, CTRL);
+        ctrl = er32(CTRL);
         /* Check to see if we shifted in a "1". */
         if (ctrl & E1000_CTRL_MDIO)
             data |= 1;
@@ -3384,8 +3360,7 @@ e1000_shift_in_mdi_bits(struct e1000_hw *hw)
     return data;
 }
 
-static s32
-e1000_swfw_sync_acquire(struct e1000_hw *hw, u16 mask)
+static s32 e1000_swfw_sync_acquire(struct e1000_hw *hw, u16 mask)
 {
     u32 swfw_sync = 0;
     u32 swmask = mask;
@@ -3404,7 +3379,7 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, u16 mask)
             if (e1000_get_hw_eeprom_semaphore(hw))
                 return -E1000_ERR_SWFW_SYNC;
 
-            swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
+            swfw_sync = er32(SW_FW_SYNC);
             if (!(swfw_sync & (fwmask | swmask))) {
                 break;
             }
@@ -3422,14 +3397,13 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, u16 mask)
     }
 
     swfw_sync |= swmask;
-    E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync);
+    ew32(SW_FW_SYNC, swfw_sync);
 
     e1000_put_hw_eeprom_semaphore(hw);
     return E1000_SUCCESS;
 }
 
-static void
-e1000_swfw_sync_release(struct e1000_hw *hw, u16 mask)
+static void e1000_swfw_sync_release(struct e1000_hw *hw, u16 mask)
 {
     u32 swfw_sync;
     u32 swmask = mask;
@@ -3451,9 +3425,9 @@ e1000_swfw_sync_release(struct e1000_hw *hw, u16 mask)
     while (e1000_get_hw_eeprom_semaphore(hw) != E1000_SUCCESS);
         /* empty */
 
-    swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
+    swfw_sync = er32(SW_FW_SYNC);
     swfw_sync &= ~swmask;
-    E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync);
+    ew32(SW_FW_SYNC, swfw_sync);
 
     e1000_put_hw_eeprom_semaphore(hw);
 }
@@ -3464,10 +3438,7 @@ e1000_swfw_sync_release(struct e1000_hw *hw, u16 mask)
 * hw - Struct containing variables accessed by shared code
 * reg_addr - address of the PHY register to read
 ******************************************************************************/
-s32
-e1000_read_phy_reg(struct e1000_hw *hw,
-                   u32 reg_addr,
-                   u16 *phy_data)
+s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 *phy_data)
 {
     u32 ret_val;
     u16 swfw;
@@ -3475,7 +3446,7 @@ e1000_read_phy_reg(struct e1000_hw *hw,
     DEBUGFUNC("e1000_read_phy_reg");
 
     if ((hw->mac_type == e1000_80003es2lan) &&
-        (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
+        (er32(STATUS) & E1000_STATUS_FUNC_1)) {
         swfw = E1000_SWFW_PHY1_SM;
     } else {
         swfw = E1000_SWFW_PHY0_SM;
@@ -3523,9 +3494,8 @@ e1000_read_phy_reg(struct e1000_hw *hw,
     return ret_val;
 }
 
-static s32
-e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
-                      u16 *phy_data)
+static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
+                                u16 *phy_data)
 {
     u32 i;
     u32 mdic = 0;
@@ -3547,12 +3517,12 @@ e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
                 (phy_addr << E1000_MDIC_PHY_SHIFT) |
                 (E1000_MDIC_OP_READ));
 
-        E1000_WRITE_REG(hw, MDIC, mdic);
+        ew32(MDIC, mdic);
 
         /* Poll the ready bit to see if the MDI read completed */
         for (i = 0; i < 64; i++) {
             udelay(50);
-            mdic = E1000_READ_REG(hw, MDIC);
+            mdic = er32(MDIC);
             if (mdic & E1000_MDIC_READY) break;
         }
         if (!(mdic & E1000_MDIC_READY)) {
@@ -3563,7 +3533,7 @@ e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
             DEBUGOUT("MDI Error\n");
             return -E1000_ERR_PHY;
         }
-        *phy_data = (u16) mdic;
+        *phy_data = (u16)mdic;
     } else {
         /* We must first send a preamble through the MDIO pin to signal the
          * beginning of an MII instruction.  This is done by sending 32
@@ -3603,9 +3573,7 @@ e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
 * reg_addr - address of the PHY register to write
 * data - data to write to the PHY
 ******************************************************************************/
-s32
-e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr,
-                    u16 phy_data)
+s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 phy_data)
 {
     u32 ret_val;
     u16 swfw;
@@ -3613,7 +3581,7 @@ e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr,
     DEBUGFUNC("e1000_write_phy_reg");
 
     if ((hw->mac_type == e1000_80003es2lan) &&
-        (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
+        (er32(STATUS) & E1000_STATUS_FUNC_1)) {
         swfw = E1000_SWFW_PHY1_SM;
     } else {
         swfw = E1000_SWFW_PHY0_SM;
@@ -3661,9 +3629,8 @@ e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr,
     return ret_val;
 }
 
-static s32
-e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
-                       u16 phy_data)
+static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
+                                 u16 phy_data)
 {
     u32 i;
     u32 mdic = 0;
@@ -3681,17 +3648,17 @@ e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
          * for the PHY register in the MDI Control register.  The MAC will take
          * care of interfacing with the PHY to send the desired data.
          */
-        mdic = (((u32) phy_data) |
+        mdic = (((u32)phy_data) |
                 (reg_addr << E1000_MDIC_REG_SHIFT) |
                 (phy_addr << E1000_MDIC_PHY_SHIFT) |
                 (E1000_MDIC_OP_WRITE));
 
-        E1000_WRITE_REG(hw, MDIC, mdic);
+        ew32(MDIC, mdic);
 
         /* Poll the ready bit to see if the MDI read completed */
         for (i = 0; i < 641; i++) {
             udelay(5);
-            mdic = E1000_READ_REG(hw, MDIC);
+            mdic = er32(MDIC);
             if (mdic & E1000_MDIC_READY) break;
         }
         if (!(mdic & E1000_MDIC_READY)) {
@@ -3715,7 +3682,7 @@ e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
         mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
                 (PHY_OP_WRITE << 12) | (PHY_SOF << 14));
         mdic <<= 16;
-        mdic |= (u32) phy_data;
+        mdic |= (u32)phy_data;
 
         e1000_shift_out_mdi_bits(hw, mdic, 32);
     }
@@ -3723,17 +3690,14 @@ e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
     return E1000_SUCCESS;
 }
 
-static s32
-e1000_read_kmrn_reg(struct e1000_hw *hw,
-                    u32 reg_addr,
-                    u16 *data)
+static s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 reg_addr, u16 *data)
 {
     u32 reg_val;
     u16 swfw;
     DEBUGFUNC("e1000_read_kmrn_reg");
 
     if ((hw->mac_type == e1000_80003es2lan) &&
-        (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
+        (er32(STATUS) & E1000_STATUS_FUNC_1)) {
         swfw = E1000_SWFW_PHY1_SM;
     } else {
         swfw = E1000_SWFW_PHY0_SM;
@@ -3745,28 +3709,25 @@ e1000_read_kmrn_reg(struct e1000_hw *hw,
     reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) &
               E1000_KUMCTRLSTA_OFFSET) |
               E1000_KUMCTRLSTA_REN;
-    E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val);
+    ew32(KUMCTRLSTA, reg_val);
     udelay(2);
 
     /* Read the data returned */
-    reg_val = E1000_READ_REG(hw, KUMCTRLSTA);
+    reg_val = er32(KUMCTRLSTA);
     *data = (u16)reg_val;
 
     e1000_swfw_sync_release(hw, swfw);
     return E1000_SUCCESS;
 }
 
-static s32
-e1000_write_kmrn_reg(struct e1000_hw *hw,
-                     u32 reg_addr,
-                     u16 data)
+static s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 reg_addr, u16 data)
 {
     u32 reg_val;
     u16 swfw;
     DEBUGFUNC("e1000_write_kmrn_reg");
 
     if ((hw->mac_type == e1000_80003es2lan) &&
-        (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
+        (er32(STATUS) & E1000_STATUS_FUNC_1)) {
         swfw = E1000_SWFW_PHY1_SM;
     } else {
         swfw = E1000_SWFW_PHY0_SM;
@@ -3776,7 +3737,7 @@ e1000_write_kmrn_reg(struct e1000_hw *hw,
 
     reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) &
               E1000_KUMCTRLSTA_OFFSET) | data;
-    E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val);
+    ew32(KUMCTRLSTA, reg_val);
     udelay(2);
 
     e1000_swfw_sync_release(hw, swfw);
@@ -3788,8 +3749,7 @@ e1000_write_kmrn_reg(struct e1000_hw *hw,
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-s32
-e1000_phy_hw_reset(struct e1000_hw *hw)
+s32 e1000_phy_hw_reset(struct e1000_hw *hw)
 {
     u32 ctrl, ctrl_ext;
     u32 led_ctrl;
@@ -3808,7 +3768,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
 
     if (hw->mac_type > e1000_82543) {
         if ((hw->mac_type == e1000_80003es2lan) &&
-            (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
+            (er32(STATUS) & E1000_STATUS_FUNC_1)) {
             swfw = E1000_SWFW_PHY1_SM;
         } else {
             swfw = E1000_SWFW_PHY0_SM;
@@ -3823,17 +3783,17 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
          * and deassert.  For e1000_82571 hardware and later, we instead delay
          * for 50us between and 10ms after the deassertion.
          */
-        ctrl = E1000_READ_REG(hw, CTRL);
-        E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
-        E1000_WRITE_FLUSH(hw);
+        ctrl = er32(CTRL);
+        ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
+        E1000_WRITE_FLUSH();
 
         if (hw->mac_type < e1000_82571)
             msleep(10);
         else
             udelay(100);
 
-        E1000_WRITE_REG(hw, CTRL, ctrl);
-        E1000_WRITE_FLUSH(hw);
+        ew32(CTRL, ctrl);
+        E1000_WRITE_FLUSH();
 
         if (hw->mac_type >= e1000_82571)
             mdelay(10);
@@ -3843,24 +3803,24 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
         /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
          * bit to put the PHY into reset. Then, take it out of reset.
          */
-        ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+        ctrl_ext = er32(CTRL_EXT);
         ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
         ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
-        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-        E1000_WRITE_FLUSH(hw);
+        ew32(CTRL_EXT, ctrl_ext);
+        E1000_WRITE_FLUSH();
         msleep(10);
         ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
-        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-        E1000_WRITE_FLUSH(hw);
+        ew32(CTRL_EXT, ctrl_ext);
+        E1000_WRITE_FLUSH();
     }
     udelay(150);
 
     if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
         /* Configure activity LED after PHY reset */
-        led_ctrl = E1000_READ_REG(hw, LEDCTL);
+        led_ctrl = er32(LEDCTL);
         led_ctrl &= IGP_ACTIVITY_LED_MASK;
         led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
-        E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
+        ew32(LEDCTL, led_ctrl);
     }
 
     /* Wait for FW to finish PHY configuration. */
@@ -3882,8 +3842,7 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
 *
 * Sets bit 15 of the MII Control register
 ******************************************************************************/
-s32
-e1000_phy_reset(struct e1000_hw *hw)
+s32 e1000_phy_reset(struct e1000_hw *hw)
 {
     s32 ret_val;
     u16 phy_data;
@@ -3934,8 +3893,7 @@ e1000_phy_reset(struct e1000_hw *hw)
 *
 * hw - struct containing variables accessed by shared code
 ******************************************************************************/
-void
-e1000_phy_powerdown_workaround(struct e1000_hw *hw)
+void e1000_phy_powerdown_workaround(struct e1000_hw *hw)
 {
     s32 reg;
     u16 phy_data;
@@ -3948,8 +3906,8 @@ e1000_phy_powerdown_workaround(struct e1000_hw *hw)
 
     do {
         /* Disable link */
-        reg = E1000_READ_REG(hw, PHY_CTRL);
-        E1000_WRITE_REG(hw, PHY_CTRL, reg | E1000_PHY_CTRL_GBE_DISABLE |
+        reg = er32(PHY_CTRL);
+        ew32(PHY_CTRL, reg | E1000_PHY_CTRL_GBE_DISABLE |
                         E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
 
         /* Write VR power-down enable - bits 9:8 should be 10b */
@@ -3964,8 +3922,8 @@ e1000_phy_powerdown_workaround(struct e1000_hw *hw)
             break;
 
         /* Issue PHY reset and repeat at most one more time */
-        reg = E1000_READ_REG(hw, CTRL);
-        E1000_WRITE_REG(hw, CTRL, reg | E1000_CTRL_PHY_RST);
+        reg = er32(CTRL);
+        ew32(CTRL, reg | E1000_CTRL_PHY_RST);
         retry++;
     } while (retry);
 
@@ -3987,8 +3945,7 @@ e1000_phy_powerdown_workaround(struct e1000_hw *hw)
 *
 * hw - struct containing variables accessed by shared code
 ******************************************************************************/
-static s32
-e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw)
+static s32 e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw)
 {
     s32 ret_val;
     s32 reg;
@@ -4024,8 +3981,8 @@ e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw)
             mdelay(5);
         }
         /* Disable GigE link negotiation */
-        reg = E1000_READ_REG(hw, PHY_CTRL);
-        E1000_WRITE_REG(hw, PHY_CTRL, reg | E1000_PHY_CTRL_GBE_DISABLE |
+        reg = er32(PHY_CTRL);
+        ew32(PHY_CTRL, reg | E1000_PHY_CTRL_GBE_DISABLE |
                         E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
 
         /* unable to acquire PCS lock */
@@ -4040,8 +3997,7 @@ e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-static s32
-e1000_detect_gig_phy(struct e1000_hw *hw)
+static s32 e1000_detect_gig_phy(struct e1000_hw *hw)
 {
     s32 phy_init_status, ret_val;
     u16 phy_id_high, phy_id_low;
@@ -4076,14 +4032,14 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
     if (ret_val)
         return ret_val;
 
-    hw->phy_id = (u32) (phy_id_high << 16);
+    hw->phy_id = (u32)(phy_id_high << 16);
     udelay(20);
     ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low);
     if (ret_val)
         return ret_val;
 
-    hw->phy_id |= (u32) (phy_id_low & PHY_REVISION_MASK);
-    hw->phy_revision = (u32) phy_id_low & ~PHY_REVISION_MASK;
+    hw->phy_id |= (u32)(phy_id_low & PHY_REVISION_MASK);
+    hw->phy_revision = (u32)phy_id_low & ~PHY_REVISION_MASK;
 
     switch (hw->mac_type) {
     case e1000_82543:
@@ -4136,8 +4092,7 @@ e1000_detect_gig_phy(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-static s32
-e1000_phy_reset_dsp(struct e1000_hw *hw)
+static s32 e1000_phy_reset_dsp(struct e1000_hw *hw)
 {
     s32 ret_val;
     DEBUGFUNC("e1000_phy_reset_dsp");
@@ -4163,9 +4118,8 @@ e1000_phy_reset_dsp(struct e1000_hw *hw)
 * hw - Struct containing variables accessed by shared code
 * phy_info - PHY information structure
 ******************************************************************************/
-static s32
-e1000_phy_igp_get_info(struct e1000_hw *hw,
-                       struct e1000_phy_info *phy_info)
+static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
+                                 struct e1000_phy_info *phy_info)
 {
     s32 ret_val;
     u16 phy_data, min_length, max_length, average;
@@ -4240,9 +4194,8 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
 * hw - Struct containing variables accessed by shared code
 * phy_info - PHY information structure
 ******************************************************************************/
-static s32
-e1000_phy_ife_get_info(struct e1000_hw *hw,
-                       struct e1000_phy_info *phy_info)
+static s32 e1000_phy_ife_get_info(struct e1000_hw *hw,
+                                 struct e1000_phy_info *phy_info)
 {
     s32 ret_val;
     u16 phy_data;
@@ -4290,9 +4243,8 @@ e1000_phy_ife_get_info(struct e1000_hw *hw,
 * hw - Struct containing variables accessed by shared code
 * phy_info - PHY information structure
 ******************************************************************************/
-static s32
-e1000_phy_m88_get_info(struct e1000_hw *hw,
-                       struct e1000_phy_info *phy_info)
+static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
+                                 struct e1000_phy_info *phy_info)
 {
     s32 ret_val;
     u16 phy_data;
@@ -4369,9 +4321,7 @@ e1000_phy_m88_get_info(struct e1000_hw *hw,
 * hw - Struct containing variables accessed by shared code
 * phy_info - PHY information structure
 ******************************************************************************/
-s32
-e1000_phy_get_info(struct e1000_hw *hw,
-                   struct e1000_phy_info *phy_info)
+s32 e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
 {
     s32 ret_val;
     u16 phy_data;
@@ -4415,8 +4365,7 @@ e1000_phy_get_info(struct e1000_hw *hw,
         return e1000_phy_m88_get_info(hw, phy_info);
 }
 
-s32
-e1000_validate_mdi_setting(struct e1000_hw *hw)
+s32 e1000_validate_mdi_setting(struct e1000_hw *hw)
 {
     DEBUGFUNC("e1000_validate_mdi_settings");
 
@@ -4436,11 +4385,10 @@ e1000_validate_mdi_setting(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-s32
-e1000_init_eeprom_params(struct e1000_hw *hw)
+s32 e1000_init_eeprom_params(struct e1000_hw *hw)
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
-    u32 eecd = E1000_READ_REG(hw, EECD);
+    u32 eecd = er32(EECD);
     s32 ret_val = E1000_SUCCESS;
     u16 eeprom_size;
 
@@ -4542,7 +4490,7 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
             /* Ensure that the Autonomous FLASH update bit is cleared due to
              * Flash update issue on parts which use a FLASH for NVM. */
             eecd &= ~E1000_EECD_AUPDEN;
-            E1000_WRITE_REG(hw, EECD, eecd);
+            ew32(EECD, eecd);
         }
         break;
     case e1000_80003es2lan:
@@ -4626,16 +4574,14 @@ e1000_init_eeprom_params(struct e1000_hw *hw)
  * hw - Struct containing variables accessed by shared code
  * eecd - EECD's current value
  *****************************************************************************/
-static void
-e1000_raise_ee_clk(struct e1000_hw *hw,
-                   u32 *eecd)
+static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd)
 {
     /* Raise the clock input to the EEPROM (by setting the SK bit), and then
      * wait <delay> microseconds.
      */
     *eecd = *eecd | E1000_EECD_SK;
-    E1000_WRITE_REG(hw, EECD, *eecd);
-    E1000_WRITE_FLUSH(hw);
+    ew32(EECD, *eecd);
+    E1000_WRITE_FLUSH();
     udelay(hw->eeprom.delay_usec);
 }
 
@@ -4645,16 +4591,14 @@ e1000_raise_ee_clk(struct e1000_hw *hw,
  * hw - Struct containing variables accessed by shared code
  * eecd - EECD's current value
  *****************************************************************************/
-static void
-e1000_lower_ee_clk(struct e1000_hw *hw,
-                   u32 *eecd)
+static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd)
 {
     /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
      * wait 50 microseconds.
      */
     *eecd = *eecd & ~E1000_EECD_SK;
-    E1000_WRITE_REG(hw, EECD, *eecd);
-    E1000_WRITE_FLUSH(hw);
+    ew32(EECD, *eecd);
+    E1000_WRITE_FLUSH();
     udelay(hw->eeprom.delay_usec);
 }
 
@@ -4665,10 +4609,7 @@ e1000_lower_ee_clk(struct e1000_hw *hw,
  * data - data to send to the EEPROM
  * count - number of bits to shift out
  *****************************************************************************/
-static void
-e1000_shift_out_ee_bits(struct e1000_hw *hw,
-                        u16 data,
-                        u16 count)
+static void e1000_shift_out_ee_bits(struct e1000_hw *hw, u16 data, u16 count)
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     u32 eecd;
@@ -4679,7 +4620,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
      * In order to do this, "data" must be broken down into bits.
      */
     mask = 0x01 << (count - 1);
-    eecd = E1000_READ_REG(hw, EECD);
+    eecd = er32(EECD);
     if (eeprom->type == e1000_eeprom_microwire) {
         eecd &= ~E1000_EECD_DO;
     } else if (eeprom->type == e1000_eeprom_spi) {
@@ -4696,8 +4637,8 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
         if (data & mask)
             eecd |= E1000_EECD_DI;
 
-        E1000_WRITE_REG(hw, EECD, eecd);
-        E1000_WRITE_FLUSH(hw);
+        ew32(EECD, eecd);
+        E1000_WRITE_FLUSH();
 
         udelay(eeprom->delay_usec);
 
@@ -4710,7 +4651,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
 
     /* We leave the "DI" bit set to "0" when we leave this routine. */
     eecd &= ~E1000_EECD_DI;
-    E1000_WRITE_REG(hw, EECD, eecd);
+    ew32(EECD, eecd);
 }
 
 /******************************************************************************
@@ -4718,9 +4659,7 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw,
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static u16
-e1000_shift_in_ee_bits(struct e1000_hw *hw,
-                       u16 count)
+static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count)
 {
     u32 eecd;
     u32 i;
@@ -4733,7 +4672,7 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw,
      * always be clear.
      */
 
-    eecd = E1000_READ_REG(hw, EECD);
+    eecd = er32(EECD);
 
     eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
     data = 0;
@@ -4742,7 +4681,7 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw,
         data = data << 1;
         e1000_raise_ee_clk(hw, &eecd);
 
-        eecd = E1000_READ_REG(hw, EECD);
+        eecd = er32(EECD);
 
         eecd &= ~(E1000_EECD_DI);
         if (eecd & E1000_EECD_DO)
@@ -4762,8 +4701,7 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw,
  * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
  * function should be called before issuing a command to the EEPROM.
  *****************************************************************************/
-static s32
-e1000_acquire_eeprom(struct e1000_hw *hw)
+static s32 e1000_acquire_eeprom(struct e1000_hw *hw)
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     u32 eecd, i=0;
@@ -4772,23 +4710,23 @@ e1000_acquire_eeprom(struct e1000_hw *hw)
 
     if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM))
         return -E1000_ERR_SWFW_SYNC;
-    eecd = E1000_READ_REG(hw, EECD);
+    eecd = er32(EECD);
 
     if (hw->mac_type != e1000_82573) {
         /* Request EEPROM Access */
         if (hw->mac_type > e1000_82544) {
             eecd |= E1000_EECD_REQ;
-            E1000_WRITE_REG(hw, EECD, eecd);
-            eecd = E1000_READ_REG(hw, EECD);
+            ew32(EECD, eecd);
+            eecd = er32(EECD);
             while ((!(eecd & E1000_EECD_GNT)) &&
                   (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
                 i++;
                 udelay(5);
-                eecd = E1000_READ_REG(hw, EECD);
+                eecd = er32(EECD);
             }
             if (!(eecd & E1000_EECD_GNT)) {
                 eecd &= ~E1000_EECD_REQ;
-                E1000_WRITE_REG(hw, EECD, eecd);
+                ew32(EECD, eecd);
                 DEBUGOUT("Could not acquire EEPROM grant\n");
                 e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
                 return -E1000_ERR_EEPROM;
@@ -4801,15 +4739,15 @@ e1000_acquire_eeprom(struct e1000_hw *hw)
     if (eeprom->type == e1000_eeprom_microwire) {
         /* Clear SK and DI */
         eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
-        E1000_WRITE_REG(hw, EECD, eecd);
+        ew32(EECD, eecd);
 
         /* Set CS */
         eecd |= E1000_EECD_CS;
-        E1000_WRITE_REG(hw, EECD, eecd);
+        ew32(EECD, eecd);
     } else if (eeprom->type == e1000_eeprom_spi) {
         /* Clear SK and CS */
         eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
-        E1000_WRITE_REG(hw, EECD, eecd);
+        ew32(EECD, eecd);
         udelay(1);
     }
 
@@ -4821,46 +4759,45 @@ e1000_acquire_eeprom(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void
-e1000_standby_eeprom(struct e1000_hw *hw)
+static void e1000_standby_eeprom(struct e1000_hw *hw)
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     u32 eecd;
 
-    eecd = E1000_READ_REG(hw, EECD);
+    eecd = er32(EECD);
 
     if (eeprom->type == e1000_eeprom_microwire) {
         eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
-        E1000_WRITE_REG(hw, EECD, eecd);
-        E1000_WRITE_FLUSH(hw);
+        ew32(EECD, eecd);
+        E1000_WRITE_FLUSH();
         udelay(eeprom->delay_usec);
 
         /* Clock high */
         eecd |= E1000_EECD_SK;
-        E1000_WRITE_REG(hw, EECD, eecd);
-        E1000_WRITE_FLUSH(hw);
+        ew32(EECD, eecd);
+        E1000_WRITE_FLUSH();
         udelay(eeprom->delay_usec);
 
         /* Select EEPROM */
         eecd |= E1000_EECD_CS;
-        E1000_WRITE_REG(hw, EECD, eecd);
-        E1000_WRITE_FLUSH(hw);
+        ew32(EECD, eecd);
+        E1000_WRITE_FLUSH();
         udelay(eeprom->delay_usec);
 
         /* Clock low */
         eecd &= ~E1000_EECD_SK;
-        E1000_WRITE_REG(hw, EECD, eecd);
-        E1000_WRITE_FLUSH(hw);
+        ew32(EECD, eecd);
+        E1000_WRITE_FLUSH();
         udelay(eeprom->delay_usec);
     } else if (eeprom->type == e1000_eeprom_spi) {
         /* Toggle CS to flush commands */
         eecd |= E1000_EECD_CS;
-        E1000_WRITE_REG(hw, EECD, eecd);
-        E1000_WRITE_FLUSH(hw);
+        ew32(EECD, eecd);
+        E1000_WRITE_FLUSH();
         udelay(eeprom->delay_usec);
         eecd &= ~E1000_EECD_CS;
-        E1000_WRITE_REG(hw, EECD, eecd);
-        E1000_WRITE_FLUSH(hw);
+        ew32(EECD, eecd);
+        E1000_WRITE_FLUSH();
         udelay(eeprom->delay_usec);
     }
 }
@@ -4870,20 +4807,19 @@ e1000_standby_eeprom(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void
-e1000_release_eeprom(struct e1000_hw *hw)
+static void e1000_release_eeprom(struct e1000_hw *hw)
 {
     u32 eecd;
 
     DEBUGFUNC("e1000_release_eeprom");
 
-    eecd = E1000_READ_REG(hw, EECD);
+    eecd = er32(EECD);
 
     if (hw->eeprom.type == e1000_eeprom_spi) {
         eecd |= E1000_EECD_CS;  /* Pull CS high */
         eecd &= ~E1000_EECD_SK; /* Lower SCK */
 
-        E1000_WRITE_REG(hw, EECD, eecd);
+        ew32(EECD, eecd);
 
         udelay(hw->eeprom.delay_usec);
     } else if (hw->eeprom.type == e1000_eeprom_microwire) {
@@ -4892,25 +4828,25 @@ e1000_release_eeprom(struct e1000_hw *hw)
         /* CS on Microwire is active-high */
         eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
 
-        E1000_WRITE_REG(hw, EECD, eecd);
+        ew32(EECD, eecd);
 
         /* Rising edge of clock */
         eecd |= E1000_EECD_SK;
-        E1000_WRITE_REG(hw, EECD, eecd);
-        E1000_WRITE_FLUSH(hw);
+        ew32(EECD, eecd);
+        E1000_WRITE_FLUSH();
         udelay(hw->eeprom.delay_usec);
 
         /* Falling edge of clock */
         eecd &= ~E1000_EECD_SK;
-        E1000_WRITE_REG(hw, EECD, eecd);
-        E1000_WRITE_FLUSH(hw);
+        ew32(EECD, eecd);
+        E1000_WRITE_FLUSH();
         udelay(hw->eeprom.delay_usec);
     }
 
     /* Stop requesting EEPROM access */
     if (hw->mac_type > e1000_82544) {
         eecd &= ~E1000_EECD_REQ;
-        E1000_WRITE_REG(hw, EECD, eecd);
+        ew32(EECD, eecd);
     }
 
     e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
@@ -4921,8 +4857,7 @@ e1000_release_eeprom(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static s32
-e1000_spi_eeprom_ready(struct e1000_hw *hw)
+static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw)
 {
     u16 retry_count = 0;
     u8 spi_stat_reg;
@@ -4967,11 +4902,7 @@ e1000_spi_eeprom_ready(struct e1000_hw *hw)
  * data - word read from the EEPROM
  * words - number of words to read
  *****************************************************************************/
-s32
-e1000_read_eeprom(struct e1000_hw *hw,
-                  u16 offset,
-                  u16 words,
-                  u16 *data)
+s32 e1000_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     u32 i = 0;
@@ -5068,11 +4999,8 @@ e1000_read_eeprom(struct e1000_hw *hw,
  * data - word read from the EEPROM
  * words - number of words to read
  *****************************************************************************/
-static s32
-e1000_read_eeprom_eerd(struct e1000_hw *hw,
-                  u16 offset,
-                  u16 words,
-                  u16 *data)
+static s32 e1000_read_eeprom_eerd(struct e1000_hw *hw, u16 offset, u16 words,
+                                 u16 *data)
 {
     u32 i, eerd = 0;
     s32 error = 0;
@@ -5081,13 +5009,13 @@ e1000_read_eeprom_eerd(struct e1000_hw *hw,
         eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) +
                          E1000_EEPROM_RW_REG_START;
 
-        E1000_WRITE_REG(hw, EERD, eerd);
+        ew32(EERD, eerd);
         error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ);
 
         if (error) {
             break;
         }
-        data[i] = (E1000_READ_REG(hw, EERD) >> E1000_EEPROM_RW_REG_DATA);
+        data[i] = (er32(EERD) >> E1000_EEPROM_RW_REG_DATA);
 
     }
 
@@ -5102,11 +5030,8 @@ e1000_read_eeprom_eerd(struct e1000_hw *hw,
  * data - word read from the EEPROM
  * words - number of words to read
  *****************************************************************************/
-static s32
-e1000_write_eeprom_eewr(struct e1000_hw *hw,
-                   u16 offset,
-                   u16 words,
-                   u16 *data)
+static s32 e1000_write_eeprom_eewr(struct e1000_hw *hw, u16 offset, u16 words,
+                                  u16 *data)
 {
     u32    register_value = 0;
     u32    i              = 0;
@@ -5125,7 +5050,7 @@ e1000_write_eeprom_eewr(struct e1000_hw *hw,
             break;
         }
 
-        E1000_WRITE_REG(hw, EEWR, register_value);
+        ew32(EEWR, register_value);
 
         error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
 
@@ -5143,8 +5068,7 @@ e1000_write_eeprom_eewr(struct e1000_hw *hw,
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static s32
-e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
+static s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
 {
     u32 attempts = 100000;
     u32 i, reg = 0;
@@ -5152,9 +5076,9 @@ e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
 
     for (i = 0; i < attempts; i++) {
         if (eerd == E1000_EEPROM_POLL_READ)
-            reg = E1000_READ_REG(hw, EERD);
+            reg = er32(EERD);
         else
-            reg = E1000_READ_REG(hw, EEWR);
+            reg = er32(EEWR);
 
         if (reg & E1000_EEPROM_RW_REG_DONE) {
             done = E1000_SUCCESS;
@@ -5171,8 +5095,7 @@ e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
 *
 * hw - Struct containing variables accessed by shared code
 ****************************************************************************/
-static bool
-e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
+static bool e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
 {
     u32 eecd = 0;
 
@@ -5182,7 +5105,7 @@ e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
         return false;
 
     if (hw->mac_type == e1000_82573) {
-        eecd = E1000_READ_REG(hw, EECD);
+        eecd = er32(EECD);
 
         /* Isolate bits 15 & 16 */
         eecd = ((eecd >> 15) & 0x03);
@@ -5204,8 +5127,7 @@ e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
  * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
  * valid.
  *****************************************************************************/
-s32
-e1000_validate_eeprom_checksum(struct e1000_hw *hw)
+s32 e1000_validate_eeprom_checksum(struct e1000_hw *hw)
 {
     u16 checksum = 0;
     u16 i, eeprom_data;
@@ -5252,7 +5174,7 @@ e1000_validate_eeprom_checksum(struct e1000_hw *hw)
         checksum += eeprom_data;
     }
 
-    if (checksum == (u16) EEPROM_SUM)
+    if (checksum == (u16)EEPROM_SUM)
         return E1000_SUCCESS;
     else {
         DEBUGOUT("EEPROM Checksum Invalid\n");
@@ -5268,8 +5190,7 @@ e1000_validate_eeprom_checksum(struct e1000_hw *hw)
  * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
  * Writes the difference to word offset 63 of the EEPROM.
  *****************************************************************************/
-s32
-e1000_update_eeprom_checksum(struct e1000_hw *hw)
+s32 e1000_update_eeprom_checksum(struct e1000_hw *hw)
 {
     u32 ctrl_ext;
     u16 checksum = 0;
@@ -5284,7 +5205,7 @@ e1000_update_eeprom_checksum(struct e1000_hw *hw)
         }
         checksum += eeprom_data;
     }
-    checksum = (u16) EEPROM_SUM - checksum;
+    checksum = (u16)EEPROM_SUM - checksum;
     if (e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
         DEBUGOUT("EEPROM Write Error\n");
         return -E1000_ERR_EEPROM;
@@ -5294,9 +5215,9 @@ e1000_update_eeprom_checksum(struct e1000_hw *hw)
         e1000_commit_shadow_ram(hw);
         /* Reload the EEPROM, or else modifications will not appear
          * until after next adapter reset. */
-        ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+        ctrl_ext = er32(CTRL_EXT);
         ctrl_ext |= E1000_CTRL_EXT_EE_RST;
-        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+        ew32(CTRL_EXT, ctrl_ext);
         msleep(10);
     }
     return E1000_SUCCESS;
@@ -5313,11 +5234,7 @@ e1000_update_eeprom_checksum(struct e1000_hw *hw)
  * If e1000_update_eeprom_checksum is not called after this function, the
  * EEPROM will most likely contain an invalid checksum.
  *****************************************************************************/
-s32
-e1000_write_eeprom(struct e1000_hw *hw,
-                   u16 offset,
-                   u16 words,
-                   u16 *data)
+s32 e1000_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     s32 status = 0;
@@ -5370,11 +5287,8 @@ e1000_write_eeprom(struct e1000_hw *hw,
  * data - pointer to array of 8 bit words to be written to the EEPROM
  *
  *****************************************************************************/
-static s32
-e1000_write_eeprom_spi(struct e1000_hw *hw,
-                       u16 offset,
-                       u16 words,
-                       u16 *data)
+static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset, u16 words,
+                                 u16 *data)
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     u16 widx = 0;
@@ -5436,11 +5350,8 @@ e1000_write_eeprom_spi(struct e1000_hw *hw,
  * data - pointer to array of 16 bit words to be written to the EEPROM
  *
  *****************************************************************************/
-static s32
-e1000_write_eeprom_microwire(struct e1000_hw *hw,
-                             u16 offset,
-                             u16 words,
-                             u16 *data)
+static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
+                                       u16 words, u16 *data)
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     u32 eecd;
@@ -5484,7 +5395,7 @@ e1000_write_eeprom_microwire(struct e1000_hw *hw,
          * If DO does not go high in 10 milliseconds, then error out.
          */
         for (i = 0; i < 200; i++) {
-            eecd = E1000_READ_REG(hw, EECD);
+            eecd = er32(EECD);
             if (eecd & E1000_EECD_DO) break;
             udelay(50);
         }
@@ -5523,8 +5434,7 @@ e1000_write_eeprom_microwire(struct e1000_hw *hw,
  * data - word read from the EEPROM
  * words - number of words to read
  *****************************************************************************/
-static s32
-e1000_commit_shadow_ram(struct e1000_hw *hw)
+static s32 e1000_commit_shadow_ram(struct e1000_hw *hw)
 {
     u32 attempts = 100000;
     u32 eecd = 0;
@@ -5539,9 +5449,9 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
 
     if (hw->mac_type == e1000_82573) {
         /* The flop register will be used to determine if flash type is STM */
-        flop = E1000_READ_REG(hw, FLOP);
+        flop = er32(FLOP);
         for (i=0; i < attempts; i++) {
-            eecd = E1000_READ_REG(hw, EECD);
+            eecd = er32(EECD);
             if ((eecd & E1000_EECD_FLUPD) == 0) {
                 break;
             }
@@ -5554,14 +5464,14 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
 
         /* If STM opcode located in bits 15:8 of flop, reset firmware */
         if ((flop & 0xFF00) == E1000_STM_OPCODE) {
-            E1000_WRITE_REG(hw, HICR, E1000_HICR_FW_RESET);
+            ew32(HICR, E1000_HICR_FW_RESET);
         }
 
         /* Perform the flash update */
-        E1000_WRITE_REG(hw, EECD, eecd | E1000_EECD_FLUPD);
+        ew32(EECD, eecd | E1000_EECD_FLUPD);
 
         for (i=0; i < attempts; i++) {
-            eecd = E1000_READ_REG(hw, EECD);
+            eecd = er32(EECD);
             if ((eecd & E1000_EECD_FLUPD) == 0) {
                 break;
             }
@@ -5577,7 +5487,7 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
         /* We're writing to the opposite bank so if we're on bank 1,
          * write to bank 0 etc.  We also need to erase the segment that
          * is going to be written */
-        if (!(E1000_READ_REG(hw, EECD) & E1000_EECD_SEC1VAL)) {
+        if (!(er32(EECD) & E1000_EECD_SEC1VAL)) {
             new_bank_offset = hw->flash_bank_size * 2;
             old_bank_offset = 0;
             e1000_erase_ich8_4k_segment(hw, 1);
@@ -5687,8 +5597,7 @@ e1000_commit_shadow_ram(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-s32
-e1000_read_mac_addr(struct e1000_hw * hw)
+s32 e1000_read_mac_addr(struct e1000_hw *hw)
 {
     u16 offset;
     u16 eeprom_data, i;
@@ -5701,8 +5610,8 @@ e1000_read_mac_addr(struct e1000_hw * hw)
             DEBUGOUT("EEPROM Read Error\n");
             return -E1000_ERR_EEPROM;
         }
-        hw->perm_mac_addr[i] = (u8) (eeprom_data & 0x00FF);
-        hw->perm_mac_addr[i+1] = (u8) (eeprom_data >> 8);
+        hw->perm_mac_addr[i] = (u8)(eeprom_data & 0x00FF);
+        hw->perm_mac_addr[i+1] = (u8)(eeprom_data >> 8);
     }
 
     switch (hw->mac_type) {
@@ -5712,7 +5621,7 @@ e1000_read_mac_addr(struct e1000_hw * hw)
     case e1000_82546_rev_3:
     case e1000_82571:
     case e1000_80003es2lan:
-        if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
+        if (er32(STATUS) & E1000_STATUS_FUNC_1)
             hw->perm_mac_addr[5] ^= 0x01;
         break;
     }
@@ -5731,8 +5640,7 @@ e1000_read_mac_addr(struct e1000_hw * hw)
  * of the receive addresss registers. Clears the multicast table. Assumes
  * the receiver is in reset when the routine is called.
  *****************************************************************************/
-static void
-e1000_init_rx_addrs(struct e1000_hw *hw)
+static void e1000_init_rx_addrs(struct e1000_hw *hw)
 {
     u32 i;
     u32 rar_num;
@@ -5758,9 +5666,9 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
     DEBUGOUT("Clearing RAR[1-15]\n");
     for (i = 1; i < rar_num; i++) {
         E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
-        E1000_WRITE_FLUSH(hw);
+        E1000_WRITE_FLUSH();
         E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
-        E1000_WRITE_FLUSH(hw);
+        E1000_WRITE_FLUSH();
     }
 }
 
@@ -5770,9 +5678,7 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
  * hw - Struct containing variables accessed by shared code
  * mc_addr - the multicast address to hash
  *****************************************************************************/
-u32
-e1000_hash_mc_addr(struct e1000_hw *hw,
-                   u8 *mc_addr)
+u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
 {
     u32 hash_value = 0;
 
@@ -5787,37 +5693,37 @@ e1000_hash_mc_addr(struct e1000_hw *hw,
     case 0:
         if (hw->mac_type == e1000_ich8lan) {
             /* [47:38] i.e. 0x158 for above example address */
-            hash_value = ((mc_addr[4] >> 6) | (((u16) mc_addr[5]) << 2));
+            hash_value = ((mc_addr[4] >> 6) | (((u16)mc_addr[5]) << 2));
         } else {
             /* [47:36] i.e. 0x563 for above example address */
-            hash_value = ((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4));
+            hash_value = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
         }
         break;
     case 1:
         if (hw->mac_type == e1000_ich8lan) {
             /* [46:37] i.e. 0x2B1 for above example address */
-            hash_value = ((mc_addr[4] >> 5) | (((u16) mc_addr[5]) << 3));
+            hash_value = ((mc_addr[4] >> 5) | (((u16)mc_addr[5]) << 3));
         } else {
             /* [46:35] i.e. 0xAC6 for above example address */
-            hash_value = ((mc_addr[4] >> 3) | (((u16) mc_addr[5]) << 5));
+            hash_value = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
         }
         break;
     case 2:
         if (hw->mac_type == e1000_ich8lan) {
             /*[45:36] i.e. 0x163 for above example address */
-            hash_value = ((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4));
+            hash_value = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
         } else {
             /* [45:34] i.e. 0x5D8 for above example address */
-            hash_value = ((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6));
+            hash_value = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
         }
         break;
     case 3:
         if (hw->mac_type == e1000_ich8lan) {
             /* [43:34] i.e. 0x18D for above example address */
-            hash_value = ((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6));
+            hash_value = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
         } else {
             /* [43:32] i.e. 0x634 for above example address */
-            hash_value = ((mc_addr[4]) | (((u16) mc_addr[5]) << 8));
+            hash_value = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
         }
         break;
     }
@@ -5835,9 +5741,7 @@ e1000_hash_mc_addr(struct e1000_hw *hw,
  * hw - Struct containing variables accessed by shared code
  * hash_value - Multicast address hash value
  *****************************************************************************/
-void
-e1000_mta_set(struct e1000_hw *hw,
-              u32 hash_value)
+void e1000_mta_set(struct e1000_hw *hw, u32 hash_value)
 {
     u32 hash_bit, hash_reg;
     u32 mta;
@@ -5868,12 +5772,12 @@ e1000_mta_set(struct e1000_hw *hw,
     if ((hw->mac_type == e1000_82544) && ((hash_reg & 0x1) == 1)) {
         temp = E1000_READ_REG_ARRAY(hw, MTA, (hash_reg - 1));
         E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
-        E1000_WRITE_FLUSH(hw);
+        E1000_WRITE_FLUSH();
         E1000_WRITE_REG_ARRAY(hw, MTA, (hash_reg - 1), temp);
-        E1000_WRITE_FLUSH(hw);
+        E1000_WRITE_FLUSH();
     } else {
         E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
-        E1000_WRITE_FLUSH(hw);
+        E1000_WRITE_FLUSH();
     }
 }
 
@@ -5884,20 +5788,16 @@ e1000_mta_set(struct e1000_hw *hw,
  * addr - Address to put into receive address register
  * index - Receive address register to write
  *****************************************************************************/
-void
-e1000_rar_set(struct e1000_hw *hw,
-              u8 *addr,
-              u32 index)
+void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
 {
     u32 rar_low, rar_high;
 
     /* HW expects these in little endian so we reverse the byte order
      * from network order (big endian) to little endian
      */
-    rar_low = ((u32) addr[0] |
-               ((u32) addr[1] << 8) |
-               ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
-    rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
+    rar_low = ((u32)addr[0] | ((u32)addr[1] << 8) |
+               ((u32)addr[2] << 16) | ((u32)addr[3] << 24));
+    rar_high = ((u32)addr[4] | ((u32)addr[5] << 8));
 
     /* Disable Rx and flush all Rx frames before enabling RSS to avoid Rx
      * unit hang.
@@ -5930,9 +5830,9 @@ e1000_rar_set(struct e1000_hw *hw,
     }
 
     E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
-    E1000_WRITE_FLUSH(hw);
+    E1000_WRITE_FLUSH();
     E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
-    E1000_WRITE_FLUSH(hw);
+    E1000_WRITE_FLUSH();
 }
 
 /******************************************************************************
@@ -5942,10 +5842,7 @@ e1000_rar_set(struct e1000_hw *hw,
  * offset - Offset in VLAN filer table to write
  * value - Value to write into VLAN filter table
  *****************************************************************************/
-void
-e1000_write_vfta(struct e1000_hw *hw,
-                 u32 offset,
-                 u32 value)
+void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
 {
     u32 temp;
 
@@ -5955,12 +5852,12 @@ e1000_write_vfta(struct e1000_hw *hw,
     if ((hw->mac_type == e1000_82544) && ((offset & 0x1) == 1)) {
         temp = E1000_READ_REG_ARRAY(hw, VFTA, (offset - 1));
         E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
-        E1000_WRITE_FLUSH(hw);
+        E1000_WRITE_FLUSH();
         E1000_WRITE_REG_ARRAY(hw, VFTA, (offset - 1), temp);
-        E1000_WRITE_FLUSH(hw);
+        E1000_WRITE_FLUSH();
     } else {
         E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
-        E1000_WRITE_FLUSH(hw);
+        E1000_WRITE_FLUSH();
     }
 }
 
@@ -5969,8 +5866,7 @@ e1000_write_vfta(struct e1000_hw *hw,
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void
-e1000_clear_vfta(struct e1000_hw *hw)
+static void e1000_clear_vfta(struct e1000_hw *hw)
 {
     u32 offset;
     u32 vfta_value = 0;
@@ -5999,12 +5895,11 @@ e1000_clear_vfta(struct e1000_hw *hw)
          * manageability unit */
         vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
         E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value);
-        E1000_WRITE_FLUSH(hw);
+        E1000_WRITE_FLUSH();
     }
 }
 
-static s32
-e1000_id_led_init(struct e1000_hw * hw)
+static s32 e1000_id_led_init(struct e1000_hw *hw)
 {
     u32 ledctl;
     const u32 ledctl_mask = 0x000000FF;
@@ -6020,7 +5915,7 @@ e1000_id_led_init(struct e1000_hw * hw)
         return E1000_SUCCESS;
     }
 
-    ledctl = E1000_READ_REG(hw, LEDCTL);
+    ledctl = er32(LEDCTL);
     hw->ledctl_default = ledctl;
     hw->ledctl_mode1 = hw->ledctl_default;
     hw->ledctl_mode2 = hw->ledctl_default;
@@ -6086,8 +5981,7 @@ e1000_id_led_init(struct e1000_hw * hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-s32
-e1000_setup_led(struct e1000_hw *hw)
+s32 e1000_setup_led(struct e1000_hw *hw)
 {
     u32 ledctl;
     s32 ret_val = E1000_SUCCESS;
@@ -6118,7 +6012,7 @@ e1000_setup_led(struct e1000_hw *hw)
         /* Fall Through */
     default:
         if (hw->media_type == e1000_media_type_fiber) {
-            ledctl = E1000_READ_REG(hw, LEDCTL);
+            ledctl = er32(LEDCTL);
             /* Save current LEDCTL settings */
             hw->ledctl_default = ledctl;
             /* Turn off LED0 */
@@ -6127,9 +6021,9 @@ e1000_setup_led(struct e1000_hw *hw)
                         E1000_LEDCTL_LED0_MODE_MASK);
             ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
                        E1000_LEDCTL_LED0_MODE_SHIFT);
-            E1000_WRITE_REG(hw, LEDCTL, ledctl);
+            ew32(LEDCTL, ledctl);
         } else if (hw->media_type == e1000_media_type_copper)
-            E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
+            ew32(LEDCTL, hw->ledctl_mode1);
         break;
     }
 
@@ -6145,8 +6039,7 @@ e1000_setup_led(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-s32
-e1000_blink_led_start(struct e1000_hw *hw)
+s32 e1000_blink_led_start(struct e1000_hw *hw)
 {
     s16  i;
     u32 ledctl_blink = 0;
@@ -6170,7 +6063,7 @@ e1000_blink_led_start(struct e1000_hw *hw)
                 ledctl_blink |= (E1000_LEDCTL_LED0_BLINK << (i * 8));
     }
 
-    E1000_WRITE_REG(hw, LEDCTL, ledctl_blink);
+    ew32(LEDCTL, ledctl_blink);
 
     return E1000_SUCCESS;
 }
@@ -6180,8 +6073,7 @@ e1000_blink_led_start(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-s32
-e1000_cleanup_led(struct e1000_hw *hw)
+s32 e1000_cleanup_led(struct e1000_hw *hw)
 {
     s32 ret_val = E1000_SUCCESS;
 
@@ -6210,7 +6102,7 @@ e1000_cleanup_led(struct e1000_hw *hw)
             break;
         }
         /* Restore LEDCTL settings */
-        E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_default);
+        ew32(LEDCTL, hw->ledctl_default);
         break;
     }
 
@@ -6222,10 +6114,9 @@ e1000_cleanup_led(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-s32
-e1000_led_on(struct e1000_hw *hw)
+s32 e1000_led_on(struct e1000_hw *hw)
 {
-    u32 ctrl = E1000_READ_REG(hw, CTRL);
+    u32 ctrl = er32(CTRL);
 
     DEBUGFUNC("e1000_led_on");
 
@@ -6257,13 +6148,13 @@ e1000_led_on(struct e1000_hw *hw)
             e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED,
                  (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON));
         } else if (hw->media_type == e1000_media_type_copper) {
-            E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2);
+            ew32(LEDCTL, hw->ledctl_mode2);
             return E1000_SUCCESS;
         }
         break;
     }
 
-    E1000_WRITE_REG(hw, CTRL, ctrl);
+    ew32(CTRL, ctrl);
 
     return E1000_SUCCESS;
 }
@@ -6273,10 +6164,9 @@ e1000_led_on(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-s32
-e1000_led_off(struct e1000_hw *hw)
+s32 e1000_led_off(struct e1000_hw *hw)
 {
-    u32 ctrl = E1000_READ_REG(hw, CTRL);
+    u32 ctrl = er32(CTRL);
 
     DEBUGFUNC("e1000_led_off");
 
@@ -6308,13 +6198,13 @@ e1000_led_off(struct e1000_hw *hw)
             e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED,
                  (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF));
         } else if (hw->media_type == e1000_media_type_copper) {
-            E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
+            ew32(LEDCTL, hw->ledctl_mode1);
             return E1000_SUCCESS;
         }
         break;
     }
 
-    E1000_WRITE_REG(hw, CTRL, ctrl);
+    ew32(CTRL, ctrl);
 
     return E1000_SUCCESS;
 }
@@ -6324,98 +6214,97 @@ e1000_led_off(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void
-e1000_clear_hw_cntrs(struct e1000_hw *hw)
+static void e1000_clear_hw_cntrs(struct e1000_hw *hw)
 {
     volatile u32 temp;
 
-    temp = E1000_READ_REG(hw, CRCERRS);
-    temp = E1000_READ_REG(hw, SYMERRS);
-    temp = E1000_READ_REG(hw, MPC);
-    temp = E1000_READ_REG(hw, SCC);
-    temp = E1000_READ_REG(hw, ECOL);
-    temp = E1000_READ_REG(hw, MCC);
-    temp = E1000_READ_REG(hw, LATECOL);
-    temp = E1000_READ_REG(hw, COLC);
-    temp = E1000_READ_REG(hw, DC);
-    temp = E1000_READ_REG(hw, SEC);
-    temp = E1000_READ_REG(hw, RLEC);
-    temp = E1000_READ_REG(hw, XONRXC);
-    temp = E1000_READ_REG(hw, XONTXC);
-    temp = E1000_READ_REG(hw, XOFFRXC);
-    temp = E1000_READ_REG(hw, XOFFTXC);
-    temp = E1000_READ_REG(hw, FCRUC);
+    temp = er32(CRCERRS);
+    temp = er32(SYMERRS);
+    temp = er32(MPC);
+    temp = er32(SCC);
+    temp = er32(ECOL);
+    temp = er32(MCC);
+    temp = er32(LATECOL);
+    temp = er32(COLC);
+    temp = er32(DC);
+    temp = er32(SEC);
+    temp = er32(RLEC);
+    temp = er32(XONRXC);
+    temp = er32(XONTXC);
+    temp = er32(XOFFRXC);
+    temp = er32(XOFFTXC);
+    temp = er32(FCRUC);
 
     if (hw->mac_type != e1000_ich8lan) {
-    temp = E1000_READ_REG(hw, PRC64);
-    temp = E1000_READ_REG(hw, PRC127);
-    temp = E1000_READ_REG(hw, PRC255);
-    temp = E1000_READ_REG(hw, PRC511);
-    temp = E1000_READ_REG(hw, PRC1023);
-    temp = E1000_READ_REG(hw, PRC1522);
-    }
-
-    temp = E1000_READ_REG(hw, GPRC);
-    temp = E1000_READ_REG(hw, BPRC);
-    temp = E1000_READ_REG(hw, MPRC);
-    temp = E1000_READ_REG(hw, GPTC);
-    temp = E1000_READ_REG(hw, GORCL);
-    temp = E1000_READ_REG(hw, GORCH);
-    temp = E1000_READ_REG(hw, GOTCL);
-    temp = E1000_READ_REG(hw, GOTCH);
-    temp = E1000_READ_REG(hw, RNBC);
-    temp = E1000_READ_REG(hw, RUC);
-    temp = E1000_READ_REG(hw, RFC);
-    temp = E1000_READ_REG(hw, ROC);
-    temp = E1000_READ_REG(hw, RJC);
-    temp = E1000_READ_REG(hw, TORL);
-    temp = E1000_READ_REG(hw, TORH);
-    temp = E1000_READ_REG(hw, TOTL);
-    temp = E1000_READ_REG(hw, TOTH);
-    temp = E1000_READ_REG(hw, TPR);
-    temp = E1000_READ_REG(hw, TPT);
+    temp = er32(PRC64);
+    temp = er32(PRC127);
+    temp = er32(PRC255);
+    temp = er32(PRC511);
+    temp = er32(PRC1023);
+    temp = er32(PRC1522);
+    }
+
+    temp = er32(GPRC);
+    temp = er32(BPRC);
+    temp = er32(MPRC);
+    temp = er32(GPTC);
+    temp = er32(GORCL);
+    temp = er32(GORCH);
+    temp = er32(GOTCL);
+    temp = er32(GOTCH);
+    temp = er32(RNBC);
+    temp = er32(RUC);
+    temp = er32(RFC);
+    temp = er32(ROC);
+    temp = er32(RJC);
+    temp = er32(TORL);
+    temp = er32(TORH);
+    temp = er32(TOTL);
+    temp = er32(TOTH);
+    temp = er32(TPR);
+    temp = er32(TPT);
 
     if (hw->mac_type != e1000_ich8lan) {
-    temp = E1000_READ_REG(hw, PTC64);
-    temp = E1000_READ_REG(hw, PTC127);
-    temp = E1000_READ_REG(hw, PTC255);
-    temp = E1000_READ_REG(hw, PTC511);
-    temp = E1000_READ_REG(hw, PTC1023);
-    temp = E1000_READ_REG(hw, PTC1522);
+    temp = er32(PTC64);
+    temp = er32(PTC127);
+    temp = er32(PTC255);
+    temp = er32(PTC511);
+    temp = er32(PTC1023);
+    temp = er32(PTC1522);
     }
 
-    temp = E1000_READ_REG(hw, MPTC);
-    temp = E1000_READ_REG(hw, BPTC);
+    temp = er32(MPTC);
+    temp = er32(BPTC);
 
     if (hw->mac_type < e1000_82543) return;
 
-    temp = E1000_READ_REG(hw, ALGNERRC);
-    temp = E1000_READ_REG(hw, RXERRC);
-    temp = E1000_READ_REG(hw, TNCRS);
-    temp = E1000_READ_REG(hw, CEXTERR);
-    temp = E1000_READ_REG(hw, TSCTC);
-    temp = E1000_READ_REG(hw, TSCTFC);
+    temp = er32(ALGNERRC);
+    temp = er32(RXERRC);
+    temp = er32(TNCRS);
+    temp = er32(CEXTERR);
+    temp = er32(TSCTC);
+    temp = er32(TSCTFC);
 
     if (hw->mac_type <= e1000_82544) return;
 
-    temp = E1000_READ_REG(hw, MGTPRC);
-    temp = E1000_READ_REG(hw, MGTPDC);
-    temp = E1000_READ_REG(hw, MGTPTC);
+    temp = er32(MGTPRC);
+    temp = er32(MGTPDC);
+    temp = er32(MGTPTC);
 
     if (hw->mac_type <= e1000_82547_rev_2) return;
 
-    temp = E1000_READ_REG(hw, IAC);
-    temp = E1000_READ_REG(hw, ICRXOC);
+    temp = er32(IAC);
+    temp = er32(ICRXOC);
 
     if (hw->mac_type == e1000_ich8lan) return;
 
-    temp = E1000_READ_REG(hw, ICRXPTC);
-    temp = E1000_READ_REG(hw, ICRXATC);
-    temp = E1000_READ_REG(hw, ICTXPTC);
-    temp = E1000_READ_REG(hw, ICTXATC);
-    temp = E1000_READ_REG(hw, ICTXQEC);
-    temp = E1000_READ_REG(hw, ICTXQMTC);
-    temp = E1000_READ_REG(hw, ICRXDMTC);
+    temp = er32(ICRXPTC);
+    temp = er32(ICRXATC);
+    temp = er32(ICTXPTC);
+    temp = er32(ICTXATC);
+    temp = er32(ICTXQEC);
+    temp = er32(ICTXQMTC);
+    temp = er32(ICRXDMTC);
 }
 
 /******************************************************************************
@@ -6428,8 +6317,7 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw)
  * current_ifs_val, ifs_min_val, ifs_max_val, ifs_step_size, and ifs_ratio
  * before calling this function.
  *****************************************************************************/
-void
-e1000_reset_adaptive(struct e1000_hw *hw)
+void e1000_reset_adaptive(struct e1000_hw *hw)
 {
     DEBUGFUNC("e1000_reset_adaptive");
 
@@ -6442,7 +6330,7 @@ e1000_reset_adaptive(struct e1000_hw *hw)
             hw->ifs_ratio = IFS_RATIO;
         }
         hw->in_ifs_mode = false;
-        E1000_WRITE_REG(hw, AIT, 0);
+        ew32(AIT, 0);
     } else {
         DEBUGOUT("Not in Adaptive IFS mode!\n");
     }
@@ -6456,8 +6344,7 @@ e1000_reset_adaptive(struct e1000_hw *hw)
  * tx_packets - Number of transmits since last callback
  * total_collisions - Number of collisions since last callback
  *****************************************************************************/
-void
-e1000_update_adaptive(struct e1000_hw *hw)
+void e1000_update_adaptive(struct e1000_hw *hw)
 {
     DEBUGFUNC("e1000_update_adaptive");
 
@@ -6470,14 +6357,14 @@ e1000_update_adaptive(struct e1000_hw *hw)
                         hw->current_ifs_val = hw->ifs_min_val;
                     else
                         hw->current_ifs_val += hw->ifs_step_size;
-                    E1000_WRITE_REG(hw, AIT, hw->current_ifs_val);
+                    ew32(AIT, hw->current_ifs_val);
                 }
             }
         } else {
             if (hw->in_ifs_mode && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
                 hw->current_ifs_val = 0;
                 hw->in_ifs_mode = false;
-                E1000_WRITE_REG(hw, AIT, 0);
+                ew32(AIT, 0);
             }
         }
     } else {
@@ -6492,11 +6379,8 @@ e1000_update_adaptive(struct e1000_hw *hw)
  * frame_len - The length of the frame in question
  * mac_addr - The Ethernet destination address of the frame in question
  *****************************************************************************/
-void
-e1000_tbi_adjust_stats(struct e1000_hw *hw,
-                       struct e1000_hw_stats *stats,
-                       u32 frame_len,
-                       u8 *mac_addr)
+void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats,
+                           u32 frame_len, u8 *mac_addr)
 {
     u64 carry_bit;
 
@@ -6527,7 +6411,7 @@ e1000_tbi_adjust_stats(struct e1000_hw *hw,
      * since the test for a multicast frame will test positive on
      * a broadcast frame.
      */
-    if ((mac_addr[0] == (u8) 0xff) && (mac_addr[1] == (u8) 0xff))
+    if ((mac_addr[0] == (u8)0xff) && (mac_addr[1] == (u8)0xff))
         /* Broadcast packet */
         stats->bprc++;
     else if (*mac_addr & 0x01)
@@ -6570,8 +6454,7 @@ e1000_tbi_adjust_stats(struct e1000_hw *hw,
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
-e1000_get_bus_info(struct e1000_hw *hw)
+void e1000_get_bus_info(struct e1000_hw *hw)
 {
     s32 ret_val;
     u16 pci_ex_link_status;
@@ -6605,7 +6488,7 @@ e1000_get_bus_info(struct e1000_hw *hw)
         hw->bus_width = e1000_bus_width_pciex_1;
         break;
     default:
-        status = E1000_READ_REG(hw, STATUS);
+        status = er32(STATUS);
         hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
                        e1000_bus_type_pcix : e1000_bus_type_pci;
 
@@ -6645,10 +6528,7 @@ e1000_get_bus_info(struct e1000_hw *hw)
  * offset - offset to write to
  * value - value to write
  *****************************************************************************/
-static void
-e1000_write_reg_io(struct e1000_hw *hw,
-                   u32 offset,
-                   u32 value)
+static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value)
 {
     unsigned long io_addr = hw->io_base;
     unsigned long io_data = hw->io_base + 4;
@@ -6672,10 +6552,8 @@ e1000_write_reg_io(struct e1000_hw *hw,
  * register to the minimum and maximum range.
  * For IGP phy's, the function calculates the range by the AGC registers.
  *****************************************************************************/
-static s32
-e1000_get_cable_length(struct e1000_hw *hw,
-                       u16 *min_length,
-                       u16 *max_length)
+static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
+                                 u16 *max_length)
 {
     s32 ret_val;
     u16 agc_value = 0;
@@ -6863,9 +6741,8 @@ e1000_get_cable_length(struct e1000_hw *hw,
  * return 0.  If the link speed is 1000 Mbps the polarity status is in the
  * IGP01E1000_PHY_PCS_INIT_REG.
  *****************************************************************************/
-static s32
-e1000_check_polarity(struct e1000_hw *hw,
-                     e1000_rev_polarity *polarity)
+static s32 e1000_check_polarity(struct e1000_hw *hw,
+                               e1000_rev_polarity *polarity)
 {
     s32 ret_val;
     u16 phy_data;
@@ -6939,8 +6816,7 @@ e1000_check_polarity(struct e1000_hw *hw,
  * Link Health register.  In IGP this bit is latched high, so the driver must
  * read it immediately after link is established.
  *****************************************************************************/
-static s32
-e1000_check_downshift(struct e1000_hw *hw)
+static s32 e1000_check_downshift(struct e1000_hw *hw)
 {
     s32 ret_val;
     u16 phy_data;
@@ -6985,9 +6861,7 @@ e1000_check_downshift(struct e1000_hw *hw)
  *
  ****************************************************************************/
 
-static s32
-e1000_config_dsp_after_link_change(struct e1000_hw *hw,
-                                   bool link_up)
+static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw, bool link_up)
 {
     s32 ret_val;
     u16 phy_data, phy_saved_data, speed, duplex, i;
@@ -7173,8 +7047,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw,
  *
  * hw - Struct containing variables accessed by shared code
  ****************************************************************************/
-static s32
-e1000_set_phy_mode(struct e1000_hw *hw)
+static s32 e1000_set_phy_mode(struct e1000_hw *hw)
 {
     s32 ret_val;
     u16 eeprom_data;
@@ -7218,9 +7091,7 @@ e1000_set_phy_mode(struct e1000_hw *hw)
  *
  ****************************************************************************/
 
-static s32
-e1000_set_d3_lplu_state(struct e1000_hw *hw,
-                        bool active)
+static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active)
 {
     u32 phy_ctrl = 0;
     s32 ret_val;
@@ -7242,7 +7113,7 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
         /* MAC writes into PHY register based on the state transition
          * and start auto-negotiation. SW driver can overwrite the settings
          * in CSR PHY power control E1000_PHY_CTRL register. */
-        phy_ctrl = E1000_READ_REG(hw, PHY_CTRL);
+        phy_ctrl = er32(PHY_CTRL);
     } else {
         ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
         if (ret_val)
@@ -7259,7 +7130,7 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
         } else {
             if (hw->mac_type == e1000_ich8lan) {
                 phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
-                E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
+                ew32(PHY_CTRL, phy_ctrl);
             } else {
                 phy_data &= ~IGP02E1000_PM_D3_LPLU;
                 ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
@@ -7310,7 +7181,7 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
         } else {
             if (hw->mac_type == e1000_ich8lan) {
                 phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU;
-                E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
+                ew32(PHY_CTRL, phy_ctrl);
             } else {
                 phy_data |= IGP02E1000_PM_D3_LPLU;
                 ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
@@ -7348,9 +7219,7 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
  *
  ****************************************************************************/
 
-static s32
-e1000_set_d0_lplu_state(struct e1000_hw *hw,
-                        bool active)
+static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
 {
     u32 phy_ctrl = 0;
     s32 ret_val;
@@ -7361,7 +7230,7 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw,
         return E1000_SUCCESS;
 
     if (hw->mac_type == e1000_ich8lan) {
-        phy_ctrl = E1000_READ_REG(hw, PHY_CTRL);
+        phy_ctrl = er32(PHY_CTRL);
     } else {
         ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
         if (ret_val)
@@ -7371,7 +7240,7 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw,
     if (!active) {
         if (hw->mac_type == e1000_ich8lan) {
             phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
-            E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
+            ew32(PHY_CTRL, phy_ctrl);
         } else {
             phy_data &= ~IGP02E1000_PM_D0_LPLU;
             ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
@@ -7412,7 +7281,7 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw,
 
         if (hw->mac_type == e1000_ich8lan) {
             phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
-            E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
+            ew32(PHY_CTRL, phy_ctrl);
         } else {
             phy_data |= IGP02E1000_PM_D0_LPLU;
             ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
@@ -7439,8 +7308,7 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw,
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static s32
-e1000_set_vco_speed(struct e1000_hw *hw)
+static s32 e1000_set_vco_speed(struct e1000_hw *hw)
 {
     s32  ret_val;
     u16 default_page = 0;
@@ -7503,8 +7371,7 @@ e1000_set_vco_speed(struct e1000_hw *hw)
  *
  * returns: - E1000_SUCCESS .
  ****************************************************************************/
-static s32
-e1000_host_if_read_cookie(struct e1000_hw * hw, u8 *buffer)
+static s32 e1000_host_if_read_cookie(struct e1000_hw *hw, u8 *buffer)
 {
     u8 i;
     u32 offset = E1000_MNG_DHCP_COOKIE_OFFSET;
@@ -7514,7 +7381,7 @@ e1000_host_if_read_cookie(struct e1000_hw * hw, u8 *buffer)
     offset = (offset >> 2);
 
     for (i = 0; i < length; i++) {
-        *((u32 *) buffer + i) =
+        *((u32 *)buffer + i) =
             E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset + i);
     }
     return E1000_SUCCESS;
@@ -7530,21 +7397,20 @@ e1000_host_if_read_cookie(struct e1000_hw * hw, u8 *buffer)
  *            timeout
  *          - E1000_SUCCESS for success.
  ****************************************************************************/
-static s32
-e1000_mng_enable_host_if(struct e1000_hw * hw)
+static s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
 {
     u32 hicr;
     u8 i;
 
     /* Check that the host interface is enabled. */
-    hicr = E1000_READ_REG(hw, HICR);
+    hicr = er32(HICR);
     if ((hicr & E1000_HICR_EN) == 0) {
         DEBUGOUT("E1000_HOST_EN bit disabled.\n");
         return -E1000_ERR_HOST_INTERFACE_COMMAND;
     }
     /* check the previous command is completed */
     for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
-        hicr = E1000_READ_REG(hw, HICR);
+        hicr = er32(HICR);
         if (!(hicr & E1000_HICR_C))
             break;
         mdelay(1);
@@ -7564,9 +7430,8 @@ e1000_mng_enable_host_if(struct e1000_hw * hw)
  *
  * returns  - E1000_SUCCESS for success.
  ****************************************************************************/
-static s32
-e1000_mng_host_if_write(struct e1000_hw * hw, u8 *buffer,
-                        u16 length, u16 offset, u8 *sum)
+static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
+                                  u16 offset, u8 *sum)
 {
     u8 *tmp;
     u8 *bufptr = buffer;
@@ -7632,9 +7497,8 @@ e1000_mng_host_if_write(struct e1000_hw * hw, u8 *buffer,
  *
  * returns  - E1000_SUCCESS for success.
  ****************************************************************************/
-static s32
-e1000_mng_write_cmd_header(struct e1000_hw * hw,
-                           struct e1000_host_mng_command_header * hdr)
+static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
+                                     struct e1000_host_mng_command_header *hdr)
 {
     u16 i;
     u8 sum;
@@ -7648,7 +7512,7 @@ e1000_mng_write_cmd_header(struct e1000_hw * hw,
     sum = hdr->checksum;
     hdr->checksum = 0;
 
-    buffer = (u8 *) hdr;
+    buffer = (u8 *)hdr;
     i = length;
     while (i--)
         sum += buffer[i];
@@ -7658,8 +7522,8 @@ e1000_mng_write_cmd_header(struct e1000_hw * hw,
     length >>= 2;
     /* The device driver writes the relevant command block into the ram area. */
     for (i = 0; i < length; i++) {
-        E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, i, *((u32 *) hdr + i));
-        E1000_WRITE_FLUSH(hw);
+        E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, i, *((u32 *)hdr + i));
+        E1000_WRITE_FLUSH();
     }
 
     return E1000_SUCCESS;
@@ -7672,14 +7536,13 @@ e1000_mng_write_cmd_header(struct e1000_hw * hw,
  *
  * returns  - E1000_SUCCESS for success.
  ****************************************************************************/
-static s32
-e1000_mng_write_commit(struct e1000_hw * hw)
+static s32 e1000_mng_write_commit(struct e1000_hw *hw)
 {
     u32 hicr;
 
-    hicr = E1000_READ_REG(hw, HICR);
+    hicr = er32(HICR);
     /* Setting this bit tells the ARC that a new command is pending. */
-    E1000_WRITE_REG(hw, HICR, hicr | E1000_HICR_C);
+    ew32(HICR, hicr | E1000_HICR_C);
 
     return E1000_SUCCESS;
 }
@@ -7690,12 +7553,11 @@ e1000_mng_write_commit(struct e1000_hw * hw)
  *
  * returns  - true when the mode is IAMT or false.
  ****************************************************************************/
-bool
-e1000_check_mng_mode(struct e1000_hw *hw)
+bool e1000_check_mng_mode(struct e1000_hw *hw)
 {
     u32 fwsm;
 
-    fwsm = E1000_READ_REG(hw, FWSM);
+    fwsm = er32(FWSM);
 
     if (hw->mac_type == e1000_ich8lan) {
         if ((fwsm & E1000_FWSM_MODE_MASK) ==
@@ -7712,9 +7574,7 @@ e1000_check_mng_mode(struct e1000_hw *hw)
 /*****************************************************************************
  * This function writes the dhcp info .
  ****************************************************************************/
-s32
-e1000_mng_write_dhcp_info(struct e1000_hw * hw, u8 *buffer,
-                          u16 length)
+s32 e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length)
 {
     s32 ret_val;
     struct e1000_host_mng_command_header hdr;
@@ -7744,8 +7604,7 @@ e1000_mng_write_dhcp_info(struct e1000_hw * hw, u8 *buffer,
  *
  * returns  - checksum of buffer contents.
  ****************************************************************************/
-static u8
-e1000_calculate_mng_checksum(char *buffer, u32 length)
+static u8 e1000_calculate_mng_checksum(char *buffer, u32 length)
 {
     u8 sum = 0;
     u32 i;
@@ -7756,7 +7615,7 @@ e1000_calculate_mng_checksum(char *buffer, u32 length)
     for (i=0; i < length; i++)
         sum += buffer[i];
 
-    return (u8) (0 - sum);
+    return (u8)(0 - sum);
 }
 
 /*****************************************************************************
@@ -7764,8 +7623,7 @@ e1000_calculate_mng_checksum(char *buffer, u32 length)
  *
  * returns  - true for packet filtering or false.
  ****************************************************************************/
-bool
-e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
+bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
 {
     /* called in init as well as watchdog timer functions */
 
@@ -7806,21 +7664,20 @@ e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
  * returns: - true/false
  *
  *****************************************************************************/
-u32
-e1000_enable_mng_pass_thru(struct e1000_hw *hw)
+u32 e1000_enable_mng_pass_thru(struct e1000_hw *hw)
 {
     u32 manc;
     u32 fwsm, factps;
 
     if (hw->asf_firmware_present) {
-        manc = E1000_READ_REG(hw, MANC);
+        manc = er32(MANC);
 
         if (!(manc & E1000_MANC_RCV_TCO_EN) ||
             !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
             return false;
         if (e1000_arc_subsystem_valid(hw)) {
-            fwsm = E1000_READ_REG(hw, FWSM);
-            factps = E1000_READ_REG(hw, FACTPS);
+            fwsm = er32(FWSM);
+            factps = er32(FACTPS);
 
             if ((((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT) ==
                    e1000_mng_mode_pt) && !(factps & E1000_FACTPS_MNGCG))
@@ -7832,8 +7689,7 @@ e1000_enable_mng_pass_thru(struct e1000_hw *hw)
     return false;
 }
 
-static s32
-e1000_polarity_reversal_workaround(struct e1000_hw *hw)
+static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw)
 {
     s32 ret_val;
     u16 mii_status_reg;
@@ -7926,8 +7782,7 @@ e1000_polarity_reversal_workaround(struct e1000_hw *hw)
  * returns: - none.
  *
  ***************************************************************************/
-static void
-e1000_set_pci_express_master_disable(struct e1000_hw *hw)
+static void e1000_set_pci_express_master_disable(struct e1000_hw *hw)
 {
     u32 ctrl;
 
@@ -7936,9 +7791,9 @@ e1000_set_pci_express_master_disable(struct e1000_hw *hw)
     if (hw->bus_type != e1000_bus_type_pci_express)
         return;
 
-    ctrl = E1000_READ_REG(hw, CTRL);
+    ctrl = er32(CTRL);
     ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
-    E1000_WRITE_REG(hw, CTRL, ctrl);
+    ew32(CTRL, ctrl);
 }
 
 /*******************************************************************************
@@ -7952,8 +7807,7 @@ e1000_set_pci_express_master_disable(struct e1000_hw *hw)
  *            E1000_SUCCESS master requests disabled.
  *
  ******************************************************************************/
-s32
-e1000_disable_pciex_master(struct e1000_hw *hw)
+s32 e1000_disable_pciex_master(struct e1000_hw *hw)
 {
     s32 timeout = MASTER_DISABLE_TIMEOUT;   /* 80ms */
 
@@ -7965,7 +7819,7 @@ e1000_disable_pciex_master(struct e1000_hw *hw)
     e1000_set_pci_express_master_disable(hw);
 
     while (timeout) {
-        if (!(E1000_READ_REG(hw, STATUS) & E1000_STATUS_GIO_MASTER_ENABLE))
+        if (!(er32(STATUS) & E1000_STATUS_GIO_MASTER_ENABLE))
             break;
         else
             udelay(100);
@@ -7990,8 +7844,7 @@ e1000_disable_pciex_master(struct e1000_hw *hw)
  *            E1000_SUCCESS at any other case.
  *
  ******************************************************************************/
-static s32
-e1000_get_auto_rd_done(struct e1000_hw *hw)
+static s32 e1000_get_auto_rd_done(struct e1000_hw *hw)
 {
     s32 timeout = AUTO_READ_DONE_TIMEOUT;
 
@@ -8007,7 +7860,7 @@ e1000_get_auto_rd_done(struct e1000_hw *hw)
     case e1000_80003es2lan:
     case e1000_ich8lan:
         while (timeout) {
-            if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD)
+            if (er32(EECD) & E1000_EECD_AUTO_RD)
                 break;
             else msleep(1);
             timeout--;
@@ -8038,8 +7891,7 @@ e1000_get_auto_rd_done(struct e1000_hw *hw)
  *            E1000_SUCCESS at any other case.
  *
  ***************************************************************************/
-static s32
-e1000_get_phy_cfg_done(struct e1000_hw *hw)
+static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
 {
     s32 timeout = PHY_CFG_TIMEOUT;
     u32 cfg_mask = E1000_EEPROM_CFG_DONE;
@@ -8052,13 +7904,13 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw)
         break;
     case e1000_80003es2lan:
         /* Separate *_CFG_DONE_* bit for each port */
-        if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
+        if (er32(STATUS) & E1000_STATUS_FUNC_1)
             cfg_mask = E1000_EEPROM_CFG_DONE_PORT_1;
         /* Fall Through */
     case e1000_82571:
     case e1000_82572:
         while (timeout) {
-            if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask)
+            if (er32(EEMNGCTL) & cfg_mask)
                 break;
             else
                 msleep(1);
@@ -8085,8 +7937,7 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw)
  *            E1000_SUCCESS at any other case.
  *
  ***************************************************************************/
-static s32
-e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
+static s32 e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
 {
     s32 timeout;
     u32 swsm;
@@ -8105,11 +7956,11 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
     /* Get the FW semaphore. */
     timeout = hw->eeprom.word_size + 1;
     while (timeout) {
-        swsm = E1000_READ_REG(hw, SWSM);
+        swsm = er32(SWSM);
         swsm |= E1000_SWSM_SWESMBI;
-        E1000_WRITE_REG(hw, SWSM, swsm);
+        ew32(SWSM, swsm);
         /* if we managed to set the bit we got the semaphore. */
-        swsm = E1000_READ_REG(hw, SWSM);
+        swsm = er32(SWSM);
         if (swsm & E1000_SWSM_SWESMBI)
             break;
 
@@ -8135,8 +7986,7 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
  * returns: - None.
  *
  ***************************************************************************/
-static void
-e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
+static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
 {
     u32 swsm;
 
@@ -8145,13 +7995,13 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
     if (!hw->eeprom_semaphore_present)
         return;
 
-    swsm = E1000_READ_REG(hw, SWSM);
+    swsm = er32(SWSM);
     if (hw->mac_type == e1000_80003es2lan) {
         /* Release both semaphores. */
         swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
     } else
         swsm &= ~(E1000_SWSM_SWESMBI);
-    E1000_WRITE_REG(hw, SWSM, swsm);
+    ew32(SWSM, swsm);
 }
 
 /***************************************************************************
@@ -8164,8 +8014,7 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
  *            E1000_SUCCESS at any other case.
  *
  ***************************************************************************/
-static s32
-e1000_get_software_semaphore(struct e1000_hw *hw)
+static s32 e1000_get_software_semaphore(struct e1000_hw *hw)
 {
     s32 timeout = hw->eeprom.word_size + 1;
     u32 swsm;
@@ -8177,7 +8026,7 @@ e1000_get_software_semaphore(struct e1000_hw *hw)
     }
 
     while (timeout) {
-        swsm = E1000_READ_REG(hw, SWSM);
+        swsm = er32(SWSM);
         /* If SMBI bit cleared, it is now set and we hold the semaphore */
         if (!(swsm & E1000_SWSM_SMBI))
             break;
@@ -8200,8 +8049,7 @@ e1000_get_software_semaphore(struct e1000_hw *hw)
  * hw: Struct containing variables accessed by shared code
  *
  ***************************************************************************/
-static void
-e1000_release_software_semaphore(struct e1000_hw *hw)
+static void e1000_release_software_semaphore(struct e1000_hw *hw)
 {
     u32 swsm;
 
@@ -8211,10 +8059,10 @@ e1000_release_software_semaphore(struct e1000_hw *hw)
         return;
     }
 
-    swsm = E1000_READ_REG(hw, SWSM);
+    swsm = er32(SWSM);
     /* Release the SW semaphores.*/
     swsm &= ~E1000_SWSM_SMBI;
-    E1000_WRITE_REG(hw, SWSM, swsm);
+    ew32(SWSM, swsm);
 }
 
 /******************************************************************************
@@ -8228,26 +8076,24 @@ e1000_release_software_semaphore(struct e1000_hw *hw)
  *            E1000_SUCCESS
  *
  *****************************************************************************/
-s32
-e1000_check_phy_reset_block(struct e1000_hw *hw)
+s32 e1000_check_phy_reset_block(struct e1000_hw *hw)
 {
     u32 manc = 0;
     u32 fwsm = 0;
 
     if (hw->mac_type == e1000_ich8lan) {
-        fwsm = E1000_READ_REG(hw, FWSM);
+        fwsm = er32(FWSM);
         return (fwsm & E1000_FWSM_RSPCIPHY) ? E1000_SUCCESS
                                             : E1000_BLK_PHY_RESET;
     }
 
     if (hw->mac_type > e1000_82547_rev_2)
-        manc = E1000_READ_REG(hw, MANC);
+        manc = er32(MANC);
     return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
         E1000_BLK_PHY_RESET : E1000_SUCCESS;
 }
 
-static u8
-e1000_arc_subsystem_valid(struct e1000_hw *hw)
+static u8 e1000_arc_subsystem_valid(struct e1000_hw *hw)
 {
     u32 fwsm;
 
@@ -8261,7 +8107,7 @@ e1000_arc_subsystem_valid(struct e1000_hw *hw)
     case e1000_82572:
     case e1000_82573:
     case e1000_80003es2lan:
-        fwsm = E1000_READ_REG(hw, FWSM);
+        fwsm = er32(FWSM);
         if ((fwsm & E1000_FWSM_MODE_MASK) != 0)
             return true;
         break;
@@ -8283,8 +8129,7 @@ e1000_arc_subsystem_valid(struct e1000_hw *hw)
  * returns: E1000_SUCCESS
  *
  *****************************************************************************/
-static s32
-e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, u32 no_snoop)
+static s32 e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, u32 no_snoop)
 {
     u32 gcr_reg = 0;
 
@@ -8297,19 +8142,19 @@ e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, u32 no_snoop)
         return E1000_SUCCESS;
 
     if (no_snoop) {
-        gcr_reg = E1000_READ_REG(hw, GCR);
+        gcr_reg = er32(GCR);
         gcr_reg &= ~(PCI_EX_NO_SNOOP_ALL);
         gcr_reg |= no_snoop;
-        E1000_WRITE_REG(hw, GCR, gcr_reg);
+        ew32(GCR, gcr_reg);
     }
     if (hw->mac_type == e1000_ich8lan) {
         u32 ctrl_ext;
 
-        E1000_WRITE_REG(hw, GCR, PCI_EX_82566_SNOOP_ALL);
+        ew32(GCR, PCI_EX_82566_SNOOP_ALL);
 
-        ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+        ctrl_ext = er32(CTRL_EXT);
         ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
-        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+        ew32(CTRL_EXT, ctrl_ext);
     }
 
     return E1000_SUCCESS;
@@ -8324,8 +8169,7 @@ e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, u32 no_snoop)
  * hw: Struct containing variables accessed by shared code
  *
  ***************************************************************************/
-static s32
-e1000_get_software_flag(struct e1000_hw *hw)
+static s32 e1000_get_software_flag(struct e1000_hw *hw)
 {
     s32 timeout = PHY_CFG_TIMEOUT;
     u32 extcnf_ctrl;
@@ -8334,11 +8178,11 @@ e1000_get_software_flag(struct e1000_hw *hw)
 
     if (hw->mac_type == e1000_ich8lan) {
         while (timeout) {
-            extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
+            extcnf_ctrl = er32(EXTCNF_CTRL);
             extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
-            E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);
+            ew32(EXTCNF_CTRL, extcnf_ctrl);
 
-            extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
+            extcnf_ctrl = er32(EXTCNF_CTRL);
             if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
                 break;
             mdelay(1);
@@ -8363,17 +8207,16 @@ e1000_get_software_flag(struct e1000_hw *hw)
  * hw: Struct containing variables accessed by shared code
  *
  ***************************************************************************/
-static void
-e1000_release_software_flag(struct e1000_hw *hw)
+static void e1000_release_software_flag(struct e1000_hw *hw)
 {
     u32 extcnf_ctrl;
 
     DEBUGFUNC("e1000_release_software_flag");
 
     if (hw->mac_type == e1000_ich8lan) {
-        extcnf_ctrl= E1000_READ_REG(hw, EXTCNF_CTRL);
+        extcnf_ctrl= er32(EXTCNF_CTRL);
         extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
-        E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);
+        ew32(EXTCNF_CTRL, extcnf_ctrl);
     }
 
     return;
@@ -8388,9 +8231,8 @@ e1000_release_software_flag(struct e1000_hw *hw)
  * data - word read from the EEPROM
  * words - number of words to read
  *****************************************************************************/
-static s32
-e1000_read_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
-                       u16 *data)
+static s32 e1000_read_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
+                                 u16 *data)
 {
     s32  error = E1000_SUCCESS;
     u32 flash_bank = 0;
@@ -8405,7 +8247,7 @@ e1000_read_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
      * to be updated with each read.
      */
     /* Value of bit 22 corresponds to the flash bank we're on. */
-    flash_bank = (E1000_READ_REG(hw, EECD) & E1000_EECD_SEC1VAL) ? 1 : 0;
+    flash_bank = (er32(EECD) & E1000_EECD_SEC1VAL) ? 1 : 0;
 
     /* Adjust offset appropriately if we're on bank 1 - adjust for word size */
     bank_offset = flash_bank * (hw->flash_bank_size * 2);
@@ -8444,9 +8286,8 @@ e1000_read_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
  * words - number of words to write
  * data - words to write to the EEPROM
  *****************************************************************************/
-static s32
-e1000_write_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
-                        u16 *data)
+static s32 e1000_write_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
+                                  u16 *data)
 {
     u32 i = 0;
     s32 error = E1000_SUCCESS;
@@ -8491,8 +8332,7 @@ e1000_write_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
  *
  * hw - The pointer to the hw structure
  ****************************************************************************/
-static s32
-e1000_ich8_cycle_init(struct e1000_hw *hw)
+static s32 e1000_ich8_cycle_init(struct e1000_hw *hw)
 {
     union ich8_hws_flash_status hsfsts;
     s32 error = E1000_ERR_EEPROM;
@@ -8558,8 +8398,7 @@ e1000_ich8_cycle_init(struct e1000_hw *hw)
  *
  * hw - The pointer to the hw structure
  ****************************************************************************/
-static s32
-e1000_ich8_flash_cycle(struct e1000_hw *hw, u32 timeout)
+static s32 e1000_ich8_flash_cycle(struct e1000_hw *hw, u32 timeout)
 {
     union ich8_hws_flash_ctrl hsflctl;
     union ich8_hws_flash_status hsfsts;
@@ -8593,9 +8432,8 @@ e1000_ich8_flash_cycle(struct e1000_hw *hw, u32 timeout)
  * size - Size of data to read, 1=byte 2=word
  * data - Pointer to the word to store the value read.
  *****************************************************************************/
-static s32
-e1000_read_ich8_data(struct e1000_hw *hw, u32 index,
-                     u32 size, u16* data)
+static s32 e1000_read_ich8_data(struct e1000_hw *hw, u32 index, u32 size,
+                               u16 *data)
 {
     union ich8_hws_flash_status hsfsts;
     union ich8_hws_flash_ctrl hsflctl;
@@ -8672,9 +8510,8 @@ e1000_read_ich8_data(struct e1000_hw *hw, u32 index,
  * size - Size of data to read, 1=byte 2=word
  * data - The byte(s) to write to the NVM.
  *****************************************************************************/
-static s32
-e1000_write_ich8_data(struct e1000_hw *hw, u32 index, u32 size,
-                      u16 data)
+static s32 e1000_write_ich8_data(struct e1000_hw *hw, u32 index, u32 size,
+                                u16 data)
 {
     union ich8_hws_flash_status hsfsts;
     union ich8_hws_flash_ctrl hsflctl;
@@ -8747,8 +8584,7 @@ e1000_write_ich8_data(struct e1000_hw *hw, u32 index, u32 size,
  * index - The index of the byte to read.
  * data - Pointer to a byte to store the value read.
  *****************************************************************************/
-static s32
-e1000_read_ich8_byte(struct e1000_hw *hw, u32 index, u8* data)
+static s32 e1000_read_ich8_byte(struct e1000_hw *hw, u32 index, u8 *data)
 {
     s32 status = E1000_SUCCESS;
     u16 word = 0;
@@ -8770,8 +8606,7 @@ e1000_read_ich8_byte(struct e1000_hw *hw, u32 index, u8* data)
  * index - The index of the byte to write.
  * byte - The byte to write to the NVM.
  *****************************************************************************/
-static s32
-e1000_verify_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 byte)
+static s32 e1000_verify_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 byte)
 {
     s32 error = E1000_SUCCESS;
     s32 program_retries = 0;
@@ -8803,8 +8638,7 @@ e1000_verify_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 byte)
  * index - The index of the byte to read.
  * data - The byte to write to the NVM.
  *****************************************************************************/
-static s32
-e1000_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 data)
+static s32 e1000_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 data)
 {
     s32 status = E1000_SUCCESS;
     u16 word = (u16)data;
@@ -8821,8 +8655,7 @@ e1000_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 data)
  * index - The starting byte index of the word to read.
  * data - Pointer to a word to store the value read.
  *****************************************************************************/
-static s32
-e1000_read_ich8_word(struct e1000_hw *hw, u32 index, u16 *data)
+static s32 e1000_read_ich8_word(struct e1000_hw *hw, u32 index, u16 *data)
 {
     s32 status = E1000_SUCCESS;
     status = e1000_read_ich8_data(hw, index, 2, data);
@@ -8840,8 +8673,7 @@ e1000_read_ich8_word(struct e1000_hw *hw, u32 index, u16 *data)
  * amount of NVM used in each bank is a *minimum* of 4 KBytes, but in fact the
  * bank size may be 4, 8 or 64 KBytes
  *****************************************************************************/
-static s32
-e1000_erase_ich8_4k_segment(struct e1000_hw *hw, u32 bank)
+static s32 e1000_erase_ich8_4k_segment(struct e1000_hw *hw, u32 bank)
 {
     union ich8_hws_flash_status hsfsts;
     union ich8_hws_flash_ctrl hsflctl;
@@ -8930,9 +8762,9 @@ e1000_erase_ich8_4k_segment(struct e1000_hw *hw, u32 bank)
     return error;
 }
 
-static s32
-e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
-                                      u32 cnf_base_addr, u32 cnf_size)
+static s32 e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
+                                                u32 cnf_base_addr,
+                                                u32 cnf_size)
 {
     u32 ret_val = E1000_SUCCESS;
     u16 word_addr, reg_data, reg_addr;
@@ -8972,8 +8804,7 @@ e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
  *
  * hw: Struct containing variables accessed by shared code
  *****************************************************************************/
-static s32
-e1000_init_lcd_from_nvm(struct e1000_hw *hw)
+static s32 e1000_init_lcd_from_nvm(struct e1000_hw *hw)
 {
     u32 reg_data, cnf_base_addr, cnf_size, ret_val, loop;
 
@@ -8981,32 +8812,32 @@ e1000_init_lcd_from_nvm(struct e1000_hw *hw)
           return E1000_SUCCESS;
 
     /* Check if SW needs configure the PHY */
-    reg_data = E1000_READ_REG(hw, FEXTNVM);
+    reg_data = er32(FEXTNVM);
     if (!(reg_data & FEXTNVM_SW_CONFIG))
         return E1000_SUCCESS;
 
     /* Wait for basic configuration completes before proceeding*/
     loop = 0;
     do {
-        reg_data = E1000_READ_REG(hw, STATUS) & E1000_STATUS_LAN_INIT_DONE;
+        reg_data = er32(STATUS) & E1000_STATUS_LAN_INIT_DONE;
         udelay(100);
         loop++;
     } while ((!reg_data) && (loop < 50));
 
     /* Clear the Init Done bit for the next init event */
-    reg_data = E1000_READ_REG(hw, STATUS);
+    reg_data = er32(STATUS);
     reg_data &= ~E1000_STATUS_LAN_INIT_DONE;
-    E1000_WRITE_REG(hw, STATUS, reg_data);
+    ew32(STATUS, reg_data);
 
     /* Make sure HW does not configure LCD from PHY extended configuration
        before SW configuration */
-    reg_data = E1000_READ_REG(hw, EXTCNF_CTRL);
+    reg_data = er32(EXTCNF_CTRL);
     if ((reg_data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) == 0x0000) {
-        reg_data = E1000_READ_REG(hw, EXTCNF_SIZE);
+        reg_data = er32(EXTCNF_SIZE);
         cnf_size = reg_data & E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH;
         cnf_size >>= 16;
         if (cnf_size) {
-            reg_data = E1000_READ_REG(hw, EXTCNF_CTRL);
+            reg_data = er32(EXTCNF_CTRL);
             cnf_base_addr = reg_data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER;
             /* cnf_base_addr is in DWORD */
             cnf_base_addr >>= 16;
index cf12b05cd011fcbd4db80d12273731d4c4ff9c03..ad6da7b67e555023532134d64e6ac1efd326049f 100644 (file)
 
 char e1000_driver_name[] = "e1000";
 static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-#ifndef CONFIG_E1000_NAPI
-#define DRIVERNAPI
-#else
-#define DRIVERNAPI "-NAPI"
-#endif
-#define DRV_VERSION "7.3.20-k2"DRIVERNAPI
+#define DRV_VERSION "7.3.20-k3-NAPI"
 const char e1000_driver_version[] = DRV_VERSION;
 static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
 
@@ -138,7 +133,6 @@ static irqreturn_t e1000_intr(int irq, void *data);
 static irqreturn_t e1000_intr_msi(int irq, void *data);
 static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
                               struct e1000_tx_ring *tx_ring);
-#ifdef CONFIG_E1000_NAPI
 static int e1000_clean(struct napi_struct *napi, int budget);
 static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
                               struct e1000_rx_ring *rx_ring,
@@ -146,12 +140,6 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
                                  struct e1000_rx_ring *rx_ring,
                                  int *work_done, int work_to_do);
-#else
-static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
-                              struct e1000_rx_ring *rx_ring);
-static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
-                                 struct e1000_rx_ring *rx_ring);
-#endif
 static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
                                    struct e1000_rx_ring *rx_ring,
                                   int cleaned_count);
@@ -232,8 +220,7 @@ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
  * loaded. All it does is register with the PCI subsystem.
  **/
 
-static int __init
-e1000_init_module(void)
+static int __init e1000_init_module(void)
 {
        int ret;
        printk(KERN_INFO "%s - version %s\n",
@@ -261,8 +248,7 @@ module_init(e1000_init_module);
  * from memory.
  **/
 
-static void __exit
-e1000_exit_module(void)
+static void __exit e1000_exit_module(void)
 {
        pci_unregister_driver(&e1000_driver);
 }
@@ -271,12 +257,13 @@ module_exit(e1000_exit_module);
 
 static int e1000_request_irq(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct net_device *netdev = adapter->netdev;
        irq_handler_t handler = e1000_intr;
        int irq_flags = IRQF_SHARED;
        int err;
 
-       if (adapter->hw.mac_type >= e1000_82571) {
+       if (hw->mac_type >= e1000_82571) {
                adapter->have_msi = !pci_enable_msi(adapter->pdev);
                if (adapter->have_msi) {
                        handler = e1000_intr_msi;
@@ -311,11 +298,12 @@ static void e1000_free_irq(struct e1000_adapter *adapter)
  * @adapter: board private structure
  **/
 
-static void
-e1000_irq_disable(struct e1000_adapter *adapter)
+static void e1000_irq_disable(struct e1000_adapter *adapter)
 {
-       E1000_WRITE_REG(&adapter->hw, IMC, ~0);
-       E1000_WRITE_FLUSH(&adapter->hw);
+       struct e1000_hw *hw = &adapter->hw;
+
+       ew32(IMC, ~0);
+       E1000_WRITE_FLUSH();
        synchronize_irq(adapter->pdev->irq);
 }
 
@@ -324,22 +312,23 @@ e1000_irq_disable(struct e1000_adapter *adapter)
  * @adapter: board private structure
  **/
 
-static void
-e1000_irq_enable(struct e1000_adapter *adapter)
+static void e1000_irq_enable(struct e1000_adapter *adapter)
 {
-       E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK);
-       E1000_WRITE_FLUSH(&adapter->hw);
+       struct e1000_hw *hw = &adapter->hw;
+
+       ew32(IMS, IMS_ENABLE_MASK);
+       E1000_WRITE_FLUSH();
 }
 
-static void
-e1000_update_mng_vlan(struct e1000_adapter *adapter)
+static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct net_device *netdev = adapter->netdev;
-       u16 vid = adapter->hw.mng_cookie.vlan_id;
+       u16 vid = hw->mng_cookie.vlan_id;
        u16 old_vid = adapter->mng_vlan_id;
        if (adapter->vlgrp) {
                if (!vlan_group_get_device(adapter->vlgrp, vid)) {
-                       if (adapter->hw.mng_cookie.status &
+                       if (hw->mng_cookie.status &
                                E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
                                e1000_vlan_rx_add_vid(netdev, vid);
                                adapter->mng_vlan_id = vid;
@@ -366,26 +355,24 @@ e1000_update_mng_vlan(struct e1000_adapter *adapter)
  *
  **/
 
-static void
-e1000_release_hw_control(struct e1000_adapter *adapter)
+static void e1000_release_hw_control(struct e1000_adapter *adapter)
 {
        u32 ctrl_ext;
        u32 swsm;
+       struct e1000_hw *hw = &adapter->hw;
 
        /* Let firmware taken over control of h/w */
-       switch (adapter->hw.mac_type) {
+       switch (hw->mac_type) {
        case e1000_82573:
-               swsm = E1000_READ_REG(&adapter->hw, SWSM);
-               E1000_WRITE_REG(&adapter->hw, SWSM,
-                               swsm & ~E1000_SWSM_DRV_LOAD);
+               swsm = er32(SWSM);
+               ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
                break;
        case e1000_82571:
        case e1000_82572:
        case e1000_80003es2lan:
        case e1000_ich8lan:
-               ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
-               E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
-                               ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
+               ctrl_ext = er32(CTRL_EXT);
+               ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
                break;
        default:
                break;
@@ -403,37 +390,36 @@ e1000_release_hw_control(struct e1000_adapter *adapter)
  *
  **/
 
-static void
-e1000_get_hw_control(struct e1000_adapter *adapter)
+static void e1000_get_hw_control(struct e1000_adapter *adapter)
 {
        u32 ctrl_ext;
        u32 swsm;
+       struct e1000_hw *hw = &adapter->hw;
 
        /* Let firmware know the driver has taken over */
-       switch (adapter->hw.mac_type) {
+       switch (hw->mac_type) {
        case e1000_82573:
-               swsm = E1000_READ_REG(&adapter->hw, SWSM);
-               E1000_WRITE_REG(&adapter->hw, SWSM,
-                               swsm | E1000_SWSM_DRV_LOAD);
+               swsm = er32(SWSM);
+               ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
                break;
        case e1000_82571:
        case e1000_82572:
        case e1000_80003es2lan:
        case e1000_ich8lan:
-               ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
-               E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
-                               ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+               ctrl_ext = er32(CTRL_EXT);
+               ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
                break;
        default:
                break;
        }
 }
 
-static void
-e1000_init_manageability(struct e1000_adapter *adapter)
+static void e1000_init_manageability(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
+
        if (adapter->en_mng_pt) {
-               u32 manc = E1000_READ_REG(&adapter->hw, MANC);
+               u32 manc = er32(MANC);
 
                /* disable hardware interception of ARP */
                manc &= ~(E1000_MANC_ARP_EN);
@@ -441,37 +427,38 @@ e1000_init_manageability(struct e1000_adapter *adapter)
                /* enable receiving management packets to the host */
                /* this will probably generate destination unreachable messages
                 * from the host OS, but the packets will be handled on SMBUS */
-               if (adapter->hw.has_manc2h) {
-                       u32 manc2h = E1000_READ_REG(&adapter->hw, MANC2H);
+               if (hw->has_manc2h) {
+                       u32 manc2h = er32(MANC2H);
 
                        manc |= E1000_MANC_EN_MNG2HOST;
 #define E1000_MNG2HOST_PORT_623 (1 << 5)
 #define E1000_MNG2HOST_PORT_664 (1 << 6)
                        manc2h |= E1000_MNG2HOST_PORT_623;
                        manc2h |= E1000_MNG2HOST_PORT_664;
-                       E1000_WRITE_REG(&adapter->hw, MANC2H, manc2h);
+                       ew32(MANC2H, manc2h);
                }
 
-               E1000_WRITE_REG(&adapter->hw, MANC, manc);
+               ew32(MANC, manc);
        }
 }
 
-static void
-e1000_release_manageability(struct e1000_adapter *adapter)
+static void e1000_release_manageability(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
+
        if (adapter->en_mng_pt) {
-               u32 manc = E1000_READ_REG(&adapter->hw, MANC);
+               u32 manc = er32(MANC);
 
                /* re-enable hardware interception of ARP */
                manc |= E1000_MANC_ARP_EN;
 
-               if (adapter->hw.has_manc2h)
+               if (hw->has_manc2h)
                        manc &= ~E1000_MANC_EN_MNG2HOST;
 
                /* don't explicitly have to mess with MANC2H since
                 * MANC has an enable disable that gates MANC2H */
 
-               E1000_WRITE_REG(&adapter->hw, MANC, manc);
+               ew32(MANC, manc);
        }
 }
 
@@ -506,18 +493,19 @@ static void e1000_configure(struct e1000_adapter *adapter)
 
 int e1000_up(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
+
        /* hardware has been reset, we need to reload some things */
        e1000_configure(adapter);
 
        clear_bit(__E1000_DOWN, &adapter->flags);
 
-#ifdef CONFIG_E1000_NAPI
        napi_enable(&adapter->napi);
-#endif
+
        e1000_irq_enable(adapter);
 
        /* fire a link change interrupt to start the watchdog */
-       E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_LSC);
+       ew32(ICS, E1000_ICS_LSC);
        return 0;
 }
 
@@ -533,30 +521,33 @@ int e1000_up(struct e1000_adapter *adapter)
 
 void e1000_power_up_phy(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        u16 mii_reg = 0;
 
        /* Just clear the power down bit to wake the phy back up */
-       if (adapter->hw.media_type == e1000_media_type_copper) {
+       if (hw->media_type == e1000_media_type_copper) {
                /* according to the manual, the phy will retain its
                 * settings across a power-down/up cycle */
-               e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
+               e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
                mii_reg &= ~MII_CR_POWER_DOWN;
-               e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
+               e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
        }
 }
 
 static void e1000_power_down_phy(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
+
        /* Power down the PHY so no link is implied when interface is down *
         * The PHY cannot be powered down if any of the following is true *
         * (a) WoL is enabled
         * (b) AMT is active
         * (c) SoL/IDER session is active */
-       if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
-          adapter->hw.media_type == e1000_media_type_copper) {
+       if (!adapter->wol && hw->mac_type >= e1000_82540 &&
+          hw->media_type == e1000_media_type_copper) {
                u16 mii_reg = 0;
 
-               switch (adapter->hw.mac_type) {
+               switch (hw->mac_type) {
                case e1000_82540:
                case e1000_82545:
                case e1000_82545_rev_3:
@@ -566,8 +557,7 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter)
                case e1000_82541_rev_2:
                case e1000_82547:
                case e1000_82547_rev_2:
-                       if (E1000_READ_REG(&adapter->hw, MANC) &
-                           E1000_MANC_SMBUS_EN)
+                       if (er32(MANC) & E1000_MANC_SMBUS_EN)
                                goto out;
                        break;
                case e1000_82571:
@@ -575,24 +565,23 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter)
                case e1000_82573:
                case e1000_80003es2lan:
                case e1000_ich8lan:
-                       if (e1000_check_mng_mode(&adapter->hw) ||
-                           e1000_check_phy_reset_block(&adapter->hw))
+                       if (e1000_check_mng_mode(hw) ||
+                           e1000_check_phy_reset_block(hw))
                                goto out;
                        break;
                default:
                        goto out;
                }
-               e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
+               e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
                mii_reg |= MII_CR_POWER_DOWN;
-               e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
+               e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
                mdelay(1);
        }
 out:
        return;
 }
 
-void
-e1000_down(struct e1000_adapter *adapter)
+void e1000_down(struct e1000_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
 
@@ -600,9 +589,8 @@ e1000_down(struct e1000_adapter *adapter)
         * reschedule our watchdog timer */
        set_bit(__E1000_DOWN, &adapter->flags);
 
-#ifdef CONFIG_E1000_NAPI
        napi_disable(&adapter->napi);
-#endif
+
        e1000_irq_disable(adapter);
 
        del_timer_sync(&adapter->tx_fifo_stall_timer);
@@ -620,8 +608,7 @@ e1000_down(struct e1000_adapter *adapter)
        e1000_clean_all_rx_rings(adapter);
 }
 
-void
-e1000_reinit_locked(struct e1000_adapter *adapter)
+void e1000_reinit_locked(struct e1000_adapter *adapter)
 {
        WARN_ON(in_interrupt());
        while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
@@ -631,9 +618,9 @@ e1000_reinit_locked(struct e1000_adapter *adapter)
        clear_bit(__E1000_RESETTING, &adapter->flags);
 }
 
-void
-e1000_reset(struct e1000_adapter *adapter)
+void e1000_reset(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        u32 pba = 0, tx_space, min_tx_space, min_rx_space;
        u16 fc_high_water_mark = E1000_FC_HIGH_DIFF;
        bool legacy_pba_adjust = false;
@@ -642,7 +629,7 @@ e1000_reset(struct e1000_adapter *adapter)
         * To take effect CTRL.RST is required.
         */
 
-       switch (adapter->hw.mac_type) {
+       switch (hw->mac_type) {
        case e1000_82542_rev2_0:
        case e1000_82542_rev2_1:
        case e1000_82543:
@@ -683,16 +670,16 @@ e1000_reset(struct e1000_adapter *adapter)
                if (adapter->netdev->mtu > E1000_RXBUFFER_8192)
                        pba -= 8; /* allocate more FIFO for Tx */
 
-               if (adapter->hw.mac_type == e1000_82547) {
+               if (hw->mac_type == e1000_82547) {
                        adapter->tx_fifo_head = 0;
                        adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
                        adapter->tx_fifo_size =
                                (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
                        atomic_set(&adapter->tx_fifo_stall, 0);
                }
-       } else if (adapter->hw.max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) {
+       } else if (hw->max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) {
                /* adjust PBA for jumbo frames */
-               E1000_WRITE_REG(&adapter->hw, PBA, pba);
+               ew32(PBA, pba);
 
                /* To maintain wire speed transmits, the Tx FIFO should be
                 * large enough to accomodate two full transmit packets,
@@ -700,7 +687,7 @@ e1000_reset(struct e1000_adapter *adapter)
                 * the Rx FIFO should be large enough to accomodate at least
                 * one full receive packet and is similarly rounded up and
                 * expressed in KB. */
-               pba = E1000_READ_REG(&adapter->hw, PBA);
+               pba = er32(PBA);
                /* upper 16 bits has Tx packet buffer allocation size in KB */
                tx_space = pba >> 16;
                /* lower 16 bits has Rx packet buffer allocation size in KB */
@@ -723,7 +710,7 @@ e1000_reset(struct e1000_adapter *adapter)
                        pba = pba - (min_tx_space - tx_space);
 
                        /* PCI/PCIx hardware has PBA alignment constraints */
-                       switch (adapter->hw.mac_type) {
+                       switch (hw->mac_type) {
                        case e1000_82545 ... e1000_82546_rev_3:
                                pba &= ~(E1000_PBA_8K - 1);
                                break;
@@ -734,7 +721,7 @@ e1000_reset(struct e1000_adapter *adapter)
                        /* if short on rx space, rx wins and must trump tx
                         * adjustment or use Early Receive if available */
                        if (pba < min_rx_space) {
-                               switch (adapter->hw.mac_type) {
+                               switch (hw->mac_type) {
                                case e1000_82573:
                                        /* ERT enabled in e1000_configure_rx */
                                        break;
@@ -746,7 +733,7 @@ e1000_reset(struct e1000_adapter *adapter)
                }
        }
 
-       E1000_WRITE_REG(&adapter->hw, PBA, pba);
+       ew32(PBA, pba);
 
        /* flow control settings */
        /* Set the FC high water mark to 90% of the FIFO size.
@@ -759,54 +746,54 @@ e1000_reset(struct e1000_adapter *adapter)
        if (pba < E1000_PBA_16K)
                fc_high_water_mark = (pba * 1024) - 1600;
 
-       adapter->hw.fc_high_water = fc_high_water_mark;
-       adapter->hw.fc_low_water = fc_high_water_mark - 8;
-       if (adapter->hw.mac_type == e1000_80003es2lan)
-               adapter->hw.fc_pause_time = 0xFFFF;
+       hw->fc_high_water = fc_high_water_mark;
+       hw->fc_low_water = fc_high_water_mark - 8;
+       if (hw->mac_type == e1000_80003es2lan)
+               hw->fc_pause_time = 0xFFFF;
        else
-               adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME;
-       adapter->hw.fc_send_xon = 1;
-       adapter->hw.fc = adapter->hw.original_fc;
+               hw->fc_pause_time = E1000_FC_PAUSE_TIME;
+       hw->fc_send_xon = 1;
+       hw->fc = hw->original_fc;
 
        /* Allow time for pending master requests to run */
-       e1000_reset_hw(&adapter->hw);
-       if (adapter->hw.mac_type >= e1000_82544)
-               E1000_WRITE_REG(&adapter->hw, WUC, 0);
+       e1000_reset_hw(hw);
+       if (hw->mac_type >= e1000_82544)
+               ew32(WUC, 0);
 
-       if (e1000_init_hw(&adapter->hw))
+       if (e1000_init_hw(hw))
                DPRINTK(PROBE, ERR, "Hardware Error\n");
        e1000_update_mng_vlan(adapter);
 
        /* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
-       if (adapter->hw.mac_type >= e1000_82544 &&
-           adapter->hw.mac_type <= e1000_82547_rev_2 &&
-           adapter->hw.autoneg == 1 &&
-           adapter->hw.autoneg_advertised == ADVERTISE_1000_FULL) {
-               u32 ctrl = E1000_READ_REG(&adapter->hw, CTRL);
+       if (hw->mac_type >= e1000_82544 &&
+           hw->mac_type <= e1000_82547_rev_2 &&
+           hw->autoneg == 1 &&
+           hw->autoneg_advertised == ADVERTISE_1000_FULL) {
+               u32 ctrl = er32(CTRL);
                /* clear phy power management bit if we are in gig only mode,
                 * which if enabled will attempt negotiation to 100Mb, which
                 * can cause a loss of link at power off or driver unload */
                ctrl &= ~E1000_CTRL_SWDPIN3;
-               E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
+               ew32(CTRL, ctrl);
        }
 
        /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
-       E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE);
+       ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
 
-       e1000_reset_adaptive(&adapter->hw);
-       e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
+       e1000_reset_adaptive(hw);
+       e1000_phy_get_info(hw, &adapter->phy_info);
 
        if (!adapter->smart_power_down &&
-           (adapter->hw.mac_type == e1000_82571 ||
-            adapter->hw.mac_type == e1000_82572)) {
+           (hw->mac_type == e1000_82571 ||
+            hw->mac_type == e1000_82572)) {
                u16 phy_data = 0;
                /* speed up time to link by disabling smart power down, ignore
                 * the return value of this function because there is nothing
                 * different we would do if it failed */
-               e1000_read_phy_reg(&adapter->hw, IGP02E1000_PHY_POWER_MGMT,
+               e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
                                   &phy_data);
                phy_data &= ~IGP02E1000_PM_SPD;
-               e1000_write_phy_reg(&adapter->hw, IGP02E1000_PHY_POWER_MGMT,
+               e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
                                    phy_data);
        }
 
@@ -865,12 +852,48 @@ static void e1000_dump_eeprom(struct e1000_adapter *adapter)
        printk(KERN_ERR "to enable this network device.\n");
        printk(KERN_ERR "Please inspect the EEPROM dump and report the issue "
               "to your hardware vendor\n");
-       printk(KERN_ERR "or Intel Customer Support: linux-nics@intel.com\n");
+       printk(KERN_ERR "or Intel Customer Support.\n");
        printk(KERN_ERR "/*********************/\n");
 
        kfree(data);
 }
 
+/**
+ * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
+ * @pdev: PCI device information struct
+ *
+ * Return true if an adapter needs ioport resources
+ **/
+static int e1000_is_need_ioport(struct pci_dev *pdev)
+{
+       switch (pdev->device) {
+       case E1000_DEV_ID_82540EM:
+       case E1000_DEV_ID_82540EM_LOM:
+       case E1000_DEV_ID_82540EP:
+       case E1000_DEV_ID_82540EP_LOM:
+       case E1000_DEV_ID_82540EP_LP:
+       case E1000_DEV_ID_82541EI:
+       case E1000_DEV_ID_82541EI_MOBILE:
+       case E1000_DEV_ID_82541ER:
+       case E1000_DEV_ID_82541ER_LOM:
+       case E1000_DEV_ID_82541GI:
+       case E1000_DEV_ID_82541GI_LF:
+       case E1000_DEV_ID_82541GI_MOBILE:
+       case E1000_DEV_ID_82544EI_COPPER:
+       case E1000_DEV_ID_82544EI_FIBER:
+       case E1000_DEV_ID_82544GC_COPPER:
+       case E1000_DEV_ID_82544GC_LOM:
+       case E1000_DEV_ID_82545EM_COPPER:
+       case E1000_DEV_ID_82545EM_FIBER:
+       case E1000_DEV_ID_82546EB_COPPER:
+       case E1000_DEV_ID_82546EB_FIBER:
+       case E1000_DEV_ID_82546EB_QUAD_COPPER:
+               return true;
+       default:
+               return false;
+       }
+}
+
 /**
  * e1000_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -882,37 +905,51 @@ static void e1000_dump_eeprom(struct e1000_adapter *adapter)
  * The OS initialization, configuring of the adapter private structure,
  * and a hardware reset occur.
  **/
-
-static int __devinit
-e1000_probe(struct pci_dev *pdev,
-            const struct pci_device_id *ent)
+static int __devinit e1000_probe(struct pci_dev *pdev,
+                                const struct pci_device_id *ent)
 {
        struct net_device *netdev;
        struct e1000_adapter *adapter;
+       struct e1000_hw *hw;
 
        static int cards_found = 0;
        static int global_quad_port_a = 0; /* global ksp3 port a indication */
        int i, err, pci_using_dac;
        u16 eeprom_data = 0;
        u16 eeprom_apme_mask = E1000_EEPROM_APME;
+       int bars, need_ioport;
        DECLARE_MAC_BUF(mac);
 
-       if ((err = pci_enable_device(pdev)))
+       /* do not allocate ioport bars when not needed */
+       need_ioport = e1000_is_need_ioport(pdev);
+       if (need_ioport) {
+               bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
+               err = pci_enable_device(pdev);
+       } else {
+               bars = pci_select_bars(pdev, IORESOURCE_MEM);
+               err = pci_enable_device(pdev);
+       }
+       if (err)
                return err;
 
-       if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
-           !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
+       if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
+           !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
                pci_using_dac = 1;
        } else {
-               if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) &&
-                   (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) {
-                       E1000_ERR("No usable DMA configuration, aborting\n");
-                       goto err_dma;
+               err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+               if (err) {
+                       err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+                       if (err) {
+                               E1000_ERR("No usable DMA configuration, "
+                                         "aborting\n");
+                               goto err_dma;
+                       }
                }
                pci_using_dac = 0;
        }
 
-       if ((err = pci_request_regions(pdev, e1000_driver_name)))
+       err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
+       if (err)
                goto err_pci_reg;
 
        pci_set_master(pdev);
@@ -928,21 +965,27 @@ e1000_probe(struct pci_dev *pdev,
        adapter = netdev_priv(netdev);
        adapter->netdev = netdev;
        adapter->pdev = pdev;
-       adapter->hw.back = adapter;
        adapter->msg_enable = (1 << debug) - 1;
+       adapter->bars = bars;
+       adapter->need_ioport = need_ioport;
+
+       hw = &adapter->hw;
+       hw->back = adapter;
 
        err = -EIO;
-       adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, BAR_0),
-                                     pci_resource_len(pdev, BAR_0));
-       if (!adapter->hw.hw_addr)
+       hw->hw_addr = ioremap(pci_resource_start(pdev, BAR_0),
+                             pci_resource_len(pdev, BAR_0));
+       if (!hw->hw_addr)
                goto err_ioremap;
 
-       for (i = BAR_1; i <= BAR_5; i++) {
-               if (pci_resource_len(pdev, i) == 0)
-                       continue;
-               if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
-                       adapter->hw.io_base = pci_resource_start(pdev, i);
-                       break;
+       if (adapter->need_ioport) {
+               for (i = BAR_1; i <= BAR_5; i++) {
+                       if (pci_resource_len(pdev, i) == 0)
+                               continue;
+                       if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
+                               hw->io_base = pci_resource_start(pdev, i);
+                               break;
+                       }
                }
        }
 
@@ -957,9 +1000,7 @@ e1000_probe(struct pci_dev *pdev,
        e1000_set_ethtool_ops(netdev);
        netdev->tx_timeout = &e1000_tx_timeout;
        netdev->watchdog_timeo = 5 * HZ;
-#ifdef CONFIG_E1000_NAPI
        netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
-#endif
        netdev->vlan_rx_register = e1000_vlan_rx_register;
        netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
        netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
@@ -972,49 +1013,50 @@ e1000_probe(struct pci_dev *pdev,
 
        /* setup the private structure */
 
-       if ((err = e1000_sw_init(adapter)))
+       err = e1000_sw_init(adapter);
+       if (err)
                goto err_sw_init;
 
        err = -EIO;
        /* Flash BAR mapping must happen after e1000_sw_init
         * because it depends on mac_type */
-       if ((adapter->hw.mac_type == e1000_ich8lan) &&
+       if ((hw->mac_type == e1000_ich8lan) &&
           (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
-               adapter->hw.flash_address =
+               hw->flash_address =
                        ioremap(pci_resource_start(pdev, 1),
                                pci_resource_len(pdev, 1));
-               if (!adapter->hw.flash_address)
+               if (!hw->flash_address)
                        goto err_flashmap;
        }
 
-       if (e1000_check_phy_reset_block(&adapter->hw))
+       if (e1000_check_phy_reset_block(hw))
                DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
 
-       if (adapter->hw.mac_type >= e1000_82543) {
+       if (hw->mac_type >= e1000_82543) {
                netdev->features = NETIF_F_SG |
                                   NETIF_F_HW_CSUM |
                                   NETIF_F_HW_VLAN_TX |
                                   NETIF_F_HW_VLAN_RX |
                                   NETIF_F_HW_VLAN_FILTER;
-               if (adapter->hw.mac_type == e1000_ich8lan)
+               if (hw->mac_type == e1000_ich8lan)
                        netdev->features &= ~NETIF_F_HW_VLAN_FILTER;
        }
 
-       if ((adapter->hw.mac_type >= e1000_82544) &&
-          (adapter->hw.mac_type != e1000_82547))
+       if ((hw->mac_type >= e1000_82544) &&
+          (hw->mac_type != e1000_82547))
                netdev->features |= NETIF_F_TSO;
 
-       if (adapter->hw.mac_type > e1000_82547_rev_2)
+       if (hw->mac_type > e1000_82547_rev_2)
                netdev->features |= NETIF_F_TSO6;
        if (pci_using_dac)
                netdev->features |= NETIF_F_HIGHDMA;
 
        netdev->features |= NETIF_F_LLTX;
 
-       adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
+       adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
 
        /* initialize eeprom parameters */
-       if (e1000_init_eeprom_params(&adapter->hw)) {
+       if (e1000_init_eeprom_params(hw)) {
                E1000_ERR("EEPROM initialization failed\n");
                goto err_eeprom;
        }
@@ -1022,10 +1064,10 @@ e1000_probe(struct pci_dev *pdev,
        /* before reading the EEPROM, reset the controller to
         * put the device in a known good starting state */
 
-       e1000_reset_hw(&adapter->hw);
+       e1000_reset_hw(hw);
 
        /* make sure the EEPROM is good */
-       if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
+       if (e1000_validate_eeprom_checksum(hw) < 0) {
                DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
                e1000_dump_eeprom(adapter);
                /*
@@ -1036,24 +1078,24 @@ e1000_probe(struct pci_dev *pdev,
                 * interface after manually setting a hw addr using
                 * `ip set address`
                 */
-               memset(adapter->hw.mac_addr, 0, netdev->addr_len);
+               memset(hw->mac_addr, 0, netdev->addr_len);
        } else {
                /* copy the MAC address out of the EEPROM */
-               if (e1000_read_mac_addr(&adapter->hw))
+               if (e1000_read_mac_addr(hw))
                        DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
        }
        /* don't block initalization here due to bad MAC address */
-       memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
-       memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
+       memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
+       memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
 
        if (!is_valid_ether_addr(netdev->perm_addr))
                DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
 
-       e1000_get_bus_info(&adapter->hw);
+       e1000_get_bus_info(hw);
 
        init_timer(&adapter->tx_fifo_stall_timer);
        adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
-       adapter->tx_fifo_stall_timer.data = (unsigned long) adapter;
+       adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
 
        init_timer(&adapter->watchdog_timer);
        adapter->watchdog_timer.function = &e1000_watchdog;
@@ -1061,7 +1103,7 @@ e1000_probe(struct pci_dev *pdev,
 
        init_timer(&adapter->phy_info_timer);
        adapter->phy_info_timer.function = &e1000_update_phy_info;
-       adapter->phy_info_timer.data = (unsigned long) adapter;
+       adapter->phy_info_timer.data = (unsigned long)adapter;
 
        INIT_WORK(&adapter->reset_task, e1000_reset_task);
 
@@ -1072,18 +1114,18 @@ e1000_probe(struct pci_dev *pdev,
         * enable the ACPI Magic Packet filter
         */
 
-       switch (adapter->hw.mac_type) {
+       switch (hw->mac_type) {
        case e1000_82542_rev2_0:
        case e1000_82542_rev2_1:
        case e1000_82543:
                break;
        case e1000_82544:
-               e1000_read_eeprom(&adapter->hw,
+               e1000_read_eeprom(hw,
                        EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
                eeprom_apme_mask = E1000_EEPROM_82544_APM;
                break;
        case e1000_ich8lan:
-               e1000_read_eeprom(&adapter->hw,
+               e1000_read_eeprom(hw,
                        EEPROM_INIT_CONTROL1_REG, 1, &eeprom_data);
                eeprom_apme_mask = E1000_EEPROM_ICH8_APME;
                break;
@@ -1091,14 +1133,14 @@ e1000_probe(struct pci_dev *pdev,
        case e1000_82546_rev_3:
        case e1000_82571:
        case e1000_80003es2lan:
-               if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1){
-                       e1000_read_eeprom(&adapter->hw,
+               if (er32(STATUS) & E1000_STATUS_FUNC_1){
+                       e1000_read_eeprom(hw,
                                EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
                        break;
                }
                /* Fall Through */
        default:
-               e1000_read_eeprom(&adapter->hw,
+               e1000_read_eeprom(hw,
                        EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
                break;
        }
@@ -1117,7 +1159,7 @@ e1000_probe(struct pci_dev *pdev,
        case E1000_DEV_ID_82571EB_FIBER:
                /* Wake events only supported on port A for dual fiber
                 * regardless of eeprom setting */
-               if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
+               if (er32(STATUS) & E1000_STATUS_FUNC_1)
                        adapter->eeprom_wol = 0;
                break;
        case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
@@ -1140,8 +1182,6 @@ e1000_probe(struct pci_dev *pdev,
        adapter->wol = adapter->eeprom_wol;
 
        /* print bus type/speed/width info */
-       {
-       struct e1000_hw *hw = &adapter->hw;
        DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
                ((hw->bus_type == e1000_bus_type_pcix) ? "-X" :
                 (hw->bus_type == e1000_bus_type_pci_express ? " Express":"")),
@@ -1154,11 +1194,10 @@ e1000_probe(struct pci_dev *pdev,
                 (hw->bus_width == e1000_bus_width_pciex_4) ? "Width x4" :
                 (hw->bus_width == e1000_bus_width_pciex_1) ? "Width x1" :
                 "32-bit"));
-       }
 
        printk("%s\n", print_mac(mac, netdev->dev_addr));
 
-       if (adapter->hw.bus_type == e1000_bus_type_pci_express) {
+       if (hw->bus_type == e1000_bus_type_pci_express) {
                DPRINTK(PROBE, WARNING, "This device (id %04x:%04x) will no "
                        "longer be supported by this driver in the future.\n",
                        pdev->vendor, pdev->device);
@@ -1173,8 +1212,8 @@ e1000_probe(struct pci_dev *pdev,
         * DRV_LOAD until the interface is up.  For all other cases,
         * let the f/w know that the h/w is now under the control
         * of the driver. */
-       if (adapter->hw.mac_type != e1000_82573 ||
-           !e1000_check_mng_mode(&adapter->hw))
+       if (hw->mac_type != e1000_82573 ||
+           !e1000_check_mng_mode(hw))
                e1000_get_hw_control(adapter);
 
        /* tell the stack to leave us alone until e1000_open() is called */
@@ -1182,7 +1221,8 @@ e1000_probe(struct pci_dev *pdev,
        netif_stop_queue(netdev);
 
        strcpy(netdev->name, "eth%d");
-       if ((err = register_netdev(netdev)))
+       err = register_netdev(netdev);
+       if (err)
                goto err_register;
 
        DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
@@ -1193,28 +1233,24 @@ e1000_probe(struct pci_dev *pdev,
 err_register:
        e1000_release_hw_control(adapter);
 err_eeprom:
-       if (!e1000_check_phy_reset_block(&adapter->hw))
-               e1000_phy_hw_reset(&adapter->hw);
+       if (!e1000_check_phy_reset_block(hw))
+               e1000_phy_hw_reset(hw);
 
-       if (adapter->hw.flash_address)
-               iounmap(adapter->hw.flash_address);
+       if (hw->flash_address)
+               iounmap(hw->flash_address);
 err_flashmap:
-#ifdef CONFIG_E1000_NAPI
        for (i = 0; i < adapter->num_rx_queues; i++)
                dev_put(&adapter->polling_netdev[i]);
-#endif
 
        kfree(adapter->tx_ring);
        kfree(adapter->rx_ring);
-#ifdef CONFIG_E1000_NAPI
        kfree(adapter->polling_netdev);
-#endif
 err_sw_init:
-       iounmap(adapter->hw.hw_addr);
+       iounmap(hw->hw_addr);
 err_ioremap:
        free_netdev(netdev);
 err_alloc_etherdev:
-       pci_release_regions(pdev);
+       pci_release_selected_regions(pdev, bars);
 err_pci_reg:
 err_dma:
        pci_disable_device(pdev);
@@ -1231,14 +1267,12 @@ err_dma:
  * memory.
  **/
 
-static void __devexit
-e1000_remove(struct pci_dev *pdev)
+static void __devexit e1000_remove(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
-#ifdef CONFIG_E1000_NAPI
+       struct e1000_hw *hw = &adapter->hw;
        int i;
-#endif
 
        cancel_work_sync(&adapter->reset_task);
 
@@ -1248,26 +1282,22 @@ e1000_remove(struct pci_dev *pdev)
         * would have already happened in close and is redundant. */
        e1000_release_hw_control(adapter);
 
-#ifdef CONFIG_E1000_NAPI
        for (i = 0; i < adapter->num_rx_queues; i++)
                dev_put(&adapter->polling_netdev[i]);
-#endif
 
        unregister_netdev(netdev);
 
-       if (!e1000_check_phy_reset_block(&adapter->hw))
-               e1000_phy_hw_reset(&adapter->hw);
+       if (!e1000_check_phy_reset_block(hw))
+               e1000_phy_hw_reset(hw);
 
        kfree(adapter->tx_ring);
        kfree(adapter->rx_ring);
-#ifdef CONFIG_E1000_NAPI
        kfree(adapter->polling_netdev);
-#endif
 
-       iounmap(adapter->hw.hw_addr);
-       if (adapter->hw.flash_address)
-               iounmap(adapter->hw.flash_address);
-       pci_release_regions(pdev);
+       iounmap(hw->hw_addr);
+       if (hw->flash_address)
+               iounmap(hw->flash_address);
+       pci_release_selected_regions(pdev, adapter->bars);
 
        free_netdev(netdev);
 
@@ -1283,15 +1313,12 @@ e1000_remove(struct pci_dev *pdev)
  * OS network device settings (MTU size).
  **/
 
-static int __devinit
-e1000_sw_init(struct e1000_adapter *adapter)
+static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
        struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
-#ifdef CONFIG_E1000_NAPI
        int i;
-#endif
 
        /* PCI config space info */
 
@@ -1349,14 +1376,12 @@ e1000_sw_init(struct e1000_adapter *adapter)
                return -ENOMEM;
        }
 
-#ifdef CONFIG_E1000_NAPI
        for (i = 0; i < adapter->num_rx_queues; i++) {
                adapter->polling_netdev[i].priv = adapter;
                dev_hold(&adapter->polling_netdev[i]);
                set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
        }
        spin_lock_init(&adapter->tx_queue_lock);
-#endif
 
        /* Explicitly disable IRQ since the NIC can be in any state. */
        e1000_irq_disable(adapter);
@@ -1377,8 +1402,7 @@ e1000_sw_init(struct e1000_adapter *adapter)
  * intended for Multiqueue, but should work fine with a single queue.
  **/
 
-static int __devinit
-e1000_alloc_queues(struct e1000_adapter *adapter)
+static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
 {
        adapter->tx_ring = kcalloc(adapter->num_tx_queues,
                                   sizeof(struct e1000_tx_ring), GFP_KERNEL);
@@ -1392,7 +1416,6 @@ e1000_alloc_queues(struct e1000_adapter *adapter)
                return -ENOMEM;
        }
 
-#ifdef CONFIG_E1000_NAPI
        adapter->polling_netdev = kcalloc(adapter->num_rx_queues,
                                          sizeof(struct net_device),
                                          GFP_KERNEL);
@@ -1401,7 +1424,6 @@ e1000_alloc_queues(struct e1000_adapter *adapter)
                kfree(adapter->rx_ring);
                return -ENOMEM;
        }
-#endif
 
        return E1000_SUCCESS;
 }
@@ -1419,10 +1441,10 @@ e1000_alloc_queues(struct e1000_adapter *adapter)
  * and the stack is notified that the interface is ready.
  **/
 
-static int
-e1000_open(struct net_device *netdev)
+static int e1000_open(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
        int err;
 
        /* disallow open during test */
@@ -1442,15 +1464,15 @@ e1000_open(struct net_device *netdev)
        e1000_power_up_phy(adapter);
 
        adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
-       if ((adapter->hw.mng_cookie.status &
+       if ((hw->mng_cookie.status &
                          E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
                e1000_update_mng_vlan(adapter);
        }
 
        /* If AMT is enabled, let the firmware know that the network
         * interface is now open */
-       if (adapter->hw.mac_type == e1000_82573 &&
-           e1000_check_mng_mode(&adapter->hw))
+       if (hw->mac_type == e1000_82573 &&
+           e1000_check_mng_mode(hw))
                e1000_get_hw_control(adapter);
 
        /* before we allocate an interrupt, we must be ready to handle it.
@@ -1466,16 +1488,14 @@ e1000_open(struct net_device *netdev)
        /* From here on the code is the same as e1000_up() */
        clear_bit(__E1000_DOWN, &adapter->flags);
 
-#ifdef CONFIG_E1000_NAPI
        napi_enable(&adapter->napi);
-#endif
 
        e1000_irq_enable(adapter);
 
        netif_start_queue(netdev);
 
        /* fire a link status change interrupt to start the watchdog */
-       E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_LSC);
+       ew32(ICS, E1000_ICS_LSC);
 
        return E1000_SUCCESS;
 
@@ -1503,10 +1523,10 @@ err_setup_tx:
  * hardware, and all transmit and receive resources are freed.
  **/
 
-static int
-e1000_close(struct net_device *netdev)
+static int e1000_close(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
 
        WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
        e1000_down(adapter);
@@ -1518,7 +1538,7 @@ e1000_close(struct net_device *netdev)
 
        /* kill manageability vlan ID if supported, but not if a vlan with
         * the same ID is registered on the host OS (let 8021q kill it) */
-       if ((adapter->hw.mng_cookie.status &
+       if ((hw->mng_cookie.status &
                          E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
             !(adapter->vlgrp &&
               vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
@@ -1527,8 +1547,8 @@ e1000_close(struct net_device *netdev)
 
        /* If AMT is enabled, let the firmware know that the network
         * interface is now closed */
-       if (adapter->hw.mac_type == e1000_82573 &&
-           e1000_check_mng_mode(&adapter->hw))
+       if (hw->mac_type == e1000_82573 &&
+           e1000_check_mng_mode(hw))
                e1000_release_hw_control(adapter);
 
        return 0;
@@ -1540,17 +1560,17 @@ e1000_close(struct net_device *netdev)
  * @start: address of beginning of memory
  * @len: length of memory
  **/
-static bool
-e1000_check_64k_bound(struct e1000_adapter *adapter,
-                     void *start, unsigned long len)
+static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
+                                 unsigned long len)
 {
-       unsigned long begin = (unsigned long) start;
+       struct e1000_hw *hw = &adapter->hw;
+       unsigned long begin = (unsigned long)start;
        unsigned long end = begin + len;
 
        /* First rev 82545 and 82546 need to not allow any memory
         * write location to cross 64k boundary due to errata 23 */
-       if (adapter->hw.mac_type == e1000_82545 ||
-           adapter->hw.mac_type == e1000_82546) {
+       if (hw->mac_type == e1000_82545 ||
+           hw->mac_type == e1000_82546) {
                return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
        }
 
@@ -1565,9 +1585,8 @@ e1000_check_64k_bound(struct e1000_adapter *adapter,
  * Return 0 on success, negative on failure
  **/
 
-static int
-e1000_setup_tx_resources(struct e1000_adapter *adapter,
-                         struct e1000_tx_ring *txdr)
+static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
+                                   struct e1000_tx_ring *txdr)
 {
        struct pci_dev *pdev = adapter->pdev;
        int size;
@@ -1641,8 +1660,7 @@ setup_tx_desc_die:
  * Return 0 on success, negative on failure
  **/
 
-int
-e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
+int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
 {
        int i, err = 0;
 
@@ -1668,8 +1686,7 @@ e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
  * Configure the Tx unit of the MAC after a reset.
  **/
 
-static void
-e1000_configure_tx(struct e1000_adapter *adapter)
+static void e1000_configure_tx(struct e1000_adapter *adapter)
 {
        u64 tdba;
        struct e1000_hw *hw = &adapter->hw;
@@ -1684,18 +1701,18 @@ e1000_configure_tx(struct e1000_adapter *adapter)
                tdba = adapter->tx_ring[0].dma;
                tdlen = adapter->tx_ring[0].count *
                        sizeof(struct e1000_tx_desc);
-               E1000_WRITE_REG(hw, TDLEN, tdlen);
-               E1000_WRITE_REG(hw, TDBAH, (tdba >> 32));
-               E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL));
-               E1000_WRITE_REG(hw, TDT, 0);
-               E1000_WRITE_REG(hw, TDH, 0);
+               ew32(TDLEN, tdlen);
+               ew32(TDBAH, (tdba >> 32));
+               ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
+               ew32(TDT, 0);
+               ew32(TDH, 0);
                adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
                adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
                break;
        }
 
        /* Set the default values for the Tx Inter Packet Gap timer */
-       if (adapter->hw.mac_type <= e1000_82547_rev_2 &&
+       if (hw->mac_type <= e1000_82547_rev_2 &&
            (hw->media_type == e1000_media_type_fiber ||
             hw->media_type == e1000_media_type_internal_serdes))
                tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
@@ -1720,34 +1737,34 @@ e1000_configure_tx(struct e1000_adapter *adapter)
        }
        tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
        tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
-       E1000_WRITE_REG(hw, TIPG, tipg);
+       ew32(TIPG, tipg);
 
        /* Set the Tx Interrupt Delay register */
 
-       E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay);
+       ew32(TIDV, adapter->tx_int_delay);
        if (hw->mac_type >= e1000_82540)
-               E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay);
+               ew32(TADV, adapter->tx_abs_int_delay);
 
        /* Program the Transmit Control Register */
 
-       tctl = E1000_READ_REG(hw, TCTL);
+       tctl = er32(TCTL);
        tctl &= ~E1000_TCTL_CT;
        tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
                (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
 
        if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
-               tarc = E1000_READ_REG(hw, TARC0);
+               tarc = er32(TARC0);
                /* set the speed mode bit, we'll clear it if we're not at
                 * gigabit link later */
                tarc |= (1 << 21);
-               E1000_WRITE_REG(hw, TARC0, tarc);
+               ew32(TARC0, tarc);
        } else if (hw->mac_type == e1000_80003es2lan) {
-               tarc = E1000_READ_REG(hw, TARC0);
+               tarc = er32(TARC0);
                tarc |= 1;
-               E1000_WRITE_REG(hw, TARC0, tarc);
-               tarc = E1000_READ_REG(hw, TARC1);
+               ew32(TARC0, tarc);
+               tarc = er32(TARC1);
                tarc |= 1;
-               E1000_WRITE_REG(hw, TARC1, tarc);
+               ew32(TARC1, tarc);
        }
 
        e1000_config_collision_dist(hw);
@@ -1770,7 +1787,7 @@ e1000_configure_tx(struct e1000_adapter *adapter)
            hw->bus_type == e1000_bus_type_pcix)
                adapter->pcix_82544 = 1;
 
-       E1000_WRITE_REG(hw, TCTL, tctl);
+       ew32(TCTL, tctl);
 
 }
 
@@ -1782,10 +1799,10 @@ e1000_configure_tx(struct e1000_adapter *adapter)
  * Returns 0 on success, negative on failure
  **/
 
-static int
-e1000_setup_rx_resources(struct e1000_adapter *adapter,
-                         struct e1000_rx_ring *rxdr)
+static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
+                                   struct e1000_rx_ring *rxdr)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct pci_dev *pdev = adapter->pdev;
        int size, desc_len;
 
@@ -1818,7 +1835,7 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter,
                return -ENOMEM;
        }
 
-       if (adapter->hw.mac_type <= e1000_82547_rev_2)
+       if (hw->mac_type <= e1000_82547_rev_2)
                desc_len = sizeof(struct e1000_rx_desc);
        else
                desc_len = sizeof(union e1000_rx_desc_packet_split);
@@ -1887,8 +1904,7 @@ setup_rx_desc_die:
  * Return 0 on success, negative on failure
  **/
 
-int
-e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
+int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
 {
        int i, err = 0;
 
@@ -1913,24 +1929,24 @@ e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
  **/
 #define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
                        (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
-static void
-e1000_setup_rctl(struct e1000_adapter *adapter)
+static void e1000_setup_rctl(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        u32 rctl, rfctl;
        u32 psrctl = 0;
 #ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
        u32 pages = 0;
 #endif
 
-       rctl = E1000_READ_REG(&adapter->hw, RCTL);
+       rctl = er32(RCTL);
 
        rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
 
        rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
                E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
-               (adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
+               (hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
 
-       if (adapter->hw.tbi_compatibility_on == 1)
+       if (hw->tbi_compatibility_on == 1)
                rctl |= E1000_RCTL_SBP;
        else
                rctl &= ~E1000_RCTL_SBP;
@@ -1983,7 +1999,7 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
        /* allocations using alloc_page take too long for regular MTU
         * so only enable packet split for jumbo frames */
        pages = PAGE_USE_COUNT(adapter->netdev->mtu);
-       if ((adapter->hw.mac_type >= e1000_82571) && (pages <= 3) &&
+       if ((hw->mac_type >= e1000_82571) && (pages <= 3) &&
            PAGE_SIZE <= 16384 && (rctl & E1000_RCTL_LPE))
                adapter->rx_ps_pages = pages;
        else
@@ -1991,14 +2007,14 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
 #endif
        if (adapter->rx_ps_pages) {
                /* Configure extra packet-split registers */
-               rfctl = E1000_READ_REG(&adapter->hw, RFCTL);
+               rfctl = er32(RFCTL);
                rfctl |= E1000_RFCTL_EXTEN;
                /* disable packet split support for IPv6 extension headers,
                 * because some malformed IPv6 headers can hang the RX */
                rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
                          E1000_RFCTL_NEW_IPV6_EXT_DIS);
 
-               E1000_WRITE_REG(&adapter->hw, RFCTL, rfctl);
+               ew32(RFCTL, rfctl);
 
                rctl |= E1000_RCTL_DTYP_PS;
 
@@ -2018,10 +2034,10 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
                        break;
                }
 
-               E1000_WRITE_REG(&adapter->hw, PSRCTL, psrctl);
+               ew32(PSRCTL, psrctl);
        }
 
-       E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+       ew32(RCTL, rctl);
 }
 
 /**
@@ -2031,8 +2047,7 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
  * Configure the Rx unit of the MAC after a reset.
  **/
 
-static void
-e1000_configure_rx(struct e1000_adapter *adapter)
+static void e1000_configure_rx(struct e1000_adapter *adapter)
 {
        u64 rdba;
        struct e1000_hw *hw = &adapter->hw;
@@ -2052,30 +2067,27 @@ e1000_configure_rx(struct e1000_adapter *adapter)
        }
 
        /* disable receives while setting up the descriptors */
-       rctl = E1000_READ_REG(hw, RCTL);
-       E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
+       rctl = er32(RCTL);
+       ew32(RCTL, rctl & ~E1000_RCTL_EN);
 
        /* set the Receive Delay Timer Register */
-       E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
+       ew32(RDTR, adapter->rx_int_delay);
 
        if (hw->mac_type >= e1000_82540) {
-               E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
+               ew32(RADV, adapter->rx_abs_int_delay);
                if (adapter->itr_setting != 0)
-                       E1000_WRITE_REG(hw, ITR,
-                               1000000000 / (adapter->itr * 256));
+                       ew32(ITR, 1000000000 / (adapter->itr * 256));
        }
 
        if (hw->mac_type >= e1000_82571) {
-               ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+               ctrl_ext = er32(CTRL_EXT);
                /* Reset delay timers after every interrupt */
                ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR;
-#ifdef CONFIG_E1000_NAPI
                /* Auto-Mask interrupts upon ICR access */
                ctrl_ext |= E1000_CTRL_EXT_IAME;
-               E1000_WRITE_REG(hw, IAM, 0xffffffff);
-#endif
-               E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-               E1000_WRITE_FLUSH(hw);
+               ew32(IAM, 0xffffffff);
+               ew32(CTRL_EXT, ctrl_ext);
+               E1000_WRITE_FLUSH();
        }
 
        /* Setup the HW Rx Head and Tail Descriptor Pointers and
@@ -2084,11 +2096,11 @@ e1000_configure_rx(struct e1000_adapter *adapter)
        case 1:
        default:
                rdba = adapter->rx_ring[0].dma;
-               E1000_WRITE_REG(hw, RDLEN, rdlen);
-               E1000_WRITE_REG(hw, RDBAH, (rdba >> 32));
-               E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
-               E1000_WRITE_REG(hw, RDT, 0);
-               E1000_WRITE_REG(hw, RDH, 0);
+               ew32(RDLEN, rdlen);
+               ew32(RDBAH, (rdba >> 32));
+               ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
+               ew32(RDT, 0);
+               ew32(RDH, 0);
                adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
                adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
                break;
@@ -2096,7 +2108,7 @@ e1000_configure_rx(struct e1000_adapter *adapter)
 
        /* Enable 82543 Receive Checksum Offload for TCP and UDP */
        if (hw->mac_type >= e1000_82543) {
-               rxcsum = E1000_READ_REG(hw, RXCSUM);
+               rxcsum = er32(RXCSUM);
                if (adapter->rx_csum) {
                        rxcsum |= E1000_RXCSUM_TUOFL;
 
@@ -2110,17 +2122,17 @@ e1000_configure_rx(struct e1000_adapter *adapter)
                        rxcsum &= ~E1000_RXCSUM_TUOFL;
                        /* don't need to clear IPPCSE as it defaults to 0 */
                }
-               E1000_WRITE_REG(hw, RXCSUM, rxcsum);
+               ew32(RXCSUM, rxcsum);
        }
 
        /* enable early receives on 82573, only takes effect if using > 2048
         * byte total frame size.  for example only for jumbo frames */
 #define E1000_ERT_2048 0x100
        if (hw->mac_type == e1000_82573)
-               E1000_WRITE_REG(hw, ERT, E1000_ERT_2048);
+               ew32(ERT, E1000_ERT_2048);
 
        /* Enable Receives */
-       E1000_WRITE_REG(hw, RCTL, rctl);
+       ew32(RCTL, rctl);
 }
 
 /**
@@ -2131,9 +2143,8 @@ e1000_configure_rx(struct e1000_adapter *adapter)
  * Free all transmit software resources
  **/
 
-static void
-e1000_free_tx_resources(struct e1000_adapter *adapter,
-                        struct e1000_tx_ring *tx_ring)
+static void e1000_free_tx_resources(struct e1000_adapter *adapter,
+                                   struct e1000_tx_ring *tx_ring)
 {
        struct pci_dev *pdev = adapter->pdev;
 
@@ -2154,8 +2165,7 @@ e1000_free_tx_resources(struct e1000_adapter *adapter,
  * Free all transmit software resources
  **/
 
-void
-e1000_free_all_tx_resources(struct e1000_adapter *adapter)
+void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
 {
        int i;
 
@@ -2163,9 +2173,8 @@ e1000_free_all_tx_resources(struct e1000_adapter *adapter)
                e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
 }
 
-static void
-e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
-                       struct e1000_buffer *buffer_info)
+static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
+                                            struct e1000_buffer *buffer_info)
 {
        if (buffer_info->dma) {
                pci_unmap_page(adapter->pdev,
@@ -2187,10 +2196,10 @@ e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
  * @tx_ring: ring to be cleaned
  **/
 
-static void
-e1000_clean_tx_ring(struct e1000_adapter *adapter,
-                    struct e1000_tx_ring *tx_ring)
+static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
+                               struct e1000_tx_ring *tx_ring)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct e1000_buffer *buffer_info;
        unsigned long size;
        unsigned int i;
@@ -2213,8 +2222,8 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter,
        tx_ring->next_to_clean = 0;
        tx_ring->last_tx_tso = 0;
 
-       writel(0, adapter->hw.hw_addr + tx_ring->tdh);
-       writel(0, adapter->hw.hw_addr + tx_ring->tdt);
+       writel(0, hw->hw_addr + tx_ring->tdh);
+       writel(0, hw->hw_addr + tx_ring->tdt);
 }
 
 /**
@@ -2222,8 +2231,7 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter,
  * @adapter: board private structure
  **/
 
-static void
-e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
+static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
 {
        int i;
 
@@ -2239,9 +2247,8 @@ e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
  * Free all receive software resources
  **/
 
-static void
-e1000_free_rx_resources(struct e1000_adapter *adapter,
-                        struct e1000_rx_ring *rx_ring)
+static void e1000_free_rx_resources(struct e1000_adapter *adapter,
+                                   struct e1000_rx_ring *rx_ring)
 {
        struct pci_dev *pdev = adapter->pdev;
 
@@ -2266,8 +2273,7 @@ e1000_free_rx_resources(struct e1000_adapter *adapter,
  * Free all receive software resources
  **/
 
-void
-e1000_free_all_rx_resources(struct e1000_adapter *adapter)
+void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
 {
        int i;
 
@@ -2281,10 +2287,10 @@ e1000_free_all_rx_resources(struct e1000_adapter *adapter)
  * @rx_ring: ring to free buffers from
  **/
 
-static void
-e1000_clean_rx_ring(struct e1000_adapter *adapter,
-                    struct e1000_rx_ring *rx_ring)
+static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
+                               struct e1000_rx_ring *rx_ring)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct e1000_buffer *buffer_info;
        struct e1000_ps_page *ps_page;
        struct e1000_ps_page_dma *ps_page_dma;
@@ -2331,8 +2337,8 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter,
        rx_ring->next_to_clean = 0;
        rx_ring->next_to_use = 0;
 
-       writel(0, adapter->hw.hw_addr + rx_ring->rdh);
-       writel(0, adapter->hw.hw_addr + rx_ring->rdt);
+       writel(0, hw->hw_addr + rx_ring->rdh);
+       writel(0, hw->hw_addr + rx_ring->rdt);
 }
 
 /**
@@ -2340,8 +2346,7 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter,
  * @adapter: board private structure
  **/
 
-static void
-e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
+static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
 {
        int i;
 
@@ -2352,38 +2357,38 @@ e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
 /* The 82542 2.0 (revision 2) needs to have the receive unit in reset
  * and memory write and invalidate disabled for certain operations
  */
-static void
-e1000_enter_82542_rst(struct e1000_adapter *adapter)
+static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct net_device *netdev = adapter->netdev;
        u32 rctl;
 
-       e1000_pci_clear_mwi(&adapter->hw);
+       e1000_pci_clear_mwi(hw);
 
-       rctl = E1000_READ_REG(&adapter->hw, RCTL);
+       rctl = er32(RCTL);
        rctl |= E1000_RCTL_RST;
-       E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
-       E1000_WRITE_FLUSH(&adapter->hw);
+       ew32(RCTL, rctl);
+       E1000_WRITE_FLUSH();
        mdelay(5);
 
        if (netif_running(netdev))
                e1000_clean_all_rx_rings(adapter);
 }
 
-static void
-e1000_leave_82542_rst(struct e1000_adapter *adapter)
+static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct net_device *netdev = adapter->netdev;
        u32 rctl;
 
-       rctl = E1000_READ_REG(&adapter->hw, RCTL);
+       rctl = er32(RCTL);
        rctl &= ~E1000_RCTL_RST;
-       E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
-       E1000_WRITE_FLUSH(&adapter->hw);
+       ew32(RCTL, rctl);
+       E1000_WRITE_FLUSH();
        mdelay(5);
 
-       if (adapter->hw.pci_cmd_word & PCI_COMMAND_INVALIDATE)
-               e1000_pci_set_mwi(&adapter->hw);
+       if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
+               e1000_pci_set_mwi(hw);
 
        if (netif_running(netdev)) {
                /* No need to loop, because 82542 supports only 1 queue */
@@ -2401,10 +2406,10 @@ e1000_leave_82542_rst(struct e1000_adapter *adapter)
  * Returns 0 on success, negative on failure
  **/
 
-static int
-e1000_set_mac(struct net_device *netdev, void *p)
+static int e1000_set_mac(struct net_device *netdev, void *p)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
        struct sockaddr *addr = p;
 
        if (!is_valid_ether_addr(addr->sa_data))
@@ -2412,19 +2417,19 @@ e1000_set_mac(struct net_device *netdev, void *p)
 
        /* 82542 2.0 needs to be in reset to write receive address registers */
 
-       if (adapter->hw.mac_type == e1000_82542_rev2_0)
+       if (hw->mac_type == e1000_82542_rev2_0)
                e1000_enter_82542_rst(adapter);
 
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-       memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
+       memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
 
-       e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
+       e1000_rar_set(hw, hw->mac_addr, 0);
 
        /* With 82571 controllers, LAA may be overwritten (with the default)
         * due to controller reset from the other port. */
-       if (adapter->hw.mac_type == e1000_82571) {
+       if (hw->mac_type == e1000_82571) {
                /* activate the work around */
-               adapter->hw.laa_is_present = 1;
+               hw->laa_is_present = 1;
 
                /* Hold a copy of the LAA in RAR[14] This is done so that
                 * between the time RAR[0] gets clobbered  and the time it
@@ -2432,11 +2437,11 @@ e1000_set_mac(struct net_device *netdev, void *p)
                 * of the RARs and no incoming packets directed to this port
                 * are dropped. Eventaully the LAA will be in RAR[0] and
                 * RAR[14] */
-               e1000_rar_set(&adapter->hw, adapter->hw.mac_addr,
+               e1000_rar_set(hw, hw->mac_addr,
                                        E1000_RAR_ENTRIES - 1);
        }
 
-       if (adapter->hw.mac_type == e1000_82542_rev2_0)
+       if (hw->mac_type == e1000_82542_rev2_0)
                e1000_leave_82542_rst(adapter);
 
        return 0;
@@ -2452,8 +2457,7 @@ e1000_set_mac(struct net_device *netdev, void *p)
  * promiscuous mode, and all-multi behavior.
  **/
 
-static void
-e1000_set_rx_mode(struct net_device *netdev)
+static void e1000_set_rx_mode(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
@@ -2466,16 +2470,16 @@ e1000_set_rx_mode(struct net_device *netdev)
                                E1000_NUM_MTA_REGISTERS_ICH8LAN :
                                E1000_NUM_MTA_REGISTERS;
 
-       if (adapter->hw.mac_type == e1000_ich8lan)
+       if (hw->mac_type == e1000_ich8lan)
                rar_entries = E1000_RAR_ENTRIES_ICH8LAN;
 
        /* reserve RAR[14] for LAA over-write work-around */
-       if (adapter->hw.mac_type == e1000_82571)
+       if (hw->mac_type == e1000_82571)
                rar_entries--;
 
        /* Check for Promiscuous and All Multicast modes */
 
-       rctl = E1000_READ_REG(hw, RCTL);
+       rctl = er32(RCTL);
 
        if (netdev->flags & IFF_PROMISC) {
                rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
@@ -2498,7 +2502,7 @@ e1000_set_rx_mode(struct net_device *netdev)
                uc_ptr = netdev->uc_list;
        }
 
-       E1000_WRITE_REG(hw, RCTL, rctl);
+       ew32(RCTL, rctl);
 
        /* 82542 2.0 needs to be in reset to write receive address registers */
 
@@ -2524,9 +2528,9 @@ e1000_set_rx_mode(struct net_device *netdev)
                        mc_ptr = mc_ptr->next;
                } else {
                        E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
-                       E1000_WRITE_FLUSH(hw);
+                       E1000_WRITE_FLUSH();
                        E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
-                       E1000_WRITE_FLUSH(hw);
+                       E1000_WRITE_FLUSH();
                }
        }
        WARN_ON(uc_ptr != NULL);
@@ -2535,7 +2539,7 @@ e1000_set_rx_mode(struct net_device *netdev)
 
        for (i = 0; i < mta_reg_count; i++) {
                E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
-               E1000_WRITE_FLUSH(hw);
+               E1000_WRITE_FLUSH();
        }
 
        /* load any remaining addresses into the hash table */
@@ -2552,11 +2556,11 @@ e1000_set_rx_mode(struct net_device *netdev)
 /* Need to wait a few seconds after link up to get diagnostic information from
  * the phy */
 
-static void
-e1000_update_phy_info(unsigned long data)
+static void e1000_update_phy_info(unsigned long data)
 {
-       struct e1000_adapter *adapter = (struct e1000_adapter *) data;
-       e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
+       struct e1000_adapter *adapter = (struct e1000_adapter *)data;
+       struct e1000_hw *hw = &adapter->hw;
+       e1000_phy_get_info(hw, &adapter->phy_info);
 }
 
 /**
@@ -2564,33 +2568,25 @@ e1000_update_phy_info(unsigned long data)
  * @data: pointer to adapter cast into an unsigned long
  **/
 
-static void
-e1000_82547_tx_fifo_stall(unsigned long data)
+static void e1000_82547_tx_fifo_stall(unsigned long data)
 {
-       struct e1000_adapter *adapter = (struct e1000_adapter *) data;
+       struct e1000_adapter *adapter = (struct e1000_adapter *)data;
+       struct e1000_hw *hw = &adapter->hw;
        struct net_device *netdev = adapter->netdev;
        u32 tctl;
 
        if (atomic_read(&adapter->tx_fifo_stall)) {
-               if ((E1000_READ_REG(&adapter->hw, TDT) ==
-                   E1000_READ_REG(&adapter->hw, TDH)) &&
-                  (E1000_READ_REG(&adapter->hw, TDFT) ==
-                   E1000_READ_REG(&adapter->hw, TDFH)) &&
-                  (E1000_READ_REG(&adapter->hw, TDFTS) ==
-                   E1000_READ_REG(&adapter->hw, TDFHS))) {
-                       tctl = E1000_READ_REG(&adapter->hw, TCTL);
-                       E1000_WRITE_REG(&adapter->hw, TCTL,
-                                       tctl & ~E1000_TCTL_EN);
-                       E1000_WRITE_REG(&adapter->hw, TDFT,
-                                       adapter->tx_head_addr);
-                       E1000_WRITE_REG(&adapter->hw, TDFH,
-                                       adapter->tx_head_addr);
-                       E1000_WRITE_REG(&adapter->hw, TDFTS,
-                                       adapter->tx_head_addr);
-                       E1000_WRITE_REG(&adapter->hw, TDFHS,
-                                       adapter->tx_head_addr);
-                       E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
-                       E1000_WRITE_FLUSH(&adapter->hw);
+               if ((er32(TDT) == er32(TDH)) &&
+                  (er32(TDFT) == er32(TDFH)) &&
+                  (er32(TDFTS) == er32(TDFHS))) {
+                       tctl = er32(TCTL);
+                       ew32(TCTL, tctl & ~E1000_TCTL_EN);
+                       ew32(TDFT, adapter->tx_head_addr);
+                       ew32(TDFH, adapter->tx_head_addr);
+                       ew32(TDFTS, adapter->tx_head_addr);
+                       ew32(TDFHS, adapter->tx_head_addr);
+                       ew32(TCTL, tctl);
+                       E1000_WRITE_FLUSH();
 
                        adapter->tx_fifo_head = 0;
                        atomic_set(&adapter->tx_fifo_stall, 0);
@@ -2605,45 +2601,45 @@ e1000_82547_tx_fifo_stall(unsigned long data)
  * e1000_watchdog - Timer Call-back
  * @data: pointer to adapter cast into an unsigned long
  **/
-static void
-e1000_watchdog(unsigned long data)
+static void e1000_watchdog(unsigned long data)
 {
-       struct e1000_adapter *adapter = (struct e1000_adapter *) data;
+       struct e1000_adapter *adapter = (struct e1000_adapter *)data;
+       struct e1000_hw *hw = &adapter->hw;
        struct net_device *netdev = adapter->netdev;
        struct e1000_tx_ring *txdr = adapter->tx_ring;
        u32 link, tctl;
        s32 ret_val;
 
-       ret_val = e1000_check_for_link(&adapter->hw);
+       ret_val = e1000_check_for_link(hw);
        if ((ret_val == E1000_ERR_PHY) &&
-           (adapter->hw.phy_type == e1000_phy_igp_3) &&
-           (E1000_READ_REG(&adapter->hw, CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
+           (hw->phy_type == e1000_phy_igp_3) &&
+           (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
                /* See e1000_kumeran_lock_loss_workaround() */
                DPRINTK(LINK, INFO,
                        "Gigabit has been disabled, downgrading speed\n");
        }
 
-       if (adapter->hw.mac_type == e1000_82573) {
-               e1000_enable_tx_pkt_filtering(&adapter->hw);
-               if (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id)
+       if (hw->mac_type == e1000_82573) {
+               e1000_enable_tx_pkt_filtering(hw);
+               if (adapter->mng_vlan_id != hw->mng_cookie.vlan_id)
                        e1000_update_mng_vlan(adapter);
        }
 
-       if ((adapter->hw.media_type == e1000_media_type_internal_serdes) &&
-          !(E1000_READ_REG(&adapter->hw, TXCW) & E1000_TXCW_ANE))
-               link = !adapter->hw.serdes_link_down;
+       if ((hw->media_type == e1000_media_type_internal_serdes) &&
+          !(er32(TXCW) & E1000_TXCW_ANE))
+               link = !hw->serdes_link_down;
        else
-               link = E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU;
+               link = er32(STATUS) & E1000_STATUS_LU;
 
        if (link) {
                if (!netif_carrier_ok(netdev)) {
                        u32 ctrl;
                        bool txb2b = true;
-                       e1000_get_speed_and_duplex(&adapter->hw,
+                       e1000_get_speed_and_duplex(hw,
                                                   &adapter->link_speed,
                                                   &adapter->link_duplex);
 
-                       ctrl = E1000_READ_REG(&adapter->hw, CTRL);
+                       ctrl = er32(CTRL);
                        DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s, "
                                "Flow Control: %s\n",
                                adapter->link_speed,
@@ -2671,19 +2667,19 @@ e1000_watchdog(unsigned long data)
                                break;
                        }
 
-                       if ((adapter->hw.mac_type == e1000_82571 ||
-                            adapter->hw.mac_type == e1000_82572) &&
+                       if ((hw->mac_type == e1000_82571 ||
+                            hw->mac_type == e1000_82572) &&
                            !txb2b) {
                                u32 tarc0;
-                               tarc0 = E1000_READ_REG(&adapter->hw, TARC0);
+                               tarc0 = er32(TARC0);
                                tarc0 &= ~(1 << 21);
-                               E1000_WRITE_REG(&adapter->hw, TARC0, tarc0);
+                               ew32(TARC0, tarc0);
                        }
 
                        /* disable TSO for pcie and 10/100 speeds, to avoid
                         * some hardware issues */
                        if (!adapter->tso_force &&
-                           adapter->hw.bus_type == e1000_bus_type_pci_express){
+                           hw->bus_type == e1000_bus_type_pci_express){
                                switch (adapter->link_speed) {
                                case SPEED_10:
                                case SPEED_100:
@@ -2704,9 +2700,9 @@ e1000_watchdog(unsigned long data)
 
                        /* enable transmits in the hardware, need to do this
                         * after setting TARC0 */
-                       tctl = E1000_READ_REG(&adapter->hw, TCTL);
+                       tctl = er32(TCTL);
                        tctl |= E1000_TCTL_EN;
-                       E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
+                       ew32(TCTL, tctl);
 
                        netif_carrier_on(netdev);
                        netif_wake_queue(netdev);
@@ -2714,10 +2710,9 @@ e1000_watchdog(unsigned long data)
                        adapter->smartspeed = 0;
                } else {
                        /* make sure the receive unit is started */
-                       if (adapter->hw.rx_needs_kicking) {
-                               struct e1000_hw *hw = &adapter->hw;
-                               u32 rctl = E1000_READ_REG(hw, RCTL);
-                               E1000_WRITE_REG(hw, RCTL, rctl | E1000_RCTL_EN);
+                       if (hw->rx_needs_kicking) {
+                               u32 rctl = er32(RCTL);
+                               ew32(RCTL, rctl | E1000_RCTL_EN);
                        }
                }
        } else {
@@ -2734,7 +2729,7 @@ e1000_watchdog(unsigned long data)
                         * disable receives in the ISR and
                         * reset device here in the watchdog
                         */
-                       if (adapter->hw.mac_type == e1000_80003es2lan)
+                       if (hw->mac_type == e1000_80003es2lan)
                                /* reset device */
                                schedule_work(&adapter->reset_task);
                }
@@ -2744,9 +2739,9 @@ e1000_watchdog(unsigned long data)
 
        e1000_update_stats(adapter);
 
-       adapter->hw.tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
+       hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
        adapter->tpt_old = adapter->stats.tpt;
-       adapter->hw.collision_delta = adapter->stats.colc - adapter->colc_old;
+       hw->collision_delta = adapter->stats.colc - adapter->colc_old;
        adapter->colc_old = adapter->stats.colc;
 
        adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
@@ -2754,7 +2749,7 @@ e1000_watchdog(unsigned long data)
        adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
        adapter->gotcl_old = adapter->stats.gotcl;
 
-       e1000_update_adaptive(&adapter->hw);
+       e1000_update_adaptive(hw);
 
        if (!netif_carrier_ok(netdev)) {
                if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
@@ -2768,15 +2763,15 @@ e1000_watchdog(unsigned long data)
        }
 
        /* Cause software interrupt to ensure rx ring is cleaned */
-       E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0);
+       ew32(ICS, E1000_ICS_RXDMT0);
 
        /* Force detection of hung controller every watchdog period */
        adapter->detect_tx_hung = true;
 
        /* With 82571 controllers, LAA may be overwritten due to controller
         * reset from the other port. Set the appropriate LAA in RAR[0] */
-       if (adapter->hw.mac_type == e1000_82571 && adapter->hw.laa_is_present)
-               e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
+       if (hw->mac_type == e1000_82571 && hw->laa_is_present)
+               e1000_rar_set(hw, hw->mac_addr, 0);
 
        /* Reset the timer */
        mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
@@ -2806,9 +2801,7 @@ enum latency_range {
  * @bytes: the number of bytes during this measurement interval
  **/
 static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
-                                   u16 itr_setting,
-                                   int packets,
-                                   int bytes)
+                                    u16 itr_setting, int packets, int bytes)
 {
        unsigned int retval = itr_setting;
        struct e1000_hw *hw = &adapter->hw;
@@ -2913,7 +2906,7 @@ set_itr_now:
                             min(adapter->itr + (new_itr >> 2), new_itr) :
                             new_itr;
                adapter->itr = new_itr;
-               E1000_WRITE_REG(hw, ITR, 1000000000 / (new_itr * 256));
+               ew32(ITR, 1000000000 / (new_itr * 256));
        }
 
        return;
@@ -2926,9 +2919,8 @@ set_itr_now:
 #define E1000_TX_FLAGS_VLAN_MASK       0xffff0000
 #define E1000_TX_FLAGS_VLAN_SHIFT      16
 
-static int
-e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
-          struct sk_buff *skb)
+static int e1000_tso(struct e1000_adapter *adapter,
+                    struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
 {
        struct e1000_context_desc *context_desc;
        struct e1000_buffer *buffer_info;
@@ -2999,9 +2991,8 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
        return false;
 }
 
-static bool
-e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
-              struct sk_buff *skb)
+static bool e1000_tx_csum(struct e1000_adapter *adapter,
+                         struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
 {
        struct e1000_context_desc *context_desc;
        struct e1000_buffer *buffer_info;
@@ -3038,11 +3029,13 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
 #define E1000_MAX_TXD_PWR      12
 #define E1000_MAX_DATA_PER_TXD (1<<E1000_MAX_TXD_PWR)
 
-static int
-e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
-             struct sk_buff *skb, unsigned int first, unsigned int max_per_txd,
-             unsigned int nr_frags, unsigned int mss)
+static int e1000_tx_map(struct e1000_adapter *adapter,
+                       struct e1000_tx_ring *tx_ring,
+                       struct sk_buff *skb, unsigned int first,
+                       unsigned int max_per_txd, unsigned int nr_frags,
+                       unsigned int mss)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct e1000_buffer *buffer_info;
        unsigned int len = skb->len;
        unsigned int offset = 0, size, count = 0, i;
@@ -3073,7 +3066,7 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
                 * The fix is to make sure that the first descriptor of a
                 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
                 */
-               if (unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
+               if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
                                (size > 2015) && count == 0))
                        size = 2015;
 
@@ -3145,10 +3138,11 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
        return count;
 }
 
-static void
-e1000_tx_queue(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
-               int tx_flags, int count)
+static void e1000_tx_queue(struct e1000_adapter *adapter,
+                          struct e1000_tx_ring *tx_ring, int tx_flags,
+                          int count)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct e1000_tx_desc *tx_desc = NULL;
        struct e1000_buffer *buffer_info;
        u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
@@ -3194,7 +3188,7 @@ e1000_tx_queue(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
        wmb();
 
        tx_ring->next_to_use = i;
-       writel(i, adapter->hw.hw_addr + tx_ring->tdt);
+       writel(i, hw->hw_addr + tx_ring->tdt);
        /* we need this if more than one processor can write to our tail
         * at a time, it syncronizes IO on IA64/Altix systems */
        mmiowb();
@@ -3212,8 +3206,8 @@ e1000_tx_queue(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
 #define E1000_FIFO_HDR                 0x10
 #define E1000_82547_PAD_LEN            0x3E0
 
-static int
-e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb)
+static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
+                                      struct sk_buff *skb)
 {
        u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
        u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
@@ -3239,19 +3233,19 @@ no_fifo_stall_required:
 }
 
 #define MINIMUM_DHCP_PACKET_SIZE 282
-static int
-e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb)
+static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
+                                   struct sk_buff *skb)
 {
        struct e1000_hw *hw =  &adapter->hw;
        u16 length, offset;
        if (vlan_tx_tag_present(skb)) {
-               if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
-                       ( adapter->hw.mng_cookie.status &
+               if (!((vlan_tx_tag_get(skb) == hw->mng_cookie.vlan_id) &&
+                       ( hw->mng_cookie.status &
                          E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
                        return 0;
        }
        if (skb->len > MINIMUM_DHCP_PACKET_SIZE) {
-               struct ethhdr *eth = (struct ethhdr *) skb->data;
+               struct ethhdr *eth = (struct ethhdr *)skb->data;
                if ((htons(ETH_P_IP) == eth->h_proto)) {
                        const struct iphdr *ip =
                                (struct iphdr *)((u8 *)skb->data+14);
@@ -3304,10 +3298,10 @@ static int e1000_maybe_stop_tx(struct net_device *netdev,
 }
 
 #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
-static int
-e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
        struct e1000_tx_ring *tx_ring;
        unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
        unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
@@ -3333,7 +3327,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
        /* 82571 and newer doesn't need the workaround that limited descriptor
         * length to 4kB */
-       if (adapter->hw.mac_type >= e1000_82571)
+       if (hw->mac_type >= e1000_82571)
                max_per_txd = 8192;
 
        mss = skb_shinfo(skb)->gso_size;
@@ -3353,7 +3347,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                * frags into skb->data */
                hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
                if (skb->data_len && hdr_len == len) {
-                       switch (adapter->hw.mac_type) {
+                       switch (hw->mac_type) {
                                unsigned int pull_size;
                        case e1000_82544:
                                /* Make sure we have room to chop off 4 bytes,
@@ -3402,7 +3396,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        /* work-around for errata 10 and it applies to all controllers
         * in PCI-X mode, so add one more descriptor to the count
         */
-       if (unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
+       if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
                        (len > 2015)))
                count++;
 
@@ -3414,8 +3408,8 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                count += nr_frags;
 
 
-       if (adapter->hw.tx_pkt_filtering &&
-           (adapter->hw.mac_type == e1000_82573))
+       if (hw->tx_pkt_filtering &&
+           (hw->mac_type == e1000_82573))
                e1000_transfer_dhcp_info(adapter, skb);
 
        if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags))
@@ -3429,7 +3423,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                return NETDEV_TX_BUSY;
        }
 
-       if (unlikely(adapter->hw.mac_type == e1000_82547)) {
+       if (unlikely(hw->mac_type == e1000_82547)) {
                if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
                        netif_stop_queue(netdev);
                        mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
@@ -3482,8 +3476,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
  * @netdev: network interface device structure
  **/
 
-static void
-e1000_tx_timeout(struct net_device *netdev)
+static void e1000_tx_timeout(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
 
@@ -3492,8 +3485,7 @@ e1000_tx_timeout(struct net_device *netdev)
        schedule_work(&adapter->reset_task);
 }
 
-static void
-e1000_reset_task(struct work_struct *work)
+static void e1000_reset_task(struct work_struct *work)
 {
        struct e1000_adapter *adapter =
                container_of(work, struct e1000_adapter, reset_task);
@@ -3509,8 +3501,7 @@ e1000_reset_task(struct work_struct *work)
  * The statistics are actually updated from the timer callback.
  **/
 
-static struct net_device_stats *
-e1000_get_stats(struct net_device *netdev)
+static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
 
@@ -3526,10 +3517,10 @@ e1000_get_stats(struct net_device *netdev)
  * Returns 0 on success, negative on failure
  **/
 
-static int
-e1000_change_mtu(struct net_device *netdev, int new_mtu)
+static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
        int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
        u16 eeprom_data = 0;
 
@@ -3540,7 +3531,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
        }
 
        /* Adapter-specific max frame size limits. */
-       switch (adapter->hw.mac_type) {
+       switch (hw->mac_type) {
        case e1000_undefined ... e1000_82542_rev2_1:
        case e1000_ich8lan:
                if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
@@ -3552,9 +3543,9 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
                /* Jumbo Frames not supported if:
                 * - this is not an 82573L device
                 * - ASPM is enabled in any way (0x1A bits 3:2) */
-               e1000_read_eeprom(&adapter->hw, EEPROM_INIT_3GIO_3, 1,
+               e1000_read_eeprom(hw, EEPROM_INIT_3GIO_3, 1,
                                  &eeprom_data);
-               if ((adapter->hw.device_id != E1000_DEV_ID_82573L) ||
+               if ((hw->device_id != E1000_DEV_ID_82573L) ||
                    (eeprom_data & EEPROM_WORD1A_ASPM_MASK)) {
                        if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
                                DPRINTK(PROBE, ERR,
@@ -3601,13 +3592,13 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
                adapter->rx_buffer_len = E1000_RXBUFFER_16384;
 
        /* adjust allocation if LPE protects us, and we aren't using SBP */
-       if (!adapter->hw.tbi_compatibility_on &&
+       if (!hw->tbi_compatibility_on &&
            ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) ||
             (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
                adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
 
        netdev->mtu = new_mtu;
-       adapter->hw.max_frame_size = max_frame;
+       hw->max_frame_size = max_frame;
 
        if (netif_running(netdev))
                e1000_reinit_locked(adapter);
@@ -3620,8 +3611,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu)
  * @adapter: board private structure
  **/
 
-void
-e1000_update_stats(struct e1000_adapter *adapter)
+void e1000_update_stats(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
        struct pci_dev *pdev = adapter->pdev;
@@ -3646,89 +3636,89 @@ e1000_update_stats(struct e1000_adapter *adapter)
         * be written while holding adapter->stats_lock
         */
 
-       adapter->stats.crcerrs += E1000_READ_REG(hw, CRCERRS);
-       adapter->stats.gprc += E1000_READ_REG(hw, GPRC);
-       adapter->stats.gorcl += E1000_READ_REG(hw, GORCL);
-       adapter->stats.gorch += E1000_READ_REG(hw, GORCH);
-       adapter->stats.bprc += E1000_READ_REG(hw, BPRC);
-       adapter->stats.mprc += E1000_READ_REG(hw, MPRC);
-       adapter->stats.roc += E1000_READ_REG(hw, ROC);
-
-       if (adapter->hw.mac_type != e1000_ich8lan) {
-               adapter->stats.prc64 += E1000_READ_REG(hw, PRC64);
-               adapter->stats.prc127 += E1000_READ_REG(hw, PRC127);
-               adapter->stats.prc255 += E1000_READ_REG(hw, PRC255);
-               adapter->stats.prc511 += E1000_READ_REG(hw, PRC511);
-               adapter->stats.prc1023 += E1000_READ_REG(hw, PRC1023);
-               adapter->stats.prc1522 += E1000_READ_REG(hw, PRC1522);
-       }
-
-       adapter->stats.symerrs += E1000_READ_REG(hw, SYMERRS);
-       adapter->stats.mpc += E1000_READ_REG(hw, MPC);
-       adapter->stats.scc += E1000_READ_REG(hw, SCC);
-       adapter->stats.ecol += E1000_READ_REG(hw, ECOL);
-       adapter->stats.mcc += E1000_READ_REG(hw, MCC);
-       adapter->stats.latecol += E1000_READ_REG(hw, LATECOL);
-       adapter->stats.dc += E1000_READ_REG(hw, DC);
-       adapter->stats.sec += E1000_READ_REG(hw, SEC);
-       adapter->stats.rlec += E1000_READ_REG(hw, RLEC);
-       adapter->stats.xonrxc += E1000_READ_REG(hw, XONRXC);
-       adapter->stats.xontxc += E1000_READ_REG(hw, XONTXC);
-       adapter->stats.xoffrxc += E1000_READ_REG(hw, XOFFRXC);
-       adapter->stats.xofftxc += E1000_READ_REG(hw, XOFFTXC);
-       adapter->stats.fcruc += E1000_READ_REG(hw, FCRUC);
-       adapter->stats.gptc += E1000_READ_REG(hw, GPTC);
-       adapter->stats.gotcl += E1000_READ_REG(hw, GOTCL);
-       adapter->stats.gotch += E1000_READ_REG(hw, GOTCH);
-       adapter->stats.rnbc += E1000_READ_REG(hw, RNBC);
-       adapter->stats.ruc += E1000_READ_REG(hw, RUC);
-       adapter->stats.rfc += E1000_READ_REG(hw, RFC);
-       adapter->stats.rjc += E1000_READ_REG(hw, RJC);
-       adapter->stats.torl += E1000_READ_REG(hw, TORL);
-       adapter->stats.torh += E1000_READ_REG(hw, TORH);
-       adapter->stats.totl += E1000_READ_REG(hw, TOTL);
-       adapter->stats.toth += E1000_READ_REG(hw, TOTH);
-       adapter->stats.tpr += E1000_READ_REG(hw, TPR);
-
-       if (adapter->hw.mac_type != e1000_ich8lan) {
-               adapter->stats.ptc64 += E1000_READ_REG(hw, PTC64);
-               adapter->stats.ptc127 += E1000_READ_REG(hw, PTC127);
-               adapter->stats.ptc255 += E1000_READ_REG(hw, PTC255);
-               adapter->stats.ptc511 += E1000_READ_REG(hw, PTC511);
-               adapter->stats.ptc1023 += E1000_READ_REG(hw, PTC1023);
-               adapter->stats.ptc1522 += E1000_READ_REG(hw, PTC1522);
-       }
-
-       adapter->stats.mptc += E1000_READ_REG(hw, MPTC);
-       adapter->stats.bptc += E1000_READ_REG(hw, BPTC);
+       adapter->stats.crcerrs += er32(CRCERRS);
+       adapter->stats.gprc += er32(GPRC);
+       adapter->stats.gorcl += er32(GORCL);
+       adapter->stats.gorch += er32(GORCH);
+       adapter->stats.bprc += er32(BPRC);
+       adapter->stats.mprc += er32(MPRC);
+       adapter->stats.roc += er32(ROC);
+
+       if (hw->mac_type != e1000_ich8lan) {
+               adapter->stats.prc64 += er32(PRC64);
+               adapter->stats.prc127 += er32(PRC127);
+               adapter->stats.prc255 += er32(PRC255);
+               adapter->stats.prc511 += er32(PRC511);
+               adapter->stats.prc1023 += er32(PRC1023);
+               adapter->stats.prc1522 += er32(PRC1522);
+       }
+
+       adapter->stats.symerrs += er32(SYMERRS);
+       adapter->stats.mpc += er32(MPC);
+       adapter->stats.scc += er32(SCC);
+       adapter->stats.ecol += er32(ECOL);
+       adapter->stats.mcc += er32(MCC);
+       adapter->stats.latecol += er32(LATECOL);
+       adapter->stats.dc += er32(DC);
+       adapter->stats.sec += er32(SEC);
+       adapter->stats.rlec += er32(RLEC);
+       adapter->stats.xonrxc += er32(XONRXC);
+       adapter->stats.xontxc += er32(XONTXC);
+       adapter->stats.xoffrxc += er32(XOFFRXC);
+       adapter->stats.xofftxc += er32(XOFFTXC);
+       adapter->stats.fcruc += er32(FCRUC);
+       adapter->stats.gptc += er32(GPTC);
+       adapter->stats.gotcl += er32(GOTCL);
+       adapter->stats.gotch += er32(GOTCH);
+       adapter->stats.rnbc += er32(RNBC);
+       adapter->stats.ruc += er32(RUC);
+       adapter->stats.rfc += er32(RFC);
+       adapter->stats.rjc += er32(RJC);
+       adapter->stats.torl += er32(TORL);
+       adapter->stats.torh += er32(TORH);
+       adapter->stats.totl += er32(TOTL);
+       adapter->stats.toth += er32(TOTH);
+       adapter->stats.tpr += er32(TPR);
+
+       if (hw->mac_type != e1000_ich8lan) {
+               adapter->stats.ptc64 += er32(PTC64);
+               adapter->stats.ptc127 += er32(PTC127);
+               adapter->stats.ptc255 += er32(PTC255);
+               adapter->stats.ptc511 += er32(PTC511);
+               adapter->stats.ptc1023 += er32(PTC1023);
+               adapter->stats.ptc1522 += er32(PTC1522);
+       }
+
+       adapter->stats.mptc += er32(MPTC);
+       adapter->stats.bptc += er32(BPTC);
 
        /* used for adaptive IFS */
 
-       hw->tx_packet_delta = E1000_READ_REG(hw, TPT);
+       hw->tx_packet_delta = er32(TPT);
        adapter->stats.tpt += hw->tx_packet_delta;
-       hw->collision_delta = E1000_READ_REG(hw, COLC);
+       hw->collision_delta = er32(COLC);
        adapter->stats.colc += hw->collision_delta;
 
        if (hw->mac_type >= e1000_82543) {
-               adapter->stats.algnerrc += E1000_READ_REG(hw, ALGNERRC);
-               adapter->stats.rxerrc += E1000_READ_REG(hw, RXERRC);
-               adapter->stats.tncrs += E1000_READ_REG(hw, TNCRS);
-               adapter->stats.cexterr += E1000_READ_REG(hw, CEXTERR);
-               adapter->stats.tsctc += E1000_READ_REG(hw, TSCTC);
-               adapter->stats.tsctfc += E1000_READ_REG(hw, TSCTFC);
+               adapter->stats.algnerrc += er32(ALGNERRC);
+               adapter->stats.rxerrc += er32(RXERRC);
+               adapter->stats.tncrs += er32(TNCRS);
+               adapter->stats.cexterr += er32(CEXTERR);
+               adapter->stats.tsctc += er32(TSCTC);
+               adapter->stats.tsctfc += er32(TSCTFC);
        }
        if (hw->mac_type > e1000_82547_rev_2) {
-               adapter->stats.iac += E1000_READ_REG(hw, IAC);
-               adapter->stats.icrxoc += E1000_READ_REG(hw, ICRXOC);
-
-               if (adapter->hw.mac_type != e1000_ich8lan) {
-                       adapter->stats.icrxptc += E1000_READ_REG(hw, ICRXPTC);
-                       adapter->stats.icrxatc += E1000_READ_REG(hw, ICRXATC);
-                       adapter->stats.ictxptc += E1000_READ_REG(hw, ICTXPTC);
-                       adapter->stats.ictxatc += E1000_READ_REG(hw, ICTXATC);
-                       adapter->stats.ictxqec += E1000_READ_REG(hw, ICTXQEC);
-                       adapter->stats.ictxqmtc += E1000_READ_REG(hw, ICTXQMTC);
-                       adapter->stats.icrxdmtc += E1000_READ_REG(hw, ICRXDMTC);
+               adapter->stats.iac += er32(IAC);
+               adapter->stats.icrxoc += er32(ICRXOC);
+
+               if (hw->mac_type != e1000_ich8lan) {
+                       adapter->stats.icrxptc += er32(ICRXPTC);
+                       adapter->stats.icrxatc += er32(ICRXATC);
+                       adapter->stats.ictxptc += er32(ICTXPTC);
+                       adapter->stats.ictxatc += er32(ICTXATC);
+                       adapter->stats.ictxqec += er32(ICTXQEC);
+                       adapter->stats.ictxqmtc += er32(ICTXQMTC);
+                       adapter->stats.icrxdmtc += er32(ICRXDMTC);
                }
        }
 
@@ -3756,7 +3746,7 @@ e1000_update_stats(struct e1000_adapter *adapter)
        adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
        adapter->net_stats.tx_window_errors = adapter->stats.latecol;
        adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
-       if (adapter->hw.bad_tx_carr_stats_fd &&
+       if (hw->bad_tx_carr_stats_fd &&
            adapter->link_duplex == FULL_DUPLEX) {
                adapter->net_stats.tx_carrier_errors = 0;
                adapter->stats.tncrs = 0;
@@ -3779,10 +3769,10 @@ e1000_update_stats(struct e1000_adapter *adapter)
        }
 
        /* Management Stats */
-       if (adapter->hw.has_smbus) {
-               adapter->stats.mgptc += E1000_READ_REG(hw, MGTPTC);
-               adapter->stats.mgprc += E1000_READ_REG(hw, MGTPRC);
-               adapter->stats.mgpdc += E1000_READ_REG(hw, MGTPDC);
+       if (hw->has_smbus) {
+               adapter->stats.mgptc += er32(MGTPTC);
+               adapter->stats.mgprc += er32(MGTPRC);
+               adapter->stats.mgpdc += er32(MGTPDC);
        }
 
        spin_unlock_irqrestore(&adapter->stats_lock, flags);
@@ -3794,16 +3784,12 @@ e1000_update_stats(struct e1000_adapter *adapter)
  * @data: pointer to a network interface device structure
  **/
 
-static irqreturn_t
-e1000_intr_msi(int irq, void *data)
+static irqreturn_t e1000_intr_msi(int irq, void *data)
 {
        struct net_device *netdev = data;
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
-#ifndef CONFIG_E1000_NAPI
-       int i;
-#endif
-       u32 icr = E1000_READ_REG(hw, ICR);
+       u32 icr = er32(ICR);
 
        /* in NAPI mode read ICR disables interrupts using IAM */
 
@@ -3813,17 +3799,16 @@ e1000_intr_msi(int irq, void *data)
                 * link down event; disable receives here in the ISR and reset
                 * adapter in watchdog */
                if (netif_carrier_ok(netdev) &&
-                   (adapter->hw.mac_type == e1000_80003es2lan)) {
+                   (hw->mac_type == e1000_80003es2lan)) {
                        /* disable receives */
-                       u32 rctl = E1000_READ_REG(hw, RCTL);
-                       E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
+                       u32 rctl = er32(RCTL);
+                       ew32(RCTL, rctl & ~E1000_RCTL_EN);
                }
                /* guard against interrupt when we're going down */
                if (!test_bit(__E1000_DOWN, &adapter->flags))
                        mod_timer(&adapter->watchdog_timer, jiffies + 1);
        }
 
-#ifdef CONFIG_E1000_NAPI
        if (likely(netif_rx_schedule_prep(netdev, &adapter->napi))) {
                adapter->total_tx_bytes = 0;
                adapter->total_tx_packets = 0;
@@ -3832,20 +3817,6 @@ e1000_intr_msi(int irq, void *data)
                __netif_rx_schedule(netdev, &adapter->napi);
        } else
                e1000_irq_enable(adapter);
-#else
-       adapter->total_tx_bytes = 0;
-       adapter->total_rx_bytes = 0;
-       adapter->total_tx_packets = 0;
-       adapter->total_rx_packets = 0;
-
-       for (i = 0; i < E1000_MAX_INTR; i++)
-               if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
-                  !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
-                       break;
-
-       if (likely(adapter->itr_setting & 3))
-               e1000_set_itr(adapter);
-#endif
 
        return IRQ_HANDLED;
 }
@@ -3856,20 +3827,16 @@ e1000_intr_msi(int irq, void *data)
  * @data: pointer to a network interface device structure
  **/
 
-static irqreturn_t
-e1000_intr(int irq, void *data)
+static irqreturn_t e1000_intr(int irq, void *data)
 {
        struct net_device *netdev = data;
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
-       u32 rctl, icr = E1000_READ_REG(hw, ICR);
-#ifndef CONFIG_E1000_NAPI
-       int i;
-#endif
+       u32 rctl, icr = er32(ICR);
+
        if (unlikely(!icr))
                return IRQ_NONE;  /* Not our interrupt */
 
-#ifdef CONFIG_E1000_NAPI
        /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
         * not set, then the adapter didn't send an interrupt */
        if (unlikely(hw->mac_type >= e1000_82571 &&
@@ -3878,7 +3845,6 @@ e1000_intr(int irq, void *data)
 
        /* Interrupt Auto-Mask...upon reading ICR, interrupts are masked.  No
         * need for the IMC write */
-#endif
 
        if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
                hw->get_link_status = 1;
@@ -3888,21 +3854,20 @@ e1000_intr(int irq, void *data)
                 * reset adapter in watchdog
                 */
                if (netif_carrier_ok(netdev) &&
-                   (adapter->hw.mac_type == e1000_80003es2lan)) {
+                   (hw->mac_type == e1000_80003es2lan)) {
                        /* disable receives */
-                       rctl = E1000_READ_REG(hw, RCTL);
-                       E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
+                       rctl = er32(RCTL);
+                       ew32(RCTL, rctl & ~E1000_RCTL_EN);
                }
                /* guard against interrupt when we're going down */
                if (!test_bit(__E1000_DOWN, &adapter->flags))
                        mod_timer(&adapter->watchdog_timer, jiffies + 1);
        }
 
-#ifdef CONFIG_E1000_NAPI
        if (unlikely(hw->mac_type < e1000_82571)) {
                /* disable interrupts, without the synchronize_irq bit */
-               E1000_WRITE_REG(hw, IMC, ~0);
-               E1000_WRITE_FLUSH(hw);
+               ew32(IMC, ~0);
+               E1000_WRITE_FLUSH();
        }
        if (likely(netif_rx_schedule_prep(netdev, &adapter->napi))) {
                adapter->total_tx_bytes = 0;
@@ -3914,48 +3879,15 @@ e1000_intr(int irq, void *data)
                /* this really should not happen! if it does it is basically a
                 * bug, but not a hard error, so enable ints and continue */
                e1000_irq_enable(adapter);
-#else
-       /* Writing IMC and IMS is needed for 82547.
-        * Due to Hub Link bus being occupied, an interrupt
-        * de-assertion message is not able to be sent.
-        * When an interrupt assertion message is generated later,
-        * two messages are re-ordered and sent out.
-        * That causes APIC to think 82547 is in de-assertion
-        * state, while 82547 is in assertion state, resulting
-        * in dead lock. Writing IMC forces 82547 into
-        * de-assertion state.
-        */
-       if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
-               E1000_WRITE_REG(hw, IMC, ~0);
-
-       adapter->total_tx_bytes = 0;
-       adapter->total_rx_bytes = 0;
-       adapter->total_tx_packets = 0;
-       adapter->total_rx_packets = 0;
 
-       for (i = 0; i < E1000_MAX_INTR; i++)
-               if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
-                  !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
-                       break;
-
-       if (likely(adapter->itr_setting & 3))
-               e1000_set_itr(adapter);
-
-       if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
-               e1000_irq_enable(adapter);
-
-#endif
        return IRQ_HANDLED;
 }
 
-#ifdef CONFIG_E1000_NAPI
 /**
  * e1000_clean - NAPI Rx polling callback
  * @adapter: board private structure
  **/
-
-static int
-e1000_clean(struct napi_struct *napi, int budget)
+static int e1000_clean(struct napi_struct *napi, int budget)
 {
        struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
        struct net_device *poll_dev = adapter->netdev;
@@ -3991,23 +3923,19 @@ e1000_clean(struct napi_struct *napi, int budget)
        return work_done;
 }
 
-#endif
 /**
  * e1000_clean_tx_irq - Reclaim resources after transmit completes
  * @adapter: board private structure
  **/
-
-static bool
-e1000_clean_tx_irq(struct e1000_adapter *adapter,
-                   struct e1000_tx_ring *tx_ring)
+static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
+                              struct e1000_tx_ring *tx_ring)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct net_device *netdev = adapter->netdev;
        struct e1000_tx_desc *tx_desc, *eop_desc;
        struct e1000_buffer *buffer_info;
        unsigned int i, eop;
-#ifdef CONFIG_E1000_NAPI
        unsigned int count = 0;
-#endif
        bool cleaned = false;
        unsigned int total_tx_bytes=0, total_tx_packets=0;
 
@@ -4039,11 +3967,10 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
 
                eop = tx_ring->buffer_info[i].next_to_watch;
                eop_desc = E1000_TX_DESC(*tx_ring, eop);
-#ifdef CONFIG_E1000_NAPI
 #define E1000_TX_WEIGHT 64
                /* weight of a sort for tx, to avoid endless transmit cleanup */
-               if (count++ == E1000_TX_WEIGHT) break;
-#endif
+               if (count++ == E1000_TX_WEIGHT)
+                       break;
        }
 
        tx_ring->next_to_clean = i;
@@ -4068,8 +3995,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
                if (tx_ring->buffer_info[eop].dma &&
                    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
                               (adapter->tx_timeout_factor * HZ))
-                   && !(E1000_READ_REG(&adapter->hw, STATUS) &
-                        E1000_STATUS_TXOFF)) {
+                   && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
 
                        /* detected Tx unit hang */
                        DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
@@ -4085,8 +4011,8 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
                                        "  next_to_watch.status <%x>\n",
                                (unsigned long)((tx_ring - adapter->tx_ring) /
                                        sizeof(struct e1000_tx_ring)),
-                               readl(adapter->hw.hw_addr + tx_ring->tdh),
-                               readl(adapter->hw.hw_addr + tx_ring->tdt),
+                               readl(hw->hw_addr + tx_ring->tdh),
+                               readl(hw->hw_addr + tx_ring->tdt),
                                tx_ring->next_to_use,
                                tx_ring->next_to_clean,
                                tx_ring->buffer_info[eop].time_stamp,
@@ -4111,17 +4037,16 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
  * @sk_buff:     socket buffer with received data
  **/
 
-static void
-e1000_rx_checksum(struct e1000_adapter *adapter,
-                 u32 status_err, u32 csum,
-                 struct sk_buff *skb)
+static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
+                             u32 csum, struct sk_buff *skb)
 {
+       struct e1000_hw *hw = &adapter->hw;
        u16 status = (u16)status_err;
        u8 errors = (u8)(status_err >> 24);
        skb->ip_summed = CHECKSUM_NONE;
 
        /* 82543 or newer only */
-       if (unlikely(adapter->hw.mac_type < e1000_82543)) return;
+       if (unlikely(hw->mac_type < e1000_82543)) return;
        /* Ignore Checksum bit is set */
        if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
        /* TCP/UDP checksum error bit is set */
@@ -4131,7 +4056,7 @@ e1000_rx_checksum(struct e1000_adapter *adapter,
                return;
        }
        /* TCP/UDP Checksum has not been calculated */
-       if (adapter->hw.mac_type <= e1000_82547_rev_2) {
+       if (hw->mac_type <= e1000_82547_rev_2) {
                if (!(status & E1000_RXD_STAT_TCPCS))
                        return;
        } else {
@@ -4142,7 +4067,7 @@ e1000_rx_checksum(struct e1000_adapter *adapter,
        if (likely(status & E1000_RXD_STAT_TCPCS)) {
                /* TCP checksum is good */
                skb->ip_summed = CHECKSUM_UNNECESSARY;
-       } else if (adapter->hw.mac_type > e1000_82547_rev_2) {
+       } else if (hw->mac_type > e1000_82547_rev_2) {
                /* IP fragment with UDP payload */
                /* Hardware complements the payload checksum, so we undo it
                 * and then put the value in host order for further stack use.
@@ -4158,17 +4083,11 @@ e1000_rx_checksum(struct e1000_adapter *adapter,
  * e1000_clean_rx_irq - Send received data up the network stack; legacy
  * @adapter: board private structure
  **/
-
-static bool
-#ifdef CONFIG_E1000_NAPI
-e1000_clean_rx_irq(struct e1000_adapter *adapter,
-                   struct e1000_rx_ring *rx_ring,
-                   int *work_done, int work_to_do)
-#else
-e1000_clean_rx_irq(struct e1000_adapter *adapter,
-                   struct e1000_rx_ring *rx_ring)
-#endif
+static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
+                              struct e1000_rx_ring *rx_ring,
+                              int *work_done, int work_to_do)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
        struct e1000_rx_desc *rx_desc, *next_rxd;
@@ -4189,11 +4108,10 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
                struct sk_buff *skb;
                u8 status;
 
-#ifdef CONFIG_E1000_NAPI
                if (*work_done >= work_to_do)
                        break;
                (*work_done)++;
-#endif
+
                status = rx_desc->status;
                skb = buffer_info->skb;
                buffer_info->skb = NULL;
@@ -4226,11 +4144,10 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
 
                if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
                        last_byte = *(skb->data + length - 1);
-                       if (TBI_ACCEPT(&adapter->hw, status,
-                                     rx_desc->errors, length, last_byte)) {
+                       if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
+                                      last_byte)) {
                                spin_lock_irqsave(&adapter->stats_lock, flags);
-                               e1000_tbi_adjust_stats(&adapter->hw,
-                                                      &adapter->stats,
+                               e1000_tbi_adjust_stats(hw, &adapter->stats,
                                                       length, skb->data);
                                spin_unlock_irqrestore(&adapter->stats_lock,
                                                       flags);
@@ -4280,7 +4197,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
                                  le16_to_cpu(rx_desc->csum), skb);
 
                skb->protocol = eth_type_trans(skb, netdev);
-#ifdef CONFIG_E1000_NAPI
+
                if (unlikely(adapter->vlgrp &&
                            (status & E1000_RXD_STAT_VP))) {
                        vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
@@ -4288,15 +4205,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
                } else {
                        netif_receive_skb(skb);
                }
-#else /* CONFIG_E1000_NAPI */
-               if (unlikely(adapter->vlgrp &&
-                           (status & E1000_RXD_STAT_VP))) {
-                       vlan_hwaccel_rx(skb, adapter->vlgrp,
-                                       le16_to_cpu(rx_desc->special));
-               } else {
-                       netif_rx(skb);
-               }
-#endif /* CONFIG_E1000_NAPI */
+
                netdev->last_rx = jiffies;
 
 next_desc:
@@ -4330,15 +4239,9 @@ next_desc:
  * @adapter: board private structure
  **/
 
-static bool
-#ifdef CONFIG_E1000_NAPI
-e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
-                      struct e1000_rx_ring *rx_ring,
-                      int *work_done, int work_to_do)
-#else
-e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
-                      struct e1000_rx_ring *rx_ring)
-#endif
+static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+                                 struct e1000_rx_ring *rx_ring,
+                                 int *work_done, int work_to_do)
 {
        union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
        struct net_device *netdev = adapter->netdev;
@@ -4361,11 +4264,11 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
        while (staterr & E1000_RXD_STAT_DD) {
                ps_page = &rx_ring->ps_page[i];
                ps_page_dma = &rx_ring->ps_page_dma[i];
-#ifdef CONFIG_E1000_NAPI
+
                if (unlikely(*work_done >= work_to_do))
                        break;
                (*work_done)++;
-#endif
+
                skb = buffer_info->skb;
 
                /* in the packet split case this is header only */
@@ -4438,7 +4341,8 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
                }
 
                for (j = 0; j < adapter->rx_ps_pages; j++) {
-                       if (!(length= le16_to_cpu(rx_desc->wb.upper.length[j])))
+                       length = le16_to_cpu(rx_desc->wb.upper.length[j]);
+                       if (!length)
                                break;
                        pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j],
                                        PAGE_SIZE, PCI_DMA_FROMDEVICE);
@@ -4466,21 +4370,14 @@ copydone:
                if (likely(rx_desc->wb.upper.header_status &
                           cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)))
                        adapter->rx_hdr_split++;
-#ifdef CONFIG_E1000_NAPI
+
                if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
                        vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
                                le16_to_cpu(rx_desc->wb.middle.vlan));
                } else {
                        netif_receive_skb(skb);
                }
-#else /* CONFIG_E1000_NAPI */
-               if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
-                       vlan_hwaccel_rx(skb, adapter->vlgrp,
-                               le16_to_cpu(rx_desc->wb.middle.vlan));
-               } else {
-                       netif_rx(skb);
-               }
-#endif /* CONFIG_E1000_NAPI */
+
                netdev->last_rx = jiffies;
 
 next_desc:
@@ -4517,11 +4414,11 @@ next_desc:
  * @adapter: address of board private structure
  **/
 
-static void
-e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
-                       struct e1000_rx_ring *rx_ring,
-                      int cleaned_count)
+static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
+                                  struct e1000_rx_ring *rx_ring,
+                                  int cleaned_count)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
        struct e1000_rx_desc *rx_desc;
@@ -4619,7 +4516,7 @@ map_skb:
                 * applicable for weak-ordered memory model archs,
                 * such as IA-64). */
                wmb();
-               writel(i, adapter->hw.hw_addr + rx_ring->rdt);
+               writel(i, hw->hw_addr + rx_ring->rdt);
        }
 }
 
@@ -4628,11 +4525,11 @@ map_skb:
  * @adapter: address of board private structure
  **/
 
-static void
-e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
-                          struct e1000_rx_ring *rx_ring,
-                         int cleaned_count)
+static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
+                                     struct e1000_rx_ring *rx_ring,
+                                     int cleaned_count)
 {
+       struct e1000_hw *hw = &adapter->hw;
        struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
        union e1000_rx_desc_packet_split *rx_desc;
@@ -4717,7 +4614,7 @@ no_buffers:
                 * descriptors are 32 bytes...so we increment tail
                 * twice as much.
                 */
-               writel(i<<1, adapter->hw.hw_addr + rx_ring->rdt);
+               writel(i<<1, hw->hw_addr + rx_ring->rdt);
        }
 }
 
@@ -4726,49 +4623,49 @@ no_buffers:
  * @adapter:
  **/
 
-static void
-e1000_smartspeed(struct e1000_adapter *adapter)
+static void e1000_smartspeed(struct e1000_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        u16 phy_status;
        u16 phy_ctrl;
 
-       if ((adapter->hw.phy_type != e1000_phy_igp) || !adapter->hw.autoneg ||
-          !(adapter->hw.autoneg_advertised & ADVERTISE_1000_FULL))
+       if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
+          !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
                return;
 
        if (adapter->smartspeed == 0) {
                /* If Master/Slave config fault is asserted twice,
                 * we assume back-to-back */
-               e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
+               e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
                if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
-               e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
+               e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
                if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
-               e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
+               e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
                if (phy_ctrl & CR_1000T_MS_ENABLE) {
                        phy_ctrl &= ~CR_1000T_MS_ENABLE;
-                       e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL,
+                       e1000_write_phy_reg(hw, PHY_1000T_CTRL,
                                            phy_ctrl);
                        adapter->smartspeed++;
-                       if (!e1000_phy_setup_autoneg(&adapter->hw) &&
-                          !e1000_read_phy_reg(&adapter->hw, PHY_CTRL,
+                       if (!e1000_phy_setup_autoneg(hw) &&
+                          !e1000_read_phy_reg(hw, PHY_CTRL,
                                               &phy_ctrl)) {
                                phy_ctrl |= (MII_CR_AUTO_NEG_EN |
                                             MII_CR_RESTART_AUTO_NEG);
-                               e1000_write_phy_reg(&adapter->hw, PHY_CTRL,
+                               e1000_write_phy_reg(hw, PHY_CTRL,
                                                    phy_ctrl);
                        }
                }
                return;
        } else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
                /* If still no link, perhaps using 2/3 pair cable */
-               e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
+               e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
                phy_ctrl |= CR_1000T_MS_ENABLE;
-               e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_ctrl);
-               if (!e1000_phy_setup_autoneg(&adapter->hw) &&
-                  !e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_ctrl)) {
+               e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
+               if (!e1000_phy_setup_autoneg(hw) &&
+                  !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
                        phy_ctrl |= (MII_CR_AUTO_NEG_EN |
                                     MII_CR_RESTART_AUTO_NEG);
-                       e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_ctrl);
+                       e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
                }
        }
        /* Restart process after E1000_SMARTSPEED_MAX iterations */
@@ -4783,8 +4680,7 @@ e1000_smartspeed(struct e1000_adapter *adapter)
  * @cmd:
  **/
 
-static int
-e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 {
        switch (cmd) {
        case SIOCGMIIPHY:
@@ -4803,28 +4699,29 @@ e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
  * @cmd:
  **/
 
-static int
-e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
+                          int cmd)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
        struct mii_ioctl_data *data = if_mii(ifr);
        int retval;
        u16 mii_reg;
        u16 spddplx;
        unsigned long flags;
 
-       if (adapter->hw.media_type != e1000_media_type_copper)
+       if (hw->media_type != e1000_media_type_copper)
                return -EOPNOTSUPP;
 
        switch (cmd) {
        case SIOCGMIIPHY:
-               data->phy_id = adapter->hw.phy_addr;
+               data->phy_id = hw->phy_addr;
                break;
        case SIOCGMIIREG:
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
                spin_lock_irqsave(&adapter->stats_lock, flags);
-               if (e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+               if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
                                   &data->val_out)) {
                        spin_unlock_irqrestore(&adapter->stats_lock, flags);
                        return -EIO;
@@ -4838,20 +4735,20 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
                        return -EFAULT;
                mii_reg = data->val_in;
                spin_lock_irqsave(&adapter->stats_lock, flags);
-               if (e1000_write_phy_reg(&adapter->hw, data->reg_num,
+               if (e1000_write_phy_reg(hw, data->reg_num,
                                        mii_reg)) {
                        spin_unlock_irqrestore(&adapter->stats_lock, flags);
                        return -EIO;
                }
                spin_unlock_irqrestore(&adapter->stats_lock, flags);
-               if (adapter->hw.media_type == e1000_media_type_copper) {
+               if (hw->media_type == e1000_media_type_copper) {
                        switch (data->reg_num) {
                        case PHY_CTRL:
                                if (mii_reg & MII_CR_POWER_DOWN)
                                        break;
                                if (mii_reg & MII_CR_AUTO_NEG_EN) {
-                                       adapter->hw.autoneg = 1;
-                                       adapter->hw.autoneg_advertised = 0x2F;
+                                       hw->autoneg = 1;
+                                       hw->autoneg_advertised = 0x2F;
                                } else {
                                        if (mii_reg & 0x40)
                                                spddplx = SPEED_1000;
@@ -4874,7 +4771,7 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
                                break;
                        case M88E1000_PHY_SPEC_CTRL:
                        case M88E1000_EXT_PHY_SPEC_CTRL:
-                               if (e1000_phy_reset(&adapter->hw))
+                               if (e1000_phy_reset(hw))
                                        return -EIO;
                                break;
                        }
@@ -4897,8 +4794,7 @@ e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
        return E1000_SUCCESS;
 }
 
-void
-e1000_pci_set_mwi(struct e1000_hw *hw)
+void e1000_pci_set_mwi(struct e1000_hw *hw)
 {
        struct e1000_adapter *adapter = hw->back;
        int ret_val = pci_set_mwi(adapter->pdev);
@@ -4907,30 +4803,26 @@ e1000_pci_set_mwi(struct e1000_hw *hw)
                DPRINTK(PROBE, ERR, "Error in setting MWI\n");
 }
 
-void
-e1000_pci_clear_mwi(struct e1000_hw *hw)
+void e1000_pci_clear_mwi(struct e1000_hw *hw)
 {
        struct e1000_adapter *adapter = hw->back;
 
        pci_clear_mwi(adapter->pdev);
 }
 
-int
-e1000_pcix_get_mmrbc(struct e1000_hw *hw)
+int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
 {
        struct e1000_adapter *adapter = hw->back;
        return pcix_get_mmrbc(adapter->pdev);
 }
 
-void
-e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
+void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
 {
        struct e1000_adapter *adapter = hw->back;
        pcix_set_mmrbc(adapter->pdev, mmrbc);
 }
 
-s32
-e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
+s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
 {
     struct e1000_adapter *adapter = hw->back;
     u16 cap_offset;
@@ -4944,16 +4836,16 @@ e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
     return E1000_SUCCESS;
 }
 
-void
-e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
+void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
 {
        outl(value, port);
 }
 
-static void
-e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
+static void e1000_vlan_rx_register(struct net_device *netdev,
+                                  struct vlan_group *grp)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
        u32 ctrl, rctl;
 
        if (!test_bit(__E1000_DOWN, &adapter->flags))
@@ -4962,22 +4854,22 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
 
        if (grp) {
                /* enable VLAN tag insert/strip */
-               ctrl = E1000_READ_REG(&adapter->hw, CTRL);
+               ctrl = er32(CTRL);
                ctrl |= E1000_CTRL_VME;
-               E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
+               ew32(CTRL, ctrl);
 
                if (adapter->hw.mac_type != e1000_ich8lan) {
                        /* enable VLAN receive filtering */
-                       rctl = E1000_READ_REG(&adapter->hw, RCTL);
+                       rctl = er32(RCTL);
                        rctl &= ~E1000_RCTL_CFIEN;
-                       E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+                       ew32(RCTL, rctl);
                        e1000_update_mng_vlan(adapter);
                }
        } else {
                /* disable VLAN tag insert/strip */
-               ctrl = E1000_READ_REG(&adapter->hw, CTRL);
+               ctrl = er32(CTRL);
                ctrl &= ~E1000_CTRL_VME;
-               E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
+               ew32(CTRL, ctrl);
 
                if (adapter->hw.mac_type != e1000_ich8lan) {
                        if (adapter->mng_vlan_id !=
@@ -4993,27 +4885,27 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
                e1000_irq_enable(adapter);
 }
 
-static void
-e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
        u32 vfta, index;
 
-       if ((adapter->hw.mng_cookie.status &
+       if ((hw->mng_cookie.status &
             E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
            (vid == adapter->mng_vlan_id))
                return;
        /* add VID to filter table */
        index = (vid >> 5) & 0x7F;
-       vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
+       vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
        vfta |= (1 << (vid & 0x1F));
-       e1000_write_vfta(&adapter->hw, index, vfta);
+       e1000_write_vfta(hw, index, vfta);
 }
 
-static void
-e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
        u32 vfta, index;
 
        if (!test_bit(__E1000_DOWN, &adapter->flags))
@@ -5022,7 +4914,7 @@ e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
        if (!test_bit(__E1000_DOWN, &adapter->flags))
                e1000_irq_enable(adapter);
 
-       if ((adapter->hw.mng_cookie.status &
+       if ((hw->mng_cookie.status &
             E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
            (vid == adapter->mng_vlan_id)) {
                /* release control to f/w */
@@ -5032,13 +4924,12 @@ e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
 
        /* remove VID from filter table */
        index = (vid >> 5) & 0x7F;
-       vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
+       vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
        vfta &= ~(1 << (vid & 0x1F));
-       e1000_write_vfta(&adapter->hw, index, vfta);
+       e1000_write_vfta(hw, index, vfta);
 }
 
-static void
-e1000_restore_vlan(struct e1000_adapter *adapter)
+static void e1000_restore_vlan(struct e1000_adapter *adapter)
 {
        e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
 
@@ -5052,13 +4943,14 @@ e1000_restore_vlan(struct e1000_adapter *adapter)
        }
 }
 
-int
-e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
+int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
 {
-       adapter->hw.autoneg = 0;
+       struct e1000_hw *hw = &adapter->hw;
+
+       hw->autoneg = 0;
 
        /* Fiber NICs only allow 1000 gbps Full duplex */
-       if ((adapter->hw.media_type == e1000_media_type_fiber) &&
+       if ((hw->media_type == e1000_media_type_fiber) &&
                spddplx != (SPEED_1000 + DUPLEX_FULL)) {
                DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
                return -EINVAL;
@@ -5066,20 +4958,20 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
 
        switch (spddplx) {
        case SPEED_10 + DUPLEX_HALF:
-               adapter->hw.forced_speed_duplex = e1000_10_half;
+               hw->forced_speed_duplex = e1000_10_half;
                break;
        case SPEED_10 + DUPLEX_FULL:
-               adapter->hw.forced_speed_duplex = e1000_10_full;
+               hw->forced_speed_duplex = e1000_10_full;
                break;
        case SPEED_100 + DUPLEX_HALF:
-               adapter->hw.forced_speed_duplex = e1000_100_half;
+               hw->forced_speed_duplex = e1000_100_half;
                break;
        case SPEED_100 + DUPLEX_FULL:
-               adapter->hw.forced_speed_duplex = e1000_100_full;
+               hw->forced_speed_duplex = e1000_100_full;
                break;
        case SPEED_1000 + DUPLEX_FULL:
-               adapter->hw.autoneg = 1;
-               adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
+               hw->autoneg = 1;
+               hw->autoneg_advertised = ADVERTISE_1000_FULL;
                break;
        case SPEED_1000 + DUPLEX_HALF: /* not supported */
        default:
@@ -5089,11 +4981,11 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
        return 0;
 }
 
-static int
-e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
        u32 ctrl, ctrl_ext, rctl, status;
        u32 wufc = adapter->wol;
 #ifdef CONFIG_PM
@@ -5113,7 +5005,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
                return retval;
 #endif
 
-       status = E1000_READ_REG(&adapter->hw, STATUS);
+       status = er32(STATUS);
        if (status & E1000_STATUS_LU)
                wufc &= ~E1000_WUFC_LNKC;
 
@@ -5123,40 +5015,40 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 
                /* turn on all-multi mode if wake on multicast is enabled */
                if (wufc & E1000_WUFC_MC) {
-                       rctl = E1000_READ_REG(&adapter->hw, RCTL);
+                       rctl = er32(RCTL);
                        rctl |= E1000_RCTL_MPE;
-                       E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+                       ew32(RCTL, rctl);
                }
 
-               if (adapter->hw.mac_type >= e1000_82540) {
-                       ctrl = E1000_READ_REG(&adapter->hw, CTRL);
+               if (hw->mac_type >= e1000_82540) {
+                       ctrl = er32(CTRL);
                        /* advertise wake from D3Cold */
                        #define E1000_CTRL_ADVD3WUC 0x00100000
                        /* phy power management enable */
                        #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
                        ctrl |= E1000_CTRL_ADVD3WUC |
                                E1000_CTRL_EN_PHY_PWR_MGMT;
-                       E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
+                       ew32(CTRL, ctrl);
                }
 
-               if (adapter->hw.media_type == e1000_media_type_fiber ||
-                  adapter->hw.media_type == e1000_media_type_internal_serdes) {
+               if (hw->media_type == e1000_media_type_fiber ||
+                  hw->media_type == e1000_media_type_internal_serdes) {
                        /* keep the laser running in D3 */
-                       ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+                       ctrl_ext = er32(CTRL_EXT);
                        ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
-                       E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext);
+                       ew32(CTRL_EXT, ctrl_ext);
                }
 
                /* Allow time for pending master requests to run */
-               e1000_disable_pciex_master(&adapter->hw);
+               e1000_disable_pciex_master(hw);
 
-               E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN);
-               E1000_WRITE_REG(&adapter->hw, WUFC, wufc);
+               ew32(WUC, E1000_WUC_PME_EN);
+               ew32(WUFC, wufc);
                pci_enable_wake(pdev, PCI_D3hot, 1);
                pci_enable_wake(pdev, PCI_D3cold, 1);
        } else {
-               E1000_WRITE_REG(&adapter->hw, WUC, 0);
-               E1000_WRITE_REG(&adapter->hw, WUFC, 0);
+               ew32(WUC, 0);
+               ew32(WUFC, 0);
                pci_enable_wake(pdev, PCI_D3hot, 0);
                pci_enable_wake(pdev, PCI_D3cold, 0);
        }
@@ -5169,8 +5061,8 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
                pci_enable_wake(pdev, PCI_D3cold, 1);
        }
 
-       if (adapter->hw.phy_type == e1000_phy_igp_3)
-               e1000_phy_powerdown_workaround(&adapter->hw);
+       if (hw->phy_type == e1000_phy_igp_3)
+               e1000_phy_powerdown_workaround(hw);
 
        if (netif_running(netdev))
                e1000_free_irq(adapter);
@@ -5187,16 +5079,21 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 }
 
 #ifdef CONFIG_PM
-static int
-e1000_resume(struct pci_dev *pdev)
+static int e1000_resume(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
        u32 err;
 
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
-       if ((err = pci_enable_device(pdev))) {
+
+       if (adapter->need_ioport)
+               err = pci_enable_device(pdev);
+       else
+               err = pci_enable_device_mem(pdev);
+       if (err) {
                printk(KERN_ERR "e1000: Cannot enable PCI device from suspend\n");
                return err;
        }
@@ -5205,12 +5102,15 @@ e1000_resume(struct pci_dev *pdev)
        pci_enable_wake(pdev, PCI_D3hot, 0);
        pci_enable_wake(pdev, PCI_D3cold, 0);
 
-       if (netif_running(netdev) && (err = e1000_request_irq(adapter)))
-               return err;
+       if (netif_running(netdev)) {
+               err = e1000_request_irq(adapter);
+               if (err)
+                       return err;
+       }
 
        e1000_power_up_phy(adapter);
        e1000_reset(adapter);
-       E1000_WRITE_REG(&adapter->hw, WUS, ~0);
+       ew32(WUS, ~0);
 
        e1000_init_manageability(adapter);
 
@@ -5223,8 +5123,8 @@ e1000_resume(struct pci_dev *pdev)
         * DRV_LOAD until the interface is up.  For all other cases,
         * let the f/w know that the h/w is now under the control
         * of the driver. */
-       if (adapter->hw.mac_type != e1000_82573 ||
-           !e1000_check_mng_mode(&adapter->hw))
+       if (hw->mac_type != e1000_82573 ||
+           !e1000_check_mng_mode(hw))
                e1000_get_hw_control(adapter);
 
        return 0;
@@ -5242,16 +5142,12 @@ static void e1000_shutdown(struct pci_dev *pdev)
  * without having to re-enable interrupts. It's not called while
  * the interrupt routine is executing.
  */
-static void
-e1000_netpoll(struct net_device *netdev)
+static void e1000_netpoll(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
 
        disable_irq(adapter->pdev->irq);
        e1000_intr(adapter->pdev->irq, netdev);
-#ifndef CONFIG_E1000_NAPI
-       adapter->clean_rx(adapter, adapter->rx_ring);
-#endif
        enable_irq(adapter->pdev->irq);
 }
 #endif
@@ -5264,7 +5160,8 @@ e1000_netpoll(struct net_device *netdev)
  * This function is called after a PCI bus error affecting
  * this device has been detected.
  */
-static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
+static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
+                                               pci_channel_state_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev->priv;
@@ -5290,8 +5187,14 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_hw *hw = &adapter->hw;
+       int err;
 
-       if (pci_enable_device(pdev)) {
+       if (adapter->need_ioport)
+               err = pci_enable_device(pdev);
+       else
+               err = pci_enable_device_mem(pdev);
+       if (err) {
                printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n");
                return PCI_ERS_RESULT_DISCONNECT;
        }
@@ -5301,7 +5204,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
        pci_enable_wake(pdev, PCI_D3cold, 0);
 
        e1000_reset(adapter);
-       E1000_WRITE_REG(&adapter->hw, WUS, ~0);
+       ew32(WUS, ~0);
 
        return PCI_ERS_RESULT_RECOVERED;
 }
@@ -5318,6 +5221,7 @@ static void e1000_io_resume(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_hw *hw = &adapter->hw;
 
        e1000_init_manageability(adapter);
 
@@ -5334,8 +5238,8 @@ static void e1000_io_resume(struct pci_dev *pdev)
         * DRV_LOAD until the interface is up.  For all other cases,
         * let the f/w know that the h/w is now under the control
         * of the driver. */
-       if (adapter->hw.mac_type != e1000_82573 ||
-           !e1000_check_mng_mode(&adapter->hw))
+       if (hw->mac_type != e1000_82573 ||
+           !e1000_check_mng_mode(hw))
                e1000_get_hw_control(adapter);
 
 }
index 365626d3177e3330c4307a673255977266a880be..d9298522f5aeef3f5f84baefc3f0f3961b21a1c0 100644 (file)
 #define DEBUGOUT7 DEBUGOUT3
 
 
-#define E1000_WRITE_REG(a, reg, value) ( \
-    writel((value), ((a)->hw_addr + \
-        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg))))
+#define er32(reg)                                                      \
+       (readl(hw->hw_addr + ((hw->mac_type >= e1000_82543)             \
+                              ? E1000_##reg : E1000_82542_##reg)))
 
-#define E1000_READ_REG(a, reg) ( \
-    readl((a)->hw_addr + \
-        (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg)))
+#define ew32(reg, value)                                               \
+       (writel((value), (hw->hw_addr + ((hw->mac_type >= e1000_82543)  \
+                                        ? E1000_##reg : E1000_82542_##reg))))
 
 #define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \
     writel((value), ((a)->hw_addr + \
@@ -96,7 +96,7 @@
         (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
         (offset)))
 
-#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS)
+#define E1000_WRITE_FLUSH() er32(STATUS)
 
 #define E1000_WRITE_ICH_FLASH_REG(a, reg, value) ( \
     writel((value), ((a)->flash_address + reg)))
index e6565ce686bcefd91499e6304ebac33f0aa97445..b9f90a5d3d4d1968f5ed3153b9960a9902cef97b 100644 (file)
@@ -213,10 +213,9 @@ struct e1000_option {
        } arg;
 };
 
-static int __devinit
-e1000_validate_option(unsigned int *value,
-                     const struct e1000_option *opt,
-                     struct e1000_adapter *adapter)
+static int __devinit e1000_validate_option(unsigned int *value,
+                                          const struct e1000_option *opt,
+                                          struct e1000_adapter *adapter)
 {
        if (*value == OPTION_UNSET) {
                *value = opt->def;
@@ -278,8 +277,7 @@ static void e1000_check_copper_options(struct e1000_adapter *adapter);
  * in a variable in the adapter structure.
  **/
 
-void __devinit
-e1000_check_options(struct e1000_adapter *adapter)
+void __devinit e1000_check_options(struct e1000_adapter *adapter)
 {
        int bd = adapter->bd_number;
        if (bd >= E1000_MAX_NIC) {
@@ -551,8 +549,7 @@ e1000_check_options(struct e1000_adapter *adapter)
  * Handles speed and duplex options on fiber adapters
  **/
 
-static void __devinit
-e1000_check_fiber_options(struct e1000_adapter *adapter)
+static void __devinit e1000_check_fiber_options(struct e1000_adapter *adapter)
 {
        int bd = adapter->bd_number;
        if (num_Speed > bd) {
@@ -579,8 +576,7 @@ e1000_check_fiber_options(struct e1000_adapter *adapter)
  * Handles speed and duplex options on copper adapters
  **/
 
-static void __devinit
-e1000_check_copper_options(struct e1000_adapter *adapter)
+static void __devinit e1000_check_copper_options(struct e1000_adapter *adapter)
 {
        unsigned int speed, dplx, an;
        int bd = adapter->bd_number;
index ae9ecb7df22be16f19038c8d0d2c63c7618e7a6e..4e4f68304e822ed9a1356ee9d225d5f5324358fa 100644 (file)
@@ -197,9 +197,6 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev)
                if (priv->link == PHY_DOWN) {
                        new_state = 1;
                        priv->link = phydev->link;
-                       netif_tx_schedule_all(dev);
-                       netif_carrier_on(dev);
-                       netif_start_queue(dev);
                }
 
        } else if (priv->link) {
@@ -207,8 +204,6 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev)
                priv->link = PHY_DOWN;
                priv->speed = 0;
                priv->duplex = -1;
-               netif_stop_queue(dev);
-               netif_carrier_off(dev);
        }
 
        if (new_state && netif_msg_link(priv))
index 1ffbe0756a0c6bde820e736b4e5ae424ffbace70..d4a305ee3455e145e4ae2b5f8144cd8db08ee522 100644 (file)
@@ -8,12 +8,7 @@ fs_enet-$(CONFIG_FS_ENET_HAS_SCC) += mac-scc.o
 fs_enet-$(CONFIG_FS_ENET_HAS_FEC) += mac-fec.o
 fs_enet-$(CONFIG_FS_ENET_HAS_FCC) += mac-fcc.o
 
-ifeq ($(CONFIG_PPC_CPM_NEW_BINDING),y)
 obj-$(CONFIG_FS_ENET_MDIO_FEC) += mii-fec.o
 obj-$(CONFIG_FS_ENET_MDIO_FCC) += mii-bitbang.o
-else
-fs_enet-$(CONFIG_FS_ENET_MDIO_FEC) += mii-fec.o
-fs_enet-$(CONFIG_FS_ENET_MDIO_FCC) += mii-bitbang.o
-endif
 
 fs_enet-objs := fs_enet-main.o $(fs_enet-m)
index 445763e5648eef9951e4858762fc9872daeeace2..9a51ec8293cc953e0ea32a8df6d7c08a9a7204f3 100644 (file)
 #include <linux/fs.h>
 #include <linux/platform_device.h>
 #include <linux/phy.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
 
 #include <linux/vmalloc.h>
 #include <asm/pgtable.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
-#include <linux/of_gpio.h>
-#include <linux/of_platform.h>
-#endif
-
 #include "fs_enet.h"
 
 /*************************************************/
 
-#ifndef CONFIG_PPC_CPM_NEW_BINDING
-static char version[] __devinitdata =
-    DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n";
-#endif
-
 MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>");
 MODULE_DESCRIPTION("Freescale Ethernet Driver");
 MODULE_LICENSE("GPL");
@@ -738,9 +730,6 @@ static void generic_adjust_link(struct  net_device *dev)
                if (!fep->oldlink) {
                        new_state = 1;
                        fep->oldlink = 1;
-                       netif_tx_schedule_all(dev);
-                       netif_carrier_on(dev);
-                       netif_start_queue(dev);
                }
 
                if (new_state)
@@ -750,8 +739,6 @@ static void generic_adjust_link(struct  net_device *dev)
                fep->oldlink = 0;
                fep->oldspeed = 0;
                fep->oldduplex = -1;
-               netif_carrier_off(dev);
-               netif_stop_queue(dev);
        }
 
        if (new_state && netif_msg_link(fep))
@@ -826,6 +813,8 @@ static int fs_enet_open(struct net_device *dev)
        }
        phy_start(fep->phydev);
 
+       netif_start_queue(dev);
+
        return 0;
 }
 
@@ -958,190 +947,6 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 extern int fs_mii_connect(struct net_device *dev);
 extern void fs_mii_disconnect(struct net_device *dev);
 
-#ifndef CONFIG_PPC_CPM_NEW_BINDING
-static struct net_device *fs_init_instance(struct device *dev,
-               struct fs_platform_info *fpi)
-{
-       struct net_device *ndev = NULL;
-       struct fs_enet_private *fep = NULL;
-       int privsize, i, r, err = 0, registered = 0;
-
-       fpi->fs_no = fs_get_id(fpi);
-       /* guard */
-       if ((unsigned int)fpi->fs_no >= FS_MAX_INDEX)
-               return ERR_PTR(-EINVAL);
-
-       privsize = sizeof(*fep) + (sizeof(struct sk_buff **) *
-                           (fpi->rx_ring + fpi->tx_ring));
-
-       ndev = alloc_etherdev(privsize);
-       if (!ndev) {
-               err = -ENOMEM;
-               goto err;
-       }
-
-       fep = netdev_priv(ndev);
-
-       fep->dev = dev;
-       dev_set_drvdata(dev, ndev);
-       fep->fpi = fpi;
-       if (fpi->init_ioports)
-               fpi->init_ioports((struct fs_platform_info *)fpi);
-
-#ifdef CONFIG_FS_ENET_HAS_FEC
-       if (fs_get_fec_index(fpi->fs_no) >= 0)
-               fep->ops = &fs_fec_ops;
-#endif
-
-#ifdef CONFIG_FS_ENET_HAS_SCC
-       if (fs_get_scc_index(fpi->fs_no) >=0)
-               fep->ops = &fs_scc_ops;
-#endif
-
-#ifdef CONFIG_FS_ENET_HAS_FCC
-       if (fs_get_fcc_index(fpi->fs_no) >= 0)
-               fep->ops = &fs_fcc_ops;
-#endif
-
-       if (fep->ops == NULL) {
-               printk(KERN_ERR DRV_MODULE_NAME
-                      ": %s No matching ops found (%d).\n",
-                      ndev->name, fpi->fs_no);
-               err = -EINVAL;
-               goto err;
-       }
-
-       r = (*fep->ops->setup_data)(ndev);
-       if (r != 0) {
-               printk(KERN_ERR DRV_MODULE_NAME
-                      ": %s setup_data failed\n",
-                       ndev->name);
-               err = r;
-               goto err;
-       }
-
-       /* point rx_skbuff, tx_skbuff */
-       fep->rx_skbuff = (struct sk_buff **)&fep[1];
-       fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring;
-
-       /* init locks */
-       spin_lock_init(&fep->lock);
-       spin_lock_init(&fep->tx_lock);
-
-       /*
-        * Set the Ethernet address.
-        */
-       for (i = 0; i < 6; i++)
-               ndev->dev_addr[i] = fpi->macaddr[i];
-
-       r = (*fep->ops->allocate_bd)(ndev);
-
-       if (fep->ring_base == NULL) {
-               printk(KERN_ERR DRV_MODULE_NAME
-                      ": %s buffer descriptor alloc failed (%d).\n", ndev->name, r);
-               err = r;
-               goto err;
-       }
-
-       /*
-        * Set receive and transmit descriptor base.
-        */
-       fep->rx_bd_base = fep->ring_base;
-       fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring;
-
-       /* initialize ring size variables */
-       fep->tx_ring = fpi->tx_ring;
-       fep->rx_ring = fpi->rx_ring;
-
-       /*
-        * The FEC Ethernet specific entries in the device structure.
-        */
-       ndev->open = fs_enet_open;
-       ndev->hard_start_xmit = fs_enet_start_xmit;
-       ndev->tx_timeout = fs_timeout;
-       ndev->watchdog_timeo = 2 * HZ;
-       ndev->stop = fs_enet_close;
-       ndev->get_stats = fs_enet_get_stats;
-       ndev->set_multicast_list = fs_set_multicast_list;
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       ndev->poll_controller = fs_enet_netpoll;
-#endif
-
-       netif_napi_add(ndev, &fep->napi,
-                      fs_enet_rx_napi, fpi->napi_weight);
-
-       ndev->ethtool_ops = &fs_ethtool_ops;
-       ndev->do_ioctl = fs_ioctl;
-
-       init_timer(&fep->phy_timer_list);
-
-       netif_carrier_off(ndev);
-
-       err = register_netdev(ndev);
-       if (err != 0) {
-               printk(KERN_ERR DRV_MODULE_NAME
-                      ": %s register_netdev failed.\n", ndev->name);
-               goto err;
-       }
-       registered = 1;
-
-
-       return ndev;
-
-err:
-       if (ndev != NULL) {
-               if (registered)
-                       unregister_netdev(ndev);
-
-               if (fep && fep->ops) {
-                       (*fep->ops->free_bd)(ndev);
-                       (*fep->ops->cleanup_data)(ndev);
-               }
-
-               free_netdev(ndev);
-       }
-
-       dev_set_drvdata(dev, NULL);
-
-       return ERR_PTR(err);
-}
-
-static int fs_cleanup_instance(struct net_device *ndev)
-{
-       struct fs_enet_private *fep;
-       const struct fs_platform_info *fpi;
-       struct device *dev;
-
-       if (ndev == NULL)
-               return -EINVAL;
-
-       fep = netdev_priv(ndev);
-       if (fep == NULL)
-               return -EINVAL;
-
-       fpi = fep->fpi;
-
-       unregister_netdev(ndev);
-
-       dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t),
-                         (void __force *)fep->ring_base, fep->ring_mem_addr);
-
-       /* reset it */
-       (*fep->ops->cleanup_data)(ndev);
-
-       dev = fep->dev;
-       if (dev != NULL) {
-               dev_set_drvdata(dev, NULL);
-               fep->dev = NULL;
-       }
-
-       free_netdev(ndev);
-
-       return 0;
-}
-#endif
-
 /**************************************************************************************/
 
 /* handy pointer to the immap */
@@ -1168,7 +973,6 @@ static void cleanup_immap(void)
 
 /**************************************************************************************/
 
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
 static int __devinit find_phy(struct device_node *np,
                               struct fs_platform_info *fpi)
 {
@@ -1408,121 +1212,6 @@ static void __exit fs_cleanup(void)
        of_unregister_platform_driver(&fs_enet_driver);
        cleanup_immap();
 }
-#else
-static int __devinit fs_enet_probe(struct device *dev)
-{
-       struct net_device *ndev;
-
-       /* no fixup - no device */
-       if (dev->platform_data == NULL) {
-               printk(KERN_INFO "fs_enet: "
-                               "probe called with no platform data; "
-                               "remove unused devices\n");
-               return -ENODEV;
-       }
-
-       ndev = fs_init_instance(dev, dev->platform_data);
-       if (IS_ERR(ndev))
-               return PTR_ERR(ndev);
-       return 0;
-}
-
-static int fs_enet_remove(struct device *dev)
-{
-       return fs_cleanup_instance(dev_get_drvdata(dev));
-}
-
-static struct device_driver fs_enet_fec_driver = {
-       .name           = "fsl-cpm-fec",
-       .bus            = &platform_bus_type,
-       .probe          = fs_enet_probe,
-       .remove         = fs_enet_remove,
-#ifdef CONFIG_PM
-/*     .suspend        = fs_enet_suspend,      TODO */
-/*     .resume         = fs_enet_resume,       TODO */
-#endif
-};
-
-static struct device_driver fs_enet_scc_driver = {
-       .name           = "fsl-cpm-scc",
-       .bus            = &platform_bus_type,
-       .probe          = fs_enet_probe,
-       .remove         = fs_enet_remove,
-#ifdef CONFIG_PM
-/*     .suspend        = fs_enet_suspend,      TODO */
-/*     .resume         = fs_enet_resume,       TODO */
-#endif
-};
-
-static struct device_driver fs_enet_fcc_driver = {
-       .name           = "fsl-cpm-fcc",
-       .bus            = &platform_bus_type,
-       .probe          = fs_enet_probe,
-       .remove         = fs_enet_remove,
-#ifdef CONFIG_PM
-/*     .suspend        = fs_enet_suspend,      TODO */
-/*     .resume         = fs_enet_resume,       TODO */
-#endif
-};
-
-static int __init fs_init(void)
-{
-       int r;
-
-       printk(KERN_INFO
-                       "%s", version);
-
-       r = setup_immap();
-       if (r != 0)
-               return r;
-
-#ifdef CONFIG_FS_ENET_HAS_FCC
-       /* let's insert mii stuff */
-       r = fs_enet_mdio_bb_init();
-
-       if (r != 0) {
-               printk(KERN_ERR DRV_MODULE_NAME
-                       "BB PHY init failed.\n");
-               return r;
-       }
-       r = driver_register(&fs_enet_fcc_driver);
-       if (r != 0)
-               goto err;
-#endif
-
-#ifdef CONFIG_FS_ENET_HAS_FEC
-       r =  fs_enet_mdio_fec_init();
-       if (r != 0) {
-               printk(KERN_ERR DRV_MODULE_NAME
-                       "FEC PHY init failed.\n");
-               return r;
-       }
-
-       r = driver_register(&fs_enet_fec_driver);
-       if (r != 0)
-               goto err;
-#endif
-
-#ifdef CONFIG_FS_ENET_HAS_SCC
-       r = driver_register(&fs_enet_scc_driver);
-       if (r != 0)
-               goto err;
-#endif
-
-       return 0;
-err:
-       cleanup_immap();
-       return r;
-}
-
-static void __exit fs_cleanup(void)
-{
-       driver_unregister(&fs_enet_fec_driver);
-       driver_unregister(&fs_enet_fcc_driver);
-       driver_unregister(&fs_enet_scc_driver);
-       cleanup_immap();
-}
-#endif
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void fs_enet_netpoll(struct net_device *dev)
index e05389c49bbb141e253bbeed681fe763aec7a2a8..db46d2e723296b1f1dd1e0a1dce297f532370299 100644 (file)
@@ -138,10 +138,6 @@ struct fs_enet_private {
 };
 
 /***************************************************************************/
-#ifndef CONFIG_PPC_CPM_NEW_BINDING
-int fs_enet_mdio_bb_init(void);
-int fs_enet_mdio_fec_init(void);
-#endif
 
 void fs_init_bds(struct net_device *dev);
 void fs_cleanup_bds(struct net_device *dev);
index 8268b3535b30caff91ed208ec6c85025a658238e..0a97fc2d97eca1528b72fd899827353181d3eb7d 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/fs.h>
 #include <linux/platform_device.h>
 #include <linux/phy.h>
+#include <linux/of_device.h>
 
 #include <asm/immap_cpm2.h>
 #include <asm/mpc8260.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
-#include <asm/of_device.h>
-#endif
-
 #include "fs_enet.h"
 
 /*************************************************/
@@ -87,7 +84,6 @@ static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op)
 
 static int do_pd_setup(struct fs_enet_private *fep)
 {
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
        struct of_device *ofdev = to_of_device(fep->dev);
        struct fs_platform_info *fpi = fep->fpi;
        int ret = -EINVAL;
@@ -125,44 +121,6 @@ out_fccp:
        iounmap(fep->fcc.fccp);
 out:
        return ret;
-#else
-       struct platform_device *pdev = to_platform_device(fep->dev);
-       struct resource *r;
-
-       /* Fill out IRQ field */
-       fep->interrupt = platform_get_irq(pdev, 0);
-       if (fep->interrupt < 0)
-               return -EINVAL;
-
-       /* Attach the memory for the FCC Parameter RAM */
-       r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram");
-       fep->fcc.ep = ioremap(r->start, r->end - r->start + 1);
-       if (fep->fcc.ep == NULL)
-               return -EINVAL;
-
-       r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs");
-       fep->fcc.fccp = ioremap(r->start, r->end - r->start + 1);
-       if (fep->fcc.fccp == NULL)
-               return -EINVAL;
-
-       if (fep->fpi->fcc_regs_c) {
-               fep->fcc.fcccp = (void __iomem *)fep->fpi->fcc_regs_c;
-       } else {
-               r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-                               "fcc_regs_c");
-               fep->fcc.fcccp = ioremap(r->start,
-                               r->end - r->start + 1);
-       }
-
-       if (fep->fcc.fcccp == NULL)
-               return -EINVAL;
-
-       fep->fcc.mem = (void __iomem *)fep->fpi->mem_offset;
-       if (fep->fcc.mem == NULL)
-               return -EINVAL;
-
-       return 0;
-#endif
 }
 
 #define FCC_NAPI_RX_EVENT_MSK  (FCC_ENET_RXF | FCC_ENET_RXB)
@@ -173,17 +131,6 @@ out:
 static int setup_data(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
-#ifndef CONFIG_PPC_CPM_NEW_BINDING
-       struct fs_platform_info *fpi = fep->fpi;
-
-       fpi->cp_command = (fpi->cp_page << 26) |
-                         (fpi->cp_block << 21) |
-                         (12 << 6);
-
-       fep->fcc.idx = fs_get_fcc_index(fpi->fs_no);
-       if ((unsigned int)fep->fcc.idx >= 3)    /* max 3 FCCs */
-               return -EINVAL;
-#endif
 
        if (do_pd_setup(fep) != 0)
                return -EINVAL;
@@ -304,9 +251,6 @@ static void restart(struct net_device *dev)
        fcc_enet_t __iomem *ep = fep->fcc.ep;
        dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
        u16 paddrh, paddrm, paddrl;
-#ifndef CONFIG_PPC_CPM_NEW_BINDING
-       u16 mem_addr;
-#endif
        const unsigned char *mac;
        int i;
 
@@ -338,19 +282,10 @@ static void restart(struct net_device *dev)
         * this area.
         */
 
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
        W16(ep, fen_genfcc.fcc_riptr, fpi->dpram_offset);
        W16(ep, fen_genfcc.fcc_tiptr, fpi->dpram_offset + 32);
 
        W16(ep, fen_padptr, fpi->dpram_offset + 64);
-#else
-       mem_addr = (u32) fep->fcc.mem;  /* de-fixup dpram offset */
-
-       W16(ep, fen_genfcc.fcc_riptr, (mem_addr & 0xffff));
-       W16(ep, fen_genfcc.fcc_tiptr, ((mem_addr + 32) & 0xffff));
-
-       W16(ep, fen_padptr, mem_addr + 64);
-#endif
 
        /* fill with special symbol...  */
        memset_io(fep->fcc.mem + fpi->dpram_offset + 64, 0x88, 32);
index 8a311d1e435b131a202588d903f557368fbe60f2..0a7d1c5c652479e1f032764360dd4b8b320e5d02 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/bitops.h>
 #include <linux/fs.h>
 #include <linux/platform_device.h>
+#include <linux/of_device.h>
 
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <asm/cpm1.h>
 #endif
 
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
-#include <asm/of_device.h>
-#endif
-
 #include "fs_enet.h"
 #include "fec.h"
 
@@ -99,7 +96,6 @@ static int whack_reset(fec_t __iomem *fecp)
 
 static int do_pd_setup(struct fs_enet_private *fep)
 {
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
        struct of_device *ofdev = to_of_device(fep->dev);
 
        fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
@@ -111,23 +107,6 @@ static int do_pd_setup(struct fs_enet_private *fep)
                return -EINVAL;
 
        return 0;
-#else
-       struct platform_device *pdev = to_platform_device(fep->dev);
-       struct resource *r;
-
-       /* Fill out IRQ field */
-       fep->interrupt = platform_get_irq_byname(pdev,"interrupt");
-       if (fep->interrupt < 0)
-               return -EINVAL;
-
-       r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
-       fep->fec.fecp = ioremap(r->start, r->end - r->start + 1);
-
-       if(fep->fec.fecp == NULL)
-               return -EINVAL;
-
-       return 0;
-#endif
 }
 
 #define FEC_NAPI_RX_EVENT_MSK  (FEC_ENET_RXF | FEC_ENET_RXB)
index e3557eca7b6d18706cc8f4e473d85a133767cce4..029b3c7ef29ce7dd4cc05c444b6b55d0dbe8289a 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/bitops.h>
 #include <linux/fs.h>
 #include <linux/platform_device.h>
+#include <linux/of_platform.h>
 
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <asm/cpm1.h>
 #endif
 
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
-#include <linux/of_platform.h>
-#endif
-
 #include "fs_enet.h"
 
 /*************************************************/
@@ -99,7 +96,6 @@ static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op)
 
 static int do_pd_setup(struct fs_enet_private *fep)
 {
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
        struct of_device *ofdev = to_of_device(fep->dev);
 
        fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
@@ -115,27 +111,6 @@ static int do_pd_setup(struct fs_enet_private *fep)
                iounmap(fep->scc.sccp);
                return -EINVAL;
        }
-#else
-       struct platform_device *pdev = to_platform_device(fep->dev);
-       struct resource *r;
-
-       /* Fill out IRQ field */
-       fep->interrupt = platform_get_irq_byname(pdev, "interrupt");
-       if (fep->interrupt < 0)
-               return -EINVAL;
-
-       r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
-       fep->scc.sccp = ioremap(r->start, r->end - r->start + 1);
-
-       if (fep->scc.sccp == NULL)
-               return -EINVAL;
-
-       r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram");
-       fep->scc.ep = ioremap(r->start, r->end - r->start + 1);
-
-       if (fep->scc.ep == NULL)
-               return -EINVAL;
-#endif
 
        return 0;
 }
@@ -149,16 +124,6 @@ static int setup_data(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
 
-#ifndef CONFIG_PPC_CPM_NEW_BINDING
-       struct fs_platform_info *fpi = fep->fpi;
-
-       fep->scc.idx = fs_get_scc_index(fpi->fs_no);
-       if ((unsigned int)fep->fcc.idx >= 4) /* max 4 SCCs */
-               return -EINVAL;
-
-       fpi->cp_command = fep->fcc.idx << 6;
-#endif
-
        do_pd_setup(fep);
 
        fep->scc.hthi = 0;
index 1620030cd33c92e7fd7044ea54c7f1d3c6442925..be4b72f4f49ae8bfec9c87d4fdc9bdbecc203f39 100644 (file)
 #include <linux/mii.h>
 #include <linux/platform_device.h>
 #include <linux/mdio-bitbang.h>
-
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
 #include <linux/of_platform.h>
-#endif
 
 #include "fs_enet.h"
 
@@ -110,7 +107,6 @@ static struct mdiobb_ops bb_ops = {
        .get_mdio_data = mdio_read,
 };
 
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
 static int __devinit fs_mii_bitbang_init(struct mii_bus *bus,
                                          struct device_node *np)
 {
@@ -271,106 +267,3 @@ static void fs_enet_mdio_bb_exit(void)
 
 module_init(fs_enet_mdio_bb_init);
 module_exit(fs_enet_mdio_bb_exit);
-#else
-static int __devinit fs_mii_bitbang_init(struct bb_info *bitbang,
-                                         struct fs_mii_bb_platform_info *fmpi)
-{
-       bitbang->dir = (u32 __iomem *)fmpi->mdio_dir.offset;
-       bitbang->dat = (u32 __iomem *)fmpi->mdio_dat.offset;
-       bitbang->mdio_msk = 1U << (31 - fmpi->mdio_dat.bit);
-       bitbang->mdc_msk = 1U << (31 - fmpi->mdc_dat.bit);
-
-       return 0;
-}
-
-static int __devinit fs_enet_mdio_probe(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct fs_mii_bb_platform_info *pdata;
-       struct mii_bus *new_bus;
-       struct bb_info *bitbang;
-       int err = 0;
-
-       if (NULL == dev)
-               return -EINVAL;
-
-       bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
-
-       if (NULL == bitbang)
-               return -ENOMEM;
-
-       bitbang->ctrl.ops = &bb_ops;
-
-       new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
-
-       if (NULL == new_bus)
-               return -ENOMEM;
-
-       new_bus->name = "BB MII Bus",
-       snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id);
-
-       new_bus->phy_mask = ~0x9;
-       pdata = (struct fs_mii_bb_platform_info *)pdev->dev.platform_data;
-
-       if (NULL == pdata) {
-               printk(KERN_ERR "gfar mdio %d: Missing platform data!\n", pdev->id);
-               return -ENODEV;
-       }
-
-       /*set up workspace*/
-       fs_mii_bitbang_init(bitbang, pdata);
-
-       new_bus->priv = bitbang;
-
-       new_bus->irq = pdata->irq;
-
-       new_bus->dev = dev;
-       dev_set_drvdata(dev, new_bus);
-
-       err = mdiobus_register(new_bus);
-
-       if (0 != err) {
-               printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
-                               new_bus->name);
-               goto bus_register_fail;
-       }
-
-       return 0;
-
-bus_register_fail:
-       free_mdio_bitbang(new_bus);
-       kfree(bitbang);
-
-       return err;
-}
-
-static int fs_enet_mdio_remove(struct device *dev)
-{
-       struct mii_bus *bus = dev_get_drvdata(dev);
-
-       mdiobus_unregister(bus);
-
-       dev_set_drvdata(dev, NULL);
-
-       free_mdio_bitbang(bus);
-
-       return 0;
-}
-
-static struct device_driver fs_enet_bb_mdio_driver = {
-       .name = "fsl-bb-mdio",
-       .bus = &platform_bus_type,
-       .probe = fs_enet_mdio_probe,
-       .remove = fs_enet_mdio_remove,
-};
-
-int fs_enet_mdio_bb_init(void)
-{
-       return driver_register(&fs_enet_bb_mdio_driver);
-}
-
-void fs_enet_mdio_bb_exit(void)
-{
-       driver_unregister(&fs_enet_bb_mdio_driver);
-}
-#endif
index 8f6a43b0e0ff18c73de6185733cce9794aa7c536..695f74cc4398a1ba66933d5130434157866a2ff0 100644 (file)
 #include <linux/ethtool.h>
 #include <linux/bitops.h>
 #include <linux/platform_device.h>
+#include <linux/of_platform.h>
 
 #include <asm/pgtable.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
-#include <linux/of_platform.h>
-#endif
-
 #include "fs_enet.h"
 #include "fec.h"
 
 
 #define FEC_MII_LOOPS  10000
 
-#ifndef CONFIG_PPC_CPM_NEW_BINDING
-static int match_has_phy (struct device *dev, void* data)
-{
-       struct platform_device* pdev = container_of(dev, struct platform_device, dev);
-       struct fs_platform_info* fpi;
-       if(strcmp(pdev->name, (char*)data))
-       {
-           return 0;
-       }
-
-       fpi = pdev->dev.platform_data;
-       if((fpi)&&(fpi->has_phy))
-               return 1;
-       return 0;
-}
-
-static int fs_mii_fec_init(struct fec_info* fec, struct fs_mii_fec_platform_info *fmpi)
-{
-       struct resource *r;
-       fec_t __iomem *fecp;
-       char* name = "fsl-cpm-fec";
-
-       /* we need fec in order to be useful */
-       struct platform_device *fec_pdev =
-               container_of(bus_find_device(&platform_bus_type, NULL, name, match_has_phy),
-                               struct platform_device, dev);
-
-       if(fec_pdev == NULL) {
-               printk(KERN_ERR"Unable to find PHY for %s", name);
-               return -ENODEV;
-       }
-
-       r = platform_get_resource_byname(fec_pdev, IORESOURCE_MEM, "regs");
-
-       fec->fecp = fecp = ioremap(r->start,sizeof(fec_t));
-       fec->mii_speed = fmpi->mii_speed;
-
-       setbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);     /* MII enable */
-       setbits32(&fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN);
-       out_be32(&fecp->fec_ievent, FEC_ENET_MII);
-       out_be32(&fecp->fec_mii_speed, fec->mii_speed);
-
-       return 0;
-}
-#endif
-
 static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
 {
        struct fec_info* fec = bus->priv;
@@ -151,7 +102,6 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus)
        return 0;
 }
 
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
 static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
 {
        const u32 *data;
@@ -286,95 +236,3 @@ static void fs_enet_mdio_fec_exit(void)
 
 module_init(fs_enet_mdio_fec_init);
 module_exit(fs_enet_mdio_fec_exit);
-#else
-static int __devinit fs_enet_fec_mdio_probe(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct fs_mii_fec_platform_info *pdata;
-       struct mii_bus *new_bus;
-       struct fec_info *fec;
-       int err = 0;
-       if (NULL == dev)
-               return -EINVAL;
-       new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
-
-       if (NULL == new_bus)
-               return -ENOMEM;
-
-       fec = kzalloc(sizeof(struct fec_info), GFP_KERNEL);
-
-       if (NULL == fec)
-               return -ENOMEM;
-
-       new_bus->name = "FEC MII Bus",
-       new_bus->read = &fs_enet_fec_mii_read,
-       new_bus->write = &fs_enet_fec_mii_write,
-       new_bus->reset = &fs_enet_fec_mii_reset,
-       snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id);
-
-       pdata = (struct fs_mii_fec_platform_info *)pdev->dev.platform_data;
-
-       if (NULL == pdata) {
-               printk(KERN_ERR "fs_enet FEC mdio %d: Missing platform data!\n", pdev->id);
-               return -ENODEV;
-       }
-
-       /*set up workspace*/
-
-       fs_mii_fec_init(fec, pdata);
-       new_bus->priv = fec;
-
-       new_bus->irq = pdata->irq;
-
-       new_bus->dev = dev;
-       dev_set_drvdata(dev, new_bus);
-
-       err = mdiobus_register(new_bus);
-
-       if (0 != err) {
-               printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
-                               new_bus->name);
-               goto bus_register_fail;
-       }
-
-       return 0;
-
-bus_register_fail:
-       kfree(new_bus);
-
-       return err;
-}
-
-
-static int fs_enet_fec_mdio_remove(struct device *dev)
-{
-       struct mii_bus *bus = dev_get_drvdata(dev);
-
-       mdiobus_unregister(bus);
-
-       dev_set_drvdata(dev, NULL);
-       kfree(bus->priv);
-
-       bus->priv = NULL;
-       kfree(bus);
-
-       return 0;
-}
-
-static struct device_driver fs_enet_fec_mdio_driver = {
-       .name = "fsl-cpm-fec-mdio",
-       .bus = &platform_bus_type,
-       .probe = fs_enet_fec_mdio_probe,
-       .remove = fs_enet_fec_mdio_remove,
-};
-
-int fs_enet_mdio_fec_init(void)
-{
-       return driver_register(&fs_enet_fec_mdio_driver);
-}
-
-void fs_enet_mdio_fec_exit(void)
-{
-       driver_unregister(&fs_enet_fec_mdio_driver);
-}
-#endif
index 45a63172852f1947719a9564df2d7a8e6b4fe021..b8394cf134e8a458ee24169d53e2da58ba142efe 100644 (file)
@@ -134,6 +134,9 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l
 static void gfar_vlan_rx_register(struct net_device *netdev,
                                struct vlan_group *grp);
 void gfar_halt(struct net_device *dev);
+#ifdef CONFIG_PM
+static void gfar_halt_nodisable(struct net_device *dev);
+#endif
 void gfar_start(struct net_device *dev);
 static void gfar_clear_exact_match(struct net_device *dev);
 static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
@@ -207,6 +210,7 @@ static int gfar_probe(struct platform_device *pdev)
 
        spin_lock_init(&priv->txlock);
        spin_lock_init(&priv->rxlock);
+       spin_lock_init(&priv->bflock);
 
        platform_set_drvdata(pdev, dev);
 
@@ -378,6 +382,103 @@ static int gfar_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int gfar_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct net_device *dev = platform_get_drvdata(pdev);
+       struct gfar_private *priv = netdev_priv(dev);
+       unsigned long flags;
+       u32 tempval;
+
+       int magic_packet = priv->wol_en &&
+               (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+
+       netif_device_detach(dev);
+
+       if (netif_running(dev)) {
+               spin_lock_irqsave(&priv->txlock, flags);
+               spin_lock(&priv->rxlock);
+
+               gfar_halt_nodisable(dev);
+
+               /* Disable Tx, and Rx if wake-on-LAN is disabled. */
+               tempval = gfar_read(&priv->regs->maccfg1);
+
+               tempval &= ~MACCFG1_TX_EN;
+
+               if (!magic_packet)
+                       tempval &= ~MACCFG1_RX_EN;
+
+               gfar_write(&priv->regs->maccfg1, tempval);
+
+               spin_unlock(&priv->rxlock);
+               spin_unlock_irqrestore(&priv->txlock, flags);
+
+#ifdef CONFIG_GFAR_NAPI
+               napi_disable(&priv->napi);
+#endif
+
+               if (magic_packet) {
+                       /* Enable interrupt on Magic Packet */
+                       gfar_write(&priv->regs->imask, IMASK_MAG);
+
+                       /* Enable Magic Packet mode */
+                       tempval = gfar_read(&priv->regs->maccfg2);
+                       tempval |= MACCFG2_MPEN;
+                       gfar_write(&priv->regs->maccfg2, tempval);
+               } else {
+                       phy_stop(priv->phydev);
+               }
+       }
+
+       return 0;
+}
+
+static int gfar_resume(struct platform_device *pdev)
+{
+       struct net_device *dev = platform_get_drvdata(pdev);
+       struct gfar_private *priv = netdev_priv(dev);
+       unsigned long flags;
+       u32 tempval;
+       int magic_packet = priv->wol_en &&
+               (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+
+       if (!netif_running(dev)) {
+               netif_device_attach(dev);
+               return 0;
+       }
+
+       if (!magic_packet && priv->phydev)
+               phy_start(priv->phydev);
+
+       /* Disable Magic Packet mode, in case something
+        * else woke us up.
+        */
+
+       spin_lock_irqsave(&priv->txlock, flags);
+       spin_lock(&priv->rxlock);
+
+       tempval = gfar_read(&priv->regs->maccfg2);
+       tempval &= ~MACCFG2_MPEN;
+       gfar_write(&priv->regs->maccfg2, tempval);
+
+       gfar_start(dev);
+
+       spin_unlock(&priv->rxlock);
+       spin_unlock_irqrestore(&priv->txlock, flags);
+
+       netif_device_attach(dev);
+
+#ifdef CONFIG_GFAR_NAPI
+       napi_enable(&priv->napi);
+#endif
+
+       return 0;
+}
+#else
+#define gfar_suspend NULL
+#define gfar_resume NULL
+#endif
 
 /* Reads the controller's registers to determine what interface
  * connects it to the PHY.
@@ -534,8 +635,9 @@ static void init_registers(struct net_device *dev)
 }
 
 
+#ifdef CONFIG_PM
 /* Halt the receive and transmit queues */
-void gfar_halt(struct net_device *dev)
+static void gfar_halt_nodisable(struct net_device *dev)
 {
        struct gfar_private *priv = netdev_priv(dev);
        struct gfar __iomem *regs = priv->regs;
@@ -558,6 +660,15 @@ void gfar_halt(struct net_device *dev)
                         (IEVENT_GRSC | IEVENT_GTSC)))
                        cpu_relax();
        }
+}
+#endif
+
+/* Halt the receive and transmit queues */
+void gfar_halt(struct net_device *dev)
+{
+       struct gfar_private *priv = netdev_priv(dev);
+       struct gfar __iomem *regs = priv->regs;
+       u32 tempval;
 
        /* Disable Rx and Tx */
        tempval = gfar_read(&regs->maccfg1);
@@ -1725,7 +1836,6 @@ static void adjust_link(struct net_device *dev)
                if (!priv->oldlink) {
                        new_state = 1;
                        priv->oldlink = 1;
-                       netif_tx_schedule_all(dev);
                }
        } else if (priv->oldlink) {
                new_state = 1;
@@ -1910,7 +2020,12 @@ static irqreturn_t gfar_error(int irq, void *dev_id)
        u32 events = gfar_read(&priv->regs->ievent);
 
        /* Clear IEVENT */
-       gfar_write(&priv->regs->ievent, IEVENT_ERR_MASK);
+       gfar_write(&priv->regs->ievent, events & IEVENT_ERR_MASK);
+
+       /* Magic Packet is not an error. */
+       if ((priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
+           (events & IEVENT_MAG))
+               events &= ~IEVENT_MAG;
 
        /* Hmm... */
        if (netif_msg_rx_err(priv) || netif_msg_tx_err(priv))
@@ -1978,6 +2093,8 @@ MODULE_ALIAS("platform:fsl-gianfar");
 static struct platform_driver gfar_driver = {
        .probe = gfar_probe,
        .remove = gfar_remove,
+       .suspend = gfar_suspend,
+       .resume = gfar_resume,
        .driver = {
                .name = "fsl-gianfar",
                .owner = THIS_MODULE,
index bead71cb2b16e3e8cd55b4473a39bd384ee33ad4..d59df98bd636ca6a9e2fcb67d0695e00e657bcd1 100644 (file)
@@ -157,6 +157,7 @@ extern const char gfar_driver_version[];
 #define MACCFG2_GMII            0x00000200
 #define MACCFG2_HUGEFRAME      0x00000020
 #define MACCFG2_LENGTHCHECK    0x00000010
+#define MACCFG2_MPEN           0x00000008
 
 #define ECNTRL_INIT_SETTINGS   0x00001000
 #define ECNTRL_TBI_MODE         0x00000020
@@ -229,6 +230,7 @@ extern const char gfar_driver_version[];
 #define IEVENT_CRL             0x00020000
 #define IEVENT_XFUN            0x00010000
 #define IEVENT_RXB0            0x00008000
+#define IEVENT_MAG             0x00000800
 #define IEVENT_GRSC            0x00000100
 #define IEVENT_RXF0            0x00000080
 #define IEVENT_FIR             0x00000008
@@ -241,7 +243,8 @@ extern const char gfar_driver_version[];
 #define IEVENT_ERR_MASK         \
 (IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \
  IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \
- | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR)
+ | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR \
+ | IEVENT_MAG)
 
 #define IMASK_INIT_CLEAR       0x00000000
 #define IMASK_BABR              0x80000000
@@ -259,6 +262,7 @@ extern const char gfar_driver_version[];
 #define IMASK_CRL              0x00020000
 #define IMASK_XFUN             0x00010000
 #define IMASK_RXB0              0x00008000
+#define IMASK_MAG              0x00000800
 #define IMASK_GTSC              0x00000100
 #define IMASK_RXFEN0           0x00000080
 #define IMASK_FIR              0x00000008
@@ -726,10 +730,14 @@ struct gfar_private {
        unsigned int fifo_starve;
        unsigned int fifo_starve_off;
 
+       /* Bitfield update lock */
+       spinlock_t bflock;
+
        unsigned char vlan_enable:1,
                rx_csum_enable:1,
                extended_hash:1,
-               bd_stash_en:1;
+               bd_stash_en:1,
+               wol_en:1; /* Wake-on-LAN enabled */
        unsigned short padding;
 
        unsigned int interruptTransmit;
index 6007147cc1e917c08e79b636d18e6fff56d1040e..fb7d3ccc0fdce8eec47cef3218e39c67746d662f 100644 (file)
@@ -479,14 +479,13 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva
 static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
 {
        struct gfar_private *priv = netdev_priv(dev);
+       unsigned long flags;
        int err = 0;
 
        if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
                return -EOPNOTSUPP;
 
        if (dev->flags & IFF_UP) {
-               unsigned long flags;
-
                /* Halt TX and RX, and process the frames which
                 * have already been received */
                spin_lock_irqsave(&priv->txlock, flags);
@@ -502,7 +501,9 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
                stop_gfar(dev);
        }
 
+       spin_lock_irqsave(&priv->bflock, flags);
        priv->rx_csum_enable = data;
+       spin_unlock_irqrestore(&priv->bflock, flags);
 
        if (dev->flags & IFF_UP)
                err = startup_gfar(dev);
@@ -564,6 +565,38 @@ static void gfar_set_msglevel(struct net_device *dev, uint32_t data)
        priv->msg_enable = data;
 }
 
+#ifdef CONFIG_PM
+static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct gfar_private *priv = netdev_priv(dev);
+
+       if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) {
+               wol->supported = WAKE_MAGIC;
+               wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0;
+       } else {
+               wol->supported = wol->wolopts = 0;
+       }
+}
+
+static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct gfar_private *priv = netdev_priv(dev);
+       unsigned long flags;
+
+       if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
+           wol->wolopts != 0)
+               return -EINVAL;
+
+       if (wol->wolopts & ~WAKE_MAGIC)
+               return -EINVAL;
+
+       spin_lock_irqsave(&priv->bflock, flags);
+       priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0;
+       spin_unlock_irqrestore(&priv->bflock, flags);
+
+       return 0;
+}
+#endif
 
 const struct ethtool_ops gfar_ethtool_ops = {
        .get_settings = gfar_gsettings,
@@ -585,4 +618,8 @@ const struct ethtool_ops gfar_ethtool_ops = {
        .set_tx_csum = gfar_set_tx_csum,
        .get_msglevel = gfar_get_msglevel,
        .set_msglevel = gfar_set_msglevel,
+#ifdef CONFIG_PM
+       .get_wol = gfar_get_wol,
+       .set_wol = gfar_set_wol,
+#endif
 };
index b6500b2aacf221a52567b2b8e15ca824ede9701d..58f4b1d7bf1fc303d5b962b9820aa423c943168b 100644 (file)
@@ -123,6 +123,7 @@ static LIST_HEAD(bpq_devices);
  * off into a separate class since they always nest.
  */
 static struct lock_class_key bpq_netdev_xmit_lock_key;
+static struct lock_class_key bpq_netdev_addr_lock_key;
 
 static void bpq_set_lockdep_class_one(struct net_device *dev,
                                      struct netdev_queue *txq,
@@ -133,6 +134,7 @@ static void bpq_set_lockdep_class_one(struct net_device *dev,
 
 static void bpq_set_lockdep_class(struct net_device *dev)
 {
+       lockdep_set_class(&dev->addr_list_lock, &bpq_netdev_addr_lock_key);
        netdev_for_each_tx_queue(dev, bpq_set_lockdep_class_one, NULL);
 }
 
index ae9629fa6882bb1dd2181e804b9a881a6c49c962..c258a0586e611d641c134f53114c76df0025ec66 100644 (file)
@@ -88,6 +88,7 @@
 static inline void append_crc_ccitt(unsigned char *buffer, int len)
 {
        unsigned int crc = crc_ccitt(0xffff, buffer, len) ^ 0xffff;
+       buffer += len;
        *buffer++ = crc;
        *buffer++ = crc >> 8;
 }
index c2c4f49d7578955de11c6749423d331f786beec6..8239939554bc4474735fb174c8f6f02da9957180 100644 (file)
@@ -262,7 +262,7 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr)
        }
 
        outw(Perf_Page, ioaddr + HP_PAGING);
-       NS8390_init(dev, 0);
+       NS8390p_init(dev, 0);
        /* Leave the 8390 and HP chip reset. */
        outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION);
 
index 8281209ededf9be993b0ad0d2c8ed0e69af2b8bc..0a8c64930ad305fc756d0dfb7addffff50d406a2 100644 (file)
@@ -389,7 +389,7 @@ static void __init
 hp_init_card(struct net_device *dev)
 {
        int irq = dev->irq;
-       NS8390_init(dev, 0);
+       NS8390p_init(dev, 0);
        outb_p(irqmap[irq&0x0f] | HP_RUN,
                   dev->base_addr - NIC_OFFSET + HP_CONFIGURE);
        return;
index 1b7cb29fe68e23eb8900baa00cca1064bec61c05..b602c4dd0d14697eef9fa10ee90c7080c853d269 100644 (file)
@@ -385,7 +385,7 @@ static void igb_configure_msix(struct igb_adapter *adapter)
 
        for (i = 0; i < adapter->num_rx_queues; i++) {
                struct igb_ring *rx_ring = &adapter->rx_ring[i];
-               rx_ring->buddy = 0;
+               rx_ring->buddy = NULL;
                igb_assign_vector(adapter, i, IGB_N0_QUEUE, vector++);
                adapter->eims_enable_mask |= rx_ring->eims_value;
                if (rx_ring->itr_val)
index be7b723c924f941a806c9faf66f11168c9625f5b..e5f3da8468cccd13c49d28125b730d49417dc27b 100644 (file)
@@ -70,8 +70,6 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
         board_82598 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT),
         board_82598 },
-       {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT_DUAL_PORT),
-        board_82598 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
         board_82598 },
 
index 0496d16f9de5f39a690597991c1bdcb4cc0eca9b..daba82bbcb5672fad842e135202abae4bed5c878 100644 (file)
@@ -164,9 +164,7 @@ static void macb_handle_link_change(struct net_device *dev)
        }
 
        if (phydev->link != bp->link) {
-               if (phydev->link)
-                       netif_tx_schedule_all(dev);
-               else {
+               if (!phydev->link) {
                        bp->speed = 0;
                        bp->duplex = -1;
                }
index efbc15567dd326b61887958f29f2c30f712f0304..42394505bb50b9a006b5d582eaef3378b1a9c5e6 100644 (file)
@@ -276,6 +276,7 @@ static int macvlan_change_mtu(struct net_device *dev, int new_mtu)
  * separate class since they always nest.
  */
 static struct lock_class_key macvlan_netdev_xmit_lock_key;
+static struct lock_class_key macvlan_netdev_addr_lock_key;
 
 #define MACVLAN_FEATURES \
        (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
@@ -295,6 +296,8 @@ static void macvlan_set_lockdep_class_one(struct net_device *dev,
 
 static void macvlan_set_lockdep_class(struct net_device *dev)
 {
+       lockdep_set_class(&dev->addr_list_lock,
+                         &macvlan_netdev_addr_lock_key);
        netdev_for_each_tx_queue(dev, macvlan_set_lockdep_class_one, NULL);
 }
 
index 0b32648a213600fcecae9eda9496a63c996b1768..4cb364e67dc65f5d022663794e6d8d0b32a6255d 100644 (file)
@@ -287,7 +287,7 @@ int meth_reset(struct net_device *dev)
 
        /* Initial mode: 10 | Half-duplex | Accept normal packets */
        priv->mac_ctrl = METH_ACCEPT_MCAST | METH_DEFAULT_IPG;
-       if (dev->flags | IFF_PROMISC)
+       if (dev->flags & IFF_PROMISC)
                priv->mac_ctrl |= METH_PROMISC;
        mace->eth.mac_ctrl = priv->mac_ctrl;
 
index 83a877f3a553ee94611dced9e87d28f2222aecaf..8a97a0066a886d5bae454fb7c703900c13dc2326 100644 (file)
@@ -2112,7 +2112,7 @@ static void mv643xx_eth_netpoll(struct net_device *dev)
 
        mv643xx_eth_irq(dev->irq, dev);
 
-       wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_CAUSE_EXT);
+       wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
 }
 #endif
 
index b3981ed972bf7768b4d90520b8f2dc2fecf3b5f3..3ab0e5289f7abd9cc2759870c77d6f8f913abcfd 100644 (file)
@@ -125,7 +125,6 @@ struct myri10ge_cmd {
 
 struct myri10ge_rx_buf {
        struct mcp_kreq_ether_recv __iomem *lanai;      /* lanai ptr for recv ring */
-       u8 __iomem *wc_fifo;    /* w/c rx dma addr fifo address */
        struct mcp_kreq_ether_recv *shadow;     /* host shadow of recv ring */
        struct myri10ge_rx_buffer_state *info;
        struct page *page;
@@ -140,7 +139,6 @@ struct myri10ge_rx_buf {
 
 struct myri10ge_tx_buf {
        struct mcp_kreq_ether_send __iomem *lanai;      /* lanai ptr for sendq */
-       u8 __iomem *wc_fifo;    /* w/c send fifo address */
        struct mcp_kreq_ether_send *req_list;   /* host shadow of sendq */
        char *req_bytes;
        struct myri10ge_tx_buffer_state *info;
@@ -332,10 +330,6 @@ MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed");
 
 static int myri10ge_reset_recover = 1;
 
-static int myri10ge_wcfifo = 0;
-module_param(myri10ge_wcfifo, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled");
-
 static int myri10ge_max_slices = 1;
 module_param(myri10ge_max_slices, int, S_IRUGO);
 MODULE_PARM_DESC(myri10ge_max_slices, "Max tx/rx queues");
@@ -1218,14 +1212,8 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
 
                /* copy 8 descriptors to the firmware at a time */
                if ((idx & 7) == 7) {
-                       if (rx->wc_fifo == NULL)
-                               myri10ge_submit_8rx(&rx->lanai[idx - 7],
-                                                   &rx->shadow[idx - 7]);
-                       else {
-                               mb();
-                               myri10ge_pio_copy(rx->wc_fifo,
-                                                 &rx->shadow[idx - 7], 64);
-                       }
+                       myri10ge_submit_8rx(&rx->lanai[idx - 7],
+                                           &rx->shadow[idx - 7]);
                }
        }
 }
@@ -2229,18 +2217,6 @@ static int myri10ge_get_txrx(struct myri10ge_priv *mgp, int slice)
        ss->rx_big.lanai = (struct mcp_kreq_ether_recv __iomem *)
            (mgp->sram + cmd.data0);
 
-       if (myri10ge_wcfifo && mgp->wc_enabled) {
-               ss->tx.wc_fifo = (u8 __iomem *)
-                   mgp->sram + MXGEFW_ETH_SEND_4 + 64 * slice;
-               ss->rx_small.wc_fifo = (u8 __iomem *)
-                   mgp->sram + MXGEFW_ETH_RECV_SMALL + 64 * slice;
-               ss->rx_big.wc_fifo = (u8 __iomem *)
-                   mgp->sram + MXGEFW_ETH_RECV_BIG + 64 * slice;
-       } else {
-               ss->tx.wc_fifo = NULL;
-               ss->rx_small.wc_fifo = NULL;
-               ss->rx_big.wc_fifo = NULL;
-       }
        return status;
 
 }
@@ -2573,27 +2549,6 @@ myri10ge_submit_req(struct myri10ge_tx_buf *tx, struct mcp_kreq_ether_send *src,
        mb();
 }
 
-static inline void
-myri10ge_submit_req_wc(struct myri10ge_tx_buf *tx,
-                      struct mcp_kreq_ether_send *src, int cnt)
-{
-       tx->req += cnt;
-       mb();
-       while (cnt >= 4) {
-               myri10ge_pio_copy(tx->wc_fifo, src, 64);
-               mb();
-               src += 4;
-               cnt -= 4;
-       }
-       if (cnt > 0) {
-               /* pad it to 64 bytes.  The src is 64 bytes bigger than it
-                * needs to be so that we don't overrun it */
-               myri10ge_pio_copy(tx->wc_fifo + MXGEFW_ETH_SEND_OFFSET(cnt),
-                                 src, 64);
-               mb();
-       }
-}
-
 /*
  * Transmit a packet.  We need to split the packet so that a single
  * segment does not cross myri10ge->tx_boundary, so this makes segment
@@ -2830,10 +2785,7 @@ again:
                                         MXGEFW_FLAGS_FIRST)));
        idx = ((count - 1) + tx->req) & tx->mask;
        tx->info[idx].last = 1;
-       if (tx->wc_fifo == NULL)
-               myri10ge_submit_req(tx, tx->req_list, count);
-       else
-               myri10ge_submit_req_wc(tx, tx->req_list, count);
+       myri10ge_submit_req(tx, tx->req_list, count);
        tx->pkt_start++;
        if ((avail - count) < MXGEFW_MAX_SEND_DESC) {
                tx->stop_queue++;
@@ -3768,14 +3720,14 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (mgp->sram_size > mgp->board_span) {
                dev_err(&pdev->dev, "board span %ld bytes too small\n",
                        mgp->board_span);
-               goto abort_with_wc;
+               goto abort_with_mtrr;
        }
-       mgp->sram = ioremap(mgp->iomem_base, mgp->board_span);
+       mgp->sram = ioremap_wc(mgp->iomem_base, mgp->board_span);
        if (mgp->sram == NULL) {
                dev_err(&pdev->dev, "ioremap failed for %ld bytes at 0x%lx\n",
                        mgp->board_span, mgp->iomem_base);
                status = -ENXIO;
-               goto abort_with_wc;
+               goto abort_with_mtrr;
        }
        memcpy_fromio(mgp->eeprom_strings,
                      mgp->sram + mgp->sram_size - MYRI10GE_EEPROM_STRINGS_SIZE,
@@ -3876,7 +3828,7 @@ abort_with_firmware:
 abort_with_ioremap:
        iounmap(mgp->sram);
 
-abort_with_wc:
+abort_with_mtrr:
 #ifdef CONFIG_MTRR
        if (mgp->mtrr >= 0)
                mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span);
index 14126973bd12f2f5117c89556b15fb298c82d609..2fec6122c7fa09aa1e6192933c4949c3048eee26 100644 (file)
@@ -355,7 +355,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
        }
 
        /* Read the 16 bytes of station address PROM.
-          We must first initialize registers, similar to NS8390_init(eifdev, 0).
+          We must first initialize registers, similar to NS8390p_init(eifdev, 0).
           We can't reliably read the SAPROM address without this.
           (I learned the hard way!). */
        {
index 8f72563469223e08ec87d269318cd39c4c602237..332df75a9ab66a06eb150ede9662d2f843807c0f 100644 (file)
@@ -404,7 +404,7 @@ static int __init ne2_probe1(struct net_device *dev, int slot)
 
        /* Read the 16 bytes of station address PROM.
           We must first initialize registers, similar to
-          NS8390_init(eifdev, 0).
+          NS8390p_init(eifdev, 0).
           We can't reliably read the SAPROM address without this.
           (I learned the hard way!). */
        {
index a07cdc6f7384fc5337cde587ba0879c77f374acf..8e7c4c910d2a75b3e1c6adc2610d9cd9bdf4df29 100644 (file)
@@ -32,4 +32,4 @@
 obj-$(CONFIG_NETXEN_NIC) := netxen_nic.o
 
 netxen_nic-y := netxen_nic_hw.o netxen_nic_main.o netxen_nic_init.o \
-       netxen_nic_isr.o netxen_nic_ethtool.o netxen_nic_niu.o
+       netxen_nic_ethtool.o netxen_nic_niu.o netxen_nic_ctx.o
index da4c4fb9706460d60dce97460574df7c40ad3c51..8e736614407d3c7ae7c6b9bf59a6f8f97fa40a2b 100644 (file)
@@ -54,6 +54,7 @@
 
 #include <linux/mm.h>
 #include <linux/mman.h>
+#include <linux/vmalloc.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 
 #include "netxen_nic_hw.h"
 
-#define _NETXEN_NIC_LINUX_MAJOR 3
-#define _NETXEN_NIC_LINUX_MINOR 4
-#define _NETXEN_NIC_LINUX_SUBVERSION 18
-#define NETXEN_NIC_LINUX_VERSIONID  "3.4.18"
+#define _NETXEN_NIC_LINUX_MAJOR 4
+#define _NETXEN_NIC_LINUX_MINOR 0
+#define _NETXEN_NIC_LINUX_SUBVERSION 0
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.0"
+
+#define NETXEN_VERSION_CODE(a, b, c)   (((a) << 16) + ((b) << 8) + (c))
 
 #define NETXEN_NUM_FLASH_SECTORS (64)
 #define NETXEN_FLASH_SECTOR_SIZE (64 * 1024)
@@ -84,7 +87,7 @@
 #define TX_RINGSIZE    \
        (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count)
 #define RCV_BUFFSIZE   \
-       (sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count)
+       (sizeof(struct netxen_rx_buffer) * rds_ring->max_rx_desc_count)
 #define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
 
 #define NETXEN_NETDEV_STATUS           0x1
 
 #define NX_P2_C0               0x24
 #define NX_P2_C1               0x25
+#define NX_P3_A0               0x30
+#define NX_P3_A2               0x30
+#define NX_P3_B0               0x40
+#define NX_P3_B1               0x41
+
+#define NX_IS_REVISION_P2(REVISION)     (REVISION <= NX_P2_C1)
+#define NX_IS_REVISION_P3(REVISION)     (REVISION >= NX_P3_A0)
 
 #define FIRST_PAGE_GROUP_START 0
 #define FIRST_PAGE_GROUP_END   0x100000
 #define SECOND_PAGE_GROUP_SIZE SECOND_PAGE_GROUP_END - SECOND_PAGE_GROUP_START
 #define THIRD_PAGE_GROUP_SIZE  THIRD_PAGE_GROUP_END - THIRD_PAGE_GROUP_START
 
+#define P2_MAX_MTU                     (8000)
+#define P3_MAX_MTU                     (9600)
+#define NX_ETHERMTU                    1500
+#define NX_MAX_ETHERHDR                32 /* This contains some padding */
+
+#define NX_RX_NORMAL_BUF_MAX_LEN       (NX_MAX_ETHERHDR + NX_ETHERMTU)
+#define NX_P2_RX_JUMBO_BUF_MAX_LEN     (NX_MAX_ETHERHDR + P2_MAX_MTU)
+#define NX_P3_RX_JUMBO_BUF_MAX_LEN     (NX_MAX_ETHERHDR + P3_MAX_MTU)
+#define NX_CT_DEFAULT_RX_BUF_LEN       2048
+
 #define MAX_RX_BUFFER_LENGTH           1760
 #define MAX_RX_JUMBO_BUFFER_LENGTH     8062
 #define MAX_RX_LRO_BUFFER_LENGTH       ((48*1024)-512)
 #define RX_JUMBO_DMA_MAP_LEN   \
        (MAX_RX_JUMBO_BUFFER_LENGTH - 2)
 #define RX_LRO_DMA_MAP_LEN             (MAX_RX_LRO_BUFFER_LENGTH - 2)
-#define NETXEN_ROM_ROUNDUP             0x80000000ULL
 
 /*
  * Maximum number of ring contexts
 #define MAX_RING_CTX 1
 
 /* Opcodes to be used with the commands */
-enum {
-       TX_ETHER_PKT = 0x01,
-/* The following opcodes are for IP checksum   */
-       TX_TCP_PKT,
-       TX_UDP_PKT,
-       TX_IP_PKT,
-       TX_TCP_LSO,
-       TX_IPSEC,
-       TX_IPSEC_CMD
-};
+#define TX_ETHER_PKT   0x01
+#define TX_TCP_PKT     0x02
+#define TX_UDP_PKT     0x03
+#define TX_IP_PKT      0x04
+#define TX_TCP_LSO     0x05
+#define TX_TCP_LSO6    0x06
+#define TX_IPSEC       0x07
+#define TX_IPSEC_CMD   0x0a
+#define TX_TCPV6_PKT   0x0b
+#define TX_UDPV6_PKT   0x0c
 
 /* The following opcodes are for internal consumption. */
 #define NETXEN_CONTROL_OP      0x10
@@ -191,6 +210,7 @@ enum {
 #define MAX_RCV_DESCRIPTORS            16384
 #define MAX_CMD_DESCRIPTORS_HOST       (MAX_CMD_DESCRIPTORS / 4)
 #define MAX_RCV_DESCRIPTORS_1G         (MAX_RCV_DESCRIPTORS / 4)
+#define MAX_RCV_DESCRIPTORS_10G                8192
 #define MAX_JUMBO_RCV_DESCRIPTORS      1024
 #define MAX_LRO_RCV_DESCRIPTORS                64
 #define MAX_RCVSTATUS_DESCRIPTORS      MAX_RCV_DESCRIPTORS
@@ -219,8 +239,6 @@ enum {
 #define MPORT_MULTI_FUNCTION_MODE 0x2222
 
 #include "netxen_nic_phan_reg.h"
-extern unsigned long long netxen_dma_mask;
-extern unsigned long last_schedule_time;
 
 /*
  * NetXen host-peg signal message structure
@@ -289,7 +307,7 @@ struct netxen_ring_ctx {
 #define netxen_set_cmd_desc_port(cmd_desc, var)        \
        ((cmd_desc)->port_ctxid |= ((var) & 0x0F))
 #define netxen_set_cmd_desc_ctxid(cmd_desc, var)       \
-       ((cmd_desc)->port_ctxid |= ((var) & 0xF0))
+       ((cmd_desc)->port_ctxid |= ((var) << 4 & 0xF0))
 
 #define netxen_set_cmd_desc_flags(cmd_desc, val)       \
        (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \
@@ -377,8 +395,8 @@ struct rcv_desc {
 };
 
 /* opcode field in status_desc */
-#define RCV_NIC_PKT    (0xA)
-#define STATUS_NIC_PKT ((RCV_NIC_PKT) << 12)
+#define NETXEN_NIC_RXPKT_DESC  0x04
+#define NETXEN_OLD_RXPKT_DESC  0x3f
 
 /* for status field in status_desc */
 #define STATUS_NEED_CKSUM      (1)
@@ -410,6 +428,8 @@ struct rcv_desc {
        (((sts_data) >> 28) & 0xFFFF)
 #define netxen_get_sts_prot(sts_data)  \
        (((sts_data) >> 44) & 0x0F)
+#define netxen_get_sts_pkt_offset(sts_data)    \
+       (((sts_data) >> 48) & 0x1F)
 #define netxen_get_sts_opcode(sts_data)        \
        (((sts_data) >> 58) & 0x03F)
 
@@ -424,17 +444,30 @@ struct rcv_desc {
 
 struct status_desc {
        /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length
-          28-43 reference_handle, 44-47 protocol, 48-52 unused
+          28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset
           53-55 desc_cnt, 56-57 owner, 58-63 opcode
         */
        __le64 status_desc_data;
-       __le32 hash_value;
-       u8 hash_type;
-       u8 msg_type;
-       u8 unused;
-       /* Bit pattern: 0-6 lro_count indicates frag sequence,
-          7 last_frag indicates last frag */
-       u8 lro;
+       union {
+               struct {
+                       __le32 hash_value;
+                       u8 hash_type;
+                       u8 msg_type;
+                       u8 unused;
+                       union {
+                               /* Bit pattern: 0-6 lro_count indicates frag
+                                * sequence, 7 last_frag indicates last frag
+                                */
+                               u8 lro;
+
+                               /* chained buffers */
+                               u8 nr_frags;
+                       };
+               };
+               struct {
+                       __le16 frag_handles[4];
+               };
+       };
 } __attribute__ ((aligned(16)));
 
 enum {
@@ -464,7 +497,20 @@ typedef enum {
 
        NETXEN_BRDTYPE_P2_SB31_10G_IMEZ = 0x000d,
        NETXEN_BRDTYPE_P2_SB31_10G_HMEZ = 0x000e,
-       NETXEN_BRDTYPE_P2_SB31_10G_CX4 = 0x000f
+       NETXEN_BRDTYPE_P2_SB31_10G_CX4 = 0x000f,
+
+       NETXEN_BRDTYPE_P3_REF_QG = 0x0021,
+       NETXEN_BRDTYPE_P3_HMEZ = 0x0022,
+       NETXEN_BRDTYPE_P3_10G_CX4_LP = 0x0023,
+       NETXEN_BRDTYPE_P3_4_GB = 0x0024,
+       NETXEN_BRDTYPE_P3_IMEZ = 0x0025,
+       NETXEN_BRDTYPE_P3_10G_SFP_PLUS = 0x0026,
+       NETXEN_BRDTYPE_P3_10000_BASE_T = 0x0027,
+       NETXEN_BRDTYPE_P3_XG_LOM = 0x0028,
+       NETXEN_BRDTYPE_P3_4_GB_MM = 0x0029,
+       NETXEN_BRDTYPE_P3_10G_CX4 = 0x0031,
+       NETXEN_BRDTYPE_P3_10G_XFP = 0x0032
+
 } netxen_brdtype_t;
 
 typedef enum {
@@ -747,6 +793,7 @@ struct netxen_cmd_buffer {
 
 /* In rx_buffer, we do not need multiple fragments as is a single buffer */
 struct netxen_rx_buffer {
+       struct list_head list;
        struct sk_buff *skb;
        u64 dma;
        u16 ref_handle;
@@ -765,7 +812,6 @@ struct netxen_rx_buffer {
  * contains interrupt info as well shared hardware info.
  */
 struct netxen_hardware_context {
-       struct pci_dev *pdev;
        void __iomem *pci_base0;
        void __iomem *pci_base1;
        void __iomem *pci_base2;
@@ -773,15 +819,20 @@ struct netxen_hardware_context {
        unsigned long first_page_group_start;
        void __iomem *db_base;
        unsigned long db_len;
+       unsigned long pci_len0;
+
+       u8 cut_through;
+       int qdr_sn_window;
+       int ddr_mn_window;
+       unsigned long mn_win_crb;
+       unsigned long ms_win_crb;
 
        u8 revision_id;
        u16 board_type;
        struct netxen_board_info boardcfg;
-       u32 xg_linkup;
-       u32 qg_linksup;
+       u32 linkup;
        /* Address of cmd ring in Phantom */
        struct cmd_desc_type0 *cmd_desc_head;
-       struct pci_dev *cmd_desc_pdev;
        dma_addr_t cmd_desc_phys_addr;
        struct netxen_adapter *adapter;
        int pci_func;
@@ -813,17 +864,17 @@ struct netxen_adapter_stats {
  * Rcv Descriptor Context. One such per Rcv Descriptor. There may
  * be one Rcv Descriptor for normal packets, one for jumbo and may be others.
  */
-struct netxen_rcv_desc_ctx {
+struct nx_host_rds_ring {
        u32 flags;
        u32 producer;
-       u32 rcv_pending;        /* Num of bufs posted in phantom */
        dma_addr_t phys_addr;
-       struct pci_dev *phys_pdev;
+       u32 crb_rcv_producer;   /* reg offset */
        struct rcv_desc *desc_head;     /* address of rx ring in Phantom */
        u32 max_rx_desc_count;
        u32 dma_size;
        u32 skb_size;
        struct netxen_rx_buffer *rx_buf_arr;    /* rx buffers for receive   */
+       struct list_head free_list;
        int begin_alloc;
 };
 
@@ -834,17 +885,319 @@ struct netxen_rcv_desc_ctx {
  * present elsewhere.
  */
 struct netxen_recv_context {
-       struct netxen_rcv_desc_ctx rcv_desc[NUM_RCV_DESC_RINGS];
-       u32 status_rx_producer;
+       u32 state;
+       u16 context_id;
+       u16 virt_port;
+
+       struct nx_host_rds_ring rds_rings[NUM_RCV_DESC_RINGS];
        u32 status_rx_consumer;
+       u32 crb_sts_consumer;   /* reg offset */
        dma_addr_t rcv_status_desc_phys_addr;
-       struct pci_dev *rcv_status_desc_pdev;
        struct status_desc *rcv_status_desc_head;
 };
 
-#define NETXEN_NIC_MSI_ENABLED 0x02
-#define NETXEN_DMA_MASK        0xfffffffe
-#define NETXEN_DB_MAPSIZE_BYTES    0x1000
+/* New HW context creation */
+
+#define NX_OS_CRB_RETRY_COUNT  4000
+#define NX_CDRP_SIGNATURE_MAKE(pcifn, version) \
+       (((pcifn) & 0xff) | (((version) & 0xff) << 8) | (0xcafe << 16))
+
+#define NX_CDRP_CLEAR          0x00000000
+#define NX_CDRP_CMD_BIT                0x80000000
+
+/*
+ * All responses must have the NX_CDRP_CMD_BIT cleared
+ * in the crb NX_CDRP_CRB_OFFSET.
+ */
+#define NX_CDRP_FORM_RSP(rsp)  (rsp)
+#define NX_CDRP_IS_RSP(rsp)    (((rsp) & NX_CDRP_CMD_BIT) == 0)
+
+#define NX_CDRP_RSP_OK         0x00000001
+#define NX_CDRP_RSP_FAIL       0x00000002
+#define NX_CDRP_RSP_TIMEOUT    0x00000003
+
+/*
+ * All commands must have the NX_CDRP_CMD_BIT set in
+ * the crb NX_CDRP_CRB_OFFSET.
+ */
+#define NX_CDRP_FORM_CMD(cmd)  (NX_CDRP_CMD_BIT | (cmd))
+#define NX_CDRP_IS_CMD(cmd)    (((cmd) & NX_CDRP_CMD_BIT) != 0)
+
+#define NX_CDRP_CMD_SUBMIT_CAPABILITIES     0x00000001
+#define NX_CDRP_CMD_READ_MAX_RDS_PER_CTX    0x00000002
+#define NX_CDRP_CMD_READ_MAX_SDS_PER_CTX    0x00000003
+#define NX_CDRP_CMD_READ_MAX_RULES_PER_CTX  0x00000004
+#define NX_CDRP_CMD_READ_MAX_RX_CTX         0x00000005
+#define NX_CDRP_CMD_READ_MAX_TX_CTX         0x00000006
+#define NX_CDRP_CMD_CREATE_RX_CTX           0x00000007
+#define NX_CDRP_CMD_DESTROY_RX_CTX          0x00000008
+#define NX_CDRP_CMD_CREATE_TX_CTX           0x00000009
+#define NX_CDRP_CMD_DESTROY_TX_CTX          0x0000000a
+#define NX_CDRP_CMD_SETUP_STATISTICS        0x0000000e
+#define NX_CDRP_CMD_GET_STATISTICS          0x0000000f
+#define NX_CDRP_CMD_DELETE_STATISTICS       0x00000010
+#define NX_CDRP_CMD_SET_MTU                 0x00000012
+#define NX_CDRP_CMD_MAX                     0x00000013
+
+#define NX_RCODE_SUCCESS               0
+#define NX_RCODE_NO_HOST_MEM           1
+#define NX_RCODE_NO_HOST_RESOURCE      2
+#define NX_RCODE_NO_CARD_CRB           3
+#define NX_RCODE_NO_CARD_MEM           4
+#define NX_RCODE_NO_CARD_RESOURCE      5
+#define NX_RCODE_INVALID_ARGS          6
+#define NX_RCODE_INVALID_ACTION                7
+#define NX_RCODE_INVALID_STATE         8
+#define NX_RCODE_NOT_SUPPORTED         9
+#define NX_RCODE_NOT_PERMITTED         10
+#define NX_RCODE_NOT_READY             11
+#define NX_RCODE_DOES_NOT_EXIST                12
+#define NX_RCODE_ALREADY_EXISTS                13
+#define NX_RCODE_BAD_SIGNATURE         14
+#define NX_RCODE_CMD_NOT_IMPL          15
+#define NX_RCODE_CMD_INVALID           16
+#define NX_RCODE_TIMEOUT               17
+#define NX_RCODE_CMD_FAILED            18
+#define NX_RCODE_MAX_EXCEEDED          19
+#define NX_RCODE_MAX                   20
+
+#define NX_DESTROY_CTX_RESET           0
+#define NX_DESTROY_CTX_D3_RESET                1
+#define NX_DESTROY_CTX_MAX             2
+
+/*
+ * Capabilities
+ */
+#define NX_CAP_BIT(class, bit)         (1 << bit)
+#define NX_CAP0_LEGACY_CONTEXT         NX_CAP_BIT(0, 0)
+#define NX_CAP0_MULTI_CONTEXT          NX_CAP_BIT(0, 1)
+#define NX_CAP0_LEGACY_MN              NX_CAP_BIT(0, 2)
+#define NX_CAP0_LEGACY_MS              NX_CAP_BIT(0, 3)
+#define NX_CAP0_CUT_THROUGH            NX_CAP_BIT(0, 4)
+#define NX_CAP0_LRO                    NX_CAP_BIT(0, 5)
+#define NX_CAP0_LSO                    NX_CAP_BIT(0, 6)
+#define NX_CAP0_JUMBO_CONTIGUOUS       NX_CAP_BIT(0, 7)
+#define NX_CAP0_LRO_CONTIGUOUS         NX_CAP_BIT(0, 8)
+
+/*
+ * Context state
+ */
+#define NX_HOST_CTX_STATE_FREED                0
+#define NX_HOST_CTX_STATE_ALLOCATED    1
+#define NX_HOST_CTX_STATE_ACTIVE       2
+#define NX_HOST_CTX_STATE_DISABLED     3
+#define NX_HOST_CTX_STATE_QUIESCED     4
+#define NX_HOST_CTX_STATE_MAX          5
+
+/*
+ * Rx context
+ */
+
+typedef struct {
+       u64 host_phys_addr;     /* Ring base addr */
+       u32 ring_size;          /* Ring entries */
+       u16 msi_index;
+       u16 rsvd;               /* Padding */
+} nx_hostrq_sds_ring_t;
+
+typedef struct {
+       u64 host_phys_addr;     /* Ring base addr */
+       u64 buff_size;          /* Packet buffer size */
+       u32 ring_size;          /* Ring entries */
+       u32 ring_kind;          /* Class of ring */
+} nx_hostrq_rds_ring_t;
+
+typedef struct {
+       u64 host_rsp_dma_addr;  /* Response dma'd here */
+       u32 capabilities[4];    /* Flag bit vector */
+       u32 host_int_crb_mode;  /* Interrupt crb usage */
+       u32 host_rds_crb_mode;  /* RDS crb usage */
+       /* These ring offsets are relative to data[0] below */
+       u32 rds_ring_offset;    /* Offset to RDS config */
+       u32 sds_ring_offset;    /* Offset to SDS config */
+       u16 num_rds_rings;      /* Count of RDS rings */
+       u16 num_sds_rings;      /* Count of SDS rings */
+       u16 rsvd1;              /* Padding */
+       u16 rsvd2;              /* Padding */
+       u8  reserved[128];      /* reserve space for future expansion*/
+       /* MUST BE 64-bit aligned.
+          The following is packed:
+          - N hostrq_rds_rings
+          - N hostrq_sds_rings */
+       char data[0];
+} nx_hostrq_rx_ctx_t;
+
+typedef struct {
+       u32 host_producer_crb;  /* Crb to use */
+       u32 rsvd1;              /* Padding */
+} nx_cardrsp_rds_ring_t;
+
+typedef struct {
+       u32 host_consumer_crb;  /* Crb to use */
+       u32 interrupt_crb;      /* Crb to use */
+} nx_cardrsp_sds_ring_t;
+
+typedef struct {
+       /* These ring offsets are relative to data[0] below */
+       u32 rds_ring_offset;    /* Offset to RDS config */
+       u32 sds_ring_offset;    /* Offset to SDS config */
+       u32 host_ctx_state;     /* Starting State */
+       u32 num_fn_per_port;    /* How many PCI fn share the port */
+       u16 num_rds_rings;      /* Count of RDS rings */
+       u16 num_sds_rings;      /* Count of SDS rings */
+       u16 context_id;         /* Handle for context */
+       u8  phys_port;          /* Physical id of port */
+       u8  virt_port;          /* Virtual/Logical id of port */
+       u8  reserved[128];      /* save space for future expansion */
+       /*  MUST BE 64-bit aligned.
+          The following is packed:
+          - N cardrsp_rds_rings
+          - N cardrs_sds_rings */
+       char data[0];
+} nx_cardrsp_rx_ctx_t;
+
+#define SIZEOF_HOSTRQ_RX(HOSTRQ_RX, rds_rings, sds_rings)      \
+       (sizeof(HOSTRQ_RX) +                                    \
+       (rds_rings)*(sizeof(nx_hostrq_rds_ring_t)) +            \
+       (sds_rings)*(sizeof(nx_hostrq_sds_ring_t)))
+
+#define SIZEOF_CARDRSP_RX(CARDRSP_RX, rds_rings, sds_rings)    \
+       (sizeof(CARDRSP_RX) +                                   \
+       (rds_rings)*(sizeof(nx_cardrsp_rds_ring_t)) +           \
+       (sds_rings)*(sizeof(nx_cardrsp_sds_ring_t)))
+
+/*
+ * Tx context
+ */
+
+typedef struct {
+       u64 host_phys_addr;     /* Ring base addr */
+       u32 ring_size;          /* Ring entries */
+       u32 rsvd;               /* Padding */
+} nx_hostrq_cds_ring_t;
+
+typedef struct {
+       u64 host_rsp_dma_addr;  /* Response dma'd here */
+       u64 cmd_cons_dma_addr;  /*  */
+       u64 dummy_dma_addr;     /*  */
+       u32 capabilities[4];    /* Flag bit vector */
+       u32 host_int_crb_mode;  /* Interrupt crb usage */
+       u32 rsvd1;              /* Padding */
+       u16 rsvd2;              /* Padding */
+       u16 interrupt_ctl;
+       u16 msi_index;
+       u16 rsvd3;              /* Padding */
+       nx_hostrq_cds_ring_t cds_ring;  /* Desc of cds ring */
+       u8  reserved[128];      /* future expansion */
+} nx_hostrq_tx_ctx_t;
+
+typedef struct {
+       u32 host_producer_crb;  /* Crb to use */
+       u32 interrupt_crb;      /* Crb to use */
+} nx_cardrsp_cds_ring_t;
+
+typedef struct {
+       u32 host_ctx_state;     /* Starting state */
+       u16 context_id;         /* Handle for context */
+       u8  phys_port;          /* Physical id of port */
+       u8  virt_port;          /* Virtual/Logical id of port */
+       nx_cardrsp_cds_ring_t cds_ring; /* Card cds settings */
+       u8  reserved[128];      /* future expansion */
+} nx_cardrsp_tx_ctx_t;
+
+#define SIZEOF_HOSTRQ_TX(HOSTRQ_TX)    (sizeof(HOSTRQ_TX))
+#define SIZEOF_CARDRSP_TX(CARDRSP_TX)  (sizeof(CARDRSP_TX))
+
+/* CRB */
+
+#define NX_HOST_RDS_CRB_MODE_UNIQUE    0
+#define NX_HOST_RDS_CRB_MODE_SHARED    1
+#define NX_HOST_RDS_CRB_MODE_CUSTOM    2
+#define NX_HOST_RDS_CRB_MODE_MAX       3
+
+#define NX_HOST_INT_CRB_MODE_UNIQUE    0
+#define NX_HOST_INT_CRB_MODE_SHARED    1
+#define NX_HOST_INT_CRB_MODE_NORX      2
+#define NX_HOST_INT_CRB_MODE_NOTX      3
+#define NX_HOST_INT_CRB_MODE_NORXTX    4
+
+
+/* MAC */
+
+#define MC_COUNT_P2    16
+#define MC_COUNT_P3    38
+
+#define NETXEN_MAC_NOOP        0
+#define NETXEN_MAC_ADD 1
+#define NETXEN_MAC_DEL 2
+
+typedef struct nx_mac_list_s {
+       struct nx_mac_list_s *next;
+       uint8_t mac_addr[MAX_ADDR_LEN];
+} nx_mac_list_t;
+
+/*
+ * Interrupt coalescing defaults. The defaults are for 1500 MTU. It is
+ * adjusted based on configured MTU.
+ */
+#define NETXEN_DEFAULT_INTR_COALESCE_RX_TIME_US        3
+#define NETXEN_DEFAULT_INTR_COALESCE_RX_PACKETS        256
+#define NETXEN_DEFAULT_INTR_COALESCE_TX_PACKETS        64
+#define NETXEN_DEFAULT_INTR_COALESCE_TX_TIME_US        4
+
+#define NETXEN_NIC_INTR_DEFAULT                        0x04
+
+typedef union {
+       struct {
+               uint16_t        rx_packets;
+               uint16_t        rx_time_us;
+               uint16_t        tx_packets;
+               uint16_t        tx_time_us;
+       } data;
+       uint64_t                word;
+} nx_nic_intr_coalesce_data_t;
+
+typedef struct {
+       uint16_t                        stats_time_us;
+       uint16_t                        rate_sample_time;
+       uint16_t                        flags;
+       uint16_t                        rsvd_1;
+       uint32_t                        low_threshold;
+       uint32_t                        high_threshold;
+       nx_nic_intr_coalesce_data_t     normal;
+       nx_nic_intr_coalesce_data_t     low;
+       nx_nic_intr_coalesce_data_t     high;
+       nx_nic_intr_coalesce_data_t     irq;
+} nx_nic_intr_coalesce_t;
+
+typedef struct {
+       u64 qhdr;
+       u64 req_hdr;
+       u64 words[6];
+} nx_nic_req_t;
+
+typedef struct {
+       u8 op;
+       u8 tag;
+       u8 mac_addr[6];
+} nx_mac_req_t;
+
+#define MAX_PENDING_DESC_BLOCK_SIZE    64
+
+#define NETXEN_NIC_MSI_ENABLED         0x02
+#define NETXEN_NIC_MSIX_ENABLED                0x04
+#define NETXEN_IS_MSI_FAMILY(adapter) \
+       ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))
+
+#define MSIX_ENTRIES_PER_ADAPTER       8
+#define NETXEN_MSIX_TBL_SPACE          8192
+#define NETXEN_PCI_REG_MSIX_TBL                0x44
+
+#define NETXEN_DB_MAPSIZE_BYTES        0x1000
+
+#define NETXEN_NETDEV_WEIGHT 120
+#define NETXEN_ADAPTER_UP_MAGIC 777
+#define NETXEN_NIC_PEG_TUNE 0
 
 struct netxen_dummy_dma {
        void *addr;
@@ -854,46 +1207,65 @@ struct netxen_dummy_dma {
 struct netxen_adapter {
        struct netxen_hardware_context ahw;
 
-       struct netxen_adapter *master;
        struct net_device *netdev;
        struct pci_dev *pdev;
+       int pci_using_dac;
        struct napi_struct napi;
        struct net_device_stats net_stats;
-       unsigned char mac_addr[ETH_ALEN];
        int mtu;
        int portnum;
        u8 physical_port;
+       u16 tx_context_id;
+
+       uint8_t         mc_enabled;
+       uint8_t         max_mc_count;
+       nx_mac_list_t   *mac_list;
+
+       struct netxen_legacy_intr_set legacy_intr;
+       u32     crb_intr_mask;
 
        struct work_struct watchdog_task;
        struct timer_list watchdog_timer;
        struct work_struct  tx_timeout_task;
 
        u32 curr_window;
+       u32 crb_win;
+       rwlock_t adapter_lock;
+
+       uint64_t dma_mask;
 
        u32 cmd_producer;
        __le32 *cmd_consumer;
        u32 last_cmd_consumer;
+       u32 crb_addr_cmd_producer;
+       u32 crb_addr_cmd_consumer;
 
        u32 max_tx_desc_count;
        u32 max_rx_desc_count;
        u32 max_jumbo_rx_desc_count;
        u32 max_lro_rx_desc_count;
 
+       int max_rds_rings;
+
        u32 flags;
        u32 irq;
        int driver_mismatch;
        u32 temp;
 
+       u32 fw_major;
+
+       u8 msix_supported;
+       u8 max_possible_rss_rings;
+       struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
+
        struct netxen_adapter_stats stats;
 
-       u16 portno;
        u16 link_speed;
        u16 link_duplex;
        u16 state;
        u16 link_autoneg;
        int rx_csum;
        int status;
-       spinlock_t stats_lock;
 
        struct netxen_cmd_buffer *cmd_buf_arr;  /* Command buffers for xmit */
 
@@ -905,25 +1277,33 @@ struct netxen_adapter {
 
        int is_up;
        struct netxen_dummy_dma dummy_dma;
+       nx_nic_intr_coalesce_t coal;
 
        /* Context interface shared between card and host */
        struct netxen_ring_ctx *ctx_desc;
-       struct pci_dev *ctx_desc_pdev;
        dma_addr_t ctx_desc_phys_addr;
        int intr_scheme;
        int msi_mode;
        int (*enable_phy_interrupts) (struct netxen_adapter *);
        int (*disable_phy_interrupts) (struct netxen_adapter *);
-       void (*handle_phy_intr) (struct netxen_adapter *);
        int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t);
        int (*set_mtu) (struct netxen_adapter *, int);
        int (*set_promisc) (struct netxen_adapter *, netxen_niu_prom_mode_t);
-       int (*unset_promisc) (struct netxen_adapter *, netxen_niu_prom_mode_t);
        int (*phy_read) (struct netxen_adapter *, long reg, u32 *);
        int (*phy_write) (struct netxen_adapter *, long reg, u32 val);
        int (*init_port) (struct netxen_adapter *, int);
-       void (*init_niu) (struct netxen_adapter *);
        int (*stop_port) (struct netxen_adapter *);
+
+       int (*hw_read_wx)(struct netxen_adapter *, ulong, void *, int);
+       int (*hw_write_wx)(struct netxen_adapter *, ulong, void *, int);
+       int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int);
+       int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int);
+       int (*pci_write_immediate)(struct netxen_adapter *, u64, u32);
+       u32 (*pci_read_immediate)(struct netxen_adapter *, u64);
+       void (*pci_write_normalize)(struct netxen_adapter *, u64, u32);
+       u32 (*pci_read_normalize)(struct netxen_adapter *, u64);
+       unsigned long (*pci_set_window)(struct netxen_adapter *,
+                       unsigned long long);
 };                             /* netxen_adapter structure */
 
 /*
@@ -988,8 +1368,6 @@ int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter);
 int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter);
 int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter);
 int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter);
-void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter);
-void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter);
 int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
                            __u32 * readval);
 int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
@@ -998,27 +1376,61 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
 /* Functions available from netxen_nic_hw.c */
 int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu);
 int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu);
-void netxen_nic_init_niu_gb(struct netxen_adapter *adapter);
-void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw);
 void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val);
 int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off);
 void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value);
-void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value);
+void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value);
+void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value);
+void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value);
 
 int netxen_nic_get_board_info(struct netxen_adapter *adapter);
-int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data,
-                         int len);
-int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
-                          int len);
+
+int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
+               ulong off, void *data, int len);
+int netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
+               ulong off, void *data, int len);
+int netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
+               u64 off, void *data, int size);
+int netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
+               u64 off, void *data, int size);
+int netxen_nic_pci_write_immediate_128M(struct netxen_adapter *adapter,
+               u64 off, u32 data);
+u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off);
+void netxen_nic_pci_write_normalize_128M(struct netxen_adapter *adapter,
+               u64 off, u32 data);
+u32 netxen_nic_pci_read_normalize_128M(struct netxen_adapter *adapter, u64 off);
+unsigned long netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
+               unsigned long long addr);
+void netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter,
+               u32 wndw);
+
+int netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
+               ulong off, void *data, int len);
+int netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
+               ulong off, void *data, int len);
+int netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
+               u64 off, void *data, int size);
+int netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
+               u64 off, void *data, int size);
 void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
                                 unsigned long off, int data);
+int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
+               u64 off, u32 data);
+u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off);
+void netxen_nic_pci_write_normalize_2M(struct netxen_adapter *adapter,
+               u64 off, u32 data);
+u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off);
+unsigned long netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
+               unsigned long long addr);
 
 /* Functions from netxen_nic_init.c */
 void netxen_free_adapter_offload(struct netxen_adapter *adapter);
 int netxen_initialize_adapter_offload(struct netxen_adapter *adapter);
 int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
+int netxen_receive_peg_ready(struct netxen_adapter *adapter);
 int netxen_load_firmware(struct netxen_adapter *adapter);
 int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
+
 int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp);
 int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
                                u8 *bytes, size_t size);
@@ -1032,33 +1444,43 @@ void netxen_halt_pegs(struct netxen_adapter *adapter);
 
 int netxen_rom_se(struct netxen_adapter *adapter, int addr);
 
-/* Functions from netxen_nic_isr.c */
-void netxen_initialize_adapter_sw(struct netxen_adapter *adapter);
-void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr,
-                  struct pci_dev **used_dev);
+int netxen_alloc_sw_resources(struct netxen_adapter *adapter);
+void netxen_free_sw_resources(struct netxen_adapter *adapter);
+
+int netxen_alloc_hw_resources(struct netxen_adapter *adapter);
+void netxen_free_hw_resources(struct netxen_adapter *adapter);
+
+void netxen_release_rx_buffers(struct netxen_adapter *adapter);
+void netxen_release_tx_buffers(struct netxen_adapter *adapter);
+
 void netxen_initialize_adapter_ops(struct netxen_adapter *adapter);
 int netxen_init_firmware(struct netxen_adapter *adapter);
-void netxen_free_hw_resources(struct netxen_adapter *adapter);
 void netxen_tso_check(struct netxen_adapter *adapter,
                      struct cmd_desc_type0 *desc, struct sk_buff *skb);
-int netxen_nic_hw_resources(struct netxen_adapter *adapter);
 void netxen_nic_clear_stats(struct netxen_adapter *adapter);
 void netxen_watchdog_task(struct work_struct *work);
 void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
                            u32 ringid);
 int netxen_process_cmd_ring(struct netxen_adapter *adapter);
 u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
-void netxen_nic_set_multi(struct net_device *netdev);
+void netxen_p2_nic_set_multi(struct net_device *netdev);
+void netxen_p3_nic_set_multi(struct net_device *netdev);
+int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
+
+u32 nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, u32 mtu);
 int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
+
 int netxen_nic_set_mac(struct net_device *netdev, void *p);
 struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
 
+void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
+               uint32_t crb_producer);
 
 /*
  * NetXen Board information
  */
 
-#define NETXEN_MAX_SHORT_NAME 16
+#define NETXEN_MAX_SHORT_NAME 32
 struct netxen_brdinfo {
        netxen_brdtype_t brdtype;       /* type of board */
        long ports;             /* max no of physical ports */
@@ -1072,6 +1494,17 @@ static const struct netxen_brdinfo netxen_boards[] = {
        {NETXEN_BRDTYPE_P2_SB31_10G, 1, "XGb XFP"},
        {NETXEN_BRDTYPE_P2_SB35_4G, 4, "Quad Gb"},
        {NETXEN_BRDTYPE_P2_SB31_2G, 2, "Dual Gb"},
+       {NETXEN_BRDTYPE_P3_REF_QG,  4, "Reference Quad Gig "},
+       {NETXEN_BRDTYPE_P3_HMEZ,    2, "Dual XGb HMEZ"},
+       {NETXEN_BRDTYPE_P3_10G_CX4_LP,   2, "Dual XGb CX4 LP"},
+       {NETXEN_BRDTYPE_P3_4_GB,    4, "Quad Gig LP"},
+       {NETXEN_BRDTYPE_P3_IMEZ,    2, "Dual XGb IMEZ"},
+       {NETXEN_BRDTYPE_P3_10G_SFP_PLUS, 2, "Dual XGb SFP+ LP"},
+       {NETXEN_BRDTYPE_P3_10000_BASE_T, 1, "XGB 10G BaseT LP"},
+       {NETXEN_BRDTYPE_P3_XG_LOM,  2, "Dual XGb LOM"},
+       {NETXEN_BRDTYPE_P3_4_GB_MM, 4, "Quad GB - March Madness"},
+       {NETXEN_BRDTYPE_P3_10G_CX4, 2, "Reference Dual CX4 Option"},
+       {NETXEN_BRDTYPE_P3_10G_XFP, 1, "Reference Single XFP Option"}
 };
 
 #define NUM_SUPPORTED_BOARDS ARRAY_SIZE(netxen_boards)
@@ -1097,7 +1530,7 @@ dma_watchdog_shutdown_request(struct netxen_adapter *adapter)
        u32 ctrl;
 
        /* check if already inactive */
-       if (netxen_nic_hw_read_wx(adapter,
+       if (adapter->hw_read_wx(adapter,
            NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
                printk(KERN_ERR "failed to read dma watchdog status\n");
 
@@ -1117,7 +1550,7 @@ dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter)
 {
        u32 ctrl;
 
-       if (netxen_nic_hw_read_wx(adapter,
+       if (adapter->hw_read_wx(adapter,
            NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
                printk(KERN_ERR "failed to read dma watchdog status\n");
 
@@ -1129,7 +1562,7 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
 {
        u32 ctrl;
 
-       if (netxen_nic_hw_read_wx(adapter,
+       if (adapter->hw_read_wx(adapter,
                NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
                printk(KERN_ERR "failed to read dma watchdog status\n");
 
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
new file mode 100644 (file)
index 0000000..64babc5
--- /dev/null
@@ -0,0 +1,710 @@
+/*
+ * Copyright (C) 2003 - 2008 NetXen, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.
+ *
+ * Contact Information:
+ *    info@netxen.com
+ * NetXen,
+ * 3965 Freedom Circle, Fourth floor,
+ * Santa Clara, CA 95054
+ *
+ */
+
+#include "netxen_nic_hw.h"
+#include "netxen_nic.h"
+#include "netxen_nic_phan_reg.h"
+
+#define NXHAL_VERSION  1
+
+static int
+netxen_api_lock(struct netxen_adapter *adapter)
+{
+       u32 done = 0, timeout = 0;
+
+       for (;;) {
+               /* Acquire PCIE HW semaphore5 */
+               netxen_nic_read_w0(adapter,
+                       NETXEN_PCIE_REG(PCIE_SEM5_LOCK), &done);
+
+               if (done == 1)
+                       break;
+
+               if (++timeout >= NX_OS_CRB_RETRY_COUNT) {
+                       printk(KERN_ERR "%s: lock timeout.\n", __func__);
+                       return -1;
+               }
+
+               msleep(1);
+       }
+
+#if 0
+       netxen_nic_write_w1(adapter,
+               NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER);
+#endif
+       return 0;
+}
+
+static int
+netxen_api_unlock(struct netxen_adapter *adapter)
+{
+       u32 val;
+
+       /* Release PCIE HW semaphore5 */
+       netxen_nic_read_w0(adapter,
+               NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK), &val);
+       return 0;
+}
+
+static u32
+netxen_poll_rsp(struct netxen_adapter *adapter)
+{
+       u32 raw_rsp, rsp = NX_CDRP_RSP_OK;
+       int     timeout = 0;
+
+       do {
+               /* give atleast 1ms for firmware to respond */
+               msleep(1);
+
+               if (++timeout > NX_OS_CRB_RETRY_COUNT)
+                       return NX_CDRP_RSP_TIMEOUT;
+
+               netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET,
+                               &raw_rsp);
+
+               rsp = le32_to_cpu(raw_rsp);
+       } while (!NX_CDRP_IS_RSP(rsp));
+
+       return rsp;
+}
+
+static u32
+netxen_issue_cmd(struct netxen_adapter *adapter,
+       u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd)
+{
+       u32 rsp;
+       u32 signature = 0;
+       u32 rcode = NX_RCODE_SUCCESS;
+
+       signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version);
+
+       /* Acquire semaphore before accessing CRB */
+       if (netxen_api_lock(adapter))
+               return NX_RCODE_TIMEOUT;
+
+       netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET,
+                       cpu_to_le32(signature));
+
+       netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET,
+                       cpu_to_le32(arg1));
+
+       netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET,
+                       cpu_to_le32(arg2));
+
+       netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET,
+                       cpu_to_le32(arg3));
+
+       netxen_nic_write_w1(adapter, NX_CDRP_CRB_OFFSET,
+                       cpu_to_le32(NX_CDRP_FORM_CMD(cmd)));
+
+       rsp = netxen_poll_rsp(adapter);
+
+       if (rsp == NX_CDRP_RSP_TIMEOUT) {
+               printk(KERN_ERR "%s: card response timeout.\n",
+                               netxen_nic_driver_name);
+
+               rcode = NX_RCODE_TIMEOUT;
+       } else if (rsp == NX_CDRP_RSP_FAIL) {
+               netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET, &rcode);
+               rcode = le32_to_cpu(rcode);
+
+               printk(KERN_ERR "%s: failed card response code:0x%x\n",
+                               netxen_nic_driver_name, rcode);
+       }
+
+       /* Release semaphore */
+       netxen_api_unlock(adapter);
+
+       return rcode;
+}
+
+u32
+nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, u32 mtu)
+{
+       u32 rcode = NX_RCODE_SUCCESS;
+       struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
+
+       if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
+               rcode = netxen_issue_cmd(adapter,
+                               adapter->ahw.pci_func,
+                               NXHAL_VERSION,
+                               recv_ctx->context_id,
+                               mtu,
+                               0,
+                               NX_CDRP_CMD_SET_MTU);
+
+       return rcode;
+}
+
+static int
+nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
+{
+       void *addr;
+       nx_hostrq_rx_ctx_t *prq;
+       nx_cardrsp_rx_ctx_t *prsp;
+       nx_hostrq_rds_ring_t *prq_rds;
+       nx_hostrq_sds_ring_t *prq_sds;
+       nx_cardrsp_rds_ring_t *prsp_rds;
+       nx_cardrsp_sds_ring_t *prsp_sds;
+       struct nx_host_rds_ring *rds_ring;
+
+       dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
+       u64 phys_addr;
+
+       int i, nrds_rings, nsds_rings;
+       size_t rq_size, rsp_size;
+       u32 cap, reg;
+
+       int err;
+
+       struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
+
+       /* only one sds ring for now */
+       nrds_rings = adapter->max_rds_rings;
+       nsds_rings = 1;
+
+       rq_size =
+               SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings);
+       rsp_size =
+               SIZEOF_CARDRSP_RX(nx_cardrsp_rx_ctx_t, nrds_rings, nsds_rings);
+
+       addr = pci_alloc_consistent(adapter->pdev,
+                               rq_size, &hostrq_phys_addr);
+       if (addr == NULL)
+               return -ENOMEM;
+       prq = (nx_hostrq_rx_ctx_t *)addr;
+
+       addr = pci_alloc_consistent(adapter->pdev,
+                       rsp_size, &cardrsp_phys_addr);
+       if (addr == NULL) {
+               err = -ENOMEM;
+               goto out_free_rq;
+       }
+       prsp = (nx_cardrsp_rx_ctx_t *)addr;
+
+       prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr);
+
+       cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN);
+       cap |= (NX_CAP0_JUMBO_CONTIGUOUS | NX_CAP0_LRO_CONTIGUOUS);
+
+       prq->capabilities[0] = cpu_to_le32(cap);
+       prq->host_int_crb_mode =
+               cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED);
+       prq->host_rds_crb_mode =
+               cpu_to_le32(NX_HOST_RDS_CRB_MODE_UNIQUE);
+
+       prq->num_rds_rings = cpu_to_le16(nrds_rings);
+       prq->num_sds_rings = cpu_to_le16(nsds_rings);
+       prq->rds_ring_offset = 0;
+       prq->sds_ring_offset = prq->rds_ring_offset +
+               (sizeof(nx_hostrq_rds_ring_t) * nrds_rings);
+
+       prq_rds = (nx_hostrq_rds_ring_t *)(prq->data + prq->rds_ring_offset);
+
+       for (i = 0; i < nrds_rings; i++) {
+
+               rds_ring = &recv_ctx->rds_rings[i];
+
+               prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
+               prq_rds[i].ring_size = cpu_to_le32(rds_ring->max_rx_desc_count);
+               prq_rds[i].ring_kind = cpu_to_le32(i);
+               prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size);
+       }
+
+       prq_sds = (nx_hostrq_sds_ring_t *)(prq->data + prq->sds_ring_offset);
+
+       prq_sds[0].host_phys_addr =
+               cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
+       prq_sds[0].ring_size = cpu_to_le32(adapter->max_rx_desc_count);
+       /* only one msix vector for now */
+       prq_sds[0].msi_index = cpu_to_le32(0);
+
+       /* now byteswap offsets */
+       prq->rds_ring_offset = cpu_to_le32(prq->rds_ring_offset);
+       prq->sds_ring_offset = cpu_to_le32(prq->sds_ring_offset);
+
+       phys_addr = hostrq_phys_addr;
+       err = netxen_issue_cmd(adapter,
+                       adapter->ahw.pci_func,
+                       NXHAL_VERSION,
+                       (u32)(phys_addr >> 32),
+                       (u32)(phys_addr & 0xffffffff),
+                       rq_size,
+                       NX_CDRP_CMD_CREATE_RX_CTX);
+       if (err) {
+               printk(KERN_WARNING
+                       "Failed to create rx ctx in firmware%d\n", err);
+               goto out_free_rsp;
+       }
+
+
+       prsp_rds = ((nx_cardrsp_rds_ring_t *)
+                        &prsp->data[prsp->rds_ring_offset]);
+
+       for (i = 0; i < le32_to_cpu(prsp->num_rds_rings); i++) {
+               rds_ring = &recv_ctx->rds_rings[i];
+
+               reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
+               rds_ring->crb_rcv_producer = NETXEN_NIC_REG(reg - 0x200);
+       }
+
+       prsp_sds = ((nx_cardrsp_sds_ring_t *)
+                       &prsp->data[prsp->sds_ring_offset]);
+       reg = le32_to_cpu(prsp_sds[0].host_consumer_crb);
+       recv_ctx->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
+
+       reg = le32_to_cpu(prsp_sds[0].interrupt_crb);
+       adapter->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);
+
+       recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
+       recv_ctx->context_id = le16_to_cpu(prsp->context_id);
+       recv_ctx->virt_port = le16_to_cpu(prsp->virt_port);
+
+out_free_rsp:
+       pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr);
+out_free_rq:
+       pci_free_consistent(adapter->pdev, rq_size, prq, hostrq_phys_addr);
+       return err;
+}
+
+static void
+nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter)
+{
+       struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
+
+       if (netxen_issue_cmd(adapter,
+                       adapter->ahw.pci_func,
+                       NXHAL_VERSION,
+                       recv_ctx->context_id,
+                       NX_DESTROY_CTX_RESET,
+                       0,
+                       NX_CDRP_CMD_DESTROY_RX_CTX)) {
+
+               printk(KERN_WARNING
+                       "%s: Failed to destroy rx ctx in firmware\n",
+                       netxen_nic_driver_name);
+       }
+}
+
+static int
+nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
+{
+       nx_hostrq_tx_ctx_t      *prq;
+       nx_hostrq_cds_ring_t    *prq_cds;
+       nx_cardrsp_tx_ctx_t     *prsp;
+       void    *rq_addr, *rsp_addr;
+       size_t  rq_size, rsp_size;
+       u32     temp;
+       int     err = 0;
+       u64     offset, phys_addr;
+       dma_addr_t      rq_phys_addr, rsp_phys_addr;
+
+       rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
+       rq_addr = pci_alloc_consistent(adapter->pdev,
+               rq_size, &rq_phys_addr);
+       if (!rq_addr)
+               return -ENOMEM;
+
+       rsp_size = SIZEOF_CARDRSP_TX(nx_cardrsp_tx_ctx_t);
+       rsp_addr = pci_alloc_consistent(adapter->pdev,
+               rsp_size, &rsp_phys_addr);
+       if (!rsp_addr) {
+               err = -ENOMEM;
+               goto out_free_rq;
+       }
+
+       memset(rq_addr, 0, rq_size);
+       prq = (nx_hostrq_tx_ctx_t *)rq_addr;
+
+       memset(rsp_addr, 0, rsp_size);
+       prsp = (nx_cardrsp_tx_ctx_t *)rsp_addr;
+
+       prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr);
+
+       temp = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN | NX_CAP0_LSO);
+       prq->capabilities[0] = cpu_to_le32(temp);
+
+       prq->host_int_crb_mode =
+               cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED);
+
+       prq->interrupt_ctl = 0;
+       prq->msi_index = 0;
+
+       prq->dummy_dma_addr = cpu_to_le64(adapter->dummy_dma.phys_addr);
+
+       offset = adapter->ctx_desc_phys_addr+sizeof(struct netxen_ring_ctx);
+       prq->cmd_cons_dma_addr = cpu_to_le64(offset);
+
+       prq_cds = &prq->cds_ring;
+
+       prq_cds->host_phys_addr =
+               cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
+
+       prq_cds->ring_size = cpu_to_le32(adapter->max_tx_desc_count);
+
+       phys_addr = rq_phys_addr;
+       err = netxen_issue_cmd(adapter,
+                       adapter->ahw.pci_func,
+                       NXHAL_VERSION,
+                       (u32)(phys_addr >> 32),
+                       ((u32)phys_addr & 0xffffffff),
+                       rq_size,
+                       NX_CDRP_CMD_CREATE_TX_CTX);
+
+       if (err == NX_RCODE_SUCCESS) {
+               temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
+               adapter->crb_addr_cmd_producer =
+                       NETXEN_NIC_REG(temp - 0x200);
+#if 0
+               adapter->tx_state =
+                       le32_to_cpu(prsp->host_ctx_state);
+#endif
+               adapter->tx_context_id =
+                       le16_to_cpu(prsp->context_id);
+       } else {
+               printk(KERN_WARNING
+                       "Failed to create tx ctx in firmware%d\n", err);
+               err = -EIO;
+       }
+
+       pci_free_consistent(adapter->pdev, rsp_size, rsp_addr, rsp_phys_addr);
+
+out_free_rq:
+       pci_free_consistent(adapter->pdev, rq_size, rq_addr, rq_phys_addr);
+
+       return err;
+}
+
+static void
+nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter)
+{
+       if (netxen_issue_cmd(adapter,
+                       adapter->ahw.pci_func,
+                       NXHAL_VERSION,
+                       adapter->tx_context_id,
+                       NX_DESTROY_CTX_RESET,
+                       0,
+                       NX_CDRP_CMD_DESTROY_TX_CTX)) {
+
+               printk(KERN_WARNING
+                       "%s: Failed to destroy tx ctx in firmware\n",
+                       netxen_nic_driver_name);
+       }
+}
+
+static u64 ctx_addr_sig_regs[][3] = {
+       {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)},
+       {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)},
+       {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)},
+       {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)}
+};
+
+#define CRB_CTX_ADDR_REG_LO(FUNC_ID)   (ctx_addr_sig_regs[FUNC_ID][0])
+#define CRB_CTX_ADDR_REG_HI(FUNC_ID)   (ctx_addr_sig_regs[FUNC_ID][2])
+#define CRB_CTX_SIGNATURE_REG(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][1])
+
+#define lower32(x)     ((u32)((x) & 0xffffffff))
+#define upper32(x)     ((u32)(((u64)(x) >> 32) & 0xffffffff))
+
+static struct netxen_recv_crb recv_crb_registers[] = {
+       /* Instance 0 */
+       {
+               /* crb_rcv_producer: */
+               {
+                       NETXEN_NIC_REG(0x100),
+                       /* Jumbo frames */
+                       NETXEN_NIC_REG(0x110),
+                       /* LRO */
+                       NETXEN_NIC_REG(0x120)
+               },
+               /* crb_sts_consumer: */
+               NETXEN_NIC_REG(0x138),
+       },
+       /* Instance 1 */
+       {
+               /* crb_rcv_producer: */
+               {
+                       NETXEN_NIC_REG(0x144),
+                       /* Jumbo frames */
+                       NETXEN_NIC_REG(0x154),
+                       /* LRO */
+                       NETXEN_NIC_REG(0x164)
+               },
+               /* crb_sts_consumer: */
+               NETXEN_NIC_REG(0x17c),
+       },
+       /* Instance 2 */
+       {
+               /* crb_rcv_producer: */
+               {
+                       NETXEN_NIC_REG(0x1d8),
+                       /* Jumbo frames */
+                       NETXEN_NIC_REG(0x1f8),
+                       /* LRO */
+                       NETXEN_NIC_REG(0x208)
+               },
+               /* crb_sts_consumer: */
+               NETXEN_NIC_REG(0x220),
+       },
+       /* Instance 3 */
+       {
+               /* crb_rcv_producer: */
+               {
+                       NETXEN_NIC_REG(0x22c),
+                       /* Jumbo frames */
+                       NETXEN_NIC_REG(0x23c),
+                       /* LRO */
+                       NETXEN_NIC_REG(0x24c)
+               },
+               /* crb_sts_consumer: */
+               NETXEN_NIC_REG(0x264),
+       },
+};
+
+static int
+netxen_init_old_ctx(struct netxen_adapter *adapter)
+{
+       struct netxen_recv_context *recv_ctx;
+       struct nx_host_rds_ring *rds_ring;
+       int ctx, ring;
+       int func_id = adapter->portnum;
+
+       adapter->ctx_desc->cmd_ring_addr =
+               cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
+       adapter->ctx_desc->cmd_ring_size =
+               cpu_to_le32(adapter->max_tx_desc_count);
+
+       for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+               recv_ctx = &adapter->recv_ctx[ctx];
+
+               for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+                       rds_ring = &recv_ctx->rds_rings[ring];
+
+                       adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
+                               cpu_to_le64(rds_ring->phys_addr);
+                       adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
+                               cpu_to_le32(rds_ring->max_rx_desc_count);
+               }
+               adapter->ctx_desc->sts_ring_addr =
+                       cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
+               adapter->ctx_desc->sts_ring_size =
+                       cpu_to_le32(adapter->max_rx_desc_count);
+       }
+
+       adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id),
+                       lower32(adapter->ctx_desc_phys_addr));
+       adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_HI(func_id),
+                       upper32(adapter->ctx_desc_phys_addr));
+       adapter->pci_write_normalize(adapter, CRB_CTX_SIGNATURE_REG(func_id),
+                       NETXEN_CTX_SIGNATURE | func_id);
+       return 0;
+}
+
+static uint32_t sw_int_mask[4] = {
+       CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1,
+       CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3
+};
+
+int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
+{
+       struct netxen_hardware_context *hw = &adapter->ahw;
+       u32 state = 0;
+       void *addr;
+       int err = 0;
+       int ctx, ring;
+       struct netxen_recv_context *recv_ctx;
+       struct nx_host_rds_ring *rds_ring;
+
+       err = netxen_receive_peg_ready(adapter);
+       if (err) {
+               printk(KERN_ERR "Rcv Peg initialization not complete:%x.\n",
+                               state);
+               return err;
+       }
+
+       addr = pci_alloc_consistent(adapter->pdev,
+                       sizeof(struct netxen_ring_ctx) + sizeof(uint32_t),
+                       &adapter->ctx_desc_phys_addr);
+
+       if (addr == NULL) {
+               DPRINTK(ERR, "failed to allocate hw context\n");
+               return -ENOMEM;
+       }
+       memset(addr, 0, sizeof(struct netxen_ring_ctx));
+       adapter->ctx_desc = (struct netxen_ring_ctx *)addr;
+       adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum);
+       adapter->ctx_desc->cmd_consumer_offset =
+               cpu_to_le64(adapter->ctx_desc_phys_addr +
+                       sizeof(struct netxen_ring_ctx));
+       adapter->cmd_consumer =
+               (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx));
+
+       /* cmd desc ring */
+       addr = pci_alloc_consistent(adapter->pdev,
+                       sizeof(struct cmd_desc_type0) *
+                       adapter->max_tx_desc_count,
+                       &hw->cmd_desc_phys_addr);
+
+       if (addr == NULL) {
+               printk(KERN_ERR "%s failed to allocate tx desc ring\n",
+                               netxen_nic_driver_name);
+               return -ENOMEM;
+       }
+
+       hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
+
+       for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+               recv_ctx = &adapter->recv_ctx[ctx];
+
+               for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+                       /* rx desc ring */
+                       rds_ring = &recv_ctx->rds_rings[ring];
+                       addr = pci_alloc_consistent(adapter->pdev,
+                                       RCV_DESC_RINGSIZE,
+                                       &rds_ring->phys_addr);
+                       if (addr == NULL) {
+                               printk(KERN_ERR "%s failed to allocate rx "
+                                       "desc ring[%d]\n",
+                                       netxen_nic_driver_name, ring);
+                               err = -ENOMEM;
+                               goto err_out_free;
+                       }
+                       rds_ring->desc_head = (struct rcv_desc *)addr;
+
+                       if (adapter->fw_major < 4)
+                               rds_ring->crb_rcv_producer =
+                                       recv_crb_registers[adapter->portnum].
+                                       crb_rcv_producer[ring];
+               }
+
+               /* status desc ring */
+               addr = pci_alloc_consistent(adapter->pdev,
+                               STATUS_DESC_RINGSIZE,
+                               &recv_ctx->rcv_status_desc_phys_addr);
+               if (addr == NULL) {
+                       printk(KERN_ERR "%s failed to allocate sts desc ring\n",
+                                       netxen_nic_driver_name);
+                       err = -ENOMEM;
+                       goto err_out_free;
+               }
+               recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;
+
+               if (adapter->fw_major < 4)
+                       recv_ctx->crb_sts_consumer =
+                               recv_crb_registers[adapter->portnum].
+                               crb_sts_consumer;
+       }
+
+       if (adapter->fw_major >= 4) {
+               adapter->intr_scheme = INTR_SCHEME_PERPORT;
+               adapter->msi_mode = MSI_MODE_MULTIFUNC;
+
+               err = nx_fw_cmd_create_rx_ctx(adapter);
+               if (err)
+                       goto err_out_free;
+               err = nx_fw_cmd_create_tx_ctx(adapter);
+               if (err)
+                       goto err_out_free;
+       } else {
+
+               adapter->intr_scheme = adapter->pci_read_normalize(adapter,
+                               CRB_NIC_CAPABILITIES_FW);
+               adapter->msi_mode = adapter->pci_read_normalize(adapter,
+                               CRB_NIC_MSI_MODE_FW);
+               adapter->crb_intr_mask = sw_int_mask[adapter->portnum];
+
+               err = netxen_init_old_ctx(adapter);
+               if (err) {
+                       netxen_free_hw_resources(adapter);
+                       return err;
+               }
+
+       }
+
+       return 0;
+
+err_out_free:
+       netxen_free_hw_resources(adapter);
+       return err;
+}
+
+void netxen_free_hw_resources(struct netxen_adapter *adapter)
+{
+       struct netxen_recv_context *recv_ctx;
+       struct nx_host_rds_ring *rds_ring;
+       int ctx, ring;
+
+       if (adapter->fw_major >= 4) {
+               nx_fw_cmd_destroy_tx_ctx(adapter);
+               nx_fw_cmd_destroy_rx_ctx(adapter);
+       }
+
+       if (adapter->ctx_desc != NULL) {
+               pci_free_consistent(adapter->pdev,
+                               sizeof(struct netxen_ring_ctx) +
+                               sizeof(uint32_t),
+                               adapter->ctx_desc,
+                               adapter->ctx_desc_phys_addr);
+               adapter->ctx_desc = NULL;
+       }
+
+       if (adapter->ahw.cmd_desc_head != NULL) {
+               pci_free_consistent(adapter->pdev,
+                               sizeof(struct cmd_desc_type0) *
+                               adapter->max_tx_desc_count,
+                               adapter->ahw.cmd_desc_head,
+                               adapter->ahw.cmd_desc_phys_addr);
+               adapter->ahw.cmd_desc_head = NULL;
+       }
+
+       for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
+               recv_ctx = &adapter->recv_ctx[ctx];
+               for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+                       rds_ring = &recv_ctx->rds_rings[ring];
+
+                       if (rds_ring->desc_head != NULL) {
+                               pci_free_consistent(adapter->pdev,
+                                               RCV_DESC_RINGSIZE,
+                                               rds_ring->desc_head,
+                                               rds_ring->phys_addr);
+                               rds_ring->desc_head = NULL;
+                       }
+               }
+
+               if (recv_ctx->rcv_status_desc_head != NULL) {
+                       pci_free_consistent(adapter->pdev,
+                                       STATUS_DESC_RINGSIZE,
+                                       recv_ctx->rcv_status_desc_head,
+                                       recv_ctx->rcv_status_desc_phys_addr);
+                       recv_ctx->rcv_status_desc_head = NULL;
+               }
+       }
+}
+
index 723487bf200cb3b612b71521252e3a065bf30635..48ee06b6f4e9c3f06cf3b2072ef75d56d9743cfb 100644 (file)
@@ -93,17 +93,21 @@ static void
 netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
 {
        struct netxen_adapter *adapter = netdev_priv(dev);
+       unsigned long flags;
        u32 fw_major = 0;
        u32 fw_minor = 0;
        u32 fw_build = 0;
 
        strncpy(drvinfo->driver, netxen_nic_driver_name, 32);
        strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
-       fw_major = readl(NETXEN_CRB_NORMALIZE(adapter,
-                                             NETXEN_FW_VERSION_MAJOR));
-       fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter,
-                                             NETXEN_FW_VERSION_MINOR));
-       fw_build = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB));
+       write_lock_irqsave(&adapter->adapter_lock, flags);
+       fw_major = adapter->pci_read_normalize(adapter,
+                                       NETXEN_FW_VERSION_MAJOR);
+       fw_minor = adapter->pci_read_normalize(adapter,
+                                       NETXEN_FW_VERSION_MINOR);
+       fw_build = adapter->pci_read_normalize(adapter,
+                                       NETXEN_FW_VERSION_SUB);
+       write_unlock_irqrestore(&adapter->adapter_lock, flags);
        sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
 
        strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
@@ -159,9 +163,16 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        switch ((netxen_brdtype_t) boardinfo->board_type) {
        case NETXEN_BRDTYPE_P2_SB35_4G:
        case NETXEN_BRDTYPE_P2_SB31_2G:
+       case NETXEN_BRDTYPE_P3_REF_QG:
+       case NETXEN_BRDTYPE_P3_4_GB:
+       case NETXEN_BRDTYPE_P3_4_GB_MM:
+       case NETXEN_BRDTYPE_P3_10000_BASE_T:
+
                ecmd->supported |= SUPPORTED_Autoneg;
                ecmd->advertising |= ADVERTISED_Autoneg;
        case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
+       case NETXEN_BRDTYPE_P3_10G_CX4:
+       case NETXEN_BRDTYPE_P3_10G_CX4_LP:
                ecmd->supported |= SUPPORTED_TP;
                ecmd->advertising |= ADVERTISED_TP;
                ecmd->port = PORT_TP;
@@ -171,12 +182,17 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
                break;
        case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
        case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
+       case NETXEN_BRDTYPE_P3_IMEZ:
+       case NETXEN_BRDTYPE_P3_XG_LOM:
+       case NETXEN_BRDTYPE_P3_HMEZ:
                ecmd->supported |= SUPPORTED_MII;
                ecmd->advertising |= ADVERTISED_MII;
                ecmd->port = PORT_FIBRE;
                ecmd->autoneg = AUTONEG_DISABLE;
                break;
        case NETXEN_BRDTYPE_P2_SB31_10G:
+       case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
+       case NETXEN_BRDTYPE_P3_10G_XFP:
                ecmd->supported |= SUPPORTED_FIBRE;
                ecmd->advertising |= ADVERTISED_FIBRE;
                ecmd->port = PORT_FIBRE;
@@ -349,19 +365,18 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
 {
        struct netxen_adapter *adapter = netdev_priv(dev);
        __u32 mode, *regs_buff = p;
-       void __iomem *addr;
        int i, window;
 
        memset(p, 0, NETXEN_NIC_REGS_LEN);
        regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
            (adapter->pdev)->device;
        /* which mode */
-       NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_MODE, &regs_buff[0]);
+       adapter->hw_read_wx(adapter, NETXEN_NIU_MODE, &regs_buff[0], 4);
        mode = regs_buff[0];
 
        /* Common registers to all the modes */
-       NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER,
-                                  &regs_buff[2]);
+       adapter->hw_read_wx(adapter,
+                       NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER, &regs_buff[2], 4);
        /* GB/XGB Mode */
        mode = (mode / 2) - 1;
        window = 0;
@@ -372,9 +387,9 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
                                window = adapter->physical_port *
                                        NETXEN_NIC_PORT_WINDOW;
 
-                       NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode].
-                                                  reg[i - 3] + window,
-                                                  &regs_buff[i]);
+                       adapter->hw_read_wx(adapter,
+                               niu_registers[mode].reg[i - 3] + window,
+                               &regs_buff[i], 4);
                }
 
        }
@@ -398,7 +413,7 @@ static u32 netxen_nic_test_link(struct net_device *dev)
                        return !val;
                }
        } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
-               val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
+               val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
                return (val == XG_LINK_UP) ? 0 : 1;
        }
        return -EIO;
@@ -427,6 +442,7 @@ netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        return 0;
 }
 
+#if 0
 static int
 netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
                        u8 * bytes)
@@ -447,7 +463,6 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
                }
                printk(KERN_INFO "%s: flash unlocked. \n",
                        netxen_nic_driver_name);
-               last_schedule_time = jiffies;
                ret = netxen_flash_erase_secondary(adapter);
                if (ret != FLASH_SUCCESS) {
                        printk(KERN_ERR "%s: Flash erase failed.\n",
@@ -497,6 +512,7 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
 
        return netxen_rom_fast_write_words(adapter, offset, bytes, eeprom->len);
 }
+#endif /* 0 */
 
 static void
 netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
@@ -508,9 +524,9 @@ netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
        ring->rx_jumbo_pending = 0;
        for (i = 0; i < MAX_RCV_CTX; ++i) {
                ring->rx_pending += adapter->recv_ctx[i].
-                   rcv_desc[RCV_DESC_NORMAL_CTXID].max_rx_desc_count;
+                   rds_rings[RCV_DESC_NORMAL_CTXID].max_rx_desc_count;
                ring->rx_jumbo_pending += adapter->recv_ctx[i].
-                   rcv_desc[RCV_DESC_JUMBO_CTXID].max_rx_desc_count;
+                   rds_rings[RCV_DESC_JUMBO_CTXID].max_rx_desc_count;
        }
        ring->tx_pending = adapter->max_tx_desc_count;
 
@@ -655,7 +671,7 @@ static int netxen_nic_reg_test(struct net_device *dev)
        data_written = (u32)0xa5a5a5a5;
 
        netxen_nic_reg_write(adapter, CRB_SCRATCHPAD_TEST, data_written);
-       data_read = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_SCRATCHPAD_TEST));
+       data_read = adapter->pci_read_normalize(adapter, CRB_SCRATCHPAD_TEST);
        if (data_written != data_read)
                return 1;
 
@@ -736,6 +752,117 @@ static int netxen_nic_set_rx_csum(struct net_device *dev, u32 data)
        return 0;
 }
 
+static u32 netxen_nic_get_tso(struct net_device *dev)
+{
+       struct netxen_adapter *adapter = netdev_priv(dev);
+
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+               return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0;
+
+       return (dev->features & NETIF_F_TSO) != 0;
+}
+
+static int netxen_nic_set_tso(struct net_device *dev, u32 data)
+{
+       if (data) {
+               struct netxen_adapter *adapter = netdev_priv(dev);
+
+               dev->features |= NETIF_F_TSO;
+               if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+                       dev->features |= NETIF_F_TSO6;
+       } else
+               dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+
+       return 0;
+}
+
+/*
+ * Set the coalescing parameters. Currently only normal is supported.
+ * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
+ * firmware coalescing to default.
+ */
+static int netxen_set_intr_coalesce(struct net_device *netdev,
+                       struct ethtool_coalesce *ethcoal)
+{
+       struct netxen_adapter *adapter = netdev_priv(netdev);
+
+       if (!NX_IS_REVISION_P3(adapter->ahw.revision_id))
+               return -EINVAL;
+
+       if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+               return -EINVAL;
+
+       /*
+       * Return Error if unsupported values or
+       * unsupported parameters are set.
+       */
+       if (ethcoal->rx_coalesce_usecs > 0xffff ||
+               ethcoal->rx_max_coalesced_frames > 0xffff ||
+               ethcoal->tx_coalesce_usecs > 0xffff ||
+               ethcoal->tx_max_coalesced_frames > 0xffff ||
+               ethcoal->rx_coalesce_usecs_irq ||
+               ethcoal->rx_max_coalesced_frames_irq ||
+               ethcoal->tx_coalesce_usecs_irq ||
+               ethcoal->tx_max_coalesced_frames_irq ||
+               ethcoal->stats_block_coalesce_usecs ||
+               ethcoal->use_adaptive_rx_coalesce ||
+               ethcoal->use_adaptive_tx_coalesce ||
+               ethcoal->pkt_rate_low ||
+               ethcoal->rx_coalesce_usecs_low ||
+               ethcoal->rx_max_coalesced_frames_low ||
+               ethcoal->tx_coalesce_usecs_low ||
+               ethcoal->tx_max_coalesced_frames_low ||
+               ethcoal->pkt_rate_high ||
+               ethcoal->rx_coalesce_usecs_high ||
+               ethcoal->rx_max_coalesced_frames_high ||
+               ethcoal->tx_coalesce_usecs_high ||
+               ethcoal->tx_max_coalesced_frames_high)
+               return -EINVAL;
+
+       if (!ethcoal->rx_coalesce_usecs ||
+               !ethcoal->rx_max_coalesced_frames) {
+               adapter->coal.flags = NETXEN_NIC_INTR_DEFAULT;
+               adapter->coal.normal.data.rx_time_us =
+                       NETXEN_DEFAULT_INTR_COALESCE_RX_TIME_US;
+               adapter->coal.normal.data.rx_packets =
+                       NETXEN_DEFAULT_INTR_COALESCE_RX_PACKETS;
+       } else {
+               adapter->coal.flags = 0;
+               adapter->coal.normal.data.rx_time_us =
+               ethcoal->rx_coalesce_usecs;
+               adapter->coal.normal.data.rx_packets =
+               ethcoal->rx_max_coalesced_frames;
+       }
+       adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs;
+       adapter->coal.normal.data.tx_packets =
+       ethcoal->tx_max_coalesced_frames;
+
+       netxen_config_intr_coalesce(adapter);
+
+       return 0;
+}
+
+static int netxen_get_intr_coalesce(struct net_device *netdev,
+                       struct ethtool_coalesce *ethcoal)
+{
+       struct netxen_adapter *adapter = netdev_priv(netdev);
+
+       if (!NX_IS_REVISION_P3(adapter->ahw.revision_id))
+               return -EINVAL;
+
+       if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+               return -EINVAL;
+
+       ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us;
+       ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us;
+       ethcoal->rx_max_coalesced_frames =
+               adapter->coal.normal.data.rx_packets;
+       ethcoal->tx_max_coalesced_frames =
+               adapter->coal.normal.data.tx_packets;
+
+       return 0;
+}
+
 struct ethtool_ops netxen_nic_ethtool_ops = {
        .get_settings = netxen_nic_get_settings,
        .set_settings = netxen_nic_set_settings,
@@ -745,17 +872,22 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
        .get_link = ethtool_op_get_link,
        .get_eeprom_len = netxen_nic_get_eeprom_len,
        .get_eeprom = netxen_nic_get_eeprom,
+#if 0
        .set_eeprom = netxen_nic_set_eeprom,
+#endif
        .get_ringparam = netxen_nic_get_ringparam,
        .get_pauseparam = netxen_nic_get_pauseparam,
        .set_pauseparam = netxen_nic_set_pauseparam,
        .set_tx_csum = ethtool_op_set_tx_csum,
        .set_sg = ethtool_op_set_sg,
-       .set_tso = ethtool_op_set_tso,
+       .get_tso = netxen_nic_get_tso,
+       .set_tso = netxen_nic_set_tso,
        .self_test = netxen_nic_diag_test,
        .get_strings = netxen_nic_get_strings,
        .get_ethtool_stats = netxen_nic_get_ethtool_stats,
        .get_sset_count = netxen_get_sset_count,
        .get_rx_csum = netxen_nic_get_rx_csum,
        .set_rx_csum = netxen_nic_set_rx_csum,
+       .get_coalesce = netxen_get_intr_coalesce,
+       .set_coalesce = netxen_set_intr_coalesce,
 };
index 24d027e29c45a60fa340b13d5bcede0981f6b8e3..3ce13e451aac8309277d03114996890ac9132cdc 100644 (file)
@@ -126,7 +126,8 @@ enum {
        NETXEN_HW_PEGR0_CRB_AGT_ADR,
        NETXEN_HW_PEGR1_CRB_AGT_ADR,
        NETXEN_HW_PEGR2_CRB_AGT_ADR,
-       NETXEN_HW_PEGR3_CRB_AGT_ADR
+       NETXEN_HW_PEGR3_CRB_AGT_ADR,
+       NETXEN_HW_PEGN4_CRB_AGT_ADR
 };
 
 /*  Hub 5 */
@@ -316,6 +317,8 @@ enum {
        ((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGN2_CRB_AGT_ADR)
 #define NETXEN_HW_CRB_HUB_AGT_ADR_PGN3 \
        ((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGN3_CRB_AGT_ADR)
+#define NETXEN_HW_CRB_HUB_AGT_ADR_PGN4 \
+       ((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGN4_CRB_AGT_ADR)
 #define NETXEN_HW_CRB_HUB_AGT_ADR_PGNC \
        ((NETXEN_HW_H4_CH_HUB_ADR << 7) | NETXEN_HW_PEGNC_CRB_AGT_ADR)
 #define NETXEN_HW_CRB_HUB_AGT_ADR_PGR0 \
@@ -435,6 +438,7 @@ enum {
 #define NETXEN_CRB_ROMUSB      \
        NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_ROMUSB)
 #define NETXEN_CRB_I2Q         NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_I2Q)
+#define NETXEN_CRB_SMB         NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_SMB)
 #define NETXEN_CRB_MAX         NETXEN_PCI_CRB_WINDOW(64)
 
 #define NETXEN_CRB_PCIX_HOST   NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PH)
@@ -446,6 +450,7 @@ enum {
 #define NETXEN_CRB_PEG_NET_D   NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGND)
 #define NETXEN_CRB_PEG_NET_I   NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGNI)
 #define NETXEN_CRB_DDR_NET     NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_MN)
+#define NETXEN_CRB_QDR_NET     NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_SN)
 
 #define NETXEN_CRB_PCIX_MD     NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PS)
 #define NETXEN_CRB_PCIE                NETXEN_CRB_PCIX_MD
@@ -461,11 +466,20 @@ enum {
 #define ISR_INT_TARGET_MASK_F2     (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F2))
 #define ISR_INT_TARGET_STATUS_F3   (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F3))
 #define ISR_INT_TARGET_MASK_F3     (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F3))
+#define ISR_INT_TARGET_STATUS_F4   (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F4))
+#define ISR_INT_TARGET_MASK_F4     (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F4))
+#define ISR_INT_TARGET_STATUS_F5   (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F5))
+#define ISR_INT_TARGET_MASK_F5     (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F5))
+#define ISR_INT_TARGET_STATUS_F6   (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F6))
+#define ISR_INT_TARGET_MASK_F6     (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F6))
+#define ISR_INT_TARGET_STATUS_F7   (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F7))
+#define ISR_INT_TARGET_MASK_F7     (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F7))
 
 #define NETXEN_PCI_MAPSIZE     128
 #define NETXEN_PCI_DDR_NET     (0x00000000UL)
 #define NETXEN_PCI_QDR_NET     (0x04000000UL)
 #define NETXEN_PCI_DIRECT_CRB  (0x04400000UL)
+#define NETXEN_PCI_CAMQM       (0x04800000UL)
 #define NETXEN_PCI_CAMQM_MAX   (0x04ffffffUL)
 #define NETXEN_PCI_OCM0                (0x05000000UL)
 #define NETXEN_PCI_OCM0_MAX    (0x050fffffUL)
@@ -474,6 +488,13 @@ enum {
 #define NETXEN_PCI_CRBSPACE    (0x06000000UL)
 #define NETXEN_PCI_128MB_SIZE  (0x08000000UL)
 #define NETXEN_PCI_32MB_SIZE   (0x02000000UL)
+#define NETXEN_PCI_2MB_SIZE    (0x00200000UL)
+
+#define NETXEN_PCI_MN_2M       (0)
+#define NETXEN_PCI_MS_2M       (0x80000)
+#define NETXEN_PCI_OCM0_2M     (0x000c0000UL)
+#define NETXEN_PCI_CAMQM_2M_BASE       (0x000ff800UL)
+#define NETXEN_PCI_CAMQM_2M_END                (0x04800800UL)
 
 #define NETXEN_CRB_CAM NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_CAM)
 
@@ -484,7 +505,14 @@ enum {
 #define NETXEN_ADDR_OCM1       (0x0000000200400000ULL)
 #define NETXEN_ADDR_OCM1_MAX   (0x00000002004fffffULL)
 #define NETXEN_ADDR_QDR_NET    (0x0000000300000000ULL)
-#define NETXEN_ADDR_QDR_NET_MAX (0x00000003003fffffULL)
+#define NETXEN_ADDR_QDR_NET_MAX_P2 (0x00000003003fffffULL)
+#define NETXEN_ADDR_QDR_NET_MAX_P3 (0x0000000303ffffffULL)
+
+/*
+ *   Register offsets for MN
+ */
+#define        NETXEN_MIU_CONTROL      (0x000)
+#define        NETXEN_MIU_MN_CONTROL   (NETXEN_CRB_DDR_NET+NETXEN_MIU_CONTROL)
 
        /* 200ms delay in each loop */
 #define        NETXEN_NIU_PHY_WAITLEN          200000
@@ -550,6 +578,9 @@ enum {
 #define NETXEN_MULTICAST_ADDR_HI_2     (NETXEN_CRB_NIU + 0x1018)
 #define NETXEN_MULTICAST_ADDR_HI_3     (NETXEN_CRB_NIU + 0x101c)
 
+#define NETXEN_UNICAST_ADDR_BASE       (NETXEN_CRB_NIU + 0x1080)
+#define        NETXEN_MULTICAST_ADDR_BASE      (NETXEN_CRB_NIU + 0x1100)
+
 #define        NETXEN_NIU_GB_MAC_CONFIG_0(I)           \
        (NETXEN_CRB_NIU + 0x30000 + (I)*0x10000)
 #define        NETXEN_NIU_GB_MAC_CONFIG_1(I)           \
@@ -630,16 +661,76 @@ enum {
 #define NETXEN_NIU_XG1_CONTROL_CHAR_CNT                (NETXEN_CRB_NIU + 0x80054)
 #define NETXEN_NIU_XG1_PAUSE_FRAME_CNT         (NETXEN_CRB_NIU + 0x80058)
 
+/* P3 802.3ap */
+#define NETXEN_NIU_AP_MAC_CONFIG_0(I)      (NETXEN_CRB_NIU+0xa0000+(I)*0x10000)
+#define NETXEN_NIU_AP_MAC_CONFIG_1(I)      (NETXEN_CRB_NIU+0xa0004+(I)*0x10000)
+#define NETXEN_NIU_AP_MAC_IPG_IFG(I)       (NETXEN_CRB_NIU+0xa0008+(I)*0x10000)
+#define NETXEN_NIU_AP_HALF_DUPLEX_CTRL(I)  (NETXEN_CRB_NIU+0xa000c+(I)*0x10000)
+#define NETXEN_NIU_AP_MAX_FRAME_SIZE(I)    (NETXEN_CRB_NIU+0xa0010+(I)*0x10000)
+#define NETXEN_NIU_AP_TEST_REG(I)          (NETXEN_CRB_NIU+0xa001c+(I)*0x10000)
+#define NETXEN_NIU_AP_MII_MGMT_CONFIG(I)   (NETXEN_CRB_NIU+0xa0020+(I)*0x10000)
+#define NETXEN_NIU_AP_MII_MGMT_COMMAND(I)  (NETXEN_CRB_NIU+0xa0024+(I)*0x10000)
+#define NETXEN_NIU_AP_MII_MGMT_ADDR(I)     (NETXEN_CRB_NIU+0xa0028+(I)*0x10000)
+#define NETXEN_NIU_AP_MII_MGMT_CTRL(I)     (NETXEN_CRB_NIU+0xa002c+(I)*0x10000)
+#define NETXEN_NIU_AP_MII_MGMT_STATUS(I)   (NETXEN_CRB_NIU+0xa0030+(I)*0x10000)
+#define NETXEN_NIU_AP_MII_MGMT_INDICATE(I) (NETXEN_CRB_NIU+0xa0034+(I)*0x10000)
+#define NETXEN_NIU_AP_INTERFACE_CTRL(I)    (NETXEN_CRB_NIU+0xa0038+(I)*0x10000)
+#define NETXEN_NIU_AP_INTERFACE_STATUS(I)  (NETXEN_CRB_NIU+0xa003c+(I)*0x10000)
+#define NETXEN_NIU_AP_STATION_ADDR_0(I)    (NETXEN_CRB_NIU+0xa0040+(I)*0x10000)
+#define NETXEN_NIU_AP_STATION_ADDR_1(I)    (NETXEN_CRB_NIU+0xa0044+(I)*0x10000)
+
+/*
+ *   Register offsets for MN
+ */
+#define        MIU_CONTROL            (0x000)
+#define MIU_TEST_AGT_CTRL      (0x090)
+#define MIU_TEST_AGT_ADDR_LO   (0x094)
+#define MIU_TEST_AGT_ADDR_HI   (0x098)
+#define MIU_TEST_AGT_WRDATA_LO (0x0a0)
+#define MIU_TEST_AGT_WRDATA_HI (0x0a4)
+#define MIU_TEST_AGT_WRDATA(i) (0x0a0+(4*(i)))
+#define MIU_TEST_AGT_RDDATA_LO (0x0a8)
+#define MIU_TEST_AGT_RDDATA_HI (0x0ac)
+#define MIU_TEST_AGT_RDDATA(i) (0x0a8+(4*(i)))
+#define MIU_TEST_AGT_ADDR_MASK 0xfffffff8
+#define MIU_TEST_AGT_UPPER_ADDR(off) (0)
+
+/* MIU_TEST_AGT_CTRL flags. work for SIU as well */
+#define MIU_TA_CTL_START        1
+#define MIU_TA_CTL_ENABLE       2
+#define MIU_TA_CTL_WRITE        4
+#define MIU_TA_CTL_BUSY         8
+
+#define SIU_TEST_AGT_CTRL      (0x060)
+#define SIU_TEST_AGT_ADDR_LO   (0x064)
+#define SIU_TEST_AGT_ADDR_HI   (0x078)
+#define SIU_TEST_AGT_WRDATA_LO (0x068)
+#define SIU_TEST_AGT_WRDATA_HI (0x06c)
+#define SIU_TEST_AGT_WRDATA(i) (0x068+(4*(i)))
+#define SIU_TEST_AGT_RDDATA_LO (0x070)
+#define SIU_TEST_AGT_RDDATA_HI (0x074)
+#define SIU_TEST_AGT_RDDATA(i) (0x070+(4*(i)))
+
+#define SIU_TEST_AGT_ADDR_MASK 0x3ffff8
+#define SIU_TEST_AGT_UPPER_ADDR(off) ((off)>>22)
+
 /* XG Link status */
 #define XG_LINK_UP     0x10
 #define XG_LINK_DOWN   0x20
 
+#define XG_LINK_UP_P3  0x01
+#define XG_LINK_DOWN_P3        0x02
+#define XG_LINK_STATE_P3_MASK 0xf
+#define XG_LINK_STATE_P3(pcifn,val) \
+       (((val) >> ((pcifn) * 4)) & XG_LINK_STATE_P3_MASK)
+
 #define NETXEN_CAM_RAM_BASE    (NETXEN_CRB_CAM + 0x02000)
 #define NETXEN_CAM_RAM(reg)    (NETXEN_CAM_RAM_BASE + (reg))
 #define NETXEN_FW_VERSION_MAJOR (NETXEN_CAM_RAM(0x150))
 #define NETXEN_FW_VERSION_MINOR (NETXEN_CAM_RAM(0x154))
 #define NETXEN_FW_VERSION_SUB  (NETXEN_CAM_RAM(0x158))
 #define NETXEN_ROM_LOCK_ID     (NETXEN_CAM_RAM(0x100))
+#define NETXEN_CRB_WIN_LOCK_ID (NETXEN_CAM_RAM(0x124))
 
 #define NETXEN_PHY_LOCK_ID     (NETXEN_CAM_RAM(0x120))
 
@@ -654,30 +745,71 @@ enum {
 #define PCIX_INT_VECTOR                (0x10100)
 #define PCIX_INT_MASK          (0x10104)
 
-#define PCIX_MN_WINDOW_F0      (0x10200)
-#define PCIX_MN_WINDOW(_f)     (PCIX_MN_WINDOW_F0 + (0x20 * (_f)))
-#define PCIX_MS_WINDOW         (0x10204)
-#define PCIX_SN_WINDOW_F0      (0x10208)
-#define PCIX_SN_WINDOW(_f)     (PCIX_SN_WINDOW_F0 + (0x20 * (_f)))
 #define PCIX_CRB_WINDOW                (0x10210)
 #define PCIX_CRB_WINDOW_F0     (0x10210)
 #define PCIX_CRB_WINDOW_F1     (0x10230)
 #define PCIX_CRB_WINDOW_F2     (0x10250)
 #define PCIX_CRB_WINDOW_F3     (0x10270)
+#define PCIX_CRB_WINDOW_F4     (0x102ac)
+#define PCIX_CRB_WINDOW_F5     (0x102bc)
+#define PCIX_CRB_WINDOW_F6     (0x102cc)
+#define PCIX_CRB_WINDOW_F7     (0x102dc)
+#define PCIE_CRB_WINDOW_REG(func)      (((func) < 4) ? \
+               (PCIX_CRB_WINDOW_F0 + (0x20 * (func))) :\
+               (PCIX_CRB_WINDOW_F4 + (0x10 * ((func)-4))))
+
+#define PCIX_MN_WINDOW         (0x10200)
+#define PCIX_MN_WINDOW_F0      (0x10200)
+#define PCIX_MN_WINDOW_F1      (0x10220)
+#define PCIX_MN_WINDOW_F2      (0x10240)
+#define PCIX_MN_WINDOW_F3      (0x10260)
+#define PCIX_MN_WINDOW_F4      (0x102a0)
+#define PCIX_MN_WINDOW_F5      (0x102b0)
+#define PCIX_MN_WINDOW_F6      (0x102c0)
+#define PCIX_MN_WINDOW_F7      (0x102d0)
+#define PCIE_MN_WINDOW_REG(func)       (((func) < 4) ? \
+               (PCIX_MN_WINDOW_F0 + (0x20 * (func))) :\
+               (PCIX_MN_WINDOW_F4 + (0x10 * ((func)-4))))
+
+#define PCIX_SN_WINDOW         (0x10208)
+#define PCIX_SN_WINDOW_F0      (0x10208)
+#define PCIX_SN_WINDOW_F1      (0x10228)
+#define PCIX_SN_WINDOW_F2      (0x10248)
+#define PCIX_SN_WINDOW_F3      (0x10268)
+#define PCIX_SN_WINDOW_F4      (0x102a8)
+#define PCIX_SN_WINDOW_F5      (0x102b8)
+#define PCIX_SN_WINDOW_F6      (0x102c8)
+#define PCIX_SN_WINDOW_F7      (0x102d8)
+#define PCIE_SN_WINDOW_REG(func)       (((func) < 4) ? \
+               (PCIX_SN_WINDOW_F0 + (0x20 * (func))) :\
+               (PCIX_SN_WINDOW_F4 + (0x10 * ((func)-4))))
 
 #define PCIX_TARGET_STATUS     (0x10118)
+#define PCIX_TARGET_STATUS_F1  (0x10160)
+#define PCIX_TARGET_STATUS_F2  (0x10164)
+#define PCIX_TARGET_STATUS_F3  (0x10168)
+#define PCIX_TARGET_STATUS_F4  (0x10360)
+#define PCIX_TARGET_STATUS_F5  (0x10364)
+#define PCIX_TARGET_STATUS_F6  (0x10368)
+#define PCIX_TARGET_STATUS_F7  (0x1036c)
+
 #define PCIX_TARGET_MASK       (0x10128)
-#define PCIX_TARGET_STATUS_F1 (0x10160)
-#define PCIX_TARGET_MASK_F1   (0x10170)
-#define PCIX_TARGET_STATUS_F2 (0x10164)
-#define PCIX_TARGET_MASK_F2   (0x10174)
-#define PCIX_TARGET_STATUS_F3 (0x10168)
-#define PCIX_TARGET_MASK_F3   (0x10178)
+#define PCIX_TARGET_MASK_F1    (0x10170)
+#define PCIX_TARGET_MASK_F2    (0x10174)
+#define PCIX_TARGET_MASK_F3    (0x10178)
+#define PCIX_TARGET_MASK_F4    (0x10370)
+#define PCIX_TARGET_MASK_F5    (0x10374)
+#define PCIX_TARGET_MASK_F6    (0x10378)
+#define PCIX_TARGET_MASK_F7    (0x1037c)
 
 #define PCIX_MSI_F0            (0x13000)
 #define PCIX_MSI_F1            (0x13004)
 #define PCIX_MSI_F2            (0x13008)
 #define PCIX_MSI_F3            (0x1300c)
+#define PCIX_MSI_F4            (0x13010)
+#define PCIX_MSI_F5            (0x13014)
+#define PCIX_MSI_F6            (0x13018)
+#define PCIX_MSI_F7            (0x1301c)
 #define PCIX_MSI_F(i)          (0x13000+((i)*4))
 
 #define PCIX_PS_MEM_SPACE      (0x90000)
@@ -695,11 +827,102 @@ enum {
 #define PCIE_SEM2_UNLOCK       (0x1c014)       /* Flash unlock */
 #define PCIE_SEM3_LOCK         (0x1c018)       /* Phy lock     */
 #define PCIE_SEM3_UNLOCK       (0x1c01c)       /* Phy unlock   */
-
+#define PCIE_SEM5_LOCK         (0x1c028)       /* API lock     */
+#define PCIE_SEM5_UNLOCK       (0x1c02c)       /* API unlock   */
+#define PCIE_SEM6_LOCK         (0x1c030)       /* sw lock      */
+#define PCIE_SEM6_UNLOCK       (0x1c034)       /* sw unlock    */
+#define PCIE_SEM7_LOCK         (0x1c038)       /* crb win lock */
+#define PCIE_SEM7_UNLOCK       (0x1c03c)       /* crbwin unlock*/
+
+#define PCIE_SETUP_FUNCTION    (0x12040)
+#define PCIE_SETUP_FUNCTION2   (0x12048)
 #define PCIE_TGT_SPLIT_CHICKEN (0x12080)
+#define PCIE_CHICKEN3          (0x120c8)
 
 #define PCIE_MAX_MASTER_SPLIT  (0x14048)
 
+#define NETXEN_PORT_MODE_NONE          0
+#define NETXEN_PORT_MODE_XG            1
+#define NETXEN_PORT_MODE_GB            2
+#define NETXEN_PORT_MODE_802_3_AP      3
+#define NETXEN_PORT_MODE_AUTO_NEG      4
+#define NETXEN_PORT_MODE_AUTO_NEG_1G   5
+#define NETXEN_PORT_MODE_AUTO_NEG_XG   6
+#define NETXEN_PORT_MODE_ADDR          (NETXEN_CAM_RAM(0x24))
+#define NETXEN_WOL_PORT_MODE           (NETXEN_CAM_RAM(0x198))
+
 #define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL               (0x14)
 
+#define        ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
+
+/*
+ * PCI Interrupt Vector Values.
+ */
+#define        PCIX_INT_VECTOR_BIT_F0  0x0080
+#define        PCIX_INT_VECTOR_BIT_F1  0x0100
+#define        PCIX_INT_VECTOR_BIT_F2  0x0200
+#define        PCIX_INT_VECTOR_BIT_F3  0x0400
+#define        PCIX_INT_VECTOR_BIT_F4  0x0800
+#define        PCIX_INT_VECTOR_BIT_F5  0x1000
+#define        PCIX_INT_VECTOR_BIT_F6  0x2000
+#define        PCIX_INT_VECTOR_BIT_F7  0x4000
+
+struct netxen_legacy_intr_set {
+       uint32_t        int_vec_bit;
+       uint32_t        tgt_status_reg;
+       uint32_t        tgt_mask_reg;
+       uint32_t        pci_int_reg;
+};
+
+#define        NX_LEGACY_INTR_CONFIG                                           \
+{                                                                      \
+       {                                                               \
+               .int_vec_bit    =       PCIX_INT_VECTOR_BIT_F0,         \
+               .tgt_status_reg =       ISR_INT_TARGET_STATUS,          \
+               .tgt_mask_reg   =       ISR_INT_TARGET_MASK,            \
+               .pci_int_reg    =       ISR_MSI_INT_TRIGGER(0) },       \
+                                                                       \
+       {                                                               \
+               .int_vec_bit    =       PCIX_INT_VECTOR_BIT_F1,         \
+               .tgt_status_reg =       ISR_INT_TARGET_STATUS_F1,       \
+               .tgt_mask_reg   =       ISR_INT_TARGET_MASK_F1,         \
+               .pci_int_reg    =       ISR_MSI_INT_TRIGGER(1) },       \
+                                                                       \
+       {                                                               \
+               .int_vec_bit    =       PCIX_INT_VECTOR_BIT_F2,         \
+               .tgt_status_reg =       ISR_INT_TARGET_STATUS_F2,       \
+               .tgt_mask_reg   =       ISR_INT_TARGET_MASK_F2,         \
+               .pci_int_reg    =       ISR_MSI_INT_TRIGGER(2) },       \
+                                                                       \
+       {                                                               \
+               .int_vec_bit    =       PCIX_INT_VECTOR_BIT_F3,         \
+               .tgt_status_reg =       ISR_INT_TARGET_STATUS_F3,       \
+               .tgt_mask_reg   =       ISR_INT_TARGET_MASK_F3,         \
+               .pci_int_reg    =       ISR_MSI_INT_TRIGGER(3) },       \
+                                                                       \
+       {                                                               \
+               .int_vec_bit    =       PCIX_INT_VECTOR_BIT_F4,         \
+               .tgt_status_reg =       ISR_INT_TARGET_STATUS_F4,       \
+               .tgt_mask_reg   =       ISR_INT_TARGET_MASK_F4,         \
+               .pci_int_reg    =       ISR_MSI_INT_TRIGGER(4) },       \
+                                                                       \
+       {                                                               \
+               .int_vec_bit    =       PCIX_INT_VECTOR_BIT_F5,         \
+               .tgt_status_reg =       ISR_INT_TARGET_STATUS_F5,       \
+               .tgt_mask_reg   =       ISR_INT_TARGET_MASK_F5,         \
+               .pci_int_reg    =       ISR_MSI_INT_TRIGGER(5) },       \
+                                                                       \
+       {                                                               \
+               .int_vec_bit    =       PCIX_INT_VECTOR_BIT_F6,         \
+               .tgt_status_reg =       ISR_INT_TARGET_STATUS_F6,       \
+               .tgt_mask_reg   =       ISR_INT_TARGET_MASK_F6,         \
+               .pci_int_reg    =       ISR_MSI_INT_TRIGGER(6) },       \
+                                                                       \
+       {                                                               \
+               .int_vec_bit    =       PCIX_INT_VECTOR_BIT_F7,         \
+               .tgt_status_reg =       ISR_INT_TARGET_STATUS_F7,       \
+               .tgt_mask_reg   =       ISR_INT_TARGET_MASK_F7,         \
+               .pci_int_reg    =       ISR_MSI_INT_TRIGGER(7) },       \
+}
+
 #endif                         /* __NETXEN_NIC_HDR_H_ */
index c43d06b8de9b1b63f01c75e2cca024f122afe1dd..96a3bc6426e27332fd86aa75ea95ba025c287d81 100644 (file)
 
 #include <net/ip.h>
 
-struct netxen_recv_crb recv_crb_registers[] = {
-       /*
-        * Instance 0.
-        */
-       {
-        /* rcv_desc_crb: */
-        {
-         {
-          /* crb_rcv_producer_offset: */
-          NETXEN_NIC_REG(0x100),
-          /* crb_rcv_consumer_offset: */
-          NETXEN_NIC_REG(0x104),
-          /* crb_gloablrcv_ring: */
-          NETXEN_NIC_REG(0x108),
-          /* crb_rcv_ring_size */
-          NETXEN_NIC_REG(0x10c),
-
-          },
-         /* Jumbo frames */
-         {
-          /* crb_rcv_producer_offset: */
-          NETXEN_NIC_REG(0x110),
-          /* crb_rcv_consumer_offset: */
-          NETXEN_NIC_REG(0x114),
-          /* crb_gloablrcv_ring: */
-          NETXEN_NIC_REG(0x118),
-          /* crb_rcv_ring_size */
-          NETXEN_NIC_REG(0x11c),
-          },
-         /* LRO */
-         {
-          /* crb_rcv_producer_offset: */
-          NETXEN_NIC_REG(0x120),
-          /* crb_rcv_consumer_offset: */
-          NETXEN_NIC_REG(0x124),
-          /* crb_gloablrcv_ring: */
-          NETXEN_NIC_REG(0x128),
-          /* crb_rcv_ring_size */
-          NETXEN_NIC_REG(0x12c),
-          }
-         },
-        /* crb_rcvstatus_ring: */
-        NETXEN_NIC_REG(0x130),
-        /* crb_rcv_status_producer: */
-        NETXEN_NIC_REG(0x134),
-        /* crb_rcv_status_consumer: */
-        NETXEN_NIC_REG(0x138),
-        /* crb_rcvpeg_state: */
-        NETXEN_NIC_REG(0x13c),
-        /* crb_status_ring_size */
-        NETXEN_NIC_REG(0x140),
-
-        },
-       /*
-        * Instance 1,
-        */
-       {
-        /* rcv_desc_crb: */
-        {
-         {
-          /* crb_rcv_producer_offset: */
-          NETXEN_NIC_REG(0x144),
-          /* crb_rcv_consumer_offset: */
-          NETXEN_NIC_REG(0x148),
-          /* crb_globalrcv_ring: */
-          NETXEN_NIC_REG(0x14c),
-          /* crb_rcv_ring_size */
-          NETXEN_NIC_REG(0x150),
-
-          },
-         /* Jumbo frames */
-         {
-          /* crb_rcv_producer_offset: */
-          NETXEN_NIC_REG(0x154),
-          /* crb_rcv_consumer_offset: */
-          NETXEN_NIC_REG(0x158),
-          /* crb_globalrcv_ring: */
-          NETXEN_NIC_REG(0x15c),
-          /* crb_rcv_ring_size */
-          NETXEN_NIC_REG(0x160),
-          },
-         /* LRO */
-         {
-          /* crb_rcv_producer_offset: */
-          NETXEN_NIC_REG(0x164),
-          /* crb_rcv_consumer_offset: */
-          NETXEN_NIC_REG(0x168),
-          /* crb_globalrcv_ring: */
-          NETXEN_NIC_REG(0x16c),
-          /* crb_rcv_ring_size */
-          NETXEN_NIC_REG(0x170),
-          }
-
-         },
-        /* crb_rcvstatus_ring: */
-        NETXEN_NIC_REG(0x174),
-        /* crb_rcv_status_producer: */
-        NETXEN_NIC_REG(0x178),
-        /* crb_rcv_status_consumer: */
-        NETXEN_NIC_REG(0x17c),
-        /* crb_rcvpeg_state: */
-        NETXEN_NIC_REG(0x180),
-        /* crb_status_ring_size */
-        NETXEN_NIC_REG(0x184),
-        },
-       /*
-        * Instance 2,
-        */
-       {
-         {
-           {
-           /* crb_rcv_producer_offset: */
-           NETXEN_NIC_REG(0x1d8),
-           /* crb_rcv_consumer_offset: */
-           NETXEN_NIC_REG(0x1dc),
-           /* crb_gloablrcv_ring: */
-           NETXEN_NIC_REG(0x1f0),
-           /* crb_rcv_ring_size */
-           NETXEN_NIC_REG(0x1f4),
-           },
-           /* Jumbo frames */
-           {
-           /* crb_rcv_producer_offset: */
-           NETXEN_NIC_REG(0x1f8),
-           /* crb_rcv_consumer_offset: */
-           NETXEN_NIC_REG(0x1fc),
-           /* crb_gloablrcv_ring: */
-           NETXEN_NIC_REG(0x200),
-           /* crb_rcv_ring_size */
-           NETXEN_NIC_REG(0x204),
-           },
-           /* LRO */
-           {
-           /* crb_rcv_producer_offset: */
-           NETXEN_NIC_REG(0x208),
-           /* crb_rcv_consumer_offset: */
-           NETXEN_NIC_REG(0x20c),
-           /* crb_gloablrcv_ring: */
-           NETXEN_NIC_REG(0x210),
-           /* crb_rcv_ring_size */
-           NETXEN_NIC_REG(0x214),
-           }
-         },
-         /* crb_rcvstatus_ring: */
-         NETXEN_NIC_REG(0x218),
-         /* crb_rcv_status_producer: */
-         NETXEN_NIC_REG(0x21c),
-         /* crb_rcv_status_consumer: */
-         NETXEN_NIC_REG(0x220),
-         /* crb_rcvpeg_state: */
-         NETXEN_NIC_REG(0x224),
-         /* crb_status_ring_size */
-         NETXEN_NIC_REG(0x228),
-       },
-       /*
-        * Instance 3,
-        */
-       {
-         {
-           {
-           /* crb_rcv_producer_offset: */
-           NETXEN_NIC_REG(0x22c),
-           /* crb_rcv_consumer_offset: */
-           NETXEN_NIC_REG(0x230),
-           /* crb_gloablrcv_ring: */
-           NETXEN_NIC_REG(0x234),
-           /* crb_rcv_ring_size */
-           NETXEN_NIC_REG(0x238),
-           },
-           /* Jumbo frames */
-           {
-           /* crb_rcv_producer_offset: */
-           NETXEN_NIC_REG(0x23c),
-           /* crb_rcv_consumer_offset: */
-           NETXEN_NIC_REG(0x240),
-           /* crb_gloablrcv_ring: */
-           NETXEN_NIC_REG(0x244),
-           /* crb_rcv_ring_size */
-           NETXEN_NIC_REG(0x248),
-           },
-           /* LRO */
-           {
-           /* crb_rcv_producer_offset: */
-           NETXEN_NIC_REG(0x24c),
-           /* crb_rcv_consumer_offset: */
-           NETXEN_NIC_REG(0x250),
-           /* crb_gloablrcv_ring: */
-           NETXEN_NIC_REG(0x254),
-           /* crb_rcv_ring_size */
-           NETXEN_NIC_REG(0x258),
-           }
-         },
-         /* crb_rcvstatus_ring: */
-         NETXEN_NIC_REG(0x25c),
-         /* crb_rcv_status_producer: */
-         NETXEN_NIC_REG(0x260),
-         /* crb_rcv_status_consumer: */
-         NETXEN_NIC_REG(0x264),
-         /* crb_rcvpeg_state: */
-         NETXEN_NIC_REG(0x268),
-         /* crb_status_ring_size */
-         NETXEN_NIC_REG(0x26c),
-       },
+#define MASK(n) ((1ULL<<(n))-1)
+#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
+#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
+#define MS_WIN(addr) (addr & 0x0ffc0000)
+
+#define GET_MEM_OFFS_2M(addr) (addr & MASK(18))
+
+#define CRB_BLK(off)   ((off >> 20) & 0x3f)
+#define CRB_SUBBLK(off)        ((off >> 16) & 0xf)
+#define CRB_WINDOW_2M  (0x130060)
+#define CRB_HI(off)    ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
+#define CRB_INDIRECT_2M        (0x1e0000UL)
+
+#define CRB_WIN_LOCK_TIMEOUT 100000000
+static crb_128M_2M_block_map_t crb_128M_2M_map[64] = {
+    {{{0, 0,         0,         0} } },                /* 0: PCI */
+    {{{1, 0x0100000, 0x0102000, 0x120000},     /* 1: PCIE */
+         {1, 0x0110000, 0x0120000, 0x130000},
+         {1, 0x0120000, 0x0122000, 0x124000},
+         {1, 0x0130000, 0x0132000, 0x126000},
+         {1, 0x0140000, 0x0142000, 0x128000},
+         {1, 0x0150000, 0x0152000, 0x12a000},
+         {1, 0x0160000, 0x0170000, 0x110000},
+         {1, 0x0170000, 0x0172000, 0x12e000},
+         {0, 0x0000000, 0x0000000, 0x000000},
+         {0, 0x0000000, 0x0000000, 0x000000},
+         {0, 0x0000000, 0x0000000, 0x000000},
+         {0, 0x0000000, 0x0000000, 0x000000},
+         {0, 0x0000000, 0x0000000, 0x000000},
+         {0, 0x0000000, 0x0000000, 0x000000},
+         {1, 0x01e0000, 0x01e0800, 0x122000},
+         {0, 0x0000000, 0x0000000, 0x000000} } },
+       {{{1, 0x0200000, 0x0210000, 0x180000} } },/* 2: MN */
+    {{{0, 0,         0,         0} } },            /* 3: */
+    {{{1, 0x0400000, 0x0401000, 0x169000} } },/* 4: P2NR1 */
+    {{{1, 0x0500000, 0x0510000, 0x140000} } },/* 5: SRE   */
+    {{{1, 0x0600000, 0x0610000, 0x1c0000} } },/* 6: NIU   */
+    {{{1, 0x0700000, 0x0704000, 0x1b8000} } },/* 7: QM    */
+    {{{1, 0x0800000, 0x0802000, 0x170000},  /* 8: SQM0  */
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {1, 0x08f0000, 0x08f2000, 0x172000} } },
+    {{{1, 0x0900000, 0x0902000, 0x174000},     /* 9: SQM1*/
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {1, 0x09f0000, 0x09f2000, 0x176000} } },
+    {{{0, 0x0a00000, 0x0a02000, 0x178000},     /* 10: SQM2*/
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {1, 0x0af0000, 0x0af2000, 0x17a000} } },
+    {{{0, 0x0b00000, 0x0b02000, 0x17c000},     /* 11: SQM3*/
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {0, 0x0000000, 0x0000000, 0x000000},
+      {1, 0x0bf0000, 0x0bf2000, 0x17e000} } },
+       {{{1, 0x0c00000, 0x0c04000, 0x1d4000} } },/* 12: I2Q */
+       {{{1, 0x0d00000, 0x0d04000, 0x1a4000} } },/* 13: TMR */
+       {{{1, 0x0e00000, 0x0e04000, 0x1a0000} } },/* 14: ROMUSB */
+       {{{1, 0x0f00000, 0x0f01000, 0x164000} } },/* 15: PEG4 */
+       {{{0, 0x1000000, 0x1004000, 0x1a8000} } },/* 16: XDMA */
+       {{{1, 0x1100000, 0x1101000, 0x160000} } },/* 17: PEG0 */
+       {{{1, 0x1200000, 0x1201000, 0x161000} } },/* 18: PEG1 */
+       {{{1, 0x1300000, 0x1301000, 0x162000} } },/* 19: PEG2 */
+       {{{1, 0x1400000, 0x1401000, 0x163000} } },/* 20: PEG3 */
+       {{{1, 0x1500000, 0x1501000, 0x165000} } },/* 21: P2ND */
+       {{{1, 0x1600000, 0x1601000, 0x166000} } },/* 22: P2NI */
+       {{{0, 0,         0,         0} } },     /* 23: */
+       {{{0, 0,         0,         0} } },     /* 24: */
+       {{{0, 0,         0,         0} } },     /* 25: */
+       {{{0, 0,         0,         0} } },     /* 26: */
+       {{{0, 0,         0,         0} } },     /* 27: */
+       {{{0, 0,         0,         0} } },     /* 28: */
+       {{{1, 0x1d00000, 0x1d10000, 0x190000} } },/* 29: MS */
+    {{{1, 0x1e00000, 0x1e01000, 0x16a000} } },/* 30: P2NR2 */
+    {{{1, 0x1f00000, 0x1f10000, 0x150000} } },/* 31: EPG */
+       {{{0} } },                              /* 32: PCI */
+       {{{1, 0x2100000, 0x2102000, 0x120000},  /* 33: PCIE */
+         {1, 0x2110000, 0x2120000, 0x130000},
+         {1, 0x2120000, 0x2122000, 0x124000},
+         {1, 0x2130000, 0x2132000, 0x126000},
+         {1, 0x2140000, 0x2142000, 0x128000},
+         {1, 0x2150000, 0x2152000, 0x12a000},
+         {1, 0x2160000, 0x2170000, 0x110000},
+         {1, 0x2170000, 0x2172000, 0x12e000},
+         {0, 0x0000000, 0x0000000, 0x000000},
+         {0, 0x0000000, 0x0000000, 0x000000},
+         {0, 0x0000000, 0x0000000, 0x000000},
+         {0, 0x0000000, 0x0000000, 0x000000},
+         {0, 0x0000000, 0x0000000, 0x000000},
+         {0, 0x0000000, 0x0000000, 0x000000},
+         {0, 0x0000000, 0x0000000, 0x000000},
+         {0, 0x0000000, 0x0000000, 0x000000} } },
+       {{{1, 0x2200000, 0x2204000, 0x1b0000} } },/* 34: CAM */
+       {{{0} } },                              /* 35: */
+       {{{0} } },                              /* 36: */
+       {{{0} } },                              /* 37: */
+       {{{0} } },                              /* 38: */
+       {{{0} } },                              /* 39: */
+       {{{1, 0x2800000, 0x2804000, 0x1a4000} } },/* 40: TMR */
+       {{{1, 0x2900000, 0x2901000, 0x16b000} } },/* 41: P2NR3 */
+       {{{1, 0x2a00000, 0x2a00400, 0x1ac400} } },/* 42: RPMX1 */
+       {{{1, 0x2b00000, 0x2b00400, 0x1ac800} } },/* 43: RPMX2 */
+       {{{1, 0x2c00000, 0x2c00400, 0x1acc00} } },/* 44: RPMX3 */
+       {{{1, 0x2d00000, 0x2d00400, 0x1ad000} } },/* 45: RPMX4 */
+       {{{1, 0x2e00000, 0x2e00400, 0x1ad400} } },/* 46: RPMX5 */
+       {{{1, 0x2f00000, 0x2f00400, 0x1ad800} } },/* 47: RPMX6 */
+       {{{1, 0x3000000, 0x3000400, 0x1adc00} } },/* 48: RPMX7 */
+       {{{0, 0x3100000, 0x3104000, 0x1a8000} } },/* 49: XDMA */
+       {{{1, 0x3200000, 0x3204000, 0x1d4000} } },/* 50: I2Q */
+       {{{1, 0x3300000, 0x3304000, 0x1a0000} } },/* 51: ROMUSB */
+       {{{0} } },                              /* 52: */
+       {{{1, 0x3500000, 0x3500400, 0x1ac000} } },/* 53: RPMX0 */
+       {{{1, 0x3600000, 0x3600400, 0x1ae000} } },/* 54: RPMX8 */
+       {{{1, 0x3700000, 0x3700400, 0x1ae400} } },/* 55: RPMX9 */
+       {{{1, 0x3800000, 0x3804000, 0x1d0000} } },/* 56: OCM0 */
+       {{{1, 0x3900000, 0x3904000, 0x1b4000} } },/* 57: CRYPTO */
+       {{{1, 0x3a00000, 0x3a04000, 0x1d8000} } },/* 58: SMB */
+       {{{0} } },                              /* 59: I2C0 */
+       {{{0} } },                              /* 60: I2C1 */
+       {{{1, 0x3d00000, 0x3d04000, 0x1d8000} } },/* 61: LPC */
+       {{{1, 0x3e00000, 0x3e01000, 0x167000} } },/* 62: P2NC */
+       {{{1, 0x3f00000, 0x3f01000, 0x168000} } }       /* 63: P2NR0 */
 };
 
-static u64 ctx_addr_sig_regs[][3] = {
-       {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)},
-       {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)},
-       {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)},
-       {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)}
+/*
+ * top 12 bits of crb internal address (hub, agent)
+ */
+static unsigned crb_hub_agt[64] =
+{
+       0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PS,
+       NETXEN_HW_CRB_HUB_AGT_ADR_MN,
+       NETXEN_HW_CRB_HUB_AGT_ADR_MS,
+       0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_SRE,
+       NETXEN_HW_CRB_HUB_AGT_ADR_NIU,
+       NETXEN_HW_CRB_HUB_AGT_ADR_QMN,
+       NETXEN_HW_CRB_HUB_AGT_ADR_SQN0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_SQN1,
+       NETXEN_HW_CRB_HUB_AGT_ADR_SQN2,
+       NETXEN_HW_CRB_HUB_AGT_ADR_SQN3,
+       NETXEN_HW_CRB_HUB_AGT_ADR_I2Q,
+       NETXEN_HW_CRB_HUB_AGT_ADR_TIMR,
+       NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PGN4,
+       NETXEN_HW_CRB_HUB_AGT_ADR_XDMA,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PGN0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PGN1,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PGN2,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PGN3,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PGND,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PGNI,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PGS0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PGS1,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PGS2,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PGS3,
+       0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PGSI,
+       NETXEN_HW_CRB_HUB_AGT_ADR_SN,
+       0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_EG,
+       0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PS,
+       NETXEN_HW_CRB_HUB_AGT_ADR_CAM,
+       0,
+       0,
+       0,
+       0,
+       0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_TIMR,
+       0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_RPMX1,
+       NETXEN_HW_CRB_HUB_AGT_ADR_RPMX2,
+       NETXEN_HW_CRB_HUB_AGT_ADR_RPMX3,
+       NETXEN_HW_CRB_HUB_AGT_ADR_RPMX4,
+       NETXEN_HW_CRB_HUB_AGT_ADR_RPMX5,
+       NETXEN_HW_CRB_HUB_AGT_ADR_RPMX6,
+       NETXEN_HW_CRB_HUB_AGT_ADR_RPMX7,
+       NETXEN_HW_CRB_HUB_AGT_ADR_XDMA,
+       NETXEN_HW_CRB_HUB_AGT_ADR_I2Q,
+       NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB,
+       0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_RPMX0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_RPMX8,
+       NETXEN_HW_CRB_HUB_AGT_ADR_RPMX9,
+       NETXEN_HW_CRB_HUB_AGT_ADR_OCM0,
+       0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_SMB,
+       NETXEN_HW_CRB_HUB_AGT_ADR_I2C0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_I2C1,
+       0,
+       NETXEN_HW_CRB_HUB_AGT_ADR_PGNC,
+       0,
 };
-#define CRB_CTX_ADDR_REG_LO(FUNC_ID)           (ctx_addr_sig_regs[FUNC_ID][0])
-#define CRB_CTX_ADDR_REG_HI(FUNC_ID)           (ctx_addr_sig_regs[FUNC_ID][2])
-#define CRB_CTX_SIGNATURE_REG(FUNC_ID)         (ctx_addr_sig_regs[FUNC_ID][1])
-
 
 /*  PCI Windowing for DDR regions.  */
 
 #define ADDR_IN_RANGE(addr, low, high) \
        (((addr) <= (high)) && ((addr) >= (low)))
 
-#define NETXEN_FLASH_BASE      (NETXEN_BOOTLD_START)
-#define NETXEN_PHANTOM_MEM_BASE        (NETXEN_FLASH_BASE)
 #define NETXEN_MAX_MTU         8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE
 #define NETXEN_MIN_MTU         64
 #define NETXEN_ETH_FCS_SIZE     4
 #define NETXEN_ENET_HEADER_SIZE 14
-#define NETXEN_WINDOW_ONE      0x2000000       /*CRB Window: bit 25 of CRB address */
+#define NETXEN_WINDOW_ONE      0x2000000 /*CRB Window: bit 25 of CRB address */
 #define NETXEN_FIRMWARE_LEN    ((16 * 1024) / 4)
 #define NETXEN_NIU_HDRSIZE     (0x1 << 6)
 #define NETXEN_NIU_TLRSIZE     (0x1 << 5)
 
-#define lower32(x)             ((u32)((x) & 0xffffffff))
-#define upper32(x)                     \
-       ((u32)(((unsigned long long)(x) >> 32) & 0xffffffff))
-
 #define NETXEN_NIC_ZERO_PAUSE_ADDR     0ULL
 #define NETXEN_NIC_UNIT_PAUSE_ADDR     0x200ULL
 #define NETXEN_NIC_EPG_PAUSE_ADDR1     0x2200010000c28001ULL
@@ -281,10 +301,6 @@ static u64 ctx_addr_sig_regs[][3] = {
 
 #define NETXEN_NIC_WINDOW_MARGIN 0x100000
 
-static unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter,
-                                              unsigned long long addr);
-void netxen_free_hw_resources(struct netxen_adapter *adapter);
-
 int netxen_nic_set_mac(struct net_device *netdev, void *p)
 {
        struct netxen_adapter *adapter = netdev_priv(netdev);
@@ -296,266 +312,370 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p)
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
 
-       DPRINTK(INFO, "valid ether addr\n");
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 
-       if (adapter->macaddr_set)
-               adapter->macaddr_set(adapter, addr->sa_data);
+       /* For P3, MAC addr is not set in NIU */
+       if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+               if (adapter->macaddr_set)
+                       adapter->macaddr_set(adapter, addr->sa_data);
 
        return 0;
 }
 
-/*
- * netxen_nic_set_multi - Multicast
- */
-void netxen_nic_set_multi(struct net_device *netdev)
+#define NETXEN_UNICAST_ADDR(port, index) \
+       (NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8))
+#define NETXEN_MCAST_ADDR(port, index) \
+       (NETXEN_MULTICAST_ADDR_BASE+(port*0x80)+(index*8))
+#define MAC_HI(addr) \
+       ((addr[2] << 16) | (addr[1] << 8) | (addr[0]))
+#define MAC_LO(addr) \
+       ((addr[5] << 16) | (addr[4] << 8) | (addr[3]))
+
+static int
+netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter)
+{
+       u32     val = 0;
+       u16 port = adapter->physical_port;
+       u8 *addr = adapter->netdev->dev_addr;
+
+       if (adapter->mc_enabled)
+               return 0;
+
+       adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+       val |= (1UL << (28+port));
+       adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+
+       /* add broadcast addr to filter */
+       val = 0xffffff;
+       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
+       netxen_crb_writelit_adapter(adapter,
+                       NETXEN_UNICAST_ADDR(port, 0)+4, val);
+
+       /* add station addr to filter */
+       val = MAC_HI(addr);
+       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), val);
+       val = MAC_LO(addr);
+       netxen_crb_writelit_adapter(adapter,
+                       NETXEN_UNICAST_ADDR(port, 1)+4, val);
+
+       adapter->mc_enabled = 1;
+       return 0;
+}
+
+static int
+netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter)
+{
+       u32     val = 0;
+       u16 port = adapter->physical_port;
+       u8 *addr = adapter->netdev->dev_addr;
+
+       if (!adapter->mc_enabled)
+               return 0;
+
+       adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+       val &= ~(1UL << (28+port));
+       adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+
+       val = MAC_HI(addr);
+       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
+       val = MAC_LO(addr);
+       netxen_crb_writelit_adapter(adapter,
+                       NETXEN_UNICAST_ADDR(port, 0)+4, val);
+
+       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), 0);
+       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0);
+
+       adapter->mc_enabled = 0;
+       return 0;
+}
+
+static int
+netxen_nic_set_mcast_addr(struct netxen_adapter *adapter,
+               int index, u8 *addr)
+{
+       u32 hi = 0, lo = 0;
+       u16 port = adapter->physical_port;
+
+       lo = MAC_LO(addr);
+       hi = MAC_HI(addr);
+
+       netxen_crb_writelit_adapter(adapter,
+                       NETXEN_MCAST_ADDR(port, index), hi);
+       netxen_crb_writelit_adapter(adapter,
+                       NETXEN_MCAST_ADDR(port, index)+4, lo);
+
+       return 0;
+}
+
+void netxen_p2_nic_set_multi(struct net_device *netdev)
 {
        struct netxen_adapter *adapter = netdev_priv(netdev);
        struct dev_mc_list *mc_ptr;
+       u8 null_addr[6];
+       int index = 0;
+
+       memset(null_addr, 0, 6);
 
-       mc_ptr = netdev->mc_list;
        if (netdev->flags & IFF_PROMISC) {
-               if (adapter->set_promisc)
-                       adapter->set_promisc(adapter,
-                                            NETXEN_NIU_PROMISC_MODE);
-       } else {
-               if (adapter->unset_promisc)
-                       adapter->unset_promisc(adapter,
-                                              NETXEN_NIU_NON_PROMISC_MODE);
+
+               adapter->set_promisc(adapter,
+                               NETXEN_NIU_PROMISC_MODE);
+
+               /* Full promiscuous mode */
+               netxen_nic_disable_mcast_filter(adapter);
+
+               return;
+       }
+
+       if (netdev->mc_count == 0) {
+               adapter->set_promisc(adapter,
+                               NETXEN_NIU_NON_PROMISC_MODE);
+               netxen_nic_disable_mcast_filter(adapter);
+               return;
+       }
+
+       adapter->set_promisc(adapter, NETXEN_NIU_ALLMULTI_MODE);
+       if (netdev->flags & IFF_ALLMULTI ||
+                       netdev->mc_count > adapter->max_mc_count) {
+               netxen_nic_disable_mcast_filter(adapter);
+               return;
        }
+
+       netxen_nic_enable_mcast_filter(adapter);
+
+       for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next, index++)
+               netxen_nic_set_mcast_addr(adapter, index, mc_ptr->dmi_addr);
+
+       if (index != netdev->mc_count)
+               printk(KERN_WARNING "%s: %s multicast address count mismatch\n",
+                       netxen_nic_driver_name, netdev->name);
+
+       /* Clear out remaining addresses */
+       for (; index < adapter->max_mc_count; index++)
+               netxen_nic_set_mcast_addr(adapter, index, null_addr);
 }
 
-/*
- * netxen_nic_change_mtu - Change the Maximum Transfer Unit
- * @returns 0 on success, negative on failure
- */
-int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
+static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
+               u8 *addr, nx_mac_list_t **add_list, nx_mac_list_t **del_list)
 {
-       struct netxen_adapter *adapter = netdev_priv(netdev);
-       int eff_mtu = mtu + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE;
+       nx_mac_list_t *cur, *prev;
+
+       /* if in del_list, move it to adapter->mac_list */
+       for (cur = *del_list, prev = NULL; cur;) {
+               if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
+                       if (prev == NULL)
+                               *del_list = cur->next;
+                       else
+                               prev->next = cur->next;
+                       cur->next = adapter->mac_list;
+                       adapter->mac_list = cur;
+                       return 0;
+               }
+               prev = cur;
+               cur = cur->next;
+       }
+
+       /* make sure to add each mac address only once */
+       for (cur = adapter->mac_list; cur; cur = cur->next) {
+               if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
+                       return 0;
+       }
+       /* not in del_list, create new entry and add to add_list */
+       cur = kmalloc(sizeof(*cur), in_atomic()? GFP_ATOMIC : GFP_KERNEL);
+       if (cur == NULL) {
+               printk(KERN_ERR "%s: cannot allocate memory. MAC filtering may"
+                               "not work properly from now.\n", __func__);
+               return -1;
+       }
 
-       if ((eff_mtu > NETXEN_MAX_MTU) || (eff_mtu < NETXEN_MIN_MTU)) {
-               printk(KERN_ERR "%s: %s %d is not supported.\n",
-                      netxen_nic_driver_name, netdev->name, mtu);
+       memcpy(cur->mac_addr, addr, ETH_ALEN);
+       cur->next = *add_list;
+       *add_list = cur;
+       return 0;
+}
+
+static int
+netxen_send_cmd_descs(struct netxen_adapter *adapter,
+               struct cmd_desc_type0 *cmd_desc_arr, int nr_elements)
+{
+       uint32_t i, producer;
+       struct netxen_cmd_buffer *pbuf;
+       struct cmd_desc_type0 *cmd_desc;
+
+       if (nr_elements > MAX_PENDING_DESC_BLOCK_SIZE || nr_elements == 0) {
+               printk(KERN_WARNING "%s: Too many command descriptors in a "
+                             "request\n", __func__);
                return -EINVAL;
        }
 
-       if (adapter->set_mtu)
-               adapter->set_mtu(adapter, mtu);
-       netdev->mtu = mtu;
+       i = 0;
+
+       producer = adapter->cmd_producer;
+       do {
+               cmd_desc = &cmd_desc_arr[i];
+
+               pbuf = &adapter->cmd_buf_arr[producer];
+               pbuf->mss = 0;
+               pbuf->total_length = 0;
+               pbuf->skb = NULL;
+               pbuf->cmd = 0;
+               pbuf->frag_count = 0;
+               pbuf->port = 0;
+
+               /* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */
+               memcpy(&adapter->ahw.cmd_desc_head[producer],
+                       &cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
+
+               producer = get_next_index(producer,
+                               adapter->max_tx_desc_count);
+               i++;
+
+       } while (i != nr_elements);
+
+       adapter->cmd_producer = producer;
+
+       /* write producer index to start the xmit */
+
+       netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer);
 
        return 0;
 }
 
-/*
- * check if the firmware has been downloaded and ready to run  and
- * setup the address for the descriptors in the adapter
- */
-int netxen_nic_hw_resources(struct netxen_adapter *adapter)
+#define NIC_REQUEST            0x14
+#define NETXEN_MAC_EVENT       0x1
+
+static int nx_p3_sre_macaddr_change(struct net_device *dev,
+               u8 *addr, unsigned op)
 {
-       struct netxen_hardware_context *hw = &adapter->ahw;
-       u32 state = 0;
-       void *addr;
-       int loops = 0, err = 0;
-       int ctx, ring;
-       struct netxen_recv_context *recv_ctx;
-       struct netxen_rcv_desc_ctx *rcv_desc;
-       int func_id = adapter->portnum;
-
-       DPRINTK(INFO, "crb_base: %lx %x", NETXEN_PCI_CRBSPACE,
-               PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE));
-       DPRINTK(INFO, "cam base: %lx %x", NETXEN_CRB_CAM,
-               pci_base_offset(adapter, NETXEN_CRB_CAM));
-       DPRINTK(INFO, "cam RAM: %lx %x", NETXEN_CAM_RAM_BASE,
-               pci_base_offset(adapter, NETXEN_CAM_RAM_BASE));
-
-
-       for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
-               DPRINTK(INFO, "Command Peg ready..waiting for rcv peg\n");
-               loops = 0;
-               state = 0;
-               /* Window 1 call */
-               state = readl(NETXEN_CRB_NORMALIZE(adapter,
-                                                  recv_crb_registers[ctx].
-                                                  crb_rcvpeg_state));
-               while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) {
-                       msleep(1);
-                       /* Window 1 call */
-                       state = readl(NETXEN_CRB_NORMALIZE(adapter,
-                                                          recv_crb_registers
-                                                          [ctx].
-                                                          crb_rcvpeg_state));
-                       loops++;
-               }
-               if (loops >= 20) {
-                       printk(KERN_ERR "Rcv Peg initialization not complete:"
-                              "%x.\n", state);
-                       err = -EIO;
-                       return err;
-               }
+       struct netxen_adapter *adapter = (struct netxen_adapter *)dev->priv;
+       nx_nic_req_t req;
+       nx_mac_req_t mac_req;
+       int rv;
+
+       memset(&req, 0, sizeof(nx_nic_req_t));
+       req.qhdr |= (NIC_REQUEST << 23);
+       req.req_hdr |= NETXEN_MAC_EVENT;
+       req.req_hdr |= ((u64)adapter->portnum << 16);
+       mac_req.op = op;
+       memcpy(&mac_req.mac_addr, addr, 6);
+       req.words[0] = cpu_to_le64(*(u64 *)&mac_req);
+
+       rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+       if (rv != 0) {
+               printk(KERN_ERR "ERROR. Could not send mac update\n");
+               return rv;
        }
-       adapter->intr_scheme = readl(
-               NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW));
-       adapter->msi_mode = readl(
-               NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_FW));
-
-       addr = netxen_alloc(adapter->ahw.pdev,
-                           sizeof(struct netxen_ring_ctx) +
-                           sizeof(uint32_t),
-                           (dma_addr_t *) & adapter->ctx_desc_phys_addr,
-                           &adapter->ctx_desc_pdev);
-
-       if (addr == NULL) {
-               DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
-               err = -ENOMEM;
-               return err;
-       }
-       memset(addr, 0, sizeof(struct netxen_ring_ctx));
-       adapter->ctx_desc = (struct netxen_ring_ctx *)addr;
-       adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum);
-       adapter->ctx_desc->cmd_consumer_offset =
-           cpu_to_le64(adapter->ctx_desc_phys_addr +
-                       sizeof(struct netxen_ring_ctx));
-       adapter->cmd_consumer = (__le32 *) (((char *)addr) +
-                                             sizeof(struct netxen_ring_ctx));
-
-       addr = netxen_alloc(adapter->ahw.pdev,
-                           sizeof(struct cmd_desc_type0) *
-                           adapter->max_tx_desc_count,
-                           (dma_addr_t *) & hw->cmd_desc_phys_addr,
-                           &adapter->ahw.cmd_desc_pdev);
-
-       if (addr == NULL) {
-               DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
-               netxen_free_hw_resources(adapter);
-               return -ENOMEM;
-       }
-
-       adapter->ctx_desc->cmd_ring_addr =
-               cpu_to_le64(hw->cmd_desc_phys_addr);
-       adapter->ctx_desc->cmd_ring_size =
-               cpu_to_le32(adapter->max_tx_desc_count);
-
-       hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
-
-       for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
-               recv_ctx = &adapter->recv_ctx[ctx];
-
-               for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
-                       rcv_desc = &recv_ctx->rcv_desc[ring];
-                       addr = netxen_alloc(adapter->ahw.pdev,
-                                           RCV_DESC_RINGSIZE,
-                                           &rcv_desc->phys_addr,
-                                           &rcv_desc->phys_pdev);
-                       if (addr == NULL) {
-                               DPRINTK(ERR, "bad return from "
-                                       "pci_alloc_consistent\n");
-                               netxen_free_hw_resources(adapter);
-                               err = -ENOMEM;
-                               return err;
-                       }
-                       rcv_desc->desc_head = (struct rcv_desc *)addr;
-                       adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
-                           cpu_to_le64(rcv_desc->phys_addr);
-                       adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
-                           cpu_to_le32(rcv_desc->max_rx_desc_count);
-               }
 
-               addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE,
-                                   &recv_ctx->rcv_status_desc_phys_addr,
-                                   &recv_ctx->rcv_status_desc_pdev);
-               if (addr == NULL) {
-                       DPRINTK(ERR, "bad return from"
-                               " pci_alloc_consistent\n");
-                       netxen_free_hw_resources(adapter);
-                       err = -ENOMEM;
-                       return err;
-               }
-               recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;
-               adapter->ctx_desc->sts_ring_addr =
-                   cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
-               adapter->ctx_desc->sts_ring_size =
-                   cpu_to_le32(adapter->max_rx_desc_count);
-
-       }
-       /* Window = 1 */
-
-       writel(lower32(adapter->ctx_desc_phys_addr),
-              NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_LO(func_id)));
-       writel(upper32(adapter->ctx_desc_phys_addr),
-              NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_HI(func_id)));
-       writel(NETXEN_CTX_SIGNATURE | func_id,
-              NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG(func_id)));
-       return err;
+       return 0;
 }
 
-void netxen_free_hw_resources(struct netxen_adapter *adapter)
+void netxen_p3_nic_set_multi(struct net_device *netdev)
 {
-       struct netxen_recv_context *recv_ctx;
-       struct netxen_rcv_desc_ctx *rcv_desc;
-       int ctx, ring;
-
-       if (adapter->ctx_desc != NULL) {
-               pci_free_consistent(adapter->ctx_desc_pdev,
-                                   sizeof(struct netxen_ring_ctx) +
-                                   sizeof(uint32_t),
-                                   adapter->ctx_desc,
-                                   adapter->ctx_desc_phys_addr);
-               adapter->ctx_desc = NULL;
-       }
-
-       if (adapter->ahw.cmd_desc_head != NULL) {
-               pci_free_consistent(adapter->ahw.cmd_desc_pdev,
-                                   sizeof(struct cmd_desc_type0) *
-                                   adapter->max_tx_desc_count,
-                                   adapter->ahw.cmd_desc_head,
-                                   adapter->ahw.cmd_desc_phys_addr);
-               adapter->ahw.cmd_desc_head = NULL;
-       }
-
-       for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
-               recv_ctx = &adapter->recv_ctx[ctx];
-               for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
-                       rcv_desc = &recv_ctx->rcv_desc[ring];
-
-                       if (rcv_desc->desc_head != NULL) {
-                               pci_free_consistent(rcv_desc->phys_pdev,
-                                                   RCV_DESC_RINGSIZE,
-                                                   rcv_desc->desc_head,
-                                                   rcv_desc->phys_addr);
-                               rcv_desc->desc_head = NULL;
-                       }
-               }
+       struct netxen_adapter *adapter = netdev_priv(netdev);
+       nx_mac_list_t *cur, *next, *del_list, *add_list = NULL;
+       struct dev_mc_list *mc_ptr;
+       u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+       adapter->set_promisc(adapter, NETXEN_NIU_PROMISC_MODE);
+
+       /*
+        * Programming mac addresses will automaticly enabling L2 filtering.
+        * HW will replace timestamp with L2 conid when L2 filtering is
+        * enabled. This causes problem for LSA. Do not enabling L2 filtering
+        * until that problem is fixed.
+        */
+       if ((netdev->flags & IFF_PROMISC) ||
+                       (netdev->mc_count > adapter->max_mc_count))
+               return;
+
+       del_list = adapter->mac_list;
+       adapter->mac_list = NULL;
 
-               if (recv_ctx->rcv_status_desc_head != NULL) {
-                       pci_free_consistent(recv_ctx->rcv_status_desc_pdev,
-                                           STATUS_DESC_RINGSIZE,
-                                           recv_ctx->rcv_status_desc_head,
-                                           recv_ctx->
-                                           rcv_status_desc_phys_addr);
-                       recv_ctx->rcv_status_desc_head = NULL;
+       nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list);
+       if (netdev->mc_count > 0) {
+               nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list);
+               for (mc_ptr = netdev->mc_list; mc_ptr;
+                    mc_ptr = mc_ptr->next) {
+                       nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr,
+                                         &add_list, &del_list);
                }
        }
+       for (cur = del_list; cur;) {
+               nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL);
+               next = cur->next;
+               kfree(cur);
+               cur = next;
+       }
+       for (cur = add_list; cur;) {
+               nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_ADD);
+               next = cur->next;
+               cur->next = adapter->mac_list;
+               adapter->mac_list = cur;
+               cur = next;
+       }
 }
 
-void netxen_tso_check(struct netxen_adapter *adapter,
-                     struct cmd_desc_type0 *desc, struct sk_buff *skb)
+#define        NETXEN_CONFIG_INTR_COALESCE     3
+
+/*
+ * Send the interrupt coalescing parameter set by ethtool to the card.
+ */
+int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
 {
-       if (desc->mss) {
-               desc->total_hdr_length = (sizeof(struct ethhdr) +
-                                         ip_hdrlen(skb) + tcp_hdrlen(skb));
-               netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO);
-       } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
-               if (ip_hdr(skb)->protocol == IPPROTO_TCP) {
-                       netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT);
-               } else if (ip_hdr(skb)->protocol == IPPROTO_UDP) {
-                       netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT);
-               } else {
-                       return;
-               }
+       nx_nic_req_t req;
+       int rv;
+
+       memset(&req, 0, sizeof(nx_nic_req_t));
+
+       req.qhdr |= (NIC_REQUEST << 23);
+       req.req_hdr |= NETXEN_CONFIG_INTR_COALESCE;
+       req.req_hdr |= ((u64)adapter->portnum << 16);
+
+       memcpy(&req.words[0], &adapter->coal, sizeof(adapter->coal));
+
+       rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+       if (rv != 0) {
+               printk(KERN_ERR "ERROR. Could not send "
+                       "interrupt coalescing parameters\n");
+       }
+
+       return rv;
+}
+
+/*
+ * netxen_nic_change_mtu - Change the Maximum Transfer Unit
+ * @returns 0 on success, negative on failure
+ */
+
+#define MTU_FUDGE_FACTOR       100
+
+int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
+{
+       struct netxen_adapter *adapter = netdev_priv(netdev);
+       int max_mtu;
+
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+               max_mtu = P3_MAX_MTU;
+       else
+               max_mtu = P2_MAX_MTU;
+
+       if (mtu > max_mtu) {
+               printk(KERN_ERR "%s: mtu > %d bytes unsupported\n",
+                               netdev->name, max_mtu);
+               return -EINVAL;
        }
-       desc->tcp_hdr_offset = skb_transport_offset(skb);
-       desc->ip_hdr_offset = skb_network_offset(skb);
+
+       if (adapter->set_mtu)
+               adapter->set_mtu(adapter, mtu);
+       netdev->mtu = mtu;
+
+       mtu += MTU_FUDGE_FACTOR;
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+               nx_fw_cmd_set_mtu(adapter, mtu);
+       else if (adapter->set_mtu)
+               adapter->set_mtu(adapter, mtu);
+
+       return 0;
 }
 
 int netxen_is_flash_supported(struct netxen_adapter *adapter)
@@ -632,41 +752,49 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[])
        return 0;
 }
 
+#define CRB_WIN_LOCK_TIMEOUT 100000000
+
+static int crb_win_lock(struct netxen_adapter *adapter)
+{
+       int done = 0, timeout = 0;
+
+       while (!done) {
+               /* acquire semaphore3 from PCI HW block */
+               adapter->hw_read_wx(adapter,
+                               NETXEN_PCIE_REG(PCIE_SEM7_LOCK), &done, 4);
+               if (done == 1)
+                       break;
+               if (timeout >= CRB_WIN_LOCK_TIMEOUT)
+                       return -1;
+               timeout++;
+               udelay(1);
+       }
+       netxen_crb_writelit_adapter(adapter,
+                       NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
+       return 0;
+}
+
+static void crb_win_unlock(struct netxen_adapter *adapter)
+{
+       int val;
+
+       adapter->hw_read_wx(adapter,
+                       NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK), &val, 4);
+}
+
 /*
  * Changes the CRB window to the specified window.
  */
-void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
+void
+netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw)
 {
        void __iomem *offset;
        u32 tmp;
        int count = 0;
+       uint8_t func = adapter->ahw.pci_func;
 
        if (adapter->curr_window == wndw)
                return;
-       switch(adapter->ahw.pci_func) {
-               case 0:
-                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
-                                       NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW));
-                       break;
-               case 1:
-                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
-                                       NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F1));
-                       break;
-               case 2:
-                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
-                                       NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F2));
-                       break;
-               case 3:
-                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
-                                       NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F3));
-                       break;
-               default:
-                       printk(KERN_INFO "Changing the window for PCI function "
-                                       "%d\n", adapter->ahw.pci_func);
-                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
-                                       NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW));
-                       break;
-       }
        /*
         * Move the CRB window.
         * We need to write to the "direct access" region of PCI
@@ -675,6 +803,8 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
         * register address is received by PCI. The direct region bypasses
         * the CRB bus.
         */
+       offset = PCI_OFFSET_SECOND_RANGE(adapter,
+                       NETXEN_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(func)));
 
        if (wndw & 0x1)
                wndw = NETXEN_WINDOW_ONE;
@@ -685,7 +815,7 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
        while ((tmp = readl(offset)) != wndw) {
                printk(KERN_WARNING "%s: %s WARNING: CRB window value not "
                       "registered properly: 0x%08x.\n",
-                      netxen_nic_driver_name, __FUNCTION__, tmp);
+                      netxen_nic_driver_name, __func__, tmp);
                mdelay(1);
                if (count >= 10)
                        break;
@@ -698,51 +828,119 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
                adapter->curr_window = 0;
 }
 
+/*
+ * Return -1 if off is not valid,
+ *      1 if window access is needed. 'off' is set to offset from
+ *        CRB space in 128M pci map
+ *      0 if no window access is needed. 'off' is set to 2M addr
+ * In: 'off' is offset from base in 128M pci map
+ */
+static int
+netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter,
+               ulong *off, int len)
+{
+       unsigned long end = *off + len;
+       crb_128M_2M_sub_block_map_t *m;
+
+
+       if (*off >= NETXEN_CRB_MAX)
+               return -1;
+
+       if (*off >= NETXEN_PCI_CAMQM && (end <= NETXEN_PCI_CAMQM_2M_END)) {
+               *off = (*off - NETXEN_PCI_CAMQM) + NETXEN_PCI_CAMQM_2M_BASE +
+                       (ulong)adapter->ahw.pci_base0;
+               return 0;
+       }
+
+       if (*off < NETXEN_PCI_CRBSPACE)
+               return -1;
+
+       *off -= NETXEN_PCI_CRBSPACE;
+       end = *off + len;
+
+       /*
+        * Try direct map
+        */
+       m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
+
+       if (m->valid && (m->start_128M <= *off) && (m->end_128M >= end)) {
+               *off = *off + m->start_2M - m->start_128M +
+                       (ulong)adapter->ahw.pci_base0;
+               return 0;
+       }
+
+       /*
+        * Not in direct map, use crb window
+        */
+       return 1;
+}
+
+/*
+ * In: 'off' is offset from CRB space in 128M pci map
+ * Out: 'off' is 2M pci map addr
+ * side effect: lock crb window
+ */
+static void
+netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
+{
+       u32 win_read;
+
+       adapter->crb_win = CRB_HI(*off);
+       writel(adapter->crb_win, (void *)(CRB_WINDOW_2M +
+               adapter->ahw.pci_base0));
+       /*
+        * Read back value to make sure write has gone through before trying
+        * to use it.
+        */
+       win_read = readl((void *)(CRB_WINDOW_2M + adapter->ahw.pci_base0));
+       if (win_read != adapter->crb_win) {
+               printk(KERN_ERR "%s: Written crbwin (0x%x) != "
+                               "Read crbwin (0x%x), off=0x%lx\n",
+                               __func__, adapter->crb_win, win_read, *off);
+       }
+       *off = (*off & MASK(16)) + CRB_INDIRECT_2M +
+               (ulong)adapter->ahw.pci_base0;
+}
+
 int netxen_load_firmware(struct netxen_adapter *adapter)
 {
        int i;
        u32 data, size = 0;
-       u32 flashaddr = NETXEN_FLASH_BASE, memaddr = NETXEN_PHANTOM_MEM_BASE;
-       u64 off;
-       void __iomem *addr;
+       u32 flashaddr = NETXEN_BOOTLD_START, memaddr = NETXEN_BOOTLD_START;
+
+       size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START)/4;
 
-       size = NETXEN_FIRMWARE_LEN;
-       writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST));
+       if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+               adapter->pci_write_normalize(adapter,
+                               NETXEN_ROMUSB_GLB_CAS_RST, 1);
 
        for (i = 0; i < size; i++) {
-               int retries = 10;
                if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0)
                        return -EIO;
 
-               off = netxen_nic_pci_set_window(adapter, memaddr);
-               addr = pci_base_offset(adapter, off);
-               writel(data, addr);
-               do {
-                       if (readl(addr) == data)
-                               break;
-                       msleep(100);
-                       writel(data, addr);
-               } while (--retries);
-               if (!retries) {
-                       printk(KERN_ERR "%s: firmware load aborted, write failed at 0x%x\n",
-                                       netxen_nic_driver_name, memaddr);
-                       return -EIO;
-               }
+               adapter->pci_mem_write(adapter, memaddr, &data, 4);
                flashaddr += 4;
                memaddr += 4;
+               cond_resched();
+       }
+       msleep(1);
+
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+               adapter->pci_write_normalize(adapter,
+                               NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d);
+       else {
+               adapter->pci_write_normalize(adapter,
+                               NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff);
+               adapter->pci_write_normalize(adapter,
+                               NETXEN_ROMUSB_GLB_CAS_RST, 0);
        }
-       udelay(100);
-       /* make sure Casper is powered on */
-       writel(0x3fff,
-              NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL));
-       writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST));
 
        return 0;
 }
 
 int
-netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
-                      int len)
+netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
+               ulong off, void *data, int len)
 {
        void __iomem *addr;
 
@@ -750,7 +948,7 @@ netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
                addr = NETXEN_CRB_NORMALIZE(adapter, off);
        } else {                /* Window 0 */
                addr = pci_base_offset(adapter, off);
-               netxen_nic_pci_change_crbwindow(adapter, 0);
+               netxen_nic_pci_change_crbwindow_128M(adapter, 0);
        }
 
        DPRINTK(INFO, "writing to base %lx offset %llx addr %p"
@@ -758,7 +956,7 @@ netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
                pci_base(adapter, off), off, addr,
                *(unsigned long long *)data, len);
        if (!addr) {
-               netxen_nic_pci_change_crbwindow(adapter, 1);
+               netxen_nic_pci_change_crbwindow_128M(adapter, 1);
                return 1;
        }
 
@@ -785,14 +983,14 @@ netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
                break;
        }
        if (!ADDR_IN_WINDOW1(off))
-               netxen_nic_pci_change_crbwindow(adapter, 1);
+               netxen_nic_pci_change_crbwindow_128M(adapter, 1);
 
        return 0;
 }
 
 int
-netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data,
-                     int len)
+netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
+               ulong off, void *data, int len)
 {
        void __iomem *addr;
 
@@ -800,13 +998,13 @@ netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data,
                addr = NETXEN_CRB_NORMALIZE(adapter, off);
        } else {                /* Window 0 */
                addr = pci_base_offset(adapter, off);
-               netxen_nic_pci_change_crbwindow(adapter, 0);
+               netxen_nic_pci_change_crbwindow_128M(adapter, 0);
        }
 
        DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
                pci_base(adapter, off), off, addr);
        if (!addr) {
-               netxen_nic_pci_change_crbwindow(adapter, 1);
+               netxen_nic_pci_change_crbwindow_128M(adapter, 1);
                return 1;
        }
        switch (len) {
@@ -830,81 +1028,195 @@ netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data,
        DPRINTK(INFO, "read %lx\n", *(unsigned long *)data);
 
        if (!ADDR_IN_WINDOW1(off))
-               netxen_nic_pci_change_crbwindow(adapter, 1);
+               netxen_nic_pci_change_crbwindow_128M(adapter, 1);
 
        return 0;
 }
 
-void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val)
-{                              /* Only for window 1 */
-       void __iomem *addr;
+int
+netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
+               ulong off, void *data, int len)
+{
+       unsigned long flags = 0;
+       int rv;
 
-       addr = NETXEN_CRB_NORMALIZE(adapter, off);
-       DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n",
-               pci_base(adapter, off), off, addr, val);
-       writel(val, addr);
+       rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
 
-}
+       if (rv == -1) {
+               printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
+                               __func__, off);
+               dump_stack();
+               return -1;
+       }
 
-int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off)
-{                              /* Only for window 1 */
-       void __iomem *addr;
-       int val;
+       if (rv == 1) {
+               write_lock_irqsave(&adapter->adapter_lock, flags);
+               crb_win_lock(adapter);
+               netxen_nic_pci_set_crbwindow_2M(adapter, &off);
+       }
 
-       addr = NETXEN_CRB_NORMALIZE(adapter, off);
-       DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
-               pci_base(adapter, off), off, addr);
-       val = readl(addr);
-       writel(val, addr);
+       DPRINTK(1, INFO, "write data %lx to offset %llx, len=%d\n",
+                       *(unsigned long *)data, off, len);
 
-       return val;
+       switch (len) {
+       case 1:
+               writeb(*(uint8_t *)data, (void *)off);
+               break;
+       case 2:
+               writew(*(uint16_t *)data, (void *)off);
+               break;
+       case 4:
+               writel(*(uint32_t *)data, (void *)off);
+               break;
+       case 8:
+               writeq(*(uint64_t *)data, (void *)off);
+               break;
+       default:
+               DPRINTK(1, INFO,
+                       "writing data %lx to offset %llx, num words=%d\n",
+                       *(unsigned long *)data, off, (len>>3));
+               break;
+       }
+       if (rv == 1) {
+               crb_win_unlock(adapter);
+               write_unlock_irqrestore(&adapter->adapter_lock, flags);
+       }
+
+       return 0;
 }
 
-/* Change the window to 0, write and change back to window 1. */
-void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value)
+int
+netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
+               ulong off, void *data, int len)
 {
-       void __iomem *addr;
+       unsigned long flags = 0;
+       int rv;
 
-       netxen_nic_pci_change_crbwindow(adapter, 0);
-       addr = pci_base_offset(adapter, index);
-       writel(value, addr);
-       netxen_nic_pci_change_crbwindow(adapter, 1);
-}
+       rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
 
-/* Change the window to 0, read and change back to window 1. */
-void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value)
-{
-       void __iomem *addr;
+       if (rv == -1) {
+               printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
+                               __func__, off);
+               dump_stack();
+               return -1;
+       }
 
-       addr = pci_base_offset(adapter, index);
+       if (rv == 1) {
+               write_lock_irqsave(&adapter->adapter_lock, flags);
+               crb_win_lock(adapter);
+               netxen_nic_pci_set_crbwindow_2M(adapter, &off);
+       }
 
-       netxen_nic_pci_change_crbwindow(adapter, 0);
-       *value = readl(addr);
-       netxen_nic_pci_change_crbwindow(adapter, 1);
-}
+       DPRINTK(1, INFO, "read from offset %lx, len=%d\n", off, len);
 
-static int netxen_pci_set_window_warning_count;
+       switch (len) {
+       case 1:
+               *(uint8_t *)data = readb((void *)off);
+               break;
+       case 2:
+               *(uint16_t *)data = readw((void *)off);
+               break;
+       case 4:
+               *(uint32_t *)data = readl((void *)off);
+               break;
+       case 8:
+               *(uint64_t *)data = readq((void *)off);
+               break;
+       default:
+               break;
+       }
 
-static  unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter,
-                                               unsigned long long addr)
-{
-       static int ddr_mn_window = -1;
-       static int qdr_sn_window = -1;
-       int window;
+       DPRINTK(1, INFO, "read %lx\n", *(unsigned long *)data);
+
+       if (rv == 1) {
+               crb_win_unlock(adapter);
+               write_unlock_irqrestore(&adapter->adapter_lock, flags);
+       }
+
+       return 0;
+}
+
+void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val)
+{
+       adapter->hw_write_wx(adapter, off, &val, 4);
+}
+
+int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off)
+{
+       int val;
+       adapter->hw_read_wx(adapter, off, &val, 4);
+       return val;
+}
+
+/* Change the window to 0, write and change back to window 1. */
+void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value)
+{
+       adapter->hw_write_wx(adapter, index, &value, 4);
+}
+
+/* Change the window to 0, read and change back to window 1. */
+void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value)
+{
+       adapter->hw_read_wx(adapter, index, value, 4);
+}
+
+void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value)
+{
+       adapter->hw_write_wx(adapter, index, &value, 4);
+}
+
+void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value)
+{
+       adapter->hw_read_wx(adapter, index, value, 4);
+}
+
+/*
+ * check memory access boundary.
+ * used by test agent. support ddr access only for now
+ */
+static unsigned long
+netxen_nic_pci_mem_bound_check(struct netxen_adapter *adapter,
+               unsigned long long addr, int size)
+{
+       if (!ADDR_IN_RANGE(addr,
+                       NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX) ||
+               !ADDR_IN_RANGE(addr+size-1,
+                       NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX) ||
+               ((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
+               return 0;
+       }
+
+       return 1;
+}
+
+static int netxen_pci_set_window_warning_count;
+
+unsigned long
+netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
+               unsigned long long addr)
+{
+       void __iomem *offset;
+       int window;
+       unsigned long long      qdr_max;
+       uint8_t func = adapter->ahw.pci_func;
+
+       if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+               qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2;
+       } else {
+               qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3;
+       }
 
        if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
                /* DDR network side */
                addr -= NETXEN_ADDR_DDR_NET;
                window = (addr >> 25) & 0x3ff;
-               if (ddr_mn_window != window) {
-                       ddr_mn_window = window;
-                       writel(window, PCI_OFFSET_SECOND_RANGE(adapter,
-                                                              NETXEN_PCIX_PH_REG
-                                                              (PCIX_MN_WINDOW(adapter->ahw.pci_func))));
+               if (adapter->ahw.ddr_mn_window != window) {
+                       adapter->ahw.ddr_mn_window = window;
+                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
+                               NETXEN_PCIX_PH_REG(PCIE_MN_WINDOW_REG(func)));
+                       writel(window, offset);
                        /* MUST make sure window is set before we forge on... */
-                       readl(PCI_OFFSET_SECOND_RANGE(adapter,
-                                                     NETXEN_PCIX_PH_REG
-                                                     (PCIX_MN_WINDOW(adapter->ahw.pci_func))));
+                       readl(offset);
                }
                addr -= (window * NETXEN_WINDOW_ONE);
                addr += NETXEN_PCI_DDR_NET;
@@ -914,22 +1226,17 @@ static  unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter,
        } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
                addr -= NETXEN_ADDR_OCM1;
                addr += NETXEN_PCI_OCM1;
-       } else
-           if (ADDR_IN_RANGE
-               (addr, NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX)) {
+       } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) {
                /* QDR network side */
                addr -= NETXEN_ADDR_QDR_NET;
                window = (addr >> 22) & 0x3f;
-               if (qdr_sn_window != window) {
-                       qdr_sn_window = window;
-                       writel((window << 22),
-                              PCI_OFFSET_SECOND_RANGE(adapter,
-                                                      NETXEN_PCIX_PH_REG
-                                                      (PCIX_SN_WINDOW(adapter->ahw.pci_func))));
+               if (adapter->ahw.qdr_sn_window != window) {
+                       adapter->ahw.qdr_sn_window = window;
+                       offset = PCI_OFFSET_SECOND_RANGE(adapter,
+                               NETXEN_PCIX_PH_REG(PCIE_SN_WINDOW_REG(func)));
+                       writel((window << 22), offset);
                        /* MUST make sure window is set before we forge on... */
-                       readl(PCI_OFFSET_SECOND_RANGE(adapter,
-                                                     NETXEN_PCIX_PH_REG
-                                                     (PCIX_SN_WINDOW(adapter->ahw.pci_func))));
+                       readl(offset);
                }
                addr -= (window * 0x400000);
                addr += NETXEN_PCI_QDR_NET;
@@ -943,11 +1250,711 @@ static  unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter,
                        printk("%s: Warning:netxen_nic_pci_set_window()"
                               " Unknown address range!\n",
                               netxen_nic_driver_name);
+               addr = -1UL;
+       }
+       return addr;
+}
+
+/*
+ * Note : only 32-bit writes!
+ */
+int netxen_nic_pci_write_immediate_128M(struct netxen_adapter *adapter,
+               u64 off, u32 data)
+{
+       writel(data, (void __iomem *)(PCI_OFFSET_SECOND_RANGE(adapter, off)));
+       return 0;
+}
+
+u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off)
+{
+       return readl((void __iomem *)(pci_base_offset(adapter, off)));
+}
+
+void netxen_nic_pci_write_normalize_128M(struct netxen_adapter *adapter,
+               u64 off, u32 data)
+{
+       writel(data, NETXEN_CRB_NORMALIZE(adapter, off));
+}
 
+u32 netxen_nic_pci_read_normalize_128M(struct netxen_adapter *adapter, u64 off)
+{
+       return readl(NETXEN_CRB_NORMALIZE(adapter, off));
+}
+
+unsigned long
+netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
+               unsigned long long addr)
+{
+       int window;
+       u32 win_read;
+
+       if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
+               /* DDR network side */
+               window = MN_WIN(addr);
+               adapter->ahw.ddr_mn_window = window;
+               adapter->hw_write_wx(adapter,
+                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
+                               &window, 4);
+               adapter->hw_read_wx(adapter,
+                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
+                               &win_read, 4);
+               if ((win_read << 17) != window) {
+                       printk(KERN_INFO "Written MNwin (0x%x) != "
+                               "Read MNwin (0x%x)\n", window, win_read);
+               }
+               addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_DDR_NET;
+       } else if (ADDR_IN_RANGE(addr,
+                               NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
+               if ((addr & 0x00ff800) == 0xff800) {
+                       printk("%s: QM access not handled.\n", __func__);
+                       addr = -1UL;
+               }
+
+               window = OCM_WIN(addr);
+               adapter->ahw.ddr_mn_window = window;
+               adapter->hw_write_wx(adapter,
+                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
+                               &window, 4);
+               adapter->hw_read_wx(adapter,
+                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
+                               &win_read, 4);
+               if ((win_read >> 7) != window) {
+                       printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
+                                       "Read OCMwin (0x%x)\n",
+                                       __func__, window, win_read);
+               }
+               addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_OCM0_2M;
+
+       } else if (ADDR_IN_RANGE(addr,
+                       NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX_P3)) {
+               /* QDR network side */
+               window = MS_WIN(addr);
+               adapter->ahw.qdr_sn_window = window;
+               adapter->hw_write_wx(adapter,
+                               adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
+                               &window, 4);
+               adapter->hw_read_wx(adapter,
+                               adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
+                               &win_read, 4);
+               if (win_read != window) {
+                       printk(KERN_INFO "%s: Written MSwin (0x%x) != "
+                                       "Read MSwin (0x%x)\n",
+                                       __func__, window, win_read);
+               }
+               addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_QDR_NET;
+
+       } else {
+               /*
+                * peg gdb frequently accesses memory that doesn't exist,
+                * this limits the chit chat so debugging isn't slowed down.
+                */
+               if ((netxen_pci_set_window_warning_count++ < 8)
+                       || (netxen_pci_set_window_warning_count%64 == 0)) {
+                       printk("%s: Warning:%s Unknown address range!\n",
+                                       __func__, netxen_nic_driver_name);
+}
+               addr = -1UL;
        }
        return addr;
 }
 
+static int netxen_nic_pci_is_same_window(struct netxen_adapter *adapter,
+                                     unsigned long long addr)
+{
+       int window;
+       unsigned long long qdr_max;
+
+       if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+               qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2;
+       else
+               qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3;
+
+       if (ADDR_IN_RANGE(addr,
+                       NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
+               /* DDR network side */
+               BUG();  /* MN access can not come here */
+       } else if (ADDR_IN_RANGE(addr,
+                       NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
+               return 1;
+       } else if (ADDR_IN_RANGE(addr,
+                               NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
+               return 1;
+       } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) {
+               /* QDR network side */
+               window = ((addr - NETXEN_ADDR_QDR_NET) >> 22) & 0x3f;
+               if (adapter->ahw.qdr_sn_window == window)
+                       return 1;
+       }
+
+       return 0;
+}
+
+static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter,
+                       u64 off, void *data, int size)
+{
+       unsigned long flags;
+       void *addr;
+       int ret = 0;
+       u64 start;
+       uint8_t *mem_ptr = NULL;
+       unsigned long mem_base;
+       unsigned long mem_page;
+
+       write_lock_irqsave(&adapter->adapter_lock, flags);
+
+       /*
+        * If attempting to access unknown address or straddle hw windows,
+        * do not access.
+        */
+       start = adapter->pci_set_window(adapter, off);
+       if ((start == -1UL) ||
+               (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
+               write_unlock_irqrestore(&adapter->adapter_lock, flags);
+               printk(KERN_ERR "%s out of bound pci memory access. "
+                       "offset is 0x%llx\n", netxen_nic_driver_name, off);
+               return -1;
+       }
+
+       addr = (void *)(pci_base_offset(adapter, start));
+       if (!addr) {
+               write_unlock_irqrestore(&adapter->adapter_lock, flags);
+               mem_base = pci_resource_start(adapter->pdev, 0);
+               mem_page = start & PAGE_MASK;
+               /* Map two pages whenever user tries to access addresses in two
+               consecutive pages.
+               */
+               if (mem_page != ((start + size - 1) & PAGE_MASK))
+                       mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+               else
+                       mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
+               if (mem_ptr == 0UL) {
+                       *(uint8_t  *)data = 0;
+                       return -1;
+               }
+               addr = mem_ptr;
+               addr += start & (PAGE_SIZE - 1);
+               write_lock_irqsave(&adapter->adapter_lock, flags);
+       }
+
+       switch (size) {
+       case 1:
+               *(uint8_t  *)data = readb(addr);
+               break;
+       case 2:
+               *(uint16_t *)data = readw(addr);
+               break;
+       case 4:
+               *(uint32_t *)data = readl(addr);
+               break;
+       case 8:
+               *(uint64_t *)data = readq(addr);
+               break;
+       default:
+               ret = -1;
+               break;
+       }
+       write_unlock_irqrestore(&adapter->adapter_lock, flags);
+       DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data);
+
+       if (mem_ptr)
+               iounmap(mem_ptr);
+       return ret;
+}
+
+static int
+netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
+               void *data, int size)
+{
+       unsigned long flags;
+       void *addr;
+       int ret = 0;
+       u64 start;
+       uint8_t *mem_ptr = NULL;
+       unsigned long mem_base;
+       unsigned long mem_page;
+
+       write_lock_irqsave(&adapter->adapter_lock, flags);
+
+       /*
+        * If attempting to access unknown address or straddle hw windows,
+        * do not access.
+        */
+       start = adapter->pci_set_window(adapter, off);
+       if ((start == -1UL) ||
+               (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
+               write_unlock_irqrestore(&adapter->adapter_lock, flags);
+               printk(KERN_ERR "%s out of bound pci memory access. "
+                       "offset is 0x%llx\n", netxen_nic_driver_name, off);
+               return -1;
+       }
+
+       addr = (void *)(pci_base_offset(adapter, start));
+       if (!addr) {
+               write_unlock_irqrestore(&adapter->adapter_lock, flags);
+               mem_base = pci_resource_start(adapter->pdev, 0);
+               mem_page = start & PAGE_MASK;
+               /* Map two pages whenever user tries to access addresses in two
+                * consecutive pages.
+                */
+               if (mem_page != ((start + size - 1) & PAGE_MASK))
+                       mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE*2);
+               else
+                       mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
+               if (mem_ptr == 0UL)
+                       return -1;
+               addr = mem_ptr;
+               addr += start & (PAGE_SIZE - 1);
+               write_lock_irqsave(&adapter->adapter_lock, flags);
+       }
+
+       switch (size) {
+       case 1:
+               writeb(*(uint8_t *)data, addr);
+               break;
+       case 2:
+               writew(*(uint16_t *)data, addr);
+               break;
+       case 4:
+               writel(*(uint32_t *)data, addr);
+               break;
+       case 8:
+               writeq(*(uint64_t *)data, addr);
+               break;
+       default:
+               ret = -1;
+               break;
+       }
+       write_unlock_irqrestore(&adapter->adapter_lock, flags);
+       DPRINTK(1, INFO, "writing data %llx to offset %llx\n",
+                       *(unsigned long long *)data, start);
+       if (mem_ptr)
+               iounmap(mem_ptr);
+       return ret;
+}
+
+#define MAX_CTL_CHECK   1000
+
+int
+netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
+               u64 off, void *data, int size)
+{
+       unsigned long   flags, mem_crb;
+       int          i, j, ret = 0, loop, sz[2], off0;
+       uint32_t      temp;
+       uint64_t      off8, tmpw, word[2] = {0, 0};
+
+       /*
+        * If not MN, go check for MS or invalid.
+        */
+       if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
+               return netxen_nic_pci_mem_write_direct(adapter,
+                               off, data, size);
+
+       off8 = off & 0xfffffff8;
+       off0 = off & 0x7;
+       sz[0] = (size < (8 - off0)) ? size : (8 - off0);
+       sz[1] = size - sz[0];
+       loop = ((off0 + size - 1) >> 3) + 1;
+       mem_crb = (unsigned long)pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+
+       if ((size != 8) || (off0 != 0))  {
+               for (i = 0; i < loop; i++) {
+                       if (adapter->pci_mem_read(adapter,
+                               off8 + (i << 3), &word[i], 8))
+                               return -1;
+               }
+       }
+
+       switch (size) {
+       case 1:
+               tmpw = *((uint8_t *)data);
+               break;
+       case 2:
+               tmpw = *((uint16_t *)data);
+               break;
+       case 4:
+               tmpw = *((uint32_t *)data);
+               break;
+       case 8:
+       default:
+               tmpw = *((uint64_t *)data);
+               break;
+       }
+       word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
+       word[0] |= tmpw << (off0 * 8);
+
+       if (loop == 2) {
+               word[1] &= ~(~0ULL << (sz[1] * 8));
+               word[1] |= tmpw >> (sz[0] * 8);
+       }
+
+       write_lock_irqsave(&adapter->adapter_lock, flags);
+       netxen_nic_pci_change_crbwindow_128M(adapter, 0);
+
+       for (i = 0; i < loop; i++) {
+               writel((uint32_t)(off8 + (i << 3)),
+                       (void *)(mem_crb+MIU_TEST_AGT_ADDR_LO));
+               writel(0,
+                       (void *)(mem_crb+MIU_TEST_AGT_ADDR_HI));
+               writel(word[i] & 0xffffffff,
+                       (void *)(mem_crb+MIU_TEST_AGT_WRDATA_LO));
+               writel((word[i] >> 32) & 0xffffffff,
+                       (void *)(mem_crb+MIU_TEST_AGT_WRDATA_HI));
+               writel(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
+                       (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+               writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
+                       (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+
+               for (j = 0; j < MAX_CTL_CHECK; j++) {
+                       temp = readl(
+                            (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+                       if ((temp & MIU_TA_CTL_BUSY) == 0)
+                               break;
+               }
+
+               if (j >= MAX_CTL_CHECK) {
+                       printk("%s: %s Fail to write through agent\n",
+                                       __func__, netxen_nic_driver_name);
+                       ret = -1;
+                       break;
+               }
+       }
+
+       netxen_nic_pci_change_crbwindow_128M(adapter, 1);
+       write_unlock_irqrestore(&adapter->adapter_lock, flags);
+       return ret;
+}
+
+int
+netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
+               u64 off, void *data, int size)
+{
+       unsigned long   flags, mem_crb;
+       int          i, j = 0, k, start, end, loop, sz[2], off0[2];
+       uint32_t      temp;
+       uint64_t      off8, val, word[2] = {0, 0};
+
+
+       /*
+        * If not MN, go check for MS or invalid.
+        */
+       if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
+               return netxen_nic_pci_mem_read_direct(adapter, off, data, size);
+
+       off8 = off & 0xfffffff8;
+       off0[0] = off & 0x7;
+       off0[1] = 0;
+       sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
+       sz[1] = size - sz[0];
+       loop = ((off0[0] + size - 1) >> 3) + 1;
+       mem_crb = (unsigned long)pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+
+       write_lock_irqsave(&adapter->adapter_lock, flags);
+       netxen_nic_pci_change_crbwindow_128M(adapter, 0);
+
+       for (i = 0; i < loop; i++) {
+               writel((uint32_t)(off8 + (i << 3)),
+                       (void *)(mem_crb+MIU_TEST_AGT_ADDR_LO));
+               writel(0,
+                       (void *)(mem_crb+MIU_TEST_AGT_ADDR_HI));
+               writel(MIU_TA_CTL_ENABLE,
+                       (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+               writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
+                       (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+
+               for (j = 0; j < MAX_CTL_CHECK; j++) {
+                       temp = readl(
+                             (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+                       if ((temp & MIU_TA_CTL_BUSY) == 0)
+                               break;
+               }
+
+               if (j >= MAX_CTL_CHECK) {
+                       printk(KERN_ERR "%s: %s Fail to read through agent\n",
+                                       __func__, netxen_nic_driver_name);
+                       break;
+               }
+
+               start = off0[i] >> 2;
+               end   = (off0[i] + sz[i] - 1) >> 2;
+               for (k = start; k <= end; k++) {
+                       word[i] |= ((uint64_t) readl(
+                                   (void *)(mem_crb +
+                                   MIU_TEST_AGT_RDDATA(k))) << (32*k));
+               }
+       }
+
+       netxen_nic_pci_change_crbwindow_128M(adapter, 1);
+       write_unlock_irqrestore(&adapter->adapter_lock, flags);
+
+       if (j >= MAX_CTL_CHECK)
+               return -1;
+
+       if (sz[0] == 8) {
+               val = word[0];
+       } else {
+               val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
+                       ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
+       }
+
+       switch (size) {
+       case 1:
+               *(uint8_t  *)data = val;
+               break;
+       case 2:
+               *(uint16_t *)data = val;
+               break;
+       case 4:
+               *(uint32_t *)data = val;
+               break;
+       case 8:
+               *(uint64_t *)data = val;
+               break;
+       }
+       DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data);
+       return 0;
+}
+
+int
+netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
+               u64 off, void *data, int size)
+{
+       int i, j, ret = 0, loop, sz[2], off0;
+       uint32_t temp;
+       uint64_t off8, mem_crb, tmpw, word[2] = {0, 0};
+
+       /*
+        * If not MN, go check for MS or invalid.
+        */
+       if (off >= NETXEN_ADDR_QDR_NET && off <= NETXEN_ADDR_QDR_NET_MAX_P3)
+               mem_crb = NETXEN_CRB_QDR_NET;
+       else {
+               mem_crb = NETXEN_CRB_DDR_NET;
+               if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
+                       return netxen_nic_pci_mem_write_direct(adapter,
+                                       off, data, size);
+       }
+
+       off8 = off & 0xfffffff8;
+       off0 = off & 0x7;
+       sz[0] = (size < (8 - off0)) ? size : (8 - off0);
+       sz[1] = size - sz[0];
+       loop = ((off0 + size - 1) >> 3) + 1;
+
+       if ((size != 8) || (off0 != 0)) {
+               for (i = 0; i < loop; i++) {
+                       if (adapter->pci_mem_read(adapter, off8 + (i << 3),
+                                               &word[i], 8))
+                               return -1;
+               }
+       }
+
+       switch (size) {
+       case 1:
+               tmpw = *((uint8_t *)data);
+               break;
+       case 2:
+               tmpw = *((uint16_t *)data);
+               break;
+       case 4:
+               tmpw = *((uint32_t *)data);
+               break;
+       case 8:
+       default:
+               tmpw = *((uint64_t *)data);
+       break;
+       }
+
+       word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
+       word[0] |= tmpw << (off0 * 8);
+
+       if (loop == 2) {
+               word[1] &= ~(~0ULL << (sz[1] * 8));
+               word[1] |= tmpw >> (sz[0] * 8);
+       }
+
+       /*
+        * don't lock here - write_wx gets the lock if each time
+        * write_lock_irqsave(&adapter->adapter_lock, flags);
+        * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
+        */
+
+       for (i = 0; i < loop; i++) {
+               temp = off8 + (i << 3);
+               adapter->hw_write_wx(adapter,
+                               mem_crb+MIU_TEST_AGT_ADDR_LO, &temp, 4);
+               temp = 0;
+               adapter->hw_write_wx(adapter,
+                               mem_crb+MIU_TEST_AGT_ADDR_HI, &temp, 4);
+               temp = word[i] & 0xffffffff;
+               adapter->hw_write_wx(adapter,
+                               mem_crb+MIU_TEST_AGT_WRDATA_LO, &temp, 4);
+               temp = (word[i] >> 32) & 0xffffffff;
+               adapter->hw_write_wx(adapter,
+                               mem_crb+MIU_TEST_AGT_WRDATA_HI, &temp, 4);
+               temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
+               adapter->hw_write_wx(adapter,
+                               mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
+               temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
+               adapter->hw_write_wx(adapter,
+                               mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
+
+               for (j = 0; j < MAX_CTL_CHECK; j++) {
+                       adapter->hw_read_wx(adapter,
+                                       mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+                       if ((temp & MIU_TA_CTL_BUSY) == 0)
+                               break;
+               }
+
+               if (j >= MAX_CTL_CHECK) {
+                       printk(KERN_ERR "%s: Fail to write through agent\n",
+                                       netxen_nic_driver_name);
+                       ret = -1;
+                       break;
+               }
+       }
+
+       /*
+        * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
+        * write_unlock_irqrestore(&adapter->adapter_lock, flags);
+        */
+       return ret;
+}
+
+int
+netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
+               u64 off, void *data, int size)
+{
+       int i, j = 0, k, start, end, loop, sz[2], off0[2];
+       uint32_t      temp;
+       uint64_t      off8, val, mem_crb, word[2] = {0, 0};
+
+       /*
+        * If not MN, go check for MS or invalid.
+        */
+
+       if (off >= NETXEN_ADDR_QDR_NET && off <= NETXEN_ADDR_QDR_NET_MAX_P3)
+               mem_crb = NETXEN_CRB_QDR_NET;
+       else {
+               mem_crb = NETXEN_CRB_DDR_NET;
+               if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
+                       return netxen_nic_pci_mem_read_direct(adapter,
+                                       off, data, size);
+       }
+
+       off8 = off & 0xfffffff8;
+       off0[0] = off & 0x7;
+       off0[1] = 0;
+       sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
+       sz[1] = size - sz[0];
+       loop = ((off0[0] + size - 1) >> 3) + 1;
+
+       /*
+        * don't lock here - write_wx gets the lock if each time
+        * write_lock_irqsave(&adapter->adapter_lock, flags);
+        * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
+        */
+
+       for (i = 0; i < loop; i++) {
+               temp = off8 + (i << 3);
+               adapter->hw_write_wx(adapter,
+                               mem_crb + MIU_TEST_AGT_ADDR_LO, &temp, 4);
+               temp = 0;
+               adapter->hw_write_wx(adapter,
+                               mem_crb + MIU_TEST_AGT_ADDR_HI, &temp, 4);
+               temp = MIU_TA_CTL_ENABLE;
+               adapter->hw_write_wx(adapter,
+                               mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+               temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
+               adapter->hw_write_wx(adapter,
+                               mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+
+               for (j = 0; j < MAX_CTL_CHECK; j++) {
+                       adapter->hw_read_wx(adapter,
+                                       mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+                       if ((temp & MIU_TA_CTL_BUSY) == 0)
+                               break;
+               }
+
+               if (j >= MAX_CTL_CHECK) {
+                       printk(KERN_ERR "%s: Fail to read through agent\n",
+                                       netxen_nic_driver_name);
+                       break;
+               }
+
+               start = off0[i] >> 2;
+               end   = (off0[i] + sz[i] - 1) >> 2;
+               for (k = start; k <= end; k++) {
+                       adapter->hw_read_wx(adapter,
+                               mem_crb + MIU_TEST_AGT_RDDATA(k), &temp, 4);
+                       word[i] |= ((uint64_t)temp << (32 * k));
+               }
+       }
+
+       /*
+        * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
+        * write_unlock_irqrestore(&adapter->adapter_lock, flags);
+        */
+
+       if (j >= MAX_CTL_CHECK)
+               return -1;
+
+       if (sz[0] == 8) {
+               val = word[0];
+       } else {
+               val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
+               ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
+       }
+
+       switch (size) {
+       case 1:
+               *(uint8_t  *)data = val;
+               break;
+       case 2:
+               *(uint16_t *)data = val;
+               break;
+       case 4:
+               *(uint32_t *)data = val;
+               break;
+       case 8:
+               *(uint64_t *)data = val;
+               break;
+       }
+       DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data);
+       return 0;
+}
+
+/*
+ * Note : only 32-bit writes!
+ */
+int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
+               u64 off, u32 data)
+{
+       adapter->hw_write_wx(adapter, off, &data, 4);
+
+       return 0;
+}
+
+u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off)
+{
+       u32 temp;
+       adapter->hw_read_wx(adapter, off, &temp, 4);
+       return temp;
+}
+
+void netxen_nic_pci_write_normalize_2M(struct netxen_adapter *adapter,
+               u64 off, u32 data)
+{
+       adapter->hw_write_wx(adapter, off, &data, 4);
+}
+
+u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off)
+{
+       u32 temp;
+       adapter->hw_read_wx(adapter, off, &temp, 4);
+       return temp;
+}
+
 #if 0
 int
 netxen_nic_erase_pxe(struct netxen_adapter *adapter)
@@ -1003,12 +2010,25 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
        case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
        case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
        case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
+       case NETXEN_BRDTYPE_P3_HMEZ:
+       case NETXEN_BRDTYPE_P3_XG_LOM:
+       case NETXEN_BRDTYPE_P3_10G_CX4:
+       case NETXEN_BRDTYPE_P3_10G_CX4_LP:
+       case NETXEN_BRDTYPE_P3_IMEZ:
+       case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
+       case NETXEN_BRDTYPE_P3_10G_XFP:
+       case NETXEN_BRDTYPE_P3_10000_BASE_T:
+
                adapter->ahw.board_type = NETXEN_NIC_XGBE;
                break;
        case NETXEN_BRDTYPE_P1_BD:
        case NETXEN_BRDTYPE_P1_SB:
        case NETXEN_BRDTYPE_P1_SMAX:
        case NETXEN_BRDTYPE_P1_SOCK:
+       case NETXEN_BRDTYPE_P3_REF_QG:
+       case NETXEN_BRDTYPE_P3_4_GB:
+       case NETXEN_BRDTYPE_P3_4_GB_MM:
+
                adapter->ahw.board_type = NETXEN_NIC_GBE;
                break;
        default:
@@ -1042,25 +2062,11 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
        return 0;
 }
 
-void netxen_nic_init_niu_gb(struct netxen_adapter *adapter)
-{
-       netxen_niu_gbe_init_port(adapter, adapter->physical_port);
-}
-
 void
-netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off,
-                           int data)
+netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
+               unsigned long off, int data)
 {
-       void __iomem *addr;
-
-       if (ADDR_IN_WINDOW1(off)) {
-               writel(data, NETXEN_CRB_NORMALIZE(adapter, off));
-       } else {
-               netxen_nic_pci_change_crbwindow(adapter, 0);
-               addr = pci_base_offset(adapter, off);
-               writel(data, addr);
-               netxen_nic_pci_change_crbwindow(adapter, 1);
-       }
+       adapter->hw_write_wx(adapter, off, &data, 4);
 }
 
 void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
@@ -1147,12 +2153,11 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
                addr += sizeof(u32);
        }
 
-       fw_major = readl(NETXEN_CRB_NORMALIZE(adapter,
-                                             NETXEN_FW_VERSION_MAJOR));
-       fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter,
-                                             NETXEN_FW_VERSION_MINOR));
-       fw_build =
-           readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB));
+       adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MAJOR, &fw_major, 4);
+       adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MINOR, &fw_minor, 4);
+       adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB, &fw_build, 4);
+
+       adapter->fw_major = fw_major;
 
        if (adapter->portnum == 0) {
                get_brd_name_by_type(board_info->board_type, brd_name);
@@ -1163,28 +2168,13 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
                                fw_minor, fw_build);
        }
 
-       if (fw_major != _NETXEN_NIC_LINUX_MAJOR) {
-               adapter->driver_mismatch = 1;
-       }
-       if (fw_minor != _NETXEN_NIC_LINUX_MINOR &&
-                       fw_minor != (_NETXEN_NIC_LINUX_MINOR + 1)) {
+       if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) <
+                       NETXEN_VERSION_CODE(3, 4, 216)) {
                adapter->driver_mismatch = 1;
-       }
-       if (adapter->driver_mismatch) {
-               printk(KERN_ERR "%s: driver and firmware version mismatch\n",
-                               adapter->netdev->name);
+               printk(KERN_ERR "%s: firmware version %d.%d.%d unsupported\n",
+                               netxen_nic_driver_name,
+                               fw_major, fw_minor, fw_build);
                return;
        }
-
-       switch (adapter->ahw.board_type) {
-       case NETXEN_NIC_GBE:
-               dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
-                               adapter->netdev->name);
-               break;
-       case NETXEN_NIC_XGBE:
-               dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n",
-                               adapter->netdev->name);
-               break;
-       }
 }
 
index a3ea1dd98c41562ed9b9f790279f7185584fc506..b8e0030f03d71941fad5a48c4f43aa1fa2c863f7 100644 (file)
@@ -82,19 +82,9 @@ struct netxen_adapter;
 
 #define NETXEN_PCI_MAPSIZE_BYTES  (NETXEN_PCI_MAPSIZE << 20)
 
-#define NETXEN_NIC_LOCKED_READ_REG(X, Y)       \
-       addr = pci_base_offset(adapter, X);     \
-       *(u32 *)Y = readl((void __iomem*) addr);
-
 struct netxen_port;
 void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
 void netxen_nic_flash_print(struct netxen_adapter *adapter);
-int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off,
-                          void *data, int len);
-void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
-                                unsigned long off, int data);
-int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off,
-                         void *data, int len);
 
 typedef u8 netxen_ethernet_macaddr_t[6];
 
@@ -432,7 +422,8 @@ typedef enum {
 /* Promiscous mode options (GbE mode only) */
 typedef enum {
        NETXEN_NIU_PROMISC_MODE = 0,
-       NETXEN_NIU_NON_PROMISC_MODE
+       NETXEN_NIU_NON_PROMISC_MODE,
+       NETXEN_NIU_ALLMULTI_MODE
 } netxen_niu_prom_mode_t;
 
 /*
@@ -478,42 +469,6 @@ typedef enum {
 #define netxen_xg_soft_reset(config_word)      \
                ((config_word) |= 1 << 4)
 
-/*
- * MAC Control Register
- *
- * Bit 0-1   : id_pool0
- * Bit 2     : enable_xtnd0
- * Bit 4-5   : id_pool1
- * Bit 6     : enable_xtnd1
- * Bit 8-9   : id_pool2
- * Bit 10    : enable_xtnd2
- * Bit 12-13 : id_pool3
- * Bit 14    : enable_xtnd3
- * Bit 24-25 : mode_select
- * Bit 28-31 : enable_pool
- */
-
-#define netxen_nic_mcr_set_id_pool0(config, val)       \
-               ((config) |= ((val) &0x03))
-#define netxen_nic_mcr_set_enable_xtnd0(config)        \
-               ((config) |= 1 << 3)
-#define netxen_nic_mcr_set_id_pool1(config, val)       \
-               ((config) |= (((val) & 0x03) << 4))
-#define netxen_nic_mcr_set_enable_xtnd1(config)        \
-               ((config) |= 1 << 6)
-#define netxen_nic_mcr_set_id_pool2(config, val)       \
-               ((config) |= (((val) & 0x03) << 8))
-#define netxen_nic_mcr_set_enable_xtnd2(config)        \
-               ((config) |= 1 << 10)
-#define netxen_nic_mcr_set_id_pool3(config, val)       \
-               ((config) |= (((val) & 0x03) << 12))
-#define netxen_nic_mcr_set_enable_xtnd3(config)        \
-               ((config) |= 1 << 14)
-#define netxen_nic_mcr_set_mode_select(config, val)    \
-               ((config) |= (((val) & 0x03) << 24))
-#define netxen_nic_mcr_set_enable_pool(config, val)    \
-               ((config) |= (((val) & 0x0f) << 28))
-
 /* Set promiscuous mode for a GbE interface */
 int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
                                    netxen_niu_prom_mode_t mode);
@@ -538,4 +493,15 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter);
 
 int netxen_niu_disable_xg_port(struct netxen_adapter *adapter);
 
+typedef struct {
+       unsigned valid;
+       unsigned start_128M;
+       unsigned end_128M;
+       unsigned start_2M;
+} crb_128M_2M_sub_block_map_t;
+
+typedef struct {
+       crb_128M_2M_sub_block_map_t sub_block[16];
+} crb_128M_2M_block_map_t;
+
 #endif                         /* __NETXEN_NIC_HW_H_ */
index 70d1b22ced220c601276f47a4e6e92b50a95f7a0..01ab31b34a85d01d08f406768a24d3c9733f3504 100644 (file)
@@ -42,8 +42,6 @@ struct crb_addr_pair {
        u32 data;
 };
 
-unsigned long last_schedule_time;
-
 #define NETXEN_MAX_CRB_XFORM 60
 static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
 #define NETXEN_ADDR_ERROR (0xffffffff)
@@ -117,6 +115,8 @@ static void crb_addr_transform_setup(void)
        crb_addr_transform(C2C1);
        crb_addr_transform(C2C0);
        crb_addr_transform(SMB);
+       crb_addr_transform(OCM0);
+       crb_addr_transform(I2C0);
 }
 
 int netxen_init_firmware(struct netxen_adapter *adapter)
@@ -124,15 +124,15 @@ int netxen_init_firmware(struct netxen_adapter *adapter)
        u32 state = 0, loops = 0, err = 0;
 
        /* Window 1 call */
-       state = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+       state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
 
        if (state == PHAN_INITIALIZE_ACK)
                return 0;
 
        while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) {
-               udelay(100);
+               msleep(1);
                /* Window 1 call */
-               state = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+               state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
 
                loops++;
        }
@@ -143,64 +143,193 @@ int netxen_init_firmware(struct netxen_adapter *adapter)
                return err;
        }
        /* Window 1 call */
-       writel(INTR_SCHEME_PERPORT,
-              NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_HOST));
-       writel(MSI_MODE_MULTIFUNC,
-              NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_HOST));
-       writel(MPORT_MULTI_FUNCTION_MODE,
-              NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE));
-       writel(PHAN_INITIALIZE_ACK,
-              NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+       adapter->pci_write_normalize(adapter,
+                       CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
+       adapter->pci_write_normalize(adapter,
+                       CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
+       adapter->pci_write_normalize(adapter,
+                       CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
+       adapter->pci_write_normalize(adapter,
+                       CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
 
        return err;
 }
 
-#define NETXEN_ADDR_LIMIT 0xffffffffULL
+void netxen_release_rx_buffers(struct netxen_adapter *adapter)
+{
+       struct netxen_recv_context *recv_ctx;
+       struct nx_host_rds_ring *rds_ring;
+       struct netxen_rx_buffer *rx_buf;
+       int i, ctxid, ring;
+
+       for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
+               recv_ctx = &adapter->recv_ctx[ctxid];
+               for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+                       rds_ring = &recv_ctx->rds_rings[ring];
+                       for (i = 0; i < rds_ring->max_rx_desc_count; ++i) {
+                               rx_buf = &(rds_ring->rx_buf_arr[i]);
+                               if (rx_buf->state == NETXEN_BUFFER_FREE)
+                                       continue;
+                               pci_unmap_single(adapter->pdev,
+                                               rx_buf->dma,
+                                               rds_ring->dma_size,
+                                               PCI_DMA_FROMDEVICE);
+                               if (rx_buf->skb != NULL)
+                                       dev_kfree_skb_any(rx_buf->skb);
+                       }
+               }
+       }
+}
 
-void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr,
-                  struct pci_dev **used_dev)
+void netxen_release_tx_buffers(struct netxen_adapter *adapter)
 {
-       void *addr;
+       struct netxen_cmd_buffer *cmd_buf;
+       struct netxen_skb_frag *buffrag;
+       int i, j;
+
+       cmd_buf = adapter->cmd_buf_arr;
+       for (i = 0; i < adapter->max_tx_desc_count; i++) {
+               buffrag = cmd_buf->frag_array;
+               if (buffrag->dma) {
+                       pci_unmap_single(adapter->pdev, buffrag->dma,
+                                        buffrag->length, PCI_DMA_TODEVICE);
+                       buffrag->dma = 0ULL;
+               }
+               for (j = 0; j < cmd_buf->frag_count; j++) {
+                       buffrag++;
+                       if (buffrag->dma) {
+                               pci_unmap_page(adapter->pdev, buffrag->dma,
+                                              buffrag->length,
+                                              PCI_DMA_TODEVICE);
+                               buffrag->dma = 0ULL;
+                       }
+               }
+               /* Free the skb we received in netxen_nic_xmit_frame */
+               if (cmd_buf->skb) {
+                       dev_kfree_skb_any(cmd_buf->skb);
+                       cmd_buf->skb = NULL;
+               }
+               cmd_buf++;
+       }
+}
 
-       addr = pci_alloc_consistent(pdev, sz, ptr);
-       if ((unsigned long long)(*ptr) < NETXEN_ADDR_LIMIT) {
-               *used_dev = pdev;
-               return addr;
+void netxen_free_sw_resources(struct netxen_adapter *adapter)
+{
+       struct netxen_recv_context *recv_ctx;
+       struct nx_host_rds_ring *rds_ring;
+       int ctx, ring;
+
+       for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) {
+               recv_ctx = &adapter->recv_ctx[ctx];
+               for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+                       rds_ring = &recv_ctx->rds_rings[ring];
+                       if (rds_ring->rx_buf_arr) {
+                               vfree(rds_ring->rx_buf_arr);
+                               rds_ring->rx_buf_arr = NULL;
+                       }
+               }
        }
-       pci_free_consistent(pdev, sz, addr, *ptr);
-       addr = pci_alloc_consistent(NULL, sz, ptr);
-       *used_dev = NULL;
-       return addr;
+       if (adapter->cmd_buf_arr)
+               vfree(adapter->cmd_buf_arr);
+       return;
 }
 
-void netxen_initialize_adapter_sw(struct netxen_adapter *adapter)
+int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
 {
-       int ctxid, ring;
-       u32 i;
-       u32 num_rx_bufs = 0;
-       struct netxen_rcv_desc_ctx *rcv_desc;
+       struct netxen_recv_context *recv_ctx;
+       struct nx_host_rds_ring *rds_ring;
+       struct netxen_rx_buffer *rx_buf;
+       int ctx, ring, i, num_rx_bufs;
 
-       DPRINTK(INFO, "initializing some queues: %p\n", adapter);
-       for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
-               for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
-                       struct netxen_rx_buffer *rx_buf;
-                       rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring];
-                       rcv_desc->begin_alloc = 0;
-                       rx_buf = rcv_desc->rx_buf_arr;
-                       num_rx_bufs = rcv_desc->max_rx_desc_count;
+       struct netxen_cmd_buffer *cmd_buf_arr;
+       struct net_device *netdev = adapter->netdev;
+
+       cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
+       if (cmd_buf_arr == NULL) {
+               printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n",
+                      netdev->name);
+               return -ENOMEM;
+       }
+       memset(cmd_buf_arr, 0, TX_RINGSIZE);
+       adapter->cmd_buf_arr = cmd_buf_arr;
+
+       for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) {
+               recv_ctx = &adapter->recv_ctx[ctx];
+               for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+                       rds_ring = &recv_ctx->rds_rings[ring];
+                       switch (RCV_DESC_TYPE(ring)) {
+                       case RCV_DESC_NORMAL:
+                               rds_ring->max_rx_desc_count =
+                                       adapter->max_rx_desc_count;
+                               rds_ring->flags = RCV_DESC_NORMAL;
+                               if (adapter->ahw.cut_through) {
+                                       rds_ring->dma_size =
+                                               NX_CT_DEFAULT_RX_BUF_LEN;
+                                       rds_ring->skb_size =
+                                               NX_CT_DEFAULT_RX_BUF_LEN;
+                               } else {
+                                       rds_ring->dma_size = RX_DMA_MAP_LEN;
+                                       rds_ring->skb_size =
+                                               MAX_RX_BUFFER_LENGTH;
+                               }
+                               break;
+
+                       case RCV_DESC_JUMBO:
+                               rds_ring->max_rx_desc_count =
+                                       adapter->max_jumbo_rx_desc_count;
+                               rds_ring->flags = RCV_DESC_JUMBO;
+                               if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+                                       rds_ring->dma_size =
+                                               NX_P3_RX_JUMBO_BUF_MAX_LEN;
+                               else
+                                       rds_ring->dma_size =
+                                               NX_P2_RX_JUMBO_BUF_MAX_LEN;
+                               rds_ring->skb_size =
+                                       rds_ring->dma_size + NET_IP_ALIGN;
+                               break;
+
+                       case RCV_RING_LRO:
+                               rds_ring->max_rx_desc_count =
+                                       adapter->max_lro_rx_desc_count;
+                               rds_ring->flags = RCV_DESC_LRO;
+                               rds_ring->dma_size = RX_LRO_DMA_MAP_LEN;
+                               rds_ring->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
+                               break;
+
+                       }
+                       rds_ring->rx_buf_arr = (struct netxen_rx_buffer *)
+                               vmalloc(RCV_BUFFSIZE);
+                       if (rds_ring->rx_buf_arr == NULL) {
+                               printk(KERN_ERR "%s: Failed to allocate "
+                                       "rx buffer ring %d\n",
+                                       netdev->name, ring);
+                               /* free whatever was already allocated */
+                               goto err_out;
+                       }
+                       memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE);
+                       INIT_LIST_HEAD(&rds_ring->free_list);
+                       rds_ring->begin_alloc = 0;
                        /*
                         * Now go through all of them, set reference handles
                         * and put them in the queues.
                         */
+                       num_rx_bufs = rds_ring->max_rx_desc_count;
+                       rx_buf = rds_ring->rx_buf_arr;
                        for (i = 0; i < num_rx_bufs; i++) {
+                               list_add_tail(&rx_buf->list,
+                                               &rds_ring->free_list);
                                rx_buf->ref_handle = i;
                                rx_buf->state = NETXEN_BUFFER_FREE;
-                               DPRINTK(INFO, "Rx buf:ctx%d i(%d) rx_buf:"
-                                       "%p\n", ctxid, i, rx_buf);
                                rx_buf++;
                        }
                }
        }
+
+       return 0;
+
+err_out:
+       netxen_free_sw_resources(adapter);
+       return -ENOMEM;
 }
 
 void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
@@ -211,14 +340,12 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
                    netxen_niu_gbe_enable_phy_interrupts;
                adapter->disable_phy_interrupts =
                    netxen_niu_gbe_disable_phy_interrupts;
-               adapter->handle_phy_intr = netxen_nic_gbe_handle_phy_intr;
                adapter->macaddr_set = netxen_niu_macaddr_set;
                adapter->set_mtu = netxen_nic_set_mtu_gb;
                adapter->set_promisc = netxen_niu_set_promiscuous_mode;
-               adapter->unset_promisc = netxen_niu_set_promiscuous_mode;
                adapter->phy_read = netxen_niu_gbe_phy_read;
                adapter->phy_write = netxen_niu_gbe_phy_write;
-               adapter->init_niu = netxen_nic_init_niu_gb;
+               adapter->init_port = netxen_niu_gbe_init_port;
                adapter->stop_port = netxen_niu_disable_gbe_port;
                break;
 
@@ -227,12 +354,10 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
                    netxen_niu_xgbe_enable_phy_interrupts;
                adapter->disable_phy_interrupts =
                    netxen_niu_xgbe_disable_phy_interrupts;
-               adapter->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr;
                adapter->macaddr_set = netxen_niu_xg_macaddr_set;
                adapter->set_mtu = netxen_nic_set_mtu_xgb;
                adapter->init_port = netxen_niu_xg_init_port;
                adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode;
-               adapter->unset_promisc = netxen_niu_xg_set_promiscuous_mode;
                adapter->stop_port = netxen_niu_disable_xg_port;
                break;
 
@@ -270,7 +395,9 @@ static u32 netxen_decode_crb_addr(u32 addr)
 
 static long rom_max_timeout = 100;
 static long rom_lock_timeout = 10000;
+#if 0
 static long rom_write_timeout = 700;
+#endif
 
 static int rom_lock(struct netxen_adapter *adapter)
 {
@@ -319,6 +446,7 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
        return 0;
 }
 
+#if 0
 static int netxen_rom_wren(struct netxen_adapter *adapter)
 {
        /* Set write enable latch in ROM status register */
@@ -348,6 +476,7 @@ static int netxen_do_rom_rdsr(struct netxen_adapter *adapter)
        }
        return netxen_rdcrbreg(adapter, NETXEN_ROMUSB_ROM_RDATA);
 }
+#endif
 
 static void netxen_rom_unlock(struct netxen_adapter *adapter)
 {
@@ -358,6 +487,7 @@ static void netxen_rom_unlock(struct netxen_adapter *adapter)
 
 }
 
+#if 0
 static int netxen_rom_wip_poll(struct netxen_adapter *adapter)
 {
        long timeout = 0;
@@ -393,6 +523,7 @@ static int do_rom_fast_write(struct netxen_adapter *adapter, int addr,
 
        return netxen_rom_wip_poll(adapter);
 }
+#endif
 
 static int do_rom_fast_read(struct netxen_adapter *adapter,
                            int addr, int *valp)
@@ -475,7 +606,6 @@ int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data)
        netxen_rom_unlock(adapter);
        return ret;
 }
-#endif  /*  0  */
 
 static int do_rom_fast_write_words(struct netxen_adapter *adapter,
                                   int addr, u8 *bytes, size_t size)
@@ -740,28 +870,25 @@ int netxen_flash_unlock(struct netxen_adapter *adapter)
 
        return ret;
 }
+#endif  /*  0  */
 
 #define NETXEN_BOARDTYPE               0x4008
 #define NETXEN_BOARDNUM                0x400c
 #define NETXEN_CHIPNUM                 0x4010
-#define NETXEN_ROMBUS_RESET            0xFFFFFFFF
-#define NETXEN_ROM_FIRST_BARRIER       0x800000000ULL
-#define NETXEN_ROM_FOUND_INIT          0x400
 
 int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 {
        int addr, val;
-       int n, i;
-       int init_delay = 0;
+       int i, init_delay = 0;
        struct crb_addr_pair *buf;
+       unsigned offset, n;
        u32 off;
 
        /* resetall */
        netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
-                                   NETXEN_ROMBUS_RESET);
+                                   0xffffffff);
 
        if (verbose) {
-               int val;
                if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0)
                        printk("P2 ROM board type: 0x%08x\n", val);
                else
@@ -776,117 +903,141 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
                        printk("Could not read chip number\n");
        }
 
-       if (netxen_rom_fast_read(adapter, 0, &n) == 0
-           && (n & NETXEN_ROM_FIRST_BARRIER)) {
-               n &= ~NETXEN_ROM_ROUNDUP;
-               if (n < NETXEN_ROM_FOUND_INIT) {
-                       if (verbose)
-                               printk("%s: %d CRB init values found"
-                                      " in ROM.\n", netxen_nic_driver_name, n);
-               } else {
-                       printk("%s:n=0x%x Error! NetXen card flash not"
-                              " initialized.\n", __FUNCTION__, n);
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+               if (netxen_rom_fast_read(adapter, 0, &n) != 0 ||
+                       (n != 0xcafecafeUL) ||
+                       netxen_rom_fast_read(adapter, 4, &n) != 0) {
+                       printk(KERN_ERR "%s: ERROR Reading crb_init area: "
+                                       "n: %08x\n", netxen_nic_driver_name, n);
                        return -EIO;
                }
-               buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL);
-               if (buf == NULL) {
-                       printk("%s: netxen_pinit_from_rom: Unable to calloc "
-                              "memory.\n", netxen_nic_driver_name);
-                       return -ENOMEM;
-               }
-               for (i = 0; i < n; i++) {
-                       if (netxen_rom_fast_read(adapter, 8 * i + 4, &val) != 0
-                           || netxen_rom_fast_read(adapter, 8 * i + 8,
-                                                   &addr) != 0)
-                               return -EIO;
-
-                       buf[i].addr = addr;
-                       buf[i].data = val;
-
-                       if (verbose)
-                               printk("%s: PCI:     0x%08x == 0x%08x\n",
-                                      netxen_nic_driver_name, (unsigned int)
-                                      netxen_decode_crb_addr(addr), val);
+               offset = n & 0xffffU;
+               n = (n >> 16) & 0xffffU;
+       } else {
+               if (netxen_rom_fast_read(adapter, 0, &n) != 0 ||
+                       !(n & 0x80000000)) {
+                       printk(KERN_ERR "%s: ERROR Reading crb_init area: "
+                                       "n: %08x\n", netxen_nic_driver_name, n);
+                       return -EIO;
                }
-               for (i = 0; i < n; i++) {
+               offset = 1;
+               n &= ~0x80000000;
+       }
+
+       if (n < 1024) {
+               if (verbose)
+                       printk(KERN_DEBUG "%s: %d CRB init values found"
+                              " in ROM.\n", netxen_nic_driver_name, n);
+       } else {
+               printk(KERN_ERR "%s:n=0x%x Error! NetXen card flash not"
+                      " initialized.\n", __func__, n);
+               return -EIO;
+       }
+
+       buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL);
+       if (buf == NULL) {
+               printk("%s: netxen_pinit_from_rom: Unable to calloc memory.\n",
+                               netxen_nic_driver_name);
+               return -ENOMEM;
+       }
+       for (i = 0; i < n; i++) {
+               if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
+               netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0)
+                       return -EIO;
+
+               buf[i].addr = addr;
+               buf[i].data = val;
 
-                       off = netxen_decode_crb_addr(buf[i].addr);
-                       if (off == NETXEN_ADDR_ERROR) {
-                               printk(KERN_ERR"CRB init value out of range %x\n",
+               if (verbose)
+                       printk(KERN_DEBUG "%s: PCI:     0x%08x == 0x%08x\n",
+                               netxen_nic_driver_name,
+                               (u32)netxen_decode_crb_addr(addr), val);
+       }
+       for (i = 0; i < n; i++) {
+
+               off = netxen_decode_crb_addr(buf[i].addr);
+               if (off == NETXEN_ADDR_ERROR) {
+                       printk(KERN_ERR"CRB init value out of range %x\n",
                                        buf[i].addr);
+                       continue;
+               }
+               off += NETXEN_PCI_CRBSPACE;
+               /* skipping cold reboot MAGIC */
+               if (off == NETXEN_CAM_RAM(0x1fc))
+                       continue;
+
+               if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+                       /* do not reset PCI */
+                       if (off == (ROMUSB_GLB + 0xbc))
                                continue;
-                       }
-                       off += NETXEN_PCI_CRBSPACE;
-                       /* skipping cold reboot MAGIC */
-                       if (off == NETXEN_CAM_RAM(0x1fc))
+                       if (off == (NETXEN_CRB_PEG_NET_1 + 0x18))
+                               buf[i].data = 0x1020;
+                       /* skip the function enable register */
+                       if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION))
+                               continue;
+                       if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION2))
                                continue;
+                       if ((off & 0x0ff00000) == NETXEN_CRB_SMB)
+                               continue;
+               }
 
-                       /* After writing this register, HW needs time for CRB */
-                       /* to quiet down (else crb_window returns 0xffffffff) */
-                       if (off == NETXEN_ROMUSB_GLB_SW_RESET) {
-                               init_delay = 1;
+               if (off == NETXEN_ADDR_ERROR) {
+                       printk(KERN_ERR "%s: Err: Unknown addr: 0x%08x\n",
+                                       netxen_nic_driver_name, buf[i].addr);
+                       continue;
+               }
+
+               /* After writing this register, HW needs time for CRB */
+               /* to quiet down (else crb_window returns 0xffffffff) */
+               if (off == NETXEN_ROMUSB_GLB_SW_RESET) {
+                       init_delay = 1;
+                       if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
                                /* hold xdma in reset also */
                                buf[i].data = NETXEN_NIC_XDMA_RESET;
                        }
+               }
 
-                       if (ADDR_IN_WINDOW1(off)) {
-                               writel(buf[i].data,
-                                      NETXEN_CRB_NORMALIZE(adapter, off));
-                       } else {
-                               netxen_nic_pci_change_crbwindow(adapter, 0);
-                               writel(buf[i].data,
-                                      pci_base_offset(adapter, off));
+               adapter->hw_write_wx(adapter, off, &buf[i].data, 4);
 
-                               netxen_nic_pci_change_crbwindow(adapter, 1);
-                       }
-                       if (init_delay == 1) {
-                               msleep(1000);
-                               init_delay = 0;
-                       }
-                       msleep(1);
+               if (init_delay == 1) {
+                       msleep(1000);
+                       init_delay = 0;
                }
-               kfree(buf);
+               msleep(1);
+       }
+       kfree(buf);
 
-               /* disable_peg_cache_all */
+       /* disable_peg_cache_all */
 
-               /* unreset_net_cache */
-               netxen_nic_hw_read_wx(adapter, NETXEN_ROMUSB_GLB_SW_RESET, &val,
-                                     4);
-               netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
-                                           (val & 0xffffff0f));
-               /* p2dn replyCount */
-               netxen_crb_writelit_adapter(adapter,
-                                           NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
-               /* disable_peg_cache 0 */
+       /* unreset_net_cache */
+       if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+               adapter->hw_read_wx(adapter,
+                               NETXEN_ROMUSB_GLB_SW_RESET, &val, 4);
                netxen_crb_writelit_adapter(adapter,
-                                           NETXEN_CRB_PEG_NET_D + 0x4c, 8);
-               /* disable_peg_cache 1 */
-               netxen_crb_writelit_adapter(adapter,
-                                           NETXEN_CRB_PEG_NET_I + 0x4c, 8);
-
-               /* peg_clr_all */
-
-               /* peg_clr 0 */
-               netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8,
-                                           0);
-               netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc,
-                                           0);
-               /* peg_clr 1 */
-               netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8,
-                                           0);
-               netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc,
-                                           0);
-               /* peg_clr 2 */
-               netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8,
-                                           0);
-               netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc,
-                                           0);
-               /* peg_clr 3 */
-               netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8,
-                                           0);
-               netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc,
-                                           0);
+                               NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f));
        }
+
+       /* p2dn replyCount */
+       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
+       /* disable_peg_cache 0 */
+       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8);
+       /* disable_peg_cache 1 */
+       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8);
+
+       /* peg_clr_all */
+
+       /* peg_clr 0 */
+       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0);
+       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0);
+       /* peg_clr 1 */
+       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0);
+       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0);
+       /* peg_clr 2 */
+       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0);
+       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0);
+       /* peg_clr 3 */
+       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0);
+       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0);
        return 0;
 }
 
@@ -897,12 +1048,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
        uint32_t lo;
 
        adapter->dummy_dma.addr =
-           pci_alloc_consistent(adapter->ahw.pdev,
+           pci_alloc_consistent(adapter->pdev,
                                 NETXEN_HOST_DUMMY_DMA_SIZE,
                                 &adapter->dummy_dma.phys_addr);
        if (adapter->dummy_dma.addr == NULL) {
                printk("%s: ERROR: Could not allocate dummy DMA memory\n",
-                      __FUNCTION__);
+                      __func__);
                return -ENOMEM;
        }
 
@@ -910,8 +1061,13 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
        hi = (addr >> 32) & 0xffffffff;
        lo = addr & 0xffffffff;
 
-       writel(hi, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI));
-       writel(lo, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO));
+       adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi);
+       adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo);
+
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+               uint32_t temp = 0;
+               adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF, &temp, 4);
+       }
 
        return 0;
 }
@@ -931,7 +1087,7 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter)
                } while (--i);
 
                if (i) {
-                       pci_free_consistent(adapter->ahw.pdev,
+                       pci_free_consistent(adapter->pdev,
                                    NETXEN_HOST_DUMMY_DMA_SIZE,
                                    adapter->dummy_dma.addr,
                                    adapter->dummy_dma.phys_addr);
@@ -946,22 +1102,24 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter)
 int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
 {
        u32 val = 0;
-       int retries = 30;
+       int retries = 60;
 
        if (!pegtune_val) {
                do {
-                       val = readl(NETXEN_CRB_NORMALIZE
-                                 (adapter, CRB_CMDPEG_STATE));
-                       pegtune_val = readl(NETXEN_CRB_NORMALIZE
-                                 (adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
+                       val = adapter->pci_read_normalize(adapter,
+                                       CRB_CMDPEG_STATE);
 
                        if (val == PHAN_INITIALIZE_COMPLETE ||
                                val == PHAN_INITIALIZE_ACK)
                                return 0;
 
-                       msleep(1000);
+                       msleep(500);
+
                } while (--retries);
+
                if (!retries) {
+                       pegtune_val = adapter->pci_read_normalize(adapter,
+                                       NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
                        printk(KERN_WARNING "netxen_phantom_init: init failed, "
                                        "pegtune_val=%x\n", pegtune_val);
                        return -1;
@@ -971,58 +1129,61 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
        return 0;
 }
 
-static int netxen_nic_check_temp(struct netxen_adapter *adapter)
+int netxen_receive_peg_ready(struct netxen_adapter *adapter)
 {
-       struct net_device *netdev = adapter->netdev;
-       uint32_t temp, temp_state, temp_val;
-       int rv = 0;
-
-       temp = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_TEMP_STATE));
-
-       temp_state = nx_get_temp_state(temp);
-       temp_val = nx_get_temp_val(temp);
-
-       if (temp_state == NX_TEMP_PANIC) {
-               printk(KERN_ALERT
-                      "%s: Device temperature %d degrees C exceeds"
-                      " maximum allowed. Hardware has been shut down.\n",
-                      netxen_nic_driver_name, temp_val);
-
-               netif_carrier_off(netdev);
-               netif_stop_queue(netdev);
-               rv = 1;
-       } else if (temp_state == NX_TEMP_WARN) {
-               if (adapter->temp == NX_TEMP_NORMAL) {
-                       printk(KERN_ALERT
-                              "%s: Device temperature %d degrees C "
-                              "exceeds operating range."
-                              " Immediate action needed.\n",
-                              netxen_nic_driver_name, temp_val);
-               }
-       } else {
-               if (adapter->temp == NX_TEMP_WARN) {
-                       printk(KERN_INFO
-                              "%s: Device temperature is now %d degrees C"
-                              " in normal range.\n", netxen_nic_driver_name,
-                              temp_val);
-               }
+       u32 val = 0;
+       int retries = 2000;
+
+       do {
+               val = adapter->pci_read_normalize(adapter, CRB_RCVPEG_STATE);
+
+               if (val == PHAN_PEG_RCV_INITIALIZED)
+                       return 0;
+
+               msleep(10);
+
+       } while (--retries);
+
+       if (!retries) {
+               printk(KERN_ERR "Receive Peg initialization not "
+                             "complete, state: 0x%x.\n", val);
+               return -EIO;
        }
-       adapter->temp = temp_state;
-       return rv;
+
+       return 0;
 }
 
-void netxen_watchdog_task(struct work_struct *work)
+static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter,
+               struct nx_host_rds_ring *rds_ring, u16 index, u16 cksum)
 {
-       struct netxen_adapter *adapter =
-               container_of(work, struct netxen_adapter, watchdog_task);
+       struct netxen_rx_buffer *buffer;
+       struct sk_buff *skb;
 
-       if ((adapter->portnum  == 0) && netxen_nic_check_temp(adapter))
-               return;
+       buffer = &rds_ring->rx_buf_arr[index];
+
+       pci_unmap_single(adapter->pdev, buffer->dma, rds_ring->dma_size,
+                       PCI_DMA_FROMDEVICE);
 
-       if (adapter->handle_phy_intr)
-               adapter->handle_phy_intr(adapter);
+       skb = buffer->skb;
+       if (!skb)
+               goto no_skb;
 
-       mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
+       if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) {
+               adapter->stats.csummed++;
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
+       } else
+               skb->ip_summed = CHECKSUM_NONE;
+
+       skb->dev = adapter->netdev;
+
+       buffer->skb = NULL;
+
+no_skb:
+       buffer->state = NETXEN_BUFFER_FREE;
+       buffer->lro_current_frags = 0;
+       buffer->lro_expected_frags = 0;
+       list_add_tail(&buffer->list, &rds_ring->free_list);
+       return skb;
 }
 
 /*
@@ -1031,9 +1192,8 @@ void netxen_watchdog_task(struct work_struct *work)
  * invoke the routine to send more rx buffers to the Phantom...
  */
 static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
-                              struct status_desc *desc)
+               struct status_desc *desc, struct status_desc *frag_desc)
 {
-       struct pci_dev *pdev = adapter->pdev;
        struct net_device *netdev = adapter->netdev;
        u64 sts_data = le64_to_cpu(desc->status_desc_data);
        int index = netxen_get_sts_refhandle(sts_data);
@@ -1042,8 +1202,8 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
        struct sk_buff *skb;
        u32 length = netxen_get_sts_totallength(sts_data);
        u32 desc_ctx;
-       struct netxen_rcv_desc_ctx *rcv_desc;
-       int ret;
+       u16 pkt_offset = 0, cksum;
+       struct nx_host_rds_ring *rds_ring;
 
        desc_ctx = netxen_get_sts_type(sts_data);
        if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) {
@@ -1052,13 +1212,13 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
                return;
        }
 
-       rcv_desc = &recv_ctx->rcv_desc[desc_ctx];
-       if (unlikely(index > rcv_desc->max_rx_desc_count)) {
+       rds_ring = &recv_ctx->rds_rings[desc_ctx];
+       if (unlikely(index > rds_ring->max_rx_desc_count)) {
                DPRINTK(ERR, "Got a buffer index:%x Max is %x\n",
-                       index, rcv_desc->max_rx_desc_count);
+                       index, rds_ring->max_rx_desc_count);
                return;
        }
-       buffer = &rcv_desc->rx_buf_arr[index];
+       buffer = &rds_ring->rx_buf_arr[index];
        if (desc_ctx == RCV_DESC_LRO_CTXID) {
                buffer->lro_current_frags++;
                if (netxen_get_sts_desc_lro_last_frag(desc)) {
@@ -1079,43 +1239,52 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
                }
        }
 
-       pci_unmap_single(pdev, buffer->dma, rcv_desc->dma_size,
-                        PCI_DMA_FROMDEVICE);
+       cksum = netxen_get_sts_status(sts_data);
 
-       skb = (struct sk_buff *)buffer->skb;
-
-       if (likely(adapter->rx_csum &&
-                       netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) {
-               adapter->stats.csummed++;
-               skb->ip_summed = CHECKSUM_UNNECESSARY;
-       } else
-               skb->ip_summed = CHECKSUM_NONE;
+       skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum);
+       if (!skb)
+               return;
 
-       skb->dev = netdev;
        if (desc_ctx == RCV_DESC_LRO_CTXID) {
                /* True length was only available on the last pkt */
                skb_put(skb, buffer->lro_length);
        } else {
-               skb_put(skb, length);
+               if (length > rds_ring->skb_size)
+                       skb_put(skb, rds_ring->skb_size);
+               else
+                       skb_put(skb, length);
+
+               pkt_offset = netxen_get_sts_pkt_offset(sts_data);
+               if (pkt_offset)
+                       skb_pull(skb, pkt_offset);
        }
 
        skb->protocol = eth_type_trans(skb, netdev);
 
-       ret = netif_receive_skb(skb);
-       netdev->last_rx = jiffies;
-
-       rcv_desc->rcv_pending--;
-
        /*
-        * We just consumed one buffer so post a buffer.
+        * rx buffer chaining is disabled, walk and free
+        * any spurious rx buffer chain.
         */
-       buffer->skb = NULL;
-       buffer->state = NETXEN_BUFFER_FREE;
-       buffer->lro_current_frags = 0;
-       buffer->lro_expected_frags = 0;
+       if (frag_desc) {
+               u16 i, nr_frags = desc->nr_frags;
+
+               dev_kfree_skb_any(skb);
+               for (i = 0; i < nr_frags; i++) {
+                       index = frag_desc->frag_handles[i];
+                       skb = netxen_process_rxbuf(adapter,
+                                       rds_ring, index, cksum);
+                       if (skb)
+                               dev_kfree_skb_any(skb);
+               }
+               adapter->stats.rxdropped++;
+       } else {
 
-       adapter->stats.no_rcv++;
-       adapter->stats.rxbytes += length;
+               netif_receive_skb(skb);
+               netdev->last_rx = jiffies;
+
+               adapter->stats.no_rcv++;
+               adapter->stats.rxbytes += length;
+       }
 }
 
 /* Process Receive status ring */
@@ -1123,10 +1292,11 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
 {
        struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
        struct status_desc *desc_head = recv_ctx->rcv_status_desc_head;
-       struct status_desc *desc;       /* used to read status desc here */
+       struct status_desc *desc, *frag_desc;
        u32 consumer = recv_ctx->status_rx_consumer;
-       u32 producer = 0;
        int count = 0, ring;
+       u64 sts_data;
+       u16 opcode;
 
        while (count < max) {
                desc = &desc_head[consumer];
@@ -1135,24 +1305,38 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
                                netxen_get_sts_owner(desc));
                        break;
                }
-               netxen_process_rcv(adapter, ctxid, desc);
+
+               sts_data = le64_to_cpu(desc->status_desc_data);
+               opcode = netxen_get_sts_opcode(sts_data);
+               frag_desc = NULL;
+               if (opcode == NETXEN_NIC_RXPKT_DESC) {
+                       if (desc->nr_frags) {
+                               consumer = get_next_index(consumer,
+                                               adapter->max_rx_desc_count);
+                               frag_desc = &desc_head[consumer];
+                               netxen_set_sts_owner(frag_desc,
+                                               STATUS_OWNER_PHANTOM);
+                       }
+               }
+
+               netxen_process_rcv(adapter, ctxid, desc, frag_desc);
+
                netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM);
-               consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1);
+
+               consumer = get_next_index(consumer,
+                               adapter->max_rx_desc_count);
                count++;
        }
-       for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++)
+       for (ring = 0; ring < adapter->max_rds_rings; ring++)
                netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
 
        /* update the consumer index in phantom */
        if (count) {
                recv_ctx->status_rx_consumer = consumer;
-               recv_ctx->status_rx_producer = producer;
 
                /* Window = 1 */
-               writel(consumer,
-                      NETXEN_CRB_NORMALIZE(adapter,
-                                   recv_crb_registers[adapter->portnum].
-                                           crb_rcv_status_consumer));
+               adapter->pci_write_normalize(adapter,
+                               recv_ctx->crb_sts_consumer, consumer);
        }
 
        return count;
@@ -1231,10 +1415,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
  */
 void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
 {
-       struct pci_dev *pdev = adapter->ahw.pdev;
+       struct pci_dev *pdev = adapter->pdev;
        struct sk_buff *skb;
        struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
-       struct netxen_rcv_desc_ctx *rcv_desc = NULL;
+       struct nx_host_rds_ring *rds_ring = NULL;
        uint producer;
        struct rcv_desc *pdesc;
        struct netxen_rx_buffer *buffer;
@@ -1242,41 +1426,36 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
        int index = 0;
        netxen_ctx_msg msg = 0;
        dma_addr_t dma;
+       struct list_head *head;
 
-       rcv_desc = &recv_ctx->rcv_desc[ringid];
+       rds_ring = &recv_ctx->rds_rings[ringid];
+
+       producer = rds_ring->producer;
+       index = rds_ring->begin_alloc;
+       head = &rds_ring->free_list;
 
-       producer = rcv_desc->producer;
-       index = rcv_desc->begin_alloc;
-       buffer = &rcv_desc->rx_buf_arr[index];
        /* We can start writing rx descriptors into the phantom memory. */
-       while (buffer->state == NETXEN_BUFFER_FREE) {
-               skb = dev_alloc_skb(rcv_desc->skb_size);
+       while (!list_empty(head)) {
+
+               skb = dev_alloc_skb(rds_ring->skb_size);
                if (unlikely(!skb)) {
-                       /*
-                        * TODO
-                        * We need to schedule the posting of buffers to the pegs.
-                        */
-                       rcv_desc->begin_alloc = index;
-                       DPRINTK(ERR, "netxen_post_rx_buffers: "
-                               " allocated only %d buffers\n", count);
+                       rds_ring->begin_alloc = index;
                        break;
                }
 
+               buffer = list_entry(head->next, struct netxen_rx_buffer, list);
+               list_del(&buffer->list);
+
                count++;        /* now there should be no failure */
-               pdesc = &rcv_desc->desc_head[producer];
+               pdesc = &rds_ring->desc_head[producer];
 
-#if defined(XGB_DEBUG)
-               *(unsigned long *)(skb->head) = 0xc0debabe;
-               if (skb_is_nonlinear(skb)) {
-                       printk("Allocated SKB @%p is nonlinear\n");
-               }
-#endif
-               skb_reserve(skb, 2);
+               if (!adapter->ahw.cut_through)
+                       skb_reserve(skb, 2);
                /* This will be setup when we receive the
                 * buffer after it has been filled  FSL  TBD TBD
                 * skb->dev = netdev;
                 */
-               dma = pci_map_single(pdev, skb->data, rcv_desc->dma_size,
+               dma = pci_map_single(pdev, skb->data, rds_ring->dma_size,
                                     PCI_DMA_FROMDEVICE);
                pdesc->addr_buffer = cpu_to_le64(dma);
                buffer->skb = skb;
@@ -1284,112 +1463,101 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
                buffer->dma = dma;
                /* make a rcv descriptor  */
                pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
-               pdesc->buffer_length = cpu_to_le32(rcv_desc->dma_size);
+               pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
                DPRINTK(INFO, "done writing descripter\n");
                producer =
-                   get_next_index(producer, rcv_desc->max_rx_desc_count);
-               index = get_next_index(index, rcv_desc->max_rx_desc_count);
-               buffer = &rcv_desc->rx_buf_arr[index];
+                   get_next_index(producer, rds_ring->max_rx_desc_count);
+               index = get_next_index(index, rds_ring->max_rx_desc_count);
        }
        /* if we did allocate buffers, then write the count to Phantom */
        if (count) {
-               rcv_desc->begin_alloc = index;
-               rcv_desc->rcv_pending += count;
-               rcv_desc->producer = producer;
+               rds_ring->begin_alloc = index;
+               rds_ring->producer = producer;
                        /* Window = 1 */
-                       writel((producer - 1) &
-                              (rcv_desc->max_rx_desc_count - 1),
-                              NETXEN_CRB_NORMALIZE(adapter,
-                                                   recv_crb_registers[
-                                                   adapter->portnum].
-                                                   rcv_desc_crb[ringid].
-                                                   crb_rcv_producer_offset));
+               adapter->pci_write_normalize(adapter,
+                               rds_ring->crb_rcv_producer,
+                               (producer-1) & (rds_ring->max_rx_desc_count-1));
+
+               if (adapter->fw_major < 4) {
                        /*
                         * Write a doorbell msg to tell phanmon of change in
                         * receive ring producer
+                        * Only for firmware version < 4.0.0
                         */
                        netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID);
                        netxen_set_msg_privid(msg);
                        netxen_set_msg_count(msg,
                                             ((producer -
-                                              1) & (rcv_desc->
+                                              1) & (rds_ring->
                                                     max_rx_desc_count - 1)));
                        netxen_set_msg_ctxid(msg, adapter->portnum);
                        netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
                        writel(msg,
                               DB_NORMALIZE(adapter,
                                            NETXEN_RCV_PRODUCER_OFFSET));
+               }
        }
 }
 
 static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
                                        uint32_t ctx, uint32_t ringid)
 {
-       struct pci_dev *pdev = adapter->ahw.pdev;
+       struct pci_dev *pdev = adapter->pdev;
        struct sk_buff *skb;
        struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
-       struct netxen_rcv_desc_ctx *rcv_desc = NULL;
+       struct nx_host_rds_ring *rds_ring = NULL;
        u32 producer;
        struct rcv_desc *pdesc;
        struct netxen_rx_buffer *buffer;
        int count = 0;
        int index = 0;
+       struct list_head *head;
 
-       rcv_desc = &recv_ctx->rcv_desc[ringid];
+       rds_ring = &recv_ctx->rds_rings[ringid];
 
-       producer = rcv_desc->producer;
-       index = rcv_desc->begin_alloc;
-       buffer = &rcv_desc->rx_buf_arr[index];
+       producer = rds_ring->producer;
+       index = rds_ring->begin_alloc;
+       head = &rds_ring->free_list;
        /* We can start writing rx descriptors into the phantom memory. */
-       while (buffer->state == NETXEN_BUFFER_FREE) {
-               skb = dev_alloc_skb(rcv_desc->skb_size);
+       while (!list_empty(head)) {
+
+               skb = dev_alloc_skb(rds_ring->skb_size);
                if (unlikely(!skb)) {
-                       /*
-                        * We need to schedule the posting of buffers to the pegs.
-                        */
-                       rcv_desc->begin_alloc = index;
-                       DPRINTK(ERR, "netxen_post_rx_buffers_nodb: "
-                               " allocated only %d buffers\n", count);
+                       rds_ring->begin_alloc = index;
                        break;
                }
+
+               buffer = list_entry(head->next, struct netxen_rx_buffer, list);
+               list_del(&buffer->list);
+
                count++;        /* now there should be no failure */
-               pdesc = &rcv_desc->desc_head[producer];
-               skb_reserve(skb, 2);
-               /*
-                * This will be setup when we receive the
-                * buffer after it has been filled
-                * skb->dev = netdev;
-                */
+               pdesc = &rds_ring->desc_head[producer];
+               if (!adapter->ahw.cut_through)
+                       skb_reserve(skb, 2);
                buffer->skb = skb;
                buffer->state = NETXEN_BUFFER_BUSY;
                buffer->dma = pci_map_single(pdev, skb->data,
-                                            rcv_desc->dma_size,
+                                            rds_ring->dma_size,
                                             PCI_DMA_FROMDEVICE);
 
                /* make a rcv descriptor  */
                pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
-               pdesc->buffer_length = cpu_to_le32(rcv_desc->dma_size);
+               pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
                pdesc->addr_buffer = cpu_to_le64(buffer->dma);
-               DPRINTK(INFO, "done writing descripter\n");
                producer =
-                   get_next_index(producer, rcv_desc->max_rx_desc_count);
-               index = get_next_index(index, rcv_desc->max_rx_desc_count);
-               buffer = &rcv_desc->rx_buf_arr[index];
+                   get_next_index(producer, rds_ring->max_rx_desc_count);
+               index = get_next_index(index, rds_ring->max_rx_desc_count);
+               buffer = &rds_ring->rx_buf_arr[index];
        }
 
        /* if we did allocate buffers, then write the count to Phantom */
        if (count) {
-               rcv_desc->begin_alloc = index;
-               rcv_desc->rcv_pending += count;
-               rcv_desc->producer = producer;
+               rds_ring->begin_alloc = index;
+               rds_ring->producer = producer;
                        /* Window = 1 */
-                       writel((producer - 1) &
-                              (rcv_desc->max_rx_desc_count - 1),
-                              NETXEN_CRB_NORMALIZE(adapter,
-                                                   recv_crb_registers[
-                                                   adapter->portnum].
-                                                   rcv_desc_crb[ringid].
-                                                   crb_rcv_producer_offset));
+               adapter->pci_write_normalize(adapter,
+                       rds_ring->crb_rcv_producer,
+                               (producer-1) & (rds_ring->max_rx_desc_count-1));
                        wmb();
        }
 }
diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c
deleted file mode 100644 (file)
index 96cec41..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA  02111-1307, USA.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
- *
- * Contact Information:
- *    info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- */
-
-#include <linux/netdevice.h>
-#include <linux/delay.h>
-
-#include "netxen_nic.h"
-#include "netxen_nic_hw.h"
-#include "netxen_nic_phan_reg.h"
-
-/*
- * netxen_nic_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- */
-struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
-{
-       struct netxen_adapter *adapter = netdev_priv(netdev);
-       struct net_device_stats *stats = &adapter->net_stats;
-
-       memset(stats, 0, sizeof(*stats));
-
-       /* total packets received   */
-       stats->rx_packets = adapter->stats.no_rcv;
-       /* total packets transmitted    */
-       stats->tx_packets = adapter->stats.xmitedframes +
-               adapter->stats.xmitfinished;
-       /* total bytes received     */
-       stats->rx_bytes = adapter->stats.rxbytes;
-       /* total bytes transmitted  */
-       stats->tx_bytes = adapter->stats.txbytes;
-       /* bad packets received     */
-       stats->rx_errors = adapter->stats.rcvdbadskb;
-       /* packet transmit problems */
-       stats->tx_errors = adapter->stats.nocmddescriptor;
-       /* no space in linux buffers    */
-       stats->rx_dropped = adapter->stats.rxdropped;
-       /* no space available in linux  */
-       stats->tx_dropped = adapter->stats.txdropped;
-
-       return stats;
-}
-
-static void netxen_indicate_link_status(struct netxen_adapter *adapter,
-                                       u32 link)
-{
-       struct net_device *netdev = adapter->netdev;
-
-       if (link)
-               netif_carrier_on(netdev);
-       else
-               netif_carrier_off(netdev);
-}
-
-#if 0
-void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable)
-{
-       __u32 int_src;
-
-       /*  This should clear the interrupt source */
-       if (adapter->phy_read)
-               adapter->phy_read(adapter,
-                                 NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
-                                 &int_src);
-       if (int_src == 0) {
-               DPRINTK(INFO, "No phy interrupts for port #%d\n", portno);
-               return;
-       }
-       if (adapter->disable_phy_interrupts)
-               adapter->disable_phy_interrupts(adapter);
-
-       if (netxen_get_phy_int_jabber(int_src))
-               DPRINTK(INFO, "Jabber interrupt \n");
-
-       if (netxen_get_phy_int_polarity_changed(int_src))
-               DPRINTK(INFO, "POLARITY CHANGED int \n");
-
-       if (netxen_get_phy_int_energy_detect(int_src))
-               DPRINTK(INFO, "ENERGY DETECT INT \n");
-
-       if (netxen_get_phy_int_downshift(int_src))
-               DPRINTK(INFO, "DOWNSHIFT INT \n");
-       /* write it down later.. */
-       if ((netxen_get_phy_int_speed_changed(int_src))
-           || (netxen_get_phy_int_link_status_changed(int_src))) {
-               __u32 status;
-
-               DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n");
-
-               if (adapter->phy_read
-                   && adapter->phy_read(adapter,
-                                        NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
-                                        &status) == 0) {
-                       if (netxen_get_phy_int_link_status_changed(int_src)) {
-                               if (netxen_get_phy_link(status)) {
-                                       printk(KERN_INFO "%s: %s Link UP\n",
-                                              netxen_nic_driver_name,
-                                              adapter->netdev->name);
-
-                               } else {
-                                       printk(KERN_INFO "%s: %s Link DOWN\n",
-                                              netxen_nic_driver_name,
-                                              adapter->netdev->name);
-                               }
-                               netxen_indicate_link_status(adapter,
-                                                           netxen_get_phy_link
-                                                           (status));
-                       }
-               }
-       }
-       if (adapter->enable_phy_interrupts)
-               adapter->enable_phy_interrupts(adapter);
-}
-#endif  /*  0  */
-
-static void netxen_nic_isr_other(struct netxen_adapter *adapter)
-{
-       int portno = adapter->portnum;
-       u32 val, linkup, qg_linksup;
-
-       /* verify the offset */
-       val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
-       val = val >> adapter->physical_port;
-       if (val == adapter->ahw.qg_linksup)
-               return;
-
-       qg_linksup = adapter->ahw.qg_linksup;
-       adapter->ahw.qg_linksup = val;
-       DPRINTK(INFO, "link update 0x%08x\n", val);
-
-       linkup = val & 1;
-
-       if (linkup != (qg_linksup & 1)) {
-               printk(KERN_INFO "%s: %s PORT %d link %s\n",
-                      adapter->netdev->name,
-                      netxen_nic_driver_name, portno,
-                      ((linkup == 0) ? "down" : "up"));
-               netxen_indicate_link_status(adapter, linkup);
-               if (linkup)
-                       netxen_nic_set_link_parameters(adapter);
-
-       }
-}
-
-void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter)
-{
-       netxen_nic_isr_other(adapter);
-}
-
-#if 0
-int netxen_nic_link_ok(struct netxen_adapter *adapter)
-{
-       switch (adapter->ahw.board_type) {
-       case NETXEN_NIC_GBE:
-               return ((adapter->ahw.qg_linksup) & 1);
-
-       case NETXEN_NIC_XGBE:
-               return ((adapter->ahw.xg_linkup) & 1);
-
-       default:
-               printk(KERN_ERR"%s: Function: %s, Unknown board type\n",
-                       netxen_nic_driver_name, __FUNCTION__);
-               break;
-       }
-
-       return 0;
-}
-#endif  /*  0  */
-
-void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       u32 val;
-
-       /* WINDOW = 1 */
-       val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
-       val >>= (adapter->physical_port * 8);
-       val &= 0xff;
-
-       if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) {
-               printk(KERN_INFO "%s: %s NIC Link is down\n",
-                      netxen_nic_driver_name, netdev->name);
-               adapter->ahw.xg_linkup = 0;
-               if (netif_running(netdev)) {
-                       netif_carrier_off(netdev);
-                       netif_stop_queue(netdev);
-               }
-       } else if (adapter->ahw.xg_linkup == 0 && val == XG_LINK_UP) {
-               printk(KERN_INFO "%s: %s NIC Link is up\n",
-                      netxen_nic_driver_name, netdev->name);
-               adapter->ahw.xg_linkup = 1;
-               netif_carrier_on(netdev);
-               netif_wake_queue(netdev);
-       }
-}
index 63cd67b931e7537cde2c407c63812c9fd3ffac02..91d209a8f6cb8e4997b74f2454bdec94c62b2545 100644 (file)
@@ -49,13 +49,18 @@ char netxen_nic_driver_name[] = "netxen_nic";
 static char netxen_nic_driver_string[] = "NetXen Network Driver version "
     NETXEN_NIC_LINUX_VERSIONID;
 
-#define NETXEN_NETDEV_WEIGHT 120
-#define NETXEN_ADAPTER_UP_MAGIC 777
-#define NETXEN_NIC_PEG_TUNE 0
+static int port_mode = NETXEN_PORT_MODE_AUTO_NEG;
+
+/* Default to restricted 1G auto-neg mode */
+static int wol_port_mode = 5;
+
+static int use_msi = 1;
+
+static int use_msi_x = 1;
 
 /* Local functions to NetXen NIC driver */
 static int __devinit netxen_nic_probe(struct pci_dev *pdev,
-                                     const struct pci_device_id *ent);
+               const struct pci_device_id *ent);
 static void __devexit netxen_nic_remove(struct pci_dev *pdev);
 static int netxen_nic_open(struct net_device *netdev);
 static int netxen_nic_close(struct net_device *netdev);
@@ -83,6 +88,7 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
        ENTRY(0x0005),
        ENTRY(0x0024),
        ENTRY(0x0025),
+       ENTRY(0x0100),
        {0,}
 };
 
@@ -108,95 +114,61 @@ static struct workqueue_struct *netxen_workq;
 
 static void netxen_watchdog(unsigned long);
 
-static void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
-                                          uint32_t crb_producer)
+static uint32_t crb_cmd_producer[4] = {
+       CRB_CMD_PRODUCER_OFFSET, CRB_CMD_PRODUCER_OFFSET_1,
+       CRB_CMD_PRODUCER_OFFSET_2, CRB_CMD_PRODUCER_OFFSET_3
+};
+
+void
+netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
+               uint32_t crb_producer)
 {
-       switch (adapter->portnum) {
-               case 0:
-                       writel(crb_producer, NETXEN_CRB_NORMALIZE
-                                       (adapter, CRB_CMD_PRODUCER_OFFSET));
-                       return;
-               case 1:
-                       writel(crb_producer, NETXEN_CRB_NORMALIZE
-                                       (adapter, CRB_CMD_PRODUCER_OFFSET_1));
-                       return;
-               case 2:
-                       writel(crb_producer, NETXEN_CRB_NORMALIZE
-                                       (adapter, CRB_CMD_PRODUCER_OFFSET_2));
-                       return;
-               case 3:
-                       writel(crb_producer, NETXEN_CRB_NORMALIZE
-                                       (adapter, CRB_CMD_PRODUCER_OFFSET_3));
-                       return;
-               default:
-                       printk(KERN_WARNING "We tried to update "
-                                       "CRB_CMD_PRODUCER_OFFSET for invalid "
-                                       "PCI function id %d\n",
-                                       adapter->portnum);
-                       return;
-       }
+       adapter->pci_write_normalize(adapter,
+                       adapter->crb_addr_cmd_producer, crb_producer);
 }
 
-static void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
-                                          u32 crb_consumer)
+static uint32_t crb_cmd_consumer[4] = {
+       CRB_CMD_CONSUMER_OFFSET, CRB_CMD_CONSUMER_OFFSET_1,
+       CRB_CMD_CONSUMER_OFFSET_2, CRB_CMD_CONSUMER_OFFSET_3
+};
+
+static inline void
+netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
+               u32 crb_consumer)
 {
-       switch (adapter->portnum) {
-               case 0:
-                       writel(crb_consumer, NETXEN_CRB_NORMALIZE
-                               (adapter, CRB_CMD_CONSUMER_OFFSET));
-                       return;
-               case 1:
-                       writel(crb_consumer, NETXEN_CRB_NORMALIZE
-                               (adapter, CRB_CMD_CONSUMER_OFFSET_1));
-                       return;
-               case 2:
-                       writel(crb_consumer, NETXEN_CRB_NORMALIZE
-                               (adapter, CRB_CMD_CONSUMER_OFFSET_2));
-                       return;
-               case 3:
-                       writel(crb_consumer, NETXEN_CRB_NORMALIZE
-                               (adapter, CRB_CMD_CONSUMER_OFFSET_3));
-                       return;
-               default:
-                       printk(KERN_WARNING "We tried to update "
-                                       "CRB_CMD_PRODUCER_OFFSET for invalid "
-                                       "PCI function id %d\n",
-                                       adapter->portnum);
-                       return;
-       }
+       adapter->pci_write_normalize(adapter,
+                       adapter->crb_addr_cmd_consumer, crb_consumer);
 }
 
-#define        ADAPTER_LIST_SIZE 12
-
-static uint32_t msi_tgt_status[4] = {
+static uint32_t msi_tgt_status[8] = {
        ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1,
-       ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3
+       ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3,
+       ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5,
+       ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7
 };
 
-static uint32_t sw_int_mask[4] = {
-       CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1,
-       CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3
-};
+static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
 
 static void netxen_nic_disable_int(struct netxen_adapter *adapter)
 {
        u32 mask = 0x7ff;
        int retries = 32;
-       int port = adapter->portnum;
        int pci_fn = adapter->ahw.pci_func;
 
        if (adapter->msi_mode != MSI_MODE_MULTIFUNC)
-               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port]));
+               adapter->pci_write_normalize(adapter,
+                               adapter->crb_intr_mask, 0);
 
        if (adapter->intr_scheme != -1 &&
            adapter->intr_scheme != INTR_SCHEME_PERPORT)
-               writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
+               adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
 
-       if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+       if (!NETXEN_IS_MSI_FAMILY(adapter)) {
                do {
-                       writel(0xffffffff,
-                              PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS));
-                       mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR));
+                       adapter->pci_write_immediate(adapter,
+                                       ISR_INT_TARGET_STATUS, 0xffffffff);
+                       mask = adapter->pci_read_immediate(adapter,
+                                       ISR_INT_VECTOR);
                        if (!(mask & 0x80))
                                break;
                        udelay(10);
@@ -208,8 +180,8 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter)
                }
        } else {
                if (adapter->msi_mode == MSI_MODE_MULTIFUNC) {
-                       writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter,
-                                               msi_tgt_status[pci_fn]));
+                       adapter->pci_write_immediate(adapter,
+                                       msi_tgt_status[pci_fn], 0xffffffff);
                }
        }
 }
@@ -217,7 +189,6 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter)
 static void netxen_nic_enable_int(struct netxen_adapter *adapter)
 {
        u32 mask;
-       int port = adapter->portnum;
 
        DPRINTK(1, INFO, "Entered ISR Enable \n");
 
@@ -235,24 +206,299 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter)
                        break;
                }
 
-               writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
+               adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
        }
 
-       writel(0x1, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port]));
+       adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1);
 
-       if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+       if (!NETXEN_IS_MSI_FAMILY(adapter)) {
                mask = 0xbff;
                if (adapter->intr_scheme != -1 &&
                        adapter->intr_scheme != INTR_SCHEME_PERPORT) {
-                       writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+                       adapter->pci_write_normalize(adapter,
+                                       CRB_INT_VECTOR, 0);
                }
-               writel(mask,
-                      PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK));
+               adapter->pci_write_immediate(adapter,
+                               ISR_INT_TARGET_MASK, mask);
        }
 
        DPRINTK(1, INFO, "Done with enable Int\n");
 }
 
+static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       int err;
+       uint64_t mask;
+
+#ifdef CONFIG_IA64
+       adapter->dma_mask = DMA_32BIT_MASK;
+#else
+       if (revision_id >= NX_P3_B0) {
+               /* should go to DMA_64BIT_MASK */
+               adapter->dma_mask = DMA_39BIT_MASK;
+               mask = DMA_39BIT_MASK;
+       } else if (revision_id == NX_P3_A2) {
+               adapter->dma_mask = DMA_39BIT_MASK;
+               mask = DMA_39BIT_MASK;
+       } else if (revision_id == NX_P2_C1) {
+               adapter->dma_mask = DMA_35BIT_MASK;
+               mask = DMA_35BIT_MASK;
+       } else {
+               adapter->dma_mask = DMA_32BIT_MASK;
+               mask = DMA_32BIT_MASK;
+               goto set_32_bit_mask;
+       }
+
+       /*
+        * Consistent DMA mask is set to 32 bit because it cannot be set to
+        * 35 bits. For P3 also leave it at 32 bits for now. Only the rings
+        * come off this pool.
+        */
+       if (pci_set_dma_mask(pdev, mask) == 0 &&
+               pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) == 0) {
+               adapter->pci_using_dac = 1;
+               return 0;
+       }
+#endif /* CONFIG_IA64 */
+
+set_32_bit_mask:
+       err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+       if (!err)
+               err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+       if (err) {
+               DPRINTK(ERR, "No usable DMA configuration, aborting:%d\n", err);
+               return err;
+       }
+
+       adapter->pci_using_dac = 0;
+       return 0;
+}
+
+static void netxen_check_options(struct netxen_adapter *adapter)
+{
+       switch (adapter->ahw.boardcfg.board_type) {
+       case NETXEN_BRDTYPE_P3_HMEZ:
+       case NETXEN_BRDTYPE_P3_XG_LOM:
+       case NETXEN_BRDTYPE_P3_10G_CX4:
+       case NETXEN_BRDTYPE_P3_10G_CX4_LP:
+       case NETXEN_BRDTYPE_P3_IMEZ:
+       case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
+       case NETXEN_BRDTYPE_P3_10G_XFP:
+       case NETXEN_BRDTYPE_P3_10000_BASE_T:
+               adapter->msix_supported = !!use_msi_x;
+               adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
+               break;
+
+       case NETXEN_BRDTYPE_P2_SB31_10G:
+       case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
+       case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
+       case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
+               adapter->msix_supported = 0;
+               adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
+               break;
+
+       case NETXEN_BRDTYPE_P3_REF_QG:
+       case NETXEN_BRDTYPE_P3_4_GB:
+       case NETXEN_BRDTYPE_P3_4_GB_MM:
+       case NETXEN_BRDTYPE_P2_SB35_4G:
+       case NETXEN_BRDTYPE_P2_SB31_2G:
+               adapter->msix_supported = 0;
+               adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
+               break;
+
+       default:
+               adapter->msix_supported = 0;
+               adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
+
+               printk(KERN_WARNING "Unknown board type(0x%x)\n",
+                               adapter->ahw.boardcfg.board_type);
+               break;
+       }
+
+       adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST;
+       adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS;
+       adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS;
+
+       adapter->max_possible_rss_rings = 1;
+       return;
+}
+
+static int
+netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot)
+{
+       int ret = 0;
+
+       if (first_boot == 0x55555555) {
+               /* This is the first boot after power up */
+
+               /* PCI bus master workaround */
+               adapter->hw_read_wx(adapter,
+                       NETXEN_PCIE_REG(0x4), &first_boot, 4);
+               if (!(first_boot & 0x4)) {
+                       first_boot |= 0x4;
+                       adapter->hw_write_wx(adapter,
+                               NETXEN_PCIE_REG(0x4), &first_boot, 4);
+                       adapter->hw_read_wx(adapter,
+                               NETXEN_PCIE_REG(0x4), &first_boot, 4);
+               }
+
+               /* This is the first boot after power up */
+               adapter->hw_read_wx(adapter,
+                       NETXEN_ROMUSB_GLB_SW_RESET, &first_boot, 4);
+               if (first_boot != 0x80000f) {
+                       /* clear the register for future unloads/loads */
+                       adapter->pci_write_normalize(adapter,
+                                       NETXEN_CAM_RAM(0x1fc), 0);
+                       ret = -1;
+               }
+
+               if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+                       /* Start P2 boot loader */
+                       adapter->pci_write_normalize(adapter,
+                               NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
+                       adapter->pci_write_normalize(adapter,
+                                       NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1);
+               }
+       }
+       return ret;
+}
+
+static void netxen_set_port_mode(struct netxen_adapter *adapter)
+{
+       u32 val, data;
+
+       val = adapter->ahw.boardcfg.board_type;
+       if ((val == NETXEN_BRDTYPE_P3_HMEZ) ||
+               (val == NETXEN_BRDTYPE_P3_XG_LOM)) {
+               if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
+                       data = NETXEN_PORT_MODE_802_3_AP;
+                       adapter->hw_write_wx(adapter,
+                               NETXEN_PORT_MODE_ADDR, &data, 4);
+               } else if (port_mode == NETXEN_PORT_MODE_XG) {
+                       data = NETXEN_PORT_MODE_XG;
+                       adapter->hw_write_wx(adapter,
+                               NETXEN_PORT_MODE_ADDR, &data, 4);
+               } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_1G) {
+                       data = NETXEN_PORT_MODE_AUTO_NEG_1G;
+                       adapter->hw_write_wx(adapter,
+                               NETXEN_PORT_MODE_ADDR, &data, 4);
+               } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_XG) {
+                       data = NETXEN_PORT_MODE_AUTO_NEG_XG;
+                       adapter->hw_write_wx(adapter,
+                               NETXEN_PORT_MODE_ADDR, &data, 4);
+               } else {
+                       data = NETXEN_PORT_MODE_AUTO_NEG;
+                       adapter->hw_write_wx(adapter,
+                               NETXEN_PORT_MODE_ADDR, &data, 4);
+               }
+
+               if ((wol_port_mode != NETXEN_PORT_MODE_802_3_AP) &&
+                       (wol_port_mode != NETXEN_PORT_MODE_XG) &&
+                       (wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_1G) &&
+                       (wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_XG)) {
+                       wol_port_mode = NETXEN_PORT_MODE_AUTO_NEG;
+               }
+               adapter->hw_write_wx(adapter, NETXEN_WOL_PORT_MODE,
+                       &wol_port_mode, 4);
+       }
+}
+
+#define PCI_CAP_ID_GEN  0x10
+
+static void netxen_pcie_strap_init(struct netxen_adapter *adapter)
+{
+       u32 pdevfuncsave;
+       u32 c8c9value = 0;
+       u32 chicken = 0;
+       u32 control = 0;
+       int i, pos;
+       struct pci_dev *pdev;
+
+       pdev = pci_get_device(0x1166, 0x0140, NULL);
+       if (pdev) {
+               pci_dev_put(pdev);
+               adapter->hw_read_wx(adapter,
+                       NETXEN_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN), &chicken, 4);
+               chicken |= 0x4000;
+               adapter->hw_write_wx(adapter,
+                       NETXEN_PCIE_REG(PCIE_TGT_SPLIT_CHICKEN), &chicken, 4);
+       }
+
+       pdev = adapter->pdev;
+
+       adapter->hw_read_wx(adapter,
+               NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4);
+       /* clear chicken3.25:24 */
+       chicken &= 0xFCFFFFFF;
+       /*
+        * if gen1 and B0, set F1020 - if gen 2, do nothing
+        * if gen2 set to F1000
+        */
+       pos = pci_find_capability(pdev, PCI_CAP_ID_GEN);
+       if (pos == 0xC0) {
+               pci_read_config_dword(pdev, pos + 0x10, &control);
+               if ((control & 0x000F0000) != 0x00020000) {
+                       /*  set chicken3.24 if gen1 */
+                       chicken |= 0x01000000;
+               }
+               printk(KERN_INFO "%s Gen2 strapping detected\n",
+                               netxen_nic_driver_name);
+               c8c9value = 0xF1000;
+       } else {
+               /* set chicken3.24 if gen1 */
+               chicken |= 0x01000000;
+               printk(KERN_INFO "%s Gen1 strapping detected\n",
+                               netxen_nic_driver_name);
+               if (adapter->ahw.revision_id == NX_P3_B0)
+                       c8c9value = 0xF1020;
+               else
+                       c8c9value = 0;
+
+       }
+       adapter->hw_write_wx(adapter,
+               NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4);
+
+       if (!c8c9value)
+               return;
+
+       pdevfuncsave = pdev->devfn;
+       if (pdevfuncsave & 0x07)
+               return;
+
+       for (i = 0; i < 8; i++) {
+               pci_read_config_dword(pdev, pos + 8, &control);
+               pci_read_config_dword(pdev, pos + 8, &control);
+               pci_write_config_dword(pdev, pos + 8, c8c9value);
+               pdev->devfn++;
+       }
+       pdev->devfn = pdevfuncsave;
+}
+
+static void netxen_set_msix_bit(struct pci_dev *pdev, int enable)
+{
+       u32 control;
+       int pos;
+
+       pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
+       if (pos) {
+               pci_read_config_dword(pdev, pos, &control);
+               if (enable)
+                       control |= PCI_MSIX_FLAGS_ENABLE;
+               else
+                       control = 0;
+               pci_write_config_dword(pdev, pos, control);
+       }
+}
+
+static void netxen_init_msix_entries(struct netxen_adapter *adapter)
+{
+       int i;
+
+       for (i = 0; i < MSIX_ENTRIES_PER_ADAPTER; i++)
+               adapter->msix_entries[i].entry = i;
+}
+
 /*
  * netxen_nic_probe()
  *
@@ -278,28 +524,28 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 
        u8 __iomem *db_ptr = NULL;
-       unsigned long mem_base, mem_len, db_base, db_len;
-       int pci_using_dac, i = 0, err;
-       int ring;
-       struct netxen_recv_context *recv_ctx = NULL;
-       struct netxen_rcv_desc_ctx *rcv_desc = NULL;
-       struct netxen_cmd_buffer *cmd_buf_arr = NULL;
+       unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0;
+       int i = 0, err;
+       int first_driver, first_boot;
        __le64 mac_addr[FLASH_NUM_PORTS + 1];
-       int valid_mac = 0;
        u32 val;
        int pci_func_id = PCI_FUNC(pdev->devfn);
        DECLARE_MAC_BUF(mac);
+       struct netxen_legacy_intr_set *legacy_intrp;
+       uint8_t revision_id;
 
        if (pci_func_id == 0)
-               printk(KERN_INFO "%s \n", netxen_nic_driver_string);
+               printk(KERN_INFO "%s\n", netxen_nic_driver_string);
 
        if (pdev->class != 0x020000) {
                printk(KERN_DEBUG "NetXen function %d, class %x will not "
                                "be enabled.\n",pci_func_id, pdev->class);
                return -ENODEV;
        }
+
        if ((err = pci_enable_device(pdev)))
                return err;
+
        if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
                err = -ENODEV;
                goto err_out_disable_pdev;
@@ -309,18 +555,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto err_out_disable_pdev;
 
        pci_set_master(pdev);
-       if (pdev->revision == NX_P2_C1 &&
-           (pci_set_dma_mask(pdev, DMA_35BIT_MASK) == 0) &&
-           (pci_set_consistent_dma_mask(pdev, DMA_35BIT_MASK) == 0)) {
-               pci_using_dac = 1;
-       } else {
-               if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
-                   (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)))
-                       goto err_out_free_res;
-
-               pci_using_dac = 0;
-       }
-
 
        netdev = alloc_etherdev(sizeof(struct netxen_adapter));
        if(!netdev) {
@@ -333,13 +567,35 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        SET_NETDEV_DEV(netdev, &pdev->dev);
 
        adapter = netdev->priv;
-
-       adapter->ahw.pdev = pdev;
+       adapter->netdev  = netdev;
+       adapter->pdev    = pdev;
        adapter->ahw.pci_func  = pci_func_id;
 
+       revision_id = pdev->revision;
+       adapter->ahw.revision_id = revision_id;
+
+       err = nx_set_dma_mask(adapter, revision_id);
+       if (err)
+               goto err_out_free_netdev;
+
+       rwlock_init(&adapter->adapter_lock);
+       adapter->ahw.qdr_sn_window = -1;
+       adapter->ahw.ddr_mn_window = -1;
+
        /* remap phys address */
        mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */
        mem_len = pci_resource_len(pdev, 0);
+       pci_len0 = 0;
+
+       adapter->hw_write_wx = netxen_nic_hw_write_wx_128M;
+       adapter->hw_read_wx = netxen_nic_hw_read_wx_128M;
+       adapter->pci_read_immediate = netxen_nic_pci_read_immediate_128M;
+       adapter->pci_write_immediate = netxen_nic_pci_write_immediate_128M;
+       adapter->pci_read_normalize = netxen_nic_pci_read_normalize_128M;
+       adapter->pci_write_normalize = netxen_nic_pci_write_normalize_128M;
+       adapter->pci_set_window = netxen_nic_pci_set_window_128M;
+       adapter->pci_mem_read = netxen_nic_pci_mem_read_128M;
+       adapter->pci_mem_write = netxen_nic_pci_mem_write_128M;
 
        /* 128 Meg of memory */
        if (mem_len == NETXEN_PCI_128MB_SIZE) {
@@ -356,27 +612,48 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
                first_page_group_start = 0;
                first_page_group_end   = 0;
+       } else if (mem_len == NETXEN_PCI_2MB_SIZE) {
+               adapter->hw_write_wx = netxen_nic_hw_write_wx_2M;
+               adapter->hw_read_wx = netxen_nic_hw_read_wx_2M;
+               adapter->pci_read_immediate = netxen_nic_pci_read_immediate_2M;
+               adapter->pci_write_immediate =
+                       netxen_nic_pci_write_immediate_2M;
+               adapter->pci_read_normalize = netxen_nic_pci_read_normalize_2M;
+               adapter->pci_write_normalize =
+                       netxen_nic_pci_write_normalize_2M;
+               adapter->pci_set_window = netxen_nic_pci_set_window_2M;
+               adapter->pci_mem_read = netxen_nic_pci_mem_read_2M;
+               adapter->pci_mem_write = netxen_nic_pci_mem_write_2M;
+
+               mem_ptr0 = ioremap(mem_base, mem_len);
+               pci_len0 = mem_len;
+               first_page_group_start = 0;
+               first_page_group_end   = 0;
+
+               adapter->ahw.ddr_mn_window = 0;
+               adapter->ahw.qdr_sn_window = 0;
+
+               adapter->ahw.mn_win_crb = 0x100000 + PCIX_MN_WINDOW +
+                       (pci_func_id * 0x20);
+               adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW;
+               if (pci_func_id < 4)
+                       adapter->ahw.ms_win_crb += (pci_func_id * 0x20);
+               else
+                       adapter->ahw.ms_win_crb +=
+                                       0xA0 + ((pci_func_id - 4) * 0x10);
        } else {
                err = -EIO;
                goto err_out_free_netdev;
        }
 
-       if ((!mem_ptr0 && mem_len == NETXEN_PCI_128MB_SIZE) ||
-                       !mem_ptr1 || !mem_ptr2) {
-               DPRINTK(ERR,
-                       "Cannot remap adapter memory aborting.:"
-                       "0 -> %p, 1 -> %p, 2 -> %p\n",
-                       mem_ptr0, mem_ptr1, mem_ptr2);
+       dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20));
 
-               err = -EIO;
-               goto err_out_iounmap;
-       }
        db_base = pci_resource_start(pdev, 4);  /* doorbell is on bar 4 */
        db_len = pci_resource_len(pdev, 4);
 
        if (db_len == 0) {
                printk(KERN_ERR "%s: doorbell is disabled\n",
-                      netxen_nic_driver_name);
+                               netxen_nic_driver_name);
                err = -EIO;
                goto err_out_iounmap;
        }
@@ -386,13 +663,14 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES);
        if (!db_ptr) {
                printk(KERN_ERR "%s: Failed to allocate doorbell map.",
-                      netxen_nic_driver_name);
+                               netxen_nic_driver_name);
                err = -EIO;
                goto err_out_iounmap;
        }
        DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr);
 
        adapter->ahw.pci_base0 = mem_ptr0;
+       adapter->ahw.pci_len0 = pci_len0;
        adapter->ahw.first_page_group_start = first_page_group_start;
        adapter->ahw.first_page_group_end   = first_page_group_end;
        adapter->ahw.pci_base1 = mem_ptr1;
@@ -400,11 +678,18 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        adapter->ahw.db_base = db_ptr;
        adapter->ahw.db_len = db_len;
 
-       adapter->netdev  = netdev;
-       adapter->pdev    = pdev;
-
        netif_napi_add(netdev, &adapter->napi,
-                      netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
+                       netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
+
+       if (revision_id >= NX_P3_B0)
+               legacy_intrp = &legacy_intr[pci_func_id];
+       else
+               legacy_intrp = &legacy_intr[0];
+
+       adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit;
+       adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg;
+       adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg;
+       adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg;
 
        /* this will be read from FW later */
        adapter->intr_scheme = -1;
@@ -414,12 +699,23 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        adapter->portnum = pci_func_id;
        adapter->status   &= ~NETXEN_NETDEV_STATUS;
        adapter->rx_csum = 1;
+       adapter->mc_enabled = 0;
+       if (NX_IS_REVISION_P3(revision_id)) {
+               adapter->max_mc_count = 38;
+               adapter->max_rds_rings = 2;
+       } else {
+               adapter->max_mc_count = 16;
+               adapter->max_rds_rings = 3;
+       }
 
        netdev->open               = netxen_nic_open;
        netdev->stop               = netxen_nic_close;
        netdev->hard_start_xmit    = netxen_nic_xmit_frame;
        netdev->get_stats          = netxen_nic_get_stats;
-       netdev->set_multicast_list = netxen_nic_set_multi;
+       if (NX_IS_REVISION_P3(revision_id))
+               netdev->set_multicast_list = netxen_p3_nic_set_multi;
+       else
+               netdev->set_multicast_list = netxen_p2_nic_set_multi;
        netdev->set_mac_address    = netxen_nic_set_mac;
        netdev->change_mtu         = netxen_nic_change_mtu;
        netdev->tx_timeout         = netxen_tx_timeout;
@@ -435,18 +731,14 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        netdev->features = NETIF_F_SG;
        netdev->features |= NETIF_F_IP_CSUM;
        netdev->features |= NETIF_F_TSO;
+       if (NX_IS_REVISION_P3(revision_id)) {
+               netdev->features |= NETIF_F_IPV6_CSUM;
+               netdev->features |= NETIF_F_TSO6;
+       }
 
-       if (pci_using_dac)
+       if (adapter->pci_using_dac)
                netdev->features |= NETIF_F_HIGHDMA;
 
-       if (pci_enable_msi(pdev))
-               adapter->flags &= ~NETXEN_NIC_MSI_ENABLED;
-       else
-               adapter->flags |= NETXEN_NIC_MSI_ENABLED;
-
-       netdev->irq = pdev->irq;
-       INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
-
        /*
         * Set the CRB window to invalid. If any register in window 0 is
         * accessed it should set the window to 0 and then reset it to 1.
@@ -455,87 +747,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        if (netxen_nic_get_board_info(adapter) != 0) {
                printk("%s: Error getting board config info.\n",
-                      netxen_nic_driver_name);
+                               netxen_nic_driver_name);
                err = -EIO;
                goto err_out_iounmap;
        }
 
-       /*
-        *  Adapter in our case is quad port so initialize it before
-        *  initializing the ports
-        */
-
        netxen_initialize_adapter_ops(adapter);
 
-       adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST;
-       if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) ||
-                       (adapter->ahw.boardcfg.board_type ==
-                        NETXEN_BRDTYPE_P2_SB31_2G))
-               adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
-       else
-               adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS;
-       adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS;
-       adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS;
-
-       cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
-       if (cmd_buf_arr == NULL) {
-               printk(KERN_ERR
-                      "%s: Could not allocate cmd_buf_arr memory:%d\n",
-                      netxen_nic_driver_name, (int)TX_RINGSIZE);
-               err = -ENOMEM;
-               goto err_out_free_adapter;
-       }
-       memset(cmd_buf_arr, 0, TX_RINGSIZE);
-       adapter->cmd_buf_arr = cmd_buf_arr;
-
-       for (i = 0; i < MAX_RCV_CTX; ++i) {
-               recv_ctx = &adapter->recv_ctx[i];
-               for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
-                       rcv_desc = &recv_ctx->rcv_desc[ring];
-                       switch (RCV_DESC_TYPE(ring)) {
-                       case RCV_DESC_NORMAL:
-                               rcv_desc->max_rx_desc_count =
-                                   adapter->max_rx_desc_count;
-                               rcv_desc->flags = RCV_DESC_NORMAL;
-                               rcv_desc->dma_size = RX_DMA_MAP_LEN;
-                               rcv_desc->skb_size = MAX_RX_BUFFER_LENGTH;
-                               break;
-
-                       case RCV_DESC_JUMBO:
-                               rcv_desc->max_rx_desc_count =
-                                   adapter->max_jumbo_rx_desc_count;
-                               rcv_desc->flags = RCV_DESC_JUMBO;
-                               rcv_desc->dma_size = RX_JUMBO_DMA_MAP_LEN;
-                               rcv_desc->skb_size = MAX_RX_JUMBO_BUFFER_LENGTH;
-                               break;
-
-                       case RCV_RING_LRO:
-                               rcv_desc->max_rx_desc_count =
-                                   adapter->max_lro_rx_desc_count;
-                               rcv_desc->flags = RCV_DESC_LRO;
-                               rcv_desc->dma_size = RX_LRO_DMA_MAP_LEN;
-                               rcv_desc->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
-                               break;
-
-                       }
-                       rcv_desc->rx_buf_arr = (struct netxen_rx_buffer *)
-                           vmalloc(RCV_BUFFSIZE);
-
-                       if (rcv_desc->rx_buf_arr == NULL) {
-                               printk(KERN_ERR "%s: Could not allocate "
-                                      "rcv_desc->rx_buf_arr memory:%d\n",
-                                      netxen_nic_driver_name,
-                                      (int)RCV_BUFFSIZE);
-                               err = -ENOMEM;
-                               goto err_out_free_rx_buffer;
-                       }
-                       memset(rcv_desc->rx_buf_arr, 0, RCV_BUFFSIZE);
-               }
-
-       }
-
-       netxen_initialize_adapter_sw(adapter);  /* initialize the buffers in adapter */
-
        /* Mezz cards have PCI function 0,2,3 enabled */
        switch (adapter->ahw.boardcfg.board_type) {
        case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
@@ -547,90 +765,71 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                break;
        }
 
-       init_timer(&adapter->watchdog_timer);
-       adapter->ahw.xg_linkup = 0;
-       adapter->watchdog_timer.function = &netxen_watchdog;
-       adapter->watchdog_timer.data = (unsigned long)adapter;
-       INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
-       adapter->ahw.pdev = pdev;
-       adapter->ahw.revision_id = pdev->revision;
-
-       /* make sure Window == 1 */
-       netxen_nic_pci_change_crbwindow(adapter, 1);
+       /*
+        * This call will setup various max rx/tx counts.
+        * It must be done before any buffer/ring allocations.
+        */
+       netxen_check_options(adapter);
 
+       first_driver = 0;
+       if (NX_IS_REVISION_P3(revision_id)) {
+               if (adapter->ahw.pci_func == 0)
+                       first_driver = 1;
+       } else {
+               if (adapter->portnum == 0)
+                       first_driver = 1;
+       }
+       adapter->crb_addr_cmd_producer = crb_cmd_producer[adapter->portnum];
+       adapter->crb_addr_cmd_consumer = crb_cmd_consumer[adapter->portnum];
        netxen_nic_update_cmd_producer(adapter, 0);
        netxen_nic_update_cmd_consumer(adapter, 0);
-       writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));
 
-       if (netxen_is_flash_supported(adapter) == 0 &&
-           netxen_get_flash_mac_addr(adapter, mac_addr) == 0)
-               valid_mac = 1;
-       else
-               valid_mac = 0;
-
-       if (valid_mac) {
-               unsigned char *p = (unsigned char *)&mac_addr[adapter->portnum];
-               netdev->dev_addr[0] = *(p + 5);
-               netdev->dev_addr[1] = *(p + 4);
-               netdev->dev_addr[2] = *(p + 3);
-               netdev->dev_addr[3] = *(p + 2);
-               netdev->dev_addr[4] = *(p + 1);
-               netdev->dev_addr[5] = *(p + 0);
+       if (first_driver) {
+               first_boot = adapter->pci_read_normalize(adapter,
+                               NETXEN_CAM_RAM(0x1fc));
 
-               memcpy(netdev->perm_addr, netdev->dev_addr,
-                       netdev->addr_len);
-               if (!is_valid_ether_addr(netdev->perm_addr)) {
-                       printk(KERN_ERR "%s: Bad MAC address %s.\n",
-                              netxen_nic_driver_name,
-                              print_mac(mac, netdev->dev_addr));
-               } else {
-                       if (adapter->macaddr_set)
-                               adapter->macaddr_set(adapter,
-                                                       netdev->dev_addr);
+               err = netxen_check_hw_init(adapter, first_boot);
+               if (err) {
+                       printk(KERN_ERR "%s: error in init HW init sequence\n",
+                                       netxen_nic_driver_name);
+                       goto err_out_iounmap;
                }
-       }
 
-       if (adapter->portnum == 0) {
-               err = netxen_initialize_adapter_offload(adapter);
-               if (err)
-                       goto err_out_free_rx_buffer;
-               val = readl(NETXEN_CRB_NORMALIZE(adapter,
-                                       NETXEN_CAM_RAM(0x1fc)));
-               if (val == 0x55555555) {
-                   /* This is the first boot after power up */
-                   netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val);
-                       if (!(val & 0x4)) {
-                               val |= 0x4;
-                               netxen_nic_write_w0(adapter, NETXEN_PCIE_REG(0x4), val);
-                               netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val);
-                               if (!(val & 0x4))
-                                       printk(KERN_ERR "%s: failed to set MSI bit in PCI-e reg\n",
-                                                       netxen_nic_driver_name);
-                       }
-                   val = readl(NETXEN_CRB_NORMALIZE(adapter,
-                                       NETXEN_ROMUSB_GLB_SW_RESET));
-                   printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val);
-                   if (val != 0x80000f) {
-                       /* clear the register for future unloads/loads */
-                               writel(0, NETXEN_CRB_NORMALIZE(adapter,
-                                                       NETXEN_CAM_RAM(0x1fc)));
-                               printk(KERN_ERR "ERROR in NetXen HW init sequence.\n");
-                               err = -ENODEV;
-                               goto err_out_free_dev;
-                   }
-               } else {
-                       writel(0, NETXEN_CRB_NORMALIZE(adapter,
-                                               CRB_CMDPEG_STATE));
+               if (NX_IS_REVISION_P3(revision_id))
+                       netxen_set_port_mode(adapter);
+
+               if (first_boot != 0x55555555) {
+                       adapter->pci_write_normalize(adapter,
+                                               CRB_CMDPEG_STATE, 0);
                        netxen_pinit_from_rom(adapter, 0);
                        msleep(1);
                        netxen_load_firmware(adapter);
-                       netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
                }
 
-               /* clear the register for future unloads/loads */
-               writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc)));
-               dev_info(&pdev->dev, "cmdpeg state: 0x%0x\n",
-                       readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));
+               if (NX_IS_REVISION_P3(revision_id))
+                       netxen_pcie_strap_init(adapter);
+
+               if (NX_IS_REVISION_P2(revision_id)) {
+
+                       /* Initialize multicast addr pool owners */
+                       val = 0x7654;
+                       if (adapter->ahw.board_type == NETXEN_NIC_XGBE)
+                               val |= 0x0f000000;
+                       netxen_crb_writelit_adapter(adapter,
+                                       NETXEN_MAC_ADDR_CNTL_REG, val);
+
+               }
+
+               if ((first_boot == 0x55555555) &&
+                       (NX_IS_REVISION_P2(revision_id))) {
+                       /* Unlock the HW, prompting the boot sequence */
+                       adapter->pci_write_normalize(adapter,
+                                       NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1);
+               }
+
+               err = netxen_initialize_adapter_offload(adapter);
+               if (err)
+                       goto err_out_iounmap;
 
                /*
                 * Tell the hardware our version number.
@@ -638,24 +837,101 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                i = (_NETXEN_NIC_LINUX_MAJOR << 16)
                        | ((_NETXEN_NIC_LINUX_MINOR << 8))
                        | (_NETXEN_NIC_LINUX_SUBVERSION);
-               writel(i, NETXEN_CRB_NORMALIZE(adapter, CRB_DRIVER_VERSION));
+               adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i);
 
-               /* Unlock the HW, prompting the boot sequence */
-               writel(1,
-                       NETXEN_CRB_NORMALIZE(adapter,
-                               NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
                /* Handshake with the card before we register the devices. */
                netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
+
+       }       /* first_driver */
+
+       netxen_nic_flash_print(adapter);
+
+       if (NX_IS_REVISION_P3(revision_id)) {
+               adapter->hw_read_wx(adapter,
+                               NETXEN_MIU_MN_CONTROL, &val, 4);
+               adapter->ahw.cut_through = (val & 0x4) ? 1 : 0;
+               dev_info(&pdev->dev, "firmware running in %s mode\n",
+               adapter->ahw.cut_through ? "cut through" : "legacy");
        }
 
        /*
         * See if the firmware gave us a virtual-physical port mapping.
         */
        adapter->physical_port = adapter->portnum;
-       i = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_V2P(adapter->portnum)));
+       i = adapter->pci_read_normalize(adapter, CRB_V2P(adapter->portnum));
        if (i != 0x55555555)
                adapter->physical_port = i;
 
+       adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
+
+       netxen_set_msix_bit(pdev, 0);
+
+       if (NX_IS_REVISION_P3(revision_id)) {
+               if ((mem_len != NETXEN_PCI_128MB_SIZE) &&
+                       mem_len != NETXEN_PCI_2MB_SIZE)
+                       adapter->msix_supported = 0;
+       }
+
+       if (adapter->msix_supported) {
+
+               netxen_init_msix_entries(adapter);
+
+               if (pci_enable_msix(pdev, adapter->msix_entries,
+                                       MSIX_ENTRIES_PER_ADAPTER))
+                       goto request_msi;
+
+               adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
+               netxen_set_msix_bit(pdev, 1);
+               dev_info(&pdev->dev, "using msi-x interrupts\n");
+
+       } else {
+request_msi:
+               if (use_msi && !pci_enable_msi(pdev)) {
+                       adapter->flags |= NETXEN_NIC_MSI_ENABLED;
+                       dev_info(&pdev->dev, "using msi interrupts\n");
+               } else
+                       dev_info(&pdev->dev, "using legacy interrupts\n");
+       }
+
+       if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
+               netdev->irq = adapter->msix_entries[0].vector;
+       else
+               netdev->irq = pdev->irq;
+
+       err = netxen_receive_peg_ready(adapter);
+       if (err)
+               goto err_out_disable_msi;
+
+       init_timer(&adapter->watchdog_timer);
+       adapter->ahw.linkup = 0;
+       adapter->watchdog_timer.function = &netxen_watchdog;
+       adapter->watchdog_timer.data = (unsigned long)adapter;
+       INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
+       INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
+
+       if (netxen_is_flash_supported(adapter) == 0 &&
+                       netxen_get_flash_mac_addr(adapter, mac_addr) == 0) {
+               unsigned char *p;
+
+               p = (unsigned char *)&mac_addr[adapter->portnum];
+               netdev->dev_addr[0] = *(p + 5);
+               netdev->dev_addr[1] = *(p + 4);
+               netdev->dev_addr[2] = *(p + 3);
+               netdev->dev_addr[3] = *(p + 2);
+               netdev->dev_addr[4] = *(p + 1);
+               netdev->dev_addr[5] = *(p + 0);
+
+               memcpy(netdev->perm_addr, netdev->dev_addr,
+                       netdev->addr_len);
+               if (!is_valid_ether_addr(netdev->perm_addr)) {
+                       printk(KERN_ERR "%s: Bad MAC address %s.\n",
+                                       netxen_nic_driver_name,
+                                       print_mac(mac, netdev->dev_addr));
+               } else {
+                       adapter->macaddr_set(adapter, netdev->dev_addr);
+               }
+       }
+
        netif_carrier_off(netdev);
        netif_stop_queue(netdev);
 
@@ -664,41 +940,37 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                               " aborting\n", netxen_nic_driver_name,
                               adapter->portnum);
                err = -EIO;
-               goto err_out_free_dev;
+               goto err_out_disable_msi;
        }
 
-       netxen_nic_flash_print(adapter);
        pci_set_drvdata(pdev, adapter);
 
-       return 0;
-
-err_out_free_dev:
-       if (adapter->portnum == 0)
-               netxen_free_adapter_offload(adapter);
-
-err_out_free_rx_buffer:
-       for (i = 0; i < MAX_RCV_CTX; ++i) {
-               recv_ctx = &adapter->recv_ctx[i];
-               for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
-                       rcv_desc = &recv_ctx->rcv_desc[ring];
-                       if (rcv_desc->rx_buf_arr != NULL) {
-                               vfree(rcv_desc->rx_buf_arr);
-                               rcv_desc->rx_buf_arr = NULL;
-                       }
-               }
+       switch (adapter->ahw.board_type) {
+       case NETXEN_NIC_GBE:
+               dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
+                               adapter->netdev->name);
+               break;
+       case NETXEN_NIC_XGBE:
+               dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n",
+                               adapter->netdev->name);
+               break;
        }
-       vfree(cmd_buf_arr);
 
-err_out_free_adapter:
+       return 0;
+
+err_out_disable_msi:
+       if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
+               pci_disable_msix(pdev);
        if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
                pci_disable_msi(pdev);
 
-       pci_set_drvdata(pdev, NULL);
+       if (first_driver)
+               netxen_free_adapter_offload(adapter);
 
+err_out_iounmap:
        if (db_ptr)
                iounmap(db_ptr);
 
-err_out_iounmap:
        if (mem_ptr0)
                iounmap(mem_ptr0);
        if (mem_ptr1)
@@ -713,6 +985,7 @@ err_out_free_res:
        pci_release_regions(pdev);
 
 err_out_disable_pdev:
+       pci_set_drvdata(pdev, NULL);
        pci_disable_device(pdev);
        return err;
 }
@@ -721,11 +994,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 {
        struct netxen_adapter *adapter;
        struct net_device *netdev;
-       struct netxen_rx_buffer *buffer;
-       struct netxen_recv_context *recv_ctx;
-       struct netxen_rcv_desc_ctx *rcv_desc;
-       int i, ctxid, ring;
-       static int init_firmware_done = 0;
 
        adapter = pci_get_drvdata(pdev);
        if (adapter == NULL)
@@ -736,36 +1004,18 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
        unregister_netdev(netdev);
 
        if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
-               init_firmware_done++;
                netxen_free_hw_resources(adapter);
+               netxen_free_sw_resources(adapter);
        }
 
-       for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
-               recv_ctx = &adapter->recv_ctx[ctxid];
-               for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
-                       rcv_desc = &recv_ctx->rcv_desc[ring];
-                       for (i = 0; i < rcv_desc->max_rx_desc_count; ++i) {
-                               buffer = &(rcv_desc->rx_buf_arr[i]);
-                               if (buffer->state == NETXEN_BUFFER_FREE)
-                                       continue;
-                               pci_unmap_single(pdev, buffer->dma,
-                                                rcv_desc->dma_size,
-                                                PCI_DMA_FROMDEVICE);
-                               if (buffer->skb != NULL)
-                                       dev_kfree_skb_any(buffer->skb);
-                       }
-                       vfree(rcv_desc->rx_buf_arr);
-               }
-       }
-
-       vfree(adapter->cmd_buf_arr);
-
        if (adapter->portnum == 0)
                netxen_free_adapter_offload(adapter);
 
        if (adapter->irq)
                free_irq(adapter->irq, adapter);
 
+       if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
+               pci_disable_msix(pdev);
        if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
                pci_disable_msi(pdev);
 
@@ -803,51 +1053,69 @@ static int netxen_nic_open(struct net_device *netdev)
                        return -EIO;
                }
 
-               /* setup all the resources for the Phantom... */
-               /* this include the descriptors for rcv, tx, and status */
-               netxen_nic_clear_stats(adapter);
-               err = netxen_nic_hw_resources(adapter);
+               err = netxen_alloc_sw_resources(adapter);
                if (err) {
-                       printk(KERN_ERR "Error in setting hw resources:%d\n",
-                              err);
+                       printk(KERN_ERR "%s: Error in setting sw resources\n",
+                                       netdev->name);
                        return err;
                }
+
+               netxen_nic_clear_stats(adapter);
+
+               err = netxen_alloc_hw_resources(adapter);
+               if (err) {
+                       printk(KERN_ERR "%s: Error in setting hw resources\n",
+                                       netdev->name);
+                       goto err_out_free_sw;
+               }
+
+               if (adapter->fw_major < 4) {
+                       adapter->crb_addr_cmd_producer =
+                               crb_cmd_producer[adapter->portnum];
+                       adapter->crb_addr_cmd_consumer =
+                               crb_cmd_consumer[adapter->portnum];
+               }
+
+               netxen_nic_update_cmd_producer(adapter, 0);
+               netxen_nic_update_cmd_consumer(adapter, 0);
+
                for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
-                       for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++)
+                       for (ring = 0; ring < adapter->max_rds_rings; ring++)
                                netxen_post_rx_buffers(adapter, ctx, ring);
                }
-               adapter->irq = adapter->ahw.pdev->irq;
-               if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
+               if (NETXEN_IS_MSI_FAMILY(adapter))
                        handler = netxen_msi_intr;
                else {
                        flags |= IRQF_SHARED;
                        handler = netxen_intr;
                }
+               adapter->irq = netdev->irq;
                err = request_irq(adapter->irq, handler,
                                  flags, netdev->name, adapter);
                if (err) {
                        printk(KERN_ERR "request_irq failed with: %d\n", err);
-                       netxen_free_hw_resources(adapter);
-                       return err;
+                       goto err_out_free_hw;
                }
 
                adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
        }
+
        /* Done here again so that even if phantom sw overwrote it,
         * we set it */
-       if (adapter->init_port
-           && adapter->init_port(adapter, adapter->portnum) != 0) {
+       err = adapter->init_port(adapter, adapter->physical_port);
+       if (err) {
                printk(KERN_ERR "%s: Failed to initialize port %d\n",
                                netxen_nic_driver_name, adapter->portnum);
-               return -EIO;
+               goto err_out_free_irq;
        }
-       if (adapter->macaddr_set)
-               adapter->macaddr_set(adapter, netdev->dev_addr);
+       adapter->macaddr_set(adapter, netdev->dev_addr);
 
        netxen_nic_set_link_parameters(adapter);
 
-       netxen_nic_set_multi(netdev);
-       if (adapter->set_mtu)
+       netdev->set_multicast_list(netdev);
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+               nx_fw_cmd_set_mtu(adapter, netdev->mtu);
+       else
                adapter->set_mtu(adapter, netdev->mtu);
 
        mod_timer(&adapter->watchdog_timer, jiffies);
@@ -858,6 +1126,14 @@ static int netxen_nic_open(struct net_device *netdev)
        netif_start_queue(netdev);
 
        return 0;
+
+err_out_free_irq:
+       free_irq(adapter->irq, adapter);
+err_out_free_hw:
+       netxen_free_hw_resources(adapter);
+err_out_free_sw:
+       netxen_free_sw_resources(adapter);
+       return err;
 }
 
 /*
@@ -866,9 +1142,6 @@ static int netxen_nic_open(struct net_device *netdev)
 static int netxen_nic_close(struct net_device *netdev)
 {
        struct netxen_adapter *adapter = netdev_priv(netdev);
-       int i, j;
-       struct netxen_cmd_buffer *cmd_buff;
-       struct netxen_skb_frag *buffrag;
 
        netif_carrier_off(netdev);
        netif_stop_queue(netdev);
@@ -879,30 +1152,8 @@ static int netxen_nic_close(struct net_device *netdev)
 
        netxen_nic_disable_int(adapter);
 
-       cmd_buff = adapter->cmd_buf_arr;
-       for (i = 0; i < adapter->max_tx_desc_count; i++) {
-               buffrag = cmd_buff->frag_array;
-               if (buffrag->dma) {
-                       pci_unmap_single(adapter->pdev, buffrag->dma,
-                                        buffrag->length, PCI_DMA_TODEVICE);
-                       buffrag->dma = 0ULL;
-               }
-               for (j = 0; j < cmd_buff->frag_count; j++) {
-                       buffrag++;
-                       if (buffrag->dma) {
-                               pci_unmap_page(adapter->pdev, buffrag->dma,
-                                              buffrag->length,
-                                              PCI_DMA_TODEVICE);
-                               buffrag->dma = 0ULL;
-                       }
-               }
-               /* Free the skb we received in netxen_nic_xmit_frame */
-               if (cmd_buff->skb) {
-                       dev_kfree_skb_any(cmd_buff->skb);
-                       cmd_buff->skb = NULL;
-               }
-               cmd_buff++;
-       }
+       netxen_release_tx_buffers(adapter);
+
        if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
                FLUSH_SCHEDULED_WORK();
                del_timer_sync(&adapter->watchdog_timer);
@@ -911,6 +1162,31 @@ static int netxen_nic_close(struct net_device *netdev)
        return 0;
 }
 
+void netxen_tso_check(struct netxen_adapter *adapter,
+                     struct cmd_desc_type0 *desc, struct sk_buff *skb)
+{
+       if (desc->mss) {
+               desc->total_hdr_length = (sizeof(struct ethhdr) +
+                                         ip_hdrlen(skb) + tcp_hdrlen(skb));
+
+               if ((NX_IS_REVISION_P3(adapter->ahw.revision_id)) &&
+                               (skb->protocol == htons(ETH_P_IPV6)))
+                       netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO6);
+               else
+                       netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO);
+
+       } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               if (ip_hdr(skb)->protocol == IPPROTO_TCP)
+                       netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT);
+               else if (ip_hdr(skb)->protocol == IPPROTO_UDP)
+                       netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT);
+               else
+                       return;
+       }
+       desc->tcp_hdr_offset = skb_transport_offset(skb);
+       desc->ip_hdr_offset = skb_network_offset(skb);
+}
+
 static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
        struct netxen_adapter *adapter = netdev_priv(netdev);
@@ -932,7 +1208,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
        /* There 4 fragments per descriptor */
        no_of_desc = (frag_count + 3) >> 2;
-       if (netdev->features & NETIF_F_TSO) {
+       if (netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) {
                if (skb_shinfo(skb)->gso_size > 0) {
 
                        no_of_desc++;
@@ -959,7 +1235,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
        /* Take skb->data itself */
        pbuf = &adapter->cmd_buf_arr[producer];
-       if ((netdev->features & NETIF_F_TSO) && skb_shinfo(skb)->gso_size > 0) {
+       if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
+                       skb_shinfo(skb)->gso_size > 0) {
                pbuf->mss = skb_shinfo(skb)->gso_size;
                hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
        } else {
@@ -1086,6 +1363,89 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        return NETDEV_TX_OK;
 }
 
+static int netxen_nic_check_temp(struct netxen_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       uint32_t temp, temp_state, temp_val;
+       int rv = 0;
+
+       temp = adapter->pci_read_normalize(adapter, CRB_TEMP_STATE);
+
+       temp_state = nx_get_temp_state(temp);
+       temp_val = nx_get_temp_val(temp);
+
+       if (temp_state == NX_TEMP_PANIC) {
+               printk(KERN_ALERT
+                      "%s: Device temperature %d degrees C exceeds"
+                      " maximum allowed. Hardware has been shut down.\n",
+                      netxen_nic_driver_name, temp_val);
+
+               netif_carrier_off(netdev);
+               netif_stop_queue(netdev);
+               rv = 1;
+       } else if (temp_state == NX_TEMP_WARN) {
+               if (adapter->temp == NX_TEMP_NORMAL) {
+                       printk(KERN_ALERT
+                              "%s: Device temperature %d degrees C "
+                              "exceeds operating range."
+                              " Immediate action needed.\n",
+                              netxen_nic_driver_name, temp_val);
+               }
+       } else {
+               if (adapter->temp == NX_TEMP_WARN) {
+                       printk(KERN_INFO
+                              "%s: Device temperature is now %d degrees C"
+                              " in normal range.\n", netxen_nic_driver_name,
+                              temp_val);
+               }
+       }
+       adapter->temp = temp_state;
+       return rv;
+}
+
+static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       u32 val, port, linkup;
+
+       port = adapter->physical_port;
+
+       if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+               val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
+               linkup = (val >> port) & 1;
+       } else {
+               if (adapter->fw_major < 4) {
+                       val = adapter->pci_read_normalize(adapter,
+                                       CRB_XG_STATE);
+                       val = (val >> port*8) & 0xff;
+                       linkup = (val == XG_LINK_UP);
+               } else {
+                       val = adapter->pci_read_normalize(adapter,
+                               CRB_XG_STATE_P3);
+                       val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
+                       linkup = (val == XG_LINK_UP_P3);
+               }
+       }
+
+       if (adapter->ahw.linkup && !linkup) {
+               printk(KERN_INFO "%s: %s NIC Link is down\n",
+                      netxen_nic_driver_name, netdev->name);
+               adapter->ahw.linkup = 0;
+               if (netif_running(netdev)) {
+                       netif_carrier_off(netdev);
+                       netif_stop_queue(netdev);
+               }
+       } else if (!adapter->ahw.linkup && linkup) {
+               printk(KERN_INFO "%s: %s NIC Link is up\n",
+                      netxen_nic_driver_name, netdev->name);
+               adapter->ahw.linkup = 1;
+               if (netif_running(netdev)) {
+                       netif_carrier_on(netdev);
+                       netif_wake_queue(netdev);
+               }
+       }
+}
+
 static void netxen_watchdog(unsigned long v)
 {
        struct netxen_adapter *adapter = (struct netxen_adapter *)v;
@@ -1093,6 +1453,19 @@ static void netxen_watchdog(unsigned long v)
        SCHEDULE_WORK(&adapter->watchdog_task);
 }
 
+void netxen_watchdog_task(struct work_struct *work)
+{
+       struct netxen_adapter *adapter =
+               container_of(work, struct netxen_adapter, watchdog_task);
+
+       if ((adapter->portnum  == 0) && netxen_nic_check_temp(adapter))
+               return;
+
+       netxen_nic_handle_phy_intr(adapter);
+
+       mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
+}
+
 static void netxen_tx_timeout(struct net_device *netdev)
 {
        struct netxen_adapter *adapter = (struct netxen_adapter *)
@@ -1118,6 +1491,38 @@ static void netxen_tx_timeout_task(struct work_struct *work)
        netif_wake_queue(adapter->netdev);
 }
 
+/*
+ * netxen_nic_get_stats - Get System Network Statistics
+ * @netdev: network interface device structure
+ */
+struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
+{
+       struct netxen_adapter *adapter = netdev_priv(netdev);
+       struct net_device_stats *stats = &adapter->net_stats;
+
+       memset(stats, 0, sizeof(*stats));
+
+       /* total packets received   */
+       stats->rx_packets = adapter->stats.no_rcv;
+       /* total packets transmitted    */
+       stats->tx_packets = adapter->stats.xmitedframes +
+               adapter->stats.xmitfinished;
+       /* total bytes received     */
+       stats->rx_bytes = adapter->stats.rxbytes;
+       /* total bytes transmitted  */
+       stats->tx_bytes = adapter->stats.txbytes;
+       /* bad packets received     */
+       stats->rx_errors = adapter->stats.rcvdbadskb;
+       /* packet transmit problems */
+       stats->tx_errors = adapter->stats.nocmddescriptor;
+       /* no space in linux buffers    */
+       stats->rx_dropped = adapter->stats.rxdropped;
+       /* no space available in linux  */
+       stats->tx_dropped = adapter->stats.txdropped;
+
+       return stats;
+}
+
 static inline void
 netxen_handle_int(struct netxen_adapter *adapter)
 {
@@ -1125,20 +1530,20 @@ netxen_handle_int(struct netxen_adapter *adapter)
        napi_schedule(&adapter->napi);
 }
 
-irqreturn_t netxen_intr(int irq, void *data)
+static irqreturn_t netxen_intr(int irq, void *data)
 {
        struct netxen_adapter *adapter = data;
        u32 our_int = 0;
 
-       our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+       our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
        /* not our interrupt */
        if ((our_int & (0x80 << adapter->portnum)) == 0)
                return IRQ_NONE;
 
        if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
                /* claim interrupt */
-               writel(our_int & ~((u32)(0x80 << adapter->portnum)),
-                       NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+               adapter->pci_write_normalize(adapter, CRB_INT_VECTOR,
+                               our_int & ~((u32)(0x80 << adapter->portnum)));
        }
 
        netxen_handle_int(adapter);
@@ -1146,7 +1551,7 @@ irqreturn_t netxen_intr(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-irqreturn_t netxen_msi_intr(int irq, void *data)
+static irqreturn_t netxen_msi_intr(int irq, void *data)
 {
        struct netxen_adapter *adapter = data;
 
@@ -1220,10 +1625,6 @@ module_init(netxen_init_module);
 
 static void __exit netxen_exit_module(void)
 {
-       /*
-        * Wait for some time to allow the dma to drain, if any.
-        */
-       msleep(100);
        pci_unregister_driver(&netxen_driver);
        destroy_workqueue(netxen_workq);
 }
index a3bc7cc67a6fd1c2c57c14e5bff6ef52e7c513cf..4cb8f4a1cf4bd8fdcd72513bb5e3f9c663fb2e79 100644 (file)
@@ -46,9 +46,8 @@ static int phy_lock(struct netxen_adapter *adapter)
        int done = 0, timeout = 0;
 
        while (!done) {
-               done =
-                   readl(pci_base_offset
-                         (adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK)));
+               done = netxen_nic_reg_read(adapter,
+                               NETXEN_PCIE_REG(PCIE_SEM3_LOCK));
                if (done == 1)
                        break;
                if (timeout >= phy_lock_timeout) {
@@ -63,14 +62,14 @@ static int phy_lock(struct netxen_adapter *adapter)
                }
        }
 
-       writel(PHY_LOCK_DRIVER,
-              NETXEN_CRB_NORMALIZE(adapter, NETXEN_PHY_LOCK_ID));
+       netxen_crb_writelit_adapter(adapter,
+                       NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER);
        return 0;
 }
 
 static int phy_unlock(struct netxen_adapter *adapter)
 {
-       readl(pci_base_offset(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK)));
+       adapter->pci_read_immediate(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK));
 
        return 0;
 }
@@ -109,7 +108,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
         * so it cannot be in reset
         */
 
-       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
+       if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
                                  &mac_cfg0, 4))
                return -EIO;
        if (netxen_gb_get_soft_reset(mac_cfg0)) {
@@ -119,7 +118,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
                netxen_gb_rx_reset_pb(temp);
                netxen_gb_tx_reset_mac(temp);
                netxen_gb_rx_reset_mac(temp);
-               if (netxen_nic_hw_write_wx(adapter,
+               if (adapter->hw_write_wx(adapter,
                                           NETXEN_NIU_GB_MAC_CONFIG_0(0),
                                           &temp, 4))
                        return -EIO;
@@ -129,22 +128,22 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
        address = 0;
        netxen_gb_mii_mgmt_reg_addr(address, reg);
        netxen_gb_mii_mgmt_phy_addr(address, phy);
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
+       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
                                   &address, 4))
                return -EIO;
        command = 0;            /* turn off any prior activity */
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
+       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
                                   &command, 4))
                return -EIO;
        /* send read command */
        netxen_gb_mii_mgmt_set_read_cycle(command);
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
+       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
                                   &command, 4))
                return -EIO;
 
        status = 0;
        do {
-               if (netxen_nic_hw_read_wx(adapter,
+               if (adapter->hw_read_wx(adapter,
                                          NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
                                          &status, 4))
                        return -EIO;
@@ -154,7 +153,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
                 && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
 
        if (timeout < NETXEN_NIU_PHY_WAITMAX) {
-               if (netxen_nic_hw_read_wx(adapter,
+               if (adapter->hw_read_wx(adapter,
                                          NETXEN_NIU_GB_MII_MGMT_STATUS(0),
                                          readval, 4))
                        return -EIO;
@@ -163,7 +162,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
                result = -1;
 
        if (restore)
-               if (netxen_nic_hw_write_wx(adapter,
+               if (adapter->hw_write_wx(adapter,
                                           NETXEN_NIU_GB_MAC_CONFIG_0(0),
                                           &mac_cfg0, 4))
                        return -EIO;
@@ -201,7 +200,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
         * cannot be in reset
         */
 
-       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
+       if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
                                  &mac_cfg0, 4))
                return -EIO;
        if (netxen_gb_get_soft_reset(mac_cfg0)) {
@@ -212,7 +211,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
                netxen_gb_tx_reset_mac(temp);
                netxen_gb_rx_reset_mac(temp);
 
-               if (netxen_nic_hw_write_wx(adapter,
+               if (adapter->hw_write_wx(adapter,
                                           NETXEN_NIU_GB_MAC_CONFIG_0(0),
                                           &temp, 4))
                        return -EIO;
@@ -220,24 +219,24 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
        }
 
        command = 0;            /* turn off any prior activity */
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
+       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
                                   &command, 4))
                return -EIO;
 
        address = 0;
        netxen_gb_mii_mgmt_reg_addr(address, reg);
        netxen_gb_mii_mgmt_phy_addr(address, phy);
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
+       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
                                   &address, 4))
                return -EIO;
 
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0),
+       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0),
                                   &val, 4))
                return -EIO;
 
        status = 0;
        do {
-               if (netxen_nic_hw_read_wx(adapter,
+               if (adapter->hw_read_wx(adapter,
                                          NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
                                          &status, 4))
                        return -EIO;
@@ -252,7 +251,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
 
        /* restore the state of port 0 MAC in case we tampered with it */
        if (restore)
-               if (netxen_nic_hw_write_wx(adapter,
+               if (adapter->hw_write_wx(adapter,
                                           NETXEN_NIU_GB_MAC_CONFIG_0(0),
                                           &mac_cfg0, 4))
                        return -EIO;
@@ -401,14 +400,16 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
 {
        int result = 0;
        __u32 status;
+
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+               return 0;
+
        if (adapter->disable_phy_interrupts)
                adapter->disable_phy_interrupts(adapter);
        mdelay(2);
 
-       if (0 ==
-           netxen_niu_gbe_phy_read(adapter,
-                                   NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
-                                   &status)) {
+       if (0 == netxen_niu_gbe_phy_read(adapter,
+                       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, &status)) {
                if (netxen_get_phy_link(status)) {
                        if (netxen_get_phy_speed(status) == 2) {
                                netxen_niu_gbe_set_gmii_mode(adapter, port, 1);
@@ -456,12 +457,12 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
 
 int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
 {
-       u32 portnum = adapter->physical_port;
-
-       netxen_crb_writelit_adapter(adapter,
-               NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), 0x1447);
-       netxen_crb_writelit_adapter(adapter,
-               NETXEN_NIU_XGE_CONFIG_0+(0x10000*portnum), 0x5);
+       if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+               netxen_crb_writelit_adapter(adapter,
+                       NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
+               netxen_crb_writelit_adapter(adapter,
+                       NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
+       }
 
        return 0;
 }
@@ -581,10 +582,10 @@ static int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
        if ((phy < 0) || (phy > 3))
                return -EINVAL;
 
-       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy),
+       if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy),
                                  &stationhigh, 4))
                return -EIO;
-       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy),
+       if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy),
                                  &stationlow, 4))
                return -EIO;
        ((__le32 *)val)[1] = cpu_to_le32(stationhigh);
@@ -613,14 +614,14 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
                temp[0] = temp[1] = 0;
                memcpy(temp + 2, addr, 2);
                val = le32_to_cpu(*(__le32 *)temp);
-               if (netxen_nic_hw_write_wx
-                   (adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4))
+               if (adapter->hw_write_wx(adapter,
+                               NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4))
                        return -EIO;
 
                memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32));
                val = le32_to_cpu(*(__le32 *)temp);
-               if (netxen_nic_hw_write_wx
-                   (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4))
+               if (adapter->hw_write_wx(adapter,
+                               NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4))
                        return -2;
 
                netxen_niu_macaddr_get(adapter,
@@ -654,7 +655,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
 
        mac_cfg0 = 0;
        netxen_gb_soft_reset(mac_cfg0);
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
                                   &mac_cfg0, 4))
                return -EIO;
        mac_cfg0 = 0;
@@ -666,7 +667,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
        netxen_gb_tx_reset_mac(mac_cfg0);
        netxen_gb_rx_reset_mac(mac_cfg0);
 
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
                                   &mac_cfg0, 4))
                return -EIO;
        mac_cfg1 = 0;
@@ -679,7 +680,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
 
        if (mode == NETXEN_NIU_10_100_MB) {
                netxen_gb_set_intfmode(mac_cfg1, 1);
-               if (netxen_nic_hw_write_wx(adapter,
+               if (adapter->hw_write_wx(adapter,
                                           NETXEN_NIU_GB_MAC_CONFIG_1(port),
                                           &mac_cfg1, 4))
                        return -EIO;
@@ -692,7 +693,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
 
        } else if (mode == NETXEN_NIU_1000_MB) {
                netxen_gb_set_intfmode(mac_cfg1, 2);
-               if (netxen_nic_hw_write_wx(adapter,
+               if (adapter->hw_write_wx(adapter,
                                           NETXEN_NIU_GB_MAC_CONFIG_1(port),
                                           &mac_cfg1, 4))
                        return -EIO;
@@ -704,7 +705,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
        }
        mii_cfg = 0;
        netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7);
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port),
+       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port),
                                   &mii_cfg, 4))
                return -EIO;
        mac_cfg0 = 0;
@@ -713,7 +714,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
        netxen_gb_unset_rx_flowctl(mac_cfg0);
        netxen_gb_unset_tx_flowctl(mac_cfg0);
 
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
                                   &mac_cfg0, 4))
                return -EIO;
        return 0;
@@ -730,7 +731,7 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
                return -EINVAL;
        mac_cfg0 = 0;
        netxen_gb_soft_reset(mac_cfg0);
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
                                   &mac_cfg0, 4))
                return -EIO;
        return 0;
@@ -746,7 +747,7 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
                return -EINVAL;
 
        mac_cfg = 0;
-       if (netxen_nic_hw_write_wx(adapter,
+       if (adapter->hw_write_wx(adapter,
                NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4))
                return -EIO;
        return 0;
@@ -763,7 +764,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
                return -EINVAL;
 
        /* save previous contents */
-       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
+       if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
                                  &reg, 4))
                return -EIO;
        if (mode == NETXEN_NIU_PROMISC_MODE) {
@@ -801,7 +802,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
                        return -EIO;
                }
        }
-       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
+       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
                                   &reg, 4))
                return -EIO;
        return 0;
@@ -826,13 +827,13 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
        case 0:
            memcpy(temp + 2, addr, 2);
            val = le32_to_cpu(*(__le32 *)temp);
-           if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
+           if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
                                &val, 4))
                return -EIO;
 
            memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
            val = le32_to_cpu(*(__le32 *)temp);
-           if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
+           if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
                                &val, 4))
                return -EIO;
            break;
@@ -840,13 +841,13 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
        case 1:
            memcpy(temp + 2, addr, 2);
            val = le32_to_cpu(*(__le32 *)temp);
-           if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1,
+           if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1,
                                &val, 4))
                return -EIO;
 
            memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
            val = le32_to_cpu(*(__le32 *)temp);
-           if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI,
+           if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI,
                                &val, 4))
                return -EIO;
            break;
@@ -877,10 +878,10 @@ int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter,
        if (phy != 0)
                return -EINVAL;
 
-       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
+       if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
                                  &stationhigh, 4))
                return -EIO;
-       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
+       if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
                                  &stationlow, 4))
                return -EIO;
        ((__le32 *)val)[1] = cpu_to_le32(stationhigh);
@@ -901,7 +902,7 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
        if (port > NETXEN_NIU_MAX_XG_PORTS)
                return -EINVAL;
 
-       if (netxen_nic_hw_read_wx(adapter,
+       if (adapter->hw_read_wx(adapter,
                NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), &reg, 4))
                        return -EIO;
        if (mode == NETXEN_NIU_PROMISC_MODE)
@@ -909,6 +910,11 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
        else
                reg = (reg & ~0x2000UL);
 
+       if (mode == NETXEN_NIU_ALLMULTI_MODE)
+               reg = (reg | 0x1000UL);
+       else
+               reg = (reg & ~0x1000UL);
+
        netxen_crb_writelit_adapter(adapter,
                NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
 
index a566b50f36f5dac6b3f20b320e479ad75f15712f..3bfa51b62a4f9e93d6c5c1c9f1760dc392416bae 100644 (file)
 #define CRB_CMD_CONSUMER_OFFSET     NETXEN_NIC_REG(0x0c)
 #define CRB_PAUSE_ADDR_LO           NETXEN_NIC_REG(0x10)       /* C0 EPG BUG  */
 #define CRB_PAUSE_ADDR_HI           NETXEN_NIC_REG(0x14)
-#define CRB_HOST_CMD_ADDR_HI        NETXEN_NIC_REG(0x18)       /* host add:cmd ring */
-#define CRB_HOST_CMD_ADDR_LO        NETXEN_NIC_REG(0x1c)
+#define NX_CDRP_CRB_OFFSET          NETXEN_NIC_REG(0x18)
+#define NX_ARG1_CRB_OFFSET          NETXEN_NIC_REG(0x1c)
+#define NX_ARG2_CRB_OFFSET          NETXEN_NIC_REG(0x20)
+#define NX_ARG3_CRB_OFFSET          NETXEN_NIC_REG(0x24)
+#define NX_SIGN_CRB_OFFSET          NETXEN_NIC_REG(0x28)
 #define CRB_CMD_INTR_LOOP           NETXEN_NIC_REG(0x20)       /* 4 regs for perf */
 #define CRB_CMD_DMA_LOOP            NETXEN_NIC_REG(0x24)
 #define CRB_RCV_INTR_LOOP           NETXEN_NIC_REG(0x28)
@@ -73,8 +76,8 @@
 #define CRB_RX_LRO_MID_TIMER        NETXEN_NIC_REG(0x88)
 #define CRB_DMA_MAX_RCV_BUFS        NETXEN_NIC_REG(0x8c)
 #define CRB_MAX_DMA_ENTRIES         NETXEN_NIC_REG(0x90)
-#define CRB_XG_STATE                NETXEN_NIC_REG(0x94)       /* XG Link status */
-#define CRB_AGENT_GO                NETXEN_NIC_REG(0x98)       /* NIC pkt gen agent */
+#define CRB_XG_STATE                NETXEN_NIC_REG(0x94) /* XG Link status */
+#define CRB_XG_STATE_P3             NETXEN_NIC_REG(0x98) /* XG PF Link status */
 #define CRB_AGENT_TX_SIZE           NETXEN_NIC_REG(0x9c)
 #define CRB_AGENT_TX_TYPE           NETXEN_NIC_REG(0xa0)
 #define CRB_AGENT_TX_ADDR           NETXEN_NIC_REG(0xa4)
 #define CRB_HOST_BUFFER_CONS        NETXEN_NIC_REG(0xf0)
 #define CRB_JUMBO_BUFFER_PROD       NETXEN_NIC_REG(0xf4)
 #define CRB_JUMBO_BUFFER_CONS       NETXEN_NIC_REG(0xf8)
+#define CRB_HOST_DUMMY_BUF          NETXEN_NIC_REG(0xfc)
 
+#define CRB_RCVPEG_STATE            NETXEN_NIC_REG(0x13c)
 #define CRB_CMD_PRODUCER_OFFSET_1   NETXEN_NIC_REG(0x1ac)
 #define CRB_CMD_CONSUMER_OFFSET_1   NETXEN_NIC_REG(0x1b0)
 #define CRB_CMD_PRODUCER_OFFSET_2   NETXEN_NIC_REG(0x1b8)
 #define nx_get_temp_state(x)           ((x) & 0xffff)
 #define nx_encode_temp(val, state)     (((val) << 16) | (state))
 
-/* CRB registers per Rcv Descriptor ring */
-struct netxen_rcv_desc_crb {
-       u32 crb_rcv_producer_offset __attribute__ ((aligned(512)));
-       u32 crb_rcv_consumer_offset;
-       u32 crb_globalrcv_ring;
-       u32 crb_rcv_ring_size;
-};
-
 /*
  * CRB registers used by the receive peg logic.
  */
 
 struct netxen_recv_crb {
-       struct netxen_rcv_desc_crb rcv_desc_crb[NUM_RCV_DESC_RINGS];
-       u32 crb_rcvstatus_ring;
-       u32 crb_rcv_status_producer;
-       u32 crb_rcv_status_consumer;
-       u32 crb_rcvpeg_state;
-       u32 crb_status_ring_size;
+       u32 crb_rcv_producer[NUM_RCV_DESC_RINGS];
+       u32 crb_sts_consumer;
 };
 
-extern struct netxen_recv_crb recv_crb_registers[];
-
 /*
  * Temperature control.
  */
index 32a8503a7acdc3ade6fcb1fd656a2009ec9eda09..4aa54794704045dfdec94bbaafea2d88970e163a 100644 (file)
@@ -158,11 +158,10 @@ static int m88e1111_config_init(struct phy_device *phydev)
 {
        int err;
        int temp;
-       int mode;
 
        /* Enable Fiber/Copper auto selection */
        temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
-       temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO;
+       temp &= ~MII_M1111_HWCFG_FIBER_COPPER_AUTO;
        phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
 
        temp = phy_read(phydev, MII_BMCR);
@@ -198,9 +197,7 @@ static int m88e1111_config_init(struct phy_device *phydev)
 
                temp &= ~(MII_M1111_HWCFG_MODE_MASK);
 
-               mode = phy_read(phydev, MII_M1111_PHY_EXT_CR);
-
-               if (mode & MII_M1111_HWCFG_FIBER_COPPER_RES)
+               if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES)
                        temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII;
                else
                        temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII;
index 6b1d7a8edf1554aeff5680fd4f467f2444dce498..739b3ab7bccc2d9ea719c6080eb3137bf2ba2dbc 100644 (file)
@@ -866,7 +866,8 @@ static int __init ppp_init(void)
                        err = PTR_ERR(ppp_class);
                        goto out_chrdev;
                }
-               device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), "ppp");
+               device_create_drvdata(ppp_class, NULL, MKDEV(PPP_MAJOR, 0),
+                                     NULL, "ppp");
        }
 
 out:
index 504a48ff73c83e5cbac2eaa96c25bdc754bbd40e..6531ff565c545bd02841fc2d15942f3e4896d65f 100644 (file)
@@ -50,8 +50,8 @@
 #include <asm/processor.h>
 
 #define DRV_NAME       "r6040"
-#define DRV_VERSION    "0.16"
-#define DRV_RELDATE    "10Nov2007"
+#define DRV_VERSION    "0.18"
+#define DRV_RELDATE    "13Jul2008"
 
 /* PHY CHIP Address */
 #define PHY1_ADDR      1       /* For MAC1 */
 #define MISR           0x3C    /* Status register */
 #define MIER           0x40    /* INT enable register */
 #define  MSK_INT       0x0000  /* Mask off interrupts */
+#define  RX_FINISH     0x0001  /* RX finished */
+#define  RX_NO_DESC    0x0002  /* No RX descriptor available */
+#define  RX_FIFO_FULL  0x0004  /* RX FIFO full */
+#define  RX_EARLY      0x0008  /* RX early */
+#define  TX_FINISH     0x0010  /* TX finished */
+#define  TX_EARLY      0x0080  /* TX early */
+#define  EVENT_OVRFL   0x0100  /* Event counter overflow */
+#define  LINK_CHANGED  0x0200  /* PHY link changed */
 #define ME_CISR                0x44    /* Event counter INT status */
 #define ME_CIER                0x48    /* Event counter INT enable  */
 #define MR_CNT         0x50    /* Successfully received packet counter */
 #define MBCR_DEFAULT   0x012A  /* MAC Bus Control Register */
 #define MCAST_MAX      4       /* Max number multicast addresses to filter */
 
+/* Descriptor status */
+#define DSC_OWNER_MAC  0x8000  /* MAC is the owner of this descriptor */
+#define DSC_RX_OK      0x4000  /* RX was successful */
+#define DSC_RX_ERR     0x0800  /* RX PHY error */
+#define DSC_RX_ERR_DRI 0x0400  /* RX dribble packet */
+#define DSC_RX_ERR_BUF 0x0200  /* RX length exceeds buffer size */
+#define DSC_RX_ERR_LONG        0x0100  /* RX length > maximum packet length */
+#define DSC_RX_ERR_RUNT        0x0080  /* RX packet length < 64 byte */
+#define DSC_RX_ERR_CRC 0x0040  /* RX CRC error */
+#define DSC_RX_BCAST   0x0020  /* RX broadcast (no error) */
+#define DSC_RX_MCAST   0x0010  /* RX multicast (no error) */
+#define DSC_RX_MCH_HIT 0x0008  /* RX multicast hit in hash table (no error) */
+#define DSC_RX_MIDH_HIT        0x0004  /* RX MID table hit (no error) */
+#define DSC_RX_IDX_MID_MASK 3  /* RX mask for the index of matched MIDx */
+
 /* PHY settings */
 #define ICPLUS_PHY_ID  0x0243
 
@@ -139,10 +162,10 @@ MODULE_AUTHOR("Sten Wang <sten.wang@rdc.com.tw>,"
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver");
 
-#define RX_INT                         0x0001
-#define TX_INT                         0x0010
-#define RX_NO_DESC_INT                 0x0002
-#define INT_MASK                 (RX_INT | TX_INT)
+/* RX and TX interrupts that we handle */
+#define RX_INTS                        (RX_FIFO_FULL | RX_NO_DESC | RX_FINISH)
+#define TX_INTS                        (TX_FINISH)
+#define INT_MASK               (RX_INTS | TX_INTS)
 
 struct r6040_descriptor {
        u16     status, len;            /* 0-3 */
@@ -167,7 +190,7 @@ struct r6040_private {
        struct r6040_descriptor *tx_ring;
        dma_addr_t rx_ring_dma;
        dma_addr_t tx_ring_dma;
-       u16     tx_free_desc, rx_free_desc, phy_addr, phy_mode;
+       u16     tx_free_desc, phy_addr, phy_mode;
        u16     mcr0, mcr1;
        u16     switch_sig;
        struct net_device *dev;
@@ -183,7 +206,7 @@ static char version[] __devinitdata = KERN_INFO DRV_NAME
 static int phy_table[] = { PHY1_ADDR, PHY2_ADDR };
 
 /* Read a word data from PHY Chip */
-static int phy_read(void __iomem *ioaddr, int phy_addr, int reg)
+static int r6040_phy_read(void __iomem *ioaddr, int phy_addr, int reg)
 {
        int limit = 2048;
        u16 cmd;
@@ -200,7 +223,7 @@ static int phy_read(void __iomem *ioaddr, int phy_addr, int reg)
 }
 
 /* Write a word data from PHY Chip */
-static void phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val)
+static void r6040_phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val)
 {
        int limit = 2048;
        u16 cmd;
@@ -216,20 +239,20 @@ static void phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val)
        }
 }
 
-static int mdio_read(struct net_device *dev, int mii_id, int reg)
+static int r6040_mdio_read(struct net_device *dev, int mii_id, int reg)
 {
        struct r6040_private *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->base;
 
-       return (phy_read(ioaddr, lp->phy_addr, reg));
+       return (r6040_phy_read(ioaddr, lp->phy_addr, reg));
 }
 
-static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
+static void r6040_mdio_write(struct net_device *dev, int mii_id, int reg, int val)
 {
        struct r6040_private *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->base;
 
-       phy_write(ioaddr, lp->phy_addr, reg, val);
+       r6040_phy_write(ioaddr, lp->phy_addr, reg, val);
 }
 
 static void r6040_free_txbufs(struct net_device *dev)
@@ -283,58 +306,101 @@ static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring,
        desc->vndescp = desc_ring;
 }
 
-/* Allocate skb buffer for rx descriptor */
-static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev)
+static void r6040_init_txbufs(struct net_device *dev)
 {
-       struct r6040_descriptor *descptr;
-       void __iomem *ioaddr = lp->base;
+       struct r6040_private *lp = netdev_priv(dev);
 
-       descptr = lp->rx_insert_ptr;
-       while (lp->rx_free_desc < RX_DCNT) {
-               descptr->skb_ptr = netdev_alloc_skb(dev, MAX_BUF_SIZE);
+       lp->tx_free_desc = TX_DCNT;
 
-               if (!descptr->skb_ptr)
-                       break;
-               descptr->buf = cpu_to_le32(pci_map_single(lp->pdev,
-                       descptr->skb_ptr->data,
-                       MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
-               descptr->status = 0x8000;
-               descptr = descptr->vndescp;
-               lp->rx_free_desc++;
-               /* Trigger RX DMA */
-               iowrite16(lp->mcr0 | 0x0002, ioaddr);
-       }
-       lp->rx_insert_ptr = descptr;
+       lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring;
+       r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT);
 }
 
-static void r6040_alloc_txbufs(struct net_device *dev)
+static int r6040_alloc_rxbufs(struct net_device *dev)
 {
        struct r6040_private *lp = netdev_priv(dev);
-       void __iomem *ioaddr = lp->base;
+       struct r6040_descriptor *desc;
+       struct sk_buff *skb;
+       int rc;
 
-       lp->tx_free_desc = TX_DCNT;
+       lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring;
+       r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT);
 
-       lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring;
-       r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT);
+       /* Allocate skbs for the rx descriptors */
+       desc = lp->rx_ring;
+       do {
+               skb = netdev_alloc_skb(dev, MAX_BUF_SIZE);
+               if (!skb) {
+                       printk(KERN_ERR "%s: failed to alloc skb for rx\n", dev->name);
+                       rc = -ENOMEM;
+                       goto err_exit;
+               }
+               desc->skb_ptr = skb;
+               desc->buf = cpu_to_le32(pci_map_single(lp->pdev,
+                                               desc->skb_ptr->data,
+                                               MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
+               desc->status = DSC_OWNER_MAC;
+               desc = desc->vndescp;
+       } while (desc != lp->rx_ring);
 
-       iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0);
-       iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1);
+       return 0;
+
+err_exit:
+       /* Deallocate all previously allocated skbs */
+       r6040_free_rxbufs(dev);
+       return rc;
 }
 
-static void r6040_alloc_rxbufs(struct net_device *dev)
+static void r6040_init_mac_regs(struct net_device *dev)
 {
        struct r6040_private *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->base;
+       int limit = 2048;
+       u16 cmd;
 
-       lp->rx_free_desc = 0;
+       /* Mask Off Interrupt */
+       iowrite16(MSK_INT, ioaddr + MIER);
 
-       lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring;
-       r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT);
+       /* Reset RDC MAC */
+       iowrite16(MAC_RST, ioaddr + MCR1);
+       while (limit--) {
+               cmd = ioread16(ioaddr + MCR1);
+               if (cmd & 0x1)
+                       break;
+       }
+       /* Reset internal state machine */
+       iowrite16(2, ioaddr + MAC_SM);
+       iowrite16(0, ioaddr + MAC_SM);
+       udelay(5000);
 
-       rx_buf_alloc(lp, dev);
+       /* MAC Bus Control Register */
+       iowrite16(MBCR_DEFAULT, ioaddr + MBCR);
+
+       /* Buffer Size Register */
+       iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR);
+
+       /* Write TX ring start address */
+       iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0);
+       iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1);
 
+       /* Write RX ring start address */
        iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0);
        iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1);
+
+       /* Set interrupt waiting time and packet numbers */
+       iowrite16(0, ioaddr + MT_ICR);
+       iowrite16(0, ioaddr + MR_ICR);
+
+       /* Enable interrupts */
+       iowrite16(INT_MASK, ioaddr + MIER);
+
+       /* Enable TX and RX */
+       iowrite16(lp->mcr0 | 0x0002, ioaddr);
+
+       /* Let TX poll the descriptors
+        * we may got called by r6040_tx_timeout which has left
+        * some unsent tx buffers */
+       iowrite16(0x01, ioaddr + MTPR);
 }
 
 static void r6040_tx_timeout(struct net_device *dev)
@@ -342,27 +408,16 @@ static void r6040_tx_timeout(struct net_device *dev)
        struct r6040_private *priv = netdev_priv(dev);
        void __iomem *ioaddr = priv->base;
 
-       printk(KERN_WARNING "%s: transmit timed out, status %4.4x, PHY status "
-               "%4.4x\n",
+       printk(KERN_WARNING "%s: transmit timed out, int enable %4.4x "
+               "status %4.4x, PHY status %4.4x\n",
                dev->name, ioread16(ioaddr + MIER),
-               mdio_read(dev, priv->mii_if.phy_id, MII_BMSR));
-
-       disable_irq(dev->irq);
-       napi_disable(&priv->napi);
-       spin_lock(&priv->lock);
-       /* Clear all descriptors */
-       r6040_free_txbufs(dev);
-       r6040_free_rxbufs(dev);
-       r6040_alloc_txbufs(dev);
-       r6040_alloc_rxbufs(dev);
-
-       /* Reset MAC */
-       iowrite16(MAC_RST, ioaddr + MCR1);
-       spin_unlock(&priv->lock);
-       enable_irq(dev->irq);
+               ioread16(ioaddr + MISR),
+               r6040_mdio_read(dev, priv->mii_if.phy_id, MII_BMSR));
 
        dev->stats.tx_errors++;
-       netif_wake_queue(dev);
+
+       /* Reset MAC and re-init all registers */
+       r6040_init_mac_regs(dev);
 }
 
 static struct net_device_stats *r6040_get_stats(struct net_device *dev)
@@ -424,6 +479,7 @@ static int r6040_close(struct net_device *dev)
        del_timer_sync(&lp->timer);
 
        spin_lock_irq(&lp->lock);
+       napi_disable(&lp->napi);
        netif_stop_queue(dev);
        r6040_down(dev);
        spin_unlock_irq(&lp->lock);
@@ -432,23 +488,23 @@ static int r6040_close(struct net_device *dev)
 }
 
 /* Status of PHY CHIP */
-static int phy_mode_chk(struct net_device *dev)
+static int r6040_phy_mode_chk(struct net_device *dev)
 {
        struct r6040_private *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->base;
        int phy_dat;
 
        /* PHY Link Status Check */
-       phy_dat = phy_read(ioaddr, lp->phy_addr, 1);
+       phy_dat = r6040_phy_read(ioaddr, lp->phy_addr, 1);
        if (!(phy_dat & 0x4))
                phy_dat = 0x8000;       /* Link Failed, full duplex */
 
        /* PHY Chip Auto-Negotiation Status */
-       phy_dat = phy_read(ioaddr, lp->phy_addr, 1);
+       phy_dat = r6040_phy_read(ioaddr, lp->phy_addr, 1);
        if (phy_dat & 0x0020) {
                /* Auto Negotiation Mode */
-               phy_dat = phy_read(ioaddr, lp->phy_addr, 5);
-               phy_dat &= phy_read(ioaddr, lp->phy_addr, 4);
+               phy_dat = r6040_phy_read(ioaddr, lp->phy_addr, 5);
+               phy_dat &= r6040_phy_read(ioaddr, lp->phy_addr, 4);
                if (phy_dat & 0x140)
                        /* Force full duplex */
                        phy_dat = 0x8000;
@@ -456,7 +512,7 @@ static int phy_mode_chk(struct net_device *dev)
                        phy_dat = 0;
        } else {
                /* Force Mode */
-               phy_dat = phy_read(ioaddr, lp->phy_addr, 0);
+               phy_dat = r6040_phy_read(ioaddr, lp->phy_addr, 0);
                if (phy_dat & 0x100)
                        phy_dat = 0x8000;
                else
@@ -468,12 +524,12 @@ static int phy_mode_chk(struct net_device *dev)
 
 static void r6040_set_carrier(struct mii_if_info *mii)
 {
-       if (phy_mode_chk(mii->dev)) {
+       if (r6040_phy_mode_chk(mii->dev)) {
                /* autoneg is off: Link is always assumed to be up */
                if (!netif_carrier_ok(mii->dev))
                        netif_carrier_on(mii->dev);
        } else
-               phy_mode_chk(mii->dev);
+               r6040_phy_mode_chk(mii->dev);
 }
 
 static int r6040_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -494,73 +550,72 @@ static int r6040_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 static int r6040_rx(struct net_device *dev, int limit)
 {
        struct r6040_private *priv = netdev_priv(dev);
-       int count;
-       void __iomem *ioaddr = priv->base;
+       struct r6040_descriptor *descptr = priv->rx_remove_ptr;
+       struct sk_buff *skb_ptr, *new_skb;
+       int count = 0;
        u16 err;
 
-       for (count = 0; count < limit; ++count) {
-               struct r6040_descriptor *descptr = priv->rx_remove_ptr;
-               struct sk_buff *skb_ptr;
-
-               /* Disable RX interrupt */
-               iowrite16(ioread16(ioaddr + MIER) & (~RX_INT), ioaddr + MIER);
-               descptr = priv->rx_remove_ptr;
-
-               /* Check for errors */
-               err = ioread16(ioaddr + MLSR);
-               if (err & 0x0400)
-                       dev->stats.rx_errors++;
-               /* RX FIFO over-run */
-               if (err & 0x8000)
-                       dev->stats.rx_fifo_errors++;
-               /* RX descriptor unavailable */
-               if (err & 0x0080)
-                       dev->stats.rx_frame_errors++;
-               /* Received packet with length over buffer lenght */
-               if (err & 0x0020)
-                       dev->stats.rx_over_errors++;
-               /* Received packet with too long or short */
-               if (err & (0x0010 | 0x0008))
-                       dev->stats.rx_length_errors++;
-               /* Received packet with CRC errors */
-               if (err & 0x0004) {
-                       spin_lock(&priv->lock);
-                       dev->stats.rx_crc_errors++;
-                       spin_unlock(&priv->lock);
-               }
-
-               while (priv->rx_free_desc) {
-                       /* No RX packet */
-                       if (descptr->status & 0x8000)
-                               break;
-                       skb_ptr = descptr->skb_ptr;
-                       if (!skb_ptr) {
-                               printk(KERN_ERR "%s: Inconsistent RX"
-                                       "descriptor chain\n",
-                                       dev->name);
-                               break;
+       /* Limit not reached and the descriptor belongs to the CPU */
+       while (count < limit && !(descptr->status & DSC_OWNER_MAC)) {
+               /* Read the descriptor status */
+               err = descptr->status;
+               /* Global error status set */
+               if (err & DSC_RX_ERR) {
+                       /* RX dribble */
+                       if (err & DSC_RX_ERR_DRI)
+                               dev->stats.rx_frame_errors++;
+                       /* Buffer lenght exceeded */
+                       if (err & DSC_RX_ERR_BUF)
+                               dev->stats.rx_length_errors++;
+                       /* Packet too long */
+                       if (err & DSC_RX_ERR_LONG)
+                               dev->stats.rx_length_errors++;
+                       /* Packet < 64 bytes */
+                       if (err & DSC_RX_ERR_RUNT)
+                               dev->stats.rx_length_errors++;
+                       /* CRC error */
+                       if (err & DSC_RX_ERR_CRC) {
+                               spin_lock(&priv->lock);
+                               dev->stats.rx_crc_errors++;
+                               spin_unlock(&priv->lock);
                        }
-                       descptr->skb_ptr = NULL;
-                       skb_ptr->dev = priv->dev;
-                       /* Do not count the CRC */
-                       skb_put(skb_ptr, descptr->len - 4);
-                       pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf),
-                               MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
-                       skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev);
-                       /* Send to upper layer */
-                       netif_receive_skb(skb_ptr);
-                       dev->last_rx = jiffies;
-                       dev->stats.rx_packets++;
-                       dev->stats.rx_bytes += descptr->len;
-                       /* To next descriptor */
-                       descptr = descptr->vndescp;
-                       priv->rx_free_desc--;
+                       goto next_descr;
+               }
+               
+               /* Packet successfully received */
+               new_skb = netdev_alloc_skb(dev, MAX_BUF_SIZE);
+               if (!new_skb) {
+                       dev->stats.rx_dropped++;
+                       goto next_descr;
                }
-               priv->rx_remove_ptr = descptr;
+               skb_ptr = descptr->skb_ptr;
+               skb_ptr->dev = priv->dev;
+               
+               /* Do not count the CRC */
+               skb_put(skb_ptr, descptr->len - 4);
+               pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf),
+                                       MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+               skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev);
+               
+               /* Send to upper layer */
+               netif_receive_skb(skb_ptr);
+               dev->last_rx = jiffies;
+               dev->stats.rx_packets++;
+               dev->stats.rx_bytes += descptr->len - 4;
+
+               /* put new skb into descriptor */
+               descptr->skb_ptr = new_skb;
+               descptr->buf = cpu_to_le32(pci_map_single(priv->pdev,
+                                               descptr->skb_ptr->data,
+                                       MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
+
+next_descr:
+               /* put the descriptor back to the MAC */
+               descptr->status = DSC_OWNER_MAC;
+               descptr = descptr->vndescp;
+               count++;
        }
-       /* Allocate new RX buffer */
-       if (priv->rx_free_desc < RX_DCNT)
-               rx_buf_alloc(priv, priv->dev);
+       priv->rx_remove_ptr = descptr;
 
        return count;
 }
@@ -584,7 +639,7 @@ static void r6040_tx(struct net_device *dev)
                if (err & (0x2000 | 0x4000))
                        dev->stats.tx_carrier_errors++;
 
-               if (descptr->status & 0x8000)
+               if (descptr->status & DSC_OWNER_MAC)
                        break; /* Not complete */
                skb_ptr = descptr->skb_ptr;
                pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf),
@@ -616,7 +671,7 @@ static int r6040_poll(struct napi_struct *napi, int budget)
        if (work_done < budget) {
                netif_rx_complete(dev, napi);
                /* Enable RX interrupt */
-               iowrite16(ioread16(ioaddr + MIER) | RX_INT, ioaddr + MIER);
+               iowrite16(ioread16(ioaddr + MIER) | RX_INTS, ioaddr + MIER);
        }
        return work_done;
 }
@@ -638,13 +693,22 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
                return IRQ_NONE;
 
        /* RX interrupt request */
-       if (status & 0x01) {
+       if (status & RX_INTS) {
+               if (status & RX_NO_DESC) {
+                       /* RX descriptor unavailable */
+                       dev->stats.rx_dropped++;
+                       dev->stats.rx_missed_errors++;
+               }
+               if (status & RX_FIFO_FULL)
+                       dev->stats.rx_fifo_errors++;
+
+               /* Mask off RX interrupt */
+               iowrite16(ioread16(ioaddr + MIER) & ~RX_INTS, ioaddr + MIER);
                netif_rx_schedule(dev, &lp->napi);
-               iowrite16(TX_INT, ioaddr + MIER);
        }
 
        /* TX interrupt request */
-       if (status & 0x10)
+       if (status & TX_INTS)
                r6040_tx(dev);
 
        return IRQ_HANDLED;
@@ -660,52 +724,48 @@ static void r6040_poll_controller(struct net_device *dev)
 #endif
 
 /* Init RDC MAC */
-static void r6040_up(struct net_device *dev)
+static int r6040_up(struct net_device *dev)
 {
        struct r6040_private *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->base;
+       int ret;
 
        /* Initialise and alloc RX/TX buffers */
-       r6040_alloc_txbufs(dev);
-       r6040_alloc_rxbufs(dev);
+       r6040_init_txbufs(dev);
+       ret = r6040_alloc_rxbufs(dev);
+       if (ret)
+               return ret;
 
-       /* Buffer Size Register */
-       iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR);
        /* Read the PHY ID */
-       lp->switch_sig = phy_read(ioaddr, 0, 2);
+       lp->switch_sig = r6040_phy_read(ioaddr, 0, 2);
 
        if (lp->switch_sig  == ICPLUS_PHY_ID) {
-               phy_write(ioaddr, 29, 31, 0x175C); /* Enable registers */
+               r6040_phy_write(ioaddr, 29, 31, 0x175C); /* Enable registers */
                lp->phy_mode = 0x8000;
        } else {
                /* PHY Mode Check */
-               phy_write(ioaddr, lp->phy_addr, 4, PHY_CAP);
-               phy_write(ioaddr, lp->phy_addr, 0, PHY_MODE);
+               r6040_phy_write(ioaddr, lp->phy_addr, 4, PHY_CAP);
+               r6040_phy_write(ioaddr, lp->phy_addr, 0, PHY_MODE);
 
                if (PHY_MODE == 0x3100)
-                       lp->phy_mode = phy_mode_chk(dev);
+                       lp->phy_mode = r6040_phy_mode_chk(dev);
                else
                        lp->phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0;
        }
-       /* MAC Bus Control Register */
-       iowrite16(MBCR_DEFAULT, ioaddr + MBCR);
 
-       /* MAC TX/RX Enable */
+       /* Set duplex mode */
        lp->mcr0 |= lp->phy_mode;
-       iowrite16(lp->mcr0, ioaddr);
-
-       /* set interrupt waiting time and packet numbers */
-       iowrite16(0x0F06, ioaddr + MT_ICR);
-       iowrite16(0x0F06, ioaddr + MR_ICR);
 
        /* improve performance (by RDC guys) */
-       phy_write(ioaddr, 30, 17, (phy_read(ioaddr, 30, 17) | 0x4000));
-       phy_write(ioaddr, 30, 17, ~((~phy_read(ioaddr, 30, 17)) | 0x2000));
-       phy_write(ioaddr, 0, 19, 0x0000);
-       phy_write(ioaddr, 0, 30, 0x01F0);
+       r6040_phy_write(ioaddr, 30, 17, (r6040_phy_read(ioaddr, 30, 17) | 0x4000));
+       r6040_phy_write(ioaddr, 30, 17, ~((~r6040_phy_read(ioaddr, 30, 17)) | 0x2000));
+       r6040_phy_write(ioaddr, 0, 19, 0x0000);
+       r6040_phy_write(ioaddr, 0, 30, 0x01F0);
 
-       /* Interrupt Mask Register */
-       iowrite16(INT_MASK, ioaddr + MIER);
+       /* Initialize all MAC registers */
+       r6040_init_mac_regs(dev);
+
+       return 0;
 }
 
 /*
@@ -721,7 +781,7 @@ static void r6040_timer(unsigned long data)
 
        /* Polling PHY Chip Status */
        if (PHY_MODE == 0x3100)
-               phy_mode = phy_mode_chk(dev);
+               phy_mode = r6040_phy_mode_chk(dev);
        else
                phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0;
 
@@ -784,7 +844,14 @@ static int r6040_open(struct net_device *dev)
                return -ENOMEM;
        }
 
-       r6040_up(dev);
+       ret = r6040_up(dev);
+       if (ret) {
+               pci_free_consistent(lp->pdev, TX_DESC_SIZE, lp->tx_ring,
+                                                       lp->tx_ring_dma);
+               pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring,
+                                                       lp->rx_ring_dma);
+               return ret;
+       }
 
        napi_enable(&lp->napi);
        netif_start_queue(dev);
@@ -830,7 +897,7 @@ static int r6040_start_xmit(struct sk_buff *skb, struct net_device *dev)
        descptr->skb_ptr = skb;
        descptr->buf = cpu_to_le32(pci_map_single(lp->pdev,
                skb->data, skb->len, PCI_DMA_TODEVICE));
-       descptr->status = 0x8000;
+       descptr->status = DSC_OWNER_MAC;
        /* Trigger the MAC to check the TX descriptor */
        iowrite16(0x01, ioaddr + MTPR);
        lp->tx_insert_ptr = descptr->vndescp;
@@ -987,24 +1054,27 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
 
        err = pci_enable_device(pdev);
        if (err)
-               return err;
+               goto err_out;
 
        /* this should always be supported */
-       if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+       err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+       if (err) {
                printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses"
                                "not supported by the card\n");
-               return -ENODEV;
+               goto err_out;
        }
-       if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+       err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+       if (err) {
                printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses"
                                "not supported by the card\n");
-               return -ENODEV;
+               goto err_out;
        }
 
        /* IO Size check */
        if (pci_resource_len(pdev, 0) < io_size) {
-               printk(KERN_ERR "Insufficient PCI resources, aborting\n");
-               return -EIO;
+               printk(KERN_ERR DRV_NAME "Insufficient PCI resources, aborting\n");
+               err = -EIO;
+               goto err_out;
        }
 
        pioaddr = pci_resource_start(pdev, 0);  /* IO map base address */
@@ -1012,24 +1082,26 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
 
        dev = alloc_etherdev(sizeof(struct r6040_private));
        if (!dev) {
-               printk(KERN_ERR "Failed to allocate etherdev\n");
-               return -ENOMEM;
+               printk(KERN_ERR DRV_NAME "Failed to allocate etherdev\n");
+               err = -ENOMEM;
+               goto err_out;
        }
        SET_NETDEV_DEV(dev, &pdev->dev);
        lp = netdev_priv(dev);
-       lp->pdev = pdev;
 
-       if (pci_request_regions(pdev, DRV_NAME)) {
+       err = pci_request_regions(pdev, DRV_NAME);
+
+       if (err) {
                printk(KERN_ERR DRV_NAME ": Failed to request PCI regions\n");
-               err = -ENODEV;
-               goto err_out_disable;
+               goto err_out_free_dev;
        }
 
        ioaddr = pci_iomap(pdev, bar, io_size);
        if (!ioaddr) {
                printk(KERN_ERR "ioremap failed for device %s\n",
                        pci_name(pdev));
-               return -EIO;
+               err = -EIO;
+               goto err_out_free_res;
        }
 
        /* Init system & device */
@@ -1049,6 +1121,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
 
        /* Link new device into r6040_root_dev */
        lp->pdev = pdev;
+       lp->dev = dev;
 
        /* Init RDC private data */
        lp->mcr0 = 0x1002;
@@ -1070,8 +1143,8 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
 #endif
        netif_napi_add(dev, &lp->napi, r6040_poll, 64);
        lp->mii_if.dev = dev;
-       lp->mii_if.mdio_read = mdio_read;
-       lp->mii_if.mdio_write = mdio_write;
+       lp->mii_if.mdio_read = r6040_mdio_read;
+       lp->mii_if.mdio_write = r6040_mdio_write;
        lp->mii_if.phy_id = lp->phy_addr;
        lp->mii_if.phy_id_mask = 0x1f;
        lp->mii_if.reg_num_mask = 0x1f;
@@ -1080,17 +1153,17 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
        err = register_netdev(dev);
        if (err) {
                printk(KERN_ERR DRV_NAME ": Failed to register net device\n");
-               goto err_out_res;
+               goto err_out_unmap;
        }
        return 0;
 
-err_out_res:
+err_out_unmap:
+       pci_iounmap(pdev, ioaddr);
+err_out_free_res:
        pci_release_regions(pdev);
-err_out_disable:
-       pci_disable_device(pdev);
-       pci_set_drvdata(pdev, NULL);
+err_out_free_dev:
        free_netdev(dev);
-
+err_out:
        return err;
 }
 
index cfe8829ed31f1426557bc840dcc84f3a20ce01e2..a3e3895e503238af8988bfb32bfe53c26a934ce5 100644 (file)
@@ -1418,8 +1418,10 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
 
        rtl_hw_phy_config(dev);
 
-       dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
-       RTL_W8(0x82, 0x01);
+       if (tp->mac_version <= RTL_GIGA_MAC_VER_06) {
+               dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
+               RTL_W8(0x82, 0x01);
+       }
 
        pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
 
@@ -3032,13 +3034,7 @@ static void rtl_set_rx_mode(struct net_device *dev)
        tmp = rtl8169_rx_config | rx_mode |
              (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
 
-       if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_15) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_16) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_17)) {
+       if (tp->mac_version > RTL_GIGA_MAC_VER_06) {
                u32 data = mc_filter[0];
 
                mc_filter[0] = swab32(mc_filter[1]);
index 7b2015f9e46994407c0fef9c0bcee02b3918ce49..45c72eebb3a7eb7b89d62aa92abef171a7676e7a 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/in.h>
 #include <linux/crc32.h>
 #include <linux/ethtool.h>
+#include <linux/topology.h>
 #include "net_driver.h"
 #include "gmii.h"
 #include "ethtool.h"
@@ -832,7 +833,23 @@ static void efx_probe_interrupts(struct efx_nic *efx)
        if (efx->interrupt_mode == EFX_INT_MODE_MSIX) {
                BUG_ON(!pci_find_capability(efx->pci_dev, PCI_CAP_ID_MSIX));
 
-               efx->rss_queues = rss_cpus ? rss_cpus : num_online_cpus();
+               if (rss_cpus == 0) {
+                       cpumask_t core_mask;
+                       int cpu;
+
+                       cpus_clear(core_mask);
+                       efx->rss_queues = 0;
+                       for_each_online_cpu(cpu) {
+                               if (!cpu_isset(cpu, core_mask)) {
+                                       ++efx->rss_queues;
+                                       cpus_or(core_mask, core_mask,
+                                               topology_core_siblings(cpu));
+                               }
+                       }
+               } else {
+                       efx->rss_queues = rss_cpus;
+               }
+
                efx->rss_queues = min(efx->rss_queues, max_channel + 1);
                efx->rss_queues = min(efx->rss_queues, EFX_MAX_CHANNELS);
 
@@ -1762,7 +1779,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
 
        efx->reset_pending = method;
 
-       queue_work(efx->workqueue, &efx->reset_work);
+       queue_work(efx->reset_workqueue, &efx->reset_work);
 }
 
 /**************************************************************************
@@ -1907,14 +1924,28 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
                goto fail1;
        }
 
+       efx->reset_workqueue = create_singlethread_workqueue("sfc_reset");
+       if (!efx->reset_workqueue) {
+               rc = -ENOMEM;
+               goto fail2;
+       }
+
        return 0;
 
+ fail2:
+       destroy_workqueue(efx->workqueue);
+       efx->workqueue = NULL;
+
  fail1:
        return rc;
 }
 
 static void efx_fini_struct(struct efx_nic *efx)
 {
+       if (efx->reset_workqueue) {
+               destroy_workqueue(efx->reset_workqueue);
+               efx->reset_workqueue = NULL;
+       }
        if (efx->workqueue) {
                destroy_workqueue(efx->workqueue);
                efx->workqueue = NULL;
@@ -1977,7 +2008,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
         * scheduled from this point because efx_stop_all() has been
         * called, we are no longer registered with driverlink, and
         * the net_device's have been removed. */
-       flush_workqueue(efx->workqueue);
+       flush_workqueue(efx->reset_workqueue);
 
        efx_pci_remove_main(efx);
 
@@ -2098,7 +2129,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
                 * scheduled since efx_stop_all() has been called, and we
                 * have not and never have been registered with either
                 * the rtnetlink or driverlink layers. */
-               cancel_work_sync(&efx->reset_work);
+               flush_workqueue(efx->reset_workqueue);
 
                /* Retry if a recoverably reset event has been scheduled */
                if ((efx->reset_pending != RESET_TYPE_INVISIBLE) &&
index 630406e142e5c7aa799695a7006a0511f07f6098..9138ee5b7b7bdc628fc782886b4ac0dbf4c951c4 100644 (file)
@@ -223,13 +223,8 @@ static struct i2c_algo_bit_data falcon_i2c_bit_operations = {
        .getsda         = falcon_getsda,
        .getscl         = falcon_getscl,
        .udelay         = 5,
-       /*
-        * This is the number of system clock ticks after which
-        * i2c-algo-bit gives up waiting for SCL to become high.
-        * It must be at least 2 since the first tick can happen
-        * immediately after it starts waiting.
-        */
-       .timeout        = 2,
+       /* Wait up to 50 ms for slave to let us pull SCL high */
+       .timeout        = DIV_ROUND_UP(HZ, 20),
 };
 
 /**************************************************************************
@@ -2479,12 +2474,11 @@ int falcon_probe_nic(struct efx_nic *efx)
 
        /* Initialise I2C adapter */
        efx->i2c_adap.owner = THIS_MODULE;
-       efx->i2c_adap.class = I2C_CLASS_HWMON;
        nic_data->i2c_data = falcon_i2c_bit_operations;
        nic_data->i2c_data.data = efx;
        efx->i2c_adap.algo_data = &nic_data->i2c_data;
        efx->i2c_adap.dev.parent = &efx->pci_dev->dev;
-       strcpy(efx->i2c_adap.name, "SFC4000 GPIO");
+       strlcpy(efx->i2c_adap.name, "SFC4000 GPIO", sizeof(efx->i2c_adap.name));
        rc = i2c_bit_add_bus(&efx->i2c_adap);
        if (rc)
                goto fail5;
index d803b86c647cd64dba5cb512b6686656d6a540df..219c74a772c32deb333b62bef44b3dd2422f18ba 100644 (file)
@@ -616,7 +616,9 @@ union efx_multicast_hash {
  * @pci_dev: The PCI device
  * @type: Controller type attributes
  * @legacy_irq: IRQ number
- * @workqueue: Workqueue for resets, port reconfigures and the HW monitor
+ * @workqueue: Workqueue for port reconfigures and the HW monitor.
+ *     Work items do not hold and must not acquire RTNL.
+ * @reset_workqueue: Workqueue for resets.  Work item will acquire RTNL.
  * @reset_work: Scheduled reset workitem
  * @monitor_work: Hardware monitor workitem
  * @membase_phys: Memory BAR value as physical address
@@ -684,6 +686,7 @@ struct efx_nic {
        const struct efx_nic_type *type;
        int legacy_irq;
        struct workqueue_struct *workqueue;
+       struct workqueue_struct *reset_workqueue;
        struct work_struct reset_work;
        struct delayed_work monitor_work;
        resource_size_t membase_phys;
index a4bc812aa99910ecce1d188058df916d9188da27..c69ba1395fa9d54b0ddcf2044209b202c32343ef 100644 (file)
@@ -642,17 +642,12 @@ static void sh_eth_adjust_link(struct net_device *ndev)
                                        | ECMR_DM, ioaddr + ECMR);
                        new_state = 1;
                        mdp->link = phydev->link;
-                       netif_tx_schedule_all(ndev);
-                       netif_carrier_on(ndev);
-                       netif_start_queue(ndev);
                }
        } else if (mdp->link) {
                new_state = 1;
                mdp->link = PHY_DOWN;
                mdp->speed = 0;
                mdp->duplex = -1;
-               netif_stop_queue(ndev);
-               netif_carrier_off(ndev);
        }
 
        if (new_state)
index f2051b209da2b1cb0e97236daab948762c84bb77..2040965d7724bc29fd0cc92532ca9e65dded071c 100644 (file)
@@ -308,7 +308,7 @@ static void smc_reset(struct net_device *dev)
         * can't handle it then there will be no recovery except for
         * a hard reset or power cycle
         */
-       if (nowait)
+       if (lp->cfg.flags & SMC91X_NOWAIT)
                cfg |= CONFIG_NO_WAIT;
 
        /*
@@ -1939,8 +1939,11 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
        if (retval)
                goto err_out;
 
-#ifdef SMC_USE_PXA_DMA
-       {
+#ifdef CONFIG_ARCH_PXA
+#  ifdef SMC_USE_PXA_DMA
+       lp->cfg.flags |= SMC91X_USE_DMA;
+#  endif
+       if (lp->cfg.flags & SMC91X_USE_DMA) {
                int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW,
                                          smc_pxa_dma_irq, NULL);
                if (dma >= 0)
@@ -1980,7 +1983,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
        }
 
 err_out:
-#ifdef SMC_USE_PXA_DMA
+#ifdef CONFIG_ARCH_PXA
        if (retval && dev->dma != (unsigned char)-1)
                pxa_free_dma(dev->dma);
 #endif
@@ -2050,9 +2053,11 @@ static int smc_enable_device(struct platform_device *pdev)
        return 0;
 }
 
-static int smc_request_attrib(struct platform_device *pdev)
+static int smc_request_attrib(struct platform_device *pdev,
+                             struct net_device *ndev)
 {
        struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
+       struct smc_local *lp = netdev_priv(ndev);
 
        if (!res)
                return 0;
@@ -2063,9 +2068,11 @@ static int smc_request_attrib(struct platform_device *pdev)
        return 0;
 }
 
-static void smc_release_attrib(struct platform_device *pdev)
+static void smc_release_attrib(struct platform_device *pdev,
+                              struct net_device *ndev)
 {
        struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
+       struct smc_local *lp = netdev_priv(ndev);
 
        if (res)
                release_mem_region(res->start, ATTRIB_SIZE);
@@ -2123,27 +2130,14 @@ static int smc_drv_probe(struct platform_device *pdev)
        struct net_device *ndev;
        struct resource *res, *ires;
        unsigned int __iomem *addr;
+       unsigned long irq_flags = SMC_IRQ_FLAGS;
        int ret;
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
-       if (!res)
-               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               ret = -ENODEV;
-               goto out;
-       }
-
-
-       if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
-               ret = -EBUSY;
-               goto out;
-       }
-
        ndev = alloc_etherdev(sizeof(struct smc_local));
        if (!ndev) {
                printk("%s: could not allocate device.\n", CARDNAME);
                ret = -ENOMEM;
-               goto out_release_io;
+               goto out;
        }
        SET_NETDEV_DEV(ndev, &pdev->dev);
 
@@ -2152,37 +2146,47 @@ static int smc_drv_probe(struct platform_device *pdev)
         */
 
        lp = netdev_priv(ndev);
-       lp->cfg.irq_flags = SMC_IRQ_FLAGS;
 
-#ifdef SMC_DYNAMIC_BUS_CONFIG
-       if (pd)
+       if (pd) {
                memcpy(&lp->cfg, pd, sizeof(lp->cfg));
-       else {
-               lp->cfg.flags = SMC91X_USE_8BIT;
-               lp->cfg.flags |= SMC91X_USE_16BIT;
-               lp->cfg.flags |= SMC91X_USE_32BIT;
+               lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags);
+       } else {
+               lp->cfg.flags |= (SMC_CAN_USE_8BIT)  ? SMC91X_USE_8BIT  : 0;
+               lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0;
+               lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0;
+               lp->cfg.flags |= (nowait) ? SMC91X_NOWAIT : 0;
        }
 
-       lp->cfg.flags &= ~(SMC_CAN_USE_8BIT ? 0 : SMC91X_USE_8BIT);
-       lp->cfg.flags &= ~(SMC_CAN_USE_16BIT ? 0 : SMC91X_USE_16BIT);
-       lp->cfg.flags &= ~(SMC_CAN_USE_32BIT ? 0 : SMC91X_USE_32BIT);
-#endif
-
        ndev->dma = (unsigned char)-1;
 
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
+       if (!res)
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               ret = -ENODEV;
+               goto out_free_netdev;
+       }
+
+
+       if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
+               ret = -EBUSY;
+               goto out_free_netdev;
+       }
+
        ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (!ires) {
                ret = -ENODEV;
-               goto out_free_netdev;
+               goto out_release_io;
        }
 
        ndev->irq = ires->start;
-       if (SMC_IRQ_FLAGS == -1)
-               lp->cfg.irq_flags = ires->flags & IRQF_TRIGGER_MASK;
 
-       ret = smc_request_attrib(pdev);
+       if (ires->flags & IRQF_TRIGGER_MASK)
+               irq_flags = ires->flags & IRQF_TRIGGER_MASK;
+
+       ret = smc_request_attrib(pdev, ndev);
        if (ret)
-               goto out_free_netdev;
+               goto out_release_io;
 #if defined(CONFIG_SA1100_ASSABET)
        NCR_0 |= NCR_ENET_OSC_EN;
 #endif
@@ -2197,7 +2201,7 @@ static int smc_drv_probe(struct platform_device *pdev)
                goto out_release_attrib;
        }
 
-#ifdef SMC_USE_PXA_DMA
+#ifdef CONFIG_ARCH_PXA
        {
                struct smc_local *lp = netdev_priv(ndev);
                lp->device = &pdev->dev;
@@ -2205,7 +2209,7 @@ static int smc_drv_probe(struct platform_device *pdev)
        }
 #endif
 
-       ret = smc_probe(ndev, addr, lp->cfg.irq_flags);
+       ret = smc_probe(ndev, addr, irq_flags);
        if (ret != 0)
                goto out_iounmap;
 
@@ -2217,11 +2221,11 @@ static int smc_drv_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, NULL);
        iounmap(addr);
  out_release_attrib:
-       smc_release_attrib(pdev);
- out_free_netdev:
-       free_netdev(ndev);
+       smc_release_attrib(pdev, ndev);
  out_release_io:
        release_mem_region(res->start, SMC_IO_EXTENT);
+ out_free_netdev:
+       free_netdev(ndev);
  out:
        printk("%s: not found (%d).\n", CARDNAME, ret);
 
@@ -2240,14 +2244,14 @@ static int smc_drv_remove(struct platform_device *pdev)
 
        free_irq(ndev->irq, ndev);
 
-#ifdef SMC_USE_PXA_DMA
+#ifdef CONFIG_ARCH_PXA
        if (ndev->dma != (unsigned char)-1)
                pxa_free_dma(ndev->dma);
 #endif
        iounmap(lp->base);
 
        smc_release_datacs(pdev,ndev);
-       smc_release_attrib(pdev);
+       smc_release_attrib(pdev,ndev);
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
        if (!res)
index 8606818653f88601fb63896b3aa0fcf19e169dae..22209b6f14057e0fadadebe9d441e5b33172d334 100644 (file)
  * Define your architecture specific bus configuration parameters here.
  */
 
-#if    defined(CONFIG_ARCH_LUBBOCK)
+#if defined(CONFIG_ARCH_LUBBOCK) ||\
+    defined(CONFIG_MACH_MAINSTONE) ||\
+    defined(CONFIG_MACH_ZYLONITE) ||\
+    defined(CONFIG_MACH_LITTLETON)
 
-/* We can only do 16-bit reads and writes in the static memory space. */
-#define SMC_CAN_USE_8BIT       0
+#include <asm/mach-types.h>
+
+/* Now the bus width is specified in the platform data
+ * pretend here to support all I/O access types
+ */
+#define SMC_CAN_USE_8BIT       1
 #define SMC_CAN_USE_16BIT      1
-#define SMC_CAN_USE_32BIT      0
+#define SMC_CAN_USE_32BIT      1
 #define SMC_NOWAIT             1
 
-/* The first two address lines aren't connected... */
-#define SMC_IO_SHIFT           2
+#define SMC_IO_SHIFT           (lp->io_shift)
 
+#define SMC_inb(a, r)          readb((a) + (r))
 #define SMC_inw(a, r)          readw((a) + (r))
-#define SMC_outw(v, a, r)      writew(v, (a) + (r))
+#define SMC_inl(a, r)          readl((a) + (r))
+#define SMC_outb(v, a, r)      writeb(v, (a) + (r))
+#define SMC_outl(v, a, r)      writel(v, (a) + (r))
 #define SMC_insw(a, r, p, l)   readsw((a) + (r), p, l)
 #define SMC_outsw(a, r, p, l)  writesw((a) + (r), p, l)
+#define SMC_insl(a, r, p, l)   readsl((a) + (r), p, l)
+#define SMC_outsl(a, r, p, l)  writesl((a) + (r), p, l)
 #define SMC_IRQ_FLAGS          (-1)    /* from resource */
 
+/* We actually can't write halfwords properly if not word aligned */
+static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg)
+{
+       if (machine_is_mainstone() && reg & 2) {
+               unsigned int v = val << 16;
+               v |= readl(ioaddr + (reg & ~2)) & 0xffff;
+               writel(v, ioaddr + (reg & ~2));
+       } else {
+               writew(val, ioaddr + reg);
+       }
+}
+
 #elif defined(CONFIG_BLACKFIN)
 
 #define SMC_IRQ_FLAGS          IRQF_TRIGGER_HIGH
 #define SMC_outsw(a, r, p, l)  writesw((a) + (r), p, l)
 
 #elif  defined(CONFIG_ARCH_INNOKOM) || \
-       defined(CONFIG_MACH_MAINSTONE) || \
        defined(CONFIG_ARCH_PXA_IDP) || \
        defined(CONFIG_ARCH_RAMSES) || \
        defined(CONFIG_ARCH_PCM027)
@@ -229,22 +251,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
        }
 }
 
-#elif defined(CONFIG_MACH_ZYLONITE)
-
-#define SMC_CAN_USE_8BIT        1
-#define SMC_CAN_USE_16BIT       1
-#define SMC_CAN_USE_32BIT       0
-#define SMC_IO_SHIFT            0
-#define SMC_NOWAIT              1
-#define SMC_USE_PXA_DMA                1
-#define SMC_inb(a, r)           readb((a) + (r))
-#define SMC_inw(a, r)           readw((a) + (r))
-#define SMC_insw(a, r, p, l)    insw((a) + (r), p, l)
-#define SMC_outsw(a, r, p, l)   outsw((a) + (r), p, l)
-#define SMC_outb(v, a, r)       writeb(v, (a) + (r))
-#define SMC_outw(v, a, r)       writew(v, (a) + (r))
-#define SMC_IRQ_FLAGS          (-1)    /* from resource */
-
 #elif  defined(CONFIG_ARCH_OMAP)
 
 /* We can only do 16-bit reads and writes in the static memory space. */
@@ -454,7 +460,6 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
 #define RPC_LSA_DEFAULT                RPC_LED_100_10
 #define RPC_LSB_DEFAULT                RPC_LED_TX_RX
 
-#define SMC_DYNAMIC_BUS_CONFIG
 #endif
 
 
@@ -493,7 +498,7 @@ struct smc_local {
 
        spinlock_t lock;
 
-#ifdef SMC_USE_PXA_DMA
+#ifdef CONFIG_ARCH_PXA
        /* DMA needs the physical address of the chip */
        u_long physaddr;
        struct device *device;
@@ -501,20 +506,17 @@ struct smc_local {
        void __iomem *base;
        void __iomem *datacs;
 
+       /* the low address lines on some platforms aren't connected... */
+       int     io_shift;
+
        struct smc91x_platdata cfg;
 };
 
-#ifdef SMC_DYNAMIC_BUS_CONFIG
-#define SMC_8BIT(p) (((p)->cfg.flags & SMC91X_USE_8BIT) && SMC_CAN_USE_8BIT)
-#define SMC_16BIT(p) (((p)->cfg.flags & SMC91X_USE_16BIT) && SMC_CAN_USE_16BIT)
-#define SMC_32BIT(p) (((p)->cfg.flags & SMC91X_USE_32BIT) && SMC_CAN_USE_32BIT)
-#else
-#define SMC_8BIT(p) SMC_CAN_USE_8BIT
-#define SMC_16BIT(p) SMC_CAN_USE_16BIT
-#define SMC_32BIT(p) SMC_CAN_USE_32BIT
-#endif
+#define SMC_8BIT(p)    ((p)->cfg.flags & SMC91X_USE_8BIT)
+#define SMC_16BIT(p)   ((p)->cfg.flags & SMC91X_USE_16BIT)
+#define SMC_32BIT(p)   ((p)->cfg.flags & SMC91X_USE_32BIT)
 
-#ifdef SMC_USE_PXA_DMA
+#ifdef CONFIG_ARCH_PXA
 /*
  * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is
  * always happening in irq context so no need to worry about races.  TX is
@@ -608,7 +610,7 @@ smc_pxa_dma_irq(int dma, void *dummy)
 {
        DCSR(dma) = 0;
 }
-#endif  /* SMC_USE_PXA_DMA */
+#endif  /* CONFIG_ARCH_PXA */
 
 
 /*
index 1aa425be306720f6928f06b8b1e97140d73f4492..b79d5f018f798abf59f7822b9def0a483b143cb6 100644 (file)
@@ -2377,8 +2377,6 @@ static void happy_meal_set_multicast(struct net_device *dev)
 
        spin_lock_irq(&hp->happy_lock);
 
-       netif_stop_queue(dev);
-
        if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
                hme_write32(hp, bregs + BMAC_HTABLE0, 0xffff);
                hme_write32(hp, bregs + BMAC_HTABLE1, 0xffff);
@@ -2410,8 +2408,6 @@ static void happy_meal_set_multicast(struct net_device *dev)
                hme_write32(hp, bregs + BMAC_HTABLE3, hash_table[3]);
        }
 
-       netif_wake_queue(dev);
-
        spin_unlock_irq(&hp->happy_lock);
 }
 
index 41d3ac45685f768857392addf61d291737a34f5b..a645e5028c14bcd12053d77b31f4f0cfd7003c9b 100644 (file)
@@ -672,7 +672,6 @@ static void tc_handle_link_change(struct net_device *dev)
                        if (dev->flags & IFF_PROMISC)
                                tc35815_set_multicast_list(dev);
 #endif
-                       netif_tx_schedule_all(dev);
                } else {
                        lp->speed = 0;
                        lp->duplex = -1;
index bc30c6e8fea2c69779746c67b250dc767918453f..617ef41bdfea669b316085ad373802e47a259e8f 100644 (file)
@@ -5514,22 +5514,6 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        netif_wake_queue(dev);                      /* Unlock the TX ring */
        break;
 
-    case DE4X5_SET_PROM:             /* Set Promiscuous Mode */
-       if (!capable(CAP_NET_ADMIN)) return -EPERM;
-       omr = inl(DE4X5_OMR);
-       omr |= OMR_PR;
-       outl(omr, DE4X5_OMR);
-       dev->flags |= IFF_PROMISC;
-       break;
-
-    case DE4X5_CLR_PROM:             /* Clear Promiscuous Mode */
-       if (!capable(CAP_NET_ADMIN)) return -EPERM;
-       omr = inl(DE4X5_OMR);
-       omr &= ~OMR_PR;
-       outl(omr, DE4X5_OMR);
-       dev->flags &= ~IFF_PROMISC;
-       break;
-
     case DE4X5_SAY_BOO:              /* Say "Boo!" to the kernel log file */
        if (!capable(CAP_NET_ADMIN)) return -EPERM;
        printk("%s: Boo!\n", dev->name);
index f5f33b3eb067ad98a4105c41b5a7adea6739ded4..9f2877438fb0067570c622207ca8a369be7e9ae6 100644 (file)
@@ -1004,8 +1004,7 @@ struct de4x5_ioctl {
 */
 #define DE4X5_GET_HWADDR       0x01 /* Get the hardware address */
 #define DE4X5_SET_HWADDR       0x02 /* Set the hardware address */
-#define DE4X5_SET_PROM         0x03 /* Set Promiscuous Mode */
-#define DE4X5_CLR_PROM         0x04 /* Clear Promiscuous Mode */
+/* 0x03 and 0x04 were used before and are obsoleted now. Don't use them. */
 #define DE4X5_SAY_BOO          0x05 /* Say "Boo!" to the kernel log file */
 #define DE4X5_GET_MCA          0x06 /* Get a multicast address */
 #define DE4X5_SET_MCA          0x07 /* Set a multicast address */
index a82b32b401319c0749eac671849e2e2792edca1b..e6bbc639c2d0c8428cc28e29692760f549bf50ce 100644 (file)
@@ -900,7 +900,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
                if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
                        return -EINVAL;
                rtnl_lock();
-               ret = update_filter(&tun->txflt, (void *) __user arg);
+               ret = update_filter(&tun->txflt, (void __user *)arg);
                rtnl_unlock();
                return ret;
 
index 756ba10b79d64cdf8489719db70bd3b012df87ef..8f944e57fd55932e0fcc0b21ba51c6fdb0dc8a84 100644 (file)
@@ -1588,7 +1588,6 @@ static void adjust_link(struct net_device *dev)
                if (!ugeth->oldlink) {
                        new_state = 1;
                        ugeth->oldlink = 1;
-                       netif_tx_schedule_all(dev);
                }
        } else if (ugeth->oldlink) {
                        new_state = 1;
index a934428a5890ba26adf4df7e00588d57a08ef786..0e061dfea78d15226e65da13e5aa1f764c09bd30 100644 (file)
@@ -50,10 +50,18 @@ static int is_activesync(struct usb_interface_descriptor *desc)
                && desc->bInterfaceProtocol == 1;
 }
 
+static int is_wireless_rndis(struct usb_interface_descriptor *desc)
+{
+       return desc->bInterfaceClass == USB_CLASS_WIRELESS_CONTROLLER
+               && desc->bInterfaceSubClass == 1
+               && desc->bInterfaceProtocol == 3;
+}
+
 #else
 
 #define is_rndis(desc)         0
 #define is_activesync(desc)    0
+#define is_wireless_rndis(desc)        0
 
 #endif
 
@@ -110,7 +118,8 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
         * of cdc-acm, it'll fail RNDIS requests cleanly.
         */
        rndis = is_rndis(&intf->cur_altsetting->desc)
-               || is_activesync(&intf->cur_altsetting->desc);
+               || is_activesync(&intf->cur_altsetting->desc)
+               || is_wireless_rndis(&intf->cur_altsetting->desc);
 
        memset(info, 0, sizeof *info);
        info->control = intf;
index 61c98beb4d17d05adb4fc741854f7163fcb84ad4..bcd858c567e04ef30c553d4c17783622a541f3ce 100644 (file)
@@ -576,6 +576,10 @@ static const struct usb_device_id  products [] = {
        /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
        USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
        .driver_info = (unsigned long) &rndis_info,
+}, {
+       /* RNDIS for tethering */
+       USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
+       .driver_info = (unsigned long) &rndis_info,
 },
        { },            // END
 };
index 5827324e9d9f94a2abde26a450c1b4be90c941cf..f7d3349dc3ec8ffcc35707287e4a3127176d9fd5 100644 (file)
@@ -397,9 +397,9 @@ static int __init cosa_init(void)
                err = PTR_ERR(cosa_class);
                goto out_chrdev;
        }
-       for (i=0; i<nr_cards; i++) {
-               device_create(cosa_class, NULL, MKDEV(cosa_major, i), "cosa%d", i);
-       }
+       for (i = 0; i < nr_cards; i++)
+               device_create_drvdata(cosa_class, NULL, MKDEV(cosa_major, i),
+                                     NULL, "cosa%d", i);
        err = 0;
        goto out;
        
index 13d5882f1f2119019781c661765a1bdf98fc0146..3153fe9d7ce09dc32bf8764bc6437569c270ba14 100644 (file)
@@ -3101,6 +3101,7 @@ static void prism2_clear_set_tim_queue(local_info_t *local)
  * This is a natural nesting, which needs a split lock type.
  */
 static struct lock_class_key hostap_netdev_xmit_lock_key;
+static struct lock_class_key hostap_netdev_addr_lock_key;
 
 static void prism2_set_lockdep_class_one(struct net_device *dev,
                                         struct netdev_queue *txq,
@@ -3112,6 +3113,8 @@ static void prism2_set_lockdep_class_one(struct net_device *dev,
 
 static void prism2_set_lockdep_class(struct net_device *dev)
 {
+       lockdep_set_class(&dev->addr_list_lock,
+                         &hostap_netdev_addr_lock_key);
        netdev_for_each_tx_queue(dev, prism2_set_lockdep_class_one, NULL);
 }
 
index 6e704608947c775f9f89267d81667d3fffcac24c..1acfbcd3703c229da68be2ee1f58fc97afcc566e 100644 (file)
@@ -4972,8 +4972,7 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
        }
       done:
        if ((ipw_tx_queue_space(q) > q->low_mark) &&
-           (qindex >= 0) &&
-           (priv->status & STATUS_ASSOCIATED) && netif_running(priv->net_dev))
+           (qindex >= 0))
                netif_wake_queue(priv->net_dev);
        used = q->first_empty - q->last_used;
        if (used < 0)
@@ -10154,14 +10153,8 @@ static  void init_sys_config(struct ipw_sys_config *sys_config)
 
 static int ipw_net_open(struct net_device *dev)
 {
-       struct ipw_priv *priv = ieee80211_priv(dev);
        IPW_DEBUG_INFO("dev->open\n");
-       /* we should be verifying the device is ready to be opened */
-       mutex_lock(&priv->mutex);
-       if (!(priv->status & STATUS_RF_KILL_MASK) &&
-           (priv->status & STATUS_ASSOCIATED))
-               netif_start_queue(dev);
-       mutex_unlock(&priv->mutex);
+       netif_start_queue(dev);
        return 0;
 }
 
@@ -10481,13 +10474,6 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
        IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
        spin_lock_irqsave(&priv->lock, flags);
 
-       if (!(priv->status & STATUS_ASSOCIATED)) {
-               IPW_DEBUG_INFO("Tx attempt while not associated.\n");
-               priv->ieee->stats.tx_carrier_errors++;
-               netif_stop_queue(dev);
-               goto fail_unlock;
-       }
-
 #ifdef CONFIG_IPW2200_PROMISCUOUS
        if (rtap_iface && netif_running(priv->prom_net_dev))
                ipw_handle_promiscuous_tx(priv, txb);
@@ -10499,10 +10485,6 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return ret;
-
-      fail_unlock:
-       spin_unlock_irqrestore(&priv->lock, flags);
-       return 1;
 }
 
 static struct net_device_stats *ipw_net_get_stats(struct net_device *dev)
@@ -10703,13 +10685,6 @@ static void ipw_link_up(struct ipw_priv *priv)
        priv->last_packet_time = 0;
 
        netif_carrier_on(priv->net_dev);
-       if (netif_queue_stopped(priv->net_dev)) {
-               IPW_DEBUG_NOTIF("waking queue\n");
-               netif_wake_queue(priv->net_dev);
-       } else {
-               IPW_DEBUG_NOTIF("starting queue\n");
-               netif_start_queue(priv->net_dev);
-       }
 
        cancel_delayed_work(&priv->request_scan);
        cancel_delayed_work(&priv->request_direct_scan);
@@ -10739,7 +10714,6 @@ static void ipw_link_down(struct ipw_priv *priv)
 {
        ipw_led_link_down(priv);
        netif_carrier_off(priv->net_dev);
-       netif_stop_queue(priv->net_dev);
        notify_wx_assoc_event(priv);
 
        /* Cancel any queued work ... */
@@ -11419,7 +11393,6 @@ static void ipw_down(struct ipw_priv *priv)
        /* Clear all bits but the RF Kill */
        priv->status &= STATUS_RF_KILL_MASK | STATUS_EXIT_PENDING;
        netif_carrier_off(priv->net_dev);
-       netif_stop_queue(priv->net_dev);
 
        ipw_stop_nic(priv);
 
@@ -11522,7 +11495,6 @@ static int ipw_prom_open(struct net_device *dev)
 
        IPW_DEBUG_INFO("prom dev->open\n");
        netif_carrier_off(dev);
-       netif_stop_queue(dev);
 
        if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
                priv->sys_config.accept_all_data_frames = 1;
@@ -11558,7 +11530,6 @@ static int ipw_prom_stop(struct net_device *dev)
 static int ipw_prom_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        IPW_DEBUG_INFO("prom dev->xmit\n");
-       netif_stop_queue(dev);
        return -EOPNOTSUPP;
 }
 
index 913dc9fe08f9a242b35d46412511e34a5c098e81..5816230d58f82505a18b5bd6c93d1481e7cc8c55 100644 (file)
@@ -364,8 +364,7 @@ static void mac80211_hwsim_free(void)
                        struct mac80211_hwsim_data *data;
                        data = hwsim_radios[i]->priv;
                        ieee80211_unregister_hw(hwsim_radios[i]);
-                       if (!IS_ERR(data->dev))
-                               device_unregister(data->dev);
+                       device_unregister(data->dev);
                        ieee80211_free_hw(hwsim_radios[i]);
                }
        }
@@ -437,7 +436,7 @@ static int __init init_mac80211_hwsim(void)
                               "mac80211_hwsim: device_create_drvdata "
                               "failed (%ld)\n", PTR_ERR(data->dev));
                        err = -ENOMEM;
-                       goto failed;
+                       goto failed_drvdata;
                }
                data->dev->driver = &mac80211_hwsim_driver;
 
@@ -461,7 +460,7 @@ static int __init init_mac80211_hwsim(void)
                if (err < 0) {
                        printk(KERN_DEBUG "mac80211_hwsim: "
                               "ieee80211_register_hw failed (%d)\n", err);
-                       goto failed;
+                       goto failed_hw;
                }
 
                printk(KERN_DEBUG "%s: hwaddr %s registered\n",
@@ -479,9 +478,9 @@ static int __init init_mac80211_hwsim(void)
        rtnl_lock();
 
        err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
-       if (err < 0) {
+       if (err < 0)
                goto failed_mon;
-       }
+
 
        err = register_netdevice(hwsim_mon);
        if (err < 0)
@@ -494,7 +493,14 @@ static int __init init_mac80211_hwsim(void)
 failed_mon:
        rtnl_unlock();
        free_netdev(hwsim_mon);
+       mac80211_hwsim_free();
+       return err;
 
+failed_hw:
+       device_unregister(data->dev);
+failed_drvdata:
+       ieee80211_free_hw(hw);
+       hwsim_radios[i] = 0;
 failed:
        mac80211_hwsim_free();
        return err;
index ef671d1a3bf08441719b5f0bda8338648b1d1ee6..902bbe7882158d5c040f8847de1ddb84bad1d0e9 100644 (file)
@@ -92,7 +92,7 @@ struct netfront_info {
         */
        union skb_entry {
                struct sk_buff *skb;
-               unsigned link;
+               unsigned long link;
        } tx_skbs[NET_TX_RING_SIZE];
        grant_ref_t gref_tx_head;
        grant_ref_t grant_tx_ref[NET_TX_RING_SIZE];
@@ -125,6 +125,17 @@ struct netfront_rx_info {
        struct xen_netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
 };
 
+static void skb_entry_set_link(union skb_entry *list, unsigned short id)
+{
+       list->link = id;
+}
+
+static int skb_entry_is_link(const union skb_entry *list)
+{
+       BUILD_BUG_ON(sizeof(list->skb) != sizeof(list->link));
+       return ((unsigned long)list->skb < PAGE_OFFSET);
+}
+
 /*
  * Access macros for acquiring freeing slots in tx_skbs[].
  */
@@ -132,7 +143,7 @@ struct netfront_rx_info {
 static void add_id_to_freelist(unsigned *head, union skb_entry *list,
                               unsigned short id)
 {
-       list[id].link = *head;
+       skb_entry_set_link(&list[id], *head);
        *head = id;
 }
 
@@ -993,7 +1004,7 @@ static void xennet_release_tx_bufs(struct netfront_info *np)
 
        for (i = 0; i < NET_TX_RING_SIZE; i++) {
                /* Skip over entries which are actually freelist references */
-               if ((unsigned long)np->tx_skbs[i].skb < PAGE_OFFSET)
+               if (skb_entry_is_link(&np->tx_skbs[i]))
                        continue;
 
                skb = np->tx_skbs[i].skb;
@@ -1123,7 +1134,7 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev
        /* Initialise tx_skbs as a free chain containing every entry. */
        np->tx_skb_freelist = 0;
        for (i = 0; i < NET_TX_RING_SIZE; i++) {
-               np->tx_skbs[i].link = i+1;
+               skb_entry_set_link(&np->tx_skbs[i], i+1);
                np->grant_tx_ref[i] = GRANT_INVALID_REF;
        }
 
index eecf7cbf4139aca028fd6c57f49c075717bcf8da..5a58b075dd8d0da2f7ae8ae451ded6ea241c0e06 100644 (file)
@@ -36,7 +36,7 @@
 #define _ACPIPHP_H
 
 #include <linux/acpi.h>
-#include <linux/kobject.h>     /* for KOBJ_NAME_LEN */
+#include <linux/kobject.h>
 #include <linux/mutex.h>
 #include <linux/pci_hotplug.h>
 
@@ -51,7 +51,7 @@
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
 
 /* name size which is used for entries in pcihpfs */
-#define SLOT_NAME_SIZE KOBJ_NAME_LEN           /* {_SUN} */
+#define SLOT_NAME_SIZE 20              /* {_SUN} */
 
 struct acpiphp_bridge;
 struct acpiphp_slot;
index 3f7b81c065d25188e17d82665b63575a91c92e19..8d0e60ac849cb5f34e609fdaf9215688091728a7 100644 (file)
@@ -37,7 +37,7 @@
 #include "intel-iommu.h"
 #include <asm/proto.h> /* force_iommu in this header in x86-64*/
 #include <asm/cacheflush.h>
-#include <asm/gart.h>
+#include <asm/iommu.h>
 #include "pci.h"
 
 #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
index 44a46c92b721a2c6d97fe1b795b6e4c0b1656ad6..d00f0e0d84537168c3464d476db3485753924450 100644 (file)
@@ -1123,8 +1123,7 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable)
 }
 
 /**
- * pci_prepare_to_sleep - prepare PCI device for system-wide transition into
- *                        a sleep state
+ * pci_prepare_to_sleep - prepare PCI device for system-wide transition into a sleep state
  * @dev: Device to handle.
  *
  * Choose the power state appropriate for the device depending on whether
@@ -1181,8 +1180,7 @@ int pci_prepare_to_sleep(struct pci_dev *dev)
 }
 
 /**
- * pci_back_from_sleep - turn PCI device on during system-wide transition into
- *                       the working state a sleep state
+ * pci_back_from_sleep - turn PCI device on during system-wide transition into working state
  * @dev: Device to handle.
  *
  * Disable device's sytem wake-up capability and put it into D0.
index e45402adac3f89e233ae1a4ebbcf6e0619e4d2dd..e0f884034c9f0c3fdfc3f1040506bbe2aac378fd 100644 (file)
@@ -219,7 +219,8 @@ config PCMCIA_SA1111
 config PCMCIA_PXA2XX
        tristate "PXA2xx support"
        depends on ARM && ARCH_PXA && PCMCIA
-       depends on ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL || MACH_ARMCORE
+       depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
+                   || MACH_ARMCORE || ARCH_PXA_PALM)
        help
          Say Y here to include support for the PXA2xx PCMCIA controller
 
index 85c6cc931f979760dd3c545762b1dbd6b4a198a1..269a9e913ba2e9464e69494f618525de8b766b44 100644 (file)
@@ -72,4 +72,5 @@ pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK)              += pxa2xx_lubbock.o sa1111_generic.o
 pxa2xx_cs-$(CONFIG_MACH_MAINSTONE)             += pxa2xx_mainstone.o
 pxa2xx_cs-$(CONFIG_PXA_SHARPSL)                        += pxa2xx_sharpsl.o
 pxa2xx_cs-$(CONFIG_MACH_ARMCORE)               += pxa2xx_cm_x270.o
+pxa2xx_cs-$(CONFIG_MACH_PALMTX)                += pxa2xx_palmtx.o
 
index f123fce65f2e19e736fa54cf48958ce34fa8ca14..bb95db7d2b76898bdbd596e25d835d9ba794202b 100644 (file)
@@ -5,83 +5,60 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * Compulab Ltd., 2003, 2007
+ * Compulab Ltd., 2003, 2007, 2008
  * Mike Rapoport <mike@compulab.co.il>
  *
  */
 
-#include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 
-#include <pcmcia/ss.h>
-#include <asm/hardware.h>
 #include <asm/mach-types.h>
-
 #include <asm/arch/pxa-regs.h>
-#include <asm/arch/pxa2xx-gpio.h>
-#include <asm/arch/cm-x270.h>
 
 #include "soc_common.h"
 
+#define GPIO_PCMCIA_S0_CD_VALID        (84)
+#define GPIO_PCMCIA_S0_RDYINT  (82)
+#define GPIO_PCMCIA_RESET      (53)
+
+#define PCMCIA_S0_CD_VALID     IRQ_GPIO(GPIO_PCMCIA_S0_CD_VALID)
+#define PCMCIA_S0_RDYINT       IRQ_GPIO(GPIO_PCMCIA_S0_RDYINT)
+
+
 static struct pcmcia_irqs irqs[] = {
        { 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" },
-       { 1, PCMCIA_S1_CD_VALID, "PCMCIA1 CD" },
 };
 
 static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
-               GPIO_bit(GPIO49_nPWE) |
-               GPIO_bit(GPIO50_nPIOR) |
-               GPIO_bit(GPIO51_nPIOW) |
-               GPIO_bit(GPIO85_nPCE_1) |
-               GPIO_bit(GPIO54_nPCE_2);
-
-       pxa_gpio_mode(GPIO48_nPOE_MD);
-       pxa_gpio_mode(GPIO49_nPWE_MD);
-       pxa_gpio_mode(GPIO50_nPIOR_MD);
-       pxa_gpio_mode(GPIO51_nPIOW_MD);
-       pxa_gpio_mode(GPIO85_nPCE_1_MD);
-       pxa_gpio_mode(GPIO54_nPCE_2_MD);
-       pxa_gpio_mode(GPIO55_nPREG_MD);
-       pxa_gpio_mode(GPIO56_nPWAIT_MD);
-       pxa_gpio_mode(GPIO57_nIOIS16_MD);
-
-       /* Reset signal */
-       pxa_gpio_mode(GPIO53_nPCE_2 | GPIO_OUT);
-       GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
-
-       set_irq_type(PCMCIA_S0_CD_VALID, IRQ_TYPE_EDGE_BOTH);
-       set_irq_type(PCMCIA_S1_CD_VALID, IRQ_TYPE_EDGE_BOTH);
-
-       /* irq's for slots: */
-       set_irq_type(PCMCIA_S0_RDYINT, IRQ_TYPE_EDGE_FALLING);
-       set_irq_type(PCMCIA_S1_RDYINT, IRQ_TYPE_EDGE_FALLING);
-
-       skt->irq = (skt->nr == 0) ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
-       return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+       int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
+       if (ret)
+               return ret;
+       gpio_direction_output(GPIO_PCMCIA_RESET, 0);
+
+       skt->irq = PCMCIA_S0_RDYINT;
+       ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+       if (!ret)
+               gpio_free(GPIO_PCMCIA_RESET);
+
+       return ret;
 }
 
 static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
 {
        soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
-
-       set_irq_type(IRQ_TO_GPIO(PCMCIA_S0_CD_VALID), IRQ_TYPE_NONE);
-       set_irq_type(IRQ_TO_GPIO(PCMCIA_S1_CD_VALID), IRQ_TYPE_NONE);
-
-       set_irq_type(IRQ_TO_GPIO(PCMCIA_S0_RDYINT), IRQ_TYPE_NONE);
-       set_irq_type(IRQ_TO_GPIO(PCMCIA_S1_RDYINT), IRQ_TYPE_NONE);
+       gpio_free(GPIO_PCMCIA_RESET);
 }
 
 
 static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                       struct pcmcia_state *state)
 {
-       state->detect = (PCC_DETECT(skt->nr) == 0) ? 1 : 0;
-       state->ready  = (PCC_READY(skt->nr) == 0) ? 0 : 1;
+       state->detect = (gpio_get_value(GPIO_PCMCIA_S0_CD_VALID) == 0) ? 1 : 0;
+       state->ready  = (gpio_get_value(GPIO_PCMCIA_S0_RDYINT) == 0) ? 0 : 1;
        state->bvd1   = 1;
        state->bvd2   = 1;
        state->vs_3v  = 0;
@@ -93,32 +70,16 @@ static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 static int cmx270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
                                          const socket_state_t *state)
 {
-       GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
-       pxa_gpio_mode(GPIO49_nPWE | GPIO_OUT);
-
        switch (skt->nr) {
        case 0:
                if (state->flags & SS_RESET) {
-                       GPCR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
-                       GPSR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
-                       udelay(10);
-                       GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
-                       GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
-               }
-               break;
-       case 1:
-               if (state->flags & SS_RESET) {
-                       GPCR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
-                       GPSR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
+                       gpio_set_value(GPIO_PCMCIA_RESET, 1);
                        udelay(10);
-                       GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
-                       GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
+                       gpio_set_value(GPIO_PCMCIA_RESET, 0);
                }
                break;
        }
 
-       pxa_gpio_mode(GPIO49_nPWE_MD);
-
        return 0;
 }
 
@@ -139,7 +100,7 @@ static struct pcmcia_low_level cmx270_pcmcia_ops __initdata = {
        .configure_socket       = cmx270_pcmcia_configure_socket,
        .socket_init            = cmx270_pcmcia_socket_init,
        .socket_suspend         = cmx270_pcmcia_socket_suspend,
-       .nr                     = 2,
+       .nr                     = 1,
 };
 
 static struct platform_device *cmx270_pcmcia_device;
diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c
new file mode 100644 (file)
index 0000000..4abde19
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * linux/drivers/pcmcia/pxa2xx_palmtx.c
+ *
+ * Driver for Palm T|X PCMCIA
+ *
+ * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/palmtx.h>
+
+#include "soc_common.h"
+
+static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+       skt->irq = IRQ_GPIO(GPIO_NR_PALMTX_PCMCIA_READY);
+       return 0;
+}
+
+static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+                                       struct pcmcia_state *state)
+{
+       state->detect = 1; /* always inserted */
+       state->ready  = !!gpio_get_value(GPIO_NR_PALMTX_PCMCIA_READY);
+       state->bvd1   = 1;
+       state->bvd2   = 1;
+       state->wrprot = 0;
+       state->vs_3v  = 1;
+       state->vs_Xv  = 0;
+}
+
+static int
+palmtx_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+                               const socket_state_t *state)
+{
+       gpio_set_value(GPIO_NR_PALMTX_PCMCIA_POWER1, 1);
+       gpio_set_value(GPIO_NR_PALMTX_PCMCIA_POWER2, 1);
+       gpio_set_value(GPIO_NR_PALMTX_PCMCIA_RESET,
+                       !!(state->flags & SS_RESET));
+
+       return 0;
+}
+
+static void palmtx_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void palmtx_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+static struct pcmcia_low_level palmtx_pcmcia_ops = {
+       .owner                  = THIS_MODULE,
+
+       .first                  = 0,
+       .nr                     = 1,
+
+       .hw_init                = palmtx_pcmcia_hw_init,
+       .hw_shutdown            = palmtx_pcmcia_hw_shutdown,
+
+       .socket_state           = palmtx_pcmcia_socket_state,
+       .configure_socket       = palmtx_pcmcia_configure_socket,
+
+       .socket_init            = palmtx_pcmcia_socket_init,
+       .socket_suspend         = palmtx_pcmcia_socket_suspend,
+};
+
+static struct platform_device *palmtx_pcmcia_device;
+
+static int __init palmtx_pcmcia_init(void)
+{
+       int ret;
+
+       if (!machine_is_palmtx())
+               return -ENODEV;
+
+       palmtx_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+       if (!palmtx_pcmcia_device)
+               return -ENOMEM;
+
+       ret = platform_device_add_data(palmtx_pcmcia_device, &palmtx_pcmcia_ops,
+                                       sizeof(palmtx_pcmcia_ops));
+
+       if (!ret)
+               ret = platform_device_add(palmtx_pcmcia_device);
+
+       if (ret)
+               platform_device_put(palmtx_pcmcia_device);
+
+       return ret;
+}
+
+static void __exit palmtx_pcmcia_exit(void)
+{
+       platform_device_unregister(palmtx_pcmcia_device);
+}
+
+fs_initcall(palmtx_pcmcia_init);
+module_exit(palmtx_pcmcia_exit);
+
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("PCMCIA support for Palm T|X");
+MODULE_ALIAS("platform:pxa2xx-pcmcia");
+MODULE_LICENSE("GPL");
index 58c806e9c58a2a941578fe9a629d0187b8ea777b..4d17d384578d7214ccbd08cac71d5b9c8a1809b1 100644 (file)
@@ -49,4 +49,10 @@ config BATTERY_OLPC
        help
          Say Y to enable support for the battery on the OLPC laptop.
 
+config BATTERY_PALMTX
+       tristate "Palm T|X battery"
+       depends on MACH_PALMTX
+       help
+         Say Y to enable support for the battery in Palm T|X.
+
 endif # POWER_SUPPLY
index 6413ded5fe5f26d3912af3ff75b324950e2ce12c..6f43a54ee420228dad366db38c71e0777d9f37cf 100644 (file)
@@ -20,3 +20,4 @@ obj-$(CONFIG_APM_POWER)               += apm_power.o
 obj-$(CONFIG_BATTERY_DS2760)   += ds2760_battery.o
 obj-$(CONFIG_BATTERY_PMU)      += pmu_battery.o
 obj-$(CONFIG_BATTERY_OLPC)     += olpc_battery.o
+obj-$(CONFIG_BATTERY_PALMTX)   += palmtx_battery.o
index a4892275659dc02ffb1d12b85d0774a86bda8b08..936bae560fa1f730255bde8a94c9493c953efdfd 100644 (file)
@@ -78,7 +78,7 @@ static void find_main_battery(void)
        main_battery = NULL;
        bp.main = main_battery;
 
-       error = class_for_each_device(power_supply_class, &bp,
+       error = class_for_each_device(power_supply_class, NULL, &bp,
                                      __find_main_battery);
        if (error) {
                main_battery = bp.main;
diff --git a/drivers/power/palmtx_battery.c b/drivers/power/palmtx_battery.c
new file mode 100644 (file)
index 0000000..244bb27
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * linux/drivers/power/palmtx_battery.c
+ *
+ * Battery measurement code for Palm T|X Handheld computer
+ *
+ * based on tosa_battery.c
+ *
+ * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/power_supply.h>
+#include <linux/wm97xx.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/arch/palmtx.h>
+
+static DEFINE_MUTEX(bat_lock);
+static struct work_struct bat_work;
+struct mutex work_lock;
+int bat_status = POWER_SUPPLY_STATUS_DISCHARGING;
+
+static unsigned long palmtx_read_bat(struct power_supply *bat_ps)
+{
+       return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
+                                   WM97XX_AUX_ID3) * 1000 / 414;
+}
+
+static unsigned long palmtx_read_temp(struct power_supply *bat_ps)
+{
+       return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
+                                   WM97XX_AUX_ID2);
+}
+
+static int palmtx_bat_get_property(struct power_supply *bat_ps,
+                           enum power_supply_property psp,
+                           union power_supply_propval *val)
+{
+       switch (psp) {
+       case POWER_SUPPLY_PROP_STATUS:
+               val->intval = bat_status;
+               break;
+       case POWER_SUPPLY_PROP_TECHNOLOGY:
+               val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO;
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+               val->intval = palmtx_read_bat(bat_ps);
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+       case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+               val->intval = PALMTX_BAT_MAX_VOLTAGE;
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+               val->intval = PALMTX_BAT_MIN_VOLTAGE;
+               break;
+       case POWER_SUPPLY_PROP_TEMP:
+               val->intval = palmtx_read_temp(bat_ps);
+               break;
+       case POWER_SUPPLY_PROP_PRESENT:
+               val->intval = 1;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static void palmtx_bat_external_power_changed(struct power_supply *bat_ps)
+{
+       schedule_work(&bat_work);
+}
+
+static char *status_text[] = {
+       [POWER_SUPPLY_STATUS_UNKNOWN] =         "Unknown",
+       [POWER_SUPPLY_STATUS_CHARGING] =        "Charging",
+       [POWER_SUPPLY_STATUS_DISCHARGING] =     "Discharging",
+};
+
+static void palmtx_bat_update(struct power_supply *bat_ps)
+{
+       int old_status = bat_status;
+
+       mutex_lock(&work_lock);
+
+       bat_status = gpio_get_value(GPIO_NR_PALMTX_POWER_DETECT) ?
+                                   POWER_SUPPLY_STATUS_CHARGING :
+                                   POWER_SUPPLY_STATUS_DISCHARGING;
+
+       if (old_status != bat_status) {
+               pr_debug("%s %s -> %s\n", bat_ps->name,
+                               status_text[old_status],
+                               status_text[bat_status]);
+               power_supply_changed(bat_ps);
+       }
+
+       mutex_unlock(&work_lock);
+}
+
+static enum power_supply_property palmtx_bat_main_props[] = {
+       POWER_SUPPLY_PROP_STATUS,
+       POWER_SUPPLY_PROP_TECHNOLOGY,
+       POWER_SUPPLY_PROP_VOLTAGE_NOW,
+       POWER_SUPPLY_PROP_VOLTAGE_MAX,
+       POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+       POWER_SUPPLY_PROP_TEMP,
+       POWER_SUPPLY_PROP_PRESENT,
+};
+
+struct power_supply bat_ps = {
+       .name                   = "main-battery",
+       .type                   = POWER_SUPPLY_TYPE_BATTERY,
+       .properties             = palmtx_bat_main_props,
+       .num_properties         = ARRAY_SIZE(palmtx_bat_main_props),
+       .get_property           = palmtx_bat_get_property,
+       .external_power_changed = palmtx_bat_external_power_changed,
+       .use_for_apm            = 1,
+};
+
+static void palmtx_bat_work(struct work_struct *work)
+{
+       palmtx_bat_update(&bat_ps);
+}
+
+#ifdef CONFIG_PM
+static int palmtx_bat_suspend(struct platform_device *dev, pm_message_t state)
+{
+       flush_scheduled_work();
+       return 0;
+}
+
+static int palmtx_bat_resume(struct platform_device *dev)
+{
+       schedule_work(&bat_work);
+       return 0;
+}
+#else
+#define palmtx_bat_suspend NULL
+#define palmtx_bat_resume NULL
+#endif
+
+static int __devinit palmtx_bat_probe(struct platform_device *dev)
+{
+       int ret = 0;
+
+       if (!machine_is_palmtx())
+               return -ENODEV;
+
+       mutex_init(&work_lock);
+
+       INIT_WORK(&bat_work, palmtx_bat_work);
+
+       ret = power_supply_register(&dev->dev, &bat_ps);
+       if (!ret)
+               schedule_work(&bat_work);
+
+       return ret;
+}
+
+static int __devexit palmtx_bat_remove(struct platform_device *dev)
+{
+       power_supply_unregister(&bat_ps);
+       return 0;
+}
+
+static struct platform_driver palmtx_bat_driver = {
+       .driver.name    = "wm97xx-battery",
+       .driver.owner   = THIS_MODULE,
+       .probe          = palmtx_bat_probe,
+       .remove         = __devexit_p(palmtx_bat_remove),
+       .suspend        = palmtx_bat_suspend,
+       .resume         = palmtx_bat_resume,
+};
+
+static int __init palmtx_bat_init(void)
+{
+       return platform_driver_register(&palmtx_bat_driver);
+}
+
+static void __exit palmtx_bat_exit(void)
+{
+       platform_driver_unregister(&palmtx_bat_driver);
+}
+
+module_init(palmtx_bat_init);
+module_exit(palmtx_bat_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("Palm T|X battery driver");
index af1633eb3b707c9c53c50e578f0ed5859ee69d96..cb1ccb4729210c1a3cfd8901bf7dea5c56117146 100644 (file)
@@ -41,7 +41,7 @@ static void power_supply_changed_work(struct work_struct *work)
 
        dev_dbg(psy->dev, "%s\n", __func__);
 
-       class_for_each_device(power_supply_class, psy,
+       class_for_each_device(power_supply_class, NULL, psy,
                              __power_supply_changed_work);
 
        power_supply_update_leds(psy);
@@ -79,7 +79,7 @@ int power_supply_am_i_supplied(struct power_supply *psy)
 {
        int error;
 
-       error = class_for_each_device(power_supply_class, psy,
+       error = class_for_each_device(power_supply_class, NULL, psy,
                                      __power_supply_am_i_supplied);
 
        dev_dbg(psy->dev, "%s %d\n", __func__, error);
index 58b7336640ff7a1559263798f46e9d7912f09088..d397fa5f3a91ab650f890aef8d1e59fc5d3005b8 100644 (file)
@@ -345,7 +345,7 @@ struct rtc_device *rtc_class_open(char *name)
        struct device *dev;
        struct rtc_device *rtc = NULL;
 
-       dev = class_find_device(rtc_class, name, __rtc_match);
+       dev = class_find_device(rtc_class, NULL, name, __rtc_match);
        if (dev)
                rtc = to_rtc_device(dev);
 
index 81a96e019080bf591ab68e3dee40b593ab2ff9f8..c3dee900a5c8b84608ef868ab73d4d0df0206cf3 100644 (file)
@@ -1168,17 +1168,19 @@ static int raw3270_create_attributes(struct raw3270 *rp)
        if (rc)
                goto out;
 
-       rp->clttydev = device_create(class3270, &rp->cdev->dev,
-                                    MKDEV(IBM_TTY3270_MAJOR, rp->minor),
-                                    "tty%s", rp->cdev->dev.bus_id);
+       rp->clttydev = device_create_drvdata(class3270, &rp->cdev->dev,
+                                            MKDEV(IBM_TTY3270_MAJOR, rp->minor),
+                                            NULL,
+                                            "tty%s", rp->cdev->dev.bus_id);
        if (IS_ERR(rp->clttydev)) {
                rc = PTR_ERR(rp->clttydev);
                goto out_ttydev;
        }
 
-       rp->cltubdev = device_create(class3270, &rp->cdev->dev,
-                                    MKDEV(IBM_FS3270_MAJOR, rp->minor),
-                                    "tub%s", rp->cdev->dev.bus_id);
+       rp->cltubdev = device_create_drvdata(class3270, &rp->cdev->dev,
+                                            MKDEV(IBM_FS3270_MAJOR, rp->minor),
+                                            NULL,
+                                            "tub%s", rp->cdev->dev.bus_id);
        if (!IS_ERR(rp->cltubdev))
                goto out;
 
index 6dfdb7c179819a121e8514db89daf6eb35811f8c..12c2a5aaf31b47e88587957b7f31cb6a24edff7b 100644 (file)
@@ -69,10 +69,9 @@ struct tape_class_device *register_tape_dev(
        if (rc)
                goto fail_with_cdev;
 
-       tcd->class_device = device_create(tape_class, device,
-                                         tcd->char_device->dev,
-                                         "%s", tcd->device_name
-                       );
+       tcd->class_device = device_create_drvdata(tape_class, device,
+                                                 tcd->char_device->dev,
+                                                 NULL, "%s", tcd->device_name);
        rc = IS_ERR(tcd->class_device) ? PTR_ERR(tcd->class_device) : 0;
        if (rc)
                goto fail_with_cdev;
index b0ac44b271270e31db9e5b689c7802175f6dc0ec..c1f352b84868c16affd93a7ff7af1f162527eb2b 100644 (file)
@@ -896,8 +896,9 @@ static int ur_set_online(struct ccw_device *cdev)
                goto fail_free_cdev;
        }
 
-       urd->device = device_create(vmur_class, NULL, urd->char_device->dev,
-                                       "%s", node_id);
+       urd->device = device_create_drvdata(vmur_class, NULL,
+                                           urd->char_device->dev, NULL,
+                                           "%s", node_id);
        if (IS_ERR(urd->device)) {
                rc = PTR_ERR(urd->device);
                TRACE("ur_set_online: device_create rc=%d\n", rc);
index c644669a75c283278f023697b91c54d44d0f63ec..a08b1682c8e852c216c0a6beafab2138f00a0d78 100644 (file)
  *    1.10  Changes for Buffer allocation
  *    1.15  Changed for 2.6 Kernel  No longer compiles on 2.4 or lower
  *    1.25  Added Packing support
+ *    1.5
  */
 #include <asm/ccwdev.h>
 #include <asm/ccwgroup.h>
 #include <asm/debug.h>
 #include <asm/idals.h>
 #include <asm/io.h>
-
 #include <linux/bitops.h>
 #include <linux/ctype.h>
 #include <linux/delay.h>
 #include "cu3088.h"
 #include "claw.h"
 
-MODULE_AUTHOR("Andy Richter <richtera@us.ibm.com>");
-MODULE_DESCRIPTION("Linux for zSeries CLAW Driver\n" \
-                       "Copyright 2000,2005 IBM Corporation\n");
-MODULE_LICENSE("GPL");
-
-/* Debugging is based on DEBUGMSG, IOTRACE, or FUNCTRACE  options:
-   DEBUGMSG  - Enables output of various debug messages in the code
-   IOTRACE   - Enables output of CCW and other IO related traces
-   FUNCTRACE - Enables output of function entry/exit trace
-   Define any combination of above options to enable tracing
-
-   CLAW also uses the s390dbf file system  see claw_trace and claw_setup
+/*
+   CLAW uses the s390dbf file system  see claw_trace and claw_setup
 */
 
-/* following enables tracing */
-//#define DEBUGMSG
-//#define IOTRACE
-//#define FUNCTRACE
-
-#ifdef DEBUGMSG
-#define DEBUG
-#endif
-
-#ifdef IOTRACE
-#define DEBUG
-#endif
-
-#ifdef FUNCTRACE
-#define DEBUG
-#endif
 
 static char debug_buffer[255];
 /**
@@ -146,7 +120,6 @@ claw_register_debug_facility(void)
        claw_dbf_setup = debug_register("claw_setup", 2, 1, 8);
        claw_dbf_trace = debug_register("claw_trace", 2, 2, 8);
        if (claw_dbf_setup == NULL || claw_dbf_trace == NULL) {
-               printk(KERN_WARNING "Not enough memory for debug facility.\n");
                claw_unregister_debug_facility();
                return -ENOMEM;
        }
@@ -232,9 +205,6 @@ static void probe_error( struct ccwgroup_device *cgdev);
 static struct net_device_stats *claw_stats(struct net_device *dev);
 static int pages_to_order_of_mag(int num_of_pages);
 static struct sk_buff *claw_pack_skb(struct claw_privbk *privptr);
-#ifdef DEBUG
-static void dumpit (char *buf, int len);
-#endif
 /* sysfs Functions */
 static ssize_t claw_hname_show(struct device *dev, struct device_attribute *attr, char *buf);
 static ssize_t claw_hname_write(struct device *dev, struct device_attribute *attr,
@@ -263,12 +233,12 @@ static int claw_snd_disc(struct net_device *dev, struct clawctl * p_ctl);
 static int claw_snd_sys_validate_rsp(struct net_device *dev,
         struct clawctl * p_ctl, __u32 return_code);
 static int claw_strt_conn_req(struct net_device *dev );
-static void claw_strt_read ( struct net_device *dev, int lock );
-static void claw_strt_out_IO( struct net_device *dev );
-static void claw_free_wrt_buf( struct net_device *dev );
+static void claw_strt_read(struct net_device *dev, int lock);
+static void claw_strt_out_IO(struct net_device *dev);
+static void claw_free_wrt_buf(struct net_device *dev);
 
 /* Functions for unpack reads   */
-static void unpack_read (struct net_device *dev );
+static void unpack_read(struct net_device *dev);
 
 /* ccwgroup table  */
 
@@ -284,7 +254,6 @@ static struct ccwgroup_driver claw_group_driver = {
 };
 
 /*
-*
 *       Key functions
 */
 
@@ -298,23 +267,14 @@ claw_probe(struct ccwgroup_device *cgdev)
        int             rc;
        struct claw_privbk *privptr=NULL;
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s Enter\n",__func__);
-#endif
-       CLAW_DBF_TEXT(2,setup,"probe");
+       CLAW_DBF_TEXT(2, setup, "probe");
        if (!get_device(&cgdev->dev))
                return -ENODEV;
-#ifdef DEBUGMSG
-        printk(KERN_INFO "claw: variable cgdev =\n");
-        dumpit((char *)cgdev, sizeof(struct ccwgroup_device));
-#endif
        privptr = kzalloc(sizeof(struct claw_privbk), GFP_KERNEL);
        if (privptr == NULL) {
                probe_error(cgdev);
                put_device(&cgdev->dev);
-               printk(KERN_WARNING "Out of memory %s %s Exit Line %d \n",
-                       cgdev->cdev[0]->dev.bus_id,__func__,__LINE__);
-               CLAW_DBF_TEXT_(2,setup,"probex%d",-ENOMEM);
+               CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM);
                return -ENOMEM;
        }
        privptr->p_mtc_envelope= kzalloc( MAX_ENVELOPE_SIZE, GFP_KERNEL);
@@ -322,9 +282,7 @@ claw_probe(struct ccwgroup_device *cgdev)
         if ((privptr->p_mtc_envelope==NULL) || (privptr->p_env==NULL)) {
                 probe_error(cgdev);
                put_device(&cgdev->dev);
-               printk(KERN_WARNING "Out of memory %s %s Exit Line %d \n",
-                       cgdev->cdev[0]->dev.bus_id,__func__,__LINE__);
-               CLAW_DBF_TEXT_(2,setup,"probex%d",-ENOMEM);
+               CLAW_DBF_TEXT_(2, setup, "probex%d", -ENOMEM);
                 return -ENOMEM;
         }
        memcpy(privptr->p_env->adapter_name,WS_NAME_NOT_DEF,8);
@@ -341,19 +299,14 @@ claw_probe(struct ccwgroup_device *cgdev)
                put_device(&cgdev->dev);
                printk(KERN_WARNING "add_files failed %s %s Exit Line %d \n",
                        cgdev->cdev[0]->dev.bus_id,__func__,__LINE__);
-               CLAW_DBF_TEXT_(2,setup,"probex%d",rc);
+               CLAW_DBF_TEXT_(2, setup, "probex%d", rc);
                return rc;
        }
-       printk(KERN_INFO "claw: sysfs files added for %s\n",cgdev->cdev[0]->dev.bus_id);
        privptr->p_env->p_priv = privptr;
         cgdev->cdev[0]->handler = claw_irq_handler;
        cgdev->cdev[1]->handler = claw_irq_handler;
        cgdev->dev.driver_data = privptr;
-#ifdef FUNCTRACE
-        printk(KERN_INFO "claw:%s exit on line %d, "
-               "rc = 0\n",__func__,__LINE__);
-#endif
-       CLAW_DBF_TEXT(2,setup,"prbext 0");
+       CLAW_DBF_TEXT(2, setup, "prbext 0");
 
         return 0;
 }  /*  end of claw_probe       */
@@ -370,37 +323,18 @@ claw_tx(struct sk_buff *skb, struct net_device *dev)
        unsigned long saveflags;
         struct chbk *p_ch;
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s enter\n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"claw_tx");
+       CLAW_DBF_TEXT(4, trace, "claw_tx");
         p_ch=&privptr->channel[WRITE];
         if (skb == NULL) {
-                printk(KERN_WARNING "%s: null pointer passed as sk_buffer\n",
-                       dev->name);
                 privptr->stats.tx_dropped++;
-#ifdef FUNCTRACE
-                printk(KERN_INFO "%s: %s() exit on line %d, rc = EIO\n",
-                       dev->name,__func__, __LINE__);
-#endif
-               CLAW_DBF_TEXT_(2,trace,"clawtx%d",-EIO);
+               privptr->stats.tx_errors++;
+               CLAW_DBF_TEXT_(2, trace, "clawtx%d", -EIO);
                 return -EIO;
         }
-
-#ifdef IOTRACE
-        printk(KERN_INFO "%s: variable sk_buff=\n",dev->name);
-        dumpit((char *) skb, sizeof(struct sk_buff));
-        printk(KERN_INFO "%s: variable dev=\n",dev->name);
-        dumpit((char *) dev, sizeof(struct net_device));
-#endif
         spin_lock_irqsave(get_ccwdev_lock(p_ch->cdev), saveflags);
         rc=claw_hw_tx( skb, dev, 1 );
         spin_unlock_irqrestore(get_ccwdev_lock(p_ch->cdev), saveflags);
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s:%s exit on line %d, rc = %d\n",
-               dev->name, __func__, __LINE__, rc);
-#endif
-       CLAW_DBF_TEXT_(4,trace,"clawtx%d",rc);
+       CLAW_DBF_TEXT_(4, trace, "clawtx%d", rc);
         return rc;
 }   /*  end of claw_tx */
 
@@ -419,7 +353,7 @@ claw_pack_skb(struct claw_privbk *privptr)
 
        new_skb = NULL;         /* assume no dice */
        pkt_cnt = 0;
-       CLAW_DBF_TEXT(4,trace,"PackSKBe");
+       CLAW_DBF_TEXT(4, trace, "PackSKBe");
        if (!skb_queue_empty(&p_ch->collect_queue)) {
        /* some data */
                held_skb = skb_dequeue(&p_ch->collect_queue);
@@ -457,13 +391,8 @@ claw_pack_skb(struct claw_privbk *privptr)
                                skb_queue_head(&p_ch->collect_queue,held_skb);
                        }
                }
-#ifdef IOTRACE
-               printk(KERN_INFO "%s: %s() Packed %d len %d\n",
-                       p_env->ndev->name,
-                       __func__,pkt_cnt,new_skb->len);
-#endif
        }
-       CLAW_DBF_TEXT(4,trace,"PackSKBx");
+       CLAW_DBF_TEXT(4, trace, "PackSKBx");
        return new_skb;
 }
 
@@ -477,29 +406,12 @@ claw_change_mtu(struct net_device *dev, int new_mtu)
 {
        struct claw_privbk  *privptr=dev->priv;
        int buff_size;
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter  \n",dev->name,__func__);
-#endif
-#ifdef DEBUGMSG
-        printk(KERN_INFO "variable dev =\n");
-        dumpit((char *) dev, sizeof(struct net_device));
-        printk(KERN_INFO "variable new_mtu = %d\n", new_mtu);
-#endif
-       CLAW_DBF_TEXT(4,trace,"setmtu");
+       CLAW_DBF_TEXT(4, trace, "setmtu");
        buff_size = privptr->p_env->write_size;
         if ((new_mtu < 60) || (new_mtu > buff_size)) {
-#ifdef FUNCTRACE
-                printk(KERN_INFO "%s:%s Exit on line %d, rc=EINVAL\n",
-               dev->name,
-               __func__, __LINE__);
-#endif
                 return -EINVAL;
         }
         dev->mtu = new_mtu;
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s:%s Exit on line %d\n",dev->name,
-       __func__, __LINE__);
-#endif
         return 0;
 }  /*   end of claw_change_mtu */
 
@@ -521,24 +433,13 @@ claw_open(struct net_device *dev)
         struct timer_list  timer;
         struct ccwbk *p_buf;
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter  \n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"open");
-       if (!dev || (dev->name[0] == 0x00)) {
-               CLAW_DBF_TEXT(2,trace,"BadDev");
-               printk(KERN_WARNING "claw: Bad device at open failing \n");
-               return -ENODEV;
-       }
+       CLAW_DBF_TEXT(4, trace, "open");
        privptr = (struct claw_privbk *)dev->priv;
         /*   allocate and initialize CCW blocks */
        if (privptr->buffs_alloc == 0) {
                rc=init_ccw_bk(dev);
                if (rc) {
-                       printk(KERN_INFO "%s:%s Exit on line %d, rc=ENOMEM\n",
-                       dev->name,
-                       __func__, __LINE__);
-                       CLAW_DBF_TEXT(2,trace,"openmem");
+                       CLAW_DBF_TEXT(2, trace, "openmem");
                        return -ENOMEM;
                }
        }
@@ -557,7 +458,7 @@ claw_open(struct net_device *dev)
        tasklet_init(&privptr->channel[READ].tasklet, claw_irq_tasklet,
                (unsigned long) &privptr->channel[READ]);
         for ( i = 0; i < 2;  i++) {
-               CLAW_DBF_TEXT_(2,trace,"opn_ch%d",i);
+               CLAW_DBF_TEXT_(2, trace, "opn_ch%d", i);
                 init_waitqueue_head(&privptr->channel[i].wait);
                /* skb_queue_head_init(&p_ch->io_queue); */
                if (i == WRITE)
@@ -595,15 +496,8 @@ claw_open(struct net_device *dev)
            ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) ||
            (((privptr->channel[READ].flag |
                privptr->channel[WRITE].flag) & CLAW_TIMER) != 0x00)) {
-#ifdef DEBUGMSG
-                printk(KERN_INFO "%s: channel problems during open - read:"
-                       " %02x -  write: %02x\n",
-                        dev->name,
-                       privptr->channel[READ].last_dstat,
-                       privptr->channel[WRITE].last_dstat);
-#endif
                 printk(KERN_INFO "%s: remote side is not ready\n", dev->name);
-               CLAW_DBF_TEXT(2,trace,"notrdy");
+               CLAW_DBF_TEXT(2, trace, "notrdy");
 
                 for ( i = 0; i < 2;  i++) {
                         spin_lock_irqsave(
@@ -659,23 +553,14 @@ claw_open(struct net_device *dev)
                 privptr->p_buff_read=NULL;
                 privptr->p_buff_write=NULL;
                 claw_clear_busy(dev);
-#ifdef FUNCTRACE
-                printk(KERN_INFO "%s:%s Exit on line %d, rc=EIO\n",
-               dev->name,__func__,__LINE__);
-#endif
-               CLAW_DBF_TEXT(2,trace,"open EIO");
+               CLAW_DBF_TEXT(2, trace, "open EIO");
                 return -EIO;
         }
 
         /*   Send SystemValidate command */
 
         claw_clear_busy(dev);
-
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s:%s Exit on line %d, rc=0\n",
-               dev->name,__func__,__LINE__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"openok");
+       CLAW_DBF_TEXT(4, trace, "openok");
         return 0;
 }    /*     end of claw_open    */
 
@@ -694,22 +579,14 @@ claw_irq_handler(struct ccw_device *cdev,
         struct claw_env  *p_env;
         struct chbk *p_ch_r=NULL;
 
-
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s enter  \n",__func__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"clawirq");
+       CLAW_DBF_TEXT(4, trace, "clawirq");
         /* Bypass all 'unsolicited interrupts' */
        if (!cdev->dev.driver_data) {
                 printk(KERN_WARNING "claw: unsolicited interrupt for device:"
                        "%s received c-%02x d-%02x\n",
                       cdev->dev.bus_id, irb->scsw.cmd.cstat,
                       irb->scsw.cmd.dstat);
-#ifdef FUNCTRACE
-                printk(KERN_INFO "claw: %s() "
-                       "exit on line %d\n",__func__,__LINE__);
-#endif
-               CLAW_DBF_TEXT(2,trace,"badirq");
+               CLAW_DBF_TEXT(2, trace, "badirq");
                 return;
         }
        privptr = (struct claw_privbk *)cdev->dev.driver_data;
@@ -722,41 +599,25 @@ claw_irq_handler(struct ccw_device *cdev,
        else {
                printk(KERN_WARNING "claw: Can't determine channel for "
                        "interrupt, device %s\n", cdev->dev.bus_id);
-               CLAW_DBF_TEXT(2,trace,"badchan");
+               CLAW_DBF_TEXT(2, trace, "badchan");
                return;
        }
-       CLAW_DBF_TEXT_(4,trace,"IRQCH=%d",p_ch->flag);
+       CLAW_DBF_TEXT_(4, trace, "IRQCH=%d", p_ch->flag);
 
        dev = (struct net_device *) (p_ch->ndev);
         p_env=privptr->p_env;
 
-#ifdef IOTRACE
-        printk(KERN_INFO "%s: interrupt for device: %04x "
-               "received c-%02x d-%02x state-%02x\n",
-              dev->name, p_ch->devno, irb->scsw.cmd.cstat,
-              irb->scsw.cmd.dstat, p_ch->claw_state);
-#endif
-
        /* Copy interruption response block. */
        memcpy(p_ch->irb, irb, sizeof(struct irb));
 
-        /* Check for good subchannel return code, otherwise error message */
+       /* Check for good subchannel return code, otherwise info message */
        if (irb->scsw.cmd.cstat && !(irb->scsw.cmd.cstat & SCHN_STAT_PCI)) {
                 printk(KERN_INFO "%s: subchannel check for device: %04x -"
                        " Sch Stat %02x  Dev Stat %02x CPA - %04x\n",
                         dev->name, p_ch->devno,
                        irb->scsw.cmd.cstat, irb->scsw.cmd.dstat,
                        irb->scsw.cmd.cpa);
-#ifdef IOTRACE
-               dumpit((char *)irb,sizeof(struct irb));
-               dumpit((char *)(unsigned long)irb->scsw.cmd.cpa,
-                       sizeof(struct ccw1));
-#endif
-#ifdef FUNCTRACE
-               printk(KERN_INFO "%s:%s Exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
-               CLAW_DBF_TEXT(2,trace,"chanchk");
+               CLAW_DBF_TEXT(2, trace, "chanchk");
                 /* return; */
         }
 
@@ -768,233 +629,138 @@ claw_irq_handler(struct ccw_device *cdev,
        p_ch->last_dstat = irb->scsw.cmd.dstat;
 
         switch (p_ch->claw_state) {
-                case CLAW_STOP:/* HALT_IO by claw_release (halt sequence) */
-#ifdef DEBUGMSG
-                        printk(KERN_INFO "%s: CLAW_STOP enter\n", dev->name);
-#endif
-                       if (!((p_ch->irb->scsw.cmd.stctl &
-                              SCSW_STCTL_SEC_STATUS) ||
-                           (p_ch->irb->scsw.cmd.stctl ==
-                               SCSW_STCTL_STATUS_PEND) ||
-                           (p_ch->irb->scsw.cmd.stctl ==
-                               (SCSW_STCTL_ALERT_STATUS |
-                                SCSW_STCTL_STATUS_PEND)))) {
-#ifdef FUNCTRACE
-                                printk(KERN_INFO "%s:%s Exit on line %d\n",
-                                       dev->name,__func__,__LINE__);
-#endif
-                                return;
-                        }
-                        wake_up(&p_ch->wait);   /* wake up claw_release */
-
-#ifdef DEBUGMSG
-                        printk(KERN_INFO "%s: CLAW_STOP exit\n", dev->name);
-#endif
-#ifdef FUNCTRACE
-                        printk(KERN_INFO "%s:%s Exit on line %d\n",
-                               dev->name,__func__,__LINE__);
-#endif
-                       CLAW_DBF_TEXT(4,trace,"stop");
-                        return;
-
-                case CLAW_START_HALT_IO: /* HALT_IO issued by claw_open  */
-#ifdef DEBUGMSG
-                        printk(KERN_INFO "%s: process CLAW_STAT_HALT_IO\n",
-                               dev->name);
-#endif
-                       if (!((p_ch->irb->scsw.cmd.stctl &
-                              SCSW_STCTL_SEC_STATUS) ||
-                           (p_ch->irb->scsw.cmd.stctl ==
-                            SCSW_STCTL_STATUS_PEND) ||
-                           (p_ch->irb->scsw.cmd.stctl ==
-                            (SCSW_STCTL_ALERT_STATUS |
-                             SCSW_STCTL_STATUS_PEND)))) {
-#ifdef FUNCTRACE
-                               printk(KERN_INFO "%s:%s Exit on line %d\n",
-                                       dev->name,__func__,__LINE__);
-#endif
-                               CLAW_DBF_TEXT(4,trace,"haltio");
-                                return;
-                        }
-                        if (p_ch->flag == CLAW_READ) {
-                                p_ch->claw_state = CLAW_START_READ;
-                                wake_up(&p_ch->wait); /* wake claw_open (READ)*/
-                        }
+       case CLAW_STOP:/* HALT_IO by claw_release (halt sequence) */
+               if (!((p_ch->irb->scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS) ||
+               (p_ch->irb->scsw.cmd.stctl == SCSW_STCTL_STATUS_PEND) ||
+               (p_ch->irb->scsw.cmd.stctl ==
+               (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND))))
+                       return;
+               wake_up(&p_ch->wait);   /* wake up claw_release */
+               CLAW_DBF_TEXT(4, trace, "stop");
+               return;
+       case CLAW_START_HALT_IO: /* HALT_IO issued by claw_open  */
+               if (!((p_ch->irb->scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS) ||
+               (p_ch->irb->scsw.cmd.stctl == SCSW_STCTL_STATUS_PEND) ||
+               (p_ch->irb->scsw.cmd.stctl ==
+               (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) {
+                       CLAW_DBF_TEXT(4, trace, "haltio");
+                       return;
+               }
+               if (p_ch->flag == CLAW_READ) {
+                       p_ch->claw_state = CLAW_START_READ;
+                       wake_up(&p_ch->wait); /* wake claw_open (READ)*/
+               } else if (p_ch->flag == CLAW_WRITE) {
+                       p_ch->claw_state = CLAW_START_WRITE;
+                       /*      send SYSTEM_VALIDATE                    */
+                       claw_strt_read(dev, LOCK_NO);
+                       claw_send_control(dev,
+                               SYSTEM_VALIDATE_REQUEST,
+                               0, 0, 0,
+                               p_env->host_name,
+                               p_env->adapter_name);
+               } else {
+                       printk(KERN_WARNING "claw: unsolicited "
+                               "interrupt for device:"
+                               "%s received c-%02x d-%02x\n",
+                               cdev->dev.bus_id,
+                               irb->scsw.cmd.cstat,
+                               irb->scsw.cmd.dstat);
+                       return;
+                       }
+               CLAW_DBF_TEXT(4, trace, "haltio");
+               return;
+       case CLAW_START_READ:
+               CLAW_DBF_TEXT(4, trace, "ReadIRQ");
+               if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
+                       clear_bit(0, (void *)&p_ch->IO_active);
+                       if ((p_ch->irb->ecw[0] & 0x41) == 0x41 ||
+                           (p_ch->irb->ecw[0] & 0x40) == 0x40 ||
+                           (p_ch->irb->ecw[0])        == 0) {
+                               privptr->stats.rx_errors++;
+                               printk(KERN_INFO "%s: Restart is "
+                                       "required after remote "
+                                       "side recovers \n",
+                                       dev->name);
+                       }
+                       CLAW_DBF_TEXT(4, trace, "notrdy");
+                       return;
+               }
+               if ((p_ch->irb->scsw.cmd.cstat & SCHN_STAT_PCI) &&
+                       (p_ch->irb->scsw.cmd.dstat == 0)) {
+                       if (test_and_set_bit(CLAW_BH_ACTIVE,
+                               (void *)&p_ch->flag_a) == 0)
+                               tasklet_schedule(&p_ch->tasklet);
                        else
-                          if (p_ch->flag == CLAW_WRITE) {
-                                p_ch->claw_state = CLAW_START_WRITE;
-                                /*      send SYSTEM_VALIDATE                    */
-                                claw_strt_read(dev, LOCK_NO);
-                                       claw_send_control(dev,
-                                       SYSTEM_VALIDATE_REQUEST,
-                                       0, 0, 0,
-                                       p_env->host_name,
-                                       p_env->adapter_name );
-                        } else {
-                               printk(KERN_WARNING "claw: unsolicited "
-                                       "interrupt for device:"
-                                       "%s received c-%02x d-%02x\n",
-                                       cdev->dev.bus_id,
-                                       irb->scsw.cmd.cstat,
-                                       irb->scsw.cmd.dstat);
-                               return;
-                               }
-#ifdef DEBUGMSG
-                        printk(KERN_INFO "%s: process CLAW_STAT_HALT_IO exit\n",
-                               dev->name);
-#endif
-#ifdef FUNCTRACE
-                        printk(KERN_INFO "%s:%s Exit on line %d\n",
-                               dev->name,__func__,__LINE__);
-#endif
-                       CLAW_DBF_TEXT(4,trace,"haltio");
-                        return;
-                case CLAW_START_READ:
-                       CLAW_DBF_TEXT(4,trace,"ReadIRQ");
-                       if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
-                                clear_bit(0, (void *)&p_ch->IO_active);
-                                if ((p_ch->irb->ecw[0] & 0x41) == 0x41 ||
-                                    (p_ch->irb->ecw[0] & 0x40) == 0x40 ||
-                                    (p_ch->irb->ecw[0])        == 0)
-                                {
-                                        privptr->stats.rx_errors++;
-                                        printk(KERN_INFO "%s: Restart is "
-                                               "required after remote "
-                                               "side recovers \n",
-                                               dev->name);
-                                }
-#ifdef FUNCTRACE
-                               printk(KERN_INFO "%s:%s Exit on line %d\n",
-                                       dev->name,__func__,__LINE__);
-#endif
-                                       CLAW_DBF_TEXT(4,trace,"notrdy");
-                                        return;
-                        }
-                       if ((p_ch->irb->scsw.cmd.cstat & SCHN_STAT_PCI) &&
-                           (p_ch->irb->scsw.cmd.dstat == 0)) {
-                                if (test_and_set_bit(CLAW_BH_ACTIVE,
-                                       (void *)&p_ch->flag_a) == 0) {
-                                       tasklet_schedule(&p_ch->tasklet);
-                                }
-                               else {
-                                       CLAW_DBF_TEXT(4,trace,"PCINoBH");
-                               }
-#ifdef FUNCTRACE
-                               printk(KERN_INFO "%s:%s Exit on line %d\n",
-                                       dev->name,__func__,__LINE__);
-#endif
-                               CLAW_DBF_TEXT(4,trace,"PCI_read");
-                                return;
-                        }
-                       if (!((p_ch->irb->scsw.cmd.stctl &
-                              SCSW_STCTL_SEC_STATUS) ||
-                            (p_ch->irb->scsw.cmd.stctl ==
-                             SCSW_STCTL_STATUS_PEND) ||
-                            (p_ch->irb->scsw.cmd.stctl ==
-                             (SCSW_STCTL_ALERT_STATUS |
-                              SCSW_STCTL_STATUS_PEND)))) {
-#ifdef FUNCTRACE
-                               printk(KERN_INFO "%s:%s Exit on line %d\n",
-                                       dev->name,__func__,__LINE__);
-#endif
-                               CLAW_DBF_TEXT(4,trace,"SPend_rd");
-                                return;
-                        }
-                        clear_bit(0, (void *)&p_ch->IO_active);
-                        claw_clearbit_busy(TB_RETRY,dev);
-                        if (test_and_set_bit(CLAW_BH_ACTIVE,
-                               (void *)&p_ch->flag_a) == 0) {
-                               tasklet_schedule(&p_ch->tasklet);
-                         }
-                       else {
-                               CLAW_DBF_TEXT(4,trace,"RdBHAct");
-                       }
-
-#ifdef DEBUGMSG
-                        printk(KERN_INFO "%s: process CLAW_START_READ exit\n",
-                               dev->name);
-#endif
-#ifdef FUNCTRACE
-                       printk(KERN_INFO "%s:%s Exit on line %d\n",
-                               dev->name,__func__,__LINE__);
-#endif
-                       CLAW_DBF_TEXT(4,trace,"RdIRQXit");
-                        return;
-                case CLAW_START_WRITE:
-                       if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
-                                printk(KERN_INFO "%s: Unit Check Occured in "
-                                       "write channel\n",dev->name);
-                                clear_bit(0, (void *)&p_ch->IO_active);
-                                if (p_ch->irb->ecw[0] & 0x80 ) {
-                                        printk(KERN_INFO "%s: Resetting Event "
-                                               "occurred:\n",dev->name);
-                                        init_timer(&p_ch->timer);
-                                        p_ch->timer.function =
-                                               (void *)claw_write_retry;
-                                        p_ch->timer.data = (unsigned long)p_ch;
-                                        p_ch->timer.expires = jiffies + 10*HZ;
-                                        add_timer(&p_ch->timer);
-                                        printk(KERN_INFO "%s: write connection "
-                                               "restarting\n",dev->name);
-                                }
-#ifdef FUNCTRACE
-                               printk(KERN_INFO "%s:%s Exit on line %d\n",
-                                       dev->name,__func__,__LINE__);
-#endif
-                               CLAW_DBF_TEXT(4,trace,"rstrtwrt");
-                                return;
-                        }
-                       if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) {
-                                        clear_bit(0, (void *)&p_ch->IO_active);
-                                        printk(KERN_INFO "%s: Unit Exception "
-                                               "Occured in write channel\n",
-                                               dev->name);
-                        }
-                       if (!((p_ch->irb->scsw.cmd.stctl &
-                              SCSW_STCTL_SEC_STATUS) ||
-                            (p_ch->irb->scsw.cmd.stctl ==
-                             SCSW_STCTL_STATUS_PEND) ||
-                            (p_ch->irb->scsw.cmd.stctl ==
-                             (SCSW_STCTL_ALERT_STATUS |
-                              SCSW_STCTL_STATUS_PEND)))) {
-#ifdef FUNCTRACE
-                               printk(KERN_INFO "%s:%s Exit on line %d\n",
-                                       dev->name,__func__,__LINE__);
-#endif
-                               CLAW_DBF_TEXT(4,trace,"writeUE");
-                                return;
-                        }
-                        clear_bit(0, (void *)&p_ch->IO_active);
-                        if (claw_test_and_setbit_busy(TB_TX,dev)==0) {
-                                claw_write_next(p_ch);
-                                claw_clearbit_busy(TB_TX,dev);
-                                claw_clear_busy(dev);
-                        }
-                        p_ch_r=(struct chbk *)&privptr->channel[READ];
-                        if (test_and_set_bit(CLAW_BH_ACTIVE,
-                                       (void *)&p_ch_r->flag_a) == 0) {
-                               tasklet_schedule(&p_ch_r->tasklet);
-                        }
-
-#ifdef DEBUGMSG
-                        printk(KERN_INFO "%s: process CLAW_START_WRITE exit\n",
-                                dev->name);
-#endif
-#ifdef FUNCTRACE
-                       printk(KERN_INFO "%s:%s Exit on line %d\n",
-                               dev->name,__func__,__LINE__);
-#endif
-                       CLAW_DBF_TEXT(4,trace,"StWtExit");
-                        return;
-                default:
-                        printk(KERN_WARNING "%s: wrong selection code - irq "
-                               "state=%d\n",dev->name,p_ch->claw_state);
-#ifdef FUNCTRACE
-                       printk(KERN_INFO "%s:%s Exit on line %d\n",
-                               dev->name,__func__,__LINE__);
-#endif
-                       CLAW_DBF_TEXT(2,trace,"badIRQ");
-                        return;
+                               CLAW_DBF_TEXT(4, trace, "PCINoBH");
+                       CLAW_DBF_TEXT(4, trace, "PCI_read");
+                       return;
+               }
+               if (!((p_ch->irb->scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS) ||
+                (p_ch->irb->scsw.cmd.stctl == SCSW_STCTL_STATUS_PEND) ||
+                (p_ch->irb->scsw.cmd.stctl ==
+                (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) {
+                       CLAW_DBF_TEXT(4, trace, "SPend_rd");
+                       return;
+               }
+               clear_bit(0, (void *)&p_ch->IO_active);
+               claw_clearbit_busy(TB_RETRY, dev);
+               if (test_and_set_bit(CLAW_BH_ACTIVE,
+                       (void *)&p_ch->flag_a) == 0)
+                       tasklet_schedule(&p_ch->tasklet);
+               else
+                       CLAW_DBF_TEXT(4, trace, "RdBHAct");
+               CLAW_DBF_TEXT(4, trace, "RdIRQXit");
+               return;
+       case CLAW_START_WRITE:
+               if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
+                       printk(KERN_INFO "%s: Unit Check Occured in "
+                               "write channel\n", dev->name);
+                       clear_bit(0, (void *)&p_ch->IO_active);
+                       if (p_ch->irb->ecw[0] & 0x80) {
+                               printk(KERN_INFO "%s: Resetting Event "
+                                       "occurred:\n", dev->name);
+                               init_timer(&p_ch->timer);
+                               p_ch->timer.function =
+                                       (void *)claw_write_retry;
+                               p_ch->timer.data = (unsigned long)p_ch;
+                               p_ch->timer.expires = jiffies + 10*HZ;
+                               add_timer(&p_ch->timer);
+                               printk(KERN_INFO "%s: write connection "
+                                       "restarting\n", dev->name);
+                       }
+                       CLAW_DBF_TEXT(4, trace, "rstrtwrt");
+                       return;
+               }
+               if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) {
+                       clear_bit(0, (void *)&p_ch->IO_active);
+                       printk(KERN_INFO "%s: Unit Exception "
+                              "Occured in write channel\n",
+                              dev->name);
+               }
+               if (!((p_ch->irb->scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS) ||
+               (p_ch->irb->scsw.cmd.stctl == SCSW_STCTL_STATUS_PEND) ||
+               (p_ch->irb->scsw.cmd.stctl ==
+               (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) {
+                       CLAW_DBF_TEXT(4, trace, "writeUE");
+                       return;
+               }
+               clear_bit(0, (void *)&p_ch->IO_active);
+               if (claw_test_and_setbit_busy(TB_TX, dev) == 0) {
+                       claw_write_next(p_ch);
+                       claw_clearbit_busy(TB_TX, dev);
+                       claw_clear_busy(dev);
+               }
+               p_ch_r = (struct chbk *)&privptr->channel[READ];
+               if (test_and_set_bit(CLAW_BH_ACTIVE,
+                       (void *)&p_ch_r->flag_a) == 0)
+                       tasklet_schedule(&p_ch_r->tasklet);
+               CLAW_DBF_TEXT(4, trace, "StWtExit");
+               return;
+       default:
+               printk(KERN_WARNING "%s: wrong selection code - irq "
+                       "state=%d\n", dev->name, p_ch->claw_state);
+               CLAW_DBF_TEXT(2, trace, "badIRQ");
+               return;
         }
 
 }       /*   end of claw_irq_handler    */
@@ -1013,29 +779,11 @@ claw_irq_tasklet ( unsigned long data )
 
        p_ch = (struct chbk *) data;
         dev = (struct net_device *)p_ch->ndev;
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter  \n",dev->name,__func__);
-#endif
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: variable p_ch =\n",dev->name);
-        dumpit((char *) p_ch, sizeof(struct chbk));
-#endif
-       CLAW_DBF_TEXT(4,trace,"IRQtask");
-
+       CLAW_DBF_TEXT(4, trace, "IRQtask");
         privptr = (struct claw_privbk *) dev->priv;
-
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: bh routine - state-%02x\n" ,
-               dev->name, p_ch->claw_state);
-#endif
-
         unpack_read(dev);
         clear_bit(CLAW_BH_ACTIVE, (void *)&p_ch->flag_a);
-       CLAW_DBF_TEXT(4,trace,"TskletXt");
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
+       CLAW_DBF_TEXT(4, trace, "TskletXt");
         return;
 }       /*    end of claw_irq_bh    */
 
@@ -1060,16 +808,7 @@ claw_release(struct net_device *dev)
         privptr = (struct claw_privbk *) dev->priv;
         if (!privptr)
                 return 0;
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter  \n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"release");
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: variable dev =\n",dev->name);
-        dumpit((char *) dev, sizeof(struct net_device));
-       printk(KERN_INFO "Priv Buffalloc %d\n",privptr->buffs_alloc);
-       printk(KERN_INFO "Priv p_buff_ccw = %p\n",&privptr->p_buff_ccw);
-#endif
+       CLAW_DBF_TEXT(4, trace, "release");
         privptr->release_pend=1;
         claw_setbit_busy(TB_STOP,dev);
         for ( i = 1; i >=0 ;  i--) {
@@ -1101,19 +840,15 @@ claw_release(struct net_device *dev)
                privptr->pk_skb = NULL;
        }
        if(privptr->buffs_alloc != 1) {
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
-               CLAW_DBF_TEXT(4,trace,"none2fre");
+               CLAW_DBF_TEXT(4, trace, "none2fre");
                return 0;
        }
-       CLAW_DBF_TEXT(4,trace,"freebufs");
+       CLAW_DBF_TEXT(4, trace, "freebufs");
        if (privptr->p_buff_ccw != NULL) {
                free_pages((unsigned long)privptr->p_buff_ccw,
                        (int)pages_to_order_of_mag(privptr->p_buff_ccw_num));
        }
-       CLAW_DBF_TEXT(4,trace,"freeread");
+       CLAW_DBF_TEXT(4, trace, "freeread");
         if (privptr->p_env->read_size < PAGE_SIZE) {
            if (privptr->p_buff_read != NULL) {
                 free_pages((unsigned long)privptr->p_buff_read,
@@ -1129,7 +864,7 @@ claw_release(struct net_device *dev)
                         p_buf=p_buf->next;
                 }
         }
-        CLAW_DBF_TEXT(4,trace,"freewrit");
+        CLAW_DBF_TEXT(4, trace, "freewrit");
         if (privptr->p_env->write_size < PAGE_SIZE ) {
                 free_pages((unsigned long)privptr->p_buff_write,
                      (int)pages_to_order_of_mag(privptr->p_buff_write_num));
@@ -1143,7 +878,7 @@ claw_release(struct net_device *dev)
                         p_buf=p_buf->next;
                 }
         }
-        CLAW_DBF_TEXT(4,trace,"clearptr");
+        CLAW_DBF_TEXT(4, trace, "clearptr");
        privptr->buffs_alloc = 0;
         privptr->p_buff_ccw=NULL;
         privptr->p_buff_read=NULL;
@@ -1180,18 +915,12 @@ claw_release(struct net_device *dev)
                 dev->name,
                privptr->channel[READ].last_dstat,
                privptr->channel[WRITE].last_dstat);
-                CLAW_DBF_TEXT(2,trace,"badclose");
+                CLAW_DBF_TEXT(2, trace, "badclose");
         }
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"rlsexit");
+       CLAW_DBF_TEXT(4, trace, "rlsexit");
         return 0;
 }      /* end of claw_release     */
 
-
-
 /*-------------------------------------------------------------------*
 *       claw_write_retry                                             *
 *                                                                    *
@@ -1203,32 +932,12 @@ claw_write_retry ( struct chbk *p_ch )
 
         struct net_device  *dev=p_ch->ndev;
 
-
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter\n",dev->name,__func__);
-        printk(KERN_INFO "claw: variable p_ch =\n");
-        dumpit((char *) p_ch, sizeof(struct chbk));
-#endif
-       CLAW_DBF_TEXT(4,trace,"w_retry");
+       CLAW_DBF_TEXT(4, trace, "w_retry");
         if (p_ch->claw_state == CLAW_STOP) {
-#ifdef FUNCTRACE
-               printk(KERN_INFO "%s:%s Exit on line %d\n",
-                       dev->name,__func__,__LINE__);
-#endif
                return;
         }
-#ifdef DEBUGMSG
-        printk( KERN_INFO "%s:%s  state-%02x\n" ,
-               dev->name,
-               __func__,
-               p_ch->claw_state);
-#endif
        claw_strt_out_IO( dev );
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"rtry_xit");
+       CLAW_DBF_TEXT(4, trace, "rtry_xit");
         return;
 }      /* end of claw_write_retry      */
 
@@ -1247,12 +956,7 @@ claw_write_next ( struct chbk * p_ch )
        struct sk_buff *pk_skb;
        int     rc;
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter  \n",p_ch->ndev->name,__func__);
-        printk(KERN_INFO "%s: variable p_ch =\n",p_ch->ndev->name);
-        dumpit((char *) p_ch, sizeof(struct chbk));
-#endif
-       CLAW_DBF_TEXT(4,trace,"claw_wrt");
+       CLAW_DBF_TEXT(4, trace, "claw_wrt");
         if (p_ch->claw_state == CLAW_STOP)
                 return;
         dev = (struct net_device *) p_ch->ndev;
@@ -1272,11 +976,6 @@ claw_write_next ( struct chbk * p_ch )
         if (privptr->p_write_active_first!=NULL) {
                 claw_strt_out_IO(dev);
         }
-
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
         return;
 }      /* end of claw_write_next      */
 
@@ -1288,22 +987,12 @@ claw_write_next ( struct chbk * p_ch )
 static void
 claw_timer ( struct chbk * p_ch )
 {
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Entry\n",p_ch->ndev->name,__func__);
-        printk(KERN_INFO "%s: variable p_ch =\n",p_ch->ndev->name);
-        dumpit((char *) p_ch, sizeof(struct chbk));
-#endif
-       CLAW_DBF_TEXT(4,trace,"timer");
+       CLAW_DBF_TEXT(4, trace, "timer");
         p_ch->flag |= CLAW_TIMER;
         wake_up(&p_ch->wait);
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Exit on line %d\n",
-               p_ch->ndev->name,__func__,__LINE__);
-#endif
         return;
 }      /* end of claw_timer  */
 
-
 /*
 *
 *       functions
@@ -1324,10 +1013,8 @@ pages_to_order_of_mag(int num_of_pages)
 {
        int     order_of_mag=1;         /* assume 2 pages */
        int     nump=2;
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s Enter pages = %d \n",__func__,num_of_pages);
-#endif
-       CLAW_DBF_TEXT_(5,trace,"pages%d",num_of_pages);
+
+       CLAW_DBF_TEXT_(5, trace, "pages%d", num_of_pages);
        if (num_of_pages == 1)   {return 0; }  /* magnitude of 0 = 1 page */
        /* 512 pages = 2Meg on 4k page systems */
        if (num_of_pages >= 512) {return 9; }
@@ -1338,11 +1025,7 @@ pages_to_order_of_mag(int num_of_pages)
          order_of_mag +=1;
        }
        if (order_of_mag > 9) { order_of_mag = 9; }  /* I know it's paranoid */
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s Exit on line %d, order = %d\n",
-       __func__,__LINE__, order_of_mag);
-#endif
-       CLAW_DBF_TEXT_(5,trace,"mag%d",order_of_mag);
+       CLAW_DBF_TEXT_(5, trace, "mag%d", order_of_mag);
        return order_of_mag;
 }
 
@@ -1358,21 +1041,7 @@ add_claw_reads(struct net_device *dev, struct ccwbk* p_first,
         struct claw_privbk *privptr;
         struct ccw1  temp_ccw;
         struct endccw * p_end;
-#ifdef IOTRACE
-        struct ccwbk*  p_buf;
-#endif
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter  \n",dev->name,__func__);
-#endif
-#ifdef DEBUGMSG
-        printk(KERN_INFO "dev\n");
-        dumpit((char *) dev, sizeof(struct net_device));
-        printk(KERN_INFO "p_first\n");
-        dumpit((char *) p_first, sizeof(struct ccwbk));
-        printk(KERN_INFO "p_last\n");
-        dumpit((char *) p_last, sizeof(struct ccwbk));
-#endif
-       CLAW_DBF_TEXT(4,trace,"addreads");
+       CLAW_DBF_TEXT(4, trace, "addreads");
         privptr = dev->priv;
         p_end = privptr->p_end_ccw;
 
@@ -1380,11 +1049,7 @@ add_claw_reads(struct net_device *dev, struct ccwbk* p_first,
         *       to apend the running channel programs
         */
         if ( p_first==NULL) {
-#ifdef FUNCTRACE
-               printk(KERN_INFO "%s:%s Exit on line %d\n",
-                       dev->name,__func__,__LINE__);
-#endif
-               CLAW_DBF_TEXT(4,trace,"addexit");
+               CLAW_DBF_TEXT(4, trace, "addexit");
                 return 0;
         }
 
@@ -1411,21 +1076,11 @@ add_claw_reads(struct net_device *dev, struct ccwbk* p_first,
         }
 
         if ( privptr-> p_read_active_first ==NULL ) {
-#ifdef DEBUGMSG
-                printk(KERN_INFO "%s:%s p_read_active_first == NULL \n",
-                       dev->name,__func__);
-                printk(KERN_INFO "%s:%s Read active first/last changed \n",
-                       dev->name,__func__);
-#endif
                 privptr-> p_read_active_first= p_first;  /*    set new first */
                 privptr-> p_read_active_last = p_last;   /*    set new last  */
         }
         else {
 
-#ifdef DEBUGMSG
-                printk(KERN_INFO "%s:%s Read in progress \n",
-               dev->name,__func__);
-#endif
                 /* set up TIC ccw  */
                 temp_ccw.cda= (__u32)__pa(&p_first->read);
                 temp_ccw.count=0;
@@ -1462,27 +1117,7 @@ add_claw_reads(struct net_device *dev, struct ccwbk* p_first,
                 privptr->p_read_active_last->next = p_first;
                 privptr->p_read_active_last=p_last;
         } /* end of if ( privptr-> p_read_active_first ==NULL)  */
-#ifdef IOTRACE
-       printk(KERN_INFO "%s:%s  dump p_last CCW BK \n",dev->name,__func__);
-        dumpit((char *)p_last, sizeof(struct ccwbk));
-       printk(KERN_INFO "%s:%s  dump p_end CCW BK \n",dev->name,__func__);
-        dumpit((char *)p_end, sizeof(struct endccw));
-
-       printk(KERN_INFO "%s:%s dump p_first CCW BK \n",dev->name,__func__);
-        dumpit((char *)p_first, sizeof(struct ccwbk));
-        printk(KERN_INFO "%s:%s Dump Active CCW chain \n",
-               dev->name,__func__);
-        p_buf=privptr->p_read_active_first;
-        while (p_buf!=NULL) {
-                dumpit((char *)p_buf, sizeof(struct ccwbk));
-                p_buf=p_buf->next;
-        }
-#endif
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"addexit");
+       CLAW_DBF_TEXT(4, trace, "addexit");
         return 0;
 }    /*     end of add_claw_reads   */
 
@@ -1494,44 +1129,29 @@ add_claw_reads(struct net_device *dev, struct ccwbk* p_first,
 static void
 ccw_check_return_code(struct ccw_device *cdev, int return_code)
 {
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s: %s() > enter  \n",
-               cdev->dev.bus_id,__func__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"ccwret");
-#ifdef DEBUGMSG
-        printk(KERN_INFO "variable cdev =\n");
-        dumpit((char *) cdev, sizeof(struct ccw_device));
-        printk(KERN_INFO "variable return_code = %d\n",return_code);
-#endif
+       CLAW_DBF_TEXT(4, trace, "ccwret");
         if (return_code != 0) {
                 switch (return_code) {
-                        case -EBUSY:
-                                printk(KERN_INFO "%s: Busy !\n",
-                                       cdev->dev.bus_id);
-                                break;
-                        case -ENODEV:
-                                printk(KERN_EMERG "%s: Missing device called "
-                                       "for IO ENODEV\n", cdev->dev.bus_id);
-                                break;
-                        case -EIO:
-                                printk(KERN_EMERG "%s: Status pending... EIO \n",
-                                       cdev->dev.bus_id);
-                                break;
-                       case -EINVAL:
-                                printk(KERN_EMERG "%s: Invalid Dev State EINVAL \n",
-                                       cdev->dev.bus_id);
-                                break;
-                        default:
-                                printk(KERN_EMERG "%s: Unknown error in "
+               case -EBUSY: /* BUSY is a transient state no action needed */
+                       break;
+               case -ENODEV:
+                       printk(KERN_EMERG "%s: Missing device called "
+                               "for IO ENODEV\n", cdev->dev.bus_id);
+                       break;
+               case -EIO:
+                       printk(KERN_EMERG "%s: Status pending... EIO \n",
+                               cdev->dev.bus_id);
+                       break;
+               case -EINVAL:
+                       printk(KERN_EMERG "%s: Invalid Dev State EINVAL \n",
+                               cdev->dev.bus_id);
+                       break;
+               default:
+                       printk(KERN_EMERG "%s: Unknown error in "
                                 "Do_IO %d\n",cdev->dev.bus_id, return_code);
-                }
-        }
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s: %s() > exit on line %d\n",
-               cdev->dev.bus_id,__func__,__LINE__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"ccwret");
+               }
+       }
+       CLAW_DBF_TEXT(4, trace, "ccwret");
 }    /*    end of ccw_check_return_code   */
 
 /*-------------------------------------------------------------------*
@@ -1541,173 +1161,46 @@ ccw_check_return_code(struct ccw_device *cdev, int return_code)
 static void
 ccw_check_unit_check(struct chbk * p_ch, unsigned char sense )
 {
-       struct net_device *dev = p_ch->ndev;
-
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s: %s() > enter\n",dev->name,__func__);
-#endif
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: variable dev =\n",dev->name);
-        dumpit((char *)dev, sizeof(struct net_device));
-        printk(KERN_INFO "%s: variable sense =\n",dev->name);
-        dumpit((char *)&sense, 2);
-#endif
-       CLAW_DBF_TEXT(4,trace,"unitchek");
+       struct net_device *ndev = p_ch->ndev;
 
+       CLAW_DBF_TEXT(4, trace, "unitchek");
         printk(KERN_INFO "%s: Unit Check with sense byte:0x%04x\n",
-                dev->name, sense);
+              ndev->name, sense);
 
         if (sense & 0x40) {
                 if (sense & 0x01) {
                         printk(KERN_WARNING "%s: Interface disconnect or "
                                "Selective reset "
-                               "occurred (remote side)\n", dev->name);
+                               "occurred (remote side)\n", ndev->name);
                 }
                 else {
                         printk(KERN_WARNING "%s: System reset occured"
-                               " (remote side)\n", dev->name);
+                               " (remote side)\n", ndev->name);
                 }
         }
         else if (sense & 0x20) {
                 if (sense & 0x04) {
                         printk(KERN_WARNING "%s: Data-streaming "
-                               "timeout)\n", dev->name);
+                               "timeout)\n", ndev->name);
                 }
                 else  {
                         printk(KERN_WARNING "%s: Data-transfer parity"
-                               " error\n", dev->name);
+                               " error\n", ndev->name);
                 }
         }
         else if (sense & 0x10) {
                 if (sense & 0x20) {
                         printk(KERN_WARNING "%s: Hardware malfunction "
-                               "(remote side)\n", dev->name);
+                               "(remote side)\n", ndev->name);
                 }
                 else {
                         printk(KERN_WARNING "%s: read-data parity error "
-                               "(remote side)\n", dev->name);
+                               "(remote side)\n", ndev->name);
                 }
         }
 
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s: %s() exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
 }   /*    end of ccw_check_unit_check    */
 
-
-
-/*-------------------------------------------------------------------*
-* Dump buffer format                                                 *
-*                                                                    *
-*--------------------------------------------------------------------*/
-#ifdef DEBUG
-static void
-dumpit(char* buf, int len)
-{
-
-        __u32      ct, sw, rm, dup;
-        char       *ptr, *rptr;
-        char       tbuf[82], tdup[82];
-#if (CONFIG_64BIT)
-        char       addr[22];
-#else
-        char       addr[12];
-#endif
-        char       boff[12];
-        char       bhex[82], duphex[82];
-        char       basc[40];
-
-        sw  = 0;
-        rptr =ptr=buf;
-        rm  = 16;
-        duphex[0]  = 0x00;
-        dup = 0;
-        for ( ct=0; ct < len; ct++, ptr++, rptr++ )  {
-                if (sw == 0) {
-#if (CONFIG_64BIT)
-                        sprintf(addr, "%16.16lX",(unsigned long)rptr);
-#else
-                        sprintf(addr, "%8.8X",(__u32)rptr);
-#endif
-                        sprintf(boff, "%4.4X", (__u32)ct);
-                        bhex[0] = '\0';
-                        basc[0] = '\0';
-                }
-                if ((sw == 4) || (sw == 12)) {
-                        strcat(bhex, " ");
-                }
-                if (sw == 8) {
-                        strcat(bhex, "  ");
-                }
-#if (CONFIG_64BIT)
-                sprintf(tbuf,"%2.2lX", (unsigned long)*ptr);
-#else
-                sprintf(tbuf,"%2.2X", (__u32)*ptr);
-#endif
-                tbuf[2] = '\0';
-                strcat(bhex, tbuf);
-                if ((0!=isprint(*ptr)) && (*ptr >= 0x20)) {
-                        basc[sw] = *ptr;
-                }
-                else {
-                        basc[sw] = '.';
-                }
-                basc[sw+1] = '\0';
-                sw++;
-                rm--;
-                if (sw==16) {
-                        if ((strcmp(duphex, bhex)) !=0) {
-                                if (dup !=0) {
-                                       sprintf(tdup,"Duplicate as above to"
-                                               " %s", addr);
-                                        printk( KERN_INFO "                 "
-                                               "   --- %s ---\n",tdup);
-                                }
-                                printk( KERN_INFO "   %s (+%s) : %s  [%s]\n",
-                                        addr, boff, bhex, basc);
-                                dup = 0;
-                                strcpy(duphex, bhex);
-                        }
-                        else {
-                                dup++;
-                        }
-                        sw = 0;
-                        rm = 16;
-                }
-        }  /* endfor */
-
-        if (sw != 0) {
-                for ( ; rm > 0; rm--, sw++ ) {
-                        if ((sw==4) || (sw==12)) strcat(bhex, " ");
-                        if (sw==8)               strcat(bhex, "  ");
-                        strcat(bhex, "  ");
-                        strcat(basc, " ");
-                }
-                if (dup !=0) {
-                        sprintf(tdup,"Duplicate as above to %s", addr);
-                        printk( KERN_INFO "                    --- %s ---\n",
-                               tdup);
-                }
-                printk( KERN_INFO "   %s (+%s) : %s  [%s]\n",
-                       addr, boff, bhex, basc);
-        }
-        else {
-                if (dup >=1) {
-                        sprintf(tdup,"Duplicate as above to %s", addr);
-                        printk( KERN_INFO "                    --- %s ---\n",
-                               tdup);
-                }
-                if (dup !=0) {
-                        printk( KERN_INFO "   %s (+%s) : %s  [%s]\n",
-                               addr, boff, bhex, basc);
-                }
-        }
-        return;
-
-}   /*   end of dumpit  */
-#endif
-
 /*-------------------------------------------------------------------*
 *               find_link                                            *
 *--------------------------------------------------------------------*/
@@ -1718,16 +1211,7 @@ find_link(struct net_device *dev, char *host_name, char *ws_name )
        struct claw_env *p_env;
        int    rc=0;
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s > enter  \n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(2,setup,"findlink");
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: variable dev = \n",dev->name);
-        dumpit((char *) dev, sizeof(struct net_device));
-        printk(KERN_INFO "%s: variable host_name = %s\n",dev->name, host_name);
-        printk(KERN_INFO "%s: variable ws_name = %s\n",dev->name, ws_name);
-#endif
+       CLAW_DBF_TEXT(2, setup, "findlink");
         privptr=dev->priv;
         p_env=privptr->p_env;
        switch (p_env->packing)
@@ -1750,10 +1234,6 @@ find_link(struct net_device *dev, char *host_name, char *ws_name )
                        break;
        }
 
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s:%s Exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
         return 0;
 }    /*    end of find_link    */
 
@@ -1782,27 +1262,11 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
         int                             lock;
        struct clawph                   *pk_head;
        struct chbk                     *ch;
-#ifdef IOTRACE
-        struct ccwbk                   *p_buf;
-#endif
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s: %s() > enter\n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"hw_tx");
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: variable dev skb =\n",dev->name);
-        dumpit((char *) skb, sizeof(struct sk_buff));
-        printk(KERN_INFO "%s: variable dev =\n",dev->name);
-        dumpit((char *) dev, sizeof(struct net_device));
-        printk(KERN_INFO "%s: variable linkid = %ld\n",dev->name,linkid);
-#endif
+
+       CLAW_DBF_TEXT(4, trace, "hw_tx");
         privptr = (struct claw_privbk *) (dev->priv);
         p_ch=(struct chbk *)&privptr->channel[WRITE];
        p_env =privptr->p_env;
-#ifdef IOTRACE
-       printk(KERN_INFO "%s: %s() dump sk_buff  \n",dev->name,__func__);
-        dumpit((char *)skb ,sizeof(struct sk_buff));
-#endif
        claw_free_wrt_buf(dev); /* Clean up free chain if posible */
         /*  scan the write queue to free any completed write packets   */
         p_first_ccw=NULL;
@@ -1834,11 +1298,6 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
                                 claw_strt_out_IO(dev );
                                 claw_free_wrt_buf( dev );
                                 if (privptr->write_free_count==0) {
-#ifdef IOTRACE
-                                       printk(KERN_INFO "%s: "
-                                          "(claw_check_busy) no free write "
-                                          "buffers\n", dev->name);
-#endif
                                        ch = &privptr->channel[WRITE];
                                        atomic_inc(&skb->users);
                                        skb_queue_tail(&ch->collect_queue, skb);
@@ -1851,10 +1310,6 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
                 }
                 /*  tx lock  */
                 if (claw_test_and_setbit_busy(TB_TX,dev)) { /* set to busy */
-#ifdef DEBUGMSG
-                        printk(KERN_INFO "%s:  busy  (claw_test_and_setbit_"
-                               "busy)\n", dev->name);
-#endif
                        ch = &privptr->channel[WRITE];
                        atomic_inc(&skb->users);
                        skb_queue_tail(&ch->collect_queue, skb);
@@ -1871,28 +1326,16 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
             privptr->p_write_free_chain == NULL ) {
 
                 claw_setbit_busy(TB_NOBUFFER,dev);
-
-#ifdef DEBUGMSG
-                printk(KERN_INFO "%s:  busy  (claw_setbit_busy"
-                       "(TB_NOBUFFER))\n", dev->name);
-                printk(KERN_INFO "       free_count: %d, numBuffers : %d\n",
-                       (int)privptr->write_free_count,(int) numBuffers );
-#endif
                ch = &privptr->channel[WRITE];
                atomic_inc(&skb->users);
                skb_queue_tail(&ch->collect_queue, skb);
-               CLAW_DBF_TEXT(2,trace,"clawbusy");
+               CLAW_DBF_TEXT(2, trace, "clawbusy");
                 goto Done2;
         }
         pDataAddress=skb->data;
         len_of_data=skb->len;
 
         while (len_of_data > 0) {
-#ifdef DEBUGMSG
-                printk(KERN_INFO "%s: %s() length-of-data is %ld \n",
-                       dev->name ,__func__,len_of_data);
-                dumpit((char *)pDataAddress ,64);
-#endif
                 p_this_ccw=privptr->p_write_free_chain;  /* get a block */
                if (p_this_ccw == NULL) { /* lost the race */
                        ch = &privptr->channel[WRITE];
@@ -1924,12 +1367,6 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
                                (__u32)__pa(&p_this_ccw->write);
                 }
                 p_last_ccw=p_this_ccw;      /* save new last block */
-#ifdef IOTRACE
-               printk(KERN_INFO "%s: %s() > CCW and Buffer %ld bytes long \n",
-                       dev->name,__func__,bytesInThisBuffer);
-                dumpit((char *)p_this_ccw, sizeof(struct ccwbk));
-                dumpit((char *)p_this_ccw->p_buffer, 64);
-#endif
         }
 
         /*      FirstCCW and LastCCW now contain a new set of write channel
@@ -1962,13 +1399,11 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
                         pEnd->write1_nop2.count=1;
                 }  /* end if if (pEnd->write1) */
 
-
                 if (privptr->p_write_active_first==NULL ) {
                         privptr->p_write_active_first=p_first_ccw;
                         privptr->p_write_active_last=p_last_ccw;
                 }
                 else {
-
                         /*      set up Tic CCWs         */
 
                         tempCCW.cda=(__u32)__pa(&p_first_ccw->write);
@@ -2007,19 +1442,6 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
                 }
 
         } /* endif (p_first_ccw!=NULL)  */
-
-
-#ifdef IOTRACE
-        printk(KERN_INFO "%s: %s() >  Dump Active CCW chain \n",
-               dev->name,__func__);
-        p_buf=privptr->p_write_active_first;
-        while (p_buf!=NULL) {
-                dumpit((char *)p_buf, sizeof(struct ccwbk));
-                p_buf=p_buf->next;
-        }
-        p_buf=(struct ccwbk*)privptr->p_end_ccw;
-        dumpit((char *)p_buf, sizeof(struct endccw));
-#endif
         dev_kfree_skb_any(skb);
        if (linkid==0) {
                lock=LOCK_NO;
@@ -2029,21 +1451,12 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
         }
         claw_strt_out_IO(dev );
         /*      if write free count is zero , set NOBUFFER       */
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: %s() > free_count is %d\n",
-               dev->name,__func__,
-               (int) privptr->write_free_count );
-#endif
        if (privptr->write_free_count==0) {
                claw_setbit_busy(TB_NOBUFFER,dev);
         }
 Done2:
        claw_clearbit_busy(TB_TX,dev);
 Done:
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s: %s() > exit on line %d, rc = %d \n",
-               dev->name,__func__,__LINE__, rc);
-#endif
        return(rc);
 }    /*    end of claw_hw_tx    */
 
@@ -2075,14 +1488,7 @@ init_ccw_bk(struct net_device *dev)
         struct clawh *pClawH=NULL;
         addr_t   real_TIC_address;
         int i,j;
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s: %s() enter  \n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"init_ccw");
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: variable dev =\n",dev->name);
-        dumpit((char *) dev, sizeof(struct net_device));
-#endif
+       CLAW_DBF_TEXT(4, trace, "init_ccw");
 
         /*  initialize  statistics field */
         privptr->active_link_ID=0;
@@ -2107,20 +1513,6 @@ init_ccw_bk(struct net_device *dev)
         */
         ccw_blocks_required =
                privptr->p_env->read_buffers+privptr->p_env->write_buffers+1;
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: %s() "
-               "ccw_blocks_required=%d\n",
-               dev->name,__func__,
-               ccw_blocks_required);
-        printk(KERN_INFO "%s: %s() "
-               "PAGE_SIZE=0x%x\n",
-               dev->name,__func__,
-               (unsigned int)PAGE_SIZE);
-        printk(KERN_INFO "%s: %s() > "
-               "PAGE_MASK=0x%x\n",
-               dev->name,__func__,
-               (unsigned int)PAGE_MASK);
-#endif
         /*
         * compute number of CCW blocks that will fit in a page
         */
@@ -2128,14 +1520,6 @@ init_ccw_bk(struct net_device *dev)
         ccw_pages_required=
                DIV_ROUND_UP(ccw_blocks_required, ccw_blocks_perpage);
 
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: %s() > ccw_blocks_perpage=%d\n",
-               dev->name,__func__,
-               ccw_blocks_perpage);
-        printk(KERN_INFO "%s: %s() > ccw_pages_required=%d\n",
-               dev->name,__func__,
-               ccw_pages_required);
-#endif
         /*
          *  read and write sizes are set by 2 constants in claw.h
         *  4k and 32k.  Unpacked values other than 4k are not going to
@@ -2166,36 +1550,6 @@ init_ccw_bk(struct net_device *dev)
                claw_write_pages = privptr->p_env->write_buffers *
                                        privptr->p_buff_pages_perwrite;
         }
-#ifdef DEBUGMSG
-        if (privptr->p_env->read_size < PAGE_SIZE) {
-            printk(KERN_INFO "%s: %s() reads_perpage=%d\n",
-               dev->name,__func__,
-               claw_reads_perpage);
-        }
-        else {
-            printk(KERN_INFO "%s: %s() pages_perread=%d\n",
-               dev->name,__func__,
-               privptr->p_buff_pages_perread);
-        }
-        printk(KERN_INFO "%s: %s() read_pages=%d\n",
-               dev->name,__func__,
-               claw_read_pages);
-        if (privptr->p_env->write_size < PAGE_SIZE) {
-            printk(KERN_INFO "%s: %s() writes_perpage=%d\n",
-               dev->name,__func__,
-               claw_writes_perpage);
-        }
-        else {
-            printk(KERN_INFO "%s: %s() pages_perwrite=%d\n",
-               dev->name,__func__,
-               privptr->p_buff_pages_perwrite);
-        }
-        printk(KERN_INFO "%s: %s() write_pages=%d\n",
-               dev->name,__func__,
-               claw_write_pages);
-#endif
-
-
         /*
         *               allocate ccw_pages_required
         */
@@ -2204,17 +1558,6 @@ init_ccw_bk(struct net_device *dev)
                        (void *)__get_free_pages(__GFP_DMA,
                        (int)pages_to_order_of_mag(ccw_pages_required ));
                 if (privptr->p_buff_ccw==NULL) {
-                        printk(KERN_INFO "%s: %s()  "
-                               "__get_free_pages for CCWs failed : "
-                               "pages is %d\n",
-                               dev->name,__func__,
-                               ccw_pages_required );
-#ifdef FUNCTRACE
-                        printk(KERN_INFO "%s: %s() > "
-                               "exit on line %d, rc = ENOMEM\n",
-                               dev->name,__func__,
-                                __LINE__);
-#endif
                         return -ENOMEM;
                 }
                 privptr->p_buff_ccw_num=ccw_pages_required;
@@ -2229,11 +1572,6 @@ init_ccw_bk(struct net_device *dev)
         privptr->p_end_ccw = (struct endccw *)&privptr->end_ccw;
         real_address  = (__u32)__pa(privptr->p_end_ccw);
         /*                              Initialize ending CCW block       */
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: %s() begin initialize ending CCW blocks\n",
-               dev->name,__func__);
-#endif
-
         p_endccw=privptr->p_end_ccw;
         p_endccw->real=real_address;
         p_endccw->write1=0x00;
@@ -2287,21 +1625,10 @@ init_ccw_bk(struct net_device *dev)
         p_endccw->read2_nop2.count        = 1;
         p_endccw->read2_nop2.cda          = 0;
 
-#ifdef IOTRACE
-        printk(KERN_INFO "%s: %s() dump claw ending CCW BK \n",
-               dev->name,__func__);
-        dumpit((char *)p_endccw, sizeof(struct endccw));
-#endif
-
         /*
         *                               Build a chain of CCWs
         *
         */
-
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: %s()  Begin build a chain of CCW buffer \n",
-               dev->name,__func__);
-#endif
         p_buff=privptr->p_buff_ccw;
 
         p_free_chain=NULL;
@@ -2316,26 +1643,10 @@ init_ccw_bk(struct net_device *dev)
                 }
                 p_buff+=PAGE_SIZE;
         }
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: %s() "
-               "End build a chain of CCW buffer \n",
-                       dev->name,__func__);
-        p_buf=p_free_chain;
-        while (p_buf!=NULL) {
-                dumpit((char *)p_buf, sizeof(struct ccwbk));
-                p_buf=p_buf->next;
-        }
-#endif
-
         /*
         *                               Initialize ClawSignalBlock
         *
         */
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: %s() "
-               "Begin initialize ClawSignalBlock \n",
-               dev->name,__func__);
-#endif
         if (privptr->p_claw_signal_blk==NULL) {
                 privptr->p_claw_signal_blk=p_free_chain;
                 p_free_chain=p_free_chain->next;
@@ -2344,12 +1655,6 @@ init_ccw_bk(struct net_device *dev)
                 pClawH->opcode=0xff;
                 pClawH->flag=CLAW_BUSY;
         }
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: %s() >  End initialize "
-               "ClawSignalBlock\n",
-               dev->name,__func__);
-        dumpit((char *)privptr->p_claw_signal_blk, sizeof(struct ccwbk));
-#endif
 
         /*
         *               allocate write_pages_required and add to free chain
@@ -2360,17 +1665,7 @@ init_ccw_bk(struct net_device *dev)
                        (void *)__get_free_pages(__GFP_DMA,
                        (int)pages_to_order_of_mag(claw_write_pages ));
                 if (privptr->p_buff_write==NULL) {
-                        printk(KERN_INFO "%s: %s() __get_free_pages for write"
-                               " bufs failed : get is for %d pages\n",
-                               dev->name,__func__,claw_write_pages );
-                        free_pages((unsigned long)privptr->p_buff_ccw,
-                          (int)pages_to_order_of_mag(privptr->p_buff_ccw_num));
                         privptr->p_buff_ccw=NULL;
-#ifdef FUNCTRACE
-                        printk(KERN_INFO "%s: %s() > exit on line %d,"
-                               "rc = ENOMEM\n",
-                               dev->name,__func__,__LINE__);
-#endif
                         return -ENOMEM;
                 }
                 /*
@@ -2380,10 +1675,6 @@ init_ccw_bk(struct net_device *dev)
 
                 memset(privptr->p_buff_write, 0x00,
                        ccw_pages_required * PAGE_SIZE);
-#ifdef DEBUGMSG
-                printk(KERN_INFO "%s: %s() Begin build claw write free "
-                       "chain \n",dev->name,__func__);
-#endif
                 privptr->p_write_free_chain=NULL;
 
                 p_buff=privptr->p_buff_write;
@@ -2419,18 +1710,7 @@ init_ccw_bk(struct net_device *dev)
                    p_buff=(void *)__get_free_pages(__GFP_DMA,
                        (int)pages_to_order_of_mag(
                        privptr->p_buff_pages_perwrite) );
-#ifdef IOTRACE
-                   printk(KERN_INFO "%s:%s __get_free_pages "
-                   "for writes buf: get for %d pages\n",
-                   dev->name,__func__,
-                   privptr->p_buff_pages_perwrite);
-#endif
                    if (p_buff==NULL) {
-                       printk(KERN_INFO "%s:%s __get_free_pages "
-                               "for writes buf failed : get is for %d pages\n",
-                               dev->name,
-                               __func__,
-                               privptr->p_buff_pages_perwrite );
                         free_pages((unsigned long)privptr->p_buff_ccw,
                              (int)pages_to_order_of_mag(
                                        privptr->p_buff_ccw_num));
@@ -2443,12 +1723,6 @@ init_ccw_bk(struct net_device *dev)
                                        privptr->p_buff_pages_perwrite));
                                 p_buf=p_buf->next;
                         }
-#ifdef FUNCTRACE
-                        printk(KERN_INFO "%s: %s exit on line %d, rc = ENOMEM\n",
-                       dev->name,
-                       __func__,
-                       __LINE__);
-#endif
                         return -ENOMEM;
                    }  /* Error on get_pages   */
                    memset(p_buff, 0x00, privptr->p_env->write_size );
@@ -2477,15 +1751,6 @@ init_ccw_bk(struct net_device *dev)
         privptr->write_free_count=privptr->p_env->write_buffers;
 
 
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s:%s  End build claw write free chain \n",
-       dev->name,__func__);
-        p_buf=privptr->p_write_free_chain;
-        while (p_buf!=NULL) {
-                dumpit((char *)p_buf, sizeof(struct ccwbk));
-                p_buf=p_buf->next;
-        }
-#endif
         /*
         *               allocate read_pages_required and chain to free chain
         */
@@ -2495,10 +1760,6 @@ init_ccw_bk(struct net_device *dev)
                        (void *)__get_free_pages(__GFP_DMA,
                        (int)pages_to_order_of_mag(claw_read_pages) );
                 if (privptr->p_buff_read==NULL) {
-                        printk(KERN_INFO "%s: %s() "
-                               "__get_free_pages for read buf failed : "
-                               "get is for %d pages\n",
-                               dev->name,__func__,claw_read_pages );
                         free_pages((unsigned long)privptr->p_buff_ccw,
                                (int)pages_to_order_of_mag(
                                        privptr->p_buff_ccw_num));
@@ -2508,10 +1769,6 @@ init_ccw_bk(struct net_device *dev)
                                privptr->p_buff_write_num));
                         privptr->p_buff_ccw=NULL;
                         privptr->p_buff_write=NULL;
-#ifdef FUNCTRACE
-                        printk(KERN_INFO "%s: %s() > exit on line %d, rc ="
-                               " ENOMEM\n",dev->name,__func__,__LINE__);
-#endif
                         return -ENOMEM;
                 }
                 memset(privptr->p_buff_read, 0x00, claw_read_pages * PAGE_SIZE);
@@ -2520,10 +1777,6 @@ init_ccw_bk(struct net_device *dev)
                 *                               Build CLAW read free chain
                 *
                 */
-#ifdef DEBUGMSG
-                printk(KERN_INFO "%s: %s() Begin build claw read free chain \n",
-                       dev->name,__func__);
-#endif
                 p_buff=privptr->p_buff_read;
                 for (i=0 ; i< privptr->p_env->read_buffers ; i++) {
                         p_buf        = p_free_chain;
@@ -2600,19 +1853,10 @@ init_ccw_bk(struct net_device *dev)
                 }   /* for read_buffers   */
           }         /* read_size < PAGE_SIZE  */
           else {  /* read Size >= PAGE_SIZE  */
-
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: %s() Begin build claw read free chain \n",
-               dev->name,__func__);
-#endif
                 for (i=0 ; i< privptr->p_env->read_buffers ; i++) {
                         p_buff = (void *)__get_free_pages(__GFP_DMA,
                                (int)pages_to_order_of_mag(privptr->p_buff_pages_perread) );
                         if (p_buff==NULL) {
-                                printk(KERN_INFO "%s: %s() __get_free_pages for read "
-                                       "buf failed : get is for %d pages\n",
-                                       dev->name,__func__,
-                                        privptr->p_buff_pages_perread );
                                 free_pages((unsigned long)privptr->p_buff_ccw,
                                        (int)pages_to_order_of_mag(privptr->p_buff_ccw_num));
                                /* free the write pages  */
@@ -2633,11 +1877,6 @@ init_ccw_bk(struct net_device *dev)
                                 }
                                 privptr->p_buff_ccw=NULL;
                                 privptr->p_buff_write=NULL;
-#ifdef FUNCTRACE
-                                printk(KERN_INFO "%s: %s() exit on line %d, rc = ENOMEM\n",
-                                       dev->name,__func__,
-                                       __LINE__);
-#endif
                                 return -ENOMEM;
                         }
                         memset(p_buff, 0x00, privptr->p_env->read_size);
@@ -2706,22 +1945,9 @@ init_ccw_bk(struct net_device *dev)
                 }    /* For read_buffers   */
           }     /*  read_size >= PAGE_SIZE   */
         }       /*  pBuffread = NULL */
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: %s() >  End build claw read free chain \n",
-               dev->name,__func__);
-        p_buf=p_first_CCWB;
-        while (p_buf!=NULL) {
-                dumpit((char *)p_buf, sizeof(struct ccwbk));
-                p_buf=p_buf->next;
-        }
-
-#endif
         add_claw_reads( dev  ,p_first_CCWB , p_last_CCWB);
        privptr->buffs_alloc = 1;
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s: %s() exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
+
         return 0;
 }    /*    end of init_ccw_bk */
 
@@ -2735,14 +1961,8 @@ static void
 probe_error( struct ccwgroup_device *cgdev)
 {
   struct claw_privbk *privptr;
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s enter  \n",__func__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"proberr");
-#ifdef DEBUGMSG
-       printk(KERN_INFO "%s variable cgdev =\n",__func__);
-        dumpit((char *) cgdev, sizeof(struct ccwgroup_device));
-#endif
+
+       CLAW_DBF_TEXT(4, trace, "proberr");
         privptr=(struct claw_privbk *)cgdev->dev.driver_data;
        if (privptr!=NULL) {
                kfree(privptr->p_env);
@@ -2752,16 +1972,9 @@ probe_error( struct ccwgroup_device *cgdev)
                 kfree(privptr);
                 privptr=NULL;
         }
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s > exit on line %d\n",
-                __func__,__LINE__);
-#endif
-
         return;
 }    /*    probe_error    */
 
-
-
 /*-------------------------------------------------------------------*
 *    claw_process_control                                            *
 *                                                                    *
@@ -2783,32 +1996,19 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
         struct conncmd *p_connect=NULL;
         int rc;
         struct chbk *p_ch = NULL;
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s: %s() > enter  \n",
-               dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(2,setup,"clw_cntl");
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: variable dev =\n",dev->name);
-        dumpit((char *) dev, sizeof(struct net_device));
-        printk(KERN_INFO "%s: variable p_ccw =\n",dev->name);
-        dumpit((char *) p_ccw, sizeof(struct ccwbk *));
-#endif
+       struct device *tdev;
+       CLAW_DBF_TEXT(2, setup, "clw_cntl");
         udelay(1000);  /* Wait a ms for the control packets to
                        *catch up to each other */
         privptr=dev->priv;
         p_env=privptr->p_env;
+       tdev = &privptr->channel[READ].cdev->dev;
        memcpy( &temp_host_name, p_env->host_name, 8);
         memcpy( &temp_ws_name, p_env->adapter_name , 8);
         printk(KERN_INFO "%s: CLAW device %.8s: "
                "Received Control Packet\n",
                dev->name, temp_ws_name);
         if (privptr->release_pend==1) {
-#ifdef FUNCTRACE
-                printk(KERN_INFO "%s: %s() > "
-                       "exit on line %d, rc=0\n",
-                       dev->name,__func__,__LINE__);
-#endif
                 return 0;
         }
         p_buf=p_ccw->p_buffer;
@@ -2818,261 +2018,246 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
        } else {
                memcpy(p_ctlbk, p_buf, sizeof(struct clawctl));
        }
-#ifdef IOTRACE
-        printk(KERN_INFO "%s: dump claw control data inbound\n",dev->name);
-        dumpit((char *)p_ctlbk, sizeof(struct clawctl));
-#endif
         switch (p_ctlbk->command)
         {
-                case SYSTEM_VALIDATE_REQUEST:
-                        if (p_ctlbk->version!=CLAW_VERSION_ID) {
-                                claw_snd_sys_validate_rsp(dev, p_ctlbk,
-                                       CLAW_RC_WRONG_VERSION );
-                                printk("%s: %d is wrong version id. "
-                                       "Expected %d\n",
-                                       dev->name, p_ctlbk->version,
-                                        CLAW_VERSION_ID);
-                        }
-                        p_sysval=(struct sysval *)&(p_ctlbk->data);
-                       printk( "%s: Recv Sys Validate Request: "
-                               "Vers=%d,link_id=%d,Corr=%d,WS name=%."
-                               "8s,Host name=%.8s\n",
-                                dev->name, p_ctlbk->version,
-                               p_ctlbk->linkid,
-                               p_ctlbk->correlator,
-                               p_sysval->WS_name,
-                                p_sysval->host_name);
-                        if (0!=memcmp(temp_host_name,p_sysval->host_name,8)) {
-                                claw_snd_sys_validate_rsp(dev, p_ctlbk,
-                                       CLAW_RC_NAME_MISMATCH );
-                               CLAW_DBF_TEXT(2,setup,"HSTBAD");
-                               CLAW_DBF_TEXT_(2,setup,"%s",p_sysval->host_name);
-                               CLAW_DBF_TEXT_(2,setup,"%s",temp_host_name);
-                                printk(KERN_INFO "%s:  Host name mismatch\n",
-                                       dev->name);
-                               printk(KERN_INFO "%s: Received :%s: "
-                                       "expected :%s: \n",
-                                       dev->name,
-                                       p_sysval->host_name,
-                                       temp_host_name);
-                        }
-                        if (0!=memcmp(temp_ws_name,p_sysval->WS_name,8)) {
-                                claw_snd_sys_validate_rsp(dev, p_ctlbk,
-                                       CLAW_RC_NAME_MISMATCH );
-                               CLAW_DBF_TEXT(2,setup,"WSNBAD");
-                                CLAW_DBF_TEXT_(2,setup,"%s",p_sysval->WS_name);
-                                CLAW_DBF_TEXT_(2,setup,"%s",temp_ws_name);
-                                printk(KERN_INFO "%s: WS name mismatch\n",
-                                       dev->name);
-                                printk(KERN_INFO "%s: Received :%s: "
-                                        "expected :%s: \n",
-                                        dev->name,
-                                        p_sysval->WS_name,
-                                       temp_ws_name);
-                        }
-                        if (( p_sysval->write_frame_size < p_env->write_size) &&
-                          ( p_env->packing == 0)) {
-                                claw_snd_sys_validate_rsp(dev, p_ctlbk,
-                                       CLAW_RC_HOST_RCV_TOO_SMALL );
-                                printk(KERN_INFO "%s: host write size is too "
-                                       "small\n", dev->name);
-                               CLAW_DBF_TEXT(2,setup,"wrtszbad");
-                        }
-                        if (( p_sysval->read_frame_size < p_env->read_size) &&
-                          ( p_env->packing == 0)) {
-                                claw_snd_sys_validate_rsp(dev, p_ctlbk,
-                                       CLAW_RC_HOST_RCV_TOO_SMALL );
-                                printk(KERN_INFO "%s: host read size is too "
-                                       "small\n", dev->name);
-                               CLAW_DBF_TEXT(2,setup,"rdsizbad");
-                        }
-                        claw_snd_sys_validate_rsp(dev, p_ctlbk, 0 );
-                        printk("%s: CLAW device %.8s: System validate"
-                               " completed.\n",dev->name, temp_ws_name);
-                       printk("%s: sys Validate Rsize:%d Wsize:%d\n",dev->name,
-                               p_sysval->read_frame_size,p_sysval->write_frame_size);
-                        privptr->system_validate_comp=1;
-                       if(strncmp(p_env->api_type,WS_APPL_NAME_PACKED,6) == 0) {
-                               p_env->packing = PACKING_ASK;
-                       }
-                        claw_strt_conn_req(dev);
-                        break;
-
-                case SYSTEM_VALIDATE_RESPONSE:
-                       p_sysval=(struct sysval *)&(p_ctlbk->data);
-                       printk("%s: Recv Sys Validate Resp: Vers=%d,Corr=%d,RC=%d,"
-                               "WS name=%.8s,Host name=%.8s\n",
-                               dev->name,
-                               p_ctlbk->version,
-                               p_ctlbk->correlator,
-                               p_ctlbk->rc,
-                               p_sysval->WS_name,
-                               p_sysval->host_name);
-                        switch (p_ctlbk->rc)
-                        {
-                                case 0:
-                                        printk(KERN_INFO "%s: CLAW device "
-                                               "%.8s: System validate "
-                                               "completed.\n",
-                                                dev->name, temp_ws_name);
-                                       if (privptr->system_validate_comp == 0)
-                                               claw_strt_conn_req(dev);
-                                       privptr->system_validate_comp=1;
-                                        break;
-                                case CLAW_RC_NAME_MISMATCH:
-                                        printk(KERN_INFO "%s: Sys Validate "
-                                               "Resp : Host, WS name is "
-                                               "mismatch\n",
-                                                dev->name);
-                                        break;
-                                case CLAW_RC_WRONG_VERSION:
-                                        printk(KERN_INFO "%s: Sys Validate "
-                                               "Resp : Wrong version\n",
-                                               dev->name);
-                                        break;
-                                case CLAW_RC_HOST_RCV_TOO_SMALL:
-                                        printk(KERN_INFO "%s: Sys Validate "
-                                               "Resp : bad frame size\n",
-                                               dev->name);
-                                        break;
-                                default:
-                                        printk(KERN_INFO "%s: Sys Validate "
-                                               "error code=%d \n",
-                                                dev->name, p_ctlbk->rc );
-                                        break;
-                        }
-                        break;
+       case SYSTEM_VALIDATE_REQUEST:
+               if (p_ctlbk->version != CLAW_VERSION_ID) {
+                       claw_snd_sys_validate_rsp(dev, p_ctlbk,
+                               CLAW_RC_WRONG_VERSION);
+                       printk("%s: %d is wrong version id. "
+                              "Expected %d\n",
+                              dev->name, p_ctlbk->version,
+                              CLAW_VERSION_ID);
+               }
+               p_sysval = (struct sysval *)&(p_ctlbk->data);
+               printk("%s: Recv Sys Validate Request: "
+                      "Vers=%d,link_id=%d,Corr=%d,WS name=%."
+                      "8s,Host name=%.8s\n",
+                      dev->name, p_ctlbk->version,
+                      p_ctlbk->linkid,
+                      p_ctlbk->correlator,
+                      p_sysval->WS_name,
+                      p_sysval->host_name);
+               if (memcmp(temp_host_name, p_sysval->host_name, 8)) {
+                       claw_snd_sys_validate_rsp(dev, p_ctlbk,
+                               CLAW_RC_NAME_MISMATCH);
+                       CLAW_DBF_TEXT(2, setup, "HSTBAD");
+                       CLAW_DBF_TEXT_(2, setup, "%s", p_sysval->host_name);
+                       CLAW_DBF_TEXT_(2, setup, "%s", temp_host_name);
+                       printk(KERN_INFO "%s:  Host name mismatch\n",
+                               dev->name);
+                       printk(KERN_INFO "%s: Received :%s: "
+                               "expected :%s: \n",
+                               dev->name,
+                               p_sysval->host_name,
+                               temp_host_name);
+               }
+               if (memcmp(temp_ws_name, p_sysval->WS_name, 8)) {
+                       claw_snd_sys_validate_rsp(dev, p_ctlbk,
+                               CLAW_RC_NAME_MISMATCH);
+                       CLAW_DBF_TEXT(2, setup, "WSNBAD");
+                       CLAW_DBF_TEXT_(2, setup, "%s", p_sysval->WS_name);
+                       CLAW_DBF_TEXT_(2, setup, "%s", temp_ws_name);
+                       printk(KERN_INFO "%s: WS name mismatch\n",
+                               dev->name);
+                       printk(KERN_INFO "%s: Received :%s: "
+                              "expected :%s: \n",
+                              dev->name,
+                              p_sysval->WS_name,
+                              temp_ws_name);
+               }
+               if ((p_sysval->write_frame_size < p_env->write_size) &&
+                   (p_env->packing == 0)) {
+                       claw_snd_sys_validate_rsp(dev, p_ctlbk,
+                               CLAW_RC_HOST_RCV_TOO_SMALL);
+                       printk(KERN_INFO "%s: host write size is too "
+                               "small\n", dev->name);
+                       CLAW_DBF_TEXT(2, setup, "wrtszbad");
+               }
+               if ((p_sysval->read_frame_size < p_env->read_size) &&
+                   (p_env->packing == 0)) {
+                       claw_snd_sys_validate_rsp(dev, p_ctlbk,
+                               CLAW_RC_HOST_RCV_TOO_SMALL);
+                       printk(KERN_INFO "%s: host read size is too "
+                               "small\n", dev->name);
+                       CLAW_DBF_TEXT(2, setup, "rdsizbad");
+               }
+               claw_snd_sys_validate_rsp(dev, p_ctlbk, 0);
+               printk(KERN_INFO "%s: CLAW device %.8s: System validate "
+                       "completed.\n", dev->name, temp_ws_name);
+               printk("%s: sys Validate Rsize:%d Wsize:%d\n", dev->name,
+                       p_sysval->read_frame_size, p_sysval->write_frame_size);
+               privptr->system_validate_comp = 1;
+               if (strncmp(p_env->api_type, WS_APPL_NAME_PACKED, 6) == 0)
+                       p_env->packing = PACKING_ASK;
+               claw_strt_conn_req(dev);
+               break;
+       case SYSTEM_VALIDATE_RESPONSE:
+               p_sysval = (struct sysval *)&(p_ctlbk->data);
+               printk("%s: Recv Sys Validate Resp: Vers=%d,Corr=%d,RC=%d,"
+                       "WS name=%.8s,Host name=%.8s\n",
+                       dev->name,
+                       p_ctlbk->version,
+                       p_ctlbk->correlator,
+                       p_ctlbk->rc,
+                       p_sysval->WS_name,
+                       p_sysval->host_name);
+               switch (p_ctlbk->rc) {
+               case 0:
+                       printk(KERN_INFO "%s: CLAW device "
+                               "%.8s: System validate "
+                               "completed.\n",
+                              dev->name, temp_ws_name);
+                       if (privptr->system_validate_comp == 0)
+                               claw_strt_conn_req(dev);
+                       privptr->system_validate_comp = 1;
+                       break;
+               case CLAW_RC_NAME_MISMATCH:
+                       printk(KERN_INFO "%s: Sys Validate "
+                               "Resp : Host, WS name is "
+                               "mismatch\n",
+                              dev->name);
+                       break;
+               case CLAW_RC_WRONG_VERSION:
+                       printk(KERN_INFO "%s: Sys Validate "
+                               "Resp : Wrong version\n",
+                               dev->name);
+                       break;
+               case CLAW_RC_HOST_RCV_TOO_SMALL:
+                       printk(KERN_INFO "%s: Sys Validate "
+                               "Resp : bad frame size\n",
+                               dev->name);
+                       break;
+               default:
+                       printk(KERN_INFO "%s: Sys Validate "
+                               "error code=%d \n",
+                                dev->name, p_ctlbk->rc);
+                       break;
+               }
+               break;
 
-                case CONNECTION_REQUEST:
-                        p_connect=(struct conncmd *)&(p_ctlbk->data);
-                        printk(KERN_INFO "%s: Recv Conn Req: Vers=%d,link_id=%d,"
-                               "Corr=%d,HOST appl=%.8s,WS appl=%.8s\n",
-                               dev->name,
-                               p_ctlbk->version,
-                               p_ctlbk->linkid,
-                               p_ctlbk->correlator,
-                               p_connect->host_name,
-                               p_connect->WS_name);
-                        if (privptr->active_link_ID!=0 ) {
-                                claw_snd_disc(dev, p_ctlbk);
-                                printk(KERN_INFO "%s: Conn Req error : "
-                                       "already logical link is active \n",
-                                       dev->name);
-                        }
-                        if (p_ctlbk->linkid!=1 ) {
-                                claw_snd_disc(dev, p_ctlbk);
-                                printk(KERN_INFO "%s: Conn Req error : "
-                                       "req logical link id is not 1\n",
+       case CONNECTION_REQUEST:
+               p_connect = (struct conncmd *)&(p_ctlbk->data);
+               printk(KERN_INFO "%s: Recv Conn Req: Vers=%d,link_id=%d,"
+                       "Corr=%d,HOST appl=%.8s,WS appl=%.8s\n",
+                       dev->name,
+                       p_ctlbk->version,
+                       p_ctlbk->linkid,
+                       p_ctlbk->correlator,
+                       p_connect->host_name,
+                       p_connect->WS_name);
+               if (privptr->active_link_ID != 0) {
+                       claw_snd_disc(dev, p_ctlbk);
+                       printk(KERN_INFO "%s: Conn Req error : "
+                               "already logical link is active \n",
+                               dev->name);
+               }
+               if (p_ctlbk->linkid != 1) {
+                       claw_snd_disc(dev, p_ctlbk);
+                       printk(KERN_INFO "%s: Conn Req error : "
+                               "req logical link id is not 1\n",
+                               dev->name);
+               }
+               rc = find_link(dev, p_connect->host_name, p_connect->WS_name);
+               if (rc != 0) {
+                       claw_snd_disc(dev, p_ctlbk);
+                       printk(KERN_INFO "%s: Conn Resp error: "
+                               "req appl name does not match\n",
+                               dev->name);
+               }
+               claw_send_control(dev,
+                       CONNECTION_CONFIRM, p_ctlbk->linkid,
+                       p_ctlbk->correlator,
+                       0, p_connect->host_name,
+                       p_connect->WS_name);
+               if (p_env->packing == PACKING_ASK) {
+                       p_env->packing = PACK_SEND;
+                       claw_snd_conn_req(dev, 0);
+               }
+               printk(KERN_INFO "%s: CLAW device %.8s: Connection "
+                       "completed link_id=%d.\n",
+                       dev->name, temp_ws_name,
+                       p_ctlbk->linkid);
+                       privptr->active_link_ID = p_ctlbk->linkid;
+                       p_ch = &privptr->channel[WRITE];
+                       wake_up(&p_ch->wait);  /* wake up claw_open ( WRITE) */
+               break;
+       case CONNECTION_RESPONSE:
+               p_connect = (struct conncmd *)&(p_ctlbk->data);
+               printk(KERN_INFO "%s: Revc Conn Resp: Vers=%d,link_id=%d,"
+                       "Corr=%d,RC=%d,Host appl=%.8s, WS appl=%.8s\n",
+                       dev->name,
+                       p_ctlbk->version,
+                       p_ctlbk->linkid,
+                       p_ctlbk->correlator,
+                       p_ctlbk->rc,
+                       p_connect->host_name,
+                       p_connect->WS_name);
+
+               if (p_ctlbk->rc != 0) {
+                       printk(KERN_INFO "%s: Conn Resp error: rc=%d \n",
+                               dev->name, p_ctlbk->rc);
+                       return 1;
+               }
+               rc = find_link(dev,
+                       p_connect->host_name, p_connect->WS_name);
+               if (rc != 0) {
+                       claw_snd_disc(dev, p_ctlbk);
+                       printk(KERN_INFO "%s: Conn Resp error: "
+                               "req appl name does not match\n",
+                                dev->name);
+               }
+               /* should be until CONNECTION_CONFIRM */
+               privptr->active_link_ID = -(p_ctlbk->linkid);
+               break;
+       case CONNECTION_CONFIRM:
+               p_connect = (struct conncmd *)&(p_ctlbk->data);
+               printk(KERN_INFO "%s: Recv Conn Confirm:Vers=%d,link_id=%d,"
+                       "Corr=%d,Host appl=%.8s,WS appl=%.8s\n",
+                       dev->name,
+                       p_ctlbk->version,
+                       p_ctlbk->linkid,
+                       p_ctlbk->correlator,
+                       p_connect->host_name,
+                       p_connect->WS_name);
+               if (p_ctlbk->linkid == -(privptr->active_link_ID)) {
+                       privptr->active_link_ID = p_ctlbk->linkid;
+                       if (p_env->packing > PACKING_ASK) {
+                               printk(KERN_INFO "%s: Confirmed Now packing\n",
                                        dev->name);
-                        }
-                        rc=find_link(dev,
-                               p_connect->host_name, p_connect->WS_name);
-                        if (rc!=0) {
-                                claw_snd_disc(dev, p_ctlbk);
-                                printk(KERN_INFO "%s: Conn Req error : "
-                                       "req appl name does not match\n",
-                                        dev->name);
-                        }
-                        claw_send_control(dev,
-                               CONNECTION_CONFIRM, p_ctlbk->linkid,
-                               p_ctlbk->correlator,
-                               0, p_connect->host_name,
-                                p_connect->WS_name);
-                       if (p_env->packing == PACKING_ASK) {
-                               printk("%s: Now Pack ask\n",dev->name);
-                               p_env->packing = PACK_SEND;
-                               claw_snd_conn_req(dev,0);
-                       }
-                        printk(KERN_INFO "%s: CLAW device %.8s: Connection "
-                               "completed link_id=%d.\n",
-                               dev->name, temp_ws_name,
-                                p_ctlbk->linkid);
-                        privptr->active_link_ID=p_ctlbk->linkid;
-                        p_ch=&privptr->channel[WRITE];
-                        wake_up(&p_ch->wait);  /* wake up claw_open ( WRITE) */
-                        break;
-                case CONNECTION_RESPONSE:
-                        p_connect=(struct conncmd *)&(p_ctlbk->data);
-                        printk(KERN_INFO "%s: Revc Conn Resp: Vers=%d,link_id=%d,"
-                               "Corr=%d,RC=%d,Host appl=%.8s, WS appl=%.8s\n",
-                                dev->name,
-                               p_ctlbk->version,
-                               p_ctlbk->linkid,
-                               p_ctlbk->correlator,
-                               p_ctlbk->rc,
-                               p_connect->host_name,
-                                p_connect->WS_name);
-
-                        if (p_ctlbk->rc !=0 ) {
-                                printk(KERN_INFO "%s: Conn Resp error: rc=%d \n",
-                                       dev->name, p_ctlbk->rc);
-                                return 1;
-                        }
-                        rc=find_link(dev,
-                               p_connect->host_name, p_connect->WS_name);
-                        if (rc!=0) {
-                                claw_snd_disc(dev, p_ctlbk);
-                                printk(KERN_INFO "%s: Conn Resp error: "
-                                       "req appl name does not match\n",
-                                        dev->name);
-                        }
-                       /* should be until CONNECTION_CONFIRM */
-                        privptr->active_link_ID =  - (p_ctlbk->linkid);
-                        break;
-                case CONNECTION_CONFIRM:
-                        p_connect=(struct conncmd *)&(p_ctlbk->data);
-                        printk(KERN_INFO "%s: Recv Conn Confirm:Vers=%d,link_id=%d,"
-                               "Corr=%d,Host appl=%.8s,WS appl=%.8s\n",
-                        dev->name,
-                        p_ctlbk->version,
-                        p_ctlbk->linkid,
-                        p_ctlbk->correlator,
-                        p_connect->host_name,
-                        p_connect->WS_name);
-                        if (p_ctlbk->linkid== -(privptr->active_link_ID)) {
-                                privptr->active_link_ID=p_ctlbk->linkid;
-                               if (p_env->packing > PACKING_ASK) {
-                                       printk(KERN_INFO "%s: Confirmed Now packing\n",dev->name);
-                                       p_env->packing = DO_PACKED;
-                                       }
-                               p_ch=&privptr->channel[WRITE];
-                                wake_up(&p_ch->wait);
-                        }
-                        else {
-                                printk(KERN_INFO "%s: Conn confirm: "
-                                       "unexpected linkid=%d \n",
-                                       dev->name, p_ctlbk->linkid);
-                                claw_snd_disc(dev, p_ctlbk);
-                        }
-                        break;
-                case DISCONNECT:
-                        printk(KERN_INFO "%s: Disconnect: "
-                               "Vers=%d,link_id=%d,Corr=%d\n",
-                               dev->name, p_ctlbk->version,
-                                p_ctlbk->linkid, p_ctlbk->correlator);
-                       if ((p_ctlbk->linkid == 2) &&
-                           (p_env->packing == PACK_SEND)) {
-                               privptr->active_link_ID = 1;
                                p_env->packing = DO_PACKED;
                        }
-                       else
-                               privptr->active_link_ID=0;
-                        break;
-                case CLAW_ERROR:
-                        printk(KERN_INFO "%s: CLAW ERROR detected\n",
-                               dev->name);
-                        break;
-                default:
-                        printk(KERN_INFO "%s:  Unexpected command code=%d \n",
-                               dev->name,  p_ctlbk->command);
-                        break;
+                       p_ch = &privptr->channel[WRITE];
+                       wake_up(&p_ch->wait);
+               } else {
+                      printk(KERN_INFO "%s: Conn confirm: "
+                               "unexpected linkid=%d \n",
+                               dev->name, p_ctlbk->linkid);
+                       claw_snd_disc(dev, p_ctlbk);
+               }
+               break;
+       case DISCONNECT:
+               printk(KERN_INFO "%s: Disconnect: "
+                       "Vers=%d,link_id=%d,Corr=%d\n",
+                       dev->name, p_ctlbk->version,
+                       p_ctlbk->linkid, p_ctlbk->correlator);
+               if ((p_ctlbk->linkid == 2) &&
+                   (p_env->packing == PACK_SEND)) {
+                       privptr->active_link_ID = 1;
+                       p_env->packing = DO_PACKED;
+               } else
+                       privptr->active_link_ID = 0;
+               break;
+       case CLAW_ERROR:
+               printk(KERN_INFO "%s: CLAW ERROR detected\n",
+                       dev->name);
+               break;
+       default:
+               printk(KERN_INFO "%s:  Unexpected command code=%d \n",
+                       dev->name,  p_ctlbk->command);
+               break;
         }
 
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s: %s() exit on line %d, rc = 0\n",
-               dev->name,__func__,__LINE__);
-#endif
-
         return 0;
 }   /*    end of claw_process_control    */
 
@@ -3092,18 +2277,7 @@ claw_send_control(struct net_device *dev, __u8 type, __u8 link,
         struct conncmd                  *p_connect;
         struct sk_buff                         *skb;
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s > enter  \n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(2,setup,"sndcntl");
-#ifdef DEBUGMSG
-       printk(KERN_INFO "%s: Sending Control Packet \n",dev->name);
-        printk(KERN_INFO "%s: variable type = 0x%X, link = "
-               "%d, correlator = %d, rc = %d\n",
-                dev->name,type, link, correlator, rc);
-        printk(KERN_INFO "%s: variable local_name = %s, "
-               "remote_name = %s\n",dev->name, local_name, remote_name);
-#endif
+       CLAW_DBF_TEXT(2, setup, "sndcntl");
         privptr=dev->priv;
         p_ctl=(struct clawctl *)&privptr->ctl_bk;
 
@@ -3125,7 +2299,7 @@ claw_send_control(struct net_device *dev, __u8 type, __u8 link,
                                p_sysval->read_frame_size=DEF_PACK_BUFSIZE;
                                p_sysval->write_frame_size=DEF_PACK_BUFSIZE;
                        } else {
-                               /* how big is the piggest group of packets */
+                               /* how big is the biggest group of packets */
                                p_sysval->read_frame_size=privptr->p_env->read_size;
                                p_sysval->write_frame_size=privptr->p_env->write_size;
                        }
@@ -3155,29 +2329,14 @@ claw_send_control(struct net_device *dev, __u8 type, __u8 link,
 
         skb = dev_alloc_skb(sizeof(struct clawctl));
         if (!skb) {
-                printk(  "%s:%s low on mem, returning...\n",
-                       dev->name,__func__);
-#ifdef DEBUG
-                printk(KERN_INFO "%s:%s Exit, rc = ENOMEM\n",
-                       dev->name,__func__);
-#endif
                 return -ENOMEM;
         }
        memcpy(skb_put(skb, sizeof(struct clawctl)),
                p_ctl, sizeof(struct clawctl));
-#ifdef IOTRACE
-        printk(KERN_INFO "%s: outbnd claw cntl data \n",dev->name);
-        dumpit((char *)p_ctl,sizeof(struct clawctl));
-#endif
        if (privptr->p_env->packing >= PACK_SEND)
                claw_hw_tx(skb, dev, 1);
        else
                claw_hw_tx(skb, dev, 0);
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s:%s Exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
-
         return 0;
 }  /*   end of claw_send_control  */
 
@@ -3192,22 +2351,11 @@ claw_snd_conn_req(struct net_device *dev, __u8 link)
         struct claw_privbk *privptr=dev->priv;
         struct clawctl            *p_ctl;
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter  \n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(2,setup,"snd_conn");
-#ifdef  DEBUGMSG
-        printk(KERN_INFO "%s: variable link = %X, dev =\n",dev->name, link);
-        dumpit((char *) dev, sizeof(struct net_device));
-#endif
+       CLAW_DBF_TEXT(2, setup, "snd_conn");
        rc = 1;
         p_ctl=(struct clawctl *)&privptr->ctl_bk;
        p_ctl->linkid = link;
         if ( privptr->system_validate_comp==0x00 ) {
-#ifdef FUNCTRACE
-                printk(KERN_INFO "%s:%s Exit on line %d, rc = 1\n",
-                       dev->name,__func__,__LINE__);
-#endif
                 return rc;
         }
        if (privptr->p_env->packing == PACKING_ASK )
@@ -3220,10 +2368,6 @@ claw_snd_conn_req(struct net_device *dev, __u8 link)
        if (privptr->p_env->packing == 0)
                rc=claw_send_control(dev, CONNECTION_REQUEST,0,0,0,
                                HOST_APPL_NAME, privptr->p_env->api_type);
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s:%s Exit on line %d, rc = %d\n",
-               dev->name,__func__,__LINE__, rc);
-#endif
         return rc;
 
 }  /*  end of claw_snd_conn_req */
@@ -3240,25 +2384,12 @@ claw_snd_disc(struct net_device *dev, struct clawctl * p_ctl)
         int rc;
         struct conncmd *  p_connect;
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter\n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(2,setup,"snd_dsc");
-#ifdef  DEBUGMSG
-        printk(KERN_INFO "%s: variable dev =\n",dev->name);
-        dumpit((char *) dev, sizeof(struct net_device));
-        printk(KERN_INFO "%s: variable p_ctl",dev->name);
-        dumpit((char *) p_ctl, sizeof(struct clawctl));
-#endif
+       CLAW_DBF_TEXT(2, setup, "snd_dsc");
         p_connect=(struct conncmd *)&p_ctl->data;
 
         rc=claw_send_control(dev, DISCONNECT, p_ctl->linkid,
                p_ctl->correlator, 0,
                 p_connect->host_name, p_connect->WS_name);
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s:%s Exit on line %d, rc = %d\n",
-               dev->name,__func__, __LINE__, rc);
-#endif
         return rc;
 }     /*   end of claw_snd_disc    */
 
@@ -3276,18 +2407,7 @@ claw_snd_sys_validate_rsp(struct net_device *dev,
         struct claw_privbk *privptr;
         int    rc;
 
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s:%s Enter\n",
-               dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(2,setup,"chkresp");
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: variable return_code = %d, dev =\n",
-               dev->name, return_code);
-        dumpit((char *) dev, sizeof(struct net_device));
-        printk(KERN_INFO "%s: variable p_ctl =\n",dev->name);
-        dumpit((char *) p_ctl, sizeof(struct clawctl));
-#endif
+       CLAW_DBF_TEXT(2, setup, "chkresp");
         privptr = dev->priv;
         p_env=privptr->p_env;
         rc=claw_send_control(dev, SYSTEM_VALIDATE_RESPONSE,
@@ -3296,10 +2416,6 @@ claw_snd_sys_validate_rsp(struct net_device *dev,
                 return_code,
                p_env->host_name,
                p_env->adapter_name  );
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s:%s Exit on line %d, rc = %d\n",
-               dev->name,__func__,__LINE__, rc);
-#endif
         return rc;
 }     /*    end of claw_snd_sys_validate_rsp    */
 
@@ -3313,19 +2429,8 @@ claw_strt_conn_req(struct net_device *dev )
 {
         int rc;
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter\n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(2,setup,"conn_req");
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s: variable dev =\n",dev->name);
-        dumpit((char *) dev, sizeof(struct net_device));
-#endif
+       CLAW_DBF_TEXT(2, setup, "conn_req");
         rc=claw_snd_conn_req(dev, 1);
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s:%s Exit on line %d, rc = %d\n",
-               dev->name,__func__,__LINE__, rc);
-#endif
         return rc;
 }    /*   end of claw_strt_conn_req   */
 
@@ -3339,15 +2444,9 @@ static struct
 net_device_stats *claw_stats(struct net_device *dev)
 {
         struct claw_privbk *privptr;
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter\n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"stats");
+
+       CLAW_DBF_TEXT(4, trace, "stats");
         privptr = dev->priv;
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s:%s Exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
         return &privptr->stats;
 }     /*   end of claw_stats   */
 
@@ -3368,36 +2467,28 @@ unpack_read(struct net_device *dev )
        struct clawph   *p_packh;
        void            *p_packd;
        struct clawctl  *p_ctlrec=NULL;
+       struct device   *p_dev;
 
         __u32  len_of_data;
        __u32   pack_off;
         __u8   link_num;
         __u8   mtc_this_frm=0;
         __u32  bytes_to_mov;
-        struct chbk *p_ch = NULL;
         int    i=0;
        int     p=0;
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s enter  \n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"unpkread");
+       CLAW_DBF_TEXT(4, trace, "unpkread");
         p_first_ccw=NULL;
         p_last_ccw=NULL;
        p_packh=NULL;
        p_packd=NULL;
         privptr=dev->priv;
+
+       p_dev = &privptr->channel[READ].cdev->dev;
        p_env = privptr->p_env;
         p_this_ccw=privptr->p_read_active_first;
         i=0;
        while (p_this_ccw!=NULL && p_this_ccw->header.flag!=CLAW_PENDING) {
-#ifdef IOTRACE
-               printk(KERN_INFO "%s p_this_ccw \n",dev->name);
-                dumpit((char*)p_this_ccw, sizeof(struct ccwbk));
-                printk(KERN_INFO "%s Inbound p_this_ccw->p_buffer(64)"
-                       " pk=%d \n",dev->name,p_env->packing);
-                dumpit((char *)p_this_ccw->p_buffer, 64 );
-#endif
                pack_off = 0;
                p = 0;
                p_this_ccw->header.flag=CLAW_PENDING;
@@ -3419,10 +2510,6 @@ unpack_read(struct net_device *dev )
                else
                        link_num=p_this_ccw->header.opcode / 8;
                 if ((p_this_ccw->header.opcode & MORE_to_COME_FLAG)!=0) {
-#ifdef DEBUGMSG
-                        printk(KERN_INFO "%s: %s > More_to_come is ON\n",
-                       dev->name,__func__);
-#endif
                         mtc_this_frm=1;
                         if (p_this_ccw->header.length!=
                                privptr->p_env->read_size ) {
@@ -3445,22 +2532,12 @@ unpack_read(struct net_device *dev )
                                 privptr->mtc_skipping=0; /* Ok, the end */
                                 privptr->mtc_logical_link=-1;
                         }
-#ifdef DEBUGMSG
-                        printk(KERN_INFO "%s:%s goto next "
-                               "frame from MoretoComeSkip \n",
-                               dev->name,__func__);
-#endif
                         goto NextFrame;
                 }
 
                 if (link_num==0) {
                         claw_process_control(dev, p_this_ccw);
-#ifdef DEBUGMSG
-                        printk(KERN_INFO "%s:%s goto next "
-                               "frame from claw_process_control \n",
-                               dev->name,__func__);
-#endif
-                       CLAW_DBF_TEXT(4,trace,"UnpkCntl");
+                       CLAW_DBF_TEXT(4, trace, "UnpkCntl");
                         goto NextFrame;
                 }
 unpack_next:
@@ -3479,10 +2556,6 @@ unpack_next:
                        bytes_to_mov=p_this_ccw->header.length;
                }
                 if (privptr->mtc_logical_link<0) {
-#ifdef DEBUGMSG
-                printk(KERN_INFO "%s: %s mtc_logical_link < 0  \n",
-                       dev->name,__func__);
-#endif
 
                 /*
                 *  if More-To-Come is set in this frame then we don't know
@@ -3496,15 +2569,6 @@ unpack_next:
 
                 if (bytes_to_mov > (MAX_ENVELOPE_SIZE- privptr->mtc_offset) ) {
                         /*      error     */
-#ifdef DEBUGMSG
-                        printk(KERN_INFO "%s: %s > goto next "
-                               "frame from MoretoComeSkip \n",
-                               dev->name,
-                               __func__);
-                        printk(KERN_INFO "      bytes_to_mov %d > (MAX_ENVELOPE_"
-                               "SIZE-privptr->mtc_offset %d)\n",
-                               bytes_to_mov,(MAX_ENVELOPE_SIZE- privptr->mtc_offset));
-#endif
                         privptr->stats.rx_frame_errors++;
                         goto NextFrame;
                 }
@@ -3516,16 +2580,6 @@ unpack_next:
                        memcpy( privptr->p_mtc_envelope+ privptr->mtc_offset,
                                p_this_ccw->p_buffer, bytes_to_mov);
                }
-#ifdef DEBUGMSG
-                printk(KERN_INFO "%s: %s() received data \n",
-                       dev->name,__func__);
-               if (p_env->packing == DO_PACKED)
-                       dumpit((char *)p_packd+sizeof(struct clawph),32);
-               else
-                       dumpit((char *)p_this_ccw->p_buffer, 32);
-               printk(KERN_INFO "%s: %s() bytelength %d \n",
-                       dev->name,__func__,bytes_to_mov);
-#endif
                 if (mtc_this_frm==0) {
                         len_of_data=privptr->mtc_offset+bytes_to_mov;
                         skb=dev_alloc_skb(len_of_data);
@@ -3540,11 +2594,6 @@ unpack_next:
                                 privptr->stats.rx_packets++;
                                privptr->stats.rx_bytes+=len_of_data;
                                 netif_rx(skb);
-#ifdef DEBUGMSG
-                                printk(KERN_INFO "%s: %s() netif_"
-                                       "rx(skb) completed \n",
-                                       dev->name,__func__);
-#endif
                         }
                         else {
                                 privptr->stats.rx_dropped++;
@@ -3581,28 +2630,14 @@ NextFrame:
                 *       chain to next block on active read queue
                 */
                 p_this_ccw = privptr->p_read_active_first;
-               CLAW_DBF_TEXT_(4,trace,"rxpkt %d",p);
+               CLAW_DBF_TEXT_(4, trace, "rxpkt %d", p);
         } /* end of while */
 
         /*      check validity                  */
 
-#ifdef IOTRACE
-        printk(KERN_INFO "%s:%s processed frame is %d \n",
-               dev->name,__func__,i);
-        printk(KERN_INFO "%s:%s  F:%lx L:%lx\n",
-               dev->name,
-               __func__,
-               (unsigned long)p_first_ccw,
-               (unsigned long)p_last_ccw);
-#endif
-       CLAW_DBF_TEXT_(4,trace,"rxfrm %d",i);
+       CLAW_DBF_TEXT_(4, trace, "rxfrm %d", i);
         add_claw_reads(dev, p_first_ccw, p_last_ccw);
-        p_ch=&privptr->channel[READ];
         claw_strt_read(dev, LOCK_YES);
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s: %s exit on line %d\n",
-               dev->name, __func__, __LINE__);
-#endif
         return;
 }     /*  end of unpack_read   */
 
@@ -3622,12 +2657,7 @@ claw_strt_read (struct net_device *dev, int lock )
         struct clawh *p_clawh;
         p_ch=&privptr->channel[READ];
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter  \n",dev->name,__func__);
-        printk(KERN_INFO "%s: variable lock = %d, dev =\n",dev->name, lock);
-        dumpit((char *) dev, sizeof(struct net_device));
-#endif
-       CLAW_DBF_TEXT(4,trace,"StRdNter");
+       CLAW_DBF_TEXT(4, trace, "StRdNter");
         p_clawh=(struct clawh *)privptr->p_claw_signal_blk;
         p_clawh->flag=CLAW_IDLE;    /* 0x00 */
 
@@ -3637,21 +2667,11 @@ claw_strt_read (struct net_device *dev, int lock )
              privptr->p_read_active_first->header.flag!=CLAW_PENDING )) {
                 p_clawh->flag=CLAW_BUSY;    /* 0xff */
         }
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s:%s state-%02x\n" ,
-               dev->name,__func__, p_ch->claw_state);
-#endif
         if (lock==LOCK_YES) {
                 spin_lock_irqsave(get_ccwdev_lock(p_ch->cdev), saveflags);
         }
         if (test_and_set_bit(0, (void *)&p_ch->IO_active) == 0) {
-#ifdef DEBUGMSG
-                printk(KERN_INFO "%s: HOT READ started in %s\n" ,
-                       dev->name,__func__);
-                p_clawh=(struct clawh *)privptr->p_claw_signal_blk;
-                dumpit((char *)&p_clawh->flag , 1);
-#endif
-               CLAW_DBF_TEXT(4,trace,"HotRead");
+               CLAW_DBF_TEXT(4, trace, "HotRead");
                 p_ccwbk=privptr->p_read_active_first;
                 parm = (unsigned long) p_ch;
                 rc = ccw_device_start (p_ch->cdev, &p_ccwbk->read, parm,
@@ -3661,21 +2681,13 @@ claw_strt_read (struct net_device *dev, int lock )
                 }
         }
        else {
-#ifdef DEBUGMSG
-               printk(KERN_INFO "%s: No READ started by %s() In progress\n" ,
-                       dev->name,__func__);
-#endif
-               CLAW_DBF_TEXT(2,trace,"ReadAct");
+               CLAW_DBF_TEXT(2, trace, "ReadAct");
        }
 
         if (lock==LOCK_YES) {
                 spin_unlock_irqrestore(get_ccwdev_lock(p_ch->cdev), saveflags);
         }
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s:%s Exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
-       CLAW_DBF_TEXT(4,trace,"StRdExit");
+       CLAW_DBF_TEXT(4, trace, "StRdExit");
         return;
 }       /*    end of claw_strt_read    */
 
@@ -3693,38 +2705,23 @@ claw_strt_out_IO( struct net_device *dev )
         struct chbk            *p_ch;
         struct ccwbk           *p_first_ccw;
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter\n",dev->name,__func__);
-#endif
        if (!dev) {
                return;
        }
         privptr=(struct claw_privbk *)dev->priv;
         p_ch=&privptr->channel[WRITE];
 
-#ifdef DEBUGMSG
-        printk(KERN_INFO "%s:%s state-%02x\n" ,
-               dev->name,__func__,p_ch->claw_state);
-#endif
-        CLAW_DBF_TEXT(4,trace,"strt_io");
+       CLAW_DBF_TEXT(4, trace, "strt_io");
         p_first_ccw=privptr->p_write_active_first;
 
         if (p_ch->claw_state == CLAW_STOP)
                 return;
         if (p_first_ccw == NULL) {
-#ifdef FUNCTRACE
-                printk(KERN_INFO "%s:%s Exit on line %d\n",
-                       dev->name,__func__,__LINE__);
-#endif
                 return;
         }
         if (test_and_set_bit(0, (void *)&p_ch->IO_active) == 0) {
                 parm = (unsigned long) p_ch;
-#ifdef DEBUGMSG
-               printk(KERN_INFO "%s:%s do_io \n" ,dev->name,__func__);
-                dumpit((char *)p_first_ccw, sizeof(struct ccwbk));
-#endif
-               CLAW_DBF_TEXT(2,trace,"StWrtIO");
+               CLAW_DBF_TEXT(2, trace, "StWrtIO");
                 rc = ccw_device_start (p_ch->cdev,&p_first_ccw->write, parm,
                                       0xff, 0);
                 if (rc != 0) {
@@ -3732,11 +2729,6 @@ claw_strt_out_IO( struct net_device *dev )
                 }
         }
         dev->trans_start = jiffies;
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Exit on line %d\n",
-               dev->name,__func__,__LINE__);
-#endif
-
         return;
 }       /*    end of claw_strt_out_IO    */
 
@@ -3754,32 +2746,11 @@ claw_free_wrt_buf( struct net_device *dev )
        struct ccwbk*p_last_ccw;
        struct ccwbk*p_this_ccw;
        struct ccwbk*p_next_ccw;
-#ifdef IOTRACE
-        struct ccwbk*p_buf;
-#endif
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter\n",dev->name,__func__);
-        printk(KERN_INFO "%s: free count = %d  variable dev =\n",
-               dev->name,privptr->write_free_count);
-#endif
-       CLAW_DBF_TEXT(4,trace,"freewrtb");
+
+       CLAW_DBF_TEXT(4, trace, "freewrtb");
         /*  scan the write queue to free any completed write packets   */
         p_first_ccw=NULL;
         p_last_ccw=NULL;
-#ifdef IOTRACE
-        printk(KERN_INFO "%s:  Dump current CCW chain \n",dev->name  );
-        p_buf=privptr->p_write_active_first;
-        while (p_buf!=NULL) {
-                dumpit((char *)p_buf, sizeof(struct ccwbk));
-                p_buf=p_buf->next;
-        }
-        if (p_buf==NULL) {
-                printk(KERN_INFO "%s: privptr->p_write_"
-                       "active_first==NULL\n",dev->name  );
-        }
-        p_buf=(struct ccwbk*)privptr->p_end_ccw;
-        dumpit((char *)p_buf, sizeof(struct endccw));
-#endif
         p_this_ccw=privptr->p_write_active_first;
         while ( (p_this_ccw!=NULL) && (p_this_ccw->header.flag!=CLAW_PENDING))
         {
@@ -3809,31 +2780,8 @@ claw_free_wrt_buf( struct net_device *dev )
         /*   whole chain removed?   */
         if (privptr->p_write_active_first==NULL) {
                 privptr->p_write_active_last=NULL;
-#ifdef DEBUGMSG
-                printk(KERN_INFO "%s:%s p_write_"
-                       "active_first==NULL\n",dev->name,__func__);
-#endif
-        }
-#ifdef IOTRACE
-        printk(KERN_INFO "%s: Dump arranged CCW chain \n",dev->name  );
-        p_buf=privptr->p_write_active_first;
-        while (p_buf!=NULL) {
-                dumpit((char *)p_buf, sizeof(struct ccwbk));
-                p_buf=p_buf->next;
         }
-        if (p_buf==NULL) {
-                printk(KERN_INFO "%s: privptr->p_write_active_"
-                       "first==NULL\n",dev->name  );
-        }
-        p_buf=(struct ccwbk*)privptr->p_end_ccw;
-        dumpit((char *)p_buf, sizeof(struct endccw));
-#endif
-
-       CLAW_DBF_TEXT_(4,trace,"FWC=%d",privptr->write_free_count);
-#ifdef FUNCTRACE
-        printk(KERN_INFO "%s:%s Exit on line %d free_count =%d\n",
-               dev->name,__func__, __LINE__,privptr->write_free_count);
-#endif
+       CLAW_DBF_TEXT_(4, trace, "FWC=%d", privptr->write_free_count);
         return;
 }
 
@@ -3845,14 +2793,11 @@ static void
 claw_free_netdevice(struct net_device * dev, int free_dev)
 {
        struct claw_privbk *privptr;
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter\n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(2,setup,"free_dev");
 
+       CLAW_DBF_TEXT(2, setup, "free_dev");
        if (!dev)
                return;
-       CLAW_DBF_TEXT_(2,setup,"%s",dev->name);
+       CLAW_DBF_TEXT_(2, setup, "%s", dev->name);
        privptr = dev->priv;
        if (dev->flags & IFF_RUNNING)
                claw_release(dev);
@@ -3865,10 +2810,7 @@ claw_free_netdevice(struct net_device * dev, int free_dev)
                free_netdev(dev);
        }
 #endif
-       CLAW_DBF_TEXT(2,setup,"feee_ok");
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Exit\n",dev->name,__func__);
-#endif
+       CLAW_DBF_TEXT(2, setup, "free_ok");
 }
 
 /**
@@ -3879,17 +2821,8 @@ claw_free_netdevice(struct net_device * dev, int free_dev)
 static void
 claw_init_netdevice(struct net_device * dev)
 {
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter\n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(2,setup,"init_dev");
-       CLAW_DBF_TEXT_(2,setup,"%s",dev->name);
-       if (!dev) {
-        printk(KERN_WARNING "claw:%s BAD Device exit line %d\n",
-               __func__,__LINE__);
-               CLAW_DBF_TEXT(2,setup,"baddev");
-               return;
-       }
+       CLAW_DBF_TEXT(2, setup, "init_dev");
+       CLAW_DBF_TEXT_(2, setup, "%s", dev->name);
        dev->mtu = CLAW_DEFAULT_MTU_SIZE;
        dev->hard_start_xmit = claw_tx;
        dev->open = claw_open;
@@ -3901,10 +2834,7 @@ claw_init_netdevice(struct net_device * dev)
        dev->type = ARPHRD_SLIP;
        dev->tx_queue_len = 1300;
        dev->flags = IFF_POINTOPOINT | IFF_NOARP;
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Exit\n",dev->name,__func__);
-#endif
-       CLAW_DBF_TEXT(2,setup,"initok");
+       CLAW_DBF_TEXT(2, setup, "initok");
        return;
 }
 
@@ -3921,10 +2851,7 @@ add_channel(struct ccw_device *cdev,int i,struct claw_privbk *privptr)
        struct chbk *p_ch;
        struct ccw_dev_id dev_id;
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "%s:%s Enter\n",cdev->dev.bus_id,__func__);
-#endif
-       CLAW_DBF_TEXT_(2,setup,"%s",cdev->dev.bus_id);
+       CLAW_DBF_TEXT_(2, setup, "%s", cdev->dev.bus_id);
        privptr->channel[i].flag  = i+1;   /* Read is 1 Write is 2 */
        p_ch = &privptr->channel[i];
        p_ch->cdev = cdev;
@@ -3932,18 +2859,8 @@ add_channel(struct ccw_device *cdev,int i,struct claw_privbk *privptr)
        ccw_device_get_id(cdev, &dev_id);
        p_ch->devno = dev_id.devno;
        if ((p_ch->irb = kzalloc(sizeof (struct irb),GFP_KERNEL)) == NULL) {
-               printk(KERN_WARNING "%s Out of memory in %s for irb\n",
-                       p_ch->id,__func__);
-#ifdef FUNCTRACE
-               printk(KERN_INFO "%s:%s Exit on line %d\n",
-                       p_ch->id,__func__,__LINE__);
-#endif
                return -ENOMEM;
        }
-#ifdef FUNCTRACE
-               printk(KERN_INFO "%s:%s Exit on line %d\n",
-                       cdev->dev.bus_id,__func__,__LINE__);
-#endif
        return 0;
 }
 
@@ -3965,9 +2882,8 @@ claw_new_device(struct ccwgroup_device *cgdev)
        int ret;
        struct ccw_dev_id dev_id;
 
-       pr_debug("%s() called\n", __func__);
        printk(KERN_INFO "claw: add for %s\n",cgdev->cdev[READ]->dev.bus_id);
-       CLAW_DBF_TEXT(2,setup,"new_dev");
+       CLAW_DBF_TEXT(2, setup, "new_dev");
        privptr = cgdev->dev.driver_data;
        cgdev->cdev[READ]->dev.driver_data = privptr;
        cgdev->cdev[WRITE]->dev.driver_data = privptr;
@@ -3982,22 +2898,21 @@ claw_new_device(struct ccwgroup_device *cgdev)
        if (ret == 0)
                ret = add_channel(cgdev->cdev[1],1,privptr);
        if (ret != 0) {
-                       printk(KERN_WARNING
-                       "add channel failed "
-                               "with ret = %d\n", ret);
-                       goto out;
+               printk(KERN_WARNING
+                       "add channel failed with ret = %d\n", ret);
+               goto out;
        }
        ret = ccw_device_set_online(cgdev->cdev[READ]);
        if (ret != 0) {
                printk(KERN_WARNING
-                "claw: ccw_device_set_online %s READ failed "
+                       "claw: ccw_device_set_online %s READ failed "
                        "with ret = %d\n",cgdev->cdev[READ]->dev.bus_id,ret);
                goto out;
        }
        ret = ccw_device_set_online(cgdev->cdev[WRITE]);
        if (ret != 0) {
                printk(KERN_WARNING
-                "claw: ccw_device_set_online %s WRITE failed "
+                       "claw: ccw_device_set_online %s WRITE failed "
                        "with ret = %d\n",cgdev->cdev[WRITE]->dev.bus_id, ret);
                goto out;
        }
@@ -4014,18 +2929,16 @@ claw_new_device(struct ccwgroup_device *cgdev)
         SET_NETDEV_DEV(dev, &cgdev->dev);
        if (register_netdev(dev) != 0) {
                claw_free_netdevice(dev, 1);
-               CLAW_DBF_TEXT(2,trace,"regfail");
+               CLAW_DBF_TEXT(2, trace, "regfail");
                goto out;
        }
        dev->flags &=~IFF_RUNNING;
        if (privptr->buffs_alloc == 0) {
                ret=init_ccw_bk(dev);
                if (ret !=0) {
-                       printk(KERN_WARNING
-                        "claw: init_ccw_bk failed with ret=%d\n", ret);
                        unregister_netdev(dev);
                        claw_free_netdevice(dev,1);
-                       CLAW_DBF_TEXT(2,trace,"ccwmem");
+                       CLAW_DBF_TEXT(2, trace, "ccwmem");
                        goto out;
                }
        }
@@ -4047,7 +2960,6 @@ claw_new_device(struct ccwgroup_device *cgdev)
 out:
        ccw_device_set_offline(cgdev->cdev[1]);
        ccw_device_set_offline(cgdev->cdev[0]);
-
        return -ENODEV;
 }
 
@@ -4056,8 +2968,7 @@ claw_purge_skb_queue(struct sk_buff_head *q)
 {
         struct sk_buff *skb;
 
-        CLAW_DBF_TEXT(4,trace,"purgque");
-
+       CLAW_DBF_TEXT(4, trace, "purgque");
         while ((skb = skb_dequeue(q))) {
                 atomic_dec(&skb->users);
                 dev_kfree_skb_any(skb);
@@ -4078,8 +2989,7 @@ claw_shutdown_device(struct ccwgroup_device *cgdev)
        struct net_device *ndev;
        int     ret;
 
-       pr_debug("%s() called\n", __func__);
-       CLAW_DBF_TEXT_(2,setup,"%s",cgdev->dev.bus_id);
+       CLAW_DBF_TEXT_(2, setup, "%s", cgdev->dev.bus_id);
        priv = cgdev->dev.driver_data;
        if (!priv)
                return -ENODEV;
@@ -4108,13 +3018,10 @@ claw_remove_device(struct ccwgroup_device *cgdev)
 {
        struct claw_privbk *priv;
 
-       pr_debug("%s() called\n", __func__);
-       CLAW_DBF_TEXT_(2,setup,"%s",cgdev->dev.bus_id);
+       BUG_ON(!cgdev);
+       CLAW_DBF_TEXT_(2, setup, "%s", cgdev->dev.bus_id);
        priv = cgdev->dev.driver_data;
-       if (!priv) {
-               printk(KERN_WARNING "claw: %s() no Priv exiting\n",__func__);
-               return;
-       }
+       BUG_ON(!priv);
        printk(KERN_INFO "claw: %s() called %s will be removed.\n",
                        __func__,cgdev->cdev[0]->dev.bus_id);
        if (cgdev->state == CCWGROUP_ONLINE)
@@ -4133,6 +3040,8 @@ claw_remove_device(struct ccwgroup_device *cgdev)
        cgdev->cdev[READ]->dev.driver_data = NULL;
        cgdev->cdev[WRITE]->dev.driver_data = NULL;
        put_device(&cgdev->dev);
+
+       return;
 }
 
 
@@ -4168,8 +3077,8 @@ claw_hname_write(struct device *dev, struct device_attribute *attr, const char *
        strncpy(p_env->host_name,buf, count);
        p_env->host_name[count-1] = 0x20;  /* clear extra 0x0a */
        p_env->host_name[MAX_NAME_LEN] = 0x00;
-       CLAW_DBF_TEXT(2,setup,"HstnSet");
-        CLAW_DBF_TEXT_(2,setup,"%s",p_env->host_name);
+       CLAW_DBF_TEXT(2, setup, "HstnSet");
+       CLAW_DBF_TEXT_(2, setup, "%s", p_env->host_name);
 
        return count;
 }
@@ -4186,7 +3095,7 @@ claw_adname_show(struct device *dev, struct device_attribute *attr, char *buf)
        if (!priv)
                return -ENODEV;
        p_env = priv->p_env;
-       return sprintf(buf, "%s\n",p_env->adapter_name);
+       return sprintf(buf, "%s\n", p_env->adapter_name);
 }
 
 static ssize_t
@@ -4205,8 +3114,8 @@ claw_adname_write(struct device *dev, struct device_attribute *attr, const char
        strncpy(p_env->adapter_name,buf, count);
        p_env->adapter_name[count-1] = 0x20; /* clear extra 0x0a */
        p_env->adapter_name[MAX_NAME_LEN] = 0x00;
-       CLAW_DBF_TEXT(2,setup,"AdnSet");
-       CLAW_DBF_TEXT_(2,setup,"%s",p_env->adapter_name);
+       CLAW_DBF_TEXT(2, setup, "AdnSet");
+       CLAW_DBF_TEXT_(2, setup, "%s", p_env->adapter_name);
 
        return count;
 }
@@ -4247,15 +3156,15 @@ claw_apname_write(struct device *dev, struct device_attribute *attr, const char
                p_env->read_size=DEF_PACK_BUFSIZE;
                p_env->write_size=DEF_PACK_BUFSIZE;
                p_env->packing=PACKING_ASK;
-               CLAW_DBF_TEXT(2,setup,"PACKING");
+               CLAW_DBF_TEXT(2, setup, "PACKING");
        }
        else {
                p_env->packing=0;
                p_env->read_size=CLAW_FRAME_SIZE;
                p_env->write_size=CLAW_FRAME_SIZE;
-               CLAW_DBF_TEXT(2,setup,"ApiSet");
+               CLAW_DBF_TEXT(2, setup, "ApiSet");
        }
-       CLAW_DBF_TEXT_(2,setup,"%s",p_env->api_type);
+       CLAW_DBF_TEXT_(2, setup, "%s", p_env->api_type);
        return count;
 }
 
@@ -4295,8 +3204,8 @@ claw_wbuff_write(struct device *dev, struct device_attribute *attr, const char *
        if ((nnn > max ) || (nnn < 2))
                return -EINVAL;
        p_env->write_buffers = nnn;
-       CLAW_DBF_TEXT(2,setup,"Wbufset");
-        CLAW_DBF_TEXT_(2,setup,"WB=%d",p_env->write_buffers);
+       CLAW_DBF_TEXT(2, setup, "Wbufset");
+       CLAW_DBF_TEXT_(2, setup, "WB=%d", p_env->write_buffers);
        return count;
 }
 
@@ -4336,8 +3245,8 @@ claw_rbuff_write(struct device *dev, struct device_attribute *attr, const char *
        if ((nnn > max ) || (nnn < 2))
                return -EINVAL;
        p_env->read_buffers = nnn;
-       CLAW_DBF_TEXT(2,setup,"Rbufset");
-       CLAW_DBF_TEXT_(2,setup,"RB=%d",p_env->read_buffers);
+       CLAW_DBF_TEXT(2, setup, "Rbufset");
+       CLAW_DBF_TEXT_(2, setup, "RB=%d", p_env->read_buffers);
        return count;
 }
 
@@ -4359,16 +3268,14 @@ static struct attribute_group claw_attr_group = {
 static int
 claw_add_files(struct device *dev)
 {
-       pr_debug("%s() called\n", __func__);
-       CLAW_DBF_TEXT(2,setup,"add_file");
+       CLAW_DBF_TEXT(2, setup, "add_file");
        return sysfs_create_group(&dev->kobj, &claw_attr_group);
 }
 
 static void
 claw_remove_files(struct device *dev)
 {
-       pr_debug("%s() called\n", __func__);
-       CLAW_DBF_TEXT(2,setup,"rem_file");
+       CLAW_DBF_TEXT(2, setup, "rem_file");
        sysfs_remove_group(&dev->kobj, &claw_attr_group);
 }
 
@@ -4397,35 +3304,27 @@ claw_init(void)
        int ret = 0;
        printk(KERN_INFO "claw: starting driver\n");
 
-#ifdef FUNCTRACE
-       printk(KERN_INFO "claw: %s() enter \n",__func__);
-#endif
        ret = claw_register_debug_facility();
        if (ret) {
                printk(KERN_WARNING "claw: %s() debug_register failed %d\n",
                        __func__,ret);
                return ret;
        }
-       CLAW_DBF_TEXT(2,setup,"init_mod");
+       CLAW_DBF_TEXT(2, setup, "init_mod");
        ret = register_cu3088_discipline(&claw_group_driver);
        if (ret) {
+               CLAW_DBF_TEXT(2, setup, "init_bad");
                claw_unregister_debug_facility();
                printk(KERN_WARNING "claw; %s() cu3088 register failed %d\n",
                        __func__,ret);
        }
-#ifdef FUNCTRACE
-       printk(KERN_INFO "claw: %s() exit \n",__func__);
-#endif
        return ret;
 }
 
 module_init(claw_init);
 module_exit(claw_cleanup);
 
-
-
-/*--------------------------------------------------------------------*
-*    End of File                                                      *
-*---------------------------------------------------------------------*/
-
-
+MODULE_AUTHOR("Andy Richter <richtera@us.ibm.com>");
+MODULE_DESCRIPTION("Linux for System z CLAW Driver\n" \
+                       "Copyright 2000,2008 IBM Corporation\n");
+MODULE_LICENSE("GPL");
index 8eb25d00b2e7de8ab9c485db5f476949fba9e42d..1ca58f15347048b775beb879012faf3e383a6f1b 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/stddef.h>
+#include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
  * Debug Facility Stuff
  */
 
-DEFINE_PER_CPU(char[256], ctcm_dbf_txt_buf);
-
 struct ctcm_dbf_info ctcm_dbf[CTCM_DBF_INFOS] = {
-       [CTCM_DBF_SETUP]        = {"ctc_setup", 8, 1, 64, 5, NULL},
-       [CTCM_DBF_ERROR]        = {"ctc_error", 8, 1, 64, 3, NULL},
-       [CTCM_DBF_TRACE]        = {"ctc_trace", 8, 1, 64, 3, NULL},
-       [CTCM_DBF_MPC_SETUP]    = {"mpc_setup", 8, 1, 64, 5, NULL},
-       [CTCM_DBF_MPC_ERROR]    = {"mpc_error", 8, 1, 64, 3, NULL},
-       [CTCM_DBF_MPC_TRACE]    = {"mpc_trace", 8, 1, 64, 3, NULL},
+       [CTCM_DBF_SETUP]     = {"ctc_setup", 8, 1, 64, CTC_DBF_INFO, NULL},
+       [CTCM_DBF_ERROR]     = {"ctc_error", 8, 1, 64, CTC_DBF_ERROR, NULL},
+       [CTCM_DBF_TRACE]     = {"ctc_trace", 8, 1, 64, CTC_DBF_ERROR, NULL},
+       [CTCM_DBF_MPC_SETUP] = {"mpc_setup", 8, 1, 80, CTC_DBF_INFO, NULL},
+       [CTCM_DBF_MPC_ERROR] = {"mpc_error", 8, 1, 80, CTC_DBF_ERROR, NULL},
+       [CTCM_DBF_MPC_TRACE] = {"mpc_trace", 8, 1, 80, CTC_DBF_ERROR, NULL},
 };
 
 void ctcm_unregister_dbf_views(void)
@@ -65,3 +64,17 @@ int ctcm_register_dbf_views(void)
        return 0;
 }
 
+void ctcm_dbf_longtext(enum ctcm_dbf_names dbf_nix, int level, char *fmt, ...)
+{
+       char dbf_txt_buf[64];
+       va_list args;
+
+       if (level > (ctcm_dbf[dbf_nix].id)->level)
+               return;
+       va_start(args, fmt);
+       vsnprintf(dbf_txt_buf, sizeof(dbf_txt_buf), fmt, args);
+       va_end(args);
+
+       debug_text_event(ctcm_dbf[dbf_nix].id, level, dbf_txt_buf);
+}
+
index fdff34fe59a2e994edb39260a89233e3d876f855..26966d0b9abd1191e3413afa7ca3bcbe42848ddc 100644 (file)
 #else
  #define do_debug 0
 #endif
-#ifdef DEBUGDATA
- #define do_debug_data 1
-#else
- #define do_debug_data 0
-#endif
 #ifdef DEBUGCCW
  #define do_debug_ccw 1
+ #define DEBUGDATA 1
 #else
  #define do_debug_ccw 0
 #endif
+#ifdef DEBUGDATA
+ #define do_debug_data 1
+#else
+ #define do_debug_data 0
+#endif
 
 /* define dbf debug levels similar to kernel msg levels */
 #define        CTC_DBF_ALWAYS  0       /* always print this                    */
@@ -42,8 +43,6 @@
 #define        CTC_DBF_INFO    5       /* informational                        */
 #define        CTC_DBF_DEBUG   6       /* debug-level messages                 */
 
-DECLARE_PER_CPU(char[256], ctcm_dbf_txt_buf);
-
 enum ctcm_dbf_names {
        CTCM_DBF_SETUP,
        CTCM_DBF_ERROR,
@@ -67,6 +66,7 @@ extern struct ctcm_dbf_info ctcm_dbf[CTCM_DBF_INFOS];
 
 int ctcm_register_dbf_views(void);
 void ctcm_unregister_dbf_views(void);
+void ctcm_dbf_longtext(enum ctcm_dbf_names dbf_nix, int level, char *text, ...);
 
 static inline const char *strtail(const char *s, int n)
 {
@@ -74,12 +74,6 @@ static inline const char *strtail(const char *s, int n)
        return (l > n) ? s + (l - n) : s;
 }
 
-/* sort out levels early to avoid unnecessary sprintfs */
-static inline int ctcm_dbf_passes(debug_info_t *dbf_grp, int level)
-{
-       return (dbf_grp->level >= level);
-}
-
 #define CTCM_FUNTAIL strtail((char *)__func__, 16)
 
 #define CTCM_DBF_TEXT(name, level, text) \
@@ -94,16 +88,7 @@ static inline int ctcm_dbf_passes(debug_info_t *dbf_grp, int level)
        } while (0)
 
 #define CTCM_DBF_TEXT_(name, level, text...) \
-       do { \
-               if (ctcm_dbf_passes(ctcm_dbf[CTCM_DBF_##name].id, level)) { \
-                       char *ctcm_dbf_txt_buf = \
-                                        get_cpu_var(ctcm_dbf_txt_buf); \
-                       sprintf(ctcm_dbf_txt_buf, text); \
-                       debug_text_event(ctcm_dbf[CTCM_DBF_##name].id, \
-                                       level, ctcm_dbf_txt_buf); \
-                       put_cpu_var(ctcm_dbf_txt_buf); \
-               } \
-       } while (0)
+       ctcm_dbf_longtext(CTCM_DBF_##name, level, text)
 
 /*
  * cat : one of {setup, mpc_setup, trace, mpc_trace, error, mpc_error}.
@@ -112,13 +97,13 @@ static inline int ctcm_dbf_passes(debug_info_t *dbf_grp, int level)
  */
 #define CTCM_DBF_DEV_NAME(cat, dev, text) \
        do { \
-               CTCM_DBF_TEXT_(cat, CTC_DBF_INFO, "%s(%s) : %s", \
+               CTCM_DBF_TEXT_(cat, CTC_DBF_INFO, "%s(%s) :- %s", \
                        CTCM_FUNTAIL, dev->name, text); \
        } while (0)
 
 #define MPC_DBF_DEV_NAME(cat, dev, text) \
        do { \
-               CTCM_DBF_TEXT_(MPC_##cat, CTC_DBF_INFO, "%s(%s) : %s", \
+               CTCM_DBF_TEXT_(MPC_##cat, CTC_DBF_INFO, "%s(%s) := %s", \
                        CTCM_FUNTAIL, dev->name, text); \
        } while (0)
 
@@ -137,13 +122,13 @@ static inline int ctcm_dbf_passes(debug_info_t *dbf_grp, int level)
  */
 #define CTCM_DBF_DEV(cat, dev, text) \
        do { \
-               CTCM_DBF_TEXT_(cat, CTC_DBF_INFO, "%s(%p) : %s", \
+               CTCM_DBF_TEXT_(cat, CTC_DBF_INFO, "%s(%p) :-: %s", \
                        CTCM_FUNTAIL, dev, text); \
        } while (0)
 
 #define MPC_DBF_DEV(cat, dev, text) \
        do { \
-               CTCM_DBF_TEXT_(MPC_##cat, CTC_DBF_INFO, "%s(%p) : %s", \
+               CTCM_DBF_TEXT_(MPC_##cat, CTC_DBF_INFO, "%s(%p) :=: %s", \
                        CTCM_FUNTAIL, dev, text); \
        } while (0)
 
index 7e6bd387f4d889f628929bd3fe08d5d212abc082..0b4e6253abe4438b4893edab7fa25fb04ef555ef 100644 (file)
@@ -190,7 +190,8 @@ static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg);
 void ctcm_ccw_check_rc(struct channel *ch, int rc, char *msg)
 {
        CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
-                       "ccw error %s (%s): %04x\n", ch->id, msg, rc);
+                       "%s(%s): %s: %04x\n",
+                               CTCM_FUNTAIL, ch->id, msg, rc);
        switch (rc) {
        case -EBUSY:
                ctcm_pr_warn("%s (%s): Busy !\n", ch->id, msg);
@@ -212,7 +213,7 @@ void ctcm_purge_skb_queue(struct sk_buff_head *q)
 {
        struct sk_buff *skb;
 
-       CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
+       CTCM_DBF_TEXT(TRACE, CTC_DBF_DEBUG, __func__);
 
        while ((skb = skb_dequeue(q))) {
                atomic_dec(&skb->users);
@@ -251,6 +252,8 @@ static void chx_txdone(fsm_instance *fi, int event, void *arg)
        unsigned long duration;
        struct timespec done_stamp = current_kernel_time(); /* xtime */
 
+       CTCM_PR_DEBUG("%s(%s): %s\n", __func__, ch->id, dev->name);
+
        duration =
            (done_stamp.tv_sec - ch->prof.send_stamp.tv_sec) * 1000000 +
            (done_stamp.tv_nsec - ch->prof.send_stamp.tv_nsec) / 1000;
@@ -258,8 +261,9 @@ static void chx_txdone(fsm_instance *fi, int event, void *arg)
                ch->prof.tx_time = duration;
 
        if (ch->irb->scsw.cmd.count != 0)
-               ctcm_pr_debug("%s: TX not complete, remaining %d bytes\n",
-                            dev->name, ch->irb->scsw.cmd.count);
+               CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
+                       "%s(%s): TX not complete, remaining %d bytes",
+                            CTCM_FUNTAIL, dev->name, ch->irb->scsw.cmd.count);
        fsm_deltimer(&ch->timer);
        while ((skb = skb_dequeue(&ch->io_queue))) {
                priv->stats.tx_packets++;
@@ -334,7 +338,8 @@ void ctcm_chx_txidle(fsm_instance *fi, int event, void *arg)
        struct net_device *dev = ch->netdev;
        struct ctcm_priv *priv = dev->priv;
 
-       CTCM_DBF_TEXT(TRACE, 6, __FUNCTION__);
+       CTCM_PR_DEBUG("%s(%s): %s\n", __func__, ch->id, dev->name);
+
        fsm_deltimer(&ch->timer);
        fsm_newstate(fi, CTC_STATE_TXIDLE);
        fsm_event(priv->fsm, DEV_EVENT_TXUP, ch->netdev);
@@ -361,15 +366,17 @@ static void chx_rx(fsm_instance *fi, int event, void *arg)
 
        fsm_deltimer(&ch->timer);
        if (len < 8) {
-               ctcm_pr_debug("%s: got packet with length %d < 8\n",
-                            dev->name, len);
+               CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
+                       "%s(%s): got packet with length %d < 8\n",
+                                       CTCM_FUNTAIL, dev->name, len);
                priv->stats.rx_dropped++;
                priv->stats.rx_length_errors++;
                                                goto again;
        }
        if (len > ch->max_bufsize) {
-               ctcm_pr_debug("%s: got packet with length %d > %d\n",
-                            dev->name, len, ch->max_bufsize);
+               CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
+                       "%s(%s): got packet with length %d > %d\n",
+                               CTCM_FUNTAIL, dev->name, len, ch->max_bufsize);
                priv->stats.rx_dropped++;
                priv->stats.rx_length_errors++;
                                                goto again;
@@ -388,8 +395,9 @@ static void chx_rx(fsm_instance *fi, int event, void *arg)
                break;
        }
        if ((len < block_len) || (len > check_len)) {
-               ctcm_pr_debug("%s: got block length %d != rx length %d\n",
-                            dev->name, block_len, len);
+               CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
+                       "%s(%s): got block length %d != rx length %d\n",
+                               CTCM_FUNTAIL, dev->name, block_len, len);
                if (do_debug)
                        ctcmpc_dump_skb(skb, 0);
 
@@ -425,17 +433,23 @@ static void chx_rx(fsm_instance *fi, int event, void *arg)
  */
 static void chx_firstio(fsm_instance *fi, int event, void *arg)
 {
-       struct channel *ch = arg;
        int rc;
+       struct channel *ch = arg;
+       int fsmstate = fsm_getstate(fi);
 
-       CTCM_DBF_TEXT(TRACE, 6, __FUNCTION__);
+       CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
+               "%s(%s) : %02x",
+               CTCM_FUNTAIL, ch->id, fsmstate);
 
-       if (fsm_getstate(fi) == CTC_STATE_TXIDLE)
-               ctcm_pr_debug("%s: remote side issued READ?, init.\n", ch->id);
+       ch->sense_rc = 0;       /* reset unit check report control */
+       if (fsmstate == CTC_STATE_TXIDLE)
+               CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
+                       "%s(%s): remote side issued READ?, init.\n",
+                               CTCM_FUNTAIL, ch->id);
        fsm_deltimer(&ch->timer);
        if (ctcm_checkalloc_buffer(ch))
                return;
-       if ((fsm_getstate(fi) == CTC_STATE_SETUPWAIT) &&
+       if ((fsmstate == CTC_STATE_SETUPWAIT) &&
            (ch->protocol == CTCM_PROTO_OS390)) {
                /* OS/390 resp. z/OS */
                if (CHANNEL_DIRECTION(ch->flags) == READ) {
@@ -451,7 +465,6 @@ static void chx_firstio(fsm_instance *fi, int event, void *arg)
                }
                return;
        }
-
        /*
         * Don't setup a timer for receiving the initial RX frame
         * if in compatibility mode, since VM TCP delays the initial
@@ -505,11 +518,10 @@ static void chx_rxidle(fsm_instance *fi, int event, void *arg)
        __u16 buflen;
        int rc;
 
-       CTCM_DBF_TEXT(TRACE, 6, __FUNCTION__);
        fsm_deltimer(&ch->timer);
        buflen = *((__u16 *)ch->trans_skb->data);
-       if (do_debug)
-               ctcm_pr_debug("%s: Initial RX count %d\n", dev->name, buflen);
+       CTCM_PR_DEBUG("%s: %s: Initial RX count = %d\n",
+                       __func__, dev->name, buflen);
 
        if (buflen >= CTCM_INITIAL_BLOCKLEN) {
                if (ctcm_checkalloc_buffer(ch))
@@ -524,9 +536,9 @@ static void chx_rxidle(fsm_instance *fi, int event, void *arg)
                } else
                        fsm_event(priv->fsm, DEV_EVENT_RXUP, dev);
        } else {
-               if (do_debug)
-                       ctcm_pr_debug("%s: Initial RX count %d not %d\n",
-                               dev->name, buflen, CTCM_INITIAL_BLOCKLEN);
+               CTCM_PR_DEBUG("%s: %s: Initial RX count %d not %d\n",
+                               __func__, dev->name,
+                                       buflen, CTCM_INITIAL_BLOCKLEN);
                chx_firstio(fi, event, arg);
        }
 }
@@ -548,14 +560,12 @@ static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg)
        fsm_deltimer(&ch->timer);
        if (IS_MPC(ch)) {
                timeout = 1500;
-               if (do_debug)
-                       ctcm_pr_debug("ctcm enter: %s(): cp=%i ch=0x%p id=%s\n",
-                               __FUNCTION__, smp_processor_id(), ch, ch->id);
+               CTCM_PR_DEBUG("enter %s: cp=%i ch=0x%p id=%s\n",
+                               __func__, smp_processor_id(), ch, ch->id);
        }
        fsm_addtimer(&ch->timer, timeout, CTC_EVENT_TIMER, ch);
        fsm_newstate(fi, CTC_STATE_SETUPWAIT);
-       if (do_debug_ccw && IS_MPC(ch))
-               ctcmpc_dumpit((char *)&ch->ccw[6], sizeof(struct ccw1) * 2);
+       CTCM_CCW_DUMP((char *)&ch->ccw[6], sizeof(struct ccw1) * 2);
 
        if (event == CTC_EVENT_TIMER)   /* only for timer not yet locked */
                spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
@@ -583,24 +593,12 @@ static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg)
  */
 static void ctcm_chx_start(fsm_instance *fi, int event, void *arg)
 {
-       struct channel *ch = arg;
-       int rc;
-       struct net_device *dev;
+       struct channel *ch      = arg;
        unsigned long saveflags;
+       int rc;
 
-       CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__);
-       if (ch == NULL) {
-               ctcm_pr_warn("chx_start ch=NULL\n");
-               return;
-       }
-       if (ch->netdev == NULL) {
-               ctcm_pr_warn("chx_start dev=NULL, id=%s\n", ch->id);
-               return;
-       }
-       dev = ch->netdev;
-
-       if (do_debug)
-               ctcm_pr_debug("%s: %s channel start\n", dev->name,
+       CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s(%s): %s",
+                       CTCM_FUNTAIL, ch->id,
                        (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
 
        if (ch->trans_skb != NULL) {
@@ -618,11 +616,12 @@ static void ctcm_chx_start(fsm_instance *fi, int event, void *arg)
                ch->ccw[1].count = 0;
        }
        if (ctcm_checkalloc_buffer(ch)) {
-               ctcm_pr_notice("%s: %s trans_skb allocation delayed "
-                               "until first transfer\n", dev->name,
+               CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
+                       "%s(%s): %s trans_skb alloc delayed "
+                       "until first transfer",
+                       CTCM_FUNTAIL, ch->id,
                        (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
        }
-
        ch->ccw[0].cmd_code = CCW_CMD_PREPARE;
        ch->ccw[0].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
        ch->ccw[0].count = 0;
@@ -661,7 +660,6 @@ static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg)
        int rc;
        int oldstate;
 
-       CTCM_DBF_TEXT(TRACE, 2, __FUNCTION__);
        fsm_deltimer(&ch->timer);
        if (IS_MPC(ch))
                fsm_deltimer(&ch->sweep_timer);
@@ -684,7 +682,7 @@ static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg)
                fsm_deltimer(&ch->timer);
                if (event != CTC_EVENT_STOP) {
                        fsm_newstate(fi, oldstate);
-                       ctcm_ccw_check_rc(ch, rc, (char *)__FUNCTION__);
+                       ctcm_ccw_check_rc(ch, rc, (char *)__func__);
                }
        }
 }
@@ -703,7 +701,9 @@ static void ctcm_chx_cleanup(fsm_instance *fi, int state,
        struct net_device *dev = ch->netdev;
        struct ctcm_priv *priv = dev->priv;
 
-       CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
+       CTCM_DBF_TEXT_(SETUP, CTC_DBF_NOTICE,
+                       "%s(%s): %s[%d]\n",
+                       CTCM_FUNTAIL, dev->name, ch->id, state);
 
        fsm_deltimer(&ch->timer);
        if (IS_MPC(ch))
@@ -743,7 +743,6 @@ static void ctcm_chx_cleanup(fsm_instance *fi, int state,
  */
 static void ctcm_chx_stopped(fsm_instance *fi, int event, void *arg)
 {
-       CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
        ctcm_chx_cleanup(fi, CTC_STATE_STOPPED, arg);
 }
 
@@ -771,7 +770,6 @@ static void ctcm_chx_stop(fsm_instance *fi, int event, void *arg)
  */
 static void ctcm_chx_fail(fsm_instance *fi, int event, void *arg)
 {
-       CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
        ctcm_chx_cleanup(fi, CTC_STATE_NOTOP, arg);
 }
 
@@ -809,8 +807,8 @@ static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg)
        }
 
        CTCM_DBF_TEXT_(ERROR, CTC_DBF_CRIT,
-               "%s : %s error during %s channel setup state=%s\n",
-               dev->name, ctc_ch_event_names[event],
+               "%s(%s) : %s error during %s channel setup state=%s\n",
+               CTCM_FUNTAIL, dev->name, ctc_ch_event_names[event],
                (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX",
                fsm_getstate_str(fi));
 
@@ -838,10 +836,12 @@ static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg)
        int oldstate;
        int rc;
 
-       CTCM_DBF_TEXT(TRACE, CTC_DBF_NOTICE, __FUNCTION__);
+       CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
+               "%s: %s[%d] of %s\n",
+                       CTCM_FUNTAIL, ch->id, event, dev->name);
+
        fsm_deltimer(&ch->timer);
-       ctcm_pr_debug("%s: %s channel restart\n", dev->name,
-                    (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
+
        fsm_addtimer(&ch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, ch);
        oldstate = fsm_getstate(fi);
        fsm_newstate(fi, CTC_STATE_STARTWAIT);
@@ -876,13 +876,10 @@ static void ctcm_chx_rxiniterr(fsm_instance *fi, int event, void *arg)
        struct net_device *dev = ch->netdev;
        struct ctcm_priv *priv = dev->priv;
 
-       CTCM_DBF_TEXT(SETUP, 3, __FUNCTION__);
        if (event == CTC_EVENT_TIMER) {
                if (!IS_MPCDEV(dev))
                        /* TODO : check if MPC deletes timer somewhere */
                        fsm_deltimer(&ch->timer);
-               ctcm_pr_debug("%s: Timeout during RX init handshake\n",
-                               dev->name);
                if (ch->retry++ < 3)
                        ctcm_chx_restart(fi, event, arg);
                else {
@@ -907,9 +904,10 @@ static void ctcm_chx_rxinitfail(fsm_instance *fi, int event, void *arg)
        struct net_device *dev = ch->netdev;
        struct ctcm_priv *priv = dev->priv;
 
-       CTCM_DBF_TEXT(SETUP, 3, __FUNCTION__);
+       CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
+                       "%s(%s): RX %s busy, init. fail",
+                               CTCM_FUNTAIL, dev->name, ch->id);
        fsm_newstate(fi, CTC_STATE_RXERR);
-       ctcm_pr_warn("%s: RX busy. Initialization failed\n", dev->name);
        fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);
 }
 
@@ -927,11 +925,10 @@ static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg)
        struct net_device *dev = ch->netdev;
        struct ctcm_priv *priv = dev->priv;
 
-       CTCM_DBF_DEV_NAME(TRACE, dev, "Got remote disconnect, re-initializing");
+       CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
+                       "%s: %s: remote disconnect - re-init ...",
+                               CTCM_FUNTAIL, dev->name);
        fsm_deltimer(&ch->timer);
-       if (do_debug)
-               ctcm_pr_debug("%s: Got remote disconnect, "
-                               "re-initializing ...\n", dev->name);
        /*
         * Notify device statemachine
         */
@@ -961,8 +958,6 @@ static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg)
 
        if (event == CTC_EVENT_TIMER) {
                fsm_deltimer(&ch->timer);
-               CTCM_DBF_DEV_NAME(ERROR, dev,
-                               "Timeout during TX init handshake");
                if (ch->retry++ < 3)
                        ctcm_chx_restart(fi, event, arg);
                else {
@@ -971,9 +966,8 @@ static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg)
                }
        } else {
                CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
-                       "%s : %s error during channel setup state=%s",
-                       dev->name, ctc_ch_event_names[event],
-                       fsm_getstate_str(fi));
+                       "%s(%s): %s in %s", CTCM_FUNTAIL, ch->id,
+                       ctc_ch_event_names[event], fsm_getstate_str(fi));
 
                ctcm_pr_warn("%s: Error during TX init handshake\n", dev->name);
        }
@@ -993,15 +987,15 @@ static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg)
        struct ctcm_priv *priv = dev->priv;
        struct sk_buff *skb;
 
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
-                       __FUNCTION__, smp_processor_id(), ch, ch->id);
+       CTCM_PR_DEBUG("Enter: %s: cp=%i ch=0x%p id=%s\n",
+                       __func__, smp_processor_id(), ch, ch->id);
 
        fsm_deltimer(&ch->timer);
        if (ch->retry++ > 3) {
                struct mpc_group *gptr = priv->mpcg;
-               ctcm_pr_debug("%s: TX retry failed, restarting channel\n",
-                            dev->name);
+               CTCM_DBF_TEXT_(TRACE, CTC_DBF_INFO,
+                               "%s: %s: retries exceeded",
+                                       CTCM_FUNTAIL, ch->id);
                fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);
                /* call restart if not MPC or if MPC and mpcg fsm is ready.
                        use gptr as mpc indicator */
@@ -1010,7 +1004,9 @@ static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg)
                                goto done;
        }
 
-       ctcm_pr_debug("%s: TX retry %d\n", dev->name, ch->retry);
+       CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
+                       "%s : %s: retry %d",
+                               CTCM_FUNTAIL, ch->id, ch->retry);
        skb = skb_peek(&ch->io_queue);
        if (skb) {
                int rc = 0;
@@ -1018,8 +1014,9 @@ static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg)
                clear_normalized_cda(&ch->ccw[4]);
                ch->ccw[4].count = skb->len;
                if (set_normalized_cda(&ch->ccw[4], skb->data)) {
-                       ctcm_pr_debug("%s: IDAL alloc failed, chan restart\n",
-                                               dev->name);
+                       CTCM_DBF_TEXT_(TRACE, CTC_DBF_INFO,
+                               "%s: %s: IDAL alloc failed",
+                                               CTCM_FUNTAIL, ch->id);
                        fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);
                        ctcm_chx_restart(fi, event, arg);
                                goto done;
@@ -1061,22 +1058,21 @@ static void ctcm_chx_iofatal(fsm_instance *fi, int event, void *arg)
        struct channel *ch = arg;
        struct net_device *dev = ch->netdev;
        struct ctcm_priv *priv = dev->priv;
+       int rd = CHANNEL_DIRECTION(ch->flags);
 
-       CTCM_DBF_TEXT(TRACE, 3, __FUNCTION__);
        fsm_deltimer(&ch->timer);
-       ctcm_pr_warn("%s %s : unrecoverable channel error\n",
-                       CTC_DRIVER_NAME, dev->name);
+       CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
+               "%s: %s: %s unrecoverable channel error",
+                       CTCM_FUNTAIL, ch->id, rd == READ ? "RX" : "TX");
+
        if (IS_MPC(ch)) {
                priv->stats.tx_dropped++;
                priv->stats.tx_errors++;
        }
-
-       if (CHANNEL_DIRECTION(ch->flags) == READ) {
-               ctcm_pr_debug("%s: RX I/O error\n", dev->name);
+       if (rd == READ) {
                fsm_newstate(fi, CTC_STATE_RXERR);
                fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev);
        } else {
-               ctcm_pr_debug("%s: TX I/O error\n", dev->name);
                fsm_newstate(fi, CTC_STATE_TXERR);
                fsm_event(priv->fsm, DEV_EVENT_TXDOWN, dev);
        }
@@ -1216,27 +1212,27 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
        struct sk_buff          *skb;
        int             first = 1;
        int             i;
-       struct timespec done_stamp;
        __u32           data_space;
        unsigned long   duration;
        struct sk_buff  *peekskb;
        int             rc;
        struct th_header *header;
        struct pdu      *p_header;
+       struct timespec done_stamp = current_kernel_time(); /* xtime */
 
-       if (do_debug)
-               ctcm_pr_debug("%s cp:%i enter:  %s()\n",
-                       dev->name, smp_processor_id(), __FUNCTION__);
+       CTCM_PR_DEBUG("Enter %s: %s cp:%i\n",
+                       __func__, dev->name, smp_processor_id());
 
-       done_stamp = current_kernel_time(); /* xtime */
-       duration = (done_stamp.tv_sec - ch->prof.send_stamp.tv_sec) * 1000000
-               (done_stamp.tv_nsec - ch->prof.send_stamp.tv_nsec) / 1000;
+       duration =
+               (done_stamp.tv_sec - ch->prof.send_stamp.tv_sec) * 1000000 +
+               (done_stamp.tv_nsec - ch->prof.send_stamp.tv_nsec) / 1000;
        if (duration > ch->prof.tx_time)
                ch->prof.tx_time = duration;
 
        if (ch->irb->scsw.cmd.count != 0)
-               ctcm_pr_debug("%s: TX not complete, remaining %d bytes\n",
-                               dev->name, ch->irb->scsw.cmd.count);
+               CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG,
+                       "%s(%s): TX not complete, remaining %d bytes",
+                            CTCM_FUNTAIL, dev->name, ch->irb->scsw.cmd.count);
        fsm_deltimer(&ch->timer);
        while ((skb = skb_dequeue(&ch->io_queue))) {
                priv->stats.tx_packets++;
@@ -1250,7 +1246,6 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
        }
        spin_lock(&ch->collect_lock);
        clear_normalized_cda(&ch->ccw[4]);
-
        if ((ch->collect_len <= 0) || (grp->in_sweep != 0)) {
                spin_unlock(&ch->collect_lock);
                fsm_newstate(fi, CTC_STATE_TXIDLE);
@@ -1269,17 +1264,13 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
        if (ch->prof.maxcqueue < skb_queue_len(&ch->collect_queue))
                ch->prof.maxcqueue = skb_queue_len(&ch->collect_queue);
        i = 0;
-
-       if (do_debug_data)
-               ctcm_pr_debug("ctcmpc: %s() building "
-                              "trans_skb from collect_q \n", __FUNCTION__);
-
+       p_header = NULL;
        data_space = grp->group_max_buflen - TH_HEADER_LENGTH;
 
-       if (do_debug_data)
-               ctcm_pr_debug("ctcmpc: %s() building trans_skb from collect_q"
-                      " data_space:%04x\n", __FUNCTION__, data_space);
-       p_header = NULL;
+       CTCM_PR_DBGDATA("%s: building trans_skb from collect_q"
+                      " data_space:%04x\n",
+                      __func__, data_space);
+
        while ((skb = skb_dequeue(&ch->collect_queue))) {
                memcpy(skb_put(ch->trans_skb, skb->len), skb->data, skb->len);
                p_header = (struct pdu *)
@@ -1290,15 +1281,12 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
                else
                        p_header->pdu_flag |= 0x20;
 
-               if (do_debug_data) {
-                       ctcm_pr_debug("ctcmpc: %s()trans_skb len:%04x \n",
-                                      __FUNCTION__, ch->trans_skb->len);
-                       ctcm_pr_debug("ctcmpc: %s() pdu header and data"
-                                      " for up to 32 bytes sent to vtam\n",
-                                      __FUNCTION__);
-                       ctcmpc_dumpit((char *)p_header,
-                                               min_t(int, skb->len, 32));
-               }
+               CTCM_PR_DBGDATA("%s: trans_skb len:%04x \n",
+                               __func__, ch->trans_skb->len);
+               CTCM_PR_DBGDATA("%s: pdu header and data for up"
+                               " to 32 bytes sent to vtam\n", __func__);
+               CTCM_D3_DUMP((char *)p_header, min_t(int, skb->len, 32));
+
                ch->collect_len -= skb->len;
                data_space -= skb->len;
                priv->stats.tx_packets++;
@@ -1314,46 +1302,38 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
        if (p_header)
                p_header->pdu_flag |= PDU_LAST; /*Say it's the last one*/
        header = kzalloc(TH_HEADER_LENGTH, gfp_type());
-
        if (!header) {
-               printk(KERN_WARNING "ctcmpc: OUT OF MEMORY IN %s()"
-                      ": Data Lost \n", __FUNCTION__);
                spin_unlock(&ch->collect_lock);
                fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
-               goto done;
+                               goto done;
        }
-
        header->th_ch_flag = TH_HAS_PDU;  /* Normal data */
        ch->th_seq_num++;
        header->th_seq_num = ch->th_seq_num;
 
-       if (do_debug_data)
-               ctcm_pr_debug("%s: ToVTAM_th_seq= %08x\n" ,
-                                       __FUNCTION__, ch->th_seq_num);
+       CTCM_PR_DBGDATA("%s: ToVTAM_th_seq= %08x\n" ,
+                                       __func__, ch->th_seq_num);
 
        memcpy(skb_push(ch->trans_skb, TH_HEADER_LENGTH), header,
                TH_HEADER_LENGTH);      /* put the TH on the packet */
 
        kfree(header);
 
-       if (do_debug_data) {
-               ctcm_pr_debug("ctcmpc: %s()trans_skb len:%04x \n",
-                      __FUNCTION__, ch->trans_skb->len);
-
-               ctcm_pr_debug("ctcmpc: %s() up-to-50 bytes of trans_skb "
-                       "data to vtam from collect_q\n", __FUNCTION__);
-               ctcmpc_dumpit((char *)ch->trans_skb->data,
+       CTCM_PR_DBGDATA("%s: trans_skb len:%04x \n",
+                      __func__, ch->trans_skb->len);
+       CTCM_PR_DBGDATA("%s: up-to-50 bytes of trans_skb "
+                       "data to vtam from collect_q\n", __func__);
+       CTCM_D3_DUMP((char *)ch->trans_skb->data,
                                min_t(int, ch->trans_skb->len, 50));
-       }
 
        spin_unlock(&ch->collect_lock);
        clear_normalized_cda(&ch->ccw[1]);
        if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) {
                dev_kfree_skb_any(ch->trans_skb);
                ch->trans_skb = NULL;
-               printk(KERN_WARNING
-                      "ctcmpc: %s()CCW failure - data lost\n",
-                      __FUNCTION__);
+               CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_ERROR,
+                       "%s: %s: IDAL alloc failed",
+                               CTCM_FUNTAIL, ch->id);
                fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
                return;
        }
@@ -1373,7 +1353,6 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
        }
 done:
        ctcm_clear_busy(dev);
-       ctcm_pr_debug("ctcmpc exit: %s  %s()\n", dev->name, __FUNCTION__);
        return;
 }
 
@@ -1393,26 +1372,25 @@ static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg)
        struct mpc_group        *grp = priv->mpcg;
        struct sk_buff          *skb = ch->trans_skb;
        struct sk_buff          *new_skb;
-       unsigned long   saveflags = 0;  /* avoids compiler warning */
+       unsigned long           saveflags = 0;  /* avoids compiler warning */
        int len = ch->max_bufsize - ch->irb->scsw.cmd.count;
 
-       if (do_debug_data) {
-               CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG, "mpc_ch_rx %s cp:%i %s\n",
-                               dev->name, smp_processor_id(), ch->id);
-               CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG, "mpc_ch_rx: maxbuf: %04x "
-                               "len: %04x\n", ch->max_bufsize, len);
-       }
+       CTCM_PR_DEBUG("%s: %s: cp:%i %s maxbuf : %04x, len: %04x\n",
+                       CTCM_FUNTAIL, dev->name, smp_processor_id(),
+                               ch->id, ch->max_bufsize, len);
        fsm_deltimer(&ch->timer);
 
        if (skb == NULL) {
-               ctcm_pr_debug("ctcmpc exit:  %s() TRANS_SKB = NULL \n",
-                              __FUNCTION__);
-                                       goto again;
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): TRANS_SKB = NULL",
+                               CTCM_FUNTAIL, dev->name);
+                       goto again;
        }
 
        if (len < TH_HEADER_LENGTH) {
-               ctcm_pr_info("%s: got packet with invalid length %d\n",
-                               dev->name, len);
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): packet length %d to short",
+                                       CTCM_FUNTAIL, dev->name, len);
                priv->stats.rx_dropped++;
                priv->stats.rx_length_errors++;
        } else {
@@ -1422,11 +1400,9 @@ static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg)
                new_skb = __dev_alloc_skb(ch->max_bufsize, GFP_ATOMIC);
 
                if (new_skb == NULL) {
-                       printk(KERN_INFO "ctcmpc:%s() NEW_SKB = NULL\n",
-                              __FUNCTION__);
-                       printk(KERN_WARNING "ctcmpc: %s() MEMORY ALLOC FAILED"
-                              " - DATA LOST - MPC FAILED\n",
-                              __FUNCTION__);
+                       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%d): skb allocation failed",
+                                               CTCM_FUNTAIL, dev->name);
                        fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
                                        goto again;
                }
@@ -1479,9 +1455,8 @@ again:
                break;
        }
 
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc exit : %s %s(): ch=0x%p id=%s\n",
-                               dev->name, __FUNCTION__, ch, ch->id);
+       CTCM_PR_DEBUG("Exit %s: %s, ch=0x%p, id=%s\n",
+                       __func__, dev->name, ch, ch->id);
 
 }
 
@@ -1497,15 +1472,16 @@ static void ctcmpc_chx_firstio(fsm_instance *fi, int event, void *arg)
        struct channel          *ch = arg;
        struct net_device       *dev = ch->netdev;
        struct ctcm_priv        *priv = dev->priv;
+       struct mpc_group        *gptr = priv->mpcg;
+
+       CTCM_PR_DEBUG("Enter %s: id=%s, ch=0x%p\n",
+                               __func__, ch->id, ch);
+
+       CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_INFO,
+                       "%s: %s: chstate:%i, grpstate:%i, prot:%i\n",
+                       CTCM_FUNTAIL, ch->id, fsm_getstate(fi),
+                       fsm_getstate(gptr->fsm), ch->protocol);
 
-       if (do_debug) {
-               struct mpc_group *gptr = priv->mpcg;
-               ctcm_pr_debug("ctcmpc enter: %s(): ch=0x%p id=%s\n",
-                               __FUNCTION__, ch, ch->id);
-               ctcm_pr_debug("%s() %s chstate:%i grpstate:%i chprotocol:%i\n",
-                               __FUNCTION__, ch->id, fsm_getstate(fi),
-                               fsm_getstate(gptr->fsm), ch->protocol);
-       }
        if (fsm_getstate(fi) == CTC_STATE_TXIDLE)
                MPC_DBF_DEV_NAME(TRACE, dev, "remote side issued READ? ");
 
@@ -1531,9 +1507,8 @@ static void ctcmpc_chx_firstio(fsm_instance *fi, int event, void *arg)
                     ? CTC_STATE_RXINIT : CTC_STATE_TXINIT);
 
 done:
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
-                       __FUNCTION__, ch, ch->id);
+       CTCM_PR_DEBUG("Exit %s: id=%s, ch=0x%p\n",
+                               __func__, ch->id, ch);
        return;
 }
 
@@ -1556,12 +1531,9 @@ void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg)
        unsigned long saveflags = 0;    /* avoids compiler warning */
 
        fsm_deltimer(&ch->timer);
-       ctcm_pr_debug("%s cp:%i enter:  %s()\n",
-                      dev->name, smp_processor_id(), __FUNCTION__);
-       if (do_debug)
-               ctcm_pr_debug("%s() %s chstate:%i grpstate:%i\n",
-                       __FUNCTION__, ch->id,
-                       fsm_getstate(fi), fsm_getstate(grp->fsm));
+       CTCM_PR_DEBUG("%s: %s: %s: cp:%i, chstate:%i grpstate:%i\n",
+                       __func__, ch->id, dev->name, smp_processor_id(),
+                               fsm_getstate(fi), fsm_getstate(grp->fsm));
 
        fsm_newstate(fi, CTC_STATE_RXIDLE);
        /* XID processing complete */
@@ -1575,9 +1547,7 @@ void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg)
                skb_reset_tail_pointer(ch->trans_skb);
                ch->trans_skb->len = 0;
                ch->ccw[1].count = ch->max_bufsize;
-               if (do_debug_ccw)
-                       ctcmpc_dumpit((char *)&ch->ccw[0],
-                                               sizeof(struct ccw1) * 3);
+               CTCM_CCW_DUMP((char *)&ch->ccw[0], sizeof(struct ccw1) * 3);
                if (event == CTC_EVENT_START)
                        /* see remark about conditional locking */
                        spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
@@ -1598,9 +1568,6 @@ void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg)
 
        fsm_event(priv->fsm, DEV_EVENT_RXUP, dev);
 done:
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc exit: %s  %s()\n",
-                                       dev->name, __FUNCTION__);
        return;
 }
 
@@ -1616,13 +1583,9 @@ static void ctcmpc_chx_attn(fsm_instance *fsm, int event, void *arg)
        struct ctcm_priv  *priv   = dev->priv;
        struct mpc_group  *grp = priv->mpcg;
 
-       if (do_debug) {
-               ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s"
-                               "GrpState:%s ChState:%s\n",
-                               __FUNCTION__, smp_processor_id(), ch, ch->id,
-               fsm_getstate_str(grp->fsm),
-               fsm_getstate_str(ch->fsm));
-       }
+       CTCM_PR_DEBUG("%s(%s): %s(ch=0x%p), cp=%i, ChStat:%s, GrpStat:%s\n",
+               __func__, dev->name, ch->id, ch, smp_processor_id(),
+                       fsm_getstate_str(ch->fsm), fsm_getstate_str(grp->fsm));
 
        switch (fsm_getstate(grp->fsm)) {
        case MPCG_STATE_XID2INITW:
@@ -1664,11 +1627,7 @@ static void ctcmpc_chx_attn(fsm_instance *fsm, int event, void *arg)
                break;
        }
 
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc exit : %s(): cp=%i ch=0x%p id=%s\n",
-                       __FUNCTION__, smp_processor_id(), ch, ch->id);
        return;
-
 }
 
 /*
@@ -1683,11 +1642,9 @@ static void ctcmpc_chx_attnbusy(fsm_instance *fsm, int event, void *arg)
        struct ctcm_priv  *priv   = dev->priv;
        struct mpc_group  *grp    = priv->mpcg;
 
-       ctcm_pr_debug("ctcmpc enter: %s  %s() %s  \nGrpState:%s ChState:%s\n",
-                      dev->name,
-                      __FUNCTION__, ch->id,
-                      fsm_getstate_str(grp->fsm),
-                      fsm_getstate_str(ch->fsm));
+       CTCM_PR_DEBUG("%s(%s): %s\n  ChState:%s GrpState:%s\n",
+                       __func__, dev->name, ch->id,
+                       fsm_getstate_str(ch->fsm), fsm_getstate_str(grp->fsm));
 
        fsm_deltimer(&ch->timer);
 
@@ -1750,16 +1707,12 @@ static void ctcmpc_chx_attnbusy(fsm_instance *fsm, int event, void *arg)
        if (ch->in_mpcgroup)
                fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch);
        else
-               printk(KERN_WARNING "ctcmpc: %s() Not all channels have"
-                       " been added to group\n", __FUNCTION__);
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): channel %s not added to group",
+                               CTCM_FUNTAIL, dev->name, ch->id);
 
 done:
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc exit : %s()%s ch=0x%p id=%s\n",
-                               __FUNCTION__, dev->name, ch, ch->id);
-
        return;
-
 }
 
 /*
@@ -1774,13 +1727,7 @@ static void ctcmpc_chx_resend(fsm_instance *fsm, int event, void *arg)
        struct ctcm_priv   *priv   = dev->priv;
        struct mpc_group   *grp    = priv->mpcg;
 
-       ctcm_pr_debug("ctcmpc enter: %s  %s() %s  \nGrpState:%s ChState:%s\n",
-                      dev->name, __FUNCTION__, ch->id,
-                      fsm_getstate_str(grp->fsm),
-                      fsm_getstate_str(ch->fsm));
-
        fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch);
-
        return;
 }
 
@@ -1802,19 +1749,16 @@ static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg)
        int rc = 0;
        unsigned long saveflags = 0;
 
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
-                       __FUNCTION__, smp_processor_id(), ach, ach->id);
+       CTCM_PR_DEBUG("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
+                       __func__, smp_processor_id(), ach, ach->id);
 
        if (grp->in_sweep == 0)
                                goto done;
 
-       if (do_debug_data) {
-               ctcm_pr_debug("ctcmpc: %s() 1: ToVTAM_th_seq= %08x\n" ,
-                              __FUNCTION__, wch->th_seq_num);
-               ctcm_pr_debug("ctcmpc: %s() 1: FromVTAM_th_seq= %08x\n" ,
-                               __FUNCTION__, rch->th_seq_num);
-       }
+       CTCM_PR_DBGDATA("%s: 1: ToVTAM_th_seq= %08x\n" ,
+                               __func__, wch->th_seq_num);
+       CTCM_PR_DBGDATA("%s: 1: FromVTAM_th_seq= %08x\n" ,
+                               __func__, rch->th_seq_num);
 
        if (fsm_getstate(wch->fsm) != CTC_STATE_TXIDLE) {
                /* give the previous IO time to complete */
@@ -1853,11 +1797,9 @@ static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg)
 
        header->sw.th_last_seq = wch->th_seq_num;
 
-       if (do_debug_ccw)
-               ctcmpc_dumpit((char *)&wch->ccw[3], sizeof(struct ccw1) * 3);
-
-       ctcm_pr_debug("ctcmpc: %s() sweep packet\n", __FUNCTION__);
-       ctcmpc_dumpit((char *)header, TH_SWEEP_LENGTH);
+       CTCM_CCW_DUMP((char *)&wch->ccw[3], sizeof(struct ccw1) * 3);
+       CTCM_PR_DBGDATA("%s: sweep packet\n", __func__);
+       CTCM_D3_DUMP((char *)header, TH_SWEEP_LENGTH);
 
        fsm_addtimer(&wch->timer, CTCM_TIME_5_SEC, CTC_EVENT_TIMER, wch);
        fsm_newstate(wch->fsm, CTC_STATE_TX);
@@ -1876,19 +1818,13 @@ static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg)
                ctcm_clear_busy_do(dev);
        }
 
-       if (do_debug_data) {
-               ctcm_pr_debug("ctcmpc: %s()2: ToVTAM_th_seq= %08x\n" ,
-                              __FUNCTION__, wch->th_seq_num);
-               ctcm_pr_debug("ctcmpc: %s()2: FromVTAM_th_seq= %08x\n" ,
-                              __FUNCTION__, rch->th_seq_num);
-       }
+       CTCM_PR_DBGDATA("%s: To-/From-VTAM_th_seq = %08x/%08x\n" ,
+                       __func__, wch->th_seq_num, rch->th_seq_num);
 
        if (rc != 0)
                ctcm_ccw_check_rc(wch, rc, "send sweep");
 
 done:
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc exit:  %s() %s\n", __FUNCTION__, ach->id);
        return;
 }
 
@@ -2149,9 +2085,8 @@ static void dev_action_stop(fsm_instance *fi, int event, void *arg)
                struct channel *ch = priv->channel[direction];
                fsm_event(ch->fsm, CTC_EVENT_STOP, ch);
                ch->th_seq_num = 0x00;
-       if (do_debug)
-               ctcm_pr_debug("ctcm: %s() CH_th_seq= %08x\n",
-                               __FUNCTION__, ch->th_seq_num);
+               CTCM_PR_DEBUG("%s: CH_th_seq= %08x\n",
+                               __func__, ch->th_seq_num);
        }
        if (IS_MPC(priv))
                fsm_newstate(priv->mpcg->fsm, MPCG_STATE_RESET);
@@ -2199,8 +2134,11 @@ static void dev_action_chup(fsm_instance *fi, int event, void *arg)
 {
        struct net_device *dev = arg;
        struct ctcm_priv *priv = dev->priv;
+       int dev_stat = fsm_getstate(fi);
 
-       CTCMY_DBF_DEV_NAME(SETUP, dev, "");
+       CTCM_DBF_TEXT_(SETUP, CTC_DBF_NOTICE,
+                       "%s(%s): priv = %p [%d,%d]\n ", CTCM_FUNTAIL,
+                               dev->name, dev->priv, dev_stat, event);
 
        switch (fsm_getstate(fi)) {
        case DEV_STATE_STARTWAIT_RXTX:
index 6b13c1c1beb81daccb09cb42a9967267e704f0cc..126a3ebb8ab2b03f416cb917fd582358b28da04b 100644 (file)
@@ -84,20 +84,19 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
                skb_pull(pskb, LL_HEADER_LENGTH);
                if ((ch->protocol == CTCM_PROTO_S390) &&
                    (header->type != ETH_P_IP)) {
-
                        if (!(ch->logflags & LOG_FLAG_ILLEGALPKT)) {
+                               ch->logflags |= LOG_FLAG_ILLEGALPKT;
                                /*
                                 * Check packet type only if we stick strictly
                                 * to S/390's protocol of OS390. This only
                                 * supports IP. Otherwise allow any packet
                                 * type.
                                 */
-                               ctcm_pr_warn("%s Illegal packet type 0x%04x "
-                                               "received, dropping\n",
-                                               dev->name, header->type);
-                               ch->logflags |= LOG_FLAG_ILLEGALPKT;
+                               CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
+                                       "%s(%s): Illegal packet type 0x%04x"
+                                       " - dropping",
+                                       CTCM_FUNTAIL, dev->name, header->type);
                        }
-
                        priv->stats.rx_dropped++;
                        priv->stats.rx_frame_errors++;
                        return;
@@ -105,11 +104,11 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
                pskb->protocol = ntohs(header->type);
                if (header->length <= LL_HEADER_LENGTH) {
                        if (!(ch->logflags & LOG_FLAG_ILLEGALSIZE)) {
-                               ctcm_pr_warn(
-                                       "%s Illegal packet size %d "
-                                       "received (MTU=%d blocklen=%d), "
-                                       "dropping\n", dev->name, header->length,
-                                       dev->mtu, len);
+                               CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
+                                       "%s(%s): Illegal packet size %d(%d,%d)"
+                                       "- dropping",
+                                       CTCM_FUNTAIL, dev->name,
+                                       header->length, dev->mtu, len);
                                ch->logflags |= LOG_FLAG_ILLEGALSIZE;
                        }
 
@@ -122,10 +121,10 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
                if ((header->length > skb_tailroom(pskb)) ||
                        (header->length > len)) {
                        if (!(ch->logflags & LOG_FLAG_OVERRUN)) {
-                               ctcm_pr_warn(
-                                       "%s Illegal packet size %d (beyond the"
-                                       " end of received data), dropping\n",
-                                       dev->name, header->length);
+                               CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
+                                       "%s(%s): Packet size %d (overrun)"
+                                       " - dropping", CTCM_FUNTAIL,
+                                               dev->name, header->length);
                                ch->logflags |= LOG_FLAG_OVERRUN;
                        }
 
@@ -139,9 +138,9 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
                skb = dev_alloc_skb(pskb->len);
                if (!skb) {
                        if (!(ch->logflags & LOG_FLAG_NOMEM)) {
-                               ctcm_pr_warn(
-                                       "%s Out of memory in ctcm_unpack_skb\n",
-                                       dev->name);
+                               CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
+                                       "%s(%s): MEMORY allocation error",
+                                               CTCM_FUNTAIL, dev->name);
                                ch->logflags |= LOG_FLAG_NOMEM;
                        }
                        priv->stats.rx_dropped++;
@@ -184,7 +183,7 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
  */
 static void channel_free(struct channel *ch)
 {
-       CTCM_DBF_TEXT(TRACE, 2, __FUNCTION__);
+       CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s(%s)", CTCM_FUNTAIL, ch->id);
        ch->flags &= ~CHANNEL_FLAGS_INUSE;
        fsm_newstate(ch->fsm, CTC_STATE_IDLE);
 }
@@ -251,19 +250,12 @@ static struct channel *channel_get(enum channel_types type,
 {
        struct channel *ch = channels;
 
-       if (do_debug) {
-               char buf[64];
-               sprintf(buf, "%s(%d, %s, %d)\n",
-                               CTCM_FUNTAIL, type, id, direction);
-               CTCM_DBF_TEXT(TRACE, CTC_DBF_INFO, buf);
-       }
        while (ch && (strncmp(ch->id, id, CTCM_ID_SIZE) || (ch->type != type)))
                ch = ch->next;
        if (!ch) {
-               char buf[64];
-               sprintf(buf, "%s(%d, %s, %d) not found in channel list\n",
+               CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
+                               "%s(%d, %s, %d) not found in channel list\n",
                                CTCM_FUNTAIL, type, id, direction);
-               CTCM_DBF_TEXT(ERROR, CTC_DBF_ERROR, buf);
        } else {
                if (ch->flags & CHANNEL_FLAGS_INUSE)
                        ch = NULL;
@@ -283,8 +275,9 @@ static long ctcm_check_irb_error(struct ccw_device *cdev, struct irb *irb)
        if (!IS_ERR(irb))
                return 0;
 
-       CTCM_DBF_TEXT_(ERROR, CTC_DBF_WARN, "irb error %ld on device %s\n",
-                       PTR_ERR(irb), cdev->dev.bus_id);
+       CTCM_DBF_TEXT_(ERROR, CTC_DBF_WARN,
+                       "irb error %ld on device %s\n",
+                               PTR_ERR(irb), cdev->dev.bus_id);
 
        switch (PTR_ERR(irb)) {
        case -EIO:
@@ -307,58 +300,85 @@ static long ctcm_check_irb_error(struct ccw_device *cdev, struct irb *irb)
  *  ch         The channel, the sense code belongs to.
  *  sense      The sense code to inspect.
  */
-static inline void ccw_unit_check(struct channel *ch, unsigned char sense)
+static inline void ccw_unit_check(struct channel *ch, __u8 sense)
 {
-       CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__);
+       CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
+                       "%s(%s): %02x",
+                               CTCM_FUNTAIL, ch->id, sense);
+
        if (sense & SNS0_INTERVENTION_REQ) {
                if (sense & 0x01) {
-                       ctcm_pr_debug("%s: Interface disc. or Sel. reset "
-                                       "(remote)\n", ch->id);
+                       if (ch->sense_rc != 0x01) {
+                               ctcm_pr_debug("%s: Interface disc. or Sel. "
+                                             "reset (remote)\n", ch->id);
+                               ch->sense_rc = 0x01;
+                       }
                        fsm_event(ch->fsm, CTC_EVENT_UC_RCRESET, ch);
                } else {
-                       ctcm_pr_debug("%s: System reset (remote)\n", ch->id);
+                       if (ch->sense_rc != SNS0_INTERVENTION_REQ) {
+                               ctcm_pr_debug("%s: System reset (remote)\n",
+                                             ch->id);
+                               ch->sense_rc = SNS0_INTERVENTION_REQ;
+                       }
                        fsm_event(ch->fsm, CTC_EVENT_UC_RSRESET, ch);
                }
        } else if (sense & SNS0_EQUIPMENT_CHECK) {
                if (sense & SNS0_BUS_OUT_CHECK) {
-                       ctcm_pr_warn("%s: Hardware malfunction (remote)\n",
-                               ch->id);
+                       if (ch->sense_rc != SNS0_BUS_OUT_CHECK) {
+                               CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
+                                       "%s(%s): remote HW error %02x",
+                                               CTCM_FUNTAIL, ch->id, sense);
+                               ch->sense_rc = SNS0_BUS_OUT_CHECK;
+                       }
                        fsm_event(ch->fsm, CTC_EVENT_UC_HWFAIL, ch);
                } else {
-                       ctcm_pr_warn("%s: Read-data parity error (remote)\n",
-                               ch->id);
+                       if (ch->sense_rc != SNS0_EQUIPMENT_CHECK) {
+                               CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
+                                       "%s(%s): remote read parity error %02x",
+                                               CTCM_FUNTAIL, ch->id, sense);
+                               ch->sense_rc = SNS0_EQUIPMENT_CHECK;
+                       }
                        fsm_event(ch->fsm, CTC_EVENT_UC_RXPARITY, ch);
                }
        } else if (sense & SNS0_BUS_OUT_CHECK) {
-               if (sense & 0x04) {
-                       ctcm_pr_warn("%s: Data-streaming timeout)\n", ch->id);
+               if (ch->sense_rc != SNS0_BUS_OUT_CHECK) {
+                       CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
+                               "%s(%s): BUS OUT error %02x",
+                                       CTCM_FUNTAIL, ch->id, sense);
+                       ch->sense_rc = SNS0_BUS_OUT_CHECK;
+               }
+               if (sense & 0x04)       /* data-streaming timeout */
                        fsm_event(ch->fsm, CTC_EVENT_UC_TXTIMEOUT, ch);
-               } else {
-                       ctcm_pr_warn("%s: Data-transfer parity error\n",
-                                       ch->id);
+               else                    /* Data-transfer parity error */
                        fsm_event(ch->fsm, CTC_EVENT_UC_TXPARITY, ch);
-               }
        } else if (sense & SNS0_CMD_REJECT) {
-               ctcm_pr_warn("%s: Command reject\n", ch->id);
+               if (ch->sense_rc != SNS0_CMD_REJECT) {
+                       CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
+                               "%s(%s): Command rejected",
+                                               CTCM_FUNTAIL, ch->id);
+                       ch->sense_rc = SNS0_CMD_REJECT;
+               }
        } else if (sense == 0) {
-               ctcm_pr_debug("%s: Unit check ZERO\n", ch->id);
+               CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
+                       "%s(%s): Unit check ZERO",
+                                       CTCM_FUNTAIL, ch->id);
                fsm_event(ch->fsm, CTC_EVENT_UC_ZERO, ch);
        } else {
-               ctcm_pr_warn("%s: Unit Check with sense code: %02x\n",
-                           ch->id, sense);
+               CTCM_DBF_TEXT_(TRACE, CTC_DBF_WARN,
+                       "%s(%s): Unit check code %02x unknown",
+                                       CTCM_FUNTAIL, ch->id, sense);
                fsm_event(ch->fsm, CTC_EVENT_UC_UNKNOWN, ch);
        }
 }
 
 int ctcm_ch_alloc_buffer(struct channel *ch)
 {
-       CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__);
-
        clear_normalized_cda(&ch->ccw[1]);
        ch->trans_skb = __dev_alloc_skb(ch->max_bufsize, GFP_ATOMIC | GFP_DMA);
        if (ch->trans_skb == NULL) {
-               ctcm_pr_warn("%s: Couldn't alloc %s trans_skb\n",
-                       ch->id,
+               CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
+                       "%s(%s): %s trans_skb allocation error",
+                       CTCM_FUNTAIL, ch->id,
                        (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
                return -ENOMEM;
        }
@@ -367,9 +387,9 @@ int ctcm_ch_alloc_buffer(struct channel *ch)
        if (set_normalized_cda(&ch->ccw[1], ch->trans_skb->data)) {
                dev_kfree_skb(ch->trans_skb);
                ch->trans_skb = NULL;
-               ctcm_pr_warn("%s: set_normalized_cda for %s "
-                       "trans_skb failed, dropping packets\n",
-                       ch->id,
+               CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
+                       "%s(%s): %s set norm_cda failed",
+                       CTCM_FUNTAIL, ch->id,
                        (CHANNEL_DIRECTION(ch->flags) == READ) ? "RX" : "TX");
                return -ENOMEM;
        }
@@ -516,7 +536,7 @@ static int ctcm_transmit_skb(struct channel *ch, struct sk_buff *skb)
                        atomic_dec(&skb->users);
                        skb_pull(skb, LL_HEADER_LENGTH + 2);
                        ctcm_clear_busy(ch->netdev);
-                       return -EBUSY;
+                       return -ENOMEM;
                }
 
                skb_reset_tail_pointer(ch->trans_skb);
@@ -570,15 +590,12 @@ static void ctcmpc_send_sweep_req(struct channel *rch)
        struct th_sweep *header;
        struct sk_buff *sweep_skb;
        struct channel *ch;
-       int rc = 0;
+       /* int rc = 0; */
 
        priv = dev->priv;
        grp = priv->mpcg;
        ch = priv->channel[WRITE];
 
-       if (do_debug)
-               MPC_DBF_DEV_NAME(TRACE, dev, ch->id);
-
        /* sweep processing is not complete until response and request */
        /* has completed for all read channels in group                */
        if (grp->in_sweep == 0) {
@@ -590,17 +607,16 @@ static void ctcmpc_send_sweep_req(struct channel *rch)
        sweep_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC|GFP_DMA);
 
        if (sweep_skb == NULL)  {
-               printk(KERN_INFO "Couldn't alloc sweep_skb\n");
-               rc = -ENOMEM;
-                                       goto done;
+               /* rc = -ENOMEM; */
+                               goto nomem;
        }
 
        header = kmalloc(TH_SWEEP_LENGTH, gfp_type());
 
        if (!header) {
                dev_kfree_skb_any(sweep_skb);
-               rc = -ENOMEM;
-                                       goto done;
+               /* rc = -ENOMEM; */
+                               goto nomem;
        }
 
        header->th.th_seg       = 0x00 ;
@@ -621,12 +637,10 @@ static void ctcmpc_send_sweep_req(struct channel *rch)
 
        return;
 
-done:
-       if (rc != 0) {
-               grp->in_sweep = 0;
-               ctcm_clear_busy(dev);
-               fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
-       }
+nomem:
+       grp->in_sweep = 0;
+       ctcm_clear_busy(dev);
+       fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
 
        return;
 }
@@ -648,11 +662,9 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
        unsigned long saveflags = 0;    /* avoids compiler warning */
        __u16 block_len;
 
-       if (do_debug)
-               ctcm_pr_debug(
-                       "ctcm enter: %s(): %s cp=%i ch=0x%p id=%s state=%s\n",
-                       __FUNCTION__, dev->name, smp_processor_id(), ch,
-                       ch->id, fsm_getstate_str(ch->fsm));
+       CTCM_PR_DEBUG("Enter %s: %s, cp=%i ch=0x%p id=%s state=%s\n",
+                       __func__, dev->name, smp_processor_id(), ch,
+                                       ch->id, fsm_getstate_str(ch->fsm));
 
        if ((fsm_getstate(ch->fsm) != CTC_STATE_TXIDLE) || grp->in_sweep) {
                spin_lock_irqsave(&ch->collect_lock, saveflags);
@@ -660,14 +672,8 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
                p_header = kmalloc(PDU_HEADER_LENGTH, gfp_type());
 
                if (!p_header) {
-                       printk(KERN_WARNING "ctcm: OUT OF MEMORY IN %s():"
-                              " Data Lost \n", __FUNCTION__);
-
-                       atomic_dec(&skb->users);
-                       dev_kfree_skb_any(skb);
                        spin_unlock_irqrestore(&ch->collect_lock, saveflags);
-                       fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
-                                       goto done;
+                               goto nomem_exit;
                }
 
                p_header->pdu_offset = skb->len;
@@ -682,13 +688,10 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
                memcpy(skb_push(skb, PDU_HEADER_LENGTH), p_header,
                       PDU_HEADER_LENGTH);
 
-               if (do_debug_data) {
-                       ctcm_pr_debug("ctcm: %s() Putting on collect_q"
-                              " - skb len: %04x \n", __FUNCTION__, skb->len);
-                       ctcm_pr_debug("ctcm: %s() pdu header and data"
-                              " for up to 32 bytes\n", __FUNCTION__);
-                       ctcmpc_dump32((char *)skb->data, skb->len);
-               }
+               CTCM_PR_DEBUG("%s(%s): Put on collect_q - skb len: %04x \n"
+                               "pdu header and data for up to 32 bytes:\n",
+                               __func__, dev->name, skb->len);
+               CTCM_D3_DUMP((char *)skb->data, min_t(int, 32, skb->len));
 
                skb_queue_tail(&ch->collect_queue, skb);
                ch->collect_len += skb->len;
@@ -713,12 +716,7 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
        if (hi) {
                nskb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
                if (!nskb) {
-                       printk(KERN_WARNING "ctcm: %s() OUT OF MEMORY"
-                               "-  Data Lost \n", __FUNCTION__);
-                       atomic_dec(&skb->users);
-                       dev_kfree_skb_any(skb);
-                       fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
-                               goto done;
+                       goto nomem_exit;
                } else {
                        memcpy(skb_put(nskb, skb->len), skb->data, skb->len);
                        atomic_inc(&nskb->users);
@@ -730,15 +728,8 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
 
        p_header = kmalloc(PDU_HEADER_LENGTH, gfp_type());
 
-       if (!p_header) {
-               printk(KERN_WARNING "ctcm: %s() OUT OF MEMORY"
-                      ": Data Lost \n", __FUNCTION__);
-
-               atomic_dec(&skb->users);
-               dev_kfree_skb_any(skb);
-               fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
-                               goto done;
-       }
+       if (!p_header)
+               goto nomem_exit;
 
        p_header->pdu_offset = skb->len;
        p_header->pdu_proto = 0x01;
@@ -768,15 +759,8 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
        ch->prof.txlen += skb->len - PDU_HEADER_LENGTH;
 
        header = kmalloc(TH_HEADER_LENGTH, gfp_type());
-
-       if (!header) {
-               printk(KERN_WARNING "ctcm: %s() OUT OF MEMORY: Data Lost \n",
-                               __FUNCTION__);
-               atomic_dec(&skb->users);
-               dev_kfree_skb_any(skb);
-               fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
-                               goto done;
-       }
+       if (!header)
+               goto nomem_exit;
 
        header->th_seg = 0x00;
        header->th_ch_flag = TH_HAS_PDU;  /* Normal data */
@@ -785,41 +769,31 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
        ch->th_seq_num++;
        header->th_seq_num = ch->th_seq_num;
 
-       if (do_debug_data)
-               ctcm_pr_debug("ctcm: %s() ToVTAM_th_seq= %08x\n" ,
-                      __FUNCTION__, ch->th_seq_num);
+       CTCM_PR_DBGDATA("%s(%s) ToVTAM_th_seq= %08x\n" ,
+                      __func__, dev->name, ch->th_seq_num);
 
        /* put the TH on the packet */
        memcpy(skb_push(skb, TH_HEADER_LENGTH), header, TH_HEADER_LENGTH);
 
        kfree(header);
 
-       if (do_debug_data) {
-               ctcm_pr_debug("ctcm: %s(): skb len: %04x \n",
-                               __FUNCTION__, skb->len);
-               ctcm_pr_debug("ctcm: %s(): pdu header and data for up to 32 "
-                               "bytes sent to vtam\n", __FUNCTION__);
-               ctcmpc_dump32((char *)skb->data, skb->len);
-       }
+       CTCM_PR_DBGDATA("%s(%s): skb len: %04x\n - pdu header and data for "
+                       "up to 32 bytes sent to vtam:\n",
+                               __func__, dev->name, skb->len);
+       CTCM_D3_DUMP((char *)skb->data, min_t(int, 32, skb->len));
 
        ch->ccw[4].count = skb->len;
        if (set_normalized_cda(&ch->ccw[4], skb->data)) {
                /*
-                * idal allocation failed, try via copying to
-                * trans_skb. trans_skb usually has a pre-allocated
-                * idal.
+                * idal allocation failed, try via copying to trans_skb.
+                * trans_skb usually has a pre-allocated idal.
                 */
                if (ctcm_checkalloc_buffer(ch)) {
                        /*
-                        * Remove our header. It gets added
-                        * again on retransmit.
+                        * Remove our header.
+                        * It gets added again on retransmit.
                         */
-                       atomic_dec(&skb->users);
-                       dev_kfree_skb_any(skb);
-                       printk(KERN_WARNING "ctcm: %s()OUT OF MEMORY:"
-                                       " Data Lost \n", __FUNCTION__);
-                       fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
-                               goto done;
+                               goto nomem_exit;
                }
 
                skb_reset_tail_pointer(ch->trans_skb);
@@ -829,14 +803,11 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
                atomic_dec(&skb->users);
                dev_kfree_skb_irq(skb);
                ccw_idx = 0;
-               if (do_debug_data) {
-                       ctcm_pr_debug("ctcm: %s() TRANS skb len: %d \n",
-                              __FUNCTION__, ch->trans_skb->len);
-                       ctcm_pr_debug("ctcm: %s up to 32 bytes of data"
-                               " sent to vtam\n", __FUNCTION__);
-                       ctcmpc_dump32((char *)ch->trans_skb->data,
-                                       ch->trans_skb->len);
-               }
+               CTCM_PR_DBGDATA("%s(%s): trans_skb len: %04x\n"
+                               "up to 32 bytes sent to vtam:\n",
+                               __func__, dev->name, ch->trans_skb->len);
+               CTCM_D3_DUMP((char *)ch->trans_skb->data,
+                               min_t(int, 32, ch->trans_skb->len));
        } else {
                skb_queue_tail(&ch->io_queue, skb);
                ccw_idx = 3;
@@ -865,13 +836,21 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
                priv->stats.tx_packets++;
                priv->stats.tx_bytes += skb->len - TH_HEADER_LENGTH;
        }
-       if (ch->th_seq_num > 0xf0000000)        /* Chose 4Billion at random. */
+       if (ch->th_seq_num > 0xf0000000)        /* Chose at random. */
                ctcmpc_send_sweep_req(ch);
 
+       goto done;
+nomem_exit:
+       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_CRIT,
+                       "%s(%s): MEMORY allocation ERROR\n",
+                       CTCM_FUNTAIL, ch->id);
+       rc = -ENOMEM;
+       atomic_dec(&skb->users);
+       dev_kfree_skb_any(skb);
+       fsm_event(priv->mpcg->fsm, MPCG_EVENT_INOP, dev);
 done:
-       if (do_debug)
-               ctcm_pr_debug("ctcm exit: %s  %s()\n", dev->name, __FUNCTION__);
-       return 0;
+       CTCM_PR_DEBUG("Exit %s(%s)\n", __func__, dev->name);
+       return rc;
 }
 
 /**
@@ -888,20 +867,19 @@ done:
 /* first merge version - leaving both functions separated */
 static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
 {
-       int rc = 0;
-       struct ctcm_priv *priv;
-
-       CTCM_DBF_TEXT(TRACE, 5, __FUNCTION__);
-       priv = dev->priv;
+       struct ctcm_priv *priv = dev->priv;
 
        if (skb == NULL) {
-               ctcm_pr_warn("%s: NULL sk_buff passed\n", dev->name);
+               CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
+                               "%s(%s): NULL sk_buff passed",
+                                       CTCM_FUNTAIL, dev->name);
                priv->stats.tx_dropped++;
                return 0;
        }
        if (skb_headroom(skb) < (LL_HEADER_LENGTH + 2)) {
-               ctcm_pr_warn("%s: Got sk_buff with head room < %ld bytes\n",
-                           dev->name, LL_HEADER_LENGTH + 2);
+               CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
+                       "%s(%s): Got sk_buff with head room < %ld bytes",
+                       CTCM_FUNTAIL, dev->name, LL_HEADER_LENGTH + 2);
                dev_kfree_skb(skb);
                priv->stats.tx_dropped++;
                return 0;
@@ -925,51 +903,43 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
 
        dev->trans_start = jiffies;
        if (ctcm_transmit_skb(priv->channel[WRITE], skb) != 0)
-               rc = 1;
-       return rc;
+               return 1;
+       return 0;
 }
 
 /* unmerged MPC variant of ctcm_tx */
 static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
 {
        int len = 0;
-       struct ctcm_priv *priv = NULL;
-       struct mpc_group *grp  = NULL;
+       struct ctcm_priv *priv = dev->priv;
+       struct mpc_group *grp  = priv->mpcg;
        struct sk_buff *newskb = NULL;
 
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc enter: %s(): skb:%0lx\n",
-                       __FUNCTION__, (unsigned long)skb);
-
-       CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG,
-                       "ctcmpc enter: %s(): skb:%0lx\n",
-                       __FUNCTION__, (unsigned long)skb);
-
-       priv = dev->priv;
-       grp  = priv->mpcg;
        /*
         * Some sanity checks ...
         */
        if (skb == NULL) {
-               ctcm_pr_warn("ctcmpc: %s: NULL sk_buff passed\n", dev->name);
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): NULL sk_buff passed",
+                                       CTCM_FUNTAIL, dev->name);
                priv->stats.tx_dropped++;
                                        goto done;
        }
        if (skb_headroom(skb) < (TH_HEADER_LENGTH + PDU_HEADER_LENGTH)) {
-               CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_WARN,
-                       "%s: Got sk_buff with head room < %ld bytes\n",
-                       dev->name, TH_HEADER_LENGTH + PDU_HEADER_LENGTH);
+               CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_ERROR,
+                       "%s(%s): Got sk_buff with head room < %ld bytes",
+                       CTCM_FUNTAIL, dev->name,
+                               TH_HEADER_LENGTH + PDU_HEADER_LENGTH);
 
-               if (do_debug_data)
-                       ctcmpc_dump32((char *)skb->data, skb->len);
+               CTCM_D3_DUMP((char *)skb->data, min_t(int, 32, skb->len));
 
                len =  skb->len + TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
                newskb = __dev_alloc_skb(len, gfp_type() | GFP_DMA);
 
                if (!newskb) {
-                       printk(KERN_WARNING "ctcmpc: %s() OUT OF MEMORY-"
-                              "Data Lost\n",
-                              __FUNCTION__);
+                       CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_ERROR,
+                               "%s: %s: __dev_alloc_skb failed",
+                                               __func__, dev->name);
 
                        dev_kfree_skb_any(skb);
                        priv->stats.tx_dropped++;
@@ -993,9 +963,9 @@ static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
        if ((fsm_getstate(priv->fsm) != DEV_STATE_RUNNING) ||
           (fsm_getstate(grp->fsm) <  MPCG_STATE_XID2INITW)) {
                dev_kfree_skb_any(skb);
-               printk(KERN_INFO "ctcmpc: %s() DATA RCVD - MPC GROUP "
-                      "NOT ACTIVE - DROPPED\n",
-                      __FUNCTION__);
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): inactive MPCGROUP - dropped",
+                                       CTCM_FUNTAIL, dev->name);
                priv->stats.tx_dropped++;
                priv->stats.tx_errors++;
                priv->stats.tx_carrier_errors++;
@@ -1003,8 +973,9 @@ static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
        }
 
        if (ctcm_test_and_set_busy(dev)) {
-               printk(KERN_WARNING "%s:DEVICE ERR - UNRECOVERABLE DATA LOSS\n",
-                      __FUNCTION__);
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): device busy - dropped",
+                                       CTCM_FUNTAIL, dev->name);
                dev_kfree_skb_any(skb);
                priv->stats.tx_dropped++;
                priv->stats.tx_errors++;
@@ -1015,12 +986,9 @@ static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
 
        dev->trans_start = jiffies;
        if (ctcmpc_transmit_skb(priv->channel[WRITE], skb) != 0) {
-               printk(KERN_WARNING "ctcmpc: %s() DEVICE ERROR"
-                      ": Data Lost \n",
-                      __FUNCTION__);
-               printk(KERN_WARNING "ctcmpc: %s() DEVICE ERROR"
-                      " - UNRECOVERABLE DATA LOSS\n",
-                      __FUNCTION__);
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): device error - dropped",
+                                       CTCM_FUNTAIL, dev->name);
                dev_kfree_skb_any(skb);
                priv->stats.tx_dropped++;
                priv->stats.tx_errors++;
@@ -1054,8 +1022,6 @@ static int ctcm_change_mtu(struct net_device *dev, int new_mtu)
        struct ctcm_priv *priv;
        int max_bufsize;
 
-       CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
-
        if (new_mtu < 576 || new_mtu > 65527)
                return -EINVAL;
 
@@ -1087,30 +1053,13 @@ static struct net_device_stats *ctcm_stats(struct net_device *dev)
        return &((struct ctcm_priv *)dev->priv)->stats;
 }
 
-
-static void ctcm_netdev_unregister(struct net_device *dev)
-{
-       CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
-       if (!dev)
-               return;
-       unregister_netdev(dev);
-}
-
-static int ctcm_netdev_register(struct net_device *dev)
-{
-       CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
-       return register_netdev(dev);
-}
-
 static void ctcm_free_netdevice(struct net_device *dev)
 {
        struct ctcm_priv *priv;
        struct mpc_group *grp;
 
-       CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
-
-       if (!dev)
-               return;
+       CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
+                       "%s(%s)", CTCM_FUNTAIL, dev->name);
        priv = dev->priv;
        if (priv) {
                grp = priv->mpcg;
@@ -1171,7 +1120,9 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv)
                dev = alloc_netdev(0, CTC_DEVICE_GENE, ctcm_dev_setup);
 
        if (!dev) {
-               ctcm_pr_err("%s: Out of memory\n", __FUNCTION__);
+               CTCM_DBF_TEXT_(ERROR, CTC_DBF_CRIT,
+                       "%s: MEMORY allocation ERROR",
+                       CTCM_FUNTAIL);
                return NULL;
        }
        dev->priv = priv;
@@ -1209,6 +1160,7 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv)
        }
 
        CTCMY_DBF_DEV(SETUP, dev, "finished");
+
        return dev;
 }
 
@@ -1226,18 +1178,24 @@ static void ctcm_irq_handler(struct ccw_device *cdev,
        struct net_device       *dev;
        struct ctcm_priv        *priv;
        struct ccwgroup_device  *cgdev;
+       int cstat;
+       int dstat;
+
+       CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
+               "Enter %s(%s)", CTCM_FUNTAIL, &cdev->dev.bus_id);
 
-       CTCM_DBF_TEXT(TRACE, CTC_DBF_DEBUG, __FUNCTION__);
        if (ctcm_check_irb_error(cdev, irb))
                return;
 
        cgdev = dev_get_drvdata(&cdev->dev);
 
+       cstat = irb->scsw.cmd.cstat;
+       dstat = irb->scsw.cmd.dstat;
+
        /* Check for unsolicited interrupts. */
        if (cgdev == NULL) {
-               ctcm_pr_warn("ctcm: Got unsolicited irq: %s c-%02x d-%02x\n",
-                           cdev->dev.bus_id, irb->scsw.cmd.cstat,
-                           irb->scsw.cmd.dstat);
+               ctcm_pr_warn("ctcm: Got unsolicited irq: c-%02x d-%02x\n",
+                            cstat, dstat);
                return;
        }
 
@@ -1254,26 +1212,22 @@ static void ctcm_irq_handler(struct ccw_device *cdev,
                return;
        }
 
-       dev = (struct net_device *)(ch->netdev);
+       dev = ch->netdev;
        if (dev == NULL) {
                ctcm_pr_crit("ctcm: %s dev=NULL bus_id=%s, ch=0x%p\n",
-                               __FUNCTION__, cdev->dev.bus_id, ch);
+                               __func__, cdev->dev.bus_id, ch);
                return;
        }
 
-       if (do_debug)
-               ctcm_pr_debug("%s: interrupt for device: %s "
-                               "received c-%02x d-%02x\n",
-                               dev->name,
-                               ch->id,
-                               irb->scsw.cmd.cstat,
-                               irb->scsw.cmd.dstat);
+       CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
+               "%s(%s): int. for %s: cstat=%02x dstat=%02x",
+                       CTCM_FUNTAIL, dev->name, ch->id, cstat, dstat);
 
        /* Copy interruption response block. */
        memcpy(ch->irb, irb, sizeof(struct irb));
 
-       /* Check for good subchannel return code, otherwise error message */
        if (irb->scsw.cmd.cstat) {
+       /* Check for good subchannel return code, otherwise error message */
                fsm_event(ch->fsm, CTC_EVENT_SC_UNKNOWN, ch);
                ctcm_pr_warn("%s: subchannel check for dev: %s - %02x %02x\n",
                            dev->name, ch->id, irb->scsw.cmd.cstat,
@@ -1283,6 +1237,11 @@ static void ctcm_irq_handler(struct ccw_device *cdev,
 
        /* Check the reason-code of a unit check */
        if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
+               if ((irb->ecw[0] & ch->sense_rc) == 0)
+                       /* print it only once */
+                       CTCM_DBF_TEXT_(TRACE, CTC_DBF_INFO,
+                               "%s(%s): sense=%02x, ds=%02x",
+                               CTCM_FUNTAIL, ch->id, irb->ecw[0], dstat);
                ccw_unit_check(ch, irb->ecw[0]);
                return;
        }
@@ -1320,14 +1279,18 @@ static int ctcm_probe_device(struct ccwgroup_device *cgdev)
        struct ctcm_priv *priv;
        int rc;
 
-       CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO, "%s %p", __FUNCTION__, cgdev);
+       CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
+                       "%s %p",
+                       __func__, cgdev);
 
        if (!get_device(&cgdev->dev))
                return -ENODEV;
 
        priv = kzalloc(sizeof(struct ctcm_priv), GFP_KERNEL);
        if (!priv) {
-               ctcm_pr_err("%s: Out of memory\n", __FUNCTION__);
+               CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
+                       "%s: memory allocation failure",
+                       CTCM_FUNTAIL);
                put_device(&cgdev->dev);
                return -ENOMEM;
        }
@@ -1364,10 +1327,13 @@ static int add_channel(struct ccw_device *cdev, enum channel_types type,
        int ccw_num;
        int rc = 0;
 
-       CTCM_DBF_TEXT(TRACE, 2, __FUNCTION__);
+       CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
+               "%s(%s), type %d, proto %d",
+                       __func__, cdev->dev.bus_id,     type, priv->protocol);
+
        ch = kzalloc(sizeof(struct channel), GFP_KERNEL);
        if (ch == NULL)
-                                       goto nomem_return;
+               return -ENOMEM;
 
        ch->protocol = priv->protocol;
        if (IS_MPC(priv)) {
@@ -1478,7 +1444,7 @@ static int add_channel(struct ccw_device *cdev, enum channel_types type,
        if (*c && (!strncmp((*c)->id, ch->id, CTCM_ID_SIZE))) {
                CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
                                "%s (%s) already in list, using old entry",
-                               __FUNCTION__, (*c)->id);
+                               __func__, (*c)->id);
 
                                goto free_return;
        }
@@ -1498,11 +1464,10 @@ static int add_channel(struct ccw_device *cdev, enum channel_types type,
        return 0;
 
 nomem_return:
-       ctcm_pr_warn("ctcm: Out of memory in %s\n", __FUNCTION__);
        rc = -ENOMEM;
 
 free_return:   /* note that all channel pointers are 0 or valid */
-       kfree(ch->ccw);         /* TODO: check that again */
+       kfree(ch->ccw);
        kfree(ch->discontact_th);
        kfree_fsm(ch->fsm);
        kfree(ch->irb);
@@ -1540,48 +1505,48 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
        enum channel_types type;
        struct ctcm_priv *priv;
        struct net_device *dev;
+       struct ccw_device *cdev0;
+       struct ccw_device *cdev1;
        int ret;
 
-       CTCM_DBF_TEXT(SETUP, CTC_DBF_INFO, __FUNCTION__);
-
        priv = dev_get_drvdata(&cgdev->dev);
        if (!priv)
                return -ENODEV;
 
-       type = get_channel_type(&cgdev->cdev[0]->id);
+       cdev0 = cgdev->cdev[0];
+       cdev1 = cgdev->cdev[1];
+
+       type = get_channel_type(&cdev0->id);
 
-       snprintf(read_id, CTCM_ID_SIZE, "ch-%s", cgdev->cdev[0]->dev.bus_id);
-       snprintf(write_id, CTCM_ID_SIZE, "ch-%s", cgdev->cdev[1]->dev.bus_id);
+       snprintf(read_id, CTCM_ID_SIZE, "ch-%s", cdev0->dev.bus_id);
+       snprintf(write_id, CTCM_ID_SIZE, "ch-%s", cdev1->dev.bus_id);
 
-       ret = add_channel(cgdev->cdev[0], type, priv);
+       ret = add_channel(cdev0, type, priv);
        if (ret)
                return ret;
-       ret = add_channel(cgdev->cdev[1], type, priv);
+       ret = add_channel(cdev1, type, priv);
        if (ret)
                return ret;
 
-       ret = ccw_device_set_online(cgdev->cdev[0]);
+       ret = ccw_device_set_online(cdev0);
        if (ret != 0) {
-               CTCM_DBF_TEXT(SETUP, CTC_DBF_WARN,
-                               "ccw_device_set_online (cdev[0]) failed ");
-               ctcm_pr_warn("ccw_device_set_online (cdev[0]) failed "
-                               "with ret = %d\n", ret);
+               /* may be ok to fail now - can be done later */
+               CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
+                       "%s(%s) set_online rc=%d",
+                               CTCM_FUNTAIL, read_id, ret);
        }
 
-       ret = ccw_device_set_online(cgdev->cdev[1]);
+       ret = ccw_device_set_online(cdev1);
        if (ret != 0) {
-               CTCM_DBF_TEXT(SETUP, CTC_DBF_WARN,
-                               "ccw_device_set_online (cdev[1]) failed ");
-               ctcm_pr_warn("ccw_device_set_online (cdev[1]) failed "
-                               "with ret = %d\n", ret);
+               /* may be ok to fail now - can be done later */
+               CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
+                       "%s(%s) set_online rc=%d",
+                               CTCM_FUNTAIL, write_id, ret);
        }
 
        dev = ctcm_init_netdevice(priv);
-
-       if (dev == NULL) {
-               ctcm_pr_warn("ctcm_init_netdevice failed\n");
-                                       goto out;
-       }
+       if (dev == NULL)
+                       goto out;
 
        for (direction = READ; direction <= WRITE; direction++) {
                priv->channel[direction] =
@@ -1590,8 +1555,7 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
                if (priv->channel[direction] == NULL) {
                        if (direction == WRITE)
                                channel_free(priv->channel[READ]);
-                       ctcm_free_netdevice(dev);
-                                       goto out;
+                       goto out_dev;
                }
                priv->channel[direction]->netdev = dev;
                priv->channel[direction]->protocol = priv->protocol;
@@ -1600,26 +1564,24 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
        /* sysfs magic */
        SET_NETDEV_DEV(dev, &cgdev->dev);
 
-       if (ctcm_netdev_register(dev) != 0) {
-               ctcm_free_netdevice(dev);
-                                       goto out;
-       }
+       if (register_netdev(dev))
+                       goto out_dev;
 
        if (ctcm_add_attributes(&cgdev->dev)) {
-               ctcm_netdev_unregister(dev);
-/*             dev->priv = NULL;       why that ????   */
-               ctcm_free_netdevice(dev);
-                                       goto out;
+               unregister_netdev(dev);
+                       goto out_dev;
        }
 
        strlcpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name));
 
        CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
-                       "setup(%s) ok : r/w = %s / %s, proto : %d",
-                       dev->name, priv->channel[READ]->id,
+               "setup(%s) OK : r/w = %s/%s, protocol : %d", dev->name,
+                       priv->channel[READ]->id,
                        priv->channel[WRITE]->id, priv->protocol);
 
        return 0;
+out_dev:
+       ctcm_free_netdevice(dev);
 out:
        ccw_device_set_offline(cgdev->cdev[1]);
        ccw_device_set_offline(cgdev->cdev[0]);
@@ -1658,8 +1620,7 @@ static int ctcm_shutdown_device(struct ccwgroup_device *cgdev)
                channel_free(priv->channel[WRITE]);
 
        if (dev) {
-               ctcm_netdev_unregister(dev);
-/*             dev->priv = NULL;       why that ???    */
+               unregister_netdev(dev);
                ctcm_free_netdevice(dev);
        }
 
@@ -1682,13 +1643,16 @@ static int ctcm_shutdown_device(struct ccwgroup_device *cgdev)
 
 static void ctcm_remove_device(struct ccwgroup_device *cgdev)
 {
-       struct ctcm_priv *priv;
+       struct ctcm_priv *priv = dev_get_drvdata(&cgdev->dev);
 
-       CTCM_DBF_TEXT(SETUP, CTC_DBF_ERROR, __FUNCTION__);
+       BUG_ON(priv == NULL);
+
+       CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
+                       "removing device %s, r/w = %s/%s, proto : %d",
+                       priv->channel[READ]->netdev->name,
+                       priv->channel[READ]->id, priv->channel[WRITE]->id,
+                       priv->protocol);
 
-       priv = dev_get_drvdata(&cgdev->dev);
-       if (!priv)
-               return;
        if (cgdev->state == CCWGROUP_ONLINE)
                ctcm_shutdown_device(cgdev);
        ctcm_remove_files(&cgdev->dev);
@@ -1748,8 +1712,6 @@ static int __init ctcm_init(void)
 
        ret = ctcm_register_dbf_views();
        if (ret) {
-               ctcm_pr_crit("ctcm_init failed with ctcm_register_dbf_views "
-                               "rc = %d\n", ret);
                return ret;
        }
        ret = register_cu3088_discipline(&ctcm_group_driver);
index 95b0c0b6ebc62f79c9886a81e0f63e92c9823b6f..a72e0feeb27f886765b106aa7279eaf7e0db6346 100644 (file)
@@ -22,9 +22,9 @@
 
 #define CTC_DRIVER_NAME        "ctcm"
 #define CTC_DEVICE_NAME        "ctc"
-#define CTC_DEVICE_GENE        "ctc%d"
 #define MPC_DEVICE_NAME        "mpc"
-#define MPC_DEVICE_GENE        "mpc%d"
+#define CTC_DEVICE_GENE CTC_DEVICE_NAME "%d"
+#define MPC_DEVICE_GENE        MPC_DEVICE_NAME "%d"
 
 #define CHANNEL_FLAGS_READ     0
 #define CHANNEL_FLAGS_WRITE    1
 #define ctcm_pr_err(fmt, arg...) printk(KERN_ERR fmt, ##arg)
 #define ctcm_pr_crit(fmt, arg...) printk(KERN_CRIT fmt, ##arg)
 
+#define CTCM_PR_DEBUG(fmt, arg...) \
+       do { \
+               if (do_debug) \
+                       printk(KERN_DEBUG fmt, ##arg); \
+       } while (0)
+
+#define        CTCM_PR_DBGDATA(fmt, arg...) \
+       do { \
+               if (do_debug_data) \
+                       printk(KERN_DEBUG fmt, ##arg); \
+       } while (0)
+
+#define        CTCM_D3_DUMP(buf, len) \
+       do { \
+               if (do_debug_data) \
+                       ctcmpc_dumpit(buf, len); \
+       } while (0)
+
+#define        CTCM_CCW_DUMP(buf, len) \
+       do { \
+               if (do_debug_ccw) \
+                       ctcmpc_dumpit(buf, len); \
+       } while (0)
+
 /*
  * CCW commands, used in this driver.
  */
@@ -161,8 +185,9 @@ struct channel {
        fsm_instance *fsm;      /* finite state machine of this channel */
        struct net_device *netdev;      /* corresponding net_device */
        struct ctcm_profile prof;
-       unsigned char *trans_skb_data;
+       __u8 *trans_skb_data;
        __u16 logflags;
+       __u8  sense_rc; /* last unit check sense code report control */
 };
 
 struct ctcm_priv {
index 044addee64a28e877429a83cf21fd8e179522f65..49ae1cd25caaede02cf3a782c99089ecc43a9061 100644 (file)
@@ -149,7 +149,7 @@ void ctcmpc_dumpit(char *buf, int len)
        for (ct = 0; ct < len; ct++, ptr++, rptr++) {
                if (sw == 0) {
                        #if (UTS_MACHINE == s390x)
-                       sprintf(addr, "%16.16lx", (unsigned long)rptr);
+                       sprintf(addr, "%16.16lx", (__u64)rptr);
                        #else
                        sprintf(addr, "%8.8X", (__u32)rptr);
                        #endif
@@ -164,7 +164,7 @@ void ctcmpc_dumpit(char *buf, int len)
                        strcat(bhex, "  ");
 
                #if (UTS_MACHINE == s390x)
-               sprintf(tbuf, "%2.2lX", (unsigned long)*ptr);
+               sprintf(tbuf, "%2.2lX", (__u64)*ptr);
                #else
                sprintf(tbuf, "%2.2X", (__u32)*ptr);
                #endif
@@ -179,24 +179,24 @@ void ctcmpc_dumpit(char *buf, int len)
                basc[sw+1] = '\0';
                sw++;
                rm--;
-               if (sw == 16) {
-                       if ((strcmp(duphex, bhex)) != 0) {
-                               if (dup != 0) {
-                                       sprintf(tdup, "Duplicate as above "
-                                               "to %s", addr);
-                                       printk(KERN_INFO "                "
-                                               "     --- %s ---\n", tdup);
-                               }
-                               printk(KERN_INFO "   %s (+%s) : %s  [%s]\n",
+               if (sw != 16)
+                       continue;
+               if ((strcmp(duphex, bhex)) != 0) {
+                       if (dup != 0) {
+                               sprintf(tdup,
+                                       "Duplicate as above to %s", addr);
+                               ctcm_pr_debug("                --- %s ---\n",
+                                               tdup);
+                       }
+                       ctcm_pr_debug("   %s (+%s) : %s  [%s]\n",
                                        addr, boff, bhex, basc);
-                               dup = 0;
-                               strcpy(duphex, bhex);
-                       } else
-                               dup++;
+                       dup = 0;
+                       strcpy(duphex, bhex);
+               } else
+                       dup++;
 
-                       sw = 0;
-                       rm = 16;
-               }
+               sw = 0;
+               rm = 16;
        }  /* endfor */
 
        if (sw != 0) {
@@ -210,19 +210,17 @@ void ctcmpc_dumpit(char *buf, int len)
                }
                if (dup != 0) {
                        sprintf(tdup, "Duplicate as above to %s", addr);
-                       printk(KERN_INFO "                "
-                               "     --- %s ---\n", tdup);
+                       ctcm_pr_debug("                --- %s ---\n", tdup);
                }
-               printk(KERN_INFO "   %s (+%s) : %s  [%s]\n",
-                       addr, boff, bhex, basc);
+               ctcm_pr_debug("   %s (+%s) : %s  [%s]\n",
+                                       addr, boff, bhex, basc);
        } else {
                if (dup >= 1) {
                        sprintf(tdup, "Duplicate as above to %s", addr);
-                       printk(KERN_INFO "                "
-                               "     --- %s ---\n", tdup);
+                       ctcm_pr_debug("                --- %s ---\n", tdup);
                }
                if (dup != 0) {
-                       printk(KERN_INFO "   %s (+%s) : %s  [%s]\n",
+                       ctcm_pr_debug("   %s (+%s) : %s  [%s]\n",
                                addr, boff, bhex, basc);
                }
        }
@@ -241,7 +239,7 @@ void ctcmpc_dumpit(char *buf, int len)
  */
 void ctcmpc_dump_skb(struct sk_buff *skb, int offset)
 {
-       unsigned char *p = skb->data;
+       __u8 *p = skb->data;
        struct th_header *header;
        struct pdu *pheader;
        int bl = skb->len;
@@ -253,8 +251,8 @@ void ctcmpc_dump_skb(struct sk_buff *skb, int offset)
        p += offset;
        header = (struct th_header *)p;
 
-       printk(KERN_INFO "dump:\n");
-       printk(KERN_INFO "skb len=%d \n", skb->len);
+       ctcm_pr_debug("dump:\n");
+       ctcm_pr_debug("skb len=%d \n", skb->len);
        if (skb->len > 2) {
                switch (header->th_ch_flag) {
                case TH_HAS_PDU:
@@ -273,32 +271,64 @@ void ctcmpc_dump_skb(struct sk_buff *skb, int offset)
                }
 
                pheader = (struct pdu *)p;
-               printk(KERN_INFO "pdu->offset: %d hex: %04x\n",
-                      pheader->pdu_offset, pheader->pdu_offset);
-               printk(KERN_INFO "pdu->flag  : %02x\n", pheader->pdu_flag);
-               printk(KERN_INFO "pdu->proto : %02x\n", pheader->pdu_proto);
-               printk(KERN_INFO "pdu->seq   : %02x\n", pheader->pdu_seq);
+               ctcm_pr_debug("pdu->offset: %d hex: %04x\n",
+                              pheader->pdu_offset, pheader->pdu_offset);
+               ctcm_pr_debug("pdu->flag  : %02x\n", pheader->pdu_flag);
+               ctcm_pr_debug("pdu->proto : %02x\n", pheader->pdu_proto);
+               ctcm_pr_debug("pdu->seq   : %02x\n", pheader->pdu_seq);
                                        goto dumpdata;
 
 dumpth:
-               printk(KERN_INFO "th->seg     : %02x\n", header->th_seg);
-               printk(KERN_INFO "th->ch      : %02x\n", header->th_ch_flag);
-               printk(KERN_INFO "th->blk_flag: %02x\n", header->th_blk_flag);
-               printk(KERN_INFO "th->type    : %s\n",
-                      (header->th_is_xid) ? "DATA" : "XID");
-               printk(KERN_INFO "th->seqnum  : %04x\n", header->th_seq_num);
+               ctcm_pr_debug("th->seg     : %02x\n", header->th_seg);
+               ctcm_pr_debug("th->ch      : %02x\n", header->th_ch_flag);
+               ctcm_pr_debug("th->blk_flag: %02x\n", header->th_blk_flag);
+               ctcm_pr_debug("th->type    : %s\n",
+                              (header->th_is_xid) ? "DATA" : "XID");
+               ctcm_pr_debug("th->seqnum  : %04x\n", header->th_seq_num);
 
        }
 dumpdata:
        if (bl > 32)
                bl = 32;
-       printk(KERN_INFO "data: ");
+       ctcm_pr_debug("data: ");
        for (i = 0; i < bl; i++)
-               printk(KERN_INFO "%02x%s", *p++, (i % 16) ? " " : "\n<7>");
-       printk(KERN_INFO "\n");
+               ctcm_pr_debug("%02x%s", *p++, (i % 16) ? " " : "\n");
+       ctcm_pr_debug("\n");
 }
 #endif
 
+static struct net_device *ctcmpc_get_dev(int port_num)
+{
+       char device[20];
+       struct net_device *dev;
+       struct ctcm_priv *priv;
+
+       sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num);
+
+       dev = __dev_get_by_name(&init_net, device);
+
+       if (dev == NULL) {
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s: Device not found by name: %s",
+                                       CTCM_FUNTAIL, device);
+               return NULL;
+       }
+       priv = dev->priv;
+       if (priv == NULL) {
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): dev->priv is NULL",
+                                       CTCM_FUNTAIL, device);
+               return NULL;
+       }
+       if (priv->mpcg == NULL) {
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): priv->mpcg is NULL",
+                                       CTCM_FUNTAIL, device);
+               return NULL;
+       }
+       return dev;
+}
+
 /*
  * ctc_mpc_alloc_channel
  *     (exported interface)
@@ -308,34 +338,23 @@ dumpdata:
  */
 int ctc_mpc_alloc_channel(int port_num, void (*callback)(int, int))
 {
-       char device[20];
        struct net_device *dev;
        struct mpc_group *grp;
        struct ctcm_priv *priv;
 
-       ctcm_pr_debug("ctcmpc enter:    %s()\n", __FUNCTION__);
-
-       sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num);
-       dev = __dev_get_by_name(&init_net, device);
-
-       if (dev == NULL) {
-               printk(KERN_INFO "ctc_mpc_alloc_channel %s dev=NULL\n", device);
+       dev = ctcmpc_get_dev(port_num);
+       if (dev == NULL)
                return 1;
-       }
-
        priv = dev->priv;
        grp = priv->mpcg;
-       if (!grp)
-               return 1;
 
        grp->allochanfunc = callback;
        grp->port_num = port_num;
        grp->port_persist = 1;
 
-       ctcm_pr_debug("ctcmpc: %s called for device %s state=%s\n",
-                      __FUNCTION__,
-                      dev->name,
-                      fsm_getstate_str(grp->fsm));
+       CTCM_DBF_TEXT_(MPC_SETUP, CTC_DBF_INFO,
+                       "%s(%s): state=%s",
+                       CTCM_FUNTAIL, dev->name, fsm_getstate_str(grp->fsm));
 
        switch (fsm_getstate(grp->fsm)) {
        case MPCG_STATE_INOP:
@@ -377,12 +396,8 @@ int ctc_mpc_alloc_channel(int port_num, void (*callback)(int, int))
                        grp->allocchan_callback_retries = 0;
                }
                break;
-       default:
-               return 0;
-
        }
 
-       ctcm_pr_debug("ctcmpc exit:  %s()\n", __FUNCTION__);
        return 0;
 }
 EXPORT_SYMBOL(ctc_mpc_alloc_channel);
@@ -394,31 +409,22 @@ EXPORT_SYMBOL(ctc_mpc_alloc_channel);
 void ctc_mpc_establish_connectivity(int port_num,
                                void (*callback)(int, int, int))
 {
-       char device[20];
        struct net_device *dev;
        struct mpc_group *grp;
        struct ctcm_priv *priv;
        struct channel *rch, *wch;
 
-       ctcm_pr_debug("ctcmpc enter:    %s()\n", __FUNCTION__);
-
-       sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num);
-       dev = __dev_get_by_name(&init_net, device);
-
-       if (dev == NULL) {
-               printk(KERN_INFO "ctc_mpc_establish_connectivity "
-                               "%s dev=NULL\n", device);
+       dev = ctcmpc_get_dev(port_num);
+       if (dev == NULL)
                return;
-       }
        priv = dev->priv;
+       grp = priv->mpcg;
        rch = priv->channel[READ];
        wch = priv->channel[WRITE];
 
-       grp = priv->mpcg;
-
-       ctcm_pr_debug("ctcmpc: %s() called for device %s state=%s\n",
-                       __FUNCTION__, dev->name,
-                       fsm_getstate_str(grp->fsm));
+       CTCM_DBF_TEXT_(MPC_SETUP, CTC_DBF_INFO,
+                       "%s(%s): state=%s",
+                       CTCM_FUNTAIL, dev->name, fsm_getstate_str(grp->fsm));
 
        grp->estconnfunc = callback;
        grp->port_num = port_num;
@@ -446,8 +452,10 @@ void ctc_mpc_establish_connectivity(int port_num,
        case MPCG_STATE_RESET:
                /* MPC Group is not ready to start XID - min num of */
                /* 1 read and 1 write channel have not been acquired*/
-               printk(KERN_WARNING "ctcmpc: %s() REJECTED ACTIVE XID Req"
-                       "uest - Channel Pair is not Active\n", __FUNCTION__);
+
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): REJECTED - inactive channels",
+                                       CTCM_FUNTAIL, dev->name);
                if (grp->estconnfunc) {
                        grp->estconnfunc(grp->port_num, -1, 0);
                        grp->estconnfunc = NULL;
@@ -457,11 +465,12 @@ void ctc_mpc_establish_connectivity(int port_num,
                /* alloc channel was called but no XID exchange    */
                /* has occurred. initiate xside XID exchange       */
                /* make sure yside XID0 processing has not started */
+
                if ((fsm_getstate(rch->fsm) > CH_XID0_PENDING) ||
                        (fsm_getstate(wch->fsm) > CH_XID0_PENDING)) {
-                       printk(KERN_WARNING "mpc: %s() ABORT ACTIVE XID"
-                              " Request- PASSIVE XID in process\n"
-                              , __FUNCTION__);
+                       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): ABORT - PASSIVE XID",
+                                       CTCM_FUNTAIL, dev->name);
                        break;
                }
                grp->send_qllc_disc = 1;
@@ -476,9 +485,9 @@ void ctc_mpc_establish_connectivity(int port_num,
                                (fsm_getstate(rch->fsm) == CH_XID0_PENDING))
                        fsm_event(grp->fsm, MPCG_EVENT_XID0DO, rch);
                else {
-                       printk(KERN_WARNING "mpc: %s() Unable to start"
-                              " ACTIVE XID0 on read channel\n",
-                              __FUNCTION__);
+                       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): RX-%s not ready for ACTIVE XID0",
+                                       CTCM_FUNTAIL, dev->name, rch->id);
                        if (grp->estconnfunc) {
                                grp->estconnfunc(grp->port_num, -1, 0);
                                grp->estconnfunc = NULL;
@@ -490,9 +499,9 @@ void ctc_mpc_establish_connectivity(int port_num,
                                (fsm_getstate(wch->fsm) == CH_XID0_PENDING))
                        fsm_event(grp->fsm, MPCG_EVENT_XID0DO, wch);
                else {
-                       printk(KERN_WARNING "mpc: %s() Unable to start"
-                               " ACTIVE XID0 on write channel\n",
-                                       __FUNCTION__);
+                       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): WX-%s not ready for ACTIVE XID0",
+                                       CTCM_FUNTAIL, dev->name, wch->id);
                        if (grp->estconnfunc) {
                                grp->estconnfunc(grp->port_num, -1, 0);
                                grp->estconnfunc = NULL;
@@ -508,7 +517,7 @@ void ctc_mpc_establish_connectivity(int port_num,
        }
 
 done:
-       ctcm_pr_debug("ctcmpc exit:  %s()\n", __FUNCTION__);
+       CTCM_PR_DEBUG("Exit %s()\n", __func__);
        return;
 }
 EXPORT_SYMBOL(ctc_mpc_establish_connectivity);
@@ -520,40 +529,22 @@ EXPORT_SYMBOL(ctc_mpc_establish_connectivity);
 void ctc_mpc_dealloc_ch(int port_num)
 {
        struct net_device *dev;
-       char device[20];
        struct ctcm_priv *priv;
        struct mpc_group *grp;
 
-       ctcm_pr_debug("ctcmpc enter:    %s()\n", __FUNCTION__);
-       sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num);
-       dev = __dev_get_by_name(&init_net, device);
-
-       if (dev == NULL) {
-               printk(KERN_INFO "%s() %s dev=NULL\n", __FUNCTION__, device);
-                                       goto done;
-       }
+       dev = ctcmpc_get_dev(port_num);
+       if (dev == NULL)
+               return;
+       priv = dev->priv;
+       grp = priv->mpcg;
 
-       ctcm_pr_debug("ctcmpc:%s %s() called for device %s refcount=%d\n",
-                       dev->name, __FUNCTION__,
-                       dev->name, atomic_read(&dev->refcnt));
+       CTCM_DBF_TEXT_(MPC_SETUP, CTC_DBF_DEBUG,
+                       "%s: %s: refcount = %d\n",
+                       CTCM_FUNTAIL, dev->name, atomic_read(&dev->refcnt));
 
-       priv = dev->priv;
-       if (priv == NULL) {
-               printk(KERN_INFO "%s() %s priv=NULL\n",
-                               __FUNCTION__, device);
-                                       goto done;
-       }
        fsm_deltimer(&priv->restart_timer);
-
-       grp = priv->mpcg;
-       if (grp == NULL) {
-               printk(KERN_INFO "%s() %s dev=NULL\n", __FUNCTION__, device);
-                                       goto done;
-       }
        grp->channels_terminating = 0;
-
        fsm_deltimer(&grp->timer);
-
        grp->allochanfunc = NULL;
        grp->estconnfunc = NULL;
        grp->port_persist = 0;
@@ -561,8 +552,6 @@ void ctc_mpc_dealloc_ch(int port_num)
        fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
 
        ctcm_close(dev);
-done:
-       ctcm_pr_debug("ctcmpc exit:  %s()\n", __FUNCTION__);
        return;
 }
 EXPORT_SYMBOL(ctc_mpc_dealloc_ch);
@@ -573,32 +562,22 @@ EXPORT_SYMBOL(ctc_mpc_dealloc_ch);
  */
 void ctc_mpc_flow_control(int port_num, int flowc)
 {
-       char device[20];
        struct ctcm_priv *priv;
        struct mpc_group *grp;
        struct net_device *dev;
        struct channel *rch;
        int mpcg_state;
 
-       ctcm_pr_debug("ctcmpc enter:    %s() %i\n", __FUNCTION__, flowc);
-
-       sprintf(device, "%s%i", MPC_DEVICE_NAME, port_num);
-       dev = __dev_get_by_name(&init_net, device);
-
-       if (dev == NULL) {
-               printk(KERN_INFO "ctc_mpc_flow_control %s dev=NULL\n", device);
+       dev = ctcmpc_get_dev(port_num);
+       if (dev == NULL)
                return;
-       }
+       priv = dev->priv;
+       grp = priv->mpcg;
 
-       ctcm_pr_debug("ctcmpc: %s %s called \n", dev->name, __FUNCTION__);
+       CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG,
+                       "%s: %s: flowc = %d",
+                               CTCM_FUNTAIL, dev->name, flowc);
 
-       priv  = dev->priv;
-       if (priv == NULL) {
-               printk(KERN_INFO "ctcmpc:%s() %s priv=NULL\n",
-                      __FUNCTION__, device);
-               return;
-       }
-       grp = priv->mpcg;
        rch = priv->channel[READ];
 
        mpcg_state = fsm_getstate(grp->fsm);
@@ -629,7 +608,6 @@ void ctc_mpc_flow_control(int port_num, int flowc)
                break;
        }
 
-       ctcm_pr_debug("ctcmpc exit:  %s() %i\n", __FUNCTION__, flowc);
 }
 EXPORT_SYMBOL(ctc_mpc_flow_control);
 
@@ -646,12 +624,8 @@ static void mpc_rcvd_sweep_resp(struct mpcg_info *mpcginfo)
        struct mpc_group  *grp = priv->mpcg;
        struct channel    *ch = priv->channel[WRITE];
 
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc enter: %s(): ch=0x%p id=%s\n",
-                       __FUNCTION__, ch, ch->id);
-
-       if (do_debug_data)
-               ctcmpc_dumpit((char *)mpcginfo->sweep, TH_SWEEP_LENGTH);
+       CTCM_PR_DEBUG("%s: ch=0x%p id=%s\n", __func__, ch, ch->id);
+       CTCM_D3_DUMP((char *)mpcginfo->sweep, TH_SWEEP_LENGTH);
 
        grp->sweep_rsp_pend_num--;
 
@@ -684,14 +658,13 @@ static void ctcmpc_send_sweep_resp(struct channel *rch)
        struct sk_buff *sweep_skb;
        struct channel *ch  = priv->channel[WRITE];
 
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
-                       __FUNCTION__, rch, rch->id);
+       CTCM_PR_DEBUG("%s: ch=0x%p id=%s\n", __func__, rch, rch->id);
 
-       sweep_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT,
-                                   GFP_ATOMIC|GFP_DMA);
+       sweep_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC | GFP_DMA);
        if (sweep_skb == NULL) {
-               printk(KERN_INFO "Couldn't alloc sweep_skb\n");
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): sweep_skb allocation ERROR\n",
+                       CTCM_FUNTAIL, rch->id);
                rc = -ENOMEM;
                                goto done;
        }
@@ -746,7 +719,7 @@ static void mpc_rcvd_sweep_req(struct mpcg_info *mpcginfo)
 
        if (do_debug)
                CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG,
-                       " %s(): ch=0x%p id=%s\n", __FUNCTION__, ch, ch->id);
+                       " %s(): ch=0x%p id=%s\n", __func__, ch, ch->id);
 
        if (grp->in_sweep == 0) {
                grp->in_sweep = 1;
@@ -755,8 +728,7 @@ static void mpc_rcvd_sweep_req(struct mpcg_info *mpcginfo)
                grp->sweep_rsp_pend_num = grp->active_channels[READ];
        }
 
-       if (do_debug_data)
-               ctcmpc_dumpit((char *)mpcginfo->sweep, TH_SWEEP_LENGTH);
+       CTCM_D3_DUMP((char *)mpcginfo->sweep, TH_SWEEP_LENGTH);
 
        grp->sweep_req_pend_num--;
        ctcmpc_send_sweep_resp(ch);
@@ -875,25 +847,13 @@ static int mpcg_fsm_len = ARRAY_SIZE(mpcg_fsm);
 static void mpc_action_go_ready(fsm_instance *fsm, int event, void *arg)
 {
        struct net_device *dev = arg;
-       struct ctcm_priv *priv = NULL;
-       struct mpc_group *grp = NULL;
-
-       if (dev == NULL) {
-               printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
-               return;
-       }
-
-       ctcm_pr_debug("ctcmpc enter: %s  %s()\n", dev->name, __FUNCTION__);
-
-       priv = dev->priv;
-       if (priv == NULL) {
-               printk(KERN_INFO "%s() priv=NULL\n", __FUNCTION__);
-               return;
-       }
+       struct ctcm_priv *priv = dev->priv;
+       struct mpc_group *grp = priv->mpcg;
 
-       grp = priv->mpcg;
        if (grp == NULL) {
-               printk(KERN_INFO "%s() grp=NULL\n", __FUNCTION__);
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): No MPC group",
+                               CTCM_FUNTAIL, dev->name);
                return;
        }
 
@@ -907,7 +867,12 @@ static void mpc_action_go_ready(fsm_instance *fsm, int event, void *arg)
                        grp->estconnfunc = NULL;
                } else if (grp->allochanfunc)
                        grp->send_qllc_disc = 1;
-                                       goto done;
+
+               fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): fails",
+                                       CTCM_FUNTAIL, dev->name);
+               return;
        }
 
        grp->port_persist = 1;
@@ -916,14 +881,7 @@ static void mpc_action_go_ready(fsm_instance *fsm, int event, void *arg)
 
        tasklet_hi_schedule(&grp->mpc_tasklet2);
 
-       ctcm_pr_debug("ctcmpc exit: %s  %s()\n", dev->name, __FUNCTION__);
        return;
-
-done:
-       fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
-
-
-       ctcm_pr_info("ctcmpc: %s()failure occurred\n", __FUNCTION__);
 }
 
 /*
@@ -933,42 +891,28 @@ done:
 void mpc_group_ready(unsigned long adev)
 {
        struct net_device *dev = (struct net_device *)adev;
-       struct ctcm_priv *priv = NULL;
-       struct mpc_group  *grp = NULL;
+       struct ctcm_priv *priv = dev->priv;
+       struct mpc_group *grp = priv->mpcg;
        struct channel *ch = NULL;
 
-
-       ctcm_pr_debug("ctcmpc enter:    %s()\n", __FUNCTION__);
-
-       if (dev == NULL) {
-               printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
-               return;
-       }
-
-       priv = dev->priv;
-       if (priv == NULL) {
-               printk(KERN_INFO "%s() priv=NULL\n", __FUNCTION__);
-               return;
-       }
-
-       grp = priv->mpcg;
        if (grp == NULL) {
-               printk(KERN_INFO "ctcmpc:%s() grp=NULL\n", __FUNCTION__);
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): No MPC group",
+                               CTCM_FUNTAIL, dev->name);
                return;
        }
 
-       printk(KERN_NOTICE "ctcmpc: %s GROUP TRANSITIONED TO READY"
-              "  maxbuf:%d\n",
-              dev->name, grp->group_max_buflen);
+       CTCM_DBF_TEXT_(MPC_SETUP, CTC_DBF_NOTICE,
+               "%s: %s: GROUP TRANSITIONED TO READY, maxbuf = %d\n",
+                       CTCM_FUNTAIL, dev->name, grp->group_max_buflen);
 
        fsm_newstate(grp->fsm, MPCG_STATE_READY);
 
        /* Put up a read on the channel */
        ch = priv->channel[READ];
        ch->pdu_seq = 0;
-       if (do_debug_data)
-               ctcm_pr_debug("ctcmpc: %s() ToDCM_pdu_seq= %08x\n" ,
-                       __FUNCTION__, ch->pdu_seq);
+       CTCM_PR_DBGDATA("ctcmpc: %s() ToDCM_pdu_seq= %08x\n" ,
+                       __func__, ch->pdu_seq);
 
        ctcmpc_chx_rxidle(ch->fsm, CTC_EVENT_START, ch);
        /* Put the write channel in idle state */
@@ -980,22 +924,18 @@ void mpc_group_ready(unsigned long adev)
                spin_unlock(&ch->collect_lock);
        }
        ctcm_chx_txidle(ch->fsm, CTC_EVENT_START, ch);
-
        ctcm_clear_busy(dev);
 
        if (grp->estconnfunc) {
                grp->estconnfunc(grp->port_num, 0,
                                    grp->group_max_buflen);
                grp->estconnfunc = NULL;
-       } else
-               if (grp->allochanfunc)
-               grp->allochanfunc(grp->port_num,
-                                    grp->group_max_buflen);
+       } else  if (grp->allochanfunc)
+               grp->allochanfunc(grp->port_num, grp->group_max_buflen);
 
        grp->send_qllc_disc = 1;
        grp->changed_side = 0;
 
-       ctcm_pr_debug("ctcmpc exit:  %s()\n", __FUNCTION__);
        return;
 
 }
@@ -1004,51 +944,26 @@ void mpc_group_ready(unsigned long adev)
  * Increment the MPC Group Active Channel Counts
  * helper of dev_action (called from channel fsm)
  */
-int mpc_channel_action(struct channel *ch, int direction, int action)
+void mpc_channel_action(struct channel *ch, int direction, int action)
 {
-       struct net_device  *dev     = ch->netdev;
-       struct ctcm_priv    *priv;
-       struct mpc_group   *grp  = NULL;
-       int         rc = 0;
-
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc enter: %s(): ch=0x%p id=%s\n",
-                       __FUNCTION__, ch, ch->id);
-
-       if (dev == NULL) {
-               printk(KERN_INFO "ctcmpc_channel_action %i dev=NULL\n",
-                      action);
-               rc = 1;
-                                       goto done;
-       }
-
-       priv = dev->priv;
-       if (priv == NULL) {
-               printk(KERN_INFO
-                      "ctcmpc_channel_action%i priv=NULL, dev=%s\n",
-                      action, dev->name);
-               rc = 2;
-                                       goto done;
-       }
-
-       grp = priv->mpcg;
+       struct net_device  *dev  = ch->netdev;
+       struct ctcm_priv   *priv = dev->priv;
+       struct mpc_group   *grp  = priv->mpcg;
 
        if (grp == NULL) {
-               printk(KERN_INFO "ctcmpc: %s()%i mpcgroup=NULL, dev=%s\n",
-                      __FUNCTION__, action, dev->name);
-               rc = 3;
-                                       goto done;
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): No MPC group",
+                               CTCM_FUNTAIL, dev->name);
+               return;
        }
 
-       ctcm_pr_info(
-                     "ctcmpc: %s() %i(): Grp:%s total_channel_paths=%i "
-                     "active_channels read=%i, write=%i\n",
-                     __FUNCTION__,
-                     action,
-                     fsm_getstate_str(grp->fsm),
-                     grp->num_channel_paths,
-                     grp->active_channels[READ],
-                     grp->active_channels[WRITE]);
+       CTCM_PR_DEBUG("enter %s: ch=0x%p id=%s\n", __func__, ch, ch->id);
+
+       CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_NOTICE,
+               "%s: %i / Grp:%s total_channels=%i, active_channels: "
+               "read=%i, write=%i\n", __func__, action,
+               fsm_getstate_str(grp->fsm), grp->num_channel_paths,
+               grp->active_channels[READ], grp->active_channels[WRITE]);
 
        if ((action == MPC_CHANNEL_ADD) && (ch->in_mpcgroup == 0)) {
                grp->num_channel_paths++;
@@ -1062,10 +977,11 @@ int mpc_channel_action(struct channel *ch, int direction, int action)
                ch->xid_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT,
                                        GFP_ATOMIC | GFP_DMA);
                if (ch->xid_skb == NULL) {
-                       printk(KERN_INFO "ctcmpc: %s()"
-                              "Couldn't alloc ch xid_skb\n", __FUNCTION__);
+                       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): Couldn't alloc ch xid_skb\n",
+                               CTCM_FUNTAIL, dev->name);
                        fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
-                       return 1;
+                       return;
                }
                ch->xid_skb_data = ch->xid_skb->data;
                ch->xid_th = (struct th_header *)ch->xid_skb->data;
@@ -1097,8 +1013,9 @@ int mpc_channel_action(struct channel *ch, int direction, int action)
                    (grp->active_channels[WRITE] > 0) &&
                        (fsm_getstate(grp->fsm) < MPCG_STATE_XID2INITW)) {
                        fsm_newstate(grp->fsm, MPCG_STATE_XID2INITW);
-                       printk(KERN_NOTICE "ctcmpc: %s MPC GROUP "
-                                       "CHANNELS ACTIVE\n", dev->name);
+                       CTCM_DBF_TEXT_(MPC_SETUP, CTC_DBF_NOTICE,
+                               "%s: %s: MPC GROUP CHANNELS ACTIVE\n",
+                                               __func__, dev->name);
                }
        } else if ((action == MPC_CHANNEL_REMOVE) &&
                        (ch->in_mpcgroup == 1)) {
@@ -1119,25 +1036,14 @@ int mpc_channel_action(struct channel *ch, int direction, int action)
                                        (grp->active_channels[READ] > 0)))
                        fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
        }
-
 done:
+       CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG,
+               "exit %s: %i / Grp:%s total_channels=%i, active_channels: "
+               "read=%i, write=%i\n", __func__, action,
+               fsm_getstate_str(grp->fsm), grp->num_channel_paths,
+               grp->active_channels[READ], grp->active_channels[WRITE]);
 
-       if (do_debug) {
-               ctcm_pr_debug(
-                      "ctcmpc: %s() %i Grp:%s ttl_chan_paths=%i "
-                      "active_chans read=%i, write=%i\n",
-                      __FUNCTION__,
-                      action,
-                      fsm_getstate_str(grp->fsm),
-                      grp->num_channel_paths,
-                      grp->active_channels[READ],
-                      grp->active_channels[WRITE]);
-
-               ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
-                               __FUNCTION__, ch, ch->id);
-       }
-       return rc;
-
+       CTCM_PR_DEBUG("exit %s: ch=0x%p id=%s\n", __func__, ch, ch->id);
 }
 
 /**
@@ -1163,9 +1069,8 @@ static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
        int skblen;
        int sendrc = 0;
 
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc enter: %s() %s cp:%i ch:%s\n",
-                      __FUNCTION__, dev->name, smp_processor_id(), ch->id);
+       CTCM_PR_DEBUG("ctcmpc enter: %s() %s cp:%i ch:%s\n",
+                       __func__, dev->name, smp_processor_id(), ch->id);
 
        header = (struct th_header *)pskb->data;
        if ((header->th_seg == 0) &&
@@ -1174,21 +1079,16 @@ static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
                (header->th_seq_num == 0))
                /* nothing for us */    goto done;
 
-       if (do_debug_data) {
-               ctcm_pr_debug("ctcmpc: %s() th_header\n", __FUNCTION__);
-               ctcmpc_dumpit((char *)header, TH_HEADER_LENGTH);
-               ctcm_pr_debug("ctcmpc: %s() pskb len: %04x \n",
-                      __FUNCTION__, pskb->len);
-       }
+       CTCM_PR_DBGDATA("%s: th_header\n", __func__);
+       CTCM_D3_DUMP((char *)header, TH_HEADER_LENGTH);
+       CTCM_PR_DBGDATA("%s: pskb len: %04x \n", __func__, pskb->len);
 
        pskb->dev = dev;
        pskb->ip_summed = CHECKSUM_UNNECESSARY;
        skb_pull(pskb, TH_HEADER_LENGTH);
 
        if (likely(header->th_ch_flag == TH_HAS_PDU)) {
-               if (do_debug_data)
-                       ctcm_pr_debug("ctcmpc: %s() came into th_has_pdu\n",
-                              __FUNCTION__);
+               CTCM_PR_DBGDATA("%s: came into th_has_pdu\n", __func__);
                if ((fsm_getstate(grp->fsm) == MPCG_STATE_FLOWC) ||
                   ((fsm_getstate(grp->fsm) == MPCG_STATE_READY) &&
                    (header->th_seq_num != ch->th_seq_num + 1) &&
@@ -1202,33 +1102,29 @@ static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
                        grp->out_of_sequence += 1;
                        __skb_push(pskb, TH_HEADER_LENGTH);
                        skb_queue_tail(&ch->io_queue, pskb);
-                       if (do_debug_data)
-                               ctcm_pr_debug("ctcmpc: %s() th_seq_num "
-                                      "expect:%08x got:%08x\n", __FUNCTION__,
-                                      ch->th_seq_num + 1, header->th_seq_num);
+                       CTCM_PR_DBGDATA("%s: th_seq_num expect:%08x "
+                                       "got:%08x\n", __func__,
+                               ch->th_seq_num + 1, header->th_seq_num);
 
                        return;
                }
                grp->out_of_sequence = 0;
                ch->th_seq_num = header->th_seq_num;
 
-               if (do_debug_data)
-                       ctcm_pr_debug("ctcmpc: %s() FromVTAM_th_seq=%08x\n",
-                              __FUNCTION__, ch->th_seq_num);
+               CTCM_PR_DBGDATA("ctcmpc: %s() FromVTAM_th_seq=%08x\n",
+                                       __func__, ch->th_seq_num);
 
                if (unlikely(fsm_getstate(grp->fsm) != MPCG_STATE_READY))
                                        goto done;
                pdu_last_seen = 0;
                while ((pskb->len > 0) && !pdu_last_seen) {
                        curr_pdu = (struct pdu *)pskb->data;
-                       if (do_debug_data) {
-                               ctcm_pr_debug("ctcm: %s() pdu_header\n",
-                                      __FUNCTION__);
-                               ctcmpc_dumpit((char *)pskb->data,
-                                               PDU_HEADER_LENGTH);
-                               ctcm_pr_debug("ctcm: %s() pskb len: %04x \n",
-                                      __FUNCTION__, pskb->len);
-                       }
+
+                       CTCM_PR_DBGDATA("%s: pdu_header\n", __func__);
+                       CTCM_D3_DUMP((char *)pskb->data, PDU_HEADER_LENGTH);
+                       CTCM_PR_DBGDATA("%s: pskb len: %04x \n",
+                                               __func__, pskb->len);
+
                        skb_pull(pskb, PDU_HEADER_LENGTH);
 
                        if (curr_pdu->pdu_flag & PDU_LAST)
@@ -1239,46 +1135,39 @@ static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
                                pskb->protocol = htons(ETH_P_SNA_DIX);
 
                        if ((pskb->len <= 0) || (pskb->len > ch->max_bufsize)) {
-                               printk(KERN_INFO
-                                      "%s Illegal packet size %d "
-                                      "received "
-                                      "dropping\n", dev->name,
-                                      pskb->len);
+                               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                                       "%s(%s): Dropping packet with "
+                                       "illegal siize %d",
+                                       CTCM_FUNTAIL, dev->name, pskb->len);
+
                                priv->stats.rx_dropped++;
                                priv->stats.rx_length_errors++;
                                        goto done;
                        }
                        skb_reset_mac_header(pskb);
                        new_len = curr_pdu->pdu_offset;
-                       if (do_debug_data)
-                               ctcm_pr_debug("ctcmpc: %s() new_len: %04x \n",
-                                      __FUNCTION__, new_len);
+                       CTCM_PR_DBGDATA("%s: new_len: %04x \n",
+                                               __func__, new_len);
                        if ((new_len == 0) || (new_len > pskb->len)) {
                                /* should never happen              */
                                /* pskb len must be hosed...bail out */
-                               printk(KERN_INFO
-                                      "ctcmpc: %s(): invalid pdu"
-                                      " offset of %04x - data may be"
-                                      "lost\n", __FUNCTION__, new_len);
-                                               goto done;
+                               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                                       "%s(%s): non valid pdu_offset: %04x",
+                                       /* "data may be lost", */
+                                       CTCM_FUNTAIL, dev->name, new_len);
+                               goto done;
                        }
                        skb = __dev_alloc_skb(new_len+4, GFP_ATOMIC);
 
                        if (!skb) {
-                               printk(KERN_INFO
-                                      "ctcm: %s Out of memory in "
-                                      "%s()- request-len:%04x \n",
-                                      dev->name,
-                                      __FUNCTION__,
-                                      new_len+4);
+                               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                                       "%s(%s): MEMORY allocation error",
+                                               CTCM_FUNTAIL, dev->name);
                                priv->stats.rx_dropped++;
-                               fsm_event(grp->fsm,
-                                         MPCG_EVENT_INOP, dev);
+                               fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
                                                goto done;
                        }
-
-                       memcpy(skb_put(skb, new_len),
-                                       pskb->data, new_len);
+                       memcpy(skb_put(skb, new_len), pskb->data, new_len);
 
                        skb_reset_mac_header(skb);
                        skb->dev = pskb->dev;
@@ -1287,17 +1176,14 @@ static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
                        *((__u32 *) skb_push(skb, 4)) = ch->pdu_seq;
                        ch->pdu_seq++;
 
-                       if (do_debug_data)
-                               ctcm_pr_debug("%s: ToDCM_pdu_seq= %08x\n",
-                                      __FUNCTION__, ch->pdu_seq);
-
-                       ctcm_pr_debug("ctcm: %s() skb:%0lx "
-                               "skb len: %d \n", __FUNCTION__,
-                              (unsigned long)skb, skb->len);
                        if (do_debug_data) {
-                               ctcm_pr_debug("ctcmpc: %s() up to 32 bytes"
-                                              " of pdu_data sent\n",
-                                              __FUNCTION__);
+                               ctcm_pr_debug("%s: ToDCM_pdu_seq= %08x\n",
+                                               __func__, ch->pdu_seq);
+                               ctcm_pr_debug("%s: skb:%0lx "
+                                       "skb len: %d \n", __func__,
+                                       (unsigned long)skb, skb->len);
+                               ctcm_pr_debug("%s: up to 32 bytes "
+                                       "of pdu_data sent\n", __func__);
                                ctcmpc_dump32((char *)skb->data, skb->len);
                        }
 
@@ -1316,8 +1202,8 @@ static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
                mpcginfo->ch = ch;
                mpcginfo->th = header;
                mpcginfo->skb = pskb;
-               ctcm_pr_debug("ctcmpc: %s() Not PDU - may be control pkt\n",
-                              __FUNCTION__);
+               CTCM_PR_DEBUG("%s: Not PDU - may be control pkt\n",
+                                       __func__);
                /*  it's a sweep?   */
                sweep = (struct th_sweep *)pskb->data;
                mpcginfo->sweep = sweep;
@@ -1333,8 +1219,9 @@ static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
                } else if (header->th_blk_flag == TH_DISCONTACT)
                        fsm_event(grp->fsm, MPCG_EVENT_DISCONC, mpcginfo);
                else if (header->th_seq_num != 0) {
-                       printk(KERN_INFO "%s unexpected packet"
-                                       " expected control pkt\n", dev->name);
+                       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): control pkt expected\n",
+                                               CTCM_FUNTAIL, dev->name);
                        priv->stats.rx_dropped++;
                        /* mpcginfo only used for non-data transfers */
                        kfree(mpcginfo);
@@ -1347,13 +1234,12 @@ done:
        dev_kfree_skb_any(pskb);
        if (sendrc == NET_RX_DROP) {
                printk(KERN_WARNING "%s %s() NETWORK BACKLOG EXCEEDED"
-                      " - PACKET DROPPED\n", dev->name, __FUNCTION__);
+                      " - PACKET DROPPED\n", dev->name, __func__);
                fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
        }
 
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc exit : %s %s(): ch=0x%p id=%s\n",
-                               dev->name, __FUNCTION__, ch, ch->id);
+       CTCM_PR_DEBUG("exit %s: %s: ch=0x%p id=%s\n",
+                       __func__, dev->name, ch, ch->id);
 }
 
 /**
@@ -1366,15 +1252,14 @@ done:
  */
 void ctcmpc_bh(unsigned long thischan)
 {
-       struct channel    *ch       = (struct channel *)thischan;
+       struct channel    *ch   = (struct channel *)thischan;
        struct sk_buff    *skb;
-       struct net_device *dev      = ch->netdev;
-       struct ctcm_priv  *priv  = dev->priv;
-       struct mpc_group  *grp   = priv->mpcg;
+       struct net_device *dev  = ch->netdev;
+       struct ctcm_priv  *priv = dev->priv;
+       struct mpc_group  *grp  = priv->mpcg;
 
-       if (do_debug)
-               ctcm_pr_debug("%s cp:%i enter:  %s() %s\n",
-                      dev->name, smp_processor_id(), __FUNCTION__, ch->id);
+       CTCM_PR_DEBUG("%s cp:%i enter:  %s() %s\n",
+              dev->name, smp_processor_id(), __func__, ch->id);
        /* caller has requested driver to throttle back */
        while ((fsm_getstate(grp->fsm) != MPCG_STATE_FLOWC) &&
                        (skb = skb_dequeue(&ch->io_queue))) {
@@ -1390,9 +1275,8 @@ void ctcmpc_bh(unsigned long thischan)
                if (skb == skb_peek(&ch->io_queue))
                        break;
        }
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc exit : %s %s(): ch=0x%p id=%s\n",
-                       dev->name, __FUNCTION__, ch,  ch->id);
+       CTCM_PR_DEBUG("exit %s: %s: ch=0x%p id=%s\n",
+                       __func__, dev->name, ch, ch->id);
        return;
 }
 
@@ -1403,16 +1287,16 @@ struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv)
 {
        struct mpc_group *grp;
 
-       CTCM_DBF_TEXT(MPC_SETUP, 3, __FUNCTION__);
+       CTCM_DBF_TEXT_(MPC_SETUP, CTC_DBF_INFO,
+                       "Enter %s(%p)", CTCM_FUNTAIL, priv);
 
        grp = kzalloc(sizeof(struct mpc_group), GFP_KERNEL);
        if (grp == NULL)
                return NULL;
 
-       grp->fsm =
-               init_fsm("mpcg", mpcg_state_names, mpcg_event_names,
-                                MPCG_NR_STATES, MPCG_NR_EVENTS, mpcg_fsm,
-                                mpcg_fsm_len, GFP_KERNEL);
+       grp->fsm = init_fsm("mpcg", mpcg_state_names, mpcg_event_names,
+                       MPCG_NR_STATES, MPCG_NR_EVENTS, mpcg_fsm,
+                       mpcg_fsm_len, GFP_KERNEL);
        if (grp->fsm == NULL) {
                kfree(grp);
                return NULL;
@@ -1424,7 +1308,6 @@ struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv)
        grp->xid_skb =
                 __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC | GFP_DMA);
        if (grp->xid_skb == NULL) {
-               printk(KERN_INFO "Couldn't alloc MPCgroup xid_skb\n");
                kfree_fsm(grp->fsm);
                kfree(grp);
                return NULL;
@@ -1435,7 +1318,7 @@ struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv)
        memcpy(skb_put(grp->xid_skb, TH_HEADER_LENGTH),
                        &thnorm, TH_HEADER_LENGTH);
 
-       grp->xid = (struct xid2 *) skb_tail_pointer(grp->xid_skb);
+       grp->xid = (struct xid2 *)skb_tail_pointer(grp->xid_skb);
        memcpy(skb_put(grp->xid_skb, XID2_LENGTH), &init_xid, XID2_LENGTH);
        grp->xid->xid2_adj_id = jiffies | 0xfff00000;
        grp->xid->xid2_sender_id = jiffies;
@@ -1446,7 +1329,6 @@ struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv)
        grp->rcvd_xid_skb =
                __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC|GFP_DMA);
        if (grp->rcvd_xid_skb == NULL) {
-               printk(KERN_INFO "Couldn't alloc MPCgroup rcvd_xid_skb\n");
                kfree_fsm(grp->fsm);
                dev_kfree_skb(grp->xid_skb);
                kfree(grp);
@@ -1492,32 +1374,27 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
        int rc = 0;
        struct channel *wch, *rch;
 
-       if (dev == NULL) {
-               printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
-               return;
-       }
-
-       ctcm_pr_debug("ctcmpc enter: %s  %s()\n", dev->name, __FUNCTION__);
+       BUG_ON(dev == NULL);
+       CTCM_PR_DEBUG("Enter %s: %s\n", __func__, dev->name);
 
        priv  = dev->priv;
        grp =  priv->mpcg;
        grp->flow_off_called = 0;
-
        fsm_deltimer(&grp->timer);
-
        if (grp->channels_terminating)
-                                       goto done;
+                       return;
 
        grp->channels_terminating = 1;
-
        grp->saved_state = fsm_getstate(grp->fsm);
        fsm_newstate(grp->fsm, MPCG_STATE_INOP);
        if (grp->saved_state > MPCG_STATE_XID7INITF)
-               printk(KERN_NOTICE "%s:MPC GROUP INOPERATIVE\n", dev->name);
+               CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_NOTICE,
+                       "%s(%s): MPC GROUP INOPERATIVE",
+                               CTCM_FUNTAIL, dev->name);
        if ((grp->saved_state != MPCG_STATE_RESET) ||
                /* dealloc_channel has been called */
-               ((grp->saved_state == MPCG_STATE_RESET) &&
-                               (grp->port_persist == 0)))
+                       ((grp->saved_state == MPCG_STATE_RESET) &&
+                                               (grp->port_persist == 0)))
                fsm_deltimer(&priv->restart_timer);
 
        wch = priv->channel[WRITE];
@@ -1567,29 +1444,24 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
        /* This can result in INOP of VTAM PU due to halting of  */
        /* outstanding IO which causes a sense to be returned    */
        /* Only about 3 senses are allowed and then IOS/VTAM will*/
-       /* ebcome unreachable without manual intervention        */
-       if ((grp->port_persist == 1)    || (grp->alloc_called)) {
+       /* become unreachable without manual intervention        */
+       if ((grp->port_persist == 1) || (grp->alloc_called)) {
                grp->alloc_called = 0;
                fsm_deltimer(&priv->restart_timer);
-               fsm_addtimer(&priv->restart_timer,
-                            500,
-                            DEV_EVENT_RESTART,
-                            dev);
+               fsm_addtimer(&priv->restart_timer, 500, DEV_EVENT_RESTART, dev);
                fsm_newstate(grp->fsm, MPCG_STATE_RESET);
                if (grp->saved_state > MPCG_STATE_XID7INITF)
-                       printk(KERN_NOTICE "%s:MPC GROUP RECOVERY SCHEDULED\n",
-                              dev->name);
+                       CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_ALWAYS,
+                               "%s(%s): MPC GROUP RECOVERY SCHEDULED",
+                                       CTCM_FUNTAIL, dev->name);
        } else {
                fsm_deltimer(&priv->restart_timer);
                fsm_addtimer(&priv->restart_timer, 500, DEV_EVENT_STOP, dev);
                fsm_newstate(grp->fsm, MPCG_STATE_RESET);
-               printk(KERN_NOTICE "%s:MPC GROUP RECOVERY NOT ATTEMPTED\n",
-                      dev->name);
+               CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_ALWAYS,
+                       "%s(%s): NO MPC GROUP RECOVERY ATTEMPTED",
+                                               CTCM_FUNTAIL, dev->name);
        }
-
-done:
-       ctcm_pr_debug("ctcmpc exit:%s  %s()\n", dev->name, __FUNCTION__);
-       return;
 }
 
 /**
@@ -1609,12 +1481,7 @@ static void mpc_action_timeout(fsm_instance *fi, int event, void *arg)
        struct channel *wch;
        struct channel *rch;
 
-       CTCM_DBF_TEXT(MPC_TRACE, 6, __FUNCTION__);
-
-       if (dev == NULL) {
-               CTCM_DBF_TEXT_(MPC_ERROR, 4, "%s: dev=NULL\n", __FUNCTION__);
-               return;
-       }
+       BUG_ON(dev == NULL);
 
        priv = dev->priv;
        grp = priv->mpcg;
@@ -1633,8 +1500,9 @@ static void mpc_action_timeout(fsm_instance *fi, int event, void *arg)
                fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
        }
 
-       CTCM_DBF_TEXT_(MPC_TRACE, 6, "%s: dev=%s exit",
-                                       __FUNCTION__, dev->name);
+       CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG,
+                       "%s: dev=%s exit",
+                       CTCM_FUNTAIL, dev->name);
        return;
 }
 
@@ -1646,25 +1514,25 @@ void mpc_action_discontact(fsm_instance *fi, int event, void *arg)
 {
        struct mpcg_info   *mpcginfo   = arg;
        struct channel     *ch         = mpcginfo->ch;
-       struct net_device  *dev        = ch->netdev;
-       struct ctcm_priv   *priv    = dev->priv;
-       struct mpc_group   *grp     = priv->mpcg;
+       struct net_device  *dev;
+       struct ctcm_priv   *priv;
+       struct mpc_group   *grp;
 
-       if (ch == NULL) {
-               printk(KERN_INFO "%s() ch=NULL\n", __FUNCTION__);
-               return;
-       }
-       if (ch->netdev == NULL) {
-               printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
-               return;
+       if (ch) {
+               dev = ch->netdev;
+               if (dev) {
+                       priv = dev->priv;
+                       if (priv) {
+                               CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_NOTICE,
+                                       "%s: %s: %s\n",
+                                       CTCM_FUNTAIL, dev->name, ch->id);
+                               grp = priv->mpcg;
+                               grp->send_qllc_disc = 1;
+                               fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
+                       }
+               }
        }
 
-       ctcm_pr_debug("ctcmpc enter: %s  %s()\n", dev->name, __FUNCTION__);
-
-       grp->send_qllc_disc = 1;
-       fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
-
-       ctcm_pr_debug("ctcmpc exit: %s  %s()\n", dev->name, __FUNCTION__);
        return;
 }
 
@@ -1675,26 +1543,9 @@ void mpc_action_discontact(fsm_instance *fi, int event, void *arg)
  */
 void mpc_action_send_discontact(unsigned long thischan)
 {
-       struct channel     *ch;
-       struct net_device  *dev;
-       struct ctcm_priv    *priv;
-       struct mpc_group   *grp;
-       int rc = 0;
-       unsigned long     saveflags;
-
-       ch = (struct channel *)thischan;
-       dev = ch->netdev;
-       priv = dev->priv;
-       grp = priv->mpcg;
-
-       ctcm_pr_info("ctcmpc: %s cp:%i enter: %s() GrpState:%s ChState:%s\n",
-                      dev->name,
-                      smp_processor_id(),
-                      __FUNCTION__,
-                      fsm_getstate_str(grp->fsm),
-                      fsm_getstate_str(ch->fsm));
-       saveflags = 0;  /* avoids compiler warning with
-                          spin_unlock_irqrestore */
+       int rc;
+       struct channel  *ch = (struct channel *)thischan;
+       unsigned long   saveflags = 0;
 
        spin_lock_irqsave(get_ccwdev_lock(ch->cdev), saveflags);
        rc = ccw_device_start(ch->cdev, &ch->ccw[15],
@@ -1702,16 +1553,9 @@ void mpc_action_send_discontact(unsigned long thischan)
        spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
 
        if (rc != 0) {
-               ctcm_pr_info("ctcmpc: %s() ch:%s IO failed \n",
-                              __FUNCTION__,
-                              ch->id);
-               ctcm_ccw_check_rc(ch, rc, "send discontact");
-               /* Not checking return code value here */
-               /* Making best effort to notify partner*/
-               /* that MPC Group is going down        */
+               ctcm_ccw_check_rc(ch, rc, (char *)__func__);
        }
 
-       ctcm_pr_debug("ctcmpc exit: %s  %s()\n", dev->name, __FUNCTION__);
        return;
 }
 
@@ -1723,49 +1567,50 @@ void mpc_action_send_discontact(unsigned long thischan)
 */
 static int mpc_validate_xid(struct mpcg_info *mpcginfo)
 {
-       struct channel     *ch      = mpcginfo->ch;
-       struct net_device  *dev     = ch->netdev;
+       struct channel     *ch   = mpcginfo->ch;
+       struct net_device  *dev  = ch->netdev;
        struct ctcm_priv   *priv = dev->priv;
        struct mpc_group   *grp  = priv->mpcg;
-       struct xid2        *xid     = mpcginfo->xid;
-       int     failed  = 0;
-       int     rc      = 0;
-       __u64   our_id, their_id = 0;
-       int     len;
-
-       len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
+       struct xid2        *xid  = mpcginfo->xid;
+       int     rc       = 0;
+       __u64   our_id   = 0;
+       __u64   their_id = 0;
+       int     len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
 
-       ctcm_pr_debug("ctcmpc enter:    %s()\n", __FUNCTION__);
+       CTCM_PR_DEBUG("Enter %s: xid=%p\n", __func__, xid);
 
-       if (mpcginfo->xid == NULL) {
-               printk(KERN_INFO "%s() xid=NULL\n", __FUNCTION__);
+       if (xid == NULL) {
                rc = 1;
-                                       goto done;
+               /* XID REJECTED: xid == NULL */
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): xid = NULL",
+                               CTCM_FUNTAIL, ch->id);
+                       goto done;
        }
 
-       ctcm_pr_debug("ctcmpc :  %s  xid received()\n", __FUNCTION__);
-       ctcmpc_dumpit((char *)mpcginfo->xid, XID2_LENGTH);
+       CTCM_D3_DUMP((char *)xid, XID2_LENGTH);
 
        /*the received direction should be the opposite of ours  */
        if (((CHANNEL_DIRECTION(ch->flags) == READ) ? XID2_WRITE_SIDE :
                                XID2_READ_SIDE) != xid->xid2_dlc_type) {
-               failed = 1;
-               printk(KERN_INFO "ctcmpc:%s() XID REJECTED - READ-WRITE CH "
-                       "Pairing Invalid \n", __FUNCTION__);
+               rc = 2;
+               /* XID REJECTED: r/w channel pairing mismatch */
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): r/w channel pairing mismatch",
+                               CTCM_FUNTAIL, ch->id);
+                       goto done;
        }
 
        if (xid->xid2_dlc_type == XID2_READ_SIDE) {
-               ctcm_pr_debug("ctcmpc: %s(): grpmaxbuf:%d xid2buflen:%d\n",
-                               __FUNCTION__, grp->group_max_buflen,
-                               xid->xid2_buf_len);
+               CTCM_PR_DEBUG("%s: grpmaxbuf:%d xid2buflen:%d\n", __func__,
+                               grp->group_max_buflen, xid->xid2_buf_len);
 
-               if (grp->group_max_buflen == 0 ||
-                       grp->group_max_buflen > xid->xid2_buf_len - len)
+               if (grp->group_max_buflen == 0 || grp->group_max_buflen >
+                                               xid->xid2_buf_len - len)
                        grp->group_max_buflen = xid->xid2_buf_len - len;
        }
 
-
-       if (grp->saved_xid2 == NULL)    {
+       if (grp->saved_xid2 == NULL) {
                grp->saved_xid2 =
                        (struct xid2 *)skb_tail_pointer(grp->rcvd_xid_skb);
 
@@ -1786,49 +1631,54 @@ static int mpc_validate_xid(struct mpcg_info *mpcginfo)
                /* lower id assume the xside role */
                if (our_id < their_id) {
                        grp->roll = XSIDE;
-                       ctcm_pr_debug("ctcmpc :%s() WE HAVE LOW ID-"
-                                      "TAKE XSIDE\n", __FUNCTION__);
+                       CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_NOTICE,
+                               "%s(%s): WE HAVE LOW ID - TAKE XSIDE",
+                                       CTCM_FUNTAIL, ch->id);
                } else {
                        grp->roll = YSIDE;
-                       ctcm_pr_debug("ctcmpc :%s() WE HAVE HIGH ID-"
-                                      "TAKE YSIDE\n", __FUNCTION__);
+                       CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_NOTICE,
+                               "%s(%s): WE HAVE HIGH ID - TAKE YSIDE",
+                                       CTCM_FUNTAIL, ch->id);
                }
 
        } else {
                if (xid->xid2_flag4 != grp->saved_xid2->xid2_flag4) {
-                       failed = 1;
-                       printk(KERN_INFO "%s XID REJECTED - XID Flag Byte4\n",
-                              __FUNCTION__);
+                       rc = 3;
+                       /* XID REJECTED: xid flag byte4 mismatch */
+                       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): xid flag byte4 mismatch",
+                                       CTCM_FUNTAIL, ch->id);
                }
                if (xid->xid2_flag2 == 0x40) {
-                       failed = 1;
-                       printk(KERN_INFO "%s XID REJECTED - XID NOGOOD\n",
-                              __FUNCTION__);
+                       rc = 4;
+                       /* XID REJECTED - xid NOGOOD */
+                       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): xid NOGOOD",
+                                       CTCM_FUNTAIL, ch->id);
                }
                if (xid->xid2_adj_id != grp->saved_xid2->xid2_adj_id) {
-                       failed = 1;
-                       printk(KERN_INFO "%s XID REJECTED - "
-                               "Adjacent Station ID Mismatch\n",
-                               __FUNCTION__);
+                       rc = 5;
+                       /* XID REJECTED - Adjacent Station ID Mismatch */
+                       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): Adjacent Station ID Mismatch",
+                                       CTCM_FUNTAIL, ch->id);
                }
                if (xid->xid2_sender_id != grp->saved_xid2->xid2_sender_id) {
-                       failed = 1;
-                       printk(KERN_INFO "%s XID REJECTED - "
-                               "Sender Address Mismatch\n", __FUNCTION__);
-
+                       rc = 6;
+                       /* XID REJECTED - Sender Address Mismatch */
+                       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): Sender Address Mismatch",
+                                       CTCM_FUNTAIL, ch->id);
                }
        }
 
-       if (failed) {
+done:
+       if (rc) {
                ctcm_pr_info("ctcmpc       :  %s() failed\n", __FUNCTION__);
                priv->xid->xid2_flag2 = 0x40;
                grp->saved_xid2->xid2_flag2 = 0x40;
-               rc = 1;
        }
 
-done:
-
-       ctcm_pr_debug("ctcmpc exit:  %s()\n", __FUNCTION__);
        return rc;
 }
 
@@ -1839,46 +1689,20 @@ done:
 static void mpc_action_side_xid(fsm_instance *fsm, void *arg, int side)
 {
        struct channel *ch = arg;
-       struct ctcm_priv *priv;
-       struct mpc_group *grp = NULL;
-       struct net_device *dev = NULL;
        int rc = 0;
        int gotlock = 0;
        unsigned long saveflags = 0;    /* avoids compiler warning with
-                          spin_unlock_irqrestore */
-
-       if (ch == NULL) {
-               printk(KERN_INFO "%s ch=NULL\n", __FUNCTION__);
-                                       goto done;
-       }
-
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
-                       __FUNCTION__, smp_processor_id(), ch, ch->id);
-
-       dev = ch->netdev;
-       if (dev == NULL) {
-               printk(KERN_INFO "%s dev=NULL\n", __FUNCTION__);
-                                       goto done;
-       }
-
-       priv = dev->priv;
-       if (priv == NULL) {
-               printk(KERN_INFO "%s priv=NULL\n", __FUNCTION__);
-                                       goto done;
-       }
+                                          spin_unlock_irqrestore */
 
-       grp = priv->mpcg;
-       if (grp == NULL) {
-               printk(KERN_INFO "%s grp=NULL\n", __FUNCTION__);
-                                       goto done;
-       }
+       CTCM_PR_DEBUG("Enter %s: cp=%i ch=0x%p id=%s\n",
+                       __func__, smp_processor_id(), ch, ch->id);
 
        if (ctcm_checkalloc_buffer(ch))
                                        goto done;
 
-       /* skb data-buffer referencing: */
-
+       /*
+        * skb data-buffer referencing:
+        */
        ch->trans_skb->data = ch->trans_skb_data;
        skb_reset_tail_pointer(ch->trans_skb);
        ch->trans_skb->len = 0;
@@ -1911,22 +1735,22 @@ static void mpc_action_side_xid(fsm_instance *fsm, void *arg, int side)
        ch->ccw[8].count        = 0;
        ch->ccw[8].cda          = 0x00;
 
+       if (!(ch->xid_th && ch->xid && ch->xid_id))
+               CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_INFO,
+                       "%s(%s): xid_th=%p, xid=%p, xid_id=%p",
+                       CTCM_FUNTAIL, ch->id, ch->xid_th, ch->xid, ch->xid_id);
+
        if (side == XSIDE) {
                /* mpc_action_xside_xid */
-               if (ch->xid_th == NULL) {
-                       printk(KERN_INFO "%s ch->xid_th=NULL\n", __FUNCTION__);
-                                       goto done;
-               }
+               if (ch->xid_th == NULL)
+                               goto done;
                ch->ccw[9].cmd_code     = CCW_CMD_WRITE;
                ch->ccw[9].flags        = CCW_FLAG_SLI | CCW_FLAG_CC;
                ch->ccw[9].count        = TH_HEADER_LENGTH;
                ch->ccw[9].cda          = virt_to_phys(ch->xid_th);
 
-               if (ch->xid == NULL) {
-                       printk(KERN_INFO "%s ch->xid=NULL\n", __FUNCTION__);
-                                       goto done;
-               }
-
+               if (ch->xid == NULL)
+                               goto done;
                ch->ccw[10].cmd_code    = CCW_CMD_WRITE;
                ch->ccw[10].flags       = CCW_FLAG_SLI | CCW_FLAG_CC;
                ch->ccw[10].count       = XID2_LENGTH;
@@ -1956,28 +1780,22 @@ static void mpc_action_side_xid(fsm_instance *fsm, void *arg, int side)
                ch->ccw[10].count       = XID2_LENGTH;
                ch->ccw[10].cda         = virt_to_phys(ch->rcvd_xid);
 
-               if (ch->xid_th == NULL) {
-                       printk(KERN_INFO "%s ch->xid_th=NULL\n", __FUNCTION__);
-                                       goto done;
-               }
+               if (ch->xid_th == NULL)
+                               goto done;
                ch->ccw[11].cmd_code    = CCW_CMD_WRITE;
                ch->ccw[11].flags       = CCW_FLAG_SLI | CCW_FLAG_CC;
                ch->ccw[11].count       = TH_HEADER_LENGTH;
                ch->ccw[11].cda         = virt_to_phys(ch->xid_th);
 
-               if (ch->xid == NULL) {
-                       printk(KERN_INFO "%s ch->xid=NULL\n", __FUNCTION__);
-                                       goto done;
-               }
+               if (ch->xid == NULL)
+                               goto done;
                ch->ccw[12].cmd_code    = CCW_CMD_WRITE;
                ch->ccw[12].flags       = CCW_FLAG_SLI | CCW_FLAG_CC;
                ch->ccw[12].count       = XID2_LENGTH;
                ch->ccw[12].cda         = virt_to_phys(ch->xid);
 
-               if (ch->xid_id == NULL) {
-                       printk(KERN_INFO "%s ch->xid_id=NULL\n", __FUNCTION__);
-                                       goto done;
-               }
+               if (ch->xid_id == NULL)
+                               goto done;
                ch->ccw[13].cmd_code    = CCW_CMD_WRITE;
                ch->ccw[13].cda         = virt_to_phys(ch->xid_id);
 
@@ -1990,12 +1808,11 @@ static void mpc_action_side_xid(fsm_instance *fsm, void *arg, int side)
        ch->ccw[14].count       = 0;
        ch->ccw[14].cda         = 0;
 
-       if (do_debug_ccw)
-               ctcmpc_dumpit((char *)&ch->ccw[8], sizeof(struct ccw1) * 7);
+       CTCM_CCW_DUMP((char *)&ch->ccw[8], sizeof(struct ccw1) * 7);
+       CTCM_D3_DUMP((char *)ch->xid_th, TH_HEADER_LENGTH);
+       CTCM_D3_DUMP((char *)ch->xid, XID2_LENGTH);
+       CTCM_D3_DUMP((char *)ch->xid_id, 4);
 
-       ctcmpc_dumpit((char *)ch->xid_th, TH_HEADER_LENGTH);
-       ctcmpc_dumpit((char *)ch->xid, XID2_LENGTH);
-       ctcmpc_dumpit((char *)ch->xid_id, 4);
        if (!in_irq()) {
                         /* Such conditional locking is a known problem for
                          * sparse because its static undeterministic.
@@ -2012,16 +1829,13 @@ static void mpc_action_side_xid(fsm_instance *fsm, void *arg, int side)
                spin_unlock_irqrestore(get_ccwdev_lock(ch->cdev), saveflags);
 
        if (rc != 0) {
-               ctcm_pr_info("ctcmpc: %s() ch:%s IO failed \n",
-                               __FUNCTION__, ch->id);
                ctcm_ccw_check_rc(ch, rc,
                                (side == XSIDE) ? "x-side XID" : "y-side XID");
        }
 
 done:
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
-                               __FUNCTION__, ch, ch->id);
+       CTCM_PR_DEBUG("Exit %s: ch=0x%p id=%s\n",
+                               __func__, ch, ch->id);
        return;
 
 }
@@ -2050,41 +1864,19 @@ static void mpc_action_yside_xid(fsm_instance *fsm, int event, void *arg)
  */
 static void mpc_action_doxid0(fsm_instance *fsm, int event, void *arg)
 {
-       struct channel     *ch = arg;
-       struct ctcm_priv    *priv;
-       struct mpc_group   *grp     = NULL;
-       struct net_device *dev = NULL;
-
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
-                       __FUNCTION__, smp_processor_id(), ch, ch->id);
-
-       if (ch == NULL) {
-               printk(KERN_WARNING "%s ch=NULL\n", __FUNCTION__);
-                                       goto done;
-       }
-
-       dev = ch->netdev;
-       if (dev == NULL) {
-               printk(KERN_WARNING "%s dev=NULL\n", __FUNCTION__);
-                                       goto done;
-       }
-
-       priv = dev->priv;
-       if (priv == NULL) {
-               printk(KERN_WARNING "%s priv=NULL\n", __FUNCTION__);
-                                       goto done;
-       }
+       struct channel     *ch   = arg;
+       struct net_device  *dev  = ch->netdev;
+       struct ctcm_priv   *priv = dev->priv;
+       struct mpc_group   *grp  = priv->mpcg;
 
-       grp = priv->mpcg;
-       if (grp == NULL) {
-               printk(KERN_WARNING "%s grp=NULL\n", __FUNCTION__);
-                                       goto done;
-       }
+       CTCM_PR_DEBUG("Enter %s: cp=%i ch=0x%p id=%s\n",
+                       __func__, smp_processor_id(), ch, ch->id);
 
        if (ch->xid == NULL) {
-               printk(KERN_WARNING "%s ch-xid=NULL\n", __FUNCTION__);
-                                       goto done;
+               CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                       "%s(%s): ch->xid == NULL",
+                               CTCM_FUNTAIL, dev->name);
+               return;
        }
 
        fsm_newstate(ch->fsm, CH_XID0_INPROGRESS);
@@ -2104,12 +1896,7 @@ static void mpc_action_doxid0(fsm_instance *fsm, int event, void *arg)
 
        fsm_event(grp->fsm, MPCG_EVENT_DOIO, ch);
 
-done:
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc exit : %s(): ch=0x%p id=%s\n",
-                       __FUNCTION__, ch, ch->id);
        return;
-
 }
 
 /*
@@ -2119,32 +1906,16 @@ done:
 static void mpc_action_doxid7(fsm_instance *fsm, int event, void *arg)
 {
        struct net_device *dev = arg;
-       struct ctcm_priv   *priv = NULL;
-       struct mpc_group  *grp = NULL;
+       struct ctcm_priv  *priv = dev->priv;
+       struct mpc_group  *grp  = NULL;
        int direction;
-       int rc = 0;
        int send = 0;
 
-       ctcm_pr_debug("ctcmpc enter:    %s() \n", __FUNCTION__);
-
-       if (dev == NULL) {
-               printk(KERN_INFO "%s dev=NULL \n", __FUNCTION__);
-               rc = 1;
-                                       goto done;
-       }
-
-       priv = dev->priv;
-       if (priv == NULL) {
-               printk(KERN_INFO "%s priv=NULL \n", __FUNCTION__);
-               rc = 1;
-                                       goto done;
-       }
-
-       grp = priv->mpcg;
+       if (priv)
+               grp = priv->mpcg;
        if (grp == NULL) {
-               printk(KERN_INFO "%s grp=NULL \n", __FUNCTION__);
-               rc = 1;
-                                       goto done;
+               fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
+               return;
        }
 
        for (direction = READ; direction <= WRITE; direction++) {
@@ -2199,11 +1970,6 @@ static void mpc_action_doxid7(fsm_instance *fsm, int event, void *arg)
                        fsm_event(grp->fsm, MPCG_EVENT_DOIO, ch);
        }
 
-done:
-
-       if (rc != 0)
-               fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
-
        return;
 }
 
@@ -2214,24 +1980,15 @@ done:
 static void mpc_action_rcvd_xid0(fsm_instance *fsm, int event, void *arg)
 {
 
-       struct mpcg_info   *mpcginfo   = arg;
-       struct channel     *ch         = mpcginfo->ch;
-       struct net_device  *dev        = ch->netdev;
-       struct ctcm_priv   *priv;
-       struct mpc_group   *grp;
-
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
-                       __FUNCTION__, smp_processor_id(), ch, ch->id);
-
-       priv = dev->priv;
-       grp = priv->mpcg;
+       struct mpcg_info   *mpcginfo  = arg;
+       struct channel     *ch   = mpcginfo->ch;
+       struct net_device  *dev  = ch->netdev;
+       struct ctcm_priv   *priv = dev->priv;
+       struct mpc_group   *grp  = priv->mpcg;
 
-       ctcm_pr_debug("ctcmpc in:%s() %s xid2:%i xid7:%i xidt_p2:%i \n",
-                      __FUNCTION__, ch->id,
-                      grp->outstanding_xid2,
-                      grp->outstanding_xid7,
-                      grp->outstanding_xid7_p2);
+       CTCM_PR_DEBUG("%s: ch-id:%s xid2:%i xid7:%i xidt_p2:%i \n",
+                       __func__, ch->id, grp->outstanding_xid2,
+                       grp->outstanding_xid7, grp->outstanding_xid7_p2);
 
        if (fsm_getstate(ch->fsm) < CH_XID7_PENDING)
                fsm_newstate(ch->fsm, CH_XID7_PENDING);
@@ -2268,17 +2025,12 @@ static void mpc_action_rcvd_xid0(fsm_instance *fsm, int event, void *arg)
        }
        kfree(mpcginfo);
 
-       if (do_debug) {
-               ctcm_pr_debug("ctcmpc:%s() %s xid2:%i xid7:%i xidt_p2:%i \n",
-                               __FUNCTION__, ch->id,
-                               grp->outstanding_xid2,
-                               grp->outstanding_xid7,
-                               grp->outstanding_xid7_p2);
-               ctcm_pr_debug("ctcmpc:%s() %s grpstate: %s chanstate: %s \n",
-                               __FUNCTION__, ch->id,
-                               fsm_getstate_str(grp->fsm),
-                               fsm_getstate_str(ch->fsm));
-       }
+       CTCM_PR_DEBUG("ctcmpc:%s() %s xid2:%i xid7:%i xidt_p2:%i \n",
+               __func__, ch->id, grp->outstanding_xid2,
+               grp->outstanding_xid7, grp->outstanding_xid7_p2);
+       CTCM_PR_DEBUG("ctcmpc:%s() %s grpstate: %s chanstate: %s \n",
+               __func__, ch->id,
+               fsm_getstate_str(grp->fsm), fsm_getstate_str(ch->fsm));
        return;
 
 }
@@ -2296,15 +2048,10 @@ static void mpc_action_rcvd_xid7(fsm_instance *fsm, int event, void *arg)
        struct ctcm_priv   *priv    = dev->priv;
        struct mpc_group   *grp     = priv->mpcg;
 
-       if (do_debug) {
-               ctcm_pr_debug("ctcmpc enter: %s(): cp=%i ch=0x%p id=%s\n",
-                               __FUNCTION__, smp_processor_id(), ch, ch->id);
-
-               ctcm_pr_debug("ctcmpc:  outstanding_xid7: %i, "
-                               " outstanding_xid7_p2: %i\n",
-                               grp->outstanding_xid7,
-                               grp->outstanding_xid7_p2);
-       }
+       CTCM_PR_DEBUG("Enter %s: cp=%i ch=0x%p id=%s\n",
+               __func__, smp_processor_id(), ch, ch->id);
+       CTCM_PR_DEBUG("%s: outstanding_xid7: %i, outstanding_xid7_p2: %i\n",
+               __func__, grp->outstanding_xid7, grp->outstanding_xid7_p2);
 
        grp->outstanding_xid7--;
        ch->xid_skb->data = ch->xid_skb_data;
@@ -2337,14 +2084,8 @@ static void mpc_action_rcvd_xid7(fsm_instance *fsm, int event, void *arg)
                mpc_validate_xid(mpcginfo);
                break;
        }
-
        kfree(mpcginfo);
-
-       if (do_debug)
-               ctcm_pr_debug("ctcmpc exit: %s(): cp=%i ch=0x%p id=%s\n",
-                       __FUNCTION__, smp_processor_id(), ch, ch->id);
        return;
-
 }
 
 /*
@@ -2353,36 +2094,14 @@ static void mpc_action_rcvd_xid7(fsm_instance *fsm, int event, void *arg)
  */
 static int mpc_send_qllc_discontact(struct net_device *dev)
 {
-       int     rc      = 0;
        __u32   new_len = 0;
        struct sk_buff   *skb;
        struct qllc      *qllcptr;
-       struct ctcm_priv *priv;
-       struct mpc_group *grp;
-
-       ctcm_pr_debug("ctcmpc enter:    %s()\n", __FUNCTION__);
-
-       if (dev == NULL) {
-               printk(KERN_INFO "%s() dev=NULL\n", __FUNCTION__);
-               rc = 1;
-                                       goto done;
-       }
-
-       priv = dev->priv;
-       if (priv == NULL) {
-               printk(KERN_INFO "%s() priv=NULL\n", __FUNCTION__);
-               rc = 1;
-                                       goto done;
-       }
+       struct ctcm_priv *priv = dev->priv;
+       struct mpc_group *grp = priv->mpcg;
 
-       grp = priv->mpcg;
-       if (grp == NULL) {
-               printk(KERN_INFO "%s() grp=NULL\n", __FUNCTION__);
-               rc = 1;
-                                       goto done;
-       }
-       ctcm_pr_info("ctcmpc: %s() GROUP STATE: %s\n", __FUNCTION__,
-                       mpcg_state_names[grp->saved_state]);
+       CTCM_PR_DEBUG("%s: GROUP STATE: %s\n",
+               __func__, mpcg_state_names[grp->saved_state]);
 
        switch (grp->saved_state) {
        /*
@@ -2408,11 +2127,10 @@ static int mpc_send_qllc_discontact(struct net_device *dev)
                new_len = sizeof(struct qllc);
                qllcptr = kzalloc(new_len, gfp_type() | GFP_DMA);
                if (qllcptr == NULL) {
-                       printk(KERN_INFO
-                              "ctcmpc: Out of memory in %s()\n",
-                              dev->name);
-                       rc = 1;
-                               goto done;
+                       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): qllcptr allocation error",
+                                               CTCM_FUNTAIL, dev->name);
+                       return -ENOMEM;
                }
 
                qllcptr->qllc_address = 0xcc;
@@ -2421,31 +2139,29 @@ static int mpc_send_qllc_discontact(struct net_device *dev)
                skb = __dev_alloc_skb(new_len, GFP_ATOMIC);
 
                if (skb == NULL) {
-                       printk(KERN_INFO "%s Out of memory in mpc_send_qllc\n",
-                              dev->name);
+                       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): skb allocation error",
+                                               CTCM_FUNTAIL, dev->name);
                        priv->stats.rx_dropped++;
-                       rc = 1;
                        kfree(qllcptr);
-                               goto done;
+                       return -ENOMEM;
                }
 
                memcpy(skb_put(skb, new_len), qllcptr, new_len);
                kfree(qllcptr);
 
                if (skb_headroom(skb) < 4) {
-                       printk(KERN_INFO "ctcmpc: %s() Unable to"
-                              " build discontact for %s\n",
-                              __FUNCTION__, dev->name);
-                       rc = 1;
+                       CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
+                               "%s(%s): skb_headroom error",
+                                               CTCM_FUNTAIL, dev->name);
                        dev_kfree_skb_any(skb);
-                               goto done;
+                       return -ENOMEM;
                }
 
                *((__u32 *)skb_push(skb, 4)) = priv->channel[READ]->pdu_seq;
                priv->channel[READ]->pdu_seq++;
-               if (do_debug_data)
-                       ctcm_pr_debug("ctcmpc: %s ToDCM_pdu_seq= %08x\n",
-                               __FUNCTION__, priv->channel[READ]->pdu_seq);
+               CTCM_PR_DBGDATA("ctcmpc: %s ToDCM_pdu_seq= %08x\n",
+                               __func__, priv->channel[READ]->pdu_seq);
 
                /* receipt of CC03 resets anticipated sequence number on
                      receiving side */
@@ -2455,7 +2171,7 @@ static int mpc_send_qllc_discontact(struct net_device *dev)
                skb->protocol = htons(ETH_P_SNAP);
                skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-               ctcmpc_dumpit((char *)skb->data, (sizeof(struct qllc) + 4));
+               CTCM_D3_DUMP(skb->data, (sizeof(struct qllc) + 4));
 
                netif_rx(skb);
                break;
@@ -2464,9 +2180,7 @@ static int mpc_send_qllc_discontact(struct net_device *dev)
 
        }
 
-done:
-       ctcm_pr_debug("ctcmpc exit:  %s()\n", __FUNCTION__);
-       return rc;
+       return 0;
 }
 /* --- This is the END my friend --- */
 
index f99686069a9139ee2419eff24c6353bd049f1415..5336120cddf108ffcd562bb3787414f9f01c0210 100644 (file)
@@ -231,7 +231,7 @@ static inline void ctcmpc_dump32(char *buf, int len)
 int ctcmpc_open(struct net_device *);
 void ctcm_ccw_check_rc(struct channel *, int, char *);
 void mpc_group_ready(unsigned long adev);
-int mpc_channel_action(struct channel *ch, int direction, int action);
+void mpc_channel_action(struct channel *ch, int direction, int action);
 void mpc_action_send_discontact(unsigned long thischan);
 void mpc_action_discontact(fsm_instance *fi, int event, void *arg);
 void ctcmpc_bh(unsigned long thischan);
index b29afef5c7fb35afbc012d3ef9337130e5443543..38de31b557082cbe006f227bb3f6e88603ed3dc4 100644 (file)
@@ -2651,7 +2651,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        tag = (u16 *)(new_skb->data + 12);
                        *tag = __constant_htons(ETH_P_8021Q);
                        *(tag + 1) = htons(vlan_tx_tag_get(new_skb));
-                       VLAN_TX_SKB_CB(new_skb)->magic = 0;
+                       new_skb->vlan_tci = 0;
                }
        }
 
index 513ba61ae966b53e0edc20bf6501a018ac79be6e..777637594acd3c11eb4c376d2547dd11ff6d5234 100644 (file)
@@ -195,8 +195,8 @@ struct uctrl_driver {
 
 static struct uctrl_driver drv;
 
-void uctrl_get_event_status(void);
-void uctrl_get_external_status(void);
+static void uctrl_get_event_status(void);
+static void uctrl_get_external_status(void);
 
 static int
 uctrl_ioctl(struct inode *inode, struct file *file,
@@ -266,12 +266,6 @@ static struct miscdevice uctrl_dev = {
   driver->regs->uctrl_stat = UCTRL_STAT_RXNE_STA; \
 }
 
-void uctrl_set_video(int status)
-{
-       struct uctrl_driver *driver = &drv;
-       
-}
-
 static void uctrl_do_txn(struct uctrl_txn *txn)
 {
        struct uctrl_driver *driver = &drv;
@@ -311,7 +305,7 @@ static void uctrl_do_txn(struct uctrl_txn *txn)
        }
 }
 
-void uctrl_get_event_status(void)
+static void uctrl_get_event_status(void)
 {
        struct uctrl_driver *driver = &drv;
        struct uctrl_txn txn;
@@ -331,7 +325,7 @@ void uctrl_get_event_status(void)
        dprintk(("ev is %x\n", driver->status.event_status));
 }
 
-void uctrl_get_external_status(void)
+static void uctrl_get_external_status(void)
 {
        struct uctrl_driver *driver = &drv;
        struct uctrl_txn txn;
@@ -363,7 +357,7 @@ void uctrl_get_external_status(void)
 static int __init ts102_uctrl_init(void)
 {
        struct uctrl_driver *driver = &drv;
-       int len, i;
+       int len;
        struct linux_prom_irqs tmp_irq[2];
         unsigned int vaddr[2] = { 0, 0 };
        int tmpnode, uctrlnode = prom_getchild(prom_root_node);
index f1aa1389ea4ac231866310a92e2cbd625fef6a7c..a5240c52aa0b7b2bd7b4ff1fa792397e938b2615 100644 (file)
@@ -133,8 +133,6 @@ struct vfc_dev {
        unsigned char saa9051_state_array[VFC_SAA9051_NR];
 };
 
-extern struct vfc_dev **vfc_dev_lst;
-
 void captstat_reset(struct vfc_dev *);
 void memptr_reset(struct vfc_dev *);
 
@@ -145,8 +143,6 @@ int vfc_i2c_sendbuf(struct vfc_dev *, unsigned char, char *, int) ;
 int vfc_i2c_recvbuf(struct vfc_dev *, unsigned char, char *, int) ;
 int vfc_i2c_reset_bus(struct vfc_dev *);
 int vfc_init_i2c_bus(struct vfc_dev *);
-void vfc_lock_device(struct vfc_dev *);
-void vfc_unlock_device(struct vfc_dev *);
 
 #define VFC_CONTROL_DIAGMODE  0x10000000
 #define VFC_CONTROL_MEMPTR    0x20000000
index 1f6cb8ae2784cddaf76aa949033381b271126037..25181bb7d627752de1d4f6932f96d8d4ec2bbb8e 100644 (file)
@@ -45,7 +45,7 @@
 #include <asm/vfc_ioctls.h>
 
 static const struct file_operations vfc_fops;
-struct vfc_dev **vfc_dev_lst;
+static struct vfc_dev **vfc_dev_lst;
 static char vfcstr[]="vfc";
 static unsigned char saa9051_init_array[VFC_SAA9051_NR] = {
        0x00, 0x64, 0x72, 0x52,
@@ -54,18 +54,18 @@ static unsigned char saa9051_init_array[VFC_SAA9051_NR] = {
        0x3e
 };
 
-void vfc_lock_device(struct vfc_dev *dev)
+static void vfc_lock_device(struct vfc_dev *dev)
 {
        mutex_lock(&dev->device_lock_mtx);
 }
 
-void vfc_unlock_device(struct vfc_dev *dev)
+static void vfc_unlock_device(struct vfc_dev *dev)
 {
        mutex_unlock(&dev->device_lock_mtx);
 }
 
 
-void vfc_captstat_reset(struct vfc_dev *dev) 
+static void vfc_captstat_reset(struct vfc_dev *dev)
 {
        dev->control_reg |= VFC_CONTROL_CAPTRESET;
        sbus_writel(dev->control_reg, &dev->regs->control);
@@ -75,7 +75,7 @@ void vfc_captstat_reset(struct vfc_dev *dev)
        sbus_writel(dev->control_reg, &dev->regs->control);
 }
 
-void vfc_memptr_reset(struct vfc_dev *dev) 
+static void vfc_memptr_reset(struct vfc_dev *dev)
 {
        dev->control_reg |= VFC_CONTROL_MEMPTR;
        sbus_writel(dev->control_reg, &dev->regs->control);
@@ -85,7 +85,7 @@ void vfc_memptr_reset(struct vfc_dev *dev)
        sbus_writel(dev->control_reg, &dev->regs->control);
 }
 
-int vfc_csr_init(struct vfc_dev *dev)
+static int vfc_csr_init(struct vfc_dev *dev)
 {
        dev->control_reg = 0x80000000;
        sbus_writel(dev->control_reg, &dev->regs->control);
@@ -107,7 +107,7 @@ int vfc_csr_init(struct vfc_dev *dev)
        return 0;
 }
 
-int vfc_saa9051_init(struct vfc_dev *dev)
+static int vfc_saa9051_init(struct vfc_dev *dev)
 {
        int i;
 
@@ -119,7 +119,7 @@ int vfc_saa9051_init(struct vfc_dev *dev)
        return 0;
 }
 
-int init_vfc_hw(struct vfc_dev *dev) 
+static int init_vfc_hw(struct vfc_dev *dev)
 {
        vfc_lock_device(dev);
        vfc_csr_init(dev);
@@ -132,7 +132,7 @@ int init_vfc_hw(struct vfc_dev *dev)
        return 0; 
 }
 
-int init_vfc_devstruct(struct vfc_dev *dev, int instance) 
+static int init_vfc_devstruct(struct vfc_dev *dev, int instance)
 {
        dev->instance=instance;
        mutex_init(&dev->device_lock_mtx);
@@ -141,7 +141,8 @@ int init_vfc_devstruct(struct vfc_dev *dev, int instance)
        return 0;
 }
 
-int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev, int instance)
+static int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev,
+                          int instance)
 {
        if(dev == NULL) {
                printk(KERN_ERR "VFC: Bogus pointer passed\n");
@@ -168,7 +169,7 @@ int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev, int instance)
 }
 
 
-struct vfc_dev *vfc_get_dev_ptr(int instance) 
+static struct vfc_dev *vfc_get_dev_ptr(int instance)
 {
        return vfc_dev_lst[instance];
 }
@@ -292,7 +293,7 @@ static int vfc_debug(struct vfc_dev *dev, int cmd, void __user *argp)
        return 0;
 }
 
-int vfc_capture_start(struct vfc_dev *dev) 
+static int vfc_capture_start(struct vfc_dev *dev)
 {
        vfc_captstat_reset(dev);
        dev->control_reg = sbus_readl(&dev->regs->control);
@@ -314,7 +315,7 @@ int vfc_capture_start(struct vfc_dev *dev)
        return 0;
 }
 
-int vfc_capture_poll(struct vfc_dev *dev) 
+static int vfc_capture_poll(struct vfc_dev *dev)
 {
        int timeout = 1000;
 
@@ -390,8 +391,8 @@ static int vfc_set_control_ioctl(struct inode *inode, struct file *file,
 }
 
 
-int vfc_port_change_ioctl(struct inode *inode, struct file *file, 
-                         struct vfc_dev *dev, unsigned long arg) 
+static int vfc_port_change_ioctl(struct inode *inode, struct file *file,
+                                struct vfc_dev *dev, unsigned long arg)
 {
        int ret = 0;
        int cmd;
@@ -460,8 +461,8 @@ int vfc_port_change_ioctl(struct inode *inode, struct file *file,
        return ret;
 }
 
-int vfc_set_video_ioctl(struct inode *inode, struct file *file, 
-                       struct vfc_dev *dev, unsigned long arg) 
+static int vfc_set_video_ioctl(struct inode *inode, struct file *file,
+                              struct vfc_dev *dev, unsigned long arg)
 {
        int ret = 0;
        int cmd;
@@ -511,8 +512,8 @@ int vfc_set_video_ioctl(struct inode *inode, struct file *file,
        return ret;
 }
 
-int vfc_get_video_ioctl(struct inode *inode, struct file *file, 
-                       struct vfc_dev *dev, unsigned long arg) 
+static int vfc_get_video_ioctl(struct inode *inode, struct file *file,
+                              struct vfc_dev *dev, unsigned long arg)
 {
        int ret = 0;
        unsigned int status = NO_LOCK;
index 9efed771f6c03bab2e7187b01d3f772790fd177e..32b986e0ed786c1379d3a83dbefca980693f3f9f 100644 (file)
@@ -114,7 +114,7 @@ int vfc_i2c_reset_bus(struct vfc_dev *dev)
        return 0;
 }
 
-int vfc_i2c_wait_for_bus(struct vfc_dev *dev) 
+static int vfc_i2c_wait_for_bus(struct vfc_dev *dev)
 {
        int timeout = 1000; 
 
@@ -126,7 +126,7 @@ int vfc_i2c_wait_for_bus(struct vfc_dev *dev)
        return 0;
 }
 
-int vfc_i2c_wait_for_pin(struct vfc_dev *dev, int ack)
+static int vfc_i2c_wait_for_pin(struct vfc_dev *dev, int ack)
 {
        int timeout = 1000; 
        int s1;
@@ -144,7 +144,8 @@ int vfc_i2c_wait_for_pin(struct vfc_dev *dev, int ack)
 }
 
 #define SHIFT(a) ((a) << 24)
-int vfc_i2c_xmit_addr(struct vfc_dev *dev, unsigned char addr, char mode) 
+static int vfc_i2c_xmit_addr(struct vfc_dev *dev, unsigned char addr,
+                            char mode)
 { 
        int ret, raddr;
 #if 1
@@ -195,7 +196,7 @@ int vfc_i2c_xmit_addr(struct vfc_dev *dev, unsigned char addr, char mode)
        return 0;
 }
 
-int vfc_i2c_xmit_byte(struct vfc_dev *dev,unsigned char *byte) 
+static int vfc_i2c_xmit_byte(struct vfc_dev *dev,unsigned char *byte)
 {
        int ret;
        u32 val = SHIFT((unsigned int)*byte);
@@ -218,7 +219,8 @@ int vfc_i2c_xmit_byte(struct vfc_dev *dev,unsigned char *byte)
        return ret;
 }
 
-int vfc_i2c_recv_byte(struct vfc_dev *dev, unsigned char *byte, int last) 
+static int vfc_i2c_recv_byte(struct vfc_dev *dev, unsigned char *byte,
+                            int last)
 {
        int ret;
 
index 57e1526746a27e1ae8424d12c2cbd3f326ef9101..ab0d2de3324c16f73318d01603ee4381a9fb2d86 100644 (file)
@@ -16,7 +16,7 @@
 
 struct sbus_dma *dma_chain;
 
-void __init init_one_dvma(struct sbus_dma *dma, int num_dma)
+static void __init init_one_dvma(struct sbus_dma *dma, int num_dma)
 {
        printk("dma%d: ", num_dma);
        
index c37d7c2587ff923ad0129a3b145f1a542f150ddf..73a86d09bba8d71dd84641e58dbde5d1c1278d03 100644 (file)
@@ -78,7 +78,7 @@ static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sde
        else
                sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev;
        sdev->ofdev.dev.bus = &sbus_bus_type;
-       sprintf(sdev->ofdev.dev.bus_id, "sbus[%08x]", dp->node);
+       dev_set_name(&sdev->ofdev.dev, "sbus[%08x]", dp->node);
 
        if (of_device_register(&sdev->ofdev) != 0)
                printk(KERN_DEBUG "sbus: device registration error for %s!\n",
@@ -257,11 +257,11 @@ static void __init build_one_sbus(struct device_node *dp, int num_sbus)
        sbus->ofdev.node = dp;
        sbus->ofdev.dev.parent = NULL;
        sbus->ofdev.dev.bus = &sbus_bus_type;
-       sprintf(sbus->ofdev.dev.bus_id, "sbus%d", num_sbus);
+       dev_set_name(&sbus->ofdev.dev, "sbus%d", num_sbus);
 
        if (of_device_register(&sbus->ofdev) != 0)
                printk(KERN_DEBUG "sbus: device registration error for %s!\n",
-                      sbus->ofdev.dev.bus_id);
+                      dev_name(&sbus->ofdev.dev));
 
        dev_dp = dp->child;
        while (dev_dp) {
index 2bc30e32b67a691823568025e802c52cd3f27a7a..1fe0901e81192d91dad44c4773908c1f6492d39a 100644 (file)
@@ -271,8 +271,8 @@ rebuild_sys_tab:
                pHba->initialized = TRUE;
                pHba->state &= ~DPTI_STATE_RESET;
                if (adpt_sysfs_class) {
-                       struct device *dev = device_create(adpt_sysfs_class,
-                               NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit),
+                       struct device *dev = device_create_drvdata(adpt_sysfs_class,
+                               NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit), NULL,
                                "dpti%d", pHba->unit);
                        if (IS_ERR(dev)) {
                                printk(KERN_WARNING"dpti%d: unable to "
index 35cd892dce04f899336a49c21228fe36984b5155..fed0b02ebc1d35ecba7c19b534956edf939eb7a6 100644 (file)
@@ -232,8 +232,8 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
        }
 
        if (shost->transportt->create_work_queue) {
-               snprintf(shost->work_q_name, KOBJ_NAME_LEN, "scsi_wq_%d",
-                       shost->host_no);
+               snprintf(shost->work_q_name, sizeof(shost->work_q_name),
+                        "scsi_wq_%d", shost->host_no);
                shost->work_q = create_singlethread_workqueue(
                                        shost->work_q_name);
                if (!shost->work_q) {
@@ -466,7 +466,8 @@ struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
        struct device *cdev;
        struct Scsi_Host *shost = ERR_PTR(-ENXIO);
 
-       cdev = class_find_device(&shost_class, &hostnum, __scsi_host_match);
+       cdev = class_find_device(&shost_class, NULL, &hostnum,
+                                __scsi_host_match);
        if (cdev) {
                shost = scsi_host_get(class_to_shost(cdev));
                put_device(cdev);
index f843c1383a4b599480fdd53c9887a1263132e294..538552495d486da9f896e5cdc3067e360ea27109 100644 (file)
@@ -84,7 +84,6 @@ typedef struct ide_scsi_obj {
        struct Scsi_Host        *host;
 
        struct ide_atapi_pc *pc;                /* Current packet command */
-       unsigned long flags;                    /* Status/Action flags */
        unsigned long transform;                /* SCSI cmd translation layer */
        unsigned long log;                      /* log flags */
 } idescsi_scsi_t;
@@ -125,16 +124,6 @@ static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive)
        return scsihost_to_idescsi(ide_drive->driver_data);
 }
 
-/*
- *     Per ATAPI device status bits.
- */
-#define IDESCSI_DRQ_INTERRUPT          0       /* DRQ interrupt device */
-
-/*
- *     ide-scsi requests.
- */
-#define IDESCSI_PC_RQ                  90
-
 /*
  *     PIO data transfer routine using the scatter gather table.
  */
@@ -142,7 +131,8 @@ static void ide_scsi_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
                                unsigned int bcount, int write)
 {
        ide_hwif_t *hwif = drive->hwif;
-       xfer_func_t *xf = write ? hwif->output_data : hwif->input_data;
+       const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+       xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data;
        char *buf;
        int count;
 
@@ -228,7 +218,6 @@ static int idescsi_check_condition(ide_drive_t *drive,
        rq->cmd_type = REQ_TYPE_SENSE;
        rq->cmd_flags |= REQ_PREEMPT;
        pc->timeout = jiffies + WAIT_READY;
-       pc->callback = ide_scsi_callback;
        /* NOTE! Save the failed packet command in "rq->buffer" */
        rq->buffer = (void *) failed_cmd->special;
        pc->scsi_cmd = ((struct ide_atapi_pc *) failed_cmd->special)->scsi_cmd;
@@ -237,6 +226,7 @@ static int idescsi_check_condition(ide_drive_t *drive,
                ide_scsi_hex_dump(pc->c, 6);
        }
        rq->rq_disk = scsi->disk;
+       memcpy(rq->cmd, pc->c, 12);
        ide_do_drive_cmd(drive, rq);
        return 0;
 }
@@ -246,10 +236,9 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
 {
        ide_hwif_t *hwif = drive->hwif;
 
-       if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT))
+       if (hwif->tp_ops->read_status(hwif) & (BUSY_STAT | DRQ_STAT))
                /* force an abort */
-               hwif->OUTBSYNC(hwif, WIN_IDLEIMMEDIATE,
-                              hwif->io_ports.command_addr);
+               hwif->tp_ops->exec_command(hwif, WIN_IDLEIMMEDIATE);
 
        rq->errors++;
 
@@ -421,10 +410,6 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r
 
        if (blk_sense_request(rq) || blk_special_request(rq)) {
                struct ide_atapi_pc *pc = (struct ide_atapi_pc *)rq->special;
-               idescsi_scsi_t *scsi = drive_to_idescsi(drive);
-
-               if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags))
-                       pc->flags |= PC_FLAG_DRQ_INTERRUPT;
 
                if (drive->using_dma && !idescsi_map_sg(drive, pc))
                        pc->flags |= PC_FLAG_DMA_OK;
@@ -460,11 +445,14 @@ static inline void idescsi_add_settings(ide_drive_t *drive) { ; }
 static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
 {
        if (drive->id && (drive->id->config & 0x0060) == 0x20)
-               set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags);
+               set_bit(IDE_AFLAG_DRQ_INTERRUPT, &drive->atapi_flags);
        clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
 #if IDESCSI_DEBUG_LOG
        set_bit(IDESCSI_LOG_CMD, &scsi->log);
 #endif /* IDESCSI_DEBUG_LOG */
+
+       drive->pc_callback = ide_scsi_callback;
+
        idescsi_add_settings(drive);
 }
 
@@ -616,7 +604,6 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
        pc->scsi_cmd = cmd;
        pc->done = done;
        pc->timeout = jiffies + cmd->timeout_per_command;
-       pc->callback = ide_scsi_callback;
 
        if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {
                printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number);
@@ -631,6 +618,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
        rq->special = (char *) pc;
        rq->cmd_type = REQ_TYPE_SPECIAL;
        spin_unlock_irq(host->host_lock);
+       memcpy(rq->cmd, pc->c, 12);
        blk_execute_rq_nowait(drive->queue, scsi->disk, rq, 0, NULL);
        spin_lock_irq(host->host_lock);
        return 0;
index 5fd64e70029dcd30d4c30c8c9dffd5a0f77648a6..a272b9a2c86945314a8ae4693cc18b2a37dce2cb 100644 (file)
@@ -417,15 +417,16 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
        fc_host->next_vport_number = 0;
        fc_host->npiv_vports_inuse = 0;
 
-       snprintf(fc_host->work_q_name, KOBJ_NAME_LEN, "fc_wq_%d",
-               shost->host_no);
+       snprintf(fc_host->work_q_name, sizeof(fc_host->work_q_name),
+                "fc_wq_%d", shost->host_no);
        fc_host->work_q = create_singlethread_workqueue(
                                        fc_host->work_q_name);
        if (!fc_host->work_q)
                return -ENOMEM;
 
-       snprintf(fc_host->devloss_work_q_name, KOBJ_NAME_LEN, "fc_dl_%d",
-               shost->host_no);
+       snprintf(fc_host->devloss_work_q_name,
+                sizeof(fc_host->devloss_work_q_name),
+                "fc_dl_%d", shost->host_no);
        fc_host->devloss_work_q = create_singlethread_workqueue(
                                        fc_host->devloss_work_q_name);
        if (!fc_host->devloss_work_q) {
index 3af7cbcc5c5d7c6f93822a2e7e29f15f17a7df13..043c3921164ff781f3b20e51232ee091d2381622 100644 (file)
@@ -170,7 +170,7 @@ iscsi_create_endpoint(int dd_size)
        int err;
 
        for (id = 1; id < ISCSI_MAX_EPID; id++) {
-               dev = class_find_device(&iscsi_endpoint_class, &id,
+               dev = class_find_device(&iscsi_endpoint_class, NULL, &id,
                                        iscsi_match_epid);
                if (!dev)
                        break;
@@ -222,7 +222,7 @@ struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
        struct iscsi_endpoint *ep;
        struct device *dev;
 
-       dev = class_find_device(&iscsi_endpoint_class, &handle,
+       dev = class_find_device(&iscsi_endpoint_class, NULL, &handle,
                                iscsi_match_epid);
        if (!dev)
                return NULL;
@@ -247,8 +247,8 @@ static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
        atomic_set(&ihost->nr_scans, 0);
        mutex_init(&ihost->mutex);
 
-       snprintf(ihost->scan_workq_name, KOBJ_NAME_LEN, "iscsi_scan_%d",
-               shost->host_no);
+       snprintf(ihost->scan_workq_name, sizeof(ihost->scan_workq_name),
+                "iscsi_scan_%d", shost->host_no);
        ihost->scan_workq = create_singlethread_workqueue(
                                                ihost->scan_workq_name);
        if (!ihost->scan_workq)
index ce948b66bbd428147d6b4ae1b09c9819b7ae41dd..27f34a9f9cb750297ea6527ce5d181b47b0ca660 100644 (file)
@@ -1874,7 +1874,9 @@ static int serial8250_startup(struct uart_port *port)
                 * the interrupt is enabled.  Delays are necessary to
                 * allow register changes to become visible.
                 */
-               spin_lock_irqsave(&up->port.lock, flags);
+               spin_lock(&up->port.lock);
+               if (up->port.flags & UPF_SHARE_IRQ)
+                       disable_irq_nosync(up->port.irq);
 
                wait_for_xmitr(up, UART_LSR_THRE);
                serial_out_sync(up, UART_IER, UART_IER_THRI);
@@ -1886,7 +1888,9 @@ static int serial8250_startup(struct uart_port *port)
                iir = serial_in(up, UART_IIR);
                serial_out(up, UART_IER, 0);
 
-               spin_unlock_irqrestore(&up->port.lock, flags);
+               if (up->port.flags & UPF_SHARE_IRQ)
+                       enable_irq(up->port.irq);
+               spin_unlock(&up->port.lock);
 
                /*
                 * If the interrupt is not reasserted, setup a timer to
index abe129cc927ad857c70a4259934a8c734414bedc..1ff80de177db21be26be01ffa35831854821e97d 100644 (file)
@@ -201,6 +201,10 @@ static void cpm_uart_int_tx(struct uart_port *port)
        cpm_uart_tx_pump(port);
 }
 
+#ifdef CONFIG_CONSOLE_POLL
+static int serial_polled;
+#endif
+
 /*
  * Receive characters
  */
@@ -209,7 +213,7 @@ static void cpm_uart_int_rx(struct uart_port *port)
        int i;
        unsigned char ch;
        u8 *cp;
-       struct tty_struct *tty = port->info->tty;
+       struct tty_struct *tty = port->info->port.tty;
        struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
        cbd_t __iomem *bdp;
        u16 status;
@@ -222,6 +226,12 @@ static void cpm_uart_int_rx(struct uart_port *port)
         */
        bdp = pinfo->rx_cur;
        for (;;) {
+#ifdef CONFIG_CONSOLE_POLL
+               if (unlikely(serial_polled)) {
+                       serial_polled = 0;
+                       return;
+               }
+#endif
                /* get status */
                status = in_be16(&bdp->cbd_sc);
                /* If this one is empty, return happy */
@@ -253,7 +263,12 @@ static void cpm_uart_int_rx(struct uart_port *port)
                                goto handle_error;
                        if (uart_handle_sysrq_char(port, ch))
                                continue;
-
+#ifdef CONFIG_CONSOLE_POLL
+                       if (unlikely(serial_polled)) {
+                               serial_polled = 0;
+                               return;
+                       }
+#endif
                      error_return:
                        tty_insert_flip_char(tty, ch, flg);
 
@@ -865,6 +880,80 @@ static void cpm_uart_config_port(struct uart_port *port, int flags)
                cpm_uart_request_port(port);
        }
 }
+
+#ifdef CONFIG_CONSOLE_POLL
+/* Serial polling routines for writing and reading from the uart while
+ * in an interrupt or debug context.
+ */
+
+#define GDB_BUF_SIZE   512     /* power of 2, please */
+
+static char poll_buf[GDB_BUF_SIZE];
+static char *pollp;
+static int poll_chars;
+
+static int poll_wait_key(char *obuf, struct uart_cpm_port *pinfo)
+{
+       u_char          c, *cp;
+       volatile cbd_t  *bdp;
+       int             i;
+
+       /* Get the address of the host memory buffer.
+        */
+       bdp = pinfo->rx_cur;
+       while (bdp->cbd_sc & BD_SC_EMPTY)
+               ;
+
+       /* If the buffer address is in the CPM DPRAM, don't
+        * convert it.
+        */
+       cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
+
+       if (obuf) {
+               i = c = bdp->cbd_datlen;
+               while (i-- > 0)
+                       *obuf++ = *cp++;
+       } else
+               c = *cp;
+       bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID);
+       bdp->cbd_sc |= BD_SC_EMPTY;
+
+       if (bdp->cbd_sc & BD_SC_WRAP)
+               bdp = pinfo->rx_bd_base;
+       else
+               bdp++;
+       pinfo->rx_cur = (cbd_t *)bdp;
+
+       return (int)c;
+}
+
+static int cpm_get_poll_char(struct uart_port *port)
+{
+       struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
+
+       if (!serial_polled) {
+               serial_polled = 1;
+               poll_chars = 0;
+       }
+       if (poll_chars <= 0) {
+               poll_chars = poll_wait_key(poll_buf, pinfo);
+               pollp = poll_buf;
+       }
+       poll_chars--;
+       return *pollp++;
+}
+
+static void cpm_put_poll_char(struct uart_port *port,
+                        unsigned char c)
+{
+       struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
+       static char ch[2];
+
+       ch[0] = (char)c;
+       cpm_uart_early_write(pinfo->port.line, ch, 1);
+}
+#endif /* CONFIG_CONSOLE_POLL */
+
 static struct uart_ops cpm_uart_pops = {
        .tx_empty       = cpm_uart_tx_empty,
        .set_mctrl      = cpm_uart_set_mctrl,
@@ -882,6 +971,10 @@ static struct uart_ops cpm_uart_pops = {
        .request_port   = cpm_uart_request_port,
        .config_port    = cpm_uart_config_port,
        .verify_port    = cpm_uart_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+       .poll_get_char = cpm_get_poll_char,
+       .poll_put_char = cpm_put_poll_char,
+#endif
 };
 
 struct uart_cpm_port cpm_uart_ports[UART_NR];
index 9c2df5c857cfc85ff46e8378b786a4dd32602bba..2b7531d9f6abcfa72c9872bcea48ef9a5cf593c6 100644 (file)
@@ -730,7 +730,7 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
 static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
 {
        short int count, rcv_buff;
-       struct tty_struct *tty = icom_port->uart_port.info->tty;
+       struct tty_struct *tty = icom_port->uart_port.info->port.tty;
        unsigned short int status;
        struct uart_icount *icount;
        unsigned long offset;
index c9f53e71f252eb2833db26f645a9621f0f68f7ba..61d3ade5286c6a50a55d7735b03f93284a631de4 100644 (file)
@@ -921,6 +921,10 @@ static int mpsc_make_ready(struct mpsc_port_info *pi)
        return 0;
 }
 
+#ifdef CONFIG_CONSOLE_POLL
+static int serial_polled;
+#endif
+
 /*
  ******************************************************************************
  *
@@ -956,7 +960,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi)
        while (!((cmdstat = be32_to_cpu(rxre->cmdstat))
                                & SDMA_DESC_CMDSTAT_O)) {
                bytes_in = be16_to_cpu(rxre->bytecnt);
-
+#ifdef CONFIG_CONSOLE_POLL
+               if (unlikely(serial_polled)) {
+                       serial_polled = 0;
+                       return 0;
+               }
+#endif
                /* Following use of tty struct directly is deprecated */
                if (unlikely(tty_buffer_request_room(tty, bytes_in)
                                        < bytes_in)) {
@@ -1017,6 +1026,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi)
                if (uart_handle_sysrq_char(&pi->port, *bp)) {
                        bp++;
                        bytes_in--;
+#ifdef CONFIG_CONSOLE_POLL
+                       if (unlikely(serial_polled)) {
+                               serial_polled = 0;
+                               return 0;
+                       }
+#endif
                        goto next_frame;
                }
 
@@ -1519,6 +1534,133 @@ static int mpsc_verify_port(struct uart_port *port, struct serial_struct *ser)
 
        return rc;
 }
+#ifdef CONFIG_CONSOLE_POLL
+/* Serial polling routines for writing and reading from the uart while
+ * in an interrupt or debug context.
+ */
+
+static char poll_buf[2048];
+static int poll_ptr;
+static int poll_cnt;
+static void mpsc_put_poll_char(struct uart_port *port,
+                                                          unsigned char c);
+
+static int mpsc_get_poll_char(struct uart_port *port)
+{
+       struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+       struct mpsc_rx_desc *rxre;
+       u32     cmdstat, bytes_in, i;
+       u8      *bp;
+
+       if (!serial_polled)
+               serial_polled = 1;
+
+       pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line);
+
+       if (poll_cnt) {
+               poll_cnt--;
+               return poll_buf[poll_ptr++];
+       }
+       poll_ptr = 0;
+       poll_cnt = 0;
+
+       while (poll_cnt == 0) {
+               rxre = (struct mpsc_rx_desc *)(pi->rxr +
+                      (pi->rxr_posn*MPSC_RXRE_SIZE));
+               dma_cache_sync(pi->port.dev, (void *)rxre,
+                              MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+               if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+                       invalidate_dcache_range((ulong)rxre,
+                       (ulong)rxre + MPSC_RXRE_SIZE);
+#endif
+               /*
+                * Loop through Rx descriptors handling ones that have
+                * been completed.
+                */
+               while (poll_cnt == 0 &&
+                      !((cmdstat = be32_to_cpu(rxre->cmdstat)) &
+                        SDMA_DESC_CMDSTAT_O)){
+                       bytes_in = be16_to_cpu(rxre->bytecnt);
+                       bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE);
+                       dma_cache_sync(pi->port.dev, (void *) bp,
+                                      MPSC_RXBE_SIZE, DMA_FROM_DEVICE);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+                       if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+                               invalidate_dcache_range((ulong)bp,
+                                       (ulong)bp + MPSC_RXBE_SIZE);
+#endif
+                       if ((unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR |
+                        SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) &&
+                               !(cmdstat & pi->port.ignore_status_mask)) {
+                               poll_buf[poll_cnt] = *bp;
+                               poll_cnt++;
+                       } else {
+                               for (i = 0; i < bytes_in; i++) {
+                                       poll_buf[poll_cnt] = *bp++;
+                                       poll_cnt++;
+                               }
+                               pi->port.icount.rx += bytes_in;
+                       }
+                       rxre->bytecnt = cpu_to_be16(0);
+                       wmb();
+                       rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O |
+                                                   SDMA_DESC_CMDSTAT_EI |
+                                                   SDMA_DESC_CMDSTAT_F |
+                                                   SDMA_DESC_CMDSTAT_L);
+                       wmb();
+                       dma_cache_sync(pi->port.dev, (void *)rxre,
+                                      MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+                       if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+                               flush_dcache_range((ulong)rxre,
+                                          (ulong)rxre + MPSC_RXRE_SIZE);
+#endif
+
+                       /* Advance to next descriptor */
+                       pi->rxr_posn = (pi->rxr_posn + 1) &
+                               (MPSC_RXR_ENTRIES - 1);
+                       rxre = (struct mpsc_rx_desc *)(pi->rxr +
+                                      (pi->rxr_posn * MPSC_RXRE_SIZE));
+                       dma_cache_sync(pi->port.dev, (void *)rxre,
+                                      MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+                       if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
+                               invalidate_dcache_range((ulong)rxre,
+                                               (ulong)rxre + MPSC_RXRE_SIZE);
+#endif
+               }
+
+               /* Restart rx engine, if its stopped */
+               if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0)
+                       mpsc_start_rx(pi);
+       }
+       if (poll_cnt) {
+               poll_cnt--;
+               return poll_buf[poll_ptr++];
+       }
+
+       return 0;
+}
+
+
+static void mpsc_put_poll_char(struct uart_port *port,
+                        unsigned char c)
+{
+       struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+       u32 data;
+
+       data = readl(pi->mpsc_base + MPSC_MPCR);
+       writeb(c, pi->mpsc_base + MPSC_CHR_1);
+       mb();
+       data = readl(pi->mpsc_base + MPSC_CHR_2);
+       data |= MPSC_CHR_2_TTCS;
+       writel(data, pi->mpsc_base + MPSC_CHR_2);
+       mb();
+
+       while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_TTCS);
+}
+#endif
 
 static struct uart_ops mpsc_pops = {
        .tx_empty       = mpsc_tx_empty,
@@ -1537,6 +1679,10 @@ static struct uart_ops mpsc_pops = {
        .request_port   = mpsc_request_port,
        .config_port    = mpsc_config_port,
        .verify_port    = mpsc_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+       .poll_get_char = mpsc_get_poll_char,
+       .poll_put_char = mpsc_put_poll_char,
+#endif
 };
 
 /*
index 4a3ecaa629e6c90773c420a3a3a7d599fe10978d..d852f83f890046b2cdc07b856c05173615873934 100644 (file)
@@ -202,7 +202,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id)
 {
        struct s3c24xx_uart_port *ourport = dev_id;
        struct uart_port *port = &ourport->port;
-       struct tty_struct *tty = port->info->tty;
+       struct tty_struct *tty = port->info->port.tty;
        unsigned int ufcon, ch, flag, ufstat, uerstat;
        int max_count = 64;
 
index 0bce1fe2c62a3bbb7073647bb040da61a2f697a5..f977c98cfa956749cb3bd37211d30bb6115d2190 100644 (file)
@@ -934,7 +934,7 @@ uart_tiocmset(struct tty_struct *tty, struct file *file,
        return ret;
 }
 
-static void uart_break_ctl(struct tty_struct *tty, int break_state)
+static int uart_break_ctl(struct tty_struct *tty, int break_state)
 {
        struct uart_state *state = tty->driver_data;
        struct uart_port *port = state->port;
@@ -945,6 +945,7 @@ static void uart_break_ctl(struct tty_struct *tty, int break_state)
                port->ops->break_ctl(port, break_state);
 
        mutex_unlock(&state->mutex);
+       return 0;
 }
 
 static int uart_do_autoconfig(struct uart_state *state)
index 7ad21925869a0550465b56bac0e5a7c771f2fb31..8fcb4c5b9a263b2db8897fe9360dec3943552569 100644 (file)
@@ -272,7 +272,7 @@ static void serial_txx9_initialize(struct uart_port *port)
 static inline void
 receive_chars(struct uart_txx9_port *up, unsigned int *status)
 {
-       struct tty_struct *tty = up->port.info->tty;
+       struct tty_struct *tty = up->port.info->port.tty;
        unsigned char ch;
        unsigned int disr = *status;
        int max_count = 256;
index 1ad12afc6ba0ace916c817c571b265dc49cc1398..1771b2456bfaf8f60ab3d0fdfafdd443813b3138 100644 (file)
@@ -502,7 +502,7 @@ struct spi_master *spi_busnum_to_master(u16 bus_num)
        struct device           *dev;
        struct spi_master       *master = NULL;
 
-       dev = class_find_device(&spi_master_class, &bus_num,
+       dev = class_find_device(&spi_master_class, NULL, &bus_num,
                                __spi_master_match);
        if (dev)
                master = container_of(dev, struct spi_master, dev);
index ddbe1a5e970e1b017b46e629100af8848c292427..2833fd772a24feb160f33a07e4bbbcc23a5cbb21 100644 (file)
@@ -576,7 +576,8 @@ static int spidev_probe(struct spi_device *spi)
                struct device *dev;
 
                spidev->devt = MKDEV(SPIDEV_MAJOR, minor);
-               dev = device_create(spidev_class, &spi->dev, spidev->devt,
+               dev = device_create_drvdata(spidev_class, &spi->dev,
+                               spidev->devt, spidev,
                                "spidev%d.%d",
                                spi->master->bus_num, spi->chip_select);
                status = IS_ERR(dev) ? PTR_ERR(dev) : 0;
@@ -586,7 +587,6 @@ static int spidev_probe(struct spi_device *spi)
        }
        if (status == 0) {
                set_bit(minor, minors);
-               spi_set_drvdata(spi, spidev);
                list_add(&spidev->device_entry, &device_list);
        }
        mutex_unlock(&device_list_lock);
index a4aaab9c7ddcd3f1a5546175a262ad0b84310a73..2e9079df26b3a2ebd67e633295167389d380ae81 100644 (file)
@@ -15,7 +15,7 @@ if UIO
 
 config UIO_CIF
        tristate "generic Hilscher CIF Card driver"
-       depends on UIO && PCI
+       depends on PCI
        default n
        help
          Driver for Hilscher CIF DeviceNet and Profibus cards.  This
@@ -26,9 +26,15 @@ config UIO_CIF
          To compile this driver as a module, choose M here: the module
          will be called uio_cif.
 
+config UIO_PDRV
+       tristate "Userspace I/O platform driver"
+       help
+         Generic platform driver for Userspace I/O devices.
+
+         If you don't know what to do here, say N.
+
 config UIO_SMX
        tristate "SMX cryptengine UIO interface"
-       depends on UIO
        default n
        help
          Userspace IO interface to the Cryptography engine found on the
index 18c45662431e302fe1b5014b3b9ca8968643f3ba..e00ce0def1a02898d0b197c2c593f8344bb989b7 100644 (file)
@@ -1,3 +1,4 @@
 obj-$(CONFIG_UIO)      += uio.o
 obj-$(CONFIG_UIO_CIF)  += uio_cif.o
+obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o
 obj-$(CONFIG_UIO_SMX)  += uio_smx.o
index 5a7ca2e6094dc4d2ea0f6fb95f2315b11373be13..3a6934bf713134edc3f53b68e25bf913ec3215e4 100644 (file)
@@ -427,6 +427,31 @@ static ssize_t uio_read(struct file *filep, char __user *buf,
        return retval;
 }
 
+static ssize_t uio_write(struct file *filep, const char __user *buf,
+                       size_t count, loff_t *ppos)
+{
+       struct uio_listener *listener = filep->private_data;
+       struct uio_device *idev = listener->dev;
+       ssize_t retval;
+       s32 irq_on;
+
+       if (idev->info->irq == UIO_IRQ_NONE)
+               return -EIO;
+
+       if (count != sizeof(s32))
+               return -EINVAL;
+
+       if (!idev->info->irqcontrol)
+               return -ENOSYS;
+
+       if (copy_from_user(&irq_on, buf, count))
+               return -EFAULT;
+
+       retval = idev->info->irqcontrol(idev->info, irq_on);
+
+       return retval ? retval : sizeof(s32);
+}
+
 static int uio_find_mem_index(struct vm_area_struct *vma)
 {
        int mi;
@@ -546,6 +571,7 @@ static const struct file_operations uio_fops = {
        .open           = uio_open,
        .release        = uio_release,
        .read           = uio_read,
+       .write          = uio_write,
        .mmap           = uio_mmap,
        .poll           = uio_poll,
        .fasync         = uio_fasync,
diff --git a/drivers/uio/uio_pdrv.c b/drivers/uio/uio_pdrv.c
new file mode 100644 (file)
index 0000000..5d0d2e8
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * drivers/uio/uio_pdrv.c
+ *
+ * Copyright (C) 2008 by Digi International 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 version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/platform_device.h>
+#include <linux/uio_driver.h>
+#include <linux/stringify.h>
+
+#define DRIVER_NAME "uio"
+
+struct uio_platdata {
+       struct uio_info *uioinfo;
+};
+
+static int uio_pdrv_probe(struct platform_device *pdev)
+{
+       struct uio_info *uioinfo = pdev->dev.platform_data;
+       struct uio_platdata *pdata;
+       struct uio_mem *uiomem;
+       int ret = -ENODEV;
+       int i;
+
+       if (!uioinfo || !uioinfo->name || !uioinfo->version) {
+               dev_dbg(&pdev->dev, "%s: err_uioinfo\n", __func__);
+               goto err_uioinfo;
+       }
+
+       pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+       if (!pdata) {
+               ret = -ENOMEM;
+               dev_dbg(&pdev->dev, "%s: err_alloc_pdata\n", __func__);
+               goto err_alloc_pdata;
+       }
+
+       pdata->uioinfo = uioinfo;
+
+       uiomem = &uioinfo->mem[0];
+
+       for (i = 0; i < pdev->num_resources; ++i) {
+               struct resource *r = &pdev->resource[i];
+
+               if (r->flags != IORESOURCE_MEM)
+                       continue;
+
+               if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
+                       dev_warn(&pdev->dev, "device has more than "
+                                       __stringify(MAX_UIO_MAPS)
+                                       " I/O memory resources.\n");
+                       break;
+               }
+
+               uiomem->memtype = UIO_MEM_PHYS;
+               uiomem->addr = r->start;
+               uiomem->size = r->end - r->start + 1;
+               ++uiomem;
+       }
+
+       while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
+               uiomem->size = 0;
+               ++uiomem;
+       }
+
+       pdata->uioinfo->priv = pdata;
+
+       ret = uio_register_device(&pdev->dev, pdata->uioinfo);
+
+       if (ret) {
+               kfree(pdata);
+err_alloc_pdata:
+err_uioinfo:
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, pdata);
+
+       return 0;
+}
+
+static int uio_pdrv_remove(struct platform_device *pdev)
+{
+       struct uio_platdata *pdata = platform_get_drvdata(pdev);
+
+       uio_unregister_device(pdata->uioinfo);
+
+       return 0;
+}
+
+static struct platform_driver uio_pdrv = {
+       .probe = uio_pdrv_probe,
+       .remove = uio_pdrv_remove,
+       .driver = {
+               .name = DRIVER_NAME,
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init uio_pdrv_init(void)
+{
+       return platform_driver_register(&uio_pdrv);
+}
+
+static void __exit uio_pdrv_exit(void)
+{
+       platform_driver_unregister(&uio_pdrv);
+}
+module_init(uio_pdrv_init);
+module_exit(uio_pdrv_exit);
+
+MODULE_AUTHOR("Uwe Kleine-Koenig");
+MODULE_DESCRIPTION("Userspace I/O platform driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
index 90583d6a59492b1922c4688d6379afaadea608f9..507a9bd0d77caa6267caa7c52f4c108a5082c959 100644 (file)
@@ -1052,7 +1052,6 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
 
        instance->usbatm = usbatm_instance;
        instance->modem_type = (struct cxacru_modem_type *) id->driver_info;
-       memset(instance->card_info, 0, sizeof(instance->card_info));
 
        mutex_init(&instance->poll_state_serialize);
        instance->poll_state = CXPOLL_STOPPED;
index 7d27c9cf3c43fee169f2c0deedb5eec1742687f1..76fce44c2f9ace8a573da9fae2e289cc904c8dc9 100644 (file)
@@ -829,7 +829,6 @@ static int speedtch_bind(struct usbatm_data *usbatm,
        if (use_isoc) {
                const struct usb_host_interface *desc = data_intf->cur_altsetting;
                const __u8 target_address = USB_DIR_IN | usbatm->driver->isoc_in;
-               int i;
 
                use_isoc = 0; /* fall back to bulk if endpoint not found */
 
index c3201affa0b6f99c17ff6d28c71e3cd08adb58c6..0725b1871f23f757b8012dde88cb08ee90e9b3b7 100644 (file)
@@ -159,12 +159,34 @@ static void acm_write_done(struct acm *acm, struct acm_wb *wb)
        spin_lock_irqsave(&acm->write_lock, flags);
        acm->write_ready = 1;
        wb->use = 0;
+       acm->transmitting--;
        spin_unlock_irqrestore(&acm->write_lock, flags);
 }
 
 /*
  * Poke write.
+ *
+ * the caller is responsible for locking
  */
+
+static int acm_start_wb(struct acm *acm, struct acm_wb *wb)
+{
+       int rc;
+
+       acm->transmitting++;
+
+       wb->urb->transfer_buffer = wb->buf;
+       wb->urb->transfer_dma = wb->dmah;
+       wb->urb->transfer_buffer_length = wb->len;
+       wb->urb->dev = acm->dev;
+
+       if ((rc = usb_submit_urb(wb->urb, GFP_ATOMIC)) < 0) {
+               dbg("usb_submit_urb(write bulk) failed: %d", rc);
+               acm_write_done(acm, wb);
+       }
+       return rc;
+}
+
 static int acm_write_start(struct acm *acm, int wbn)
 {
        unsigned long flags;
@@ -182,26 +204,31 @@ static int acm_write_start(struct acm *acm, int wbn)
                return 0;       /* A white lie */
        }
 
+       wb = &acm->wb[wbn];
+       if(acm_wb_is_avail(acm) <= 1)
+               acm->write_ready = 0;
+
+       dbg("%s susp_count: %d", __func__, acm->susp_count);
+       if (acm->susp_count) {
+               acm->old_ready = acm->write_ready;
+               acm->delayed_wb = wb;
+               acm->write_ready = 0;
+               schedule_work(&acm->waker);
+               spin_unlock_irqrestore(&acm->write_lock, flags);
+               return 0;       /* A white lie */
+       }
+       usb_mark_last_busy(acm->dev);
+
        if (!acm_wb_is_used(acm, wbn)) {
                spin_unlock_irqrestore(&acm->write_lock, flags);
                return 0;
        }
-       wb = &acm->wb[wbn];
 
-       if(acm_wb_is_avail(acm) <= 1)
-               acm->write_ready = 0;
+       rc = acm_start_wb(acm, wb);
        spin_unlock_irqrestore(&acm->write_lock, flags);
 
-       wb->urb->transfer_buffer = wb->buf;
-       wb->urb->transfer_dma = wb->dmah;
-       wb->urb->transfer_buffer_length = wb->len;
-       wb->urb->dev = acm->dev;
-
-       if ((rc = usb_submit_urb(wb->urb, GFP_ATOMIC)) < 0) {
-               dbg("usb_submit_urb(write bulk) failed: %d", rc);
-               acm_write_done(acm, wb);
-       }
        return rc;
+
 }
 /*
  * attributes exported through sysfs
@@ -304,6 +331,7 @@ static void acm_ctrl_irq(struct urb *urb)
                        break;
        }
 exit:
+       usb_mark_last_busy(acm->dev);
        retval = usb_submit_urb (urb, GFP_ATOMIC);
        if (retval)
                err ("%s - usb_submit_urb failed with result %d",
@@ -320,8 +348,11 @@ static void acm_read_bulk(struct urb *urb)
 
        dbg("Entering acm_read_bulk with status %d", status);
 
-       if (!ACM_READY(acm))
+       if (!ACM_READY(acm)) {
+               dev_dbg(&acm->data->dev, "Aborting, acm not ready");
                return;
+       }
+       usb_mark_last_busy(acm->dev);
 
        if (status)
                dev_dbg(&acm->data->dev, "bulk rx status %d\n", status);
@@ -331,6 +362,7 @@ static void acm_read_bulk(struct urb *urb)
 
        if (likely(status == 0)) {
                spin_lock(&acm->read_lock);
+               acm->processing++;
                list_add_tail(&rcv->list, &acm->spare_read_urbs);
                list_add_tail(&buf->list, &acm->filled_read_bufs);
                spin_unlock(&acm->read_lock);
@@ -343,7 +375,8 @@ static void acm_read_bulk(struct urb *urb)
                /* nevertheless the tasklet must be kicked unconditionally
                so the queue cannot dry up */
        }
-       tasklet_schedule(&acm->urb_task);
+       if (likely(!acm->susp_count))
+               tasklet_schedule(&acm->urb_task);
 }
 
 static void acm_rx_tasklet(unsigned long _acm)
@@ -354,16 +387,23 @@ static void acm_rx_tasklet(unsigned long _acm)
        struct acm_ru *rcv;
        unsigned long flags;
        unsigned char throttled;
+
        dbg("Entering acm_rx_tasklet");
 
        if (!ACM_READY(acm))
+       {
+               dbg("acm_rx_tasklet: ACM not ready");
                return;
+       }
 
        spin_lock_irqsave(&acm->throttle_lock, flags);
        throttled = acm->throttle;
        spin_unlock_irqrestore(&acm->throttle_lock, flags);
        if (throttled)
+       {
+               dbg("acm_rx_tasklet: throttled");
                return;
+       }
 
 next_buffer:
        spin_lock_irqsave(&acm->read_lock, flags);
@@ -403,6 +443,7 @@ urbs:
        while (!list_empty(&acm->spare_read_bufs)) {
                spin_lock_irqsave(&acm->read_lock, flags);
                if (list_empty(&acm->spare_read_urbs)) {
+                       acm->processing = 0;
                        spin_unlock_irqrestore(&acm->read_lock, flags);
                        return;
                }
@@ -425,18 +466,23 @@ urbs:
                rcv->urb->transfer_dma = buf->dma;
                rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-               dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p", rcv->urb, rcv, buf);
-
                /* This shouldn't kill the driver as unsuccessful URBs are returned to the
                   free-urbs-pool and resubmited ASAP */
-               if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) {
+               spin_lock_irqsave(&acm->read_lock, flags);
+               if (acm->susp_count || usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) {
                        list_add(&buf->list, &acm->spare_read_bufs);
-                       spin_lock_irqsave(&acm->read_lock, flags);
                        list_add(&rcv->list, &acm->spare_read_urbs);
+                       acm->processing = 0;
                        spin_unlock_irqrestore(&acm->read_lock, flags);
                        return;
+               } else {
+                       spin_unlock_irqrestore(&acm->read_lock, flags);
+                       dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p", rcv->urb, rcv, buf);
                }
        }
+       spin_lock_irqsave(&acm->read_lock, flags);
+       acm->processing = 0;
+       spin_unlock_irqrestore(&acm->read_lock, flags);
 }
 
 /* data interface wrote those outgoing bytes */
@@ -463,6 +509,27 @@ static void acm_softint(struct work_struct *work)
        tty_wakeup(acm->tty);
 }
 
+static void acm_waker(struct work_struct *waker)
+{
+       struct acm *acm = container_of(waker, struct acm, waker);
+       long flags;
+       int rv;
+
+       rv = usb_autopm_get_interface(acm->control);
+       if (rv < 0) {
+               err("Autopm failure in %s", __func__);
+               return;
+       }
+       if (acm->delayed_wb) {
+               acm_start_wb(acm, acm->delayed_wb);
+               acm->delayed_wb = NULL;
+       }
+       spin_lock_irqsave(&acm->write_lock, flags);
+       acm->write_ready = acm->old_ready;
+       spin_unlock_irqrestore(&acm->write_lock, flags);
+       usb_autopm_put_interface(acm->control);
+}
+
 /*
  * TTY handlers
  */
@@ -492,6 +559,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
 
        if (usb_autopm_get_interface(acm->control) < 0)
                goto early_bail;
+       else
+               acm->control->needs_remote_wakeup = 1;
 
        mutex_lock(&acm->mutex);
        if (acm->used++) {
@@ -509,6 +578,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
        if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) &&
            (acm->ctrl_caps & USB_CDC_CAP_LINE))
                goto full_bailout;
+       usb_autopm_put_interface(acm->control);
 
        INIT_LIST_HEAD(&acm->spare_read_urbs);
        INIT_LIST_HEAD(&acm->spare_read_bufs);
@@ -570,12 +640,14 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
        mutex_lock(&open_mutex);
        if (!--acm->used) {
                if (acm->dev) {
+                       usb_autopm_get_interface(acm->control);
                        acm_set_control(acm, acm->ctrlout = 0);
                        usb_kill_urb(acm->ctrlurb);
                        for (i = 0; i < ACM_NW; i++)
                                usb_kill_urb(acm->wb[i].urb);
                        for (i = 0; i < nr; i++)
                                usb_kill_urb(acm->ru[i].urb);
+                       acm->control->needs_remote_wakeup = 0;
                        usb_autopm_put_interface(acm->control);
                } else
                        acm_tty_unregister(acm);
@@ -660,13 +732,16 @@ static void acm_tty_unthrottle(struct tty_struct *tty)
        tasklet_schedule(&acm->urb_task);
 }
 
-static void acm_tty_break_ctl(struct tty_struct *tty, int state)
+static int acm_tty_break_ctl(struct tty_struct *tty, int state)
 {
        struct acm *acm = tty->driver_data;
+       int retval;
        if (!ACM_READY(acm))
-               return;
-       if (acm_send_break(acm, state ? 0xffff : 0))
+               return -EINVAL;
+       retval = acm_send_break(acm, state ? 0xffff : 0);
+       if (retval < 0)
                dbg("send break failed");
+       return retval;
 }
 
 static int acm_tty_tiocmget(struct tty_struct *tty, struct file *file)
@@ -766,7 +841,7 @@ static void acm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios
  * USB probe and disconnect routines.
  */
 
-/* Little helper: write buffers free */
+/* Little helpers: write/read buffers free */
 static void acm_write_buffers_free(struct acm *acm)
 {
        int i;
@@ -777,6 +852,15 @@ static void acm_write_buffers_free(struct acm *acm)
        }
 }
 
+static void acm_read_buffers_free(struct acm *acm)
+{
+       struct usb_device *usb_dev = interface_to_usbdev(acm->control);
+       int i, n = acm->rx_buflimit;
+
+       for (i = 0; i < n; i++)
+               usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
+}
+
 /* Little helper: write buffers allocate */
 static int acm_write_buffers_alloc(struct acm *acm)
 {
@@ -987,6 +1071,7 @@ skip_normal_probe:
        acm->urb_task.func = acm_rx_tasklet;
        acm->urb_task.data = (unsigned long) acm;
        INIT_WORK(&acm->work, acm_softint);
+       INIT_WORK(&acm->waker, acm_waker);
        spin_lock_init(&acm->throttle_lock);
        spin_lock_init(&acm->write_lock);
        spin_lock_init(&acm->read_lock);
@@ -1098,8 +1183,7 @@ alloc_fail8:
        for (i = 0; i < ACM_NW; i++)
                usb_free_urb(acm->wb[i].urb);
 alloc_fail7:
-       for (i = 0; i < num_rx_buf; i++)
-               usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
+       acm_read_buffers_free(acm);
        for (i = 0; i < num_rx_buf; i++)
                usb_free_urb(acm->ru[i].urb);
        usb_free_urb(acm->ctrlurb);
@@ -1116,6 +1200,7 @@ alloc_fail:
 static void stop_data_traffic(struct acm *acm)
 {
        int i;
+       dbg("Entering stop_data_traffic");
 
        tasklet_disable(&acm->urb_task);
 
@@ -1128,21 +1213,16 @@ static void stop_data_traffic(struct acm *acm)
        tasklet_enable(&acm->urb_task);
 
        cancel_work_sync(&acm->work);
+       cancel_work_sync(&acm->waker);
 }
 
 static void acm_disconnect(struct usb_interface *intf)
 {
        struct acm *acm = usb_get_intfdata(intf);
        struct usb_device *usb_dev = interface_to_usbdev(intf);
-       int i;
-
-       if (!acm || !acm->dev) {
-               dbg("disconnect on nonexisting interface");
-               return;
-       }
 
        mutex_lock(&open_mutex);
-       if (!usb_get_intfdata(intf)) {
+       if (!acm || !acm->dev) {
                mutex_unlock(&open_mutex);
                return;
        }
@@ -1161,10 +1241,10 @@ static void acm_disconnect(struct usb_interface *intf)
 
        acm_write_buffers_free(acm);
        usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
-       for (i = 0; i < acm->rx_buflimit; i++)
-               usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
+       acm_read_buffers_free(acm);
 
-       usb_driver_release_interface(&acm_driver, intf == acm->control ? acm->data : intf);
+       usb_driver_release_interface(&acm_driver, intf == acm->control ?
+                                       acm->data : acm->control);
 
        if (!acm->used) {
                acm_tty_unregister(acm);
@@ -1178,11 +1258,31 @@ static void acm_disconnect(struct usb_interface *intf)
                tty_hangup(acm->tty);
 }
 
+#ifdef CONFIG_PM
 static int acm_suspend(struct usb_interface *intf, pm_message_t message)
 {
        struct acm *acm = usb_get_intfdata(intf);
+       int cnt;
+
+       if (acm->dev->auto_pm) {
+               int b;
+
+               spin_lock_irq(&acm->read_lock);
+               spin_lock(&acm->write_lock);
+               b = acm->processing + acm->transmitting;
+               spin_unlock(&acm->write_lock);
+               spin_unlock_irq(&acm->read_lock);
+               if (b)
+                       return -EBUSY;
+       }
+
+       spin_lock_irq(&acm->read_lock);
+       spin_lock(&acm->write_lock);
+       cnt = acm->susp_count++;
+       spin_unlock(&acm->write_lock);
+       spin_unlock_irq(&acm->read_lock);
 
-       if (acm->susp_count++)
+       if (cnt)
                return 0;
        /*
        we treat opened interfaces differently,
@@ -1201,15 +1301,21 @@ static int acm_resume(struct usb_interface *intf)
 {
        struct acm *acm = usb_get_intfdata(intf);
        int rv = 0;
+       int cnt;
+
+       spin_lock_irq(&acm->read_lock);
+       acm->susp_count -= 1;
+       cnt = acm->susp_count;
+       spin_unlock_irq(&acm->read_lock);
 
-       if (--acm->susp_count)
+       if (cnt)
                return 0;
 
        mutex_lock(&acm->mutex);
        if (acm->used) {
                rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
                if (rv < 0)
-               goto err_out;
+                       goto err_out;
 
                tasklet_schedule(&acm->urb_task);
        }
@@ -1218,6 +1324,8 @@ err_out:
        mutex_unlock(&acm->mutex);
        return rv;
 }
+
+#endif /* CONFIG_PM */
 /*
  * USB driver structure.
  */
@@ -1273,10 +1381,14 @@ static struct usb_driver acm_driver = {
        .name =         "cdc_acm",
        .probe =        acm_probe,
        .disconnect =   acm_disconnect,
+#ifdef CONFIG_PM
        .suspend =      acm_suspend,
        .resume =       acm_resume,
+#endif
        .id_table =     acm_ids,
+#ifdef CONFIG_PM
        .supports_autosuspend = 1,
+#endif
 };
 
 /*
index 046e064b033af6675bb48208b277f9967130c243..85c3aaaab7c58570ec0155e0cbd37590cb0a4472 100644 (file)
@@ -107,10 +107,14 @@ struct acm {
        struct list_head filled_read_bufs;
        int write_used;                                 /* number of non-empty write buffers */
        int write_ready;                                /* write urb is not running */
+       int old_ready;
+       int processing;
+       int transmitting;
        spinlock_t write_lock;
        struct mutex mutex;
        struct usb_cdc_line_coding line;                /* bits, stop, parity */
        struct work_struct work;                        /* work queue entry for line discipline waking up */
+       struct work_struct waker;
        struct tasklet_struct urb_task;                 /* rx processing */
        spinlock_t throttle_lock;                       /* synchronize throtteling and read callback */
        unsigned int ctrlin;                            /* input control lines (DCD, DSR, RI, break, overruns) */
@@ -123,6 +127,7 @@ struct acm {
        unsigned char clocal;                           /* termios CLOCAL */
        unsigned int ctrl_caps;                         /* control capabilities from the class specific header */
        unsigned int susp_count;                        /* number of suspended interfaces */
+       struct acm_wb *delayed_wb;                      /* write queued for a device about to be woken */
 };
 
 #define CDC_DATA_INTERFACE_TYPE        0x0a
index 731db051070a82d63a5eeebe048c6ab314b92810..7e8e1235e4e52d93cf3aa0ab930a7cce618bc7ea 100644 (file)
@@ -28,8 +28,9 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.02"
+#define DRIVER_VERSION "v0.03"
 #define DRIVER_AUTHOR "Oliver Neukum"
+#define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management"
 
 static struct usb_device_id wdm_ids[] = {
        {
@@ -87,6 +88,7 @@ struct wdm_device {
        dma_addr_t              ihandle;
        struct mutex            wlock;
        struct mutex            rlock;
+       struct mutex            plock;
        wait_queue_head_t       wait;
        struct work_struct      rxwork;
        int                     werr;
@@ -205,7 +207,7 @@ static void wdm_int_callback(struct urb *urb)
        req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
        req->wValue = 0;
        req->wIndex = desc->inum;
-       req->wLength = cpu_to_le16(desc->bMaxPacketSize0);
+       req->wLength = cpu_to_le16(desc->wMaxCommand);
 
        usb_fill_control_urb(
                desc->response,
@@ -214,7 +216,7 @@ static void wdm_int_callback(struct urb *urb)
                usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0),
                (unsigned char *)req,
                desc->inbuf,
-               desc->bMaxPacketSize0,
+               desc->wMaxCommand,
                wdm_in_callback,
                desc
        );
@@ -247,6 +249,7 @@ exit:
 
 static void kill_urbs(struct wdm_device *desc)
 {
+       /* the order here is essential */
        usb_kill_urb(desc->command);
        usb_kill_urb(desc->validity);
        usb_kill_urb(desc->response);
@@ -266,7 +269,7 @@ static void cleanup(struct wdm_device *desc)
                        desc->sbuf,
                        desc->validity->transfer_dma);
        usb_buffer_free(interface_to_usbdev(desc->intf),
-                       desc->wMaxPacketSize,
+                       desc->wMaxCommand,
                        desc->inbuf,
                        desc->response->transfer_dma);
        kfree(desc->orq);
@@ -299,6 +302,9 @@ static ssize_t wdm_write
        if (r)
                goto outnl;
 
+       r = usb_autopm_get_interface(desc->intf);
+       if (r < 0)
+               goto outnp;
        r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
                                                           &desc->flags));
        if (r < 0)
@@ -347,11 +353,14 @@ static ssize_t wdm_write
        if (rv < 0) {
                kfree(buf);
                clear_bit(WDM_IN_USE, &desc->flags);
+               err("Tx URB error: %d", rv);
        } else {
                dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d",
                        req->wIndex);
        }
 out:
+       usb_autopm_put_interface(desc->intf);
+outnp:
        mutex_unlock(&desc->wlock);
 outnl:
        return rv < 0 ? rv : count;
@@ -376,6 +385,11 @@ retry:
                rv = wait_event_interruptible(desc->wait,
                                              test_bit(WDM_READ, &desc->flags));
 
+               if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
+                       rv = -ENODEV;
+                       goto err;
+               }
+               usb_mark_last_busy(interface_to_usbdev(desc->intf));
                if (rv < 0) {
                        rv = -ERESTARTSYS;
                        goto err;
@@ -418,6 +432,9 @@ retry:
                desc->ubuf[i] = desc->ubuf[i + cntr];
 
        desc->length -= cntr;
+       /* in case we had outstanding data */
+       if (!desc->length)
+               clear_bit(WDM_READ, &desc->flags);
        rv = cntr;
 
 err:
@@ -480,18 +497,28 @@ static int wdm_open(struct inode *inode, struct file *file)
        if (test_bit(WDM_DISCONNECTING, &desc->flags))
                goto out;
 
-       desc->count++;
+       ;
        file->private_data = desc;
 
-       rv = usb_submit_urb(desc->validity, GFP_KERNEL);
-
+       rv = usb_autopm_get_interface(desc->intf);
        if (rv < 0) {
-               desc->count--;
-               err("Error submitting int urb - %d", rv);
+               err("Error autopm - %d", rv);
                goto out;
        }
-       rv = 0;
+       intf->needs_remote_wakeup = 1;
 
+       mutex_lock(&desc->plock);
+       if (!desc->count++) {
+               rv = usb_submit_urb(desc->validity, GFP_KERNEL);
+               if (rv < 0) {
+                       desc->count--;
+                       err("Error submitting int urb - %d", rv);
+               }
+       } else {
+               rv = 0;
+       }
+       mutex_unlock(&desc->plock);
+       usb_autopm_put_interface(desc->intf);
 out:
        mutex_unlock(&wdm_mutex);
        return rv;
@@ -502,10 +529,15 @@ static int wdm_release(struct inode *inode, struct file *file)
        struct wdm_device *desc = file->private_data;
 
        mutex_lock(&wdm_mutex);
+       mutex_lock(&desc->plock);
        desc->count--;
+       mutex_unlock(&desc->plock);
+
        if (!desc->count) {
                dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
                kill_urbs(desc);
+               if (!test_bit(WDM_DISCONNECTING, &desc->flags))
+                       desc->intf->needs_remote_wakeup = 0;
        }
        mutex_unlock(&wdm_mutex);
        return 0;
@@ -597,6 +629,7 @@ next_desc:
                goto out;
        mutex_init(&desc->wlock);
        mutex_init(&desc->rlock);
+       mutex_init(&desc->plock);
        spin_lock_init(&desc->iuspin);
        init_waitqueue_head(&desc->wait);
        desc->wMaxCommand = maxcom;
@@ -698,6 +731,7 @@ static void wdm_disconnect(struct usb_interface *intf)
        spin_lock_irqsave(&desc->iuspin, flags);
        set_bit(WDM_DISCONNECTING, &desc->flags);
        set_bit(WDM_READ, &desc->flags);
+       /* to terminate pending flushes */
        clear_bit(WDM_IN_USE, &desc->flags);
        spin_unlock_irqrestore(&desc->iuspin, flags);
        cancel_work_sync(&desc->rxwork);
@@ -708,11 +742,81 @@ static void wdm_disconnect(struct usb_interface *intf)
        mutex_unlock(&wdm_mutex);
 }
 
+static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct wdm_device *desc = usb_get_intfdata(intf);
+       int rv = 0;
+
+       dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
+
+       mutex_lock(&desc->plock);
+#ifdef CONFIG_PM
+       if (interface_to_usbdev(desc->intf)->auto_pm && test_bit(WDM_IN_USE, &desc->flags)) {
+               rv = -EBUSY;
+       } else {
+#endif
+               cancel_work_sync(&desc->rxwork);
+               kill_urbs(desc);
+#ifdef CONFIG_PM
+       }
+#endif
+       mutex_unlock(&desc->plock);
+
+       return rv;
+}
+
+static int recover_from_urb_loss(struct wdm_device *desc)
+{
+       int rv = 0;
+
+       if (desc->count) {
+               rv = usb_submit_urb(desc->validity, GFP_NOIO);
+               if (rv < 0)
+                       err("Error resume submitting int urb - %d", rv);
+       }
+       return rv;
+}
+static int wdm_resume(struct usb_interface *intf)
+{
+       struct wdm_device *desc = usb_get_intfdata(intf);
+       int rv;
+
+       dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor);
+       mutex_lock(&desc->plock);
+       rv = recover_from_urb_loss(desc);
+       mutex_unlock(&desc->plock);
+       return rv;
+}
+
+static int wdm_pre_reset(struct usb_interface *intf)
+{
+       struct wdm_device *desc = usb_get_intfdata(intf);
+
+       mutex_lock(&desc->plock);
+       return 0;
+}
+
+static int wdm_post_reset(struct usb_interface *intf)
+{
+       struct wdm_device *desc = usb_get_intfdata(intf);
+       int rv;
+
+       rv = recover_from_urb_loss(desc);
+       mutex_unlock(&desc->plock);
+       return 0;
+}
+
 static struct usb_driver wdm_driver = {
        .name =         "cdc_wdm",
        .probe =        wdm_probe,
        .disconnect =   wdm_disconnect,
+       .suspend =      wdm_suspend,
+       .resume =       wdm_resume,
+       .reset_resume = wdm_resume,
+       .pre_reset =    wdm_pre_reset,
+       .post_reset =   wdm_post_reset,
        .id_table =     wdm_ids,
+       .supports_autosuspend = 1,
 };
 
 /* --- low level module stuff --- */
@@ -735,6 +839,5 @@ module_init(wdm_init);
 module_exit(wdm_exit);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION("USB Abstract Control Model driver for "
-                  "USB WCM Device Management");
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
index 83d9dc379d968c7ecc87f759251f16e926ff4d89..6ec38175a8170129a58f3954d7c438e488737a09 100644 (file)
@@ -46,8 +46,6 @@
  * 2000-07-05: Ashley Montanaro <ashley@compsoc.man.ac.uk>
  *   Converted file reading routine to dump to buffer once
  *   per device, not per bus
- *
- * $Id: devices.c,v 1.5 2000/01/11 13:58:21 tom Exp $
  */
 
 #include <linux/fs.h>
@@ -63,8 +61,6 @@
 #include "usb.h"
 #include "hcd.h"
 
-#define MAX_TOPO_LEVEL         6
-
 /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */
 #define ALLOW_SERIAL_NUMBER
 
index 9218cca210431dea3b840e85b4fa9a0f0653a3fd..20290c5b15625c3b4272765ff95eefa3feb07b88 100644 (file)
@@ -19,8 +19,6 @@
  *      along with this program; if not, write to the Free Software
  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *  $Id: devio.c,v 1.7 2000/02/01 17:28:48 fliegl Exp $
- *
  *  This file implements the usbfs/x/y files, where
  *  x is the bus number and y the device number.
  *
 /* Mutual exclusion for removal, open, and release */
 DEFINE_MUTEX(usbfs_mutex);
 
+struct dev_state {
+       struct list_head list;      /* state list */
+       struct usb_device *dev;
+       struct file *file;
+       spinlock_t lock;            /* protects the async urb lists */
+       struct list_head async_pending;
+       struct list_head async_completed;
+       wait_queue_head_t wait;     /* wake up if a request completed */
+       unsigned int discsignr;
+       struct pid *disc_pid;
+       uid_t disc_uid, disc_euid;
+       void __user *disccontext;
+       unsigned long ifclaimed;
+       u32 secid;
+};
+
 struct async {
        struct list_head asynclist;
        struct dev_state *ps;
@@ -536,23 +550,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,
        return ret;
 }
 
-static int __match_minor(struct device *dev, void *data)
+static int match_devt(struct device *dev, void *data)
 {
-       int minor = *((int *)data);
-
-       if (dev->devt == MKDEV(USB_DEVICE_MAJOR, minor))
-               return 1;
-       return 0;
+       return dev->devt == (dev_t) (unsigned long) data;
 }
 
-static struct usb_device *usbdev_lookup_by_minor(int minor)
+static struct usb_device *usbdev_lookup_by_devt(dev_t devt)
 {
        struct device *dev;
 
-       dev = bus_find_device(&usb_bus_type, NULL, &minor, __match_minor);
+       dev = bus_find_device(&usb_bus_type, NULL,
+                             (void *) (unsigned long) devt, match_devt);
        if (!dev)
                return NULL;
-       put_device(dev);
        return container_of(dev, struct usb_device, dev);
 }
 
@@ -575,21 +585,27 @@ static int usbdev_open(struct inode *inode, struct file *file)
                goto out;
 
        ret = -ENOENT;
+
        /* usbdev device-node */
        if (imajor(inode) == USB_DEVICE_MAJOR)
-               dev = usbdev_lookup_by_minor(iminor(inode));
+               dev = usbdev_lookup_by_devt(inode->i_rdev);
 #ifdef CONFIG_USB_DEVICEFS
        /* procfs file */
-       if (!dev)
+       if (!dev) {
                dev = inode->i_private;
+               if (dev && dev->usbfs_dentry &&
+                                       dev->usbfs_dentry->d_inode == inode)
+                       usb_get_dev(dev);
+               else
+                       dev = NULL;
+       }
 #endif
-       if (!dev)
+       if (!dev || dev->state == USB_STATE_NOTATTACHED)
                goto out;
        ret = usb_autoresume_device(dev);
        if (ret)
                goto out;
 
-       usb_get_dev(dev);
        ret = 0;
        ps->dev = dev;
        ps->file = file;
@@ -609,8 +625,10 @@ static int usbdev_open(struct inode *inode, struct file *file)
        list_add_tail(&ps->list, &dev->filelist);
        file->private_data = ps;
  out:
-       if (ret)
+       if (ret) {
                kfree(ps);
+               usb_put_dev(dev);
+       }
        mutex_unlock(&usbfs_mutex);
        unlock_kernel();
        return ret;
@@ -874,7 +892,7 @@ static int proc_connectinfo(struct dev_state *ps, void __user *arg)
 
 static int proc_resetdevice(struct dev_state *ps)
 {
-       return usb_reset_composite_device(ps->dev, NULL);
+       return usb_reset_device(ps->dev);
 }
 
 static int proc_setintf(struct dev_state *ps, void __user *arg)
@@ -1682,25 +1700,49 @@ const struct file_operations usbdev_file_operations = {
        .release =      usbdev_release,
 };
 
+void usb_fs_classdev_common_remove(struct usb_device *udev)
+{
+       struct dev_state *ps;
+       struct siginfo sinfo;
+
+       while (!list_empty(&udev->filelist)) {
+               ps = list_entry(udev->filelist.next, struct dev_state, list);
+               destroy_all_async(ps);
+               wake_up_all(&ps->wait);
+               list_del_init(&ps->list);
+               if (ps->discsignr) {
+                       sinfo.si_signo = ps->discsignr;
+                       sinfo.si_errno = EPIPE;
+                       sinfo.si_code = SI_ASYNCIO;
+                       sinfo.si_addr = ps->disccontext;
+                       kill_pid_info_as_uid(ps->discsignr, &sinfo,
+                                       ps->disc_pid, ps->disc_uid,
+                                       ps->disc_euid, ps->secid);
+               }
+       }
+}
+
 #ifdef CONFIG_USB_DEVICE_CLASS
 static struct class *usb_classdev_class;
 
 static int usb_classdev_add(struct usb_device *dev)
 {
-       int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
-
-       dev->usb_classdev = device_create(usb_classdev_class, &dev->dev,
-                               MKDEV(USB_DEVICE_MAJOR, minor),
-                               "usbdev%d.%d", dev->bus->busnum, dev->devnum);
-       if (IS_ERR(dev->usb_classdev))
-               return PTR_ERR(dev->usb_classdev);
-
+       struct device *cldev;
+
+       cldev = device_create_drvdata(usb_classdev_class, &dev->dev,
+                                     dev->dev.devt, NULL, "usbdev%d.%d",
+                                     dev->bus->busnum, dev->devnum);
+       if (IS_ERR(cldev))
+               return PTR_ERR(cldev);
+       dev->usb_classdev = cldev;
        return 0;
 }
 
 static void usb_classdev_remove(struct usb_device *dev)
 {
-       device_unregister(dev->usb_classdev);
+       if (dev->usb_classdev)
+               device_unregister(dev->usb_classdev);
+       usb_fs_classdev_common_remove(dev);
 }
 
 static int usb_classdev_notify(struct notifier_block *self,
@@ -1750,6 +1792,11 @@ int __init usb_devio_init(void)
                usb_classdev_class = NULL;
                goto out;
        }
+       /* devices of this class shadow the major:minor of their parent
+        * device, so clear ->dev_kobj to prevent adding duplicate entries
+        * to /sys/dev
+        */
+       usb_classdev_class->dev_kobj = NULL;
 
        usb_register_notify(&usbdev_nb);
 #endif
index 1e56f1cfa6dc9447c22df3de61a840a3ac401330..ddb54e14a5c54595908b4773f125db97c3e550e5 100644 (file)
@@ -201,6 +201,7 @@ static int usb_probe_interface(struct device *dev)
 
        intf = to_usb_interface(dev);
        udev = interface_to_usbdev(intf);
+       intf->needs_binding = 0;
 
        if (udev->authorized == 0) {
                dev_err(&intf->dev, "Device is not authorized for usage\n");
@@ -257,15 +258,16 @@ static int usb_unbind_interface(struct device *dev)
        udev = interface_to_usbdev(intf);
        error = usb_autoresume_device(udev);
 
-       /* release all urbs for this interface */
-       usb_disable_interface(interface_to_usbdev(intf), intf);
+       /* Terminate all URBs for this interface unless the driver
+        * supports "soft" unbinding.
+        */
+       if (!driver->soft_unbind)
+               usb_disable_interface(udev, intf);
 
        driver->disconnect(intf);
 
        /* reset other interface state */
-       usb_set_interface(interface_to_usbdev(intf),
-                       intf->altsetting[0].desc.bInterfaceNumber,
-                       0);
+       usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
        usb_set_intfdata(intf, NULL);
 
        intf->condition = USB_INTERFACE_UNBOUND;
@@ -310,6 +312,7 @@ int usb_driver_claim_interface(struct usb_driver *driver,
 
        dev->driver = &driver->drvwrap.driver;
        usb_set_intfdata(iface, priv);
+       iface->needs_binding = 0;
 
        usb_pm_lock(udev);
        iface->condition = USB_INTERFACE_BOUND;
@@ -586,7 +589,7 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
        struct usb_device *usb_dev;
 
        /* driver is often null here; dev_dbg() would oops */
-       pr_debug("usb %s: uevent\n", dev->bus_id);
+       pr_debug("usb %s: uevent\n", dev_name(dev));
 
        if (is_usb_device(dev))
                usb_dev = to_usb_device(dev);
@@ -596,11 +599,11 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
        }
 
        if (usb_dev->devnum < 0) {
-               pr_debug("usb %s: already deleted?\n", dev->bus_id);
+               pr_debug("usb %s: already deleted?\n", dev_name(dev));
                return -ENODEV;
        }
        if (!usb_dev->bus) {
-               pr_debug("usb %s: bus removed?\n", dev->bus_id);
+               pr_debug("usb %s: bus removed?\n", dev_name(dev));
                return -ENODEV;
        }
 
@@ -771,6 +774,104 @@ void usb_deregister(struct usb_driver *driver)
 }
 EXPORT_SYMBOL_GPL(usb_deregister);
 
+
+/* Forced unbinding of a USB interface driver, either because
+ * it doesn't support pre_reset/post_reset/reset_resume or
+ * because it doesn't support suspend/resume.
+ *
+ * The caller must hold @intf's device's lock, but not its pm_mutex
+ * and not @intf->dev.sem.
+ */
+void usb_forced_unbind_intf(struct usb_interface *intf)
+{
+       struct usb_driver *driver = to_usb_driver(intf->dev.driver);
+
+       dev_dbg(&intf->dev, "forced unbind\n");
+       usb_driver_release_interface(driver, intf);
+
+       /* Mark the interface for later rebinding */
+       intf->needs_binding = 1;
+}
+
+/* Delayed forced unbinding of a USB interface driver and scan
+ * for rebinding.
+ *
+ * The caller must hold @intf's device's lock, but not its pm_mutex
+ * and not @intf->dev.sem.
+ *
+ * FIXME: The caller must block system sleep transitions.
+ */
+void usb_rebind_intf(struct usb_interface *intf)
+{
+       int rc;
+
+       /* Delayed unbind of an existing driver */
+       if (intf->dev.driver) {
+               struct usb_driver *driver =
+                               to_usb_driver(intf->dev.driver);
+
+               dev_dbg(&intf->dev, "forced unbind\n");
+               usb_driver_release_interface(driver, intf);
+       }
+
+       /* Try to rebind the interface */
+       intf->needs_binding = 0;
+       rc = device_attach(&intf->dev);
+       if (rc < 0)
+               dev_warn(&intf->dev, "rebind failed: %d\n", rc);
+}
+
+#define DO_UNBIND      0
+#define DO_REBIND      1
+
+/* Unbind drivers for @udev's interfaces that don't support suspend/resume,
+ * or rebind interfaces that have been unbound, according to @action.
+ *
+ * The caller must hold @udev's device lock.
+ * FIXME: For rebinds, the caller must block system sleep transitions.
+ */
+static void do_unbind_rebind(struct usb_device *udev, int action)
+{
+       struct usb_host_config  *config;
+       int                     i;
+       struct usb_interface    *intf;
+       struct usb_driver       *drv;
+
+       config = udev->actconfig;
+       if (config) {
+               for (i = 0; i < config->desc.bNumInterfaces; ++i) {
+                       intf = config->interface[i];
+                       switch (action) {
+                       case DO_UNBIND:
+                               if (intf->dev.driver) {
+                                       drv = to_usb_driver(intf->dev.driver);
+                                       if (!drv->suspend || !drv->resume)
+                                               usb_forced_unbind_intf(intf);
+                               }
+                               break;
+                       case DO_REBIND:
+                               if (intf->needs_binding) {
+
+       /* FIXME: The next line is needed because we are going to probe
+        * the interface, but as far as the PM core is concerned the
+        * interface is still suspended.  The problem wouldn't exist
+        * if we could rebind the interface during the interface's own
+        * resume() call, but at the time the usb_device isn't locked!
+        *
+        * The real solution will be to carry this out during the device's
+        * complete() callback.  Until that is implemented, we have to
+        * use this hack.
+        */
+//                                     intf->dev.power.sleeping = 0;
+
+                                       usb_rebind_intf(intf);
+                               }
+                               break;
+                       }
+               }
+       }
+}
+
 #ifdef CONFIG_PM
 
 /* Caller has locked udev's pm_mutex */
@@ -805,8 +906,6 @@ static int usb_resume_device(struct usb_device *udev)
 
        if (udev->state == USB_STATE_NOTATTACHED)
                goto done;
-       if (udev->state != USB_STATE_SUSPENDED && !udev->reset_resume)
-               goto done;
 
        /* Can't resume it if it doesn't have a driver. */
        if (udev->dev.driver == NULL) {
@@ -842,7 +941,7 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
                goto done;
        driver = to_usb_driver(intf->dev.driver);
 
-       if (driver->suspend && driver->resume) {
+       if (driver->suspend) {
                status = driver->suspend(intf, msg);
                if (status == 0)
                        mark_quiesced(intf);
@@ -850,12 +949,10 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
                        dev_err(&intf->dev, "%s error %d\n",
                                        "suspend", status);
        } else {
-               /*
-                * FIXME else if there's no suspend method, disconnect...
-                * Not possible if auto_pm is set...
-                */
-               dev_warn(&intf->dev, "no suspend for driver %s?\n",
-                               driver->name);
+               /* Later we will unbind the driver and reprobe */
+               intf->needs_binding = 1;
+               dev_warn(&intf->dev, "no %s for driver %s?\n",
+                               "suspend", driver->name);
                mark_quiesced(intf);
        }
 
@@ -879,10 +976,12 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
                goto done;
 
        /* Can't resume it if it doesn't have a driver. */
-       if (intf->condition == USB_INTERFACE_UNBOUND) {
-               status = -ENOTCONN;
+       if (intf->condition == USB_INTERFACE_UNBOUND)
+               goto done;
+
+       /* Don't resume if the interface is marked for rebinding */
+       if (intf->needs_binding)
                goto done;
-       }
        driver = to_usb_driver(intf->dev.driver);
 
        if (reset_resume) {
@@ -892,7 +991,7 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
                                dev_err(&intf->dev, "%s error %d\n",
                                                "reset_resume", status);
                } else {
-                       /* status = -EOPNOTSUPP; */
+                       intf->needs_binding = 1;
                        dev_warn(&intf->dev, "no %s for driver %s?\n",
                                        "reset_resume", driver->name);
                }
@@ -903,7 +1002,7 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
                                dev_err(&intf->dev, "%s error %d\n",
                                                "resume", status);
                } else {
-                       /* status = -EOPNOTSUPP; */
+                       intf->needs_binding = 1;
                        dev_warn(&intf->dev, "no %s for driver %s?\n",
                                        "resume", driver->name);
                }
@@ -911,11 +1010,10 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
 
 done:
        dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status);
-       if (status == 0)
+       if (status == 0 && intf->condition == USB_INTERFACE_BOUND)
                mark_active(intf);
 
-       /* FIXME: Unbind the driver and reprobe if the resume failed
-        * (not possible if auto_pm is set) */
+       /* Later we will unbind the driver and/or reprobe, if necessary */
        return status;
 }
 
@@ -1173,11 +1271,8 @@ static int usb_resume_both(struct usb_device *udev)
                         * then we're stuck. */
                        status = usb_resume_device(udev);
                }
-       } else {
-
-               /* Needed for reset-resume */
+       } else if (udev->reset_resume)
                status = usb_resume_device(udev);
-       }
 
        if (status == 0 && udev->actconfig) {
                for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
@@ -1474,6 +1569,7 @@ int usb_external_suspend_device(struct usb_device *udev, pm_message_t msg)
 {
        int     status;
 
+       do_unbind_rebind(udev, DO_UNBIND);
        usb_pm_lock(udev);
        udev->auto_pm = 0;
        status = usb_suspend_both(udev, msg);
@@ -1501,6 +1597,7 @@ int usb_external_resume_device(struct usb_device *udev)
        status = usb_resume_both(udev);
        udev->last_busy = jiffies;
        usb_pm_unlock(udev);
+       do_unbind_rebind(udev, DO_REBIND);
 
        /* Now that the device is awake, we can start trying to autosuspend
         * it again. */
@@ -1542,14 +1639,11 @@ static int usb_resume(struct device *dev)
        udev = to_usb_device(dev);
 
        /* If udev->skip_sys_resume is set then udev was already suspended
-        * when the system suspend started, so we don't want to resume
-        * udev during this system wakeup.  However a reset-resume counts
-        * as a wakeup event, so allow a reset-resume to occur if remote
-        * wakeup is enabled. */
-       if (udev->skip_sys_resume) {
-               if (!(udev->reset_resume && udev->do_remote_wakeup))
-                       return -EHOSTUNREACH;
-       }
+        * when the system sleep started, so we don't want to resume it
+        * during this system wakeup.
+        */
+       if (udev->skip_sys_resume)
+               return 0;
        return usb_external_resume_device(udev);
 }
 
index fae55a31e26dca055b5047b8ed70f8a56446cc41..22912136fc142b780d1af23815cc29e7e3dbe0e7 100644 (file)
@@ -296,7 +296,7 @@ int usb_create_ep_files(struct device *parent,
        retval = endpoint_get_minor(ep_dev);
        if (retval) {
                dev_err(parent, "can not allocate minor number for %s\n",
-                       ep_dev->dev.bus_id);
+                       dev_name(&ep_dev->dev));
                goto error_register;
        }
 
@@ -307,7 +307,7 @@ int usb_create_ep_files(struct device *parent,
        ep_dev->dev.class = ep_class->class;
        ep_dev->dev.parent = parent;
        ep_dev->dev.release = ep_device_release;
-       snprintf(ep_dev->dev.bus_id, BUS_ID_SIZE, "usbdev%d.%d_ep%02x",
+       dev_set_name(&ep_dev->dev, "usbdev%d.%d_ep%02x",
                 udev->bus->busnum, udev->devnum,
                 endpoint->desc.bEndpointAddress);
 
index c6a95395e52a29f19a4a8d53045bb458a5f8001d..6b1b229e38cd1d28790d5f29e54eebbe3efe2fb8 100644 (file)
@@ -150,7 +150,7 @@ int usb_register_dev(struct usb_interface *intf,
        int retval = -EINVAL;
        int minor_base = class_driver->minor_base;
        int minor = 0;
-       char name[BUS_ID_SIZE];
+       char name[20];
        char *temp;
 
 #ifdef CONFIG_USB_DYNAMIC_MINORS
@@ -190,14 +190,15 @@ int usb_register_dev(struct usb_interface *intf,
        intf->minor = minor;
 
        /* create a usb class device for this usb interface */
-       snprintf(name, BUS_ID_SIZE, class_driver->name, minor - minor_base);
+       snprintf(name, sizeof(name), class_driver->name, minor - minor_base);
        temp = strrchr(name, '/');
-       if (temp && (temp[1] != 0x00))
+       if (temp && (temp[1] != '\0'))
                ++temp;
        else
                temp = name;
-       intf->usb_dev = device_create(usb_class->class, &intf->dev,
-                                     MKDEV(USB_MAJOR, minor), "%s", temp);
+       intf->usb_dev = device_create_drvdata(usb_class->class, &intf->dev,
+                                             MKDEV(USB_MAJOR, minor), NULL,
+                                             "%s", temp);
        if (IS_ERR(intf->usb_dev)) {
                down_write(&minor_rwsem);
                usb_minors[intf->minor] = NULL;
@@ -227,7 +228,7 @@ void usb_deregister_dev(struct usb_interface *intf,
                        struct usb_class_driver *class_driver)
 {
        int minor_base = class_driver->minor_base;
-       char name[BUS_ID_SIZE];
+       char name[20];
 
 #ifdef CONFIG_USB_DYNAMIC_MINORS
        minor_base = 0;
@@ -242,7 +243,7 @@ void usb_deregister_dev(struct usb_interface *intf,
        usb_minors[intf->minor] = NULL;
        up_write(&minor_rwsem);
 
-       snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);
+       snprintf(name, sizeof(name), class_driver->name, intf->minor - minor_base);
        device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
        intf->usb_dev = NULL;
        intf->minor = -1;
index 42a436478b78bba99c05a9cf609ea89e4e11adfe..f7bfd72ef115bae2855e05c9b622ff41588477b1 100644 (file)
@@ -900,14 +900,14 @@ static int register_root_hub(struct usb_hcd *hcd)
        if (retval != sizeof usb_dev->descriptor) {
                mutex_unlock(&usb_bus_list_lock);
                dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
-                               usb_dev->dev.bus_id, retval);
+                               dev_name(&usb_dev->dev), retval);
                return (retval < 0) ? retval : -EMSGSIZE;
        }
 
        retval = usb_new_device (usb_dev);
        if (retval) {
                dev_err (parent_dev, "can't register root hub for %s, %d\n",
-                               usb_dev->dev.bus_id, retval);
+                               dev_name(&usb_dev->dev), retval);
        }
        mutex_unlock(&usb_bus_list_lock);
 
@@ -1764,7 +1764,7 @@ EXPORT_SYMBOL_GPL (usb_hc_died);
  * If memory is unavailable, returns NULL.
  */
 struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,
-               struct device *dev, char *bus_name)
+               struct device *dev, const char *bus_name)
 {
        struct usb_hcd *hcd;
 
index b9de1569b39e792f8de8301b5b3c8b27782100ee..5b0b59b0d89b37709da23af08cf0271c193d9ebf 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <linux/rwsem.h>
 
+#define MAX_TOPO_LEVEL         6
+
 /* This file contains declarations of usbcore internals that are mostly
  * used or exposed by Host Controller Drivers.
  */
@@ -235,7 +237,7 @@ extern void usb_hcd_disable_endpoint(struct usb_device *udev,
 extern int usb_hcd_get_frame_number(struct usb_device *udev);
 
 extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver,
-               struct device *dev, char *bus_name);
+               struct device *dev, const char *bus_name);
 extern struct usb_hcd *usb_get_hcd(struct usb_hcd *hcd);
 extern void usb_put_hcd(struct usb_hcd *hcd);
 extern int usb_add_hcd(struct usb_hcd *hcd,
index 4cfe32a16c37fb689e8bab4796b6918a36728382..107e1d25ddec3fbe0a485191131dad985342c8ff 100644 (file)
@@ -72,7 +72,6 @@ struct usb_hub {
 
        unsigned                limited_power:1;
        unsigned                quiescing:1;
-       unsigned                activating:1;
        unsigned                disconnected:1;
 
        unsigned                has_indicators:1;
@@ -131,6 +130,12 @@ MODULE_PARM_DESC(use_both_schemes,
 DECLARE_RWSEM(ehci_cf_port_reset_rwsem);
 EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
 
+#define HUB_DEBOUNCE_TIMEOUT   1500
+#define HUB_DEBOUNCE_STEP        25
+#define HUB_DEBOUNCE_STABLE     100
+
+
+static int usb_reset_and_verify_device(struct usb_device *udev);
 
 static inline char *portspeed(int portstatus)
 {
@@ -535,37 +540,6 @@ static void hub_power_on(struct usb_hub *hub)
        msleep(max(pgood_delay, (unsigned) 100));
 }
 
-static void hub_quiesce(struct usb_hub *hub)
-{
-       /* (nonblocking) khubd and related activity won't re-trigger */
-       hub->quiescing = 1;
-       hub->activating = 0;
-
-       /* (blocking) stop khubd and related activity */
-       usb_kill_urb(hub->urb);
-       if (hub->has_indicators)
-               cancel_delayed_work_sync(&hub->leds);
-       if (hub->tt.hub)
-               cancel_work_sync(&hub->tt.kevent);
-}
-
-static void hub_activate(struct usb_hub *hub)
-{
-       int     status;
-
-       hub->quiescing = 0;
-       hub->activating = 1;
-
-       status = usb_submit_urb(hub->urb, GFP_NOIO);
-       if (status < 0)
-               dev_err(hub->intfdev, "activate --> %d\n", status);
-       if (hub->has_indicators && blinkenlights)
-               schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
-
-       /* scan all ports ASAP */
-       kick_khubd(hub);
-}
-
 static int hub_hub_status(struct usb_hub *hub,
                u16 *status, u16 *change)
 {
@@ -624,136 +598,149 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
        kick_khubd(hub);
 }
 
-/* caller has locked the hub device */
-static void hub_stop(struct usb_hub *hub)
+enum hub_activation_type {
+       HUB_INIT, HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME
+};
+
+static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 {
        struct usb_device *hdev = hub->hdev;
-       int i;
+       int port1;
+       int status;
+       bool need_debounce_delay = false;
 
-       /* Disconnect all the children */
-       for (i = 0; i < hdev->maxchild; ++i) {
-               if (hdev->children[i])
-                       usb_disconnect(&hdev->children[i]);
-       }
-       hub_quiesce(hub);
-}
+       /* After a resume, port power should still be on.
+        * For any other type of activation, turn it on.
+        */
+       if (type != HUB_RESUME)
+               hub_power_on(hub);
 
-#define HUB_RESET              1
-#define HUB_RESUME             2
-#define HUB_RESET_RESUME       3
+       /* Check each port and set hub->change_bits to let khubd know
+        * which ports need attention.
+        */
+       for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
+               struct usb_device *udev = hdev->children[port1-1];
+               u16 portstatus, portchange;
 
-#ifdef CONFIG_PM
+               portstatus = portchange = 0;
+               status = hub_port_status(hub, port1, &portstatus, &portchange);
+               if (udev || (portstatus & USB_PORT_STAT_CONNECTION))
+                       dev_dbg(hub->intfdev,
+                                       "port %d: status %04x change %04x\n",
+                                       port1, portstatus, portchange);
 
-/* Try to identify which devices need USB-PERSIST handling */
-static int persistent_device(struct usb_device *udev)
-{
-       int i;
-       int retval;
-       struct usb_host_config *actconfig;
+               /* After anything other than HUB_RESUME (i.e., initialization
+                * or any sort of reset), every port should be disabled.
+                * Unconnected ports should likewise be disabled (paranoia),
+                * and so should ports for which we have no usb_device.
+                */
+               if ((portstatus & USB_PORT_STAT_ENABLE) && (
+                               type != HUB_RESUME ||
+                               !(portstatus & USB_PORT_STAT_CONNECTION) ||
+                               !udev ||
+                               udev->state == USB_STATE_NOTATTACHED)) {
+                       clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
+                       portstatus &= ~USB_PORT_STAT_ENABLE;
+               }
 
-       /* Explicitly not marked persistent? */
-       if (!udev->persist_enabled)
-               return 0;
+               /* Clear status-change flags; we'll debounce later */
+               if (portchange & USB_PORT_STAT_C_CONNECTION) {
+                       need_debounce_delay = true;
+                       clear_port_feature(hub->hdev, port1,
+                                       USB_PORT_FEAT_C_CONNECTION);
+               }
+               if (portchange & USB_PORT_STAT_C_ENABLE) {
+                       need_debounce_delay = true;
+                       clear_port_feature(hub->hdev, port1,
+                                       USB_PORT_FEAT_C_ENABLE);
+               }
 
-       /* No active config? */
-       actconfig = udev->actconfig;
-       if (!actconfig)
-               return 0;
+               if (!udev || udev->state == USB_STATE_NOTATTACHED) {
+                       /* Tell khubd to disconnect the device or
+                        * check for a new connection
+                        */
+                       if (udev || (portstatus & USB_PORT_STAT_CONNECTION))
+                               set_bit(port1, hub->change_bits);
+
+               } else if (portstatus & USB_PORT_STAT_ENABLE) {
+                       /* The power session apparently survived the resume.
+                        * If there was an overcurrent or suspend change
+                        * (i.e., remote wakeup request), have khubd
+                        * take care of it.
+                        */
+                       if (portchange)
+                               set_bit(port1, hub->change_bits);
 
-       /* FIXME! We should check whether it's open here or not! */
+               } else if (udev->persist_enabled) {
+#ifdef CONFIG_PM
+                       udev->reset_resume = 1;
+#endif
+                       set_bit(port1, hub->change_bits);
 
-       /*
-        * Check that all the interface drivers have a
-        * 'reset_resume' entrypoint
+               } else {
+                       /* The power session is gone; tell khubd */
+                       usb_set_device_state(udev, USB_STATE_NOTATTACHED);
+                       set_bit(port1, hub->change_bits);
+               }
+       }
+
+       /* If no port-status-change flags were set, we don't need any
+        * debouncing.  If flags were set we can try to debounce the
+        * ports all at once right now, instead of letting khubd do them
+        * one at a time later on.
+        *
+        * If any port-status changes do occur during this delay, khubd
+        * will see them later and handle them normally.
         */
-       retval = 0;
-       for (i = 0; i < actconfig->desc.bNumInterfaces; i++) {
-               struct usb_interface *intf;
-               struct usb_driver *driver;
+       if (need_debounce_delay)
+               msleep(HUB_DEBOUNCE_STABLE);
 
-               intf = actconfig->interface[i];
-               if (!intf->dev.driver)
-                       continue;
-               driver = to_usb_driver(intf->dev.driver);
-               if (!driver->reset_resume)
-                       return 0;
-               /*
-                * We have at least one driver, and that one
-                * has a reset_resume method.
-                */
-               retval = 1;
-       }
-       return retval;
-}
+       hub->quiescing = 0;
 
-static void hub_restart(struct usb_hub *hub, int type)
-{
-       struct usb_device *hdev = hub->hdev;
-       int port1;
+       status = usb_submit_urb(hub->urb, GFP_NOIO);
+       if (status < 0)
+               dev_err(hub->intfdev, "activate --> %d\n", status);
+       if (hub->has_indicators && blinkenlights)
+               schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
 
-       /* Check each of the children to see if they require
-        * USB-PERSIST handling or disconnection.  Also check
-        * each unoccupied port to make sure it is still disabled.
-        */
-       for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
-               struct usb_device *udev = hdev->children[port1-1];
-               int status = 0;
-               u16 portstatus, portchange;
+       /* Scan all ports that need attention */
+       kick_khubd(hub);
+}
 
-               if (!udev || udev->state == USB_STATE_NOTATTACHED) {
-                       if (type != HUB_RESET) {
-                               status = hub_port_status(hub, port1,
-                                               &portstatus, &portchange);
-                               if (status == 0 && (portstatus &
-                                               USB_PORT_STAT_ENABLE))
-                                       clear_port_feature(hdev, port1,
-                                                       USB_PORT_FEAT_ENABLE);
-                       }
-                       continue;
-               }
+enum hub_quiescing_type {
+       HUB_DISCONNECT, HUB_PRE_RESET, HUB_SUSPEND
+};
 
-               /* Was the power session lost while we were suspended? */
-               status = hub_port_status(hub, port1, &portstatus, &portchange);
+static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
+{
+       struct usb_device *hdev = hub->hdev;
+       int i;
 
-               /* If the device is gone, khubd will handle it later */
-               if (status == 0 && !(portstatus & USB_PORT_STAT_CONNECTION))
-                       continue;
+       /* khubd and related activity won't re-trigger */
+       hub->quiescing = 1;
 
-               /* For "USB_PERSIST"-enabled children we must
-                * mark the child device for reset-resume and
-                * turn off the various status changes to prevent
-                * khubd from disconnecting it later.
-                */
-               if (status == 0 && !(portstatus & USB_PORT_STAT_ENABLE) &&
-                               persistent_device(udev)) {
-                       if (portchange & USB_PORT_STAT_C_ENABLE)
-                               clear_port_feature(hub->hdev, port1,
-                                               USB_PORT_FEAT_C_ENABLE);
-                       if (portchange & USB_PORT_STAT_C_CONNECTION)
-                               clear_port_feature(hub->hdev, port1,
-                                               USB_PORT_FEAT_C_CONNECTION);
-                       udev->reset_resume = 1;
+       if (type != HUB_SUSPEND) {
+               /* Disconnect all the children */
+               for (i = 0; i < hdev->maxchild; ++i) {
+                       if (hdev->children[i])
+                               usb_disconnect(&hdev->children[i]);
                }
-
-               /* Otherwise for a reset_resume we must disconnect the child,
-                * but as we may not lock the child device here
-                * we have to do a "logical" disconnect.
-                */
-               else if (type == HUB_RESET_RESUME)
-                       hub_port_logical_disconnect(hub, port1);
        }
 
-       hub_activate(hub);
+       /* Stop khubd and related activity */
+       usb_kill_urb(hub->urb);
+       if (hub->has_indicators)
+               cancel_delayed_work_sync(&hub->leds);
+       if (hub->tt.hub)
+               cancel_work_sync(&hub->tt.kevent);
 }
 
-#endif /* CONFIG_PM */
-
 /* caller has locked the hub device */
 static int hub_pre_reset(struct usb_interface *intf)
 {
        struct usb_hub *hub = usb_get_intfdata(intf);
 
-       hub_stop(hub);
+       hub_quiesce(hub, HUB_PRE_RESET);
        return 0;
 }
 
@@ -762,8 +749,7 @@ static int hub_post_reset(struct usb_interface *intf)
 {
        struct usb_hub *hub = usb_get_intfdata(intf);
 
-       hub_power_on(hub);
-       hub_activate(hub);
+       hub_activate(hub, HUB_POST_RESET);
        return 0;
 }
 
@@ -1009,8 +995,7 @@ static int hub_configure(struct usb_hub *hub,
        if (hub->has_indicators && blinkenlights)
                hub->indicator [0] = INDICATOR_CYCLE;
 
-       hub_power_on(hub);
-       hub_activate(hub);
+       hub_activate(hub, HUB_INIT);
        return 0;
 
 fail:
@@ -1042,7 +1027,7 @@ static void hub_disconnect(struct usb_interface *intf)
 
        /* Disconnect all children and quiesce the hub */
        hub->error = 0;
-       hub_stop(hub);
+       hub_quiesce(hub, HUB_DISCONNECT);
 
        usb_set_intfdata (intf, NULL);
 
@@ -1068,6 +1053,12 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
        desc = intf->cur_altsetting;
        hdev = interface_to_usbdev(intf);
 
+       if (hdev->level == MAX_TOPO_LEVEL) {
+               dev_err(&intf->dev, "Unsupported bus topology: "
+                               "hub nested too deep\n");
+               return -E2BIG;
+       }
+
 #ifdef CONFIG_USB_OTG_BLACKLIST_HUB
        if (hdev->parent) {
                dev_warn(&intf->dev, "ignoring external hub\n");
@@ -1814,6 +1805,51 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
 
 #ifdef CONFIG_PM
 
+#define MASK_BITS      (USB_PORT_STAT_POWER | USB_PORT_STAT_CONNECTION | \
+                               USB_PORT_STAT_SUSPEND)
+#define WANT_BITS      (USB_PORT_STAT_POWER | USB_PORT_STAT_CONNECTION)
+
+/* Determine whether the device on a port is ready for a normal resume,
+ * is ready for a reset-resume, or should be disconnected.
+ */
+static int check_port_resume_type(struct usb_device *udev,
+               struct usb_hub *hub, int port1,
+               int status, unsigned portchange, unsigned portstatus)
+{
+       /* Is the device still present? */
+       if (status || (portstatus & MASK_BITS) != WANT_BITS) {
+               if (status >= 0)
+                       status = -ENODEV;
+       }
+
+       /* Can't do a normal resume if the port isn't enabled,
+        * so try a reset-resume instead.
+        */
+       else if (!(portstatus & USB_PORT_STAT_ENABLE) && !udev->reset_resume) {
+               if (udev->persist_enabled)
+                       udev->reset_resume = 1;
+               else
+                       status = -ENODEV;
+       }
+
+       if (status) {
+               dev_dbg(hub->intfdev,
+                               "port %d status %04x.%04x after resume, %d\n",
+                               port1, portchange, portstatus, status);
+       } else if (udev->reset_resume) {
+
+               /* Late port handoff can set status-change bits */
+               if (portchange & USB_PORT_STAT_C_CONNECTION)
+                       clear_port_feature(hub->hdev, port1,
+                                       USB_PORT_FEAT_C_CONNECTION);
+               if (portchange & USB_PORT_STAT_C_ENABLE)
+                       clear_port_feature(hub->hdev, port1,
+                                       USB_PORT_FEAT_C_ENABLE);
+       }
+
+       return status;
+}
+
 #ifdef CONFIG_USB_SUSPEND
 
 /*
@@ -1943,7 +1979,8 @@ static int finish_port_resume(struct usb_device *udev)
         * resumed.
         */
        if (udev->reset_resume)
-               status = usb_reset_device(udev);
+ retry_reset_resume:
+               status = usb_reset_and_verify_device(udev);
 
        /* 10.5.4.5 says be sure devices in the tree are still there.
         * For now let's assume the device didn't go crazy on resume,
@@ -1954,6 +1991,13 @@ static int finish_port_resume(struct usb_device *udev)
                status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
                if (status >= 0)
                        status = (status > 0 ? 0 : -ENODEV);
+
+               /* If a normal resume failed, try doing a reset-resume */
+               if (status && !udev->reset_resume && udev->persist_enabled) {
+                       dev_dbg(&udev->dev, "retry with reset-resume\n");
+                       udev->reset_resume = 1;
+                       goto retry_reset_resume;
+               }
        }
 
        if (status) {
@@ -2002,7 +2046,7 @@ static int finish_port_resume(struct usb_device *udev)
  * to it will be lost.  Using the USB_PERSIST facility, the device can be
  * made to appear as if it had not disconnected.
  *
- * This facility can be dangerous.  Although usb_reset_device() makes
+ * This facility can be dangerous.  Although usb_reset_and_verify_device() makes
  * every effort to insure that the same device is present after the
  * reset as before, it cannot provide a 100% guarantee.  Furthermore it's
  * quite possible for a device to remain unaltered but its media to be
@@ -2018,7 +2062,6 @@ int usb_port_resume(struct usb_device *udev)
        int             port1 = udev->portnum;
        int             status;
        u16             portchange, portstatus;
-       unsigned        mask_flags, want_flags;
 
        /* Skip the initial Clear-Suspend step for a remote wakeup */
        status = hub_port_status(hub, port1, &portstatus, &portchange);
@@ -2047,35 +2090,23 @@ int usb_port_resume(struct usb_device *udev)
                 */
                status = hub_port_status(hub, port1, &portstatus, &portchange);
 
- SuspendCleared:
-               if (udev->reset_resume)
-                       want_flags = USB_PORT_STAT_POWER
-                                       | USB_PORT_STAT_CONNECTION;
-               else
-                       want_flags = USB_PORT_STAT_POWER
-                                       | USB_PORT_STAT_CONNECTION
-                                       | USB_PORT_STAT_ENABLE;
-               mask_flags = want_flags | USB_PORT_STAT_SUSPEND;
+               /* TRSMRCY = 10 msec */
+               msleep(10);
+       }
 
-               if (status < 0 || (portstatus & mask_flags) != want_flags) {
-                       dev_dbg(hub->intfdev,
-                               "port %d status %04x.%04x after resume, %d\n",
-                               port1, portchange, portstatus, status);
-                       if (status >= 0)
-                               status = -ENODEV;
-               } else {
-                       if (portchange & USB_PORT_STAT_C_SUSPEND)
-                               clear_port_feature(hub->hdev, port1,
-                                               USB_PORT_FEAT_C_SUSPEND);
-                       /* TRSMRCY = 10 msec */
-                       msleep(10);
-               }
+ SuspendCleared:
+       if (status == 0) {
+               if (portchange & USB_PORT_STAT_C_SUSPEND)
+                       clear_port_feature(hub->hdev, port1,
+                                       USB_PORT_FEAT_C_SUSPEND);
        }
 
        clear_bit(port1, hub->busy_bits);
        if (!hub->hdev->parent && !hub->busy_bits[0])
                usb_enable_root_hub_irq(hub->hdev->bus);
 
+       status = check_port_resume_type(udev,
+                       hub, port1, status, portchange, portstatus);
        if (status == 0)
                status = finish_port_resume(udev);
        if (status < 0) {
@@ -2085,17 +2116,16 @@ int usb_port_resume(struct usb_device *udev)
        return status;
 }
 
+/* caller has locked udev */
 static int remote_wakeup(struct usb_device *udev)
 {
        int     status = 0;
 
-       usb_lock_device(udev);
        if (udev->state == USB_STATE_SUSPENDED) {
                dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-");
                usb_mark_last_busy(udev);
                status = usb_external_resume_device(udev);
        }
-       usb_unlock_device(udev);
        return status;
 }
 
@@ -2108,14 +2138,25 @@ int usb_port_suspend(struct usb_device *udev)
        return 0;
 }
 
+/* However we may need to do a reset-resume */
+
 int usb_port_resume(struct usb_device *udev)
 {
-       int status = 0;
+       struct usb_hub  *hub = hdev_to_hub(udev->parent);
+       int             port1 = udev->portnum;
+       int             status;
+       u16             portchange, portstatus;
 
-       /* However we may need to do a reset-resume */
-       if (udev->reset_resume) {
+       status = hub_port_status(hub, port1, &portstatus, &portchange);
+       status = check_port_resume_type(udev,
+                       hub, port1, status, portchange, portstatus);
+
+       if (status) {
+               dev_dbg(&udev->dev, "can't resume, status %d\n", status);
+               hub_port_logical_disconnect(hub, port1);
+       } else if (udev->reset_resume) {
                dev_dbg(&udev->dev, "reset-resume\n");
-               status = usb_reset_device(udev);
+               status = usb_reset_and_verify_device(udev);
        }
        return status;
 }
@@ -2149,7 +2190,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
        dev_dbg(&intf->dev, "%s\n", __func__);
 
        /* stop khubd and related activity */
-       hub_quiesce(hub);
+       hub_quiesce(hub, HUB_SUSPEND);
        return 0;
 }
 
@@ -2158,7 +2199,7 @@ static int hub_resume(struct usb_interface *intf)
        struct usb_hub *hub = usb_get_intfdata(intf);
 
        dev_dbg(&intf->dev, "%s\n", __func__);
-       hub_restart(hub, HUB_RESUME);
+       hub_activate(hub, HUB_RESUME);
        return 0;
 }
 
@@ -2167,8 +2208,7 @@ static int hub_reset_resume(struct usb_interface *intf)
        struct usb_hub *hub = usb_get_intfdata(intf);
 
        dev_dbg(&intf->dev, "%s\n", __func__);
-       hub_power_on(hub);
-       hub_restart(hub, HUB_RESET_RESUME);
+       hub_activate(hub, HUB_RESET_RESUME);
        return 0;
 }
 
@@ -2218,11 +2258,6 @@ static inline int remote_wakeup(struct usb_device *udev)
  * every 25ms for transient disconnects.  When the port status has been
  * unchanged for 100ms it returns the port status.
  */
-
-#define HUB_DEBOUNCE_TIMEOUT   1500
-#define HUB_DEBOUNCE_STEP        25
-#define HUB_DEBOUNCE_STABLE     100
-
 static int hub_port_debounce(struct usb_hub *hub, int port1)
 {
        int ret;
@@ -2302,7 +2337,7 @@ static int hub_set_address(struct usb_device *udev, int devnum)
  * Returns device in USB_STATE_ADDRESS, except on error.
  *
  * If this is called for an already-existing device (as part of
- * usb_reset_device), the caller must own the device lock.  For a
+ * usb_reset_and_verify_device), the caller must own the device lock.  For a
  * newly detected device that is not accessible through any global
  * pointers, it's not necessary to lock the device.
  */
@@ -2619,7 +2654,7 @@ hub_power_remaining (struct usb_hub *hub)
  * This routine is called when:
  *     a port connection-change occurs;
  *     a port enable-change occurs (often caused by EMI);
- *     usb_reset_device() encounters changed descriptors (as from
+ *     usb_reset_and_verify_device() encounters changed descriptors (as from
  *             a firmware download)
  * caller already locked the hub
  */
@@ -2629,9 +2664,11 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
        struct usb_device *hdev = hub->hdev;
        struct device *hub_dev = hub->intfdev;
        struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
-       u16 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
+       unsigned wHubCharacteristics =
+                       le16_to_cpu(hub->descriptor->wHubCharacteristics);
+       struct usb_device *udev;
        int status, i;
+
        dev_dbg (hub_dev,
                "port %d, status %04x, change %04x, %s\n",
                port1, portstatus, portchange, portspeed (portstatus));
@@ -2640,30 +2677,73 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                set_port_led(hub, port1, HUB_LED_AUTO);
                hub->indicator[port1-1] = INDICATOR_AUTO;
        }
-       /* Disconnect any existing devices under this port */
-       if (hdev->children[port1-1])
-               usb_disconnect(&hdev->children[port1-1]);
-       clear_bit(port1, hub->change_bits);
 
 #ifdef CONFIG_USB_OTG
        /* during HNP, don't repeat the debounce */
        if (hdev->bus->is_b_host)
-               portchange &= ~USB_PORT_STAT_C_CONNECTION;
+               portchange &= ~(USB_PORT_STAT_C_CONNECTION |
+                               USB_PORT_STAT_C_ENABLE);
 #endif
 
-       if (portchange & USB_PORT_STAT_C_CONNECTION) {
+       /* Try to use the debounce delay for protection against
+        * port-enable changes caused, for example, by EMI.
+        */
+       if (portchange & (USB_PORT_STAT_C_CONNECTION |
+                               USB_PORT_STAT_C_ENABLE)) {
                status = hub_port_debounce(hub, port1);
                if (status < 0) {
                        if (printk_ratelimit())
                                dev_err (hub_dev, "connect-debounce failed, "
                                                "port %d disabled\n", port1);
-                       goto done;
+                       portstatus &= ~USB_PORT_STAT_CONNECTION;
+               } else {
+                       portstatus = status;
+               }
+       }
+
+       /* Try to resuscitate an existing device */
+       udev = hdev->children[port1-1];
+       if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
+                       udev->state != USB_STATE_NOTATTACHED) {
+
+               usb_lock_device(udev);
+               if (portstatus & USB_PORT_STAT_ENABLE) {
+                       status = 0;             /* Nothing to do */
+               } else if (!udev->persist_enabled) {
+                       status = -ENODEV;       /* Mustn't resuscitate */
+
+#ifdef CONFIG_USB_SUSPEND
+               } else if (udev->state == USB_STATE_SUSPENDED) {
+                       /* For a suspended device, treat this as a
+                        * remote wakeup event.
+                        */
+                       if (udev->do_remote_wakeup)
+                               status = remote_wakeup(udev);
+
+                       /* Otherwise leave it be; devices can't tell the
+                        * difference between suspended and disabled.
+                        */
+                       else
+                               status = 0;
+#endif
+
+               } else {
+                       status = usb_reset_device(udev);
+               }
+               usb_unlock_device(udev);
+
+               if (status == 0) {
+                       clear_bit(port1, hub->change_bits);
+                       return;
                }
-               portstatus = status;
        }
 
-       /* Return now if nothing is connected */
+       /* Disconnect any existing devices under this port */
+       if (udev)
+               usb_disconnect(&hdev->children[port1-1]);
+       clear_bit(port1, hub->change_bits);
+
+       /* Return now if debouncing failed or nothing is connected */
        if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
 
                /* maybe switch power back on (e.g. root hub was reset) */
@@ -2677,7 +2757,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
        }
 
        for (i = 0; i < SET_CONFIG_TRIES; i++) {
-               struct usb_device *udev;
 
                /* reallocate for each attempt, since references
                 * to the previous one can escape in various ways
@@ -2858,7 +2937,7 @@ static void hub_events(void)
                /* If the hub has died, clean up after it */
                if (hdev->state == USB_STATE_NOTATTACHED) {
                        hub->error = -ENODEV;
-                       hub_stop(hub);
+                       hub_quiesce(hub, HUB_DISCONNECT);
                        goto loop;
                }
 
@@ -2877,7 +2956,7 @@ static void hub_events(void)
                        dev_dbg (hub_dev, "resetting for error %d\n",
                                hub->error);
 
-                       ret = usb_reset_composite_device(hdev, intf);
+                       ret = usb_reset_device(hdev);
                        if (ret) {
                                dev_dbg (hub_dev,
                                        "error resetting hub: %d\n", ret);
@@ -2894,7 +2973,7 @@ static void hub_events(void)
                                continue;
                        connect_change = test_bit(i, hub->change_bits);
                        if (!test_and_clear_bit(i, hub->event_bits) &&
-                                       !connect_change && !hub->activating)
+                                       !connect_change)
                                continue;
 
                        ret = hub_port_status(hub, i,
@@ -2902,11 +2981,6 @@ static void hub_events(void)
                        if (ret < 0)
                                continue;
 
-                       if (hub->activating && !hdev->children[i-1] &&
-                                       (portstatus &
-                                               USB_PORT_STAT_CONNECTION))
-                               connect_change = 1;
-
                        if (portchange & USB_PORT_STAT_C_CONNECTION) {
                                clear_port_feature(hdev, i,
                                        USB_PORT_FEAT_C_CONNECTION);
@@ -2941,11 +3015,16 @@ static void hub_events(void)
                        }
 
                        if (portchange & USB_PORT_STAT_C_SUSPEND) {
+                               struct usb_device *udev;
+
                                clear_port_feature(hdev, i,
                                        USB_PORT_FEAT_C_SUSPEND);
-                               if (hdev->children[i-1]) {
+                               udev = hdev->children[i-1];
+                               if (udev) {
+                                       usb_lock_device(udev);
                                        ret = remote_wakeup(hdev->
                                                        children[i-1]);
+                                       usb_unlock_device(udev);
                                        if (ret < 0)
                                                connect_change = 1;
                                } else {
@@ -3002,8 +3081,6 @@ static void hub_events(void)
                        }
                }
 
-               hub->activating = 0;
-
                /* If this is a root hub, tell the HCD it's okay to
                 * re-enable port-change interrupts now. */
                if (!hdev->parent && !hub->busy_bits[0])
@@ -3172,12 +3249,12 @@ static int descriptors_changed(struct usb_device *udev,
 }
 
 /**
- * usb_reset_device - perform a USB port reset to reinitialize a device
+ * usb_reset_and_verify_device - perform a USB port reset to reinitialize a device
  * @udev: device to reset (not in SUSPENDED or NOTATTACHED state)
  *
  * WARNING - don't use this routine to reset a composite device
  * (one with multiple interfaces owned by separate drivers)!
- * Use usb_reset_composite_device() instead.
+ * Use usb_reset_device() instead.
  *
  * Do a port reset, reassign the device's address, and establish its
  * former operating configuration.  If the reset fails, or the device's
@@ -3201,7 +3278,7 @@ static int descriptors_changed(struct usb_device *udev,
  * holding the device lock because these tasks should always call
  * usb_autopm_resume_device(), thereby preventing any unwanted autoresume.
  */
-int usb_reset_device(struct usb_device *udev)
+static int usb_reset_and_verify_device(struct usb_device *udev)
 {
        struct usb_device               *parent_hdev = udev->parent;
        struct usb_hub                  *parent_hub;
@@ -3289,26 +3366,28 @@ re_enumerate:
        hub_port_logical_disconnect(parent_hub, port1);
        return -ENODEV;
 }
-EXPORT_SYMBOL_GPL(usb_reset_device);
 
 /**
- * usb_reset_composite_device - warn interface drivers and perform a USB port reset
+ * usb_reset_device - warn interface drivers and perform a USB port reset
  * @udev: device to reset (not in SUSPENDED or NOTATTACHED state)
- * @iface: interface bound to the driver making the request (optional)
  *
  * Warns all drivers bound to registered interfaces (using their pre_reset
  * method), performs the port reset, and then lets the drivers know that
  * the reset is over (using their post_reset method).
  *
- * Return value is the same as for usb_reset_device().
+ * Return value is the same as for usb_reset_and_verify_device().
  *
  * The caller must own the device lock.  For example, it's safe to use
  * this from a driver probe() routine after downloading new firmware.
  * For calls that might not occur during probe(), drivers should lock
  * the device using usb_lock_device_for_reset().
+ *
+ * If an interface is currently being probed or disconnected, we assume
+ * its driver knows how to handle resets.  For all other interfaces,
+ * if the driver doesn't have pre_reset and post_reset methods then
+ * we attempt to unbind it and rebind afterward.
  */
-int usb_reset_composite_device(struct usb_device *udev,
-               struct usb_interface *iface)
+int usb_reset_device(struct usb_device *udev)
 {
        int ret;
        int i;
@@ -3324,40 +3403,47 @@ int usb_reset_composite_device(struct usb_device *udev,
        /* Prevent autosuspend during the reset */
        usb_autoresume_device(udev);
 
-       if (iface && iface->condition != USB_INTERFACE_BINDING)
-               iface = NULL;
-
        if (config) {
                for (i = 0; i < config->desc.bNumInterfaces; ++i) {
                        struct usb_interface *cintf = config->interface[i];
                        struct usb_driver *drv;
+                       int unbind = 0;
 
                        if (cintf->dev.driver) {
                                drv = to_usb_driver(cintf->dev.driver);
-                               if (drv->pre_reset)
-                                       (drv->pre_reset)(cintf);
-       /* FIXME: Unbind if pre_reset returns an error or isn't defined */
+                               if (drv->pre_reset && drv->post_reset)
+                                       unbind = (drv->pre_reset)(cintf);
+                               else if (cintf->condition ==
+                                               USB_INTERFACE_BOUND)
+                                       unbind = 1;
+                               if (unbind)
+                                       usb_forced_unbind_intf(cintf);
                        }
                }
        }
 
-       ret = usb_reset_device(udev);
+       ret = usb_reset_and_verify_device(udev);
 
        if (config) {
                for (i = config->desc.bNumInterfaces - 1; i >= 0; --i) {
                        struct usb_interface *cintf = config->interface[i];
                        struct usb_driver *drv;
+                       int rebind = cintf->needs_binding;
 
-                       if (cintf->dev.driver) {
+                       if (!rebind && cintf->dev.driver) {
                                drv = to_usb_driver(cintf->dev.driver);
                                if (drv->post_reset)
-                                       (drv->post_reset)(cintf);
-       /* FIXME: Unbind if post_reset returns an error or isn't defined */
+                                       rebind = (drv->post_reset)(cintf);
+                               else if (cintf->condition ==
+                                               USB_INTERFACE_BOUND)
+                                       rebind = 1;
                        }
+                       if (rebind)
+                               usb_rebind_intf(cintf);
                }
        }
 
        usb_autosuspend_device(udev);
        return ret;
 }
-EXPORT_SYMBOL_GPL(usb_reset_composite_device);
+EXPORT_SYMBOL_GPL(usb_reset_device);
index 1d253dd4ea8143040b4175286331d349a95a1e9c..db410e92c80da6f9d489ce77fe3942e4b414fc64 100644 (file)
@@ -712,25 +712,11 @@ static void usbfs_add_device(struct usb_device *dev)
 
 static void usbfs_remove_device(struct usb_device *dev)
 {
-       struct dev_state *ds;
-       struct siginfo sinfo;
-
        if (dev->usbfs_dentry) {
                fs_remove_file (dev->usbfs_dentry);
                dev->usbfs_dentry = NULL;
        }
-       while (!list_empty(&dev->filelist)) {
-               ds = list_entry(dev->filelist.next, struct dev_state, list);
-               wake_up_all(&ds->wait);
-               list_del_init(&ds->list);
-               if (ds->discsignr) {
-                       sinfo.si_signo = ds->discsignr;
-                       sinfo.si_errno = EPIPE;
-                       sinfo.si_code = SI_ASYNCIO;
-                       sinfo.si_addr = ds->disccontext;
-                       kill_pid_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid, ds->secid);
-               }
-       }
+       usb_fs_classdev_common_remove(dev);
 }
 
 static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev)
index fe47d145255ae95f248dbe6825c9abc7836e1bb8..2fcc06eb5e60a8f9fc982c844113ebf193f62aed 100644 (file)
@@ -400,7 +400,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,
        if (usb_pipein(pipe))
                urb_flags |= URB_SHORT_NOT_OK;
 
-       for (i = 0; i < io->entries; i++) {
+       for_each_sg(sg, sg, io->entries, i) {
                unsigned len;
 
                io->urbs[i] = usb_alloc_urb(0, mem_flags);
@@ -434,17 +434,17 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,
                 * to prevent stale pointers and to help spot bugs.
                 */
                if (dma) {
-                       io->urbs[i]->transfer_dma = sg_dma_address(sg + i);
-                       len = sg_dma_len(sg + i);
+                       io->urbs[i]->transfer_dma = sg_dma_address(sg);
+                       len = sg_dma_len(sg);
 #if defined(CONFIG_HIGHMEM) || defined(CONFIG_GART_IOMMU)
                        io->urbs[i]->transfer_buffer = NULL;
 #else
-                       io->urbs[i]->transfer_buffer = sg_virt(&sg[i]);
+                       io->urbs[i]->transfer_buffer = sg_virt(sg);
 #endif
                } else {
                        /* hc may use _only_ transfer_buffer */
-                       io->urbs[i]->transfer_buffer = sg_virt(&sg[i]);
-                       len = sg[i].length;
+                       io->urbs[i]->transfer_buffer = sg_virt(sg);
+                       len = sg->length;
                }
 
                if (length) {
@@ -1090,7 +1090,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
                        if (!device_is_registered(&interface->dev))
                                continue;
                        dev_dbg(&dev->dev, "unregistering interface %s\n",
-                               interface->dev.bus_id);
+                               dev_name(&interface->dev));
                        device_del(&interface->dev);
                        usb_remove_sysfs_intf_files(interface);
                }
@@ -1476,7 +1476,7 @@ static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev,
  *
  * This call is synchronous. The calling context must be able to sleep,
  * must own the device lock, and must not hold the driver model's USB
- * bus mutex; usb device driver probe() methods cannot use this routine.
+ * bus mutex; usb interface driver probe() methods cannot use this routine.
  *
  * Returns zero on success, or else the status code returned by the
  * underlying call that failed.  On successful completion, each interface
@@ -1611,7 +1611,7 @@ free_interfaces:
                intf->dev.dma_mask = dev->dev.dma_mask;
                device_initialize(&intf->dev);
                mark_quiesced(intf);
-               sprintf(&intf->dev.bus_id[0], "%d-%s:%d.%d",
+               dev_set_name(&intf->dev, "%d-%s:%d.%d",
                        dev->bus->busnum, dev->devpath,
                        configuration, alt->desc.bInterfaceNumber);
        }
@@ -1631,12 +1631,12 @@ free_interfaces:
 
                dev_dbg(&dev->dev,
                        "adding %s (config #%d, interface %d)\n",
-                       intf->dev.bus_id, configuration,
+                       dev_name(&intf->dev), configuration,
                        intf->cur_altsetting->desc.bInterfaceNumber);
                ret = device_add(&intf->dev);
                if (ret != 0) {
                        dev_err(&dev->dev, "device_add(%s) --> %d\n",
-                               intf->dev.bus_id, ret);
+                               dev_name(&intf->dev), ret);
                        continue;
                }
                usb_create_sysfs_intf_files(intf);
index 325774375837e5f1c578c7c402fd7bffaf18960a..84fcaa6a21ec285e85ab309bfc0b4be728f62caa 100644 (file)
@@ -308,7 +308,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
         * by location for diagnostics, tools, driver model, etc.  The
         * string is a path along hub ports, from the root.  Each device's
         * dev->devpath will be stable until USB is re-cabled, and hubs
-        * are often labeled with these port numbers.  The bus_id isn't
+        * are often labeled with these port numbers.  The name isn't
         * as stable:  bus->busnum changes easily from modprobe order,
         * cardbus or pci hotplugging, and so on.
         */
@@ -316,7 +316,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
                dev->devpath[0] = '0';
 
                dev->dev.parent = bus->controller;
-               sprintf(&dev->dev.bus_id[0], "usb%d", bus->busnum);
+               dev_set_name(&dev->dev, "usb%d", bus->busnum);
                root_hub = 1;
        } else {
                /* match any labeling on the hubs; it's one-based */
@@ -328,8 +328,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
                                "%s.%d", parent->devpath, port1);
 
                dev->dev.parent = &parent->dev;
-               sprintf(&dev->dev.bus_id[0], "%d-%s",
-                       bus->busnum, dev->devpath);
+               dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath);
 
                /* hub driver sets up TT records */
        }
index 1a8bc21c335e8848ebe5c2c1947fd5c0c38cd775..d9a6e16dbf842fbb645117eb57093b429ce9c6e0 100644 (file)
@@ -29,6 +29,8 @@ extern int usb_choose_configuration(struct usb_device *udev);
 extern void usb_kick_khubd(struct usb_device *dev);
 extern int usb_match_device(struct usb_device *dev,
                            const struct usb_device_id *id);
+extern void usb_forced_unbind_intf(struct usb_interface *intf);
+extern void usb_rebind_intf(struct usb_interface *intf);
 
 extern int  usb_hub_init(void);
 extern void usb_hub_cleanup(void);
@@ -140,26 +142,11 @@ extern struct usb_driver usbfs_driver;
 extern const struct file_operations usbfs_devices_fops;
 extern const struct file_operations usbdev_file_operations;
 extern void usbfs_conn_disc_event(void);
+extern void usb_fs_classdev_common_remove(struct usb_device *udev);
 
 extern int usb_devio_init(void);
 extern void usb_devio_cleanup(void);
 
-struct dev_state {
-       struct list_head list;      /* state list */
-       struct usb_device *dev;
-       struct file *file;
-       spinlock_t lock;            /* protects the async urb lists */
-       struct list_head async_pending;
-       struct list_head async_completed;
-       wait_queue_head_t wait;     /* wake up if a request completed */
-       unsigned int discsignr;
-       struct pid *disc_pid;
-       uid_t disc_uid, disc_euid;
-       void __user *disccontext;
-       unsigned long ifclaimed;
-       u32 secid;
-};
-
 /* internal notify stuff */
 extern void usb_notify_add_device(struct usb_device *udev);
 extern void usb_notify_remove_device(struct usb_device *udev);
index d6bab0d5f453ba458eec51e044f40e72a5e96a7f..c6a8c6b1116a45381d5ee4acb98bbda541d36ae8 100644 (file)
@@ -586,6 +586,20 @@ config USB_G_PRINTER
          For more information, see Documentation/usb/gadget_printer.txt
          which includes sample code for accessing the device file.
 
+config USB_CDC_COMPOSITE
+       tristate "CDC Composite Device (Ethernet and ACM)"
+       depends on NET
+       help
+         This driver provides two functions in one configuration:
+         a CDC Ethernet (ECM) link, and a CDC ACM (serial port) link.
+
+         This driver requires four bulk and two interrupt endpoints,
+         plus the ability to handle altsettings.  Not all peripheral
+         controllers are that capable.
+
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module.
+
 # put drivers that need isochronous transfer support (for audio
 # or video class gadget drivers), or specific hardware, here.
 
index e258afd25fafaec2316596b7d695a1159e8d4f07..fcb5cb9094d905d7e26c35a7dae074fc28b633bd 100644 (file)
@@ -22,18 +22,22 @@ obj-$(CONFIG_USB_M66592)    += m66592-udc.o
 #
 # USB gadget drivers
 #
-g_zero-objs                    := zero.o usbstring.o config.o epautoconf.o
-g_ether-objs                   := ether.o usbstring.o config.o epautoconf.o
-g_serial-objs                  := serial.o usbstring.o config.o epautoconf.o
+C_UTILS =      composite.o usbstring.o config.o epautoconf.o
+
+g_zero-objs                    := zero.o f_sourcesink.o f_loopback.o $(C_UTILS)
+g_ether-objs                   := ether.o u_ether.o f_subset.o f_ecm.o $(C_UTILS)
+g_serial-objs                  := serial.o u_serial.o f_acm.o f_serial.o $(C_UTILS)
 g_midi-objs                    := gmidi.o usbstring.o config.o epautoconf.o
 gadgetfs-objs                  := inode.o
 g_file_storage-objs            := file_storage.o usbstring.o config.o \
                                        epautoconf.o
 g_printer-objs                 := printer.o usbstring.o config.o \
                                        epautoconf.o
+g_cdc-objs                     := cdc2.o u_ether.o f_ecm.o \
+                                       u_serial.o f_acm.o $(C_UTILS)
 
 ifeq ($(CONFIG_USB_ETH_RNDIS),y)
-       g_ether-objs            += rndis.o
+       g_ether-objs            += f_rndis.o rndis.o
 endif
  
 obj-$(CONFIG_USB_ZERO)         += g_zero.o
@@ -43,4 +47,5 @@ obj-$(CONFIG_USB_FILE_STORAGE)        += g_file_storage.o
 obj-$(CONFIG_USB_G_SERIAL)     += g_serial.o
 obj-$(CONFIG_USB_G_PRINTER)    += g_printer.o
 obj-$(CONFIG_USB_MIDI_GADGET)  += g_midi.o
+obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o
 
index f261d2a9a5f00bafd2e02f6cb4b119378773c04a..1500e1b3c30289af26bdc9400c59845129aaa9d1 100644 (file)
@@ -3342,7 +3342,7 @@ static int udc_probe(struct udc *dev)
        spin_lock_init(&dev->lock);
        dev->gadget.ops = &udc_ops;
 
-       strcpy(dev->gadget.dev.bus_id, "gadget");
+       dev_set_name(&dev->gadget.dev, "gadget");
        dev->gadget.dev.release = gadget_release;
        dev->gadget.name = name;
        dev->gadget.name = name;
index b6b2a0a5ba376e3310ddd0b2133f16b78d35b03a..e2d8a5d86c40d079ad82a07ef3514ae8d178b08b 100644 (file)
@@ -1687,6 +1687,19 @@ static int __init at91udc_probe(struct platform_device *pdev)
                                udc->board.pullup_active_low);
        }
 
+       /* newer chips have more FIFO memory than rm9200 */
+       if (cpu_is_at91sam9260()) {
+               udc->ep[0].maxpacket = 64;
+               udc->ep[3].maxpacket = 64;
+               udc->ep[4].maxpacket = 512;
+               udc->ep[5].maxpacket = 512;
+       } else if (cpu_is_at91sam9261()) {
+               udc->ep[3].maxpacket = 64;
+       } else if (cpu_is_at91sam9263()) {
+               udc->ep[0].maxpacket = 64;
+               udc->ep[3].maxpacket = 64;
+       }
+
        udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1);
        if (!udc->udp_baseaddr) {
                retval = -ENOMEM;
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
new file mode 100644 (file)
index 0000000..d490d02
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * cdc2.c -- CDC Composite driver, with ECM and ACM support
+ *
+ * Copyright (C) 2008 David Brownell
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/utsname.h>
+
+#include "u_ether.h"
+#include "u_serial.h"
+
+
+#define DRIVER_DESC            "CDC Composite Gadget"
+#define DRIVER_VERSION         "King Kamehameha Day 2008"
+
+/*-------------------------------------------------------------------------*/
+
+/* DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
+ * Instead:  allocate your own, using normal USB-IF procedures.
+ */
+
+/* Thanks to NetChip Technologies for donating this product ID.
+ * It's for devices with only this composite CDC configuration.
+ */
+#define CDC_VENDOR_NUM         0x0525  /* NetChip */
+#define CDC_PRODUCT_NUM                0xa4aa  /* CDC Composite: ECM + ACM */
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_device_descriptor device_desc = {
+       .bLength =              sizeof device_desc,
+       .bDescriptorType =      USB_DT_DEVICE,
+
+       .bcdUSB =               __constant_cpu_to_le16(0x0200),
+
+       .bDeviceClass =         USB_CLASS_COMM,
+       .bDeviceSubClass =      0,
+       .bDeviceProtocol =      0,
+       /* .bMaxPacketSize0 = f(hardware) */
+
+       /* Vendor and product id can be overridden by module parameters.  */
+       .idVendor =             __constant_cpu_to_le16(CDC_VENDOR_NUM),
+       .idProduct =            __constant_cpu_to_le16(CDC_PRODUCT_NUM),
+       /* .bcdDevice = f(hardware) */
+       /* .iManufacturer = DYNAMIC */
+       /* .iProduct = DYNAMIC */
+       /* NO SERIAL NUMBER */
+       .bNumConfigurations =   1,
+};
+
+static struct usb_otg_descriptor otg_descriptor = {
+       .bLength =              sizeof otg_descriptor,
+       .bDescriptorType =      USB_DT_OTG,
+
+       /* REVISIT SRP-only hardware is possible, although
+        * it would not be called "OTG" ...
+        */
+       .bmAttributes =         USB_OTG_SRP | USB_OTG_HNP,
+};
+
+static const struct usb_descriptor_header *otg_desc[] = {
+       (struct usb_descriptor_header *) &otg_descriptor,
+       NULL,
+};
+
+
+/* string IDs are assigned dynamically */
+
+#define STRING_MANUFACTURER_IDX                0
+#define STRING_PRODUCT_IDX             1
+
+static char manufacturer[50];
+
+static struct usb_string strings_dev[] = {
+       [STRING_MANUFACTURER_IDX].s = manufacturer,
+       [STRING_PRODUCT_IDX].s = DRIVER_DESC,
+       {  } /* end of list */
+};
+
+static struct usb_gadget_strings stringtab_dev = {
+       .language       = 0x0409,       /* en-us */
+       .strings        = strings_dev,
+};
+
+static struct usb_gadget_strings *dev_strings[] = {
+       &stringtab_dev,
+       NULL,
+};
+
+static u8 hostaddr[ETH_ALEN];
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * We _always_ have both CDC ECM and CDC ACM functions.
+ */
+static int __init cdc_do_config(struct usb_configuration *c)
+{
+       int     status;
+
+       if (gadget_is_otg(c->cdev->gadget)) {
+               c->descriptors = otg_desc;
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+
+       status = ecm_bind_config(c, hostaddr);
+       if (status < 0)
+               return status;
+
+       status = acm_bind_config(c, 0);
+       if (status < 0)
+               return status;
+
+       return 0;
+}
+
+static struct usb_configuration cdc_config_driver = {
+       .label                  = "CDC Composite (ECM + ACM)",
+       .bind                   = cdc_do_config,
+       .bConfigurationValue    = 1,
+       /* .iConfiguration = DYNAMIC */
+       .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
+       .bMaxPower              = 1,    /* 2 mA, minimal */
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int __init cdc_bind(struct usb_composite_dev *cdev)
+{
+       int                     gcnum;
+       struct usb_gadget       *gadget = cdev->gadget;
+       int                     status;
+
+       if (!can_support_ecm(cdev->gadget)) {
+               ERROR(cdev, "controller '%s' not usable\n", gadget->name);
+               return -EINVAL;
+       }
+
+       /* set up network link layer */
+       status = gether_setup(cdev->gadget, hostaddr);
+       if (status < 0)
+               return status;
+
+       /* set up serial link layer */
+       status = gserial_setup(cdev->gadget, 1);
+       if (status < 0)
+               goto fail0;
+
+       gcnum = usb_gadget_controller_number(gadget);
+       if (gcnum >= 0)
+               device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
+       else {
+               /* We assume that can_support_ecm() tells the truth;
+                * but if the controller isn't recognized at all then
+                * that assumption is a bit more likely to be wrong.
+                */
+               WARN(cdev, "controller '%s' not recognized; trying %s\n",
+                               gadget->name,
+                               cdc_config_driver.label);
+               device_desc.bcdDevice =
+                       __constant_cpu_to_le16(0x0300 | 0x0099);
+       }
+
+
+       /* Allocate string descriptor numbers ... note that string
+        * contents can be overridden by the composite_dev glue.
+        */
+
+       /* device descriptor strings: manufacturer, product */
+       snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
+               init_utsname()->sysname, init_utsname()->release,
+               gadget->name);
+       status = usb_string_id(cdev);
+       if (status < 0)
+               goto fail1;
+       strings_dev[STRING_MANUFACTURER_IDX].id = status;
+       device_desc.iManufacturer = status;
+
+       status = usb_string_id(cdev);
+       if (status < 0)
+               goto fail1;
+       strings_dev[STRING_PRODUCT_IDX].id = status;
+       device_desc.iProduct = status;
+
+       /* register our configuration */
+       status = usb_add_config(cdev, &cdc_config_driver);
+       if (status < 0)
+               goto fail1;
+
+       INFO(cdev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC);
+
+       return 0;
+
+fail1:
+       gserial_cleanup();
+fail0:
+       gether_cleanup();
+       return status;
+}
+
+static int __exit cdc_unbind(struct usb_composite_dev *cdev)
+{
+       gserial_cleanup();
+       gether_cleanup();
+       return 0;
+}
+
+static struct usb_composite_driver cdc_driver = {
+       .name           = "g_cdc",
+       .dev            = &device_desc,
+       .strings        = dev_strings,
+       .bind           = cdc_bind,
+       .unbind         = __exit_p(cdc_unbind),
+};
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("David Brownell");
+MODULE_LICENSE("GPL");
+
+static int __init init(void)
+{
+       return usb_composite_register(&cdc_driver);
+}
+module_init(init);
+
+static void __exit cleanup(void)
+{
+       usb_composite_unregister(&cdc_driver);
+}
+module_exit(cleanup);
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
new file mode 100644 (file)
index 0000000..85c876c
--- /dev/null
@@ -0,0 +1,1041 @@
+/*
+ * composite.c - infrastructure for Composite USB Gadgets
+ *
+ * Copyright (C) 2006-2008 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 VERBOSE_DEBUG */
+
+#include <linux/kallsyms.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+
+#include <linux/usb/composite.h>
+
+
+/*
+ * The code in this file is utility code, used to build a gadget driver
+ * from one or more "function" drivers, one or more "configuration"
+ * objects, and a "usb_composite_driver" by gluing them together along
+ * with the relevant device-wide data.
+ */
+
+/* big enough to hold our biggest descriptor */
+#define USB_BUFSIZ     512
+
+static struct usb_composite_driver *composite;
+
+/* Some systems will need runtime overrides for the  product identifers
+ * published in the device descriptor, either numbers or strings or both.
+ * String parameters are in UTF-8 (superset of ASCII's 7 bit characters).
+ */
+
+static ushort idVendor;
+module_param(idVendor, ushort, 0);
+MODULE_PARM_DESC(idVendor, "USB Vendor ID");
+
+static ushort idProduct;
+module_param(idProduct, ushort, 0);
+MODULE_PARM_DESC(idProduct, "USB Product ID");
+
+static ushort bcdDevice;
+module_param(bcdDevice, ushort, 0);
+MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)");
+
+static char *iManufacturer;
+module_param(iManufacturer, charp, 0);
+MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string");
+
+static char *iProduct;
+module_param(iProduct, charp, 0);
+MODULE_PARM_DESC(iProduct, "USB Product string");
+
+static char *iSerialNumber;
+module_param(iSerialNumber, charp, 0);
+MODULE_PARM_DESC(iSerialNumber, "SerialNumber string");
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * usb_add_function() - add a function to a configuration
+ * @config: the configuration
+ * @function: the function being added
+ * Context: single threaded during gadget setup
+ *
+ * After initialization, each configuration must have one or more
+ * functions added to it.  Adding a function involves calling its @bind()
+ * method to allocate resources such as interface and string identifiers
+ * and endpoints.
+ *
+ * This function returns the value of the function's bind(), which is
+ * zero for success else a negative errno value.
+ */
+int __init usb_add_function(struct usb_configuration *config,
+               struct usb_function *function)
+{
+       int     value = -EINVAL;
+
+       DBG(config->cdev, "adding '%s'/%p to config '%s'/%p\n",
+                       function->name, function,
+                       config->label, config);
+
+       if (!function->set_alt || !function->disable)
+               goto done;
+
+       function->config = config;
+       list_add_tail(&function->list, &config->functions);
+
+       /* REVISIT *require* function->bind? */
+       if (function->bind) {
+               value = function->bind(config, function);
+               if (value < 0) {
+                       list_del(&function->list);
+                       function->config = NULL;
+               }
+       } else
+               value = 0;
+
+       /* We allow configurations that don't work at both speeds.
+        * If we run into a lowspeed Linux system, treat it the same
+        * as full speed ... it's the function drivers that will need
+        * to avoid bulk and ISO transfers.
+        */
+       if (!config->fullspeed && function->descriptors)
+               config->fullspeed = true;
+       if (!config->highspeed && function->hs_descriptors)
+               config->highspeed = true;
+
+done:
+       if (value)
+               DBG(config->cdev, "adding '%s'/%p --> %d\n",
+                               function->name, function, value);
+       return value;
+}
+
+/**
+ * usb_interface_id() - allocate an unused interface ID
+ * @config: configuration associated with the interface
+ * @function: function handling the interface
+ * Context: single threaded during gadget setup
+ *
+ * usb_interface_id() is called from usb_function.bind() callbacks to
+ * allocate new interface IDs.  The function driver will then store that
+ * ID in interface, association, CDC union, and other descriptors.  It
+ * will also handle any control requests targetted at that interface,
+ * particularly changing its altsetting via set_alt().  There may
+ * also be class-specific or vendor-specific requests to handle.
+ *
+ * All interface identifier should be allocated using this routine, to
+ * ensure that for example different functions don't wrongly assign
+ * different meanings to the same identifier.  Note that since interface
+ * identifers are configuration-specific, functions used in more than
+ * one configuration (or more than once in a given configuration) need
+ * multiple versions of the relevant descriptors.
+ *
+ * Returns the interface ID which was allocated; or -ENODEV if no
+ * more interface IDs can be allocated.
+ */
+int __init usb_interface_id(struct usb_configuration *config,
+               struct usb_function *function)
+{
+       unsigned id = config->next_interface_id;
+
+       if (id < MAX_CONFIG_INTERFACES) {
+               config->interface[id] = function;
+               config->next_interface_id = id + 1;
+               return id;
+       }
+       return -ENODEV;
+}
+
+static int config_buf(struct usb_configuration *config,
+               enum usb_device_speed speed, void *buf, u8 type)
+{
+       struct usb_config_descriptor    *c = buf;
+       void                            *next = buf + USB_DT_CONFIG_SIZE;
+       int                             len = USB_BUFSIZ - USB_DT_CONFIG_SIZE;
+       struct usb_function             *f;
+       int                             status;
+
+       /* write the config descriptor */
+       c = buf;
+       c->bLength = USB_DT_CONFIG_SIZE;
+       c->bDescriptorType = type;
+       /* wTotalLength is written later */
+       c->bNumInterfaces = config->next_interface_id;
+       c->bConfigurationValue = config->bConfigurationValue;
+       c->iConfiguration = config->iConfiguration;
+       c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes;
+       c->bMaxPower = config->bMaxPower;
+
+       /* There may be e.g. OTG descriptors */
+       if (config->descriptors) {
+               status = usb_descriptor_fillbuf(next, len,
+                               config->descriptors);
+               if (status < 0)
+                       return status;
+               len -= status;
+               next += status;
+       }
+
+       /* add each function's descriptors */
+       list_for_each_entry(f, &config->functions, list) {
+               struct usb_descriptor_header **descriptors;
+
+               if (speed == USB_SPEED_HIGH)
+                       descriptors = f->hs_descriptors;
+               else
+                       descriptors = f->descriptors;
+               if (!descriptors)
+                       continue;
+               status = usb_descriptor_fillbuf(next, len,
+                       (const struct usb_descriptor_header **) descriptors);
+               if (status < 0)
+                       return status;
+               len -= status;
+               next += status;
+       }
+
+       len = next - buf;
+       c->wTotalLength = cpu_to_le16(len);
+       return len;
+}
+
+static int config_desc(struct usb_composite_dev *cdev, unsigned w_value)
+{
+       struct usb_gadget               *gadget = cdev->gadget;
+       struct usb_configuration        *c;
+       u8                              type = w_value >> 8;
+       enum usb_device_speed           speed = USB_SPEED_UNKNOWN;
+
+       if (gadget_is_dualspeed(gadget)) {
+               int                     hs = 0;
+
+               if (gadget->speed == USB_SPEED_HIGH)
+                       hs = 1;
+               if (type == USB_DT_OTHER_SPEED_CONFIG)
+                       hs = !hs;
+               if (hs)
+                       speed = USB_SPEED_HIGH;
+
+       }
+
+       /* This is a lookup by config *INDEX* */
+       w_value &= 0xff;
+       list_for_each_entry(c, &cdev->configs, list) {
+               /* ignore configs that won't work at this speed */
+               if (speed == USB_SPEED_HIGH) {
+                       if (!c->highspeed)
+                               continue;
+               } else {
+                       if (!c->fullspeed)
+                               continue;
+               }
+               if (w_value == 0)
+                       return config_buf(c, speed, cdev->req->buf, type);
+               w_value--;
+       }
+       return -EINVAL;
+}
+
+static int count_configs(struct usb_composite_dev *cdev, unsigned type)
+{
+       struct usb_gadget               *gadget = cdev->gadget;
+       struct usb_configuration        *c;
+       unsigned                        count = 0;
+       int                             hs = 0;
+
+       if (gadget_is_dualspeed(gadget)) {
+               if (gadget->speed == USB_SPEED_HIGH)
+                       hs = 1;
+               if (type == USB_DT_DEVICE_QUALIFIER)
+                       hs = !hs;
+       }
+       list_for_each_entry(c, &cdev->configs, list) {
+               /* ignore configs that won't work at this speed */
+               if (hs) {
+                       if (!c->highspeed)
+                               continue;
+               } else {
+                       if (!c->fullspeed)
+                               continue;
+               }
+               count++;
+       }
+       return count;
+}
+
+static void device_qual(struct usb_composite_dev *cdev)
+{
+       struct usb_qualifier_descriptor *qual = cdev->req->buf;
+
+       qual->bLength = sizeof(*qual);
+       qual->bDescriptorType = USB_DT_DEVICE_QUALIFIER;
+       /* POLICY: same bcdUSB and device type info at both speeds */
+       qual->bcdUSB = cdev->desc.bcdUSB;
+       qual->bDeviceClass = cdev->desc.bDeviceClass;
+       qual->bDeviceSubClass = cdev->desc.bDeviceSubClass;
+       qual->bDeviceProtocol = cdev->desc.bDeviceProtocol;
+       /* ASSUME same EP0 fifo size at both speeds */
+       qual->bMaxPacketSize0 = cdev->desc.bMaxPacketSize0;
+       qual->bNumConfigurations = count_configs(cdev, USB_DT_DEVICE_QUALIFIER);
+       qual->bRESERVED = 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void reset_config(struct usb_composite_dev *cdev)
+{
+       struct usb_function             *f;
+
+       DBG(cdev, "reset config\n");
+
+       list_for_each_entry(f, &cdev->config->functions, list) {
+               if (f->disable)
+                       f->disable(f);
+       }
+       cdev->config = NULL;
+}
+
+static int set_config(struct usb_composite_dev *cdev,
+               const struct usb_ctrlrequest *ctrl, unsigned number)
+{
+       struct usb_gadget       *gadget = cdev->gadget;
+       struct usb_configuration *c = NULL;
+       int                     result = -EINVAL;
+       unsigned                power = gadget_is_otg(gadget) ? 8 : 100;
+       int                     tmp;
+
+       if (cdev->config)
+               reset_config(cdev);
+
+       if (number) {
+               list_for_each_entry(c, &cdev->configs, list) {
+                       if (c->bConfigurationValue == number) {
+                               result = 0;
+                               break;
+                       }
+               }
+               if (result < 0)
+                       goto done;
+       } else
+               result = 0;
+
+       INFO(cdev, "%s speed config #%d: %s\n",
+               ({ char *speed;
+               switch (gadget->speed) {
+               case USB_SPEED_LOW:     speed = "low"; break;
+               case USB_SPEED_FULL:    speed = "full"; break;
+               case USB_SPEED_HIGH:    speed = "high"; break;
+               default:                speed = "?"; break;
+               } ; speed; }), number, c ? c->label : "unconfigured");
+
+       if (!c)
+               goto done;
+
+       cdev->config = c;
+
+       /* Initialize all interfaces by setting them to altsetting zero. */
+       for (tmp = 0; tmp < MAX_CONFIG_INTERFACES; tmp++) {
+               struct usb_function     *f = c->interface[tmp];
+
+               if (!f)
+                       break;
+
+               result = f->set_alt(f, tmp, 0);
+               if (result < 0) {
+                       DBG(cdev, "interface %d (%s/%p) alt 0 --> %d\n",
+                                       tmp, f->name, f, result);
+
+                       reset_config(cdev);
+                       goto done;
+               }
+       }
+
+       /* when we return, be sure our power usage is valid */
+       power = 2 * c->bMaxPower;
+done:
+       usb_gadget_vbus_draw(gadget, power);
+       return result;
+}
+
+/**
+ * usb_add_config() - add a configuration to a device.
+ * @cdev: wraps the USB gadget
+ * @config: the configuration, with bConfigurationValue assigned
+ * Context: single threaded during gadget setup
+ *
+ * One of the main tasks of a composite driver's bind() routine is to
+ * add each of the configurations it supports, using this routine.
+ *
+ * This function returns the value of the configuration's bind(), which
+ * is zero for success else a negative errno value.  Binding configurations
+ * assigns global resources including string IDs, and per-configuration
+ * resources such as interface IDs and endpoints.
+ */
+int __init usb_add_config(struct usb_composite_dev *cdev,
+               struct usb_configuration *config)
+{
+       int                             status = -EINVAL;
+       struct usb_configuration        *c;
+
+       DBG(cdev, "adding config #%u '%s'/%p\n",
+                       config->bConfigurationValue,
+                       config->label, config);
+
+       if (!config->bConfigurationValue || !config->bind)
+               goto done;
+
+       /* Prevent duplicate configuration identifiers */
+       list_for_each_entry(c, &cdev->configs, list) {
+               if (c->bConfigurationValue == config->bConfigurationValue) {
+                       status = -EBUSY;
+                       goto done;
+               }
+       }
+
+       config->cdev = cdev;
+       list_add_tail(&config->list, &cdev->configs);
+
+       INIT_LIST_HEAD(&config->functions);
+       config->next_interface_id = 0;
+
+       status = config->bind(config);
+       if (status < 0) {
+               list_del(&config->list);
+               config->cdev = NULL;
+       } else {
+               unsigned        i;
+
+               DBG(cdev, "cfg %d/%p speeds:%s%s\n",
+                       config->bConfigurationValue, config,
+                       config->highspeed ? " high" : "",
+                       config->fullspeed
+                               ? (gadget_is_dualspeed(cdev->gadget)
+                                       ? " full"
+                                       : " full/low")
+                               : "");
+
+               for (i = 0; i < MAX_CONFIG_INTERFACES; i++) {
+                       struct usb_function     *f = config->interface[i];
+
+                       if (!f)
+                               continue;
+                       DBG(cdev, "  interface %d = %s/%p\n",
+                               i, f->name, f);
+               }
+       }
+
+       /* set_alt(), or next config->bind(), sets up
+        * ep->driver_data as needed.
+        */
+       usb_ep_autoconfig_reset(cdev->gadget);
+
+done:
+       if (status)
+               DBG(cdev, "added config '%s'/%u --> %d\n", config->label,
+                               config->bConfigurationValue, status);
+       return status;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* We support strings in multiple languages ... string descriptor zero
+ * says which languages are supported.  The typical case will be that
+ * only one language (probably English) is used, with I18N handled on
+ * the host side.
+ */
+
+static void collect_langs(struct usb_gadget_strings **sp, __le16 *buf)
+{
+       const struct usb_gadget_strings *s;
+       u16                             language;
+       __le16                          *tmp;
+
+       while (*sp) {
+               s = *sp;
+               language = cpu_to_le16(s->language);
+               for (tmp = buf; *tmp && tmp < &buf[126]; tmp++) {
+                       if (*tmp == language)
+                               goto repeat;
+               }
+               *tmp++ = language;
+repeat:
+               sp++;
+       }
+}
+
+static int lookup_string(
+       struct usb_gadget_strings       **sp,
+       void                            *buf,
+       u16                             language,
+       int                             id
+)
+{
+       struct usb_gadget_strings       *s;
+       int                             value;
+
+       while (*sp) {
+               s = *sp++;
+               if (s->language != language)
+                       continue;
+               value = usb_gadget_get_string(s, id, buf);
+               if (value > 0)
+                       return value;
+       }
+       return -EINVAL;
+}
+
+static int get_string(struct usb_composite_dev *cdev,
+               void *buf, u16 language, int id)
+{
+       struct usb_configuration        *c;
+       struct usb_function             *f;
+       int                             len;
+
+       /* Yes, not only is USB's I18N support probably more than most
+        * folk will ever care about ... also, it's all supported here.
+        * (Except for UTF8 support for Unicode's "Astral Planes".)
+        */
+
+       /* 0 == report all available language codes */
+       if (id == 0) {
+               struct usb_string_descriptor    *s = buf;
+               struct usb_gadget_strings       **sp;
+
+               memset(s, 0, 256);
+               s->bDescriptorType = USB_DT_STRING;
+
+               sp = composite->strings;
+               if (sp)
+                       collect_langs(sp, s->wData);
+
+               list_for_each_entry(c, &cdev->configs, list) {
+                       sp = c->strings;
+                       if (sp)
+                               collect_langs(sp, s->wData);
+
+                       list_for_each_entry(f, &c->functions, list) {
+                               sp = f->strings;
+                               if (sp)
+                                       collect_langs(sp, s->wData);
+                       }
+               }
+
+               for (len = 0; s->wData[len] && len <= 126; len++)
+                       continue;
+               if (!len)
+                       return -EINVAL;
+
+               s->bLength = 2 * (len + 1);
+               return s->bLength;
+       }
+
+       /* Otherwise, look up and return a specified string.  String IDs
+        * are device-scoped, so we look up each string table we're told
+        * about.  These lookups are infrequent; simpler-is-better here.
+        */
+       if (composite->strings) {
+               len = lookup_string(composite->strings, buf, language, id);
+               if (len > 0)
+                       return len;
+       }
+       list_for_each_entry(c, &cdev->configs, list) {
+               if (c->strings) {
+                       len = lookup_string(c->strings, buf, language, id);
+                       if (len > 0)
+                               return len;
+               }
+               list_for_each_entry(f, &c->functions, list) {
+                       if (!f->strings)
+                               continue;
+                       len = lookup_string(f->strings, buf, language, id);
+                       if (len > 0)
+                               return len;
+               }
+       }
+       return -EINVAL;
+}
+
+/**
+ * usb_string_id() - allocate an unused string ID
+ * @cdev: the device whose string descriptor IDs are being allocated
+ * Context: single threaded during gadget setup
+ *
+ * @usb_string_id() is called from bind() callbacks to allocate
+ * string IDs.  Drivers for functions, configurations, or gadgets will
+ * then store that ID in the appropriate descriptors and string table.
+ *
+ * All string identifier should be allocated using this routine, to
+ * ensure that for example different functions don't wrongly assign
+ * different meanings to the same identifier.
+ */
+int __init usb_string_id(struct usb_composite_dev *cdev)
+{
+       if (cdev->next_string_id < 254) {
+               /* string id 0 is reserved */
+               cdev->next_string_id++;
+               return cdev->next_string_id;
+       }
+       return -ENODEV;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       if (req->status || req->actual != req->length)
+               DBG((struct usb_composite_dev *) ep->driver_data,
+                               "setup complete --> %d, %d/%d\n",
+                               req->status, req->actual, req->length);
+}
+
+/*
+ * The setup() callback implements all the ep0 functionality that's
+ * not handled lower down, in hardware or the hardware driver(like
+ * device and endpoint feature flags, and their status).  It's all
+ * housekeeping for the gadget function we're implementing.  Most of
+ * the work is in config and function specific setup.
+ */
+static int
+composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
+{
+       struct usb_composite_dev        *cdev = get_gadget_data(gadget);
+       struct usb_request              *req = cdev->req;
+       int                             value = -EOPNOTSUPP;
+       u16                             w_index = le16_to_cpu(ctrl->wIndex);
+       u16                             w_value = le16_to_cpu(ctrl->wValue);
+       u16                             w_length = le16_to_cpu(ctrl->wLength);
+       struct usb_function             *f = NULL;
+
+       /* partial re-init of the response message; the function or the
+        * gadget might need to intercept e.g. a control-OUT completion
+        * when we delegate to it.
+        */
+       req->zero = 0;
+       req->complete = composite_setup_complete;
+       req->length = USB_BUFSIZ;
+       gadget->ep0->driver_data = cdev;
+
+       switch (ctrl->bRequest) {
+
+       /* we handle all standard USB descriptors */
+       case USB_REQ_GET_DESCRIPTOR:
+               if (ctrl->bRequestType != USB_DIR_IN)
+                       goto unknown;
+               switch (w_value >> 8) {
+
+               case USB_DT_DEVICE:
+                       cdev->desc.bNumConfigurations =
+                               count_configs(cdev, USB_DT_DEVICE);
+                       value = min(w_length, (u16) sizeof cdev->desc);
+                       memcpy(req->buf, &cdev->desc, value);
+                       break;
+               case USB_DT_DEVICE_QUALIFIER:
+                       if (!gadget_is_dualspeed(gadget))
+                               break;
+                       device_qual(cdev);
+                       value = min_t(int, w_length,
+                               sizeof(struct usb_qualifier_descriptor));
+                       break;
+               case USB_DT_OTHER_SPEED_CONFIG:
+                       if (!gadget_is_dualspeed(gadget))
+                               break;
+                       /* FALLTHROUGH */
+               case USB_DT_CONFIG:
+                       value = config_desc(cdev, w_value);
+                       if (value >= 0)
+                               value = min(w_length, (u16) value);
+                       break;
+               case USB_DT_STRING:
+                       value = get_string(cdev, req->buf,
+                                       w_index, w_value & 0xff);
+                       if (value >= 0)
+                               value = min(w_length, (u16) value);
+                       break;
+               }
+               break;
+
+       /* any number of configs can work */
+       case USB_REQ_SET_CONFIGURATION:
+               if (ctrl->bRequestType != 0)
+                       goto unknown;
+               if (gadget_is_otg(gadget)) {
+                       if (gadget->a_hnp_support)
+                               DBG(cdev, "HNP available\n");
+                       else if (gadget->a_alt_hnp_support)
+                               DBG(cdev, "HNP on another port\n");
+                       else
+                               VDBG(cdev, "HNP inactive\n");
+               }
+               spin_lock(&cdev->lock);
+               value = set_config(cdev, ctrl, w_value);
+               spin_unlock(&cdev->lock);
+               break;
+       case USB_REQ_GET_CONFIGURATION:
+               if (ctrl->bRequestType != USB_DIR_IN)
+                       goto unknown;
+               if (cdev->config)
+                       *(u8 *)req->buf = cdev->config->bConfigurationValue;
+               else
+                       *(u8 *)req->buf = 0;
+               value = min(w_length, (u16) 1);
+               break;
+
+       /* function drivers must handle get/set altsetting; if there's
+        * no get() method, we know only altsetting zero works.
+        */
+       case USB_REQ_SET_INTERFACE:
+               if (ctrl->bRequestType != USB_RECIP_INTERFACE)
+                       goto unknown;
+               if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)
+                       break;
+               f = cdev->config->interface[w_index];
+               if (!f)
+                       break;
+               if (w_value && !f->get_alt)
+                       break;
+               value = f->set_alt(f, w_index, w_value);
+               break;
+       case USB_REQ_GET_INTERFACE:
+               if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE))
+                       goto unknown;
+               if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)
+                       break;
+               f = cdev->config->interface[w_index];
+               if (!f)
+                       break;
+               /* lots of interfaces only need altsetting zero... */
+               value = f->get_alt ? f->get_alt(f, w_index) : 0;
+               if (value < 0)
+                       break;
+               *((u8 *)req->buf) = value;
+               value = min(w_length, (u16) 1);
+               break;
+       default:
+unknown:
+               VDBG(cdev,
+                       "non-core control req%02x.%02x v%04x i%04x l%d\n",
+                       ctrl->bRequestType, ctrl->bRequest,
+                       w_value, w_index, w_length);
+
+               /* functions always handle their interfaces ... punt other
+                * recipients (endpoint, other, WUSB, ...) to the current
+                * configuration code.
+                *
+                * REVISIT it could make sense to let the composite device
+                * take such requests too, if that's ever needed:  to work
+                * in config 0, etc.
+                */
+               if ((ctrl->bRequestType & USB_RECIP_MASK)
+                               == USB_RECIP_INTERFACE) {
+                       f = cdev->config->interface[w_index];
+                       if (f && f->setup)
+                               value = f->setup(f, ctrl);
+                       else
+                               f = NULL;
+               }
+               if (value < 0 && !f) {
+                       struct usb_configuration        *c;
+
+                       c = cdev->config;
+                       if (c && c->setup)
+                               value = c->setup(c, ctrl);
+               }
+
+               goto done;
+       }
+
+       /* respond with data transfer before status phase? */
+       if (value >= 0) {
+               req->length = value;
+               req->zero = value < w_length;
+               value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
+               if (value < 0) {
+                       DBG(cdev, "ep_queue --> %d\n", value);
+                       req->status = 0;
+                       composite_setup_complete(gadget->ep0, req);
+               }
+       }
+
+done:
+       /* device either stalls (value < 0) or reports success */
+       return value;
+}
+
+static void composite_disconnect(struct usb_gadget *gadget)
+{
+       struct usb_composite_dev        *cdev = get_gadget_data(gadget);
+       unsigned long                   flags;
+
+       /* REVISIT:  should we have config and device level
+        * disconnect callbacks?
+        */
+       spin_lock_irqsave(&cdev->lock, flags);
+       if (cdev->config)
+               reset_config(cdev);
+       spin_unlock_irqrestore(&cdev->lock, flags);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void /* __init_or_exit */
+composite_unbind(struct usb_gadget *gadget)
+{
+       struct usb_composite_dev        *cdev = get_gadget_data(gadget);
+
+       /* composite_disconnect() must already have been called
+        * by the underlying peripheral controller driver!
+        * so there's no i/o concurrency that could affect the
+        * state protected by cdev->lock.
+        */
+       WARN_ON(cdev->config);
+
+       while (!list_empty(&cdev->configs)) {
+               struct usb_configuration        *c;
+
+               c = list_first_entry(&cdev->configs,
+                               struct usb_configuration, list);
+               while (!list_empty(&c->functions)) {
+                       struct usb_function             *f;
+
+                       f = list_first_entry(&c->functions,
+                                       struct usb_function, list);
+                       list_del(&f->list);
+                       if (f->unbind) {
+                               DBG(cdev, "unbind function '%s'/%p\n",
+                                               f->name, f);
+                               f->unbind(c, f);
+                               /* may free memory for "f" */
+                       }
+               }
+               list_del(&c->list);
+               if (c->unbind) {
+                       DBG(cdev, "unbind config '%s'/%p\n", c->label, c);
+                       c->unbind(c);
+                       /* may free memory for "c" */
+               }
+       }
+       if (composite->unbind)
+               composite->unbind(cdev);
+
+       if (cdev->req) {
+               kfree(cdev->req->buf);
+               usb_ep_free_request(gadget->ep0, cdev->req);
+       }
+       kfree(cdev);
+       set_gadget_data(gadget, NULL);
+       composite = NULL;
+}
+
+static void __init
+string_override_one(struct usb_gadget_strings *tab, u8 id, const char *s)
+{
+       struct usb_string               *str = tab->strings;
+
+       for (str = tab->strings; str->s; str++) {
+               if (str->id == id) {
+                       str->s = s;
+                       return;
+               }
+       }
+}
+
+static void __init
+string_override(struct usb_gadget_strings **tab, u8 id, const char *s)
+{
+       while (*tab) {
+               string_override_one(*tab, id, s);
+               tab++;
+       }
+}
+
+static int __init composite_bind(struct usb_gadget *gadget)
+{
+       struct usb_composite_dev        *cdev;
+       int                             status = -ENOMEM;
+
+       cdev = kzalloc(sizeof *cdev, GFP_KERNEL);
+       if (!cdev)
+               return status;
+
+       spin_lock_init(&cdev->lock);
+       cdev->gadget = gadget;
+       set_gadget_data(gadget, cdev);
+       INIT_LIST_HEAD(&cdev->configs);
+
+       /* preallocate control response and buffer */
+       cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL);
+       if (!cdev->req)
+               goto fail;
+       cdev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL);
+       if (!cdev->req->buf)
+               goto fail;
+       cdev->req->complete = composite_setup_complete;
+       gadget->ep0->driver_data = cdev;
+
+       cdev->bufsiz = USB_BUFSIZ;
+       cdev->driver = composite;
+
+       usb_gadget_set_selfpowered(gadget);
+
+       /* interface and string IDs start at zero via kzalloc.
+        * we force endpoints to start unassigned; few controller
+        * drivers will zero ep->driver_data.
+        */
+       usb_ep_autoconfig_reset(cdev->gadget);
+
+       /* composite gadget needs to assign strings for whole device (like
+        * serial number), register function drivers, potentially update
+        * power state and consumption, etc
+        */
+       status = composite->bind(cdev);
+       if (status < 0)
+               goto fail;
+
+       cdev->desc = *composite->dev;
+       cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
+
+       /* standardized runtime overrides for device ID data */
+       if (idVendor)
+               cdev->desc.idVendor = cpu_to_le16(idVendor);
+       if (idProduct)
+               cdev->desc.idProduct = cpu_to_le16(idProduct);
+       if (bcdDevice)
+               cdev->desc.bcdDevice = cpu_to_le16(bcdDevice);
+
+       /* strings can't be assigned before bind() allocates the
+        * releavnt identifiers
+        */
+       if (cdev->desc.iManufacturer && iManufacturer)
+               string_override(composite->strings,
+                       cdev->desc.iManufacturer, iManufacturer);
+       if (cdev->desc.iProduct && iProduct)
+               string_override(composite->strings,
+                       cdev->desc.iProduct, iProduct);
+       if (cdev->desc.iSerialNumber && iSerialNumber)
+               string_override(composite->strings,
+                       cdev->desc.iSerialNumber, iSerialNumber);
+
+       INFO(cdev, "%s ready\n", composite->name);
+       return 0;
+
+fail:
+       composite_unbind(gadget);
+       return status;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void
+composite_suspend(struct usb_gadget *gadget)
+{
+       struct usb_composite_dev        *cdev = get_gadget_data(gadget);
+       struct usb_function             *f;
+
+       /* REVISIT:  should we have config and device level
+        * suspend/resume callbacks?
+        */
+       DBG(cdev, "suspend\n");
+       if (cdev->config) {
+               list_for_each_entry(f, &cdev->config->functions, list) {
+                       if (f->suspend)
+                               f->suspend(f);
+               }
+       }
+}
+
+static void
+composite_resume(struct usb_gadget *gadget)
+{
+       struct usb_composite_dev        *cdev = get_gadget_data(gadget);
+       struct usb_function             *f;
+
+       /* REVISIT:  should we have config and device level
+        * suspend/resume callbacks?
+        */
+       DBG(cdev, "resume\n");
+       if (cdev->config) {
+               list_for_each_entry(f, &cdev->config->functions, list) {
+                       if (f->resume)
+                               f->resume(f);
+               }
+       }
+}
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_gadget_driver composite_driver = {
+       .speed          = USB_SPEED_HIGH,
+
+       .bind           = composite_bind,
+       .unbind         = __exit_p(composite_unbind),
+
+       .setup          = composite_setup,
+       .disconnect     = composite_disconnect,
+
+       .suspend        = composite_suspend,
+       .resume         = composite_resume,
+
+       .driver = {
+               .owner          = THIS_MODULE,
+       },
+};
+
+/**
+ * usb_composite_register() - register a composite driver
+ * @driver: the driver to register
+ * Context: single threaded during gadget setup
+ *
+ * This function is used to register drivers using the composite driver
+ * framework.  The return value is zero, or a negative errno value.
+ * Those values normally come from the driver's @bind method, which does
+ * all the work of setting up the driver to match the hardware.
+ *
+ * On successful return, the gadget is ready to respond to requests from
+ * the host, unless one of its components invokes usb_gadget_disconnect()
+ * while it was binding.  That would usually be done in order to wait for
+ * some userspace participation.
+ */
+int __init usb_composite_register(struct usb_composite_driver *driver)
+{
+       if (!driver || !driver->dev || !driver->bind || composite)
+               return -EINVAL;
+
+       if (!driver->name)
+               driver->name = "composite";
+       composite_driver.function =  (char *) driver->name;
+       composite_driver.driver.name = driver->name;
+       composite = driver;
+
+       return usb_gadget_register_driver(&composite_driver);
+}
+
+/**
+ * usb_composite_unregister() - unregister a composite driver
+ * @driver: the driver to unregister
+ *
+ * This function is used to unregister drivers using the composite
+ * driver framework.
+ */
+void __exit usb_composite_unregister(struct usb_composite_driver *driver)
+{
+       if (composite != driver)
+               return;
+       usb_gadget_unregister_driver(&composite_driver);
+}
index a4e54b2743f008e4368b551db63d87ef88bee11d..1ca1c326392a9051c4609d84ad4b9ec2284432ec 100644 (file)
@@ -96,7 +96,7 @@ int usb_gadget_config_buf(
        /* config descriptor first */
        if (length < USB_DT_CONFIG_SIZE || !desc)
                return -EINVAL;
-       *cp = *config; 
+       *cp = *config;
 
        /* then interface/endpoint/class/vendor/... */
        len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (u8*)buf,
@@ -115,3 +115,77 @@ int usb_gadget_config_buf(
        return len;
 }
 
+/**
+ * usb_copy_descriptors - copy a vector of USB descriptors
+ * @src: null-terminated vector to copy
+ * Context: initialization code, which may sleep
+ *
+ * This makes a copy of a vector of USB descriptors.  Its primary use
+ * is to support usb_function objects which can have multiple copies,
+ * each needing different descriptors.  Functions may have static
+ * tables of descriptors, which are used as templates and customized
+ * with identifiers (for interfaces, strings, endpoints, and more)
+ * as needed by a given function instance.
+ */
+struct usb_descriptor_header **__init
+usb_copy_descriptors(struct usb_descriptor_header **src)
+{
+       struct usb_descriptor_header **tmp;
+       unsigned bytes;
+       unsigned n_desc;
+       void *mem;
+       struct usb_descriptor_header **ret;
+
+       /* count descriptors and their sizes; then add vector size */
+       for (bytes = 0, n_desc = 0, tmp = src; *tmp; tmp++, n_desc++)
+               bytes += (*tmp)->bLength;
+       bytes += (n_desc + 1) * sizeof(*tmp);
+
+       mem = kmalloc(bytes, GFP_KERNEL);
+       if (!mem)
+               return NULL;
+
+       /* fill in pointers starting at "tmp",
+        * to descriptors copied starting at "mem";
+        * and return "ret"
+        */
+       tmp = mem;
+       ret = mem;
+       mem += (n_desc + 1) * sizeof(*tmp);
+       while (*src) {
+               memcpy(mem, *src, (*src)->bLength);
+               *tmp = mem;
+               tmp++;
+               mem += (*src)->bLength;
+               src++;
+       }
+       *tmp = NULL;
+
+       return ret;
+}
+
+/**
+ * usb_find_endpoint - find a copy of an endpoint descriptor
+ * @src: original vector of descriptors
+ * @copy: copy of @src
+ * @ep: endpoint descriptor found in @src
+ *
+ * This returns the copy of the @match descriptor made for @copy.  Its
+ * intended use is to help remembering the endpoint descriptor to use
+ * when enabling a given endpoint.
+ */
+struct usb_endpoint_descriptor *__init
+usb_find_endpoint(
+       struct usb_descriptor_header **src,
+       struct usb_descriptor_header **copy,
+       struct usb_endpoint_descriptor *match
+)
+{
+       while (*src) {
+               if (*src == (void *) match)
+                       return (void *)*copy;
+               src++;
+               copy++;
+       }
+       return NULL;
+}
index 42036192a03c4cc4abb61078b591dfcac1da1a70..21d1406af9ee04f8e07d3afe0b073fd6df02bdaf 100644 (file)
@@ -862,7 +862,7 @@ static int dummy_udc_probe (struct platform_device *pdev)
        /* maybe claim OTG support, though we won't complete HNP */
        dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0);
 
-       strcpy (dum->gadget.dev.bus_id, "gadget");
+       dev_set_name(&dum->gadget.dev, "gadget");
        dum->gadget.dev.parent = &pdev->dev;
        dum->gadget.dev.release = dummy_gadget_release;
        rc = device_register (&dum->gadget.dev);
@@ -1865,7 +1865,7 @@ static int dummy_hcd_probe(struct platform_device *pdev)
 
        dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
 
-       hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, pdev->dev.bus_id);
+       hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, dev_name(&pdev->dev));
        if (!hcd)
                return -ENOMEM;
        the_controller = hcd_to_dummy (hcd);
index 8bdad221fa91adc094c45ee1dea65cb0677c84e2..9462e30192d8d742d419b59821cb135d89176ae3 100644 (file)
@@ -159,6 +159,7 @@ ep_matches (
        /* MATCH!! */
 
        /* report address */
+       desc->bEndpointAddress &= USB_DIR_IN;
        if (isdigit (ep->name [2])) {
                u8      num = simple_strtol (&ep->name [2], NULL, 10);
                desc->bEndpointAddress |= num;
index 4ce3950b997fb887507d28495e524cce94c812b2..d7aaaa29b1e1978b78cfeaad0495ad4e2e455f6e 100644 (file)
@@ -1,8 +1,9 @@
 /*
  * ether.c -- Ethernet gadget driver, with CDC and non-CDC options
  *
- * Copyright (C) 2003-2005 David Brownell
+ * Copyright (C) 2003-2005,2008 David Brownell
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
+ * Copyright (C) 2008 Nokia Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 #include <linux/kernel.h>
 #include <linux/utsname.h>
-#include <linux/device.h>
-#include <linux/ctype.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
 
-#include <linux/usb/ch9.h>
-#include <linux/usb/cdc.h>
-#include <linux/usb/gadget.h>
+#include "u_ether.h"
 
-#include "gadget_chips.h"
-
-/*-------------------------------------------------------------------------*/
 
 /*
  * Ethernet gadget driver -- with CDC and non-CDC options
  * this USB-IF standard as its open-systems interoperability solution;
  * most host side USB stacks (except from Microsoft) support it.
  *
- * There's some hardware that can't talk CDC.  We make that hardware
+ * This is sometimes called "CDC ECM" (Ethernet Control Model) to support
+ * TLA-soup.  "CDC ACM" (Abstract Control Model) is for modems, and a new
+ * "CDC EEM" (Ethernet Emulation Model) is starting to spread.
+ *
+ * There's some hardware that can't talk CDC ECM.  We make that hardware
  * implement a "minimalist" vendor-agnostic CDC core:  same framing, but
  * link-level setup only requires activating the configuration.  Only the
  * endpoint descriptors, and product/vendor IDs, are relevant; no control
  * A third option is also in use.  Rather than CDC Ethernet, or something
  * simpler, Microsoft pushes their own approach: RNDIS.  The published
  * RNDIS specs are ambiguous and appear to be incomplete, and are also
- * needlessly complex.
+ * needlessly complex.  They borrow more from CDC ACM than CDC ECM.
  */
 
 #define DRIVER_DESC            "Ethernet Gadget"
-#define DRIVER_VERSION         "May Day 2005"
-
-static const char shortname [] = "ether";
-static const char driver_desc [] = DRIVER_DESC;
+#define DRIVER_VERSION         "Memorial Day 2008"
 
-#define RX_EXTRA       20              /* guard against rx overflows */
-
-#include "rndis.h"
-
-#ifndef        CONFIG_USB_ETH_RNDIS
-#define rndis_uninit(x)                do{}while(0)
-#define rndis_deregister(c)    do{}while(0)
-#define rndis_exit()           do{}while(0)
+#ifdef CONFIG_USB_ETH_RNDIS
+#define PREFIX                 "RNDIS/"
+#else
+#define PREFIX                 ""
 #endif
 
-/* CDC and RNDIS support the same host-chosen outgoing packet filters. */
-#define        DEFAULT_FILTER  (USB_CDC_PACKET_TYPE_BROADCAST \
-                       |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
-                       |USB_CDC_PACKET_TYPE_PROMISCUOUS \
-                       |USB_CDC_PACKET_TYPE_DIRECTED)
-
-
-/*-------------------------------------------------------------------------*/
-
-struct eth_dev {
-       spinlock_t              lock;
-       struct usb_gadget       *gadget;
-       struct usb_request      *req;           /* for control responses */
-       struct usb_request      *stat_req;      /* for cdc & rndis status */
-
-       u8                      config;
-       struct usb_ep           *in_ep, *out_ep, *status_ep;
-       const struct usb_endpoint_descriptor
-                               *in, *out, *status;
-
-       spinlock_t              req_lock;
-       struct list_head        tx_reqs, rx_reqs;
-
-       struct net_device       *net;
-       struct net_device_stats stats;
-       atomic_t                tx_qlen;
-
-       struct work_struct      work;
-       unsigned                zlp:1;
-       unsigned                cdc:1;
-       unsigned                rndis:1;
-       unsigned                suspended:1;
-       u16                     cdc_filter;
-       unsigned long           todo;
-#define        WORK_RX_MEMORY          0
-       int                     rndis_config;
-       u8                      host_mac [ETH_ALEN];
-};
-
-/* This version autoconfigures as much as possible at run-time.
+/*
+ * This driver aims for interoperability by using CDC ECM unless
+ *
+ *             can_support_ecm()
  *
- * It also ASSUMES a self-powered device, without remote wakeup,
- * although remote wakeup support would make sense.
+ * returns false, in which case it supports the CDC Subset.  By default,
+ * that returns true; most hardware has no problems with CDC ECM, that's
+ * a good default.  Previous versions of this driver had no default; this
+ * version changes that, removing overhead for new controller support.
+ *
+ *     IF YOUR HARDWARE CAN'T SUPPORT CDC ECM, UPDATE THAT ROUTINE!
  */
 
+static inline bool has_rndis(void)
+{
+#ifdef CONFIG_USB_ETH_RNDIS
+       return true;
+#else
+       return false;
+#endif
+}
+
 /*-------------------------------------------------------------------------*/
 
 /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
@@ -137,8 +103,8 @@ struct eth_dev {
 /* Thanks to NetChip Technologies for donating this product ID.
  * It's for devices with only CDC Ethernet configurations.
  */
-#define CDC_VENDOR_NUM 0x0525          /* NetChip */
-#define CDC_PRODUCT_NUM        0xa4a1          /* Linux-USB Ethernet Gadget */
+#define CDC_VENDOR_NUM         0x0525  /* NetChip */
+#define CDC_PRODUCT_NUM                0xa4a1  /* Linux-USB Ethernet Gadget */
 
 /* For hardware that can't talk CDC, we use the same vendor ID that
  * ARM Linux has used for ethernet-over-usb, both with sa1100 and
@@ -162,274 +128,9 @@ struct eth_dev {
 #define RNDIS_VENDOR_NUM       0x0525  /* NetChip */
 #define RNDIS_PRODUCT_NUM      0xa4a2  /* Ethernet/RNDIS Gadget */
 
-
-/* Some systems will want different product identifers published in the
- * device descriptor, either numbers or strings or both.  These string
- * parameters are in UTF-8 (superset of ASCII's 7 bit characters).
- */
-
-static ushort idVendor;
-module_param(idVendor, ushort, S_IRUGO);
-MODULE_PARM_DESC(idVendor, "USB Vendor ID");
-
-static ushort idProduct;
-module_param(idProduct, ushort, S_IRUGO);
-MODULE_PARM_DESC(idProduct, "USB Product ID");
-
-static ushort bcdDevice;
-module_param(bcdDevice, ushort, S_IRUGO);
-MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)");
-
-static char *iManufacturer;
-module_param(iManufacturer, charp, S_IRUGO);
-MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string");
-
-static char *iProduct;
-module_param(iProduct, charp, S_IRUGO);
-MODULE_PARM_DESC(iProduct, "USB Product string");
-
-static char *iSerialNumber;
-module_param(iSerialNumber, charp, S_IRUGO);
-MODULE_PARM_DESC(iSerialNumber, "SerialNumber");
-
-/* initial value, changed by "ifconfig usb0 hw ether xx:xx:xx:xx:xx:xx" */
-static char *dev_addr;
-module_param(dev_addr, charp, S_IRUGO);
-MODULE_PARM_DESC(dev_addr, "Device Ethernet Address");
-
-/* this address is invisible to ifconfig */
-static char *host_addr;
-module_param(host_addr, charp, S_IRUGO);
-MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Include CDC support if we could run on CDC-capable hardware. */
-
-#ifdef CONFIG_USB_GADGET_NET2280
-#define        DEV_CONFIG_CDC
-#endif
-
-#ifdef CONFIG_USB_GADGET_DUMMY_HCD
-#define        DEV_CONFIG_CDC
-#endif
-
-#ifdef CONFIG_USB_GADGET_GOKU
-#define        DEV_CONFIG_CDC
-#endif
-
-#ifdef CONFIG_USB_GADGET_LH7A40X
-#define DEV_CONFIG_CDC
-#endif
-
-#ifdef CONFIG_USB_GADGET_MQ11XX
-#define        DEV_CONFIG_CDC
-#endif
-
-#ifdef CONFIG_USB_GADGET_OMAP
-#define        DEV_CONFIG_CDC
-#endif
-
-#ifdef CONFIG_USB_GADGET_N9604
-#define        DEV_CONFIG_CDC
-#endif
-
-#ifdef CONFIG_USB_GADGET_S3C2410
-#define DEV_CONFIG_CDC
-#endif
-
-#ifdef CONFIG_USB_GADGET_AT91
-#define DEV_CONFIG_CDC
-#endif
-
-#ifdef CONFIG_USB_GADGET_MUSBHSFC
-#define DEV_CONFIG_CDC
-#endif
-
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-#define DEV_CONFIG_CDC
-#endif
-
-#ifdef CONFIG_USB_GADGET_ATMEL_USBA
-#define DEV_CONFIG_CDC
-#endif
-
-#ifdef CONFIG_USB_GADGET_FSL_USB2
-#define DEV_CONFIG_CDC
-#endif
-
-/* For CDC-incapable hardware, choose the simple cdc subset.
- * Anything that talks bulk (without notable bugs) can do this.
- */
-#ifdef CONFIG_USB_GADGET_PXA25X
-#define        DEV_CONFIG_SUBSET
-#endif
-
-#ifdef CONFIG_USB_GADGET_PXA27X
-#define        DEV_CONFIG_SUBSET
-#endif
-
-#ifdef CONFIG_USB_GADGET_SUPERH
-#define        DEV_CONFIG_SUBSET
-#endif
-
-#ifdef CONFIG_USB_GADGET_SA1100
-/* use non-CDC for backwards compatibility */
-#define        DEV_CONFIG_SUBSET
-#endif
-
-#ifdef CONFIG_USB_GADGET_M66592
-#define DEV_CONFIG_CDC
-#endif
-
-#ifdef CONFIG_USB_GADGET_AMD5536UDC
-#define        DEV_CONFIG_CDC
-#endif
-
-
-/*-------------------------------------------------------------------------*/
-
-/* "main" config is either CDC, or its simple subset */
-static inline int is_cdc(struct eth_dev *dev)
-{
-#if    !defined(DEV_CONFIG_SUBSET)
-       return 1;               /* only cdc possible */
-#elif  !defined (DEV_CONFIG_CDC)
-       return 0;               /* only subset possible */
-#else
-       return dev->cdc;        /* depends on what hardware we found */
-#endif
-}
-
-/* "secondary" RNDIS config may sometimes be activated */
-static inline int rndis_active(struct eth_dev *dev)
-{
-#ifdef CONFIG_USB_ETH_RNDIS
-       return dev->rndis;
-#else
-       return 0;
-#endif
-}
-
-#define        subset_active(dev)      (!is_cdc(dev) && !rndis_active(dev))
-#define        cdc_active(dev)         ( is_cdc(dev) && !rndis_active(dev))
-
-
-
-#define DEFAULT_QLEN   2       /* double buffering by default */
-
-/* peak bulk transfer bits-per-second */
-#define        HS_BPS          (13 * 512 * 8 * 1000 * 8)
-#define        FS_BPS          (19 *  64 * 1 * 1000 * 8)
-
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-#define        DEVSPEED        USB_SPEED_HIGH
-
-static unsigned qmult = 5;
-module_param (qmult, uint, S_IRUGO|S_IWUSR);
-
-
-/* for dual-speed hardware, use deeper queues at highspeed */
-#define qlen(gadget) \
-       (DEFAULT_QLEN*((gadget->speed == USB_SPEED_HIGH) ? qmult : 1))
-
-static inline int BITRATE(struct usb_gadget *g)
-{
-       return (g->speed == USB_SPEED_HIGH) ? HS_BPS : FS_BPS;
-}
-
-#else  /* full speed (low speed doesn't do bulk) */
-
-#define qmult          1
-
-#define        DEVSPEED        USB_SPEED_FULL
-
-#define qlen(gadget) DEFAULT_QLEN
-
-static inline int BITRATE(struct usb_gadget *g)
-{
-       return FS_BPS;
-}
-#endif
-
-
-/*-------------------------------------------------------------------------*/
-
-#define xprintk(d,level,fmt,args...) \
-       printk(level "%s: " fmt , (d)->net->name , ## args)
-
-#ifdef DEBUG
-#undef DEBUG
-#define DEBUG(dev,fmt,args...) \
-       xprintk(dev , KERN_DEBUG , fmt , ## args)
-#else
-#define DEBUG(dev,fmt,args...) \
-       do { } while (0)
-#endif /* DEBUG */
-
-#ifdef VERBOSE_DEBUG
-#define VDEBUG DEBUG
-#else
-#define VDEBUG(dev,fmt,args...) \
-       do { } while (0)
-#endif /* DEBUG */
-
-#define ERROR(dev,fmt,args...) \
-       xprintk(dev , KERN_ERR , fmt , ## args)
-#define WARN(dev,fmt,args...) \
-       xprintk(dev , KERN_WARNING , fmt , ## args)
-#define INFO(dev,fmt,args...) \
-       xprintk(dev , KERN_INFO , fmt , ## args)
-
 /*-------------------------------------------------------------------------*/
 
-/* USB DRIVER HOOKUP (to the hardware driver, below us), mostly
- * ep0 implementation:  descriptors, config management, setup().
- * also optional class-specific notification interrupt transfer.
- */
-
-/*
- * DESCRIPTORS ... most are static, but strings and (full) configuration
- * descriptors are built on demand.  For now we do either full CDC, or
- * our simple subset, with RNDIS as an optional second configuration.
- *
- * RNDIS includes some CDC ACM descriptors ... like CDC Ethernet.  But
- * the class descriptors match a modem (they're ignored; it's really just
- * Ethernet functionality), they don't need the NOP altsetting, and the
- * status transfer endpoint isn't optional.
- */
-
-#define STRING_MANUFACTURER            1
-#define STRING_PRODUCT                 2
-#define STRING_ETHADDR                 3
-#define STRING_DATA                    4
-#define STRING_CONTROL                 5
-#define STRING_RNDIS_CONTROL           6
-#define STRING_CDC                     7
-#define STRING_SUBSET                  8
-#define STRING_RNDIS                   9
-#define STRING_SERIALNUMBER            10
-
-/* holds our biggest descriptor (or RNDIS response) */
-#define USB_BUFSIZ     256
-
-/*
- * This device advertises one configuration, eth_config, unless RNDIS
- * is enabled (rndis_config) on hardware supporting at least two configs.
- *
- * NOTE:  Controllers like superh_udc should probably be able to use
- * an RNDIS-only configuration.
- *
- * FIXME define some higher-powered configurations to make it easier
- * to recharge batteries ...
- */
-
-#define DEV_CONFIG_VALUE       1       /* cdc or subset */
-#define DEV_RNDIS_CONFIG_VALUE 2       /* rndis; optional */
-
-static struct usb_device_descriptor
-device_desc = {
+static struct usb_device_descriptor device_desc = {
        .bLength =              sizeof device_desc,
        .bDescriptorType =      USB_DT_DEVICE,
 
@@ -438,2220 +139,234 @@ device_desc = {
        .bDeviceClass =         USB_CLASS_COMM,
        .bDeviceSubClass =      0,
        .bDeviceProtocol =      0,
+       /* .bMaxPacketSize0 = f(hardware) */
 
+       /* Vendor and product id defaults change according to what configs
+        * we support.  (As does bNumConfigurations.)  These values can
+        * also be overridden by module parameters.
+        */
        .idVendor =             __constant_cpu_to_le16 (CDC_VENDOR_NUM),
        .idProduct =            __constant_cpu_to_le16 (CDC_PRODUCT_NUM),
-       .iManufacturer =        STRING_MANUFACTURER,
-       .iProduct =             STRING_PRODUCT,
+       /* .bcdDevice = f(hardware) */
+       /* .iManufacturer = DYNAMIC */
+       /* .iProduct = DYNAMIC */
+       /* NO SERIAL NUMBER */
        .bNumConfigurations =   1,
 };
 
-static struct usb_otg_descriptor
-otg_descriptor = {
+static struct usb_otg_descriptor otg_descriptor = {
        .bLength =              sizeof otg_descriptor,
        .bDescriptorType =      USB_DT_OTG,
 
-       .bmAttributes =         USB_OTG_SRP,
-};
-
-static struct usb_config_descriptor
-eth_config = {
-       .bLength =              sizeof eth_config,
-       .bDescriptorType =      USB_DT_CONFIG,
-
-       /* compute wTotalLength on the fly */
-       .bNumInterfaces =       2,
-       .bConfigurationValue =  DEV_CONFIG_VALUE,
-       .iConfiguration =       STRING_CDC,
-       .bmAttributes =         USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-       .bMaxPower =            50,
-};
-
-#ifdef CONFIG_USB_ETH_RNDIS
-static struct usb_config_descriptor
-rndis_config = {
-       .bLength =              sizeof rndis_config,
-       .bDescriptorType =      USB_DT_CONFIG,
-
-       /* compute wTotalLength on the fly */
-       .bNumInterfaces =       2,
-       .bConfigurationValue =  DEV_RNDIS_CONFIG_VALUE,
-       .iConfiguration =       STRING_RNDIS,
-       .bmAttributes =         USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-       .bMaxPower =            50,
-};
-#endif
-
-/*
- * Compared to the simple CDC subset, the full CDC Ethernet model adds
- * three class descriptors, two interface descriptors, optional status
- * endpoint.  Both have a "data" interface and two bulk endpoints.
- * There are also differences in how control requests are handled.
- *
- * RNDIS shares a lot with CDC-Ethernet, since it's a variant of the
- * CDC-ACM (modem) spec.  Unfortunately MSFT's RNDIS driver is buggy; it
- * may hang or oops.  Since bugfixes (or accurate specs, letting Linux
- * work around those bugs) are unlikely to ever come from MSFT, you may
- * wish to avoid using RNDIS.
- *
- * MCCI offers an alternative to RNDIS if you need to connect to Windows
- * but have hardware that can't support CDC Ethernet.   We add descriptors
- * to present the CDC Subset as a (nonconformant) CDC MDLM variant called
- * "SAFE".  That borrows from both CDC Ethernet and CDC MDLM.  You can
- * get those drivers from MCCI, or bundled with various products.
- */
-
-#ifdef DEV_CONFIG_CDC
-static struct usb_interface_descriptor
-control_intf = {
-       .bLength =              sizeof control_intf,
-       .bDescriptorType =      USB_DT_INTERFACE,
-
-       .bInterfaceNumber =     0,
-       /* status endpoint is optional; this may be patched later */
-       .bNumEndpoints =        1,
-       .bInterfaceClass =      USB_CLASS_COMM,
-       .bInterfaceSubClass =   USB_CDC_SUBCLASS_ETHERNET,
-       .bInterfaceProtocol =   USB_CDC_PROTO_NONE,
-       .iInterface =           STRING_CONTROL,
+       /* REVISIT SRP-only hardware is possible, although
+        * it would not be called "OTG" ...
+        */
+       .bmAttributes =         USB_OTG_SRP | USB_OTG_HNP,
 };
-#endif
-
-#ifdef CONFIG_USB_ETH_RNDIS
-static const struct usb_interface_descriptor
-rndis_control_intf = {
-       .bLength =              sizeof rndis_control_intf,
-       .bDescriptorType =      USB_DT_INTERFACE,
 
-       .bInterfaceNumber =     0,
-       .bNumEndpoints =        1,
-       .bInterfaceClass =      USB_CLASS_COMM,
-       .bInterfaceSubClass =   USB_CDC_SUBCLASS_ACM,
-       .bInterfaceProtocol =   USB_CDC_ACM_PROTO_VENDOR,
-       .iInterface =           STRING_RNDIS_CONTROL,
+static const struct usb_descriptor_header *otg_desc[] = {
+       (struct usb_descriptor_header *) &otg_descriptor,
+       NULL,
 };
-#endif
 
-static const struct usb_cdc_header_desc header_desc = {
-       .bLength =              sizeof header_desc,
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
 
-       .bcdCDC =               __constant_cpu_to_le16 (0x0110),
-};
+/* string IDs are assigned dynamically */
 
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+#define STRING_MANUFACTURER_IDX                0
+#define STRING_PRODUCT_IDX             1
 
-static const struct usb_cdc_union_desc union_desc = {
-       .bLength =              sizeof union_desc,
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubType =   USB_CDC_UNION_TYPE,
+static char manufacturer[50];
 
-       .bMasterInterface0 =    0,      /* index of control interface */
-       .bSlaveInterface0 =     1,      /* index of DATA interface */
+static struct usb_string strings_dev[] = {
+       [STRING_MANUFACTURER_IDX].s = manufacturer,
+       [STRING_PRODUCT_IDX].s = PREFIX DRIVER_DESC,
+       {  } /* end of list */
 };
 
-#endif /* CDC || RNDIS */
-
-#ifdef CONFIG_USB_ETH_RNDIS
-
-static const struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor = {
-       .bLength =              sizeof call_mgmt_descriptor,
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubType =   USB_CDC_CALL_MANAGEMENT_TYPE,
-
-       .bmCapabilities =       0x00,
-       .bDataInterface =       0x01,
+static struct usb_gadget_strings stringtab_dev = {
+       .language       = 0x0409,       /* en-us */
+       .strings        = strings_dev,
 };
 
-static const struct usb_cdc_acm_descriptor acm_descriptor = {
-       .bLength =              sizeof acm_descriptor,
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubType =   USB_CDC_ACM_TYPE,
-
-       .bmCapabilities =       0x00,
+static struct usb_gadget_strings *dev_strings[] = {
+       &stringtab_dev,
+       NULL,
 };
 
-#endif
-
-#ifndef DEV_CONFIG_CDC
-
-/* "SAFE" loosely follows CDC WMC MDLM, violating the spec in various
- * ways:  data endpoints live in the control interface, there's no data
- * interface, and it's not used to talk to a cell phone radio.
- */
-
-static const struct usb_cdc_mdlm_desc mdlm_desc = {
-       .bLength =              sizeof mdlm_desc,
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubType =   USB_CDC_MDLM_TYPE,
+static u8 hostaddr[ETH_ALEN];
 
-       .bcdVersion =           __constant_cpu_to_le16(0x0100),
-       .bGUID = {
-               0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
-               0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
-       },
-};
+/*-------------------------------------------------------------------------*/
 
-/* since "usb_cdc_mdlm_detail_desc" is a variable length structure, we
- * can't really use its struct.  All we do here is say that we're using
- * the submode of "SAFE" which directly matches the CDC Subset.
+/*
+ * We may not have an RNDIS configuration, but if we do it needs to be
+ * the first one present.  That's to make Microsoft's drivers happy,
+ * and to follow DOCSIS 1.0 (cable modem standard).
  */
-static const u8 mdlm_detail_desc[] = {
-       6,
-       USB_DT_CS_INTERFACE,
-       USB_CDC_MDLM_DETAIL_TYPE,
-
-       0,      /* "SAFE" */
-       0,      /* network control capabilities (none) */
-       0,      /* network data capabilities ("raw" encapsulation) */
-};
+static int __init rndis_do_config(struct usb_configuration *c)
+{
+       /* FIXME alloc iConfiguration string, set it in c->strings */
 
-#endif
+       if (gadget_is_otg(c->cdev->gadget)) {
+               c->descriptors = otg_desc;
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
 
-static const struct usb_cdc_ether_desc ether_desc = {
-       .bLength =              sizeof ether_desc,
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubType =   USB_CDC_ETHERNET_TYPE,
+       return rndis_bind_config(c, hostaddr);
+}
 
-       /* this descriptor actually adds value, surprise! */
-       .iMACAddress =          STRING_ETHADDR,
-       .bmEthernetStatistics = __constant_cpu_to_le32 (0), /* no statistics */
-       .wMaxSegmentSize =      __constant_cpu_to_le16 (ETH_FRAME_LEN),
-       .wNumberMCFilters =     __constant_cpu_to_le16 (0),
-       .bNumberPowerFilters =  0,
+static struct usb_configuration rndis_config_driver = {
+       .label                  = "RNDIS",
+       .bind                   = rndis_do_config,
+       .bConfigurationValue    = 2,
+       /* .iConfiguration = DYNAMIC */
+       .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
+       .bMaxPower              = 1,    /* 2 mA, minimal */
 };
 
+/*-------------------------------------------------------------------------*/
 
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
-
-/* include the status endpoint if we can, even where it's optional.
- * use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one
- * packet, to simplify cancellation; and a big transfer interval, to
- * waste less bandwidth.
- *
- * some drivers (like Linux 2.4 cdc-ether!) "need" it to exist even
- * if they ignore the connect/disconnect notifications that real aether
- * can provide.  more advanced cdc configurations might want to support
- * encapsulated commands (vendor-specific, using control-OUT).
- *
- * RNDIS requires the status endpoint, since it uses that encapsulation
- * mechanism for its funky RPC scheme.
+/*
+ * We _always_ have an ECM or CDC Subset configuration.
  */
+static int __init eth_do_config(struct usb_configuration *c)
+{
+       /* FIXME alloc iConfiguration string, set it in c->strings */
 
-#define LOG2_STATUS_INTERVAL_MSEC      5       /* 1 << 5 == 32 msec */
-#define STATUS_BYTECOUNT               16      /* 8 byte header + data */
-
-static struct usb_endpoint_descriptor
-fs_status_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16 (STATUS_BYTECOUNT),
-       .bInterval =            1 << LOG2_STATUS_INTERVAL_MSEC,
-};
-#endif
-
-#ifdef DEV_CONFIG_CDC
-
-/* the default data interface has no endpoints ... */
+       if (gadget_is_otg(c->cdev->gadget)) {
+               c->descriptors = otg_desc;
+               c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
 
-static const struct usb_interface_descriptor
-data_nop_intf = {
-       .bLength =              sizeof data_nop_intf,
-       .bDescriptorType =      USB_DT_INTERFACE,
+       if (can_support_ecm(c->cdev->gadget))
+               return ecm_bind_config(c, hostaddr);
+       else
+               return geth_bind_config(c, hostaddr);
+}
 
-       .bInterfaceNumber =     1,
-       .bAlternateSetting =    0,
-       .bNumEndpoints =        0,
-       .bInterfaceClass =      USB_CLASS_CDC_DATA,
-       .bInterfaceSubClass =   0,
-       .bInterfaceProtocol =   0,
+static struct usb_configuration eth_config_driver = {
+       /* .label = f(hardware) */
+       .bind                   = eth_do_config,
+       .bConfigurationValue    = 1,
+       /* .iConfiguration = DYNAMIC */
+       .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
+       .bMaxPower              = 1,    /* 2 mA, minimal */
 };
 
-/* ... but the "real" data interface has two bulk endpoints */
-
-static const struct usb_interface_descriptor
-data_intf = {
-       .bLength =              sizeof data_intf,
-       .bDescriptorType =      USB_DT_INTERFACE,
+/*-------------------------------------------------------------------------*/
 
-       .bInterfaceNumber =     1,
-       .bAlternateSetting =    1,
-       .bNumEndpoints =        2,
-       .bInterfaceClass =      USB_CLASS_CDC_DATA,
-       .bInterfaceSubClass =   0,
-       .bInterfaceProtocol =   0,
-       .iInterface =           STRING_DATA,
-};
+static int __init eth_bind(struct usb_composite_dev *cdev)
+{
+       int                     gcnum;
+       struct usb_gadget       *gadget = cdev->gadget;
+       int                     status;
 
-#endif
+       /* set up network link layer */
+       status = gether_setup(cdev->gadget, hostaddr);
+       if (status < 0)
+               return status;
 
-#ifdef CONFIG_USB_ETH_RNDIS
+       /* set up main config label and device descriptor */
+       if (can_support_ecm(cdev->gadget)) {
+               /* ECM */
+               eth_config_driver.label = "CDC Ethernet (ECM)";
+       } else {
+               /* CDC Subset */
+               eth_config_driver.label = "CDC Subset/SAFE";
 
-/* RNDIS doesn't activate by changing to the "real" altsetting */
+               device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM),
+               device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM),
+               device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+       }
 
-static const struct usb_interface_descriptor
-rndis_data_intf = {
-       .bLength =              sizeof rndis_data_intf,
-       .bDescriptorType =      USB_DT_INTERFACE,
+       if (has_rndis()) {
+               /* RNDIS plus ECM-or-Subset */
+               device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM),
+               device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM),
+               device_desc.bNumConfigurations = 2;
+       }
 
-       .bInterfaceNumber =     1,
-       .bAlternateSetting =    0,
-       .bNumEndpoints =        2,
-       .bInterfaceClass =      USB_CLASS_CDC_DATA,
-       .bInterfaceSubClass =   0,
-       .bInterfaceProtocol =   0,
-       .iInterface =           STRING_DATA,
-};
+       gcnum = usb_gadget_controller_number(gadget);
+       if (gcnum >= 0)
+               device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
+       else {
+               /* We assume that can_support_ecm() tells the truth;
+                * but if the controller isn't recognized at all then
+                * that assumption is a bit more likely to be wrong.
+                */
+               WARN(cdev, "controller '%s' not recognized; trying %s\n",
+                               gadget->name,
+                               eth_config_driver.label);
+               device_desc.bcdDevice =
+                       __constant_cpu_to_le16(0x0300 | 0x0099);
+       }
 
-#endif
 
-#ifdef DEV_CONFIG_SUBSET
+       /* Allocate string descriptor numbers ... note that string
+        * contents can be overridden by the composite_dev glue.
+        */
 
-/*
- * "Simple" CDC-subset option is a simple vendor-neutral model that most
- * full speed controllers can handle:  one interface, two bulk endpoints.
- *
- * To assist host side drivers, we fancy it up a bit, and add descriptors
- * so some host side drivers will understand it as a "SAFE" variant.
- */
+       /* device descriptor strings: manufacturer, product */
+       snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
+               init_utsname()->sysname, init_utsname()->release,
+               gadget->name);
+       status = usb_string_id(cdev);
+       if (status < 0)
+               goto fail;
+       strings_dev[STRING_MANUFACTURER_IDX].id = status;
+       device_desc.iManufacturer = status;
 
-static const struct usb_interface_descriptor
-subset_data_intf = {
-       .bLength =              sizeof subset_data_intf,
-       .bDescriptorType =      USB_DT_INTERFACE,
+       status = usb_string_id(cdev);
+       if (status < 0)
+               goto fail;
+       strings_dev[STRING_PRODUCT_IDX].id = status;
+       device_desc.iProduct = status;
 
-       .bInterfaceNumber =     0,
-       .bAlternateSetting =    0,
-       .bNumEndpoints =        2,
-       .bInterfaceClass =      USB_CLASS_COMM,
-       .bInterfaceSubClass =   USB_CDC_SUBCLASS_MDLM,
-       .bInterfaceProtocol =   0,
-       .iInterface =           STRING_DATA,
-};
+       /* register our configuration(s); RNDIS first, if it's used */
+       if (has_rndis()) {
+               status = usb_add_config(cdev, &rndis_config_driver);
+               if (status < 0)
+                       goto fail;
+       }
 
-#endif /* SUBSET */
+       status = usb_add_config(cdev, &eth_config_driver);
+       if (status < 0)
+               goto fail;
 
+       INFO(cdev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC);
 
-static struct usb_endpoint_descriptor
-fs_source_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
+       return 0;
 
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-};
+fail:
+       gether_cleanup();
+       return status;
+}
 
-static struct usb_endpoint_descriptor
-fs_sink_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
+static int __exit eth_unbind(struct usb_composite_dev *cdev)
+{
+       gether_cleanup();
+       return 0;
+}
 
-       .bEndpointAddress =     USB_DIR_OUT,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+static struct usb_composite_driver eth_driver = {
+       .name           = "g_ether",
+       .dev            = &device_desc,
+       .strings        = dev_strings,
+       .bind           = eth_bind,
+       .unbind         = __exit_p(eth_unbind),
 };
 
-static const struct usb_descriptor_header *fs_eth_function [11] = {
-       (struct usb_descriptor_header *) &otg_descriptor,
-#ifdef DEV_CONFIG_CDC
-       /* "cdc" mode descriptors */
-       (struct usb_descriptor_header *) &control_intf,
-       (struct usb_descriptor_header *) &header_desc,
-       (struct usb_descriptor_header *) &union_desc,
-       (struct usb_descriptor_header *) &ether_desc,
-       /* NOTE: status endpoint may need to be removed */
-       (struct usb_descriptor_header *) &fs_status_desc,
-       /* data interface, with altsetting */
-       (struct usb_descriptor_header *) &data_nop_intf,
-       (struct usb_descriptor_header *) &data_intf,
-       (struct usb_descriptor_header *) &fs_source_desc,
-       (struct usb_descriptor_header *) &fs_sink_desc,
-       NULL,
-#endif /* DEV_CONFIG_CDC */
-};
+MODULE_DESCRIPTION(PREFIX DRIVER_DESC);
+MODULE_AUTHOR("David Brownell, Benedikt Spanger");
+MODULE_LICENSE("GPL");
 
-static inline void __init fs_subset_descriptors(void)
+static int __init init(void)
 {
-#ifdef DEV_CONFIG_SUBSET
-       /* behavior is "CDC Subset"; extra descriptors say "SAFE" */
-       fs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf;
-       fs_eth_function[2] = (struct usb_descriptor_header *) &header_desc;
-       fs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc;
-       fs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc;
-       fs_eth_function[5] = (struct usb_descriptor_header *) &ether_desc;
-       fs_eth_function[6] = (struct usb_descriptor_header *) &fs_source_desc;
-       fs_eth_function[7] = (struct usb_descriptor_header *) &fs_sink_desc;
-       fs_eth_function[8] = NULL;
-#else
-       fs_eth_function[1] = NULL;
-#endif
+       return usb_composite_register(&eth_driver);
 }
+module_init(init);
 
-#ifdef CONFIG_USB_ETH_RNDIS
-static const struct usb_descriptor_header *fs_rndis_function [] = {
-       (struct usb_descriptor_header *) &otg_descriptor,
-       /* control interface matches ACM, not Ethernet */
-       (struct usb_descriptor_header *) &rndis_control_intf,
-       (struct usb_descriptor_header *) &header_desc,
-       (struct usb_descriptor_header *) &call_mgmt_descriptor,
-       (struct usb_descriptor_header *) &acm_descriptor,
-       (struct usb_descriptor_header *) &union_desc,
-       (struct usb_descriptor_header *) &fs_status_desc,
-       /* data interface has no altsetting */
-       (struct usb_descriptor_header *) &rndis_data_intf,
-       (struct usb_descriptor_header *) &fs_source_desc,
-       (struct usb_descriptor_header *) &fs_sink_desc,
-       NULL,
-};
-#endif
-
-/*
- * usb 2.0 devices need to expose both high speed and full speed
- * descriptors, unless they only run at full speed.
- */
-
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
-static struct usb_endpoint_descriptor
-hs_status_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16 (STATUS_BYTECOUNT),
-       .bInterval =            LOG2_STATUS_INTERVAL_MSEC + 4,
-};
-#endif /* DEV_CONFIG_CDC */
-
-static struct usb_endpoint_descriptor
-hs_source_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16 (512),
-};
-
-static struct usb_endpoint_descriptor
-hs_sink_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16 (512),
-};
-
-static struct usb_qualifier_descriptor
-dev_qualifier = {
-       .bLength =              sizeof dev_qualifier,
-       .bDescriptorType =      USB_DT_DEVICE_QUALIFIER,
-
-       .bcdUSB =               __constant_cpu_to_le16 (0x0200),
-       .bDeviceClass =         USB_CLASS_COMM,
-
-       .bNumConfigurations =   1,
-};
-
-static const struct usb_descriptor_header *hs_eth_function [11] = {
-       (struct usb_descriptor_header *) &otg_descriptor,
-#ifdef DEV_CONFIG_CDC
-       /* "cdc" mode descriptors */
-       (struct usb_descriptor_header *) &control_intf,
-       (struct usb_descriptor_header *) &header_desc,
-       (struct usb_descriptor_header *) &union_desc,
-       (struct usb_descriptor_header *) &ether_desc,
-       /* NOTE: status endpoint may need to be removed */
-       (struct usb_descriptor_header *) &hs_status_desc,
-       /* data interface, with altsetting */
-       (struct usb_descriptor_header *) &data_nop_intf,
-       (struct usb_descriptor_header *) &data_intf,
-       (struct usb_descriptor_header *) &hs_source_desc,
-       (struct usb_descriptor_header *) &hs_sink_desc,
-       NULL,
-#endif /* DEV_CONFIG_CDC */
-};
-
-static inline void __init hs_subset_descriptors(void)
-{
-#ifdef DEV_CONFIG_SUBSET
-       /* behavior is "CDC Subset"; extra descriptors say "SAFE" */
-       hs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf;
-       hs_eth_function[2] = (struct usb_descriptor_header *) &header_desc;
-       hs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc;
-       hs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc;
-       hs_eth_function[5] = (struct usb_descriptor_header *) &ether_desc;
-       hs_eth_function[6] = (struct usb_descriptor_header *) &hs_source_desc;
-       hs_eth_function[7] = (struct usb_descriptor_header *) &hs_sink_desc;
-       hs_eth_function[8] = NULL;
-#else
-       hs_eth_function[1] = NULL;
-#endif
-}
-
-#ifdef CONFIG_USB_ETH_RNDIS
-static const struct usb_descriptor_header *hs_rndis_function [] = {
-       (struct usb_descriptor_header *) &otg_descriptor,
-       /* control interface matches ACM, not Ethernet */
-       (struct usb_descriptor_header *) &rndis_control_intf,
-       (struct usb_descriptor_header *) &header_desc,
-       (struct usb_descriptor_header *) &call_mgmt_descriptor,
-       (struct usb_descriptor_header *) &acm_descriptor,
-       (struct usb_descriptor_header *) &union_desc,
-       (struct usb_descriptor_header *) &hs_status_desc,
-       /* data interface has no altsetting */
-       (struct usb_descriptor_header *) &rndis_data_intf,
-       (struct usb_descriptor_header *) &hs_source_desc,
-       (struct usb_descriptor_header *) &hs_sink_desc,
-       NULL,
-};
-#endif
-
-
-/* maxpacket and other transfer characteristics vary by speed. */
-static inline struct usb_endpoint_descriptor *
-ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,
-               struct usb_endpoint_descriptor *fs)
-{
-       if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
-               return hs;
-       return fs;
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-/* descriptors that are built on-demand */
-
-static char                            manufacturer [50];
-static char                            product_desc [40] = DRIVER_DESC;
-static char                            serial_number [20];
-
-/* address that the host will use ... usually assigned at random */
-static char                            ethaddr [2 * ETH_ALEN + 1];
-
-/* static strings, in UTF-8 */
-static struct usb_string               strings [] = {
-       { STRING_MANUFACTURER,  manufacturer, },
-       { STRING_PRODUCT,       product_desc, },
-       { STRING_SERIALNUMBER,  serial_number, },
-       { STRING_DATA,          "Ethernet Data", },
-       { STRING_ETHADDR,       ethaddr, },
-#ifdef DEV_CONFIG_CDC
-       { STRING_CDC,           "CDC Ethernet", },
-       { STRING_CONTROL,       "CDC Communications Control", },
-#endif
-#ifdef DEV_CONFIG_SUBSET
-       { STRING_SUBSET,        "CDC Ethernet Subset", },
-#endif
-#ifdef CONFIG_USB_ETH_RNDIS
-       { STRING_RNDIS,         "RNDIS", },
-       { STRING_RNDIS_CONTROL, "RNDIS Communications Control", },
-#endif
-       {  }            /* end of list */
-};
-
-static struct usb_gadget_strings       stringtab = {
-       .language       = 0x0409,       /* en-us */
-       .strings        = strings,
-};
-
-/*
- * one config, two interfaces:  control, data.
- * complications: class descriptors, and an altsetting.
- */
-static int
-config_buf(struct usb_gadget *g, u8 *buf, u8 type, unsigned index, int is_otg)
-{
-       int                                     len;
-       const struct usb_config_descriptor      *config;
-       const struct usb_descriptor_header      **function;
-       int                                     hs = 0;
-
-       if (gadget_is_dualspeed(g)) {
-               hs = (g->speed == USB_SPEED_HIGH);
-               if (type == USB_DT_OTHER_SPEED_CONFIG)
-                       hs = !hs;
-       }
-#define which_fn(t)    (hs ? hs_ ## t ## _function : fs_ ## t ## _function)
-
-       if (index >= device_desc.bNumConfigurations)
-               return -EINVAL;
-
-#ifdef CONFIG_USB_ETH_RNDIS
-       /* list the RNDIS config first, to make Microsoft's drivers
-        * happy. DOCSIS 1.0 needs this too.
-        */
-       if (device_desc.bNumConfigurations == 2 && index == 0) {
-               config = &rndis_config;
-               function = which_fn (rndis);
-       } else
-#endif
-       {
-               config = &eth_config;
-               function = which_fn (eth);
-       }
-
-       /* for now, don't advertise srp-only devices */
-       if (!is_otg)
-               function++;
-
-       len = usb_gadget_config_buf (config, buf, USB_BUFSIZ, function);
-       if (len < 0)
-               return len;
-       ((struct usb_config_descriptor *) buf)->bDescriptorType = type;
-       return len;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void eth_start (struct eth_dev *dev, gfp_t gfp_flags);
-static int alloc_requests (struct eth_dev *dev, unsigned n, gfp_t gfp_flags);
-
-static int
-set_ether_config (struct eth_dev *dev, gfp_t gfp_flags)
-{
-       int                                     result = 0;
-       struct usb_gadget                       *gadget = dev->gadget;
-
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
-       /* status endpoint used for RNDIS and (optionally) CDC */
-       if (!subset_active(dev) && dev->status_ep) {
-               dev->status = ep_desc (gadget, &hs_status_desc,
-                                               &fs_status_desc);
-               dev->status_ep->driver_data = dev;
-
-               result = usb_ep_enable (dev->status_ep, dev->status);
-               if (result != 0) {
-                       DEBUG (dev, "enable %s --> %d\n",
-                               dev->status_ep->name, result);
-                       goto done;
-               }
-       }
-#endif
-
-       dev->in = ep_desc(gadget, &hs_source_desc, &fs_source_desc);
-       dev->in_ep->driver_data = dev;
-
-       dev->out = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc);
-       dev->out_ep->driver_data = dev;
-
-       /* With CDC,  the host isn't allowed to use these two data
-        * endpoints in the default altsetting for the interface.
-        * so we don't activate them yet.  Reset from SET_INTERFACE.
-        *
-        * Strictly speaking RNDIS should work the same: activation is
-        * a side effect of setting a packet filter.  Deactivation is
-        * from REMOTE_NDIS_HALT_MSG, reset from REMOTE_NDIS_RESET_MSG.
-        */
-       if (!cdc_active(dev)) {
-               result = usb_ep_enable (dev->in_ep, dev->in);
-               if (result != 0) {
-                       DEBUG(dev, "enable %s --> %d\n",
-                               dev->in_ep->name, result);
-                       goto done;
-               }
-
-               result = usb_ep_enable (dev->out_ep, dev->out);
-               if (result != 0) {
-                       DEBUG (dev, "enable %s --> %d\n",
-                               dev->out_ep->name, result);
-                       goto done;
-               }
-       }
-
-done:
-       if (result == 0)
-               result = alloc_requests (dev, qlen (gadget), gfp_flags);
-
-       /* on error, disable any endpoints  */
-       if (result < 0) {
-               if (!subset_active(dev) && dev->status_ep)
-                       (void) usb_ep_disable (dev->status_ep);
-               dev->status = NULL;
-               (void) usb_ep_disable (dev->in_ep);
-               (void) usb_ep_disable (dev->out_ep);
-               dev->in = NULL;
-               dev->out = NULL;
-       }
-
-       /* activate non-CDC configs right away
-        * this isn't strictly according to the RNDIS spec
-        */
-       else if (!cdc_active (dev)) {
-               netif_carrier_on (dev->net);
-               if (netif_running (dev->net)) {
-                       spin_unlock (&dev->lock);
-                       eth_start (dev, GFP_ATOMIC);
-                       spin_lock (&dev->lock);
-               }
-       }
-
-       if (result == 0)
-               DEBUG (dev, "qlen %d\n", qlen (gadget));
-
-       /* caller is responsible for cleanup on error */
-       return result;
-}
-
-static void eth_reset_config (struct eth_dev *dev)
-{
-       struct usb_request      *req;
-
-       if (dev->config == 0)
-               return;
-
-       DEBUG (dev, "%s\n", __func__);
-
-       netif_stop_queue (dev->net);
-       netif_carrier_off (dev->net);
-       rndis_uninit(dev->rndis_config);
-
-       /* disable endpoints, forcing (synchronous) completion of
-        * pending i/o.  then free the requests.
-        */
-       if (dev->in) {
-               usb_ep_disable (dev->in_ep);
-               spin_lock(&dev->req_lock);
-               while (likely (!list_empty (&dev->tx_reqs))) {
-                       req = container_of (dev->tx_reqs.next,
-                                               struct usb_request, list);
-                       list_del (&req->list);
-
-                       spin_unlock(&dev->req_lock);
-                       usb_ep_free_request (dev->in_ep, req);
-                       spin_lock(&dev->req_lock);
-               }
-               spin_unlock(&dev->req_lock);
-       }
-       if (dev->out) {
-               usb_ep_disable (dev->out_ep);
-               spin_lock(&dev->req_lock);
-               while (likely (!list_empty (&dev->rx_reqs))) {
-                       req = container_of (dev->rx_reqs.next,
-                                               struct usb_request, list);
-                       list_del (&req->list);
-
-                       spin_unlock(&dev->req_lock);
-                       usb_ep_free_request (dev->out_ep, req);
-                       spin_lock(&dev->req_lock);
-               }
-               spin_unlock(&dev->req_lock);
-       }
-
-       if (dev->status) {
-               usb_ep_disable (dev->status_ep);
-       }
-       dev->rndis = 0;
-       dev->cdc_filter = 0;
-       dev->config = 0;
-}
-
-/* change our operational config.  must agree with the code
- * that returns config descriptors, and altsetting code.
- */
-static int
-eth_set_config (struct eth_dev *dev, unsigned number, gfp_t gfp_flags)
-{
-       int                     result = 0;
-       struct usb_gadget       *gadget = dev->gadget;
-
-       if (gadget_is_sa1100 (gadget)
-                       && dev->config
-                       && atomic_read (&dev->tx_qlen) != 0) {
-               /* tx fifo is full, but we can't clear it...*/
-               INFO (dev, "can't change configurations\n");
-               return -ESPIPE;
-       }
-       eth_reset_config (dev);
-
-       switch (number) {
-       case DEV_CONFIG_VALUE:
-               result = set_ether_config (dev, gfp_flags);
-               break;
-#ifdef CONFIG_USB_ETH_RNDIS
-       case DEV_RNDIS_CONFIG_VALUE:
-               dev->rndis = 1;
-               result = set_ether_config (dev, gfp_flags);
-               break;
-#endif
-       default:
-               result = -EINVAL;
-               /* FALL THROUGH */
-       case 0:
-               break;
-       }
-
-       if (result) {
-               if (number)
-                       eth_reset_config (dev);
-               usb_gadget_vbus_draw(dev->gadget,
-                               gadget_is_otg(dev->gadget) ? 8 : 100);
-       } else {
-               char *speed;
-               unsigned power;
-
-               power = 2 * eth_config.bMaxPower;
-               usb_gadget_vbus_draw(dev->gadget, power);
-
-               switch (gadget->speed) {
-               case USB_SPEED_FULL:    speed = "full"; break;
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-               case USB_SPEED_HIGH:    speed = "high"; break;
-#endif
-               default:                speed = "?"; break;
-               }
-
-               dev->config = number;
-               INFO (dev, "%s speed config #%d: %d mA, %s, using %s\n",
-                               speed, number, power, driver_desc,
-                               rndis_active(dev)
-                                       ? "RNDIS"
-                                       : (cdc_active(dev)
-                                               ? "CDC Ethernet"
-                                               : "CDC Ethernet Subset"));
-       }
-       return result;
-}
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef DEV_CONFIG_CDC
-
-/* The interrupt endpoint is used in CDC networking models (Ethernet, ATM)
- * only to notify the host about link status changes (which we support) or
- * report completion of some encapsulated command (as used in RNDIS).  Since
- * we want this CDC Ethernet code to be vendor-neutral, we don't use that
- * command mechanism; and only one status request is ever queued.
- */
-
-static void eth_status_complete (struct usb_ep *ep, struct usb_request *req)
-{
-       struct usb_cdc_notification     *event = req->buf;
-       int                             value = req->status;
-       struct eth_dev                  *dev = ep->driver_data;
-
-       /* issue the second notification if host reads the first */
-       if (event->bNotificationType == USB_CDC_NOTIFY_NETWORK_CONNECTION
-                       && value == 0) {
-               __le32  *data = req->buf + sizeof *event;
-
-               event->bmRequestType = 0xA1;
-               event->bNotificationType = USB_CDC_NOTIFY_SPEED_CHANGE;
-               event->wValue = __constant_cpu_to_le16 (0);
-               event->wIndex = __constant_cpu_to_le16 (1);
-               event->wLength = __constant_cpu_to_le16 (8);
-
-               /* SPEED_CHANGE data is up/down speeds in bits/sec */
-               data [0] = data [1] = cpu_to_le32 (BITRATE (dev->gadget));
-
-               req->length = STATUS_BYTECOUNT;
-               value = usb_ep_queue (ep, req, GFP_ATOMIC);
-               DEBUG (dev, "send SPEED_CHANGE --> %d\n", value);
-               if (value == 0)
-                       return;
-       } else if (value != -ECONNRESET)
-               DEBUG (dev, "event %02x --> %d\n",
-                       event->bNotificationType, value);
-       req->context = NULL;
-}
-
-static void issue_start_status (struct eth_dev *dev)
-{
-       struct usb_request              *req = dev->stat_req;
-       struct usb_cdc_notification     *event;
-       int                             value;
-
-       DEBUG (dev, "%s, flush old status first\n", __func__);
-
-       /* flush old status
-        *
-        * FIXME ugly idiom, maybe we'd be better with just
-        * a "cancel the whole queue" primitive since any
-        * unlink-one primitive has way too many error modes.
-        * here, we "know" toggle is already clear...
-        *
-        * FIXME iff req->context != null just dequeue it
-        */
-       usb_ep_disable (dev->status_ep);
-       usb_ep_enable (dev->status_ep, dev->status);
-
-       /* 3.8.1 says to issue first NETWORK_CONNECTION, then
-        * a SPEED_CHANGE.  could be useful in some configs.
-        */
-       event = req->buf;
-       event->bmRequestType = 0xA1;
-       event->bNotificationType = USB_CDC_NOTIFY_NETWORK_CONNECTION;
-       event->wValue = __constant_cpu_to_le16 (1);     /* connected */
-       event->wIndex = __constant_cpu_to_le16 (1);
-       event->wLength = 0;
-
-       req->length = sizeof *event;
-       req->complete = eth_status_complete;
-       req->context = dev;
-
-       value = usb_ep_queue (dev->status_ep, req, GFP_ATOMIC);
-       if (value < 0)
-               DEBUG (dev, "status buf queue --> %d\n", value);
-}
-
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-static void eth_setup_complete (struct usb_ep *ep, struct usb_request *req)
-{
-       if (req->status || req->actual != req->length)
-               DEBUG ((struct eth_dev *) ep->driver_data,
-                               "setup complete --> %d, %d/%d\n",
-                               req->status, req->actual, req->length);
-}
-
-#ifdef CONFIG_USB_ETH_RNDIS
-
-static void rndis_response_complete (struct usb_ep *ep, struct usb_request *req)
-{
-       if (req->status || req->actual != req->length)
-               DEBUG ((struct eth_dev *) ep->driver_data,
-                       "rndis response complete --> %d, %d/%d\n",
-                       req->status, req->actual, req->length);
-
-       /* done sending after USB_CDC_GET_ENCAPSULATED_RESPONSE */
-}
-
-static void rndis_command_complete (struct usb_ep *ep, struct usb_request *req)
-{
-       struct eth_dev          *dev = ep->driver_data;
-       int                     status;
-
-       /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
-       spin_lock(&dev->lock);
-       status = rndis_msg_parser (dev->rndis_config, (u8 *) req->buf);
-       if (status < 0)
-               ERROR(dev, "%s: rndis parse error %d\n", __func__, status);
-       spin_unlock(&dev->lock);
-}
-
-#endif /* RNDIS */
-
-/*
- * The setup() callback implements all the ep0 functionality that's not
- * handled lower down.  CDC has a number of less-common features:
- *
- *  - two interfaces:  control, and ethernet data
- *  - Ethernet data interface has two altsettings:  default, and active
- *  - class-specific descriptors for the control interface
- *  - class-specific control requests
- */
-static int
-eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
-{
-       struct eth_dev          *dev = get_gadget_data (gadget);
-       struct usb_request      *req = dev->req;
-       int                     value = -EOPNOTSUPP;
-       u16                     wIndex = le16_to_cpu(ctrl->wIndex);
-       u16                     wValue = le16_to_cpu(ctrl->wValue);
-       u16                     wLength = le16_to_cpu(ctrl->wLength);
-
-       /* descriptors just go into the pre-allocated ep0 buffer,
-        * while config change events may enable network traffic.
-        */
-       req->complete = eth_setup_complete;
-       switch (ctrl->bRequest) {
-
-       case USB_REQ_GET_DESCRIPTOR:
-               if (ctrl->bRequestType != USB_DIR_IN)
-                       break;
-               switch (wValue >> 8) {
-
-               case USB_DT_DEVICE:
-                       value = min (wLength, (u16) sizeof device_desc);
-                       memcpy (req->buf, &device_desc, value);
-                       break;
-               case USB_DT_DEVICE_QUALIFIER:
-                       if (!gadget_is_dualspeed(gadget))
-                               break;
-                       value = min (wLength, (u16) sizeof dev_qualifier);
-                       memcpy (req->buf, &dev_qualifier, value);
-                       break;
-
-               case USB_DT_OTHER_SPEED_CONFIG:
-                       if (!gadget_is_dualspeed(gadget))
-                               break;
-                       // FALLTHROUGH
-               case USB_DT_CONFIG:
-                       value = config_buf(gadget, req->buf,
-                                       wValue >> 8,
-                                       wValue & 0xff,
-                                       gadget_is_otg(gadget));
-                       if (value >= 0)
-                               value = min (wLength, (u16) value);
-                       break;
-
-               case USB_DT_STRING:
-                       value = usb_gadget_get_string (&stringtab,
-                                       wValue & 0xff, req->buf);
-                       if (value >= 0)
-                               value = min (wLength, (u16) value);
-                       break;
-               }
-               break;
-
-       case USB_REQ_SET_CONFIGURATION:
-               if (ctrl->bRequestType != 0)
-                       break;
-               if (gadget->a_hnp_support)
-                       DEBUG (dev, "HNP available\n");
-               else if (gadget->a_alt_hnp_support)
-                       DEBUG (dev, "HNP needs a different root port\n");
-               spin_lock (&dev->lock);
-               value = eth_set_config (dev, wValue, GFP_ATOMIC);
-               spin_unlock (&dev->lock);
-               break;
-       case USB_REQ_GET_CONFIGURATION:
-               if (ctrl->bRequestType != USB_DIR_IN)
-                       break;
-               *(u8 *)req->buf = dev->config;
-               value = min (wLength, (u16) 1);
-               break;
-
-       case USB_REQ_SET_INTERFACE:
-               if (ctrl->bRequestType != USB_RECIP_INTERFACE
-                               || !dev->config
-                               || wIndex > 1)
-                       break;
-               if (!cdc_active(dev) && wIndex != 0)
-                       break;
-               spin_lock (&dev->lock);
-
-               /* PXA hardware partially handles SET_INTERFACE;
-                * we need to kluge around that interference.
-                */
-               if (gadget_is_pxa (gadget)) {
-                       value = eth_set_config (dev, DEV_CONFIG_VALUE,
-                                               GFP_ATOMIC);
-                       goto done_set_intf;
-               }
-
-#ifdef DEV_CONFIG_CDC
-               switch (wIndex) {
-               case 0:         /* control/master intf */
-                       if (wValue != 0)
-                               break;
-                       if (dev->status) {
-                               usb_ep_disable (dev->status_ep);
-                               usb_ep_enable (dev->status_ep, dev->status);
-                       }
-                       value = 0;
-                       break;
-               case 1:         /* data intf */
-                       if (wValue > 1)
-                               break;
-                       usb_ep_disable (dev->in_ep);
-                       usb_ep_disable (dev->out_ep);
-
-                       /* CDC requires the data transfers not be done from
-                        * the default interface setting ... also, setting
-                        * the non-default interface resets filters etc.
-                        */
-                       if (wValue == 1) {
-                               if (!cdc_active (dev))
-                                       break;
-                               usb_ep_enable (dev->in_ep, dev->in);
-                               usb_ep_enable (dev->out_ep, dev->out);
-                               dev->cdc_filter = DEFAULT_FILTER;
-                               netif_carrier_on (dev->net);
-                               if (dev->status)
-                                       issue_start_status (dev);
-                               if (netif_running (dev->net)) {
-                                       spin_unlock (&dev->lock);
-                                       eth_start (dev, GFP_ATOMIC);
-                                       spin_lock (&dev->lock);
-                               }
-                       } else {
-                               netif_stop_queue (dev->net);
-                               netif_carrier_off (dev->net);
-                       }
-                       value = 0;
-                       break;
-               }
-#else
-               /* FIXME this is wrong, as is the assumption that
-                * all non-PXA hardware talks real CDC ...
-                */
-               dev_warn (&gadget->dev, "set_interface ignored!\n");
-#endif /* DEV_CONFIG_CDC */
-
-done_set_intf:
-               spin_unlock (&dev->lock);
-               break;
-       case USB_REQ_GET_INTERFACE:
-               if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)
-                               || !dev->config
-                               || wIndex > 1)
-                       break;
-               if (!(cdc_active(dev) || rndis_active(dev)) && wIndex != 0)
-                       break;
-
-               /* for CDC, iff carrier is on, data interface is active. */
-               if (rndis_active(dev) || wIndex != 1)
-                       *(u8 *)req->buf = 0;
-               else
-                       *(u8 *)req->buf = netif_carrier_ok (dev->net) ? 1 : 0;
-               value = min (wLength, (u16) 1);
-               break;
-
-#ifdef DEV_CONFIG_CDC
-       case USB_CDC_SET_ETHERNET_PACKET_FILTER:
-               /* see 6.2.30: no data, wIndex = interface,
-                * wValue = packet filter bitmap
-                */
-               if (ctrl->bRequestType != (USB_TYPE_CLASS|USB_RECIP_INTERFACE)
-                               || !cdc_active(dev)
-                               || wLength != 0
-                               || wIndex > 1)
-                       break;
-               DEBUG (dev, "packet filter %02x\n", wValue);
-               dev->cdc_filter = wValue;
-               value = 0;
-               break;
-
-       /* and potentially:
-        * case USB_CDC_SET_ETHERNET_MULTICAST_FILTERS:
-        * case USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER:
-        * case USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER:
-        * case USB_CDC_GET_ETHERNET_STATISTIC:
-        */
-
-#endif /* DEV_CONFIG_CDC */
-
-#ifdef CONFIG_USB_ETH_RNDIS
-       /* RNDIS uses the CDC command encapsulation mechanism to implement
-        * an RPC scheme, with much getting/setting of attributes by OID.
-        */
-       case USB_CDC_SEND_ENCAPSULATED_COMMAND:
-               if (ctrl->bRequestType != (USB_TYPE_CLASS|USB_RECIP_INTERFACE)
-                               || !rndis_active(dev)
-                               || wLength > USB_BUFSIZ
-                               || wValue
-                               || rndis_control_intf.bInterfaceNumber
-                                       != wIndex)
-                       break;
-               /* read the request, then process it */
-               value = wLength;
-               req->complete = rndis_command_complete;
-               /* later, rndis_control_ack () sends a notification */
-               break;
-
-       case USB_CDC_GET_ENCAPSULATED_RESPONSE:
-               if ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)
-                                       == ctrl->bRequestType
-                               && rndis_active(dev)
-                               // && wLength >= 0x0400
-                               && !wValue
-                               && rndis_control_intf.bInterfaceNumber
-                                       == wIndex) {
-                       u8 *buf;
-                       u32 n;
-
-                       /* return the result */
-                       buf = rndis_get_next_response(dev->rndis_config, &n);
-                       if (buf) {
-                               memcpy(req->buf, buf, n);
-                               req->complete = rndis_response_complete;
-                               rndis_free_response(dev->rndis_config, buf);
-                               value = n;
-                       }
-                       /* else stalls ... spec says to avoid that */
-               }
-               break;
-#endif /* RNDIS */
-
-       default:
-               VDEBUG (dev,
-                       "unknown control req%02x.%02x v%04x i%04x l%d\n",
-                       ctrl->bRequestType, ctrl->bRequest,
-                       wValue, wIndex, wLength);
-       }
-
-       /* respond with data transfer before status phase? */
-       if (value >= 0) {
-               req->length = value;
-               req->zero = value < wLength
-                               && (value % gadget->ep0->maxpacket) == 0;
-               value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
-               if (value < 0) {
-                       DEBUG (dev, "ep_queue --> %d\n", value);
-                       req->status = 0;
-                       eth_setup_complete (gadget->ep0, req);
-               }
-       }
-
-       /* host either stalls (value < 0) or reports success */
-       return value;
-}
-
-static void
-eth_disconnect (struct usb_gadget *gadget)
-{
-       struct eth_dev          *dev = get_gadget_data (gadget);
-       unsigned long           flags;
-
-       spin_lock_irqsave (&dev->lock, flags);
-       netif_stop_queue (dev->net);
-       netif_carrier_off (dev->net);
-       eth_reset_config (dev);
-       spin_unlock_irqrestore (&dev->lock, flags);
-
-       /* FIXME RNDIS should enter RNDIS_UNINITIALIZED */
-
-       /* next we may get setup() calls to enumerate new connections;
-        * or an unbind() during shutdown (including removing module).
-        */
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* NETWORK DRIVER HOOKUP (to the layer above this driver) */
-
-static int eth_change_mtu (struct net_device *net, int new_mtu)
-{
-       struct eth_dev  *dev = netdev_priv(net);
-
-       if (dev->rndis)
-               return -EBUSY;
-
-       if (new_mtu <= ETH_HLEN || new_mtu > ETH_FRAME_LEN)
-               return -ERANGE;
-       /* no zero-length packet read wanted after mtu-sized packets */
-       if (((new_mtu + sizeof (struct ethhdr)) % dev->in_ep->maxpacket) == 0)
-               return -EDOM;
-       net->mtu = new_mtu;
-       return 0;
-}
-
-static struct net_device_stats *eth_get_stats (struct net_device *net)
-{
-       return &((struct eth_dev *)netdev_priv(net))->stats;
-}
-
-static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p)
-{
-       struct eth_dev  *dev = netdev_priv(net);
-       strlcpy(p->driver, shortname, sizeof p->driver);
-       strlcpy(p->version, DRIVER_VERSION, sizeof p->version);
-       strlcpy(p->fw_version, dev->gadget->name, sizeof p->fw_version);
-       strlcpy (p->bus_info, dev->gadget->dev.bus_id, sizeof p->bus_info);
-}
-
-static u32 eth_get_link(struct net_device *net)
-{
-       struct eth_dev  *dev = netdev_priv(net);
-       return dev->gadget->speed != USB_SPEED_UNKNOWN;
-}
-
-static struct ethtool_ops ops = {
-       .get_drvinfo = eth_get_drvinfo,
-       .get_link = eth_get_link
-};
-
-static void defer_kevent (struct eth_dev *dev, int flag)
-{
-       if (test_and_set_bit (flag, &dev->todo))
-               return;
-       if (!schedule_work (&dev->work))
-               ERROR (dev, "kevent %d may have been dropped\n", flag);
-       else
-               DEBUG (dev, "kevent %d scheduled\n", flag);
-}
-
-static void rx_complete (struct usb_ep *ep, struct usb_request *req);
-
-static int
-rx_submit (struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
-{
-       struct sk_buff          *skb;
-       int                     retval = -ENOMEM;
-       size_t                  size;
-
-       /* Padding up to RX_EXTRA handles minor disagreements with host.
-        * Normally we use the USB "terminate on short read" convention;
-        * so allow up to (N*maxpacket), since that memory is normally
-        * already allocated.  Some hardware doesn't deal well with short
-        * reads (e.g. DMA must be N*maxpacket), so for now don't trim a
-        * byte off the end (to force hardware errors on overflow).
-        *
-        * RNDIS uses internal framing, and explicitly allows senders to
-        * pad to end-of-packet.  That's potentially nice for speed,
-        * but means receivers can't recover synch on their own.
-        */
-       size = (sizeof (struct ethhdr) + dev->net->mtu + RX_EXTRA);
-       size += dev->out_ep->maxpacket - 1;
-       if (rndis_active(dev))
-               size += sizeof (struct rndis_packet_msg_type);
-       size -= size % dev->out_ep->maxpacket;
-
-       skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags);
-       if (skb == NULL) {
-               DEBUG (dev, "no rx skb\n");
-               goto enomem;
-       }
-
-       /* Some platforms perform better when IP packets are aligned,
-        * but on at least one, checksumming fails otherwise.  Note:
-        * RNDIS headers involve variable numbers of LE32 values.
-        */
-       skb_reserve(skb, NET_IP_ALIGN);
-
-       req->buf = skb->data;
-       req->length = size;
-       req->complete = rx_complete;
-       req->context = skb;
-
-       retval = usb_ep_queue (dev->out_ep, req, gfp_flags);
-       if (retval == -ENOMEM)
-enomem:
-               defer_kevent (dev, WORK_RX_MEMORY);
-       if (retval) {
-               DEBUG (dev, "rx submit --> %d\n", retval);
-               if (skb)
-                       dev_kfree_skb_any(skb);
-               spin_lock(&dev->req_lock);
-               list_add (&req->list, &dev->rx_reqs);
-               spin_unlock(&dev->req_lock);
-       }
-       return retval;
-}
-
-static void rx_complete (struct usb_ep *ep, struct usb_request *req)
-{
-       struct sk_buff  *skb = req->context;
-       struct eth_dev  *dev = ep->driver_data;
-       int             status = req->status;
-
-       switch (status) {
-
-       /* normal completion */
-       case 0:
-               skb_put (skb, req->actual);
-               /* we know MaxPacketsPerTransfer == 1 here */
-               if (rndis_active(dev))
-                       status = rndis_rm_hdr (skb);
-               if (status < 0
-                               || ETH_HLEN > skb->len
-                               || skb->len > ETH_FRAME_LEN) {
-                       dev->stats.rx_errors++;
-                       dev->stats.rx_length_errors++;
-                       DEBUG (dev, "rx length %d\n", skb->len);
-                       break;
-               }
-
-               skb->protocol = eth_type_trans (skb, dev->net);
-               dev->stats.rx_packets++;
-               dev->stats.rx_bytes += skb->len;
-
-               /* no buffer copies needed, unless hardware can't
-                * use skb buffers.
-                */
-               status = netif_rx (skb);
-               skb = NULL;
-               break;
-
-       /* software-driven interface shutdown */
-       case -ECONNRESET:               // unlink
-       case -ESHUTDOWN:                // disconnect etc
-               VDEBUG (dev, "rx shutdown, code %d\n", status);
-               goto quiesce;
-
-       /* for hardware automagic (such as pxa) */
-       case -ECONNABORTED:             // endpoint reset
-               DEBUG (dev, "rx %s reset\n", ep->name);
-               defer_kevent (dev, WORK_RX_MEMORY);
-quiesce:
-               dev_kfree_skb_any (skb);
-               goto clean;
-
-       /* data overrun */
-       case -EOVERFLOW:
-               dev->stats.rx_over_errors++;
-               // FALLTHROUGH
-
-       default:
-               dev->stats.rx_errors++;
-               DEBUG (dev, "rx status %d\n", status);
-               break;
-       }
-
-       if (skb)
-               dev_kfree_skb_any (skb);
-       if (!netif_running (dev->net)) {
-clean:
-               spin_lock(&dev->req_lock);
-               list_add (&req->list, &dev->rx_reqs);
-               spin_unlock(&dev->req_lock);
-               req = NULL;
-       }
-       if (req)
-               rx_submit (dev, req, GFP_ATOMIC);
-}
-
-static int prealloc (struct list_head *list, struct usb_ep *ep,
-                       unsigned n, gfp_t gfp_flags)
-{
-       unsigned                i;
-       struct usb_request      *req;
-
-       if (!n)
-               return -ENOMEM;
-
-       /* queue/recycle up to N requests */
-       i = n;
-       list_for_each_entry (req, list, list) {
-               if (i-- == 0)
-                       goto extra;
-       }
-       while (i--) {
-               req = usb_ep_alloc_request (ep, gfp_flags);
-               if (!req)
-                       return list_empty (list) ? -ENOMEM : 0;
-               list_add (&req->list, list);
-       }
-       return 0;
-
-extra:
-       /* free extras */
-       for (;;) {
-               struct list_head        *next;
-
-               next = req->list.next;
-               list_del (&req->list);
-               usb_ep_free_request (ep, req);
-
-               if (next == list)
-                       break;
-
-               req = container_of (next, struct usb_request, list);
-       }
-       return 0;
-}
-
-static int alloc_requests (struct eth_dev *dev, unsigned n, gfp_t gfp_flags)
-{
-       int status;
-
-       spin_lock(&dev->req_lock);
-       status = prealloc (&dev->tx_reqs, dev->in_ep, n, gfp_flags);
-       if (status < 0)
-               goto fail;
-       status = prealloc (&dev->rx_reqs, dev->out_ep, n, gfp_flags);
-       if (status < 0)
-               goto fail;
-       goto done;
-fail:
-       DEBUG (dev, "can't alloc requests\n");
-done:
-       spin_unlock(&dev->req_lock);
-       return status;
-}
-
-static void rx_fill (struct eth_dev *dev, gfp_t gfp_flags)
-{
-       struct usb_request      *req;
-       unsigned long           flags;
-
-       /* fill unused rxq slots with some skb */
-       spin_lock_irqsave(&dev->req_lock, flags);
-       while (!list_empty (&dev->rx_reqs)) {
-               req = container_of (dev->rx_reqs.next,
-                               struct usb_request, list);
-               list_del_init (&req->list);
-               spin_unlock_irqrestore(&dev->req_lock, flags);
-
-               if (rx_submit (dev, req, gfp_flags) < 0) {
-                       defer_kevent (dev, WORK_RX_MEMORY);
-                       return;
-               }
-
-               spin_lock_irqsave(&dev->req_lock, flags);
-       }
-       spin_unlock_irqrestore(&dev->req_lock, flags);
-}
-
-static void eth_work (struct work_struct *work)
-{
-       struct eth_dev  *dev = container_of(work, struct eth_dev, work);
-
-       if (test_and_clear_bit (WORK_RX_MEMORY, &dev->todo)) {
-               if (netif_running (dev->net))
-                       rx_fill (dev, GFP_KERNEL);
-       }
-
-       if (dev->todo)
-               DEBUG (dev, "work done, flags = 0x%lx\n", dev->todo);
-}
-
-static void tx_complete (struct usb_ep *ep, struct usb_request *req)
-{
-       struct sk_buff  *skb = req->context;
-       struct eth_dev  *dev = ep->driver_data;
-
-       switch (req->status) {
-       default:
-               dev->stats.tx_errors++;
-               VDEBUG (dev, "tx err %d\n", req->status);
-               /* FALLTHROUGH */
-       case -ECONNRESET:               // unlink
-       case -ESHUTDOWN:                // disconnect etc
-               break;
-       case 0:
-               dev->stats.tx_bytes += skb->len;
-       }
-       dev->stats.tx_packets++;
-
-       spin_lock(&dev->req_lock);
-       list_add (&req->list, &dev->tx_reqs);
-       spin_unlock(&dev->req_lock);
-       dev_kfree_skb_any (skb);
-
-       atomic_dec (&dev->tx_qlen);
-       if (netif_carrier_ok (dev->net))
-               netif_wake_queue (dev->net);
-}
-
-static inline int eth_is_promisc (struct eth_dev *dev)
-{
-       /* no filters for the CDC subset; always promisc */
-       if (subset_active (dev))
-               return 1;
-       return dev->cdc_filter & USB_CDC_PACKET_TYPE_PROMISCUOUS;
-}
-
-static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
-{
-       struct eth_dev          *dev = netdev_priv(net);
-       int                     length = skb->len;
-       int                     retval;
-       struct usb_request      *req = NULL;
-       unsigned long           flags;
-
-       /* apply outgoing CDC or RNDIS filters */
-       if (!eth_is_promisc (dev)) {
-               u8              *dest = skb->data;
-
-               if (is_multicast_ether_addr(dest)) {
-                       u16     type;
-
-                       /* ignores USB_CDC_PACKET_TYPE_MULTICAST and host
-                        * SET_ETHERNET_MULTICAST_FILTERS requests
-                        */
-                       if (is_broadcast_ether_addr(dest))
-                               type = USB_CDC_PACKET_TYPE_BROADCAST;
-                       else
-                               type = USB_CDC_PACKET_TYPE_ALL_MULTICAST;
-                       if (!(dev->cdc_filter & type)) {
-                               dev_kfree_skb_any (skb);
-                               return 0;
-                       }
-               }
-               /* ignores USB_CDC_PACKET_TYPE_DIRECTED */
-       }
-
-       spin_lock_irqsave(&dev->req_lock, flags);
-       /*
-        * this freelist can be empty if an interrupt triggered disconnect()
-        * and reconfigured the gadget (shutting down this queue) after the
-        * network stack decided to xmit but before we got the spinlock.
-        */
-       if (list_empty(&dev->tx_reqs)) {
-               spin_unlock_irqrestore(&dev->req_lock, flags);
-               return 1;
-       }
-
-       req = container_of (dev->tx_reqs.next, struct usb_request, list);
-       list_del (&req->list);
-
-       /* temporarily stop TX queue when the freelist empties */
-       if (list_empty (&dev->tx_reqs))
-               netif_stop_queue (net);
-       spin_unlock_irqrestore(&dev->req_lock, flags);
-
-       /* no buffer copies needed, unless the network stack did it
-        * or the hardware can't use skb buffers.
-        * or there's not enough space for any RNDIS headers we need
-        */
-       if (rndis_active(dev)) {
-               struct sk_buff  *skb_rndis;
-
-               skb_rndis = skb_realloc_headroom (skb,
-                               sizeof (struct rndis_packet_msg_type));
-               if (!skb_rndis)
-                       goto drop;
-
-               dev_kfree_skb_any (skb);
-               skb = skb_rndis;
-               rndis_add_hdr (skb);
-               length = skb->len;
-       }
-       req->buf = skb->data;
-       req->context = skb;
-       req->complete = tx_complete;
-
-       /* use zlp framing on tx for strict CDC-Ether conformance,
-        * though any robust network rx path ignores extra padding.
-        * and some hardware doesn't like to write zlps.
-        */
-       req->zero = 1;
-       if (!dev->zlp && (length % dev->in_ep->maxpacket) == 0)
-               length++;
-
-       req->length = length;
-
-       /* throttle highspeed IRQ rate back slightly */
-       if (gadget_is_dualspeed(dev->gadget))
-               req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH)
-                       ? ((atomic_read(&dev->tx_qlen) % qmult) != 0)
-                       : 0;
-
-       retval = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC);
-       switch (retval) {
-       default:
-               DEBUG (dev, "tx queue err %d\n", retval);
-               break;
-       case 0:
-               net->trans_start = jiffies;
-               atomic_inc (&dev->tx_qlen);
-       }
-
-       if (retval) {
-drop:
-               dev->stats.tx_dropped++;
-               dev_kfree_skb_any (skb);
-               spin_lock_irqsave(&dev->req_lock, flags);
-               if (list_empty (&dev->tx_reqs))
-                       netif_start_queue (net);
-               list_add (&req->list, &dev->tx_reqs);
-               spin_unlock_irqrestore(&dev->req_lock, flags);
-       }
-       return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef CONFIG_USB_ETH_RNDIS
-
-/* The interrupt endpoint is used in RNDIS to notify the host when messages
- * other than data packets are available ... notably the REMOTE_NDIS_*_CMPLT
- * messages, but also REMOTE_NDIS_INDICATE_STATUS_MSG and potentially even
- * REMOTE_NDIS_KEEPALIVE_MSG.
- *
- * The RNDIS control queue is processed by GET_ENCAPSULATED_RESPONSE, and
- * normally just one notification will be queued.
- */
-
-static struct usb_request *eth_req_alloc (struct usb_ep *, unsigned, gfp_t);
-static void eth_req_free (struct usb_ep *ep, struct usb_request *req);
-
-static void
-rndis_control_ack_complete (struct usb_ep *ep, struct usb_request *req)
-{
-       struct eth_dev          *dev = ep->driver_data;
-
-       if (req->status || req->actual != req->length)
-               DEBUG (dev,
-                       "rndis control ack complete --> %d, %d/%d\n",
-                       req->status, req->actual, req->length);
-       req->context = NULL;
-
-       if (req != dev->stat_req)
-               eth_req_free(ep, req);
-}
-
-static int rndis_control_ack (struct net_device *net)
-{
-       struct eth_dev          *dev = netdev_priv(net);
-       int                     length;
-       struct usb_request      *resp = dev->stat_req;
-
-       /* in case RNDIS calls this after disconnect */
-       if (!dev->status) {
-               DEBUG (dev, "status ENODEV\n");
-               return -ENODEV;
-       }
-
-       /* in case queue length > 1 */
-       if (resp->context) {
-               resp = eth_req_alloc (dev->status_ep, 8, GFP_ATOMIC);
-               if (!resp)
-                       return -ENOMEM;
-       }
-
-       /* Send RNDIS RESPONSE_AVAILABLE notification;
-        * USB_CDC_NOTIFY_RESPONSE_AVAILABLE should work too
-        */
-       resp->length = 8;
-       resp->complete = rndis_control_ack_complete;
-       resp->context = dev;
-
-       *((__le32 *) resp->buf) = __constant_cpu_to_le32 (1);
-       *((__le32 *) resp->buf + 1) = __constant_cpu_to_le32 (0);
-
-       length = usb_ep_queue (dev->status_ep, resp, GFP_ATOMIC);
-       if (length < 0) {
-               resp->status = 0;
-               rndis_control_ack_complete (dev->status_ep, resp);
-       }
-
-       return 0;
-}
-
-#else
-
-#define        rndis_control_ack       NULL
-
-#endif /* RNDIS */
-
-static void eth_start (struct eth_dev *dev, gfp_t gfp_flags)
-{
-       DEBUG (dev, "%s\n", __func__);
-
-       /* fill the rx queue */
-       rx_fill (dev, gfp_flags);
-
-       /* and open the tx floodgates */
-       atomic_set (&dev->tx_qlen, 0);
-       netif_wake_queue (dev->net);
-       if (rndis_active(dev)) {
-               rndis_set_param_medium (dev->rndis_config,
-                                       NDIS_MEDIUM_802_3,
-                                       BITRATE(dev->gadget)/100);
-               (void) rndis_signal_connect (dev->rndis_config);
-       }
-}
-
-static int eth_open (struct net_device *net)
-{
-       struct eth_dev          *dev = netdev_priv(net);
-
-       DEBUG (dev, "%s\n", __func__);
-       if (netif_carrier_ok (dev->net))
-               eth_start (dev, GFP_KERNEL);
-       return 0;
-}
-
-static int eth_stop (struct net_device *net)
-{
-       struct eth_dev          *dev = netdev_priv(net);
-
-       VDEBUG (dev, "%s\n", __func__);
-       netif_stop_queue (net);
-
-       DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n",
-               dev->stats.rx_packets, dev->stats.tx_packets,
-               dev->stats.rx_errors, dev->stats.tx_errors
-               );
-
-       /* ensure there are no more active requests */
-       if (dev->config) {
-               usb_ep_disable (dev->in_ep);
-               usb_ep_disable (dev->out_ep);
-               if (netif_carrier_ok (dev->net)) {
-                       DEBUG (dev, "host still using in/out endpoints\n");
-                       // FIXME idiom may leave toggle wrong here
-                       usb_ep_enable (dev->in_ep, dev->in);
-                       usb_ep_enable (dev->out_ep, dev->out);
-               }
-               if (dev->status_ep) {
-                       usb_ep_disable (dev->status_ep);
-                       usb_ep_enable (dev->status_ep, dev->status);
-               }
-       }
-
-       if (rndis_active(dev)) {
-               rndis_set_param_medium(dev->rndis_config, NDIS_MEDIUM_802_3, 0);
-               (void) rndis_signal_disconnect (dev->rndis_config);
-       }
-
-       return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static struct usb_request *
-eth_req_alloc (struct usb_ep *ep, unsigned size, gfp_t gfp_flags)
-{
-       struct usb_request      *req;
-
-       req = usb_ep_alloc_request (ep, gfp_flags);
-       if (!req)
-               return NULL;
-
-       req->buf = kmalloc (size, gfp_flags);
-       if (!req->buf) {
-               usb_ep_free_request (ep, req);
-               req = NULL;
-       }
-       return req;
-}
-
-static void
-eth_req_free (struct usb_ep *ep, struct usb_request *req)
-{
-       kfree (req->buf);
-       usb_ep_free_request (ep, req);
-}
-
-
-static void /* __init_or_exit */
-eth_unbind (struct usb_gadget *gadget)
+static void __exit cleanup(void)
 {
-       struct eth_dev          *dev = get_gadget_data (gadget);
-
-       DEBUG (dev, "unbind\n");
-       rndis_deregister (dev->rndis_config);
-       rndis_exit ();
-
-       /* we've already been disconnected ... no i/o is active */
-       if (dev->req) {
-               eth_req_free (gadget->ep0, dev->req);
-               dev->req = NULL;
-       }
-       if (dev->stat_req) {
-               eth_req_free (dev->status_ep, dev->stat_req);
-               dev->stat_req = NULL;
-       }
-
-       unregister_netdev (dev->net);
-       free_netdev(dev->net);
-
-       /* assuming we used keventd, it must quiesce too */
-       flush_scheduled_work ();
-       set_gadget_data (gadget, NULL);
-}
-
-static u8 __init nibble (unsigned char c)
-{
-       if (likely (isdigit (c)))
-               return c - '0';
-       c = toupper (c);
-       if (likely (isxdigit (c)))
-               return 10 + c - 'A';
-       return 0;
-}
-
-static int __init get_ether_addr(const char *str, u8 *dev_addr)
-{
-       if (str) {
-               unsigned        i;
-
-               for (i = 0; i < 6; i++) {
-                       unsigned char num;
-
-                       if((*str == '.') || (*str == ':'))
-                               str++;
-                       num = nibble(*str++) << 4;
-                       num |= (nibble(*str++));
-                       dev_addr [i] = num;
-               }
-               if (is_valid_ether_addr (dev_addr))
-                       return 0;
-       }
-       random_ether_addr(dev_addr);
-       return 1;
-}
-
-static int __init
-eth_bind (struct usb_gadget *gadget)
-{
-       struct eth_dev          *dev;
-       struct net_device       *net;
-       u8                      cdc = 1, zlp = 1, rndis = 1;
-       struct usb_ep           *in_ep, *out_ep, *status_ep = NULL;
-       int                     status = -ENOMEM;
-       int                     gcnum;
-
-       /* these flags are only ever cleared; compiler take note */
-#ifndef        DEV_CONFIG_CDC
-       cdc = 0;
-#endif
-#ifndef        CONFIG_USB_ETH_RNDIS
-       rndis = 0;
-#endif
-
-       /* Because most host side USB stacks handle CDC Ethernet, that
-        * standard protocol is _strongly_ preferred for interop purposes.
-        * (By everyone except Microsoft.)
-        */
-       if (gadget_is_pxa (gadget)) {
-               /* pxa doesn't support altsettings */
-               cdc = 0;
-       } else if (gadget_is_musbhdrc(gadget)) {
-               /* reduce tx dma overhead by avoiding special cases */
-               zlp = 0;
-       } else if (gadget_is_sh(gadget)) {
-               /* sh doesn't support multiple interfaces or configs */
-               cdc = 0;
-               rndis = 0;
-       } else if (gadget_is_sa1100 (gadget)) {
-               /* hardware can't write zlps */
-               zlp = 0;
-               /* sa1100 CAN do CDC, without status endpoint ... we use
-                * non-CDC to be compatible with ARM Linux-2.4 "usb-eth".
-                */
-               cdc = 0;
-       }
-
-       gcnum = usb_gadget_controller_number (gadget);
-       if (gcnum >= 0)
-               device_desc.bcdDevice = cpu_to_le16 (0x0200 + gcnum);
-       else {
-               /* can't assume CDC works.  don't want to default to
-                * anything less functional on CDC-capable hardware,
-                * so we fail in this case.
-                */
-               dev_err (&gadget->dev,
-                       "controller '%s' not recognized\n",
-                       gadget->name);
-               return -ENODEV;
-       }
-       snprintf (manufacturer, sizeof manufacturer, "%s %s/%s",
-               init_utsname()->sysname, init_utsname()->release,
-               gadget->name);
-
-       /* If there's an RNDIS configuration, that's what Windows wants to
-        * be using ... so use these product IDs here and in the "linux.inf"
-        * needed to install MSFT drivers.  Current Linux kernels will use
-        * the second configuration if it's CDC Ethernet, and need some help
-        * to choose the right configuration otherwise.
-        */
-       if (rndis) {
-               device_desc.idVendor =
-                       __constant_cpu_to_le16(RNDIS_VENDOR_NUM);
-               device_desc.idProduct =
-                       __constant_cpu_to_le16(RNDIS_PRODUCT_NUM);
-               snprintf (product_desc, sizeof product_desc,
-                       "RNDIS/%s", driver_desc);
-
-       /* CDC subset ... recognized by Linux since 2.4.10, but Windows
-        * drivers aren't widely available.  (That may be improved by
-        * supporting one submode of the "SAFE" variant of MDLM.)
-        */
-       } else if (!cdc) {
-               device_desc.idVendor =
-                       __constant_cpu_to_le16(SIMPLE_VENDOR_NUM);
-               device_desc.idProduct =
-                       __constant_cpu_to_le16(SIMPLE_PRODUCT_NUM);
-       }
-
-       /* support optional vendor/distro customization */
-       if (idVendor) {
-               if (!idProduct) {
-                       dev_err (&gadget->dev, "idVendor needs idProduct!\n");
-                       return -ENODEV;
-               }
-               device_desc.idVendor = cpu_to_le16(idVendor);
-               device_desc.idProduct = cpu_to_le16(idProduct);
-               if (bcdDevice)
-                       device_desc.bcdDevice = cpu_to_le16(bcdDevice);
-       }
-       if (iManufacturer)
-               strlcpy (manufacturer, iManufacturer, sizeof manufacturer);
-       if (iProduct)
-               strlcpy (product_desc, iProduct, sizeof product_desc);
-       if (iSerialNumber) {
-               device_desc.iSerialNumber = STRING_SERIALNUMBER,
-               strlcpy(serial_number, iSerialNumber, sizeof serial_number);
-       }
-
-       /* all we really need is bulk IN/OUT */
-       usb_ep_autoconfig_reset (gadget);
-       in_ep = usb_ep_autoconfig (gadget, &fs_source_desc);
-       if (!in_ep) {
-autoconf_fail:
-               dev_err (&gadget->dev,
-                       "can't autoconfigure on %s\n",
-                       gadget->name);
-               return -ENODEV;
-       }
-       in_ep->driver_data = in_ep;     /* claim */
-
-       out_ep = usb_ep_autoconfig (gadget, &fs_sink_desc);
-       if (!out_ep)
-               goto autoconf_fail;
-       out_ep->driver_data = out_ep;   /* claim */
-
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
-       /* CDC Ethernet control interface doesn't require a status endpoint.
-        * Since some hosts expect one, try to allocate one anyway.
-        */
-       if (cdc || rndis) {
-               status_ep = usb_ep_autoconfig (gadget, &fs_status_desc);
-               if (status_ep) {
-                       status_ep->driver_data = status_ep;     /* claim */
-               } else if (rndis) {
-                       dev_err (&gadget->dev,
-                               "can't run RNDIS on %s\n",
-                               gadget->name);
-                       return -ENODEV;
-#ifdef DEV_CONFIG_CDC
-               /* pxa25x only does CDC subset; often used with RNDIS */
-               } else if (cdc) {
-                       control_intf.bNumEndpoints = 0;
-                       /* FIXME remove endpoint from descriptor list */
-#endif
-               }
-       }
-#endif
-
-       /* one config:  cdc, else minimal subset */
-       if (!cdc) {
-               eth_config.bNumInterfaces = 1;
-               eth_config.iConfiguration = STRING_SUBSET;
-
-               /* use functions to set these up, in case we're built to work
-                * with multiple controllers and must override CDC Ethernet.
-                */
-               fs_subset_descriptors();
-               hs_subset_descriptors();
-       }
-
-       device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
-       usb_gadget_set_selfpowered (gadget);
-
-       /* For now RNDIS is always a second config */
-       if (rndis)
-               device_desc.bNumConfigurations = 2;
-
-       if (gadget_is_dualspeed(gadget)) {
-               if (rndis)
-                       dev_qualifier.bNumConfigurations = 2;
-               else if (!cdc)
-                       dev_qualifier.bDeviceClass = USB_CLASS_VENDOR_SPEC;
-
-               /* assumes ep0 uses the same value for both speeds ... */
-               dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;
-
-               /* and that all endpoints are dual-speed */
-               hs_source_desc.bEndpointAddress =
-                               fs_source_desc.bEndpointAddress;
-               hs_sink_desc.bEndpointAddress =
-                               fs_sink_desc.bEndpointAddress;
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
-               if (status_ep)
-                       hs_status_desc.bEndpointAddress =
-                                       fs_status_desc.bEndpointAddress;
-#endif
-       }
-
-       if (gadget_is_otg(gadget)) {
-               otg_descriptor.bmAttributes |= USB_OTG_HNP,
-               eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
-               eth_config.bMaxPower = 4;
-#ifdef CONFIG_USB_ETH_RNDIS
-               rndis_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
-               rndis_config.bMaxPower = 4;
-#endif
-       }
-
-       net = alloc_etherdev (sizeof *dev);
-       if (!net)
-               return status;
-       dev = netdev_priv(net);
-       spin_lock_init (&dev->lock);
-       spin_lock_init (&dev->req_lock);
-       INIT_WORK (&dev->work, eth_work);
-       INIT_LIST_HEAD (&dev->tx_reqs);
-       INIT_LIST_HEAD (&dev->rx_reqs);
-
-       /* network device setup */
-       dev->net = net;
-       strcpy (net->name, "usb%d");
-       dev->cdc = cdc;
-       dev->zlp = zlp;
-
-       dev->in_ep = in_ep;
-       dev->out_ep = out_ep;
-       dev->status_ep = status_ep;
-
-       /* Module params for these addresses should come from ID proms.
-        * The host side address is used with CDC and RNDIS, and commonly
-        * ends up in a persistent config database.  It's not clear if
-        * host side code for the SAFE thing cares -- its original BLAN
-        * thing didn't, Sharp never assigned those addresses on Zaurii.
-        */
-       if (get_ether_addr(dev_addr, net->dev_addr))
-               dev_warn(&gadget->dev,
-                       "using random %s ethernet address\n", "self");
-       if (get_ether_addr(host_addr, dev->host_mac))
-               dev_warn(&gadget->dev,
-                       "using random %s ethernet address\n", "host");
-       snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X",
-               dev->host_mac [0], dev->host_mac [1],
-               dev->host_mac [2], dev->host_mac [3],
-               dev->host_mac [4], dev->host_mac [5]);
-
-       if (rndis) {
-               status = rndis_init();
-               if (status < 0) {
-                       dev_err (&gadget->dev, "can't init RNDIS, %d\n",
-                               status);
-                       goto fail;
-               }
-       }
-
-       net->change_mtu = eth_change_mtu;
-       net->get_stats = eth_get_stats;
-       net->hard_start_xmit = eth_start_xmit;
-       net->open = eth_open;
-       net->stop = eth_stop;
-       // watchdog_timeo, tx_timeout ...
-       // set_multicast_list
-       SET_ETHTOOL_OPS(net, &ops);
-
-       /* preallocate control message data and buffer */
-       dev->req = eth_req_alloc (gadget->ep0, USB_BUFSIZ, GFP_KERNEL);
-       if (!dev->req)
-               goto fail;
-       dev->req->complete = eth_setup_complete;
-
-       /* ... and maybe likewise for status transfer */
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
-       if (dev->status_ep) {
-               dev->stat_req = eth_req_alloc (dev->status_ep,
-                                       STATUS_BYTECOUNT, GFP_KERNEL);
-               if (!dev->stat_req) {
-                       eth_req_free (gadget->ep0, dev->req);
-                       goto fail;
-               }
-               dev->stat_req->context = NULL;
-       }
-#endif
-
-       /* finish hookup to lower layer ... */
-       dev->gadget = gadget;
-       set_gadget_data (gadget, dev);
-       gadget->ep0->driver_data = dev;
-
-       /* two kinds of host-initiated state changes:
-        *  - iff DATA transfer is active, carrier is "on"
-        *  - tx queueing enabled if open *and* carrier is "on"
-        */
-       netif_stop_queue (dev->net);
-       netif_carrier_off (dev->net);
-
-       SET_NETDEV_DEV (dev->net, &gadget->dev);
-       status = register_netdev (dev->net);
-       if (status < 0)
-               goto fail1;
-
-       INFO (dev, "%s, version: " DRIVER_VERSION "\n", driver_desc);
-       INFO (dev, "using %s, OUT %s IN %s%s%s\n", gadget->name,
-               out_ep->name, in_ep->name,
-               status_ep ? " STATUS " : "",
-               status_ep ? status_ep->name : ""
-               );
-       INFO (dev, "MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
-               net->dev_addr [0], net->dev_addr [1],
-               net->dev_addr [2], net->dev_addr [3],
-               net->dev_addr [4], net->dev_addr [5]);
-
-       if (cdc || rndis)
-               INFO (dev, "HOST MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
-                       dev->host_mac [0], dev->host_mac [1],
-                       dev->host_mac [2], dev->host_mac [3],
-                       dev->host_mac [4], dev->host_mac [5]);
-
-       if (rndis) {
-               u32     vendorID = 0;
-
-               /* FIXME RNDIS vendor id == "vendor NIC code" == ? */
-
-               dev->rndis_config = rndis_register (rndis_control_ack);
-               if (dev->rndis_config < 0) {
-fail0:
-                       unregister_netdev (dev->net);
-                       status = -ENODEV;
-                       goto fail;
-               }
-
-               /* these set up a lot of the OIDs that RNDIS needs */
-               rndis_set_host_mac (dev->rndis_config, dev->host_mac);
-               if (rndis_set_param_dev (dev->rndis_config, dev->net,
-                                        &dev->stats, &dev->cdc_filter))
-                       goto fail0;
-               if (rndis_set_param_vendor(dev->rndis_config, vendorID,
-                                       manufacturer))
-                       goto fail0;
-               if (rndis_set_param_medium(dev->rndis_config,
-                                       NDIS_MEDIUM_802_3, 0))
-                       goto fail0;
-               INFO (dev, "RNDIS ready\n");
-       }
-
-       return status;
-
-fail1:
-       dev_dbg(&gadget->dev, "register_netdev failed, %d\n", status);
-fail:
-       eth_unbind (gadget);
-       return status;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void
-eth_suspend (struct usb_gadget *gadget)
-{
-       struct eth_dev          *dev = get_gadget_data (gadget);
-
-       DEBUG (dev, "suspend\n");
-       dev->suspended = 1;
-}
-
-static void
-eth_resume (struct usb_gadget *gadget)
-{
-       struct eth_dev          *dev = get_gadget_data (gadget);
-
-       DEBUG (dev, "resume\n");
-       dev->suspended = 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static struct usb_gadget_driver eth_driver = {
-       .speed          = DEVSPEED,
-
-       .function       = (char *) driver_desc,
-       .bind           = eth_bind,
-       .unbind         = eth_unbind,
-
-       .setup          = eth_setup,
-       .disconnect     = eth_disconnect,
-
-       .suspend        = eth_suspend,
-       .resume         = eth_resume,
-
-       .driver = {
-               .name           = (char *) shortname,
-               .owner          = THIS_MODULE,
-       },
-};
-
-MODULE_DESCRIPTION (DRIVER_DESC);
-MODULE_AUTHOR ("David Brownell, Benedikt Spanger");
-MODULE_LICENSE ("GPL");
-
-
-static int __init init (void)
-{
-       return usb_gadget_register_driver (&eth_driver);
+       usb_composite_unregister(&eth_driver);
 }
-module_init (init);
-
-static void __exit cleanup (void)
-{
-       usb_gadget_unregister_driver (&eth_driver);
-}
-module_exit (cleanup);
-
+module_exit(cleanup);
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
new file mode 100644 (file)
index 0000000..d8faccf
--- /dev/null
@@ -0,0 +1,589 @@
+/*
+ * f_acm.c -- USB CDC serial (ACM) function driver
+ *
+ * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
+ * Copyright (C) 2008 by David Brownell
+ * Copyright (C) 2008 by Nokia Corporation
+ *
+ * This software is distributed under the terms of the GNU General
+ * Public License ("GPL") as published by the Free Software Foundation,
+ * either version 2 of that License or (at your option) any later version.
+ */
+
+/* #define VERBOSE_DEBUG */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+
+#include "u_serial.h"
+#include "gadget_chips.h"
+
+
+/*
+ * This CDC ACM function support just wraps control functions and
+ * notifications around the generic serial-over-usb code.
+ *
+ * Because CDC ACM is standardized by the USB-IF, many host operating
+ * systems have drivers for it.  Accordingly, ACM is the preferred
+ * interop solution for serial-port type connections.  The control
+ * models are often not necessary, and in any case don't do much in
+ * this bare-bones implementation.
+ *
+ * Note that even MS-Windows has some support for ACM.  However, that
+ * support is somewhat broken because when you use ACM in a composite
+ * device, having multiple interfaces confuses the poor OS.  It doesn't
+ * seem to understand CDC Union descriptors.  The new "association"
+ * descriptors (roughly equivalent to CDC Unions) may sometimes help.
+ */
+
+struct acm_ep_descs {
+       struct usb_endpoint_descriptor  *in;
+       struct usb_endpoint_descriptor  *out;
+       struct usb_endpoint_descriptor  *notify;
+};
+
+struct f_acm {
+       struct gserial                  port;
+       u8                              ctrl_id, data_id;
+       u8                              port_num;
+
+       struct usb_descriptor_header    **fs_function;
+       struct acm_ep_descs             fs;
+       struct usb_descriptor_header    **hs_function;
+       struct acm_ep_descs             hs;
+
+       struct usb_ep                   *notify;
+       struct usb_endpoint_descriptor  *notify_desc;
+
+       struct usb_cdc_line_coding      port_line_coding;       /* 8-N-1 etc */
+       u16                             port_handshake_bits;
+#define RS232_RTS      (1 << 1)        /* unused with full duplex */
+#define RS232_DTR      (1 << 0)        /* host is ready for data r/w */
+};
+
+static inline struct f_acm *func_to_acm(struct usb_function *f)
+{
+       return container_of(f, struct f_acm, port.func);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* notification endpoint uses smallish and infrequent fixed-size messages */
+
+#define GS_LOG2_NOTIFY_INTERVAL                5       /* 1 << 5 == 32 msec */
+#define GS_NOTIFY_MAXPACKET            8
+
+/* interface and class descriptors: */
+
+static struct usb_interface_descriptor acm_control_interface_desc __initdata = {
+       .bLength =              USB_DT_INTERFACE_SIZE,
+       .bDescriptorType =      USB_DT_INTERFACE,
+       /* .bInterfaceNumber = DYNAMIC */
+       .bNumEndpoints =        1,
+       .bInterfaceClass =      USB_CLASS_COMM,
+       .bInterfaceSubClass =   USB_CDC_SUBCLASS_ACM,
+       .bInterfaceProtocol =   USB_CDC_ACM_PROTO_AT_V25TER,
+       /* .iInterface = DYNAMIC */
+};
+
+static struct usb_interface_descriptor acm_data_interface_desc __initdata = {
+       .bLength =              USB_DT_INTERFACE_SIZE,
+       .bDescriptorType =      USB_DT_INTERFACE,
+       /* .bInterfaceNumber = DYNAMIC */
+       .bNumEndpoints =        2,
+       .bInterfaceClass =      USB_CLASS_CDC_DATA,
+       .bInterfaceSubClass =   0,
+       .bInterfaceProtocol =   0,
+       /* .iInterface = DYNAMIC */
+};
+
+static struct usb_cdc_header_desc acm_header_desc __initdata = {
+       .bLength =              sizeof(acm_header_desc),
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
+       .bcdCDC =               __constant_cpu_to_le16(0x0110),
+};
+
+static struct usb_cdc_call_mgmt_descriptor
+acm_call_mgmt_descriptor __initdata = {
+       .bLength =              sizeof(acm_call_mgmt_descriptor),
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_CALL_MANAGEMENT_TYPE,
+       .bmCapabilities =       0,
+       /* .bDataInterface = DYNAMIC */
+};
+
+static struct usb_cdc_acm_descriptor acm_descriptor __initdata = {
+       .bLength =              sizeof(acm_descriptor),
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_ACM_TYPE,
+       .bmCapabilities =       (1 << 1),
+};
+
+static struct usb_cdc_union_desc acm_union_desc __initdata = {
+       .bLength =              sizeof(acm_union_desc),
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_UNION_TYPE,
+       /* .bMasterInterface0 = DYNAMIC */
+       /* .bSlaveInterface0 =  DYNAMIC */
+};
+
+/* full speed support: */
+
+static struct usb_endpoint_descriptor acm_fs_notify_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_INT,
+       .wMaxPacketSize =       __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
+       .bInterval =            1 << GS_LOG2_NOTIFY_INTERVAL,
+};
+
+static struct usb_endpoint_descriptor acm_fs_in_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_endpoint_descriptor acm_fs_out_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_descriptor_header *acm_fs_function[] __initdata = {
+       (struct usb_descriptor_header *) &acm_control_interface_desc,
+       (struct usb_descriptor_header *) &acm_header_desc,
+       (struct usb_descriptor_header *) &acm_call_mgmt_descriptor,
+       (struct usb_descriptor_header *) &acm_descriptor,
+       (struct usb_descriptor_header *) &acm_union_desc,
+       (struct usb_descriptor_header *) &acm_fs_notify_desc,
+       (struct usb_descriptor_header *) &acm_data_interface_desc,
+       (struct usb_descriptor_header *) &acm_fs_in_desc,
+       (struct usb_descriptor_header *) &acm_fs_out_desc,
+       NULL,
+};
+
+/* high speed support: */
+
+static struct usb_endpoint_descriptor acm_hs_notify_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_INT,
+       .wMaxPacketSize =       __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
+       .bInterval =            GS_LOG2_NOTIFY_INTERVAL+4,
+};
+
+static struct usb_endpoint_descriptor acm_hs_in_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor acm_hs_out_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_descriptor_header *acm_hs_function[] __initdata = {
+       (struct usb_descriptor_header *) &acm_control_interface_desc,
+       (struct usb_descriptor_header *) &acm_header_desc,
+       (struct usb_descriptor_header *) &acm_call_mgmt_descriptor,
+       (struct usb_descriptor_header *) &acm_descriptor,
+       (struct usb_descriptor_header *) &acm_union_desc,
+       (struct usb_descriptor_header *) &acm_hs_notify_desc,
+       (struct usb_descriptor_header *) &acm_data_interface_desc,
+       (struct usb_descriptor_header *) &acm_hs_in_desc,
+       (struct usb_descriptor_header *) &acm_hs_out_desc,
+       NULL,
+};
+
+/* string descriptors: */
+
+#define ACM_CTRL_IDX   0
+#define ACM_DATA_IDX   1
+
+/* static strings, in UTF-8 */
+static struct usb_string acm_string_defs[] = {
+       [ACM_CTRL_IDX].s = "CDC Abstract Control Model (ACM)",
+       [ACM_DATA_IDX].s = "CDC ACM Data",
+       {  /* ZEROES END LIST */ },
+};
+
+static struct usb_gadget_strings acm_string_table = {
+       .language =             0x0409, /* en-us */
+       .strings =              acm_string_defs,
+};
+
+static struct usb_gadget_strings *acm_strings[] = {
+       &acm_string_table,
+       NULL,
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* ACM control ... data handling is delegated to tty library code.
+ * The main task of this function is to activate and deactivate
+ * that code based on device state; track parameters like line
+ * speed, handshake state, and so on; and issue notifications.
+ */
+
+static void acm_complete_set_line_coding(struct usb_ep *ep,
+               struct usb_request *req)
+{
+       struct f_acm    *acm = ep->driver_data;
+       struct usb_composite_dev *cdev = acm->port.func.config->cdev;
+
+       if (req->status != 0) {
+               DBG(cdev, "acm ttyGS%d completion, err %d\n",
+                               acm->port_num, req->status);
+               return;
+       }
+
+       /* normal completion */
+       if (req->actual != sizeof(acm->port_line_coding)) {
+               DBG(cdev, "acm ttyGS%d short resp, len %d\n",
+                               acm->port_num, req->actual);
+               usb_ep_set_halt(ep);
+       } else {
+               struct usb_cdc_line_coding      *value = req->buf;
+
+               /* REVISIT:  we currently just remember this data.
+                * If we change that, (a) validate it first, then
+                * (b) update whatever hardware needs updating,
+                * (c) worry about locking.  This is information on
+                * the order of 9600-8-N-1 ... most of which means
+                * nothing unless we control a real RS232 line.
+                */
+               acm->port_line_coding = *value;
+       }
+}
+
+static int acm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
+{
+       struct f_acm            *acm = func_to_acm(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+       struct usb_request      *req = cdev->req;
+       int                     value = -EOPNOTSUPP;
+       u16                     w_index = le16_to_cpu(ctrl->wIndex);
+       u16                     w_value = le16_to_cpu(ctrl->wValue);
+       u16                     w_length = le16_to_cpu(ctrl->wLength);
+
+       /* composite driver infrastructure handles everything except
+        * CDC class messages; interface activation uses set_alt().
+        */
+       switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
+
+       /* SET_LINE_CODING ... just read and save what the host sends */
+       case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
+                       | USB_CDC_REQ_SET_LINE_CODING:
+               if (w_length != sizeof(struct usb_cdc_line_coding)
+                               || w_index != acm->ctrl_id)
+                       goto invalid;
+
+               value = w_length;
+               cdev->gadget->ep0->driver_data = acm;
+               req->complete = acm_complete_set_line_coding;
+               break;
+
+       /* GET_LINE_CODING ... return what host sent, or initial value */
+       case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
+                       | USB_CDC_REQ_GET_LINE_CODING:
+               if (w_index != acm->ctrl_id)
+                       goto invalid;
+
+               value = min_t(unsigned, w_length,
+                               sizeof(struct usb_cdc_line_coding));
+               memcpy(req->buf, &acm->port_line_coding, value);
+               break;
+
+       /* SET_CONTROL_LINE_STATE ... save what the host sent */
+       case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
+                       | USB_CDC_REQ_SET_CONTROL_LINE_STATE:
+               if (w_index != acm->ctrl_id)
+                       goto invalid;
+
+               value = 0;
+
+               /* FIXME we should not allow data to flow until the
+                * host sets the RS232_DTR bit; and when it clears
+                * that bit, we should return to that no-flow state.
+                */
+               acm->port_handshake_bits = w_value;
+               break;
+
+       default:
+invalid:
+               VDBG(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n",
+                       ctrl->bRequestType, ctrl->bRequest,
+                       w_value, w_index, w_length);
+       }
+
+       /* respond with data transfer or status phase? */
+       if (value >= 0) {
+               DBG(cdev, "acm ttyGS%d req%02x.%02x v%04x i%04x l%d\n",
+                       acm->port_num, ctrl->bRequestType, ctrl->bRequest,
+                       w_value, w_index, w_length);
+               req->zero = 0;
+               req->length = value;
+               value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
+               if (value < 0)
+                       ERROR(cdev, "acm response on ttyGS%d, err %d\n",
+                                       acm->port_num, value);
+       }
+
+       /* device either stalls (value < 0) or reports success */
+       return value;
+}
+
+static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+{
+       struct f_acm            *acm = func_to_acm(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+
+       /* we know alt == 0, so this is an activation or a reset */
+
+       if (intf == acm->ctrl_id) {
+               /* REVISIT this may need more work when we start to
+                * send notifications ...
+                */
+               if (acm->notify->driver_data) {
+                       VDBG(cdev, "reset acm control interface %d\n", intf);
+                       usb_ep_disable(acm->notify);
+               } else {
+                       VDBG(cdev, "init acm ctrl interface %d\n", intf);
+                       acm->notify_desc = ep_choose(cdev->gadget,
+                                       acm->hs.notify,
+                                       acm->fs.notify);
+               }
+               usb_ep_enable(acm->notify, acm->notify_desc);
+               acm->notify->driver_data = acm;
+
+       } else if (intf == acm->data_id) {
+               if (acm->port.in->driver_data) {
+                       DBG(cdev, "reset acm ttyGS%d\n", acm->port_num);
+                       gserial_disconnect(&acm->port);
+               } else {
+                       DBG(cdev, "activate acm ttyGS%d\n", acm->port_num);
+                       acm->port.in_desc = ep_choose(cdev->gadget,
+                                       acm->hs.in, acm->fs.in);
+                       acm->port.out_desc = ep_choose(cdev->gadget,
+                                       acm->hs.out, acm->fs.out);
+               }
+               gserial_connect(&acm->port, acm->port_num);
+
+       } else
+               return -EINVAL;
+
+       return 0;
+}
+
+static void acm_disable(struct usb_function *f)
+{
+       struct f_acm    *acm = func_to_acm(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+
+       DBG(cdev, "acm ttyGS%d deactivated\n", acm->port_num);
+       gserial_disconnect(&acm->port);
+       usb_ep_disable(acm->notify);
+       acm->notify->driver_data = NULL;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* ACM function driver setup/binding */
+static int __init
+acm_bind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_acm            *acm = func_to_acm(f);
+       int                     status;
+       struct usb_ep           *ep;
+
+       /* allocate instance-specific interface IDs, and patch descriptors */
+       status = usb_interface_id(c, f);
+       if (status < 0)
+               goto fail;
+       acm->ctrl_id = status;
+
+       acm_control_interface_desc.bInterfaceNumber = status;
+       acm_union_desc .bMasterInterface0 = status;
+
+       status = usb_interface_id(c, f);
+       if (status < 0)
+               goto fail;
+       acm->data_id = status;
+
+       acm_data_interface_desc.bInterfaceNumber = status;
+       acm_union_desc.bSlaveInterface0 = status;
+       acm_call_mgmt_descriptor.bDataInterface = status;
+
+       status = -ENODEV;
+
+       /* allocate instance-specific endpoints */
+       ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_in_desc);
+       if (!ep)
+               goto fail;
+       acm->port.in = ep;
+       ep->driver_data = cdev; /* claim */
+
+       ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_out_desc);
+       if (!ep)
+               goto fail;
+       acm->port.out = ep;
+       ep->driver_data = cdev; /* claim */
+
+       ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_notify_desc);
+       if (!ep)
+               goto fail;
+       acm->notify = ep;
+       ep->driver_data = cdev; /* claim */
+
+       /* copy descriptors, and track endpoint copies */
+       f->descriptors = usb_copy_descriptors(acm_fs_function);
+
+       acm->fs.in = usb_find_endpoint(acm_fs_function,
+                       f->descriptors, &acm_fs_in_desc);
+       acm->fs.out = usb_find_endpoint(acm_fs_function,
+                       f->descriptors, &acm_fs_out_desc);
+       acm->fs.notify = usb_find_endpoint(acm_fs_function,
+                       f->descriptors, &acm_fs_notify_desc);
+
+       /* support all relevant hardware speeds... we expect that when
+        * hardware is dual speed, all bulk-capable endpoints work at
+        * both speeds
+        */
+       if (gadget_is_dualspeed(c->cdev->gadget)) {
+               acm_hs_in_desc.bEndpointAddress =
+                               acm_fs_in_desc.bEndpointAddress;
+               acm_hs_out_desc.bEndpointAddress =
+                               acm_fs_out_desc.bEndpointAddress;
+               acm_hs_notify_desc.bEndpointAddress =
+                               acm_fs_notify_desc.bEndpointAddress;
+
+               /* copy descriptors, and track endpoint copies */
+               f->hs_descriptors = usb_copy_descriptors(acm_hs_function);
+
+               acm->hs.in = usb_find_endpoint(acm_hs_function,
+                               f->hs_descriptors, &acm_hs_in_desc);
+               acm->hs.out = usb_find_endpoint(acm_hs_function,
+                               f->hs_descriptors, &acm_hs_out_desc);
+               acm->hs.notify = usb_find_endpoint(acm_hs_function,
+                               f->hs_descriptors, &acm_hs_notify_desc);
+       }
+
+       /* FIXME provide a callback for triggering notifications */
+
+       DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n",
+                       acm->port_num,
+                       gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
+                       acm->port.in->name, acm->port.out->name,
+                       acm->notify->name);
+       return 0;
+
+fail:
+       /* we might as well release our claims on endpoints */
+       if (acm->notify)
+               acm->notify->driver_data = NULL;
+       if (acm->port.out)
+               acm->port.out->driver_data = NULL;
+       if (acm->port.in)
+               acm->port.in->driver_data = NULL;
+
+       ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status);
+
+       return status;
+}
+
+static void
+acm_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       if (gadget_is_dualspeed(c->cdev->gadget))
+               usb_free_descriptors(f->hs_descriptors);
+       usb_free_descriptors(f->descriptors);
+       kfree(func_to_acm(f));
+}
+
+/* Some controllers can't support CDC ACM ... */
+static inline bool can_support_cdc(struct usb_configuration *c)
+{
+       /* SH3 doesn't support multiple interfaces */
+       if (gadget_is_sh(c->cdev->gadget))
+               return false;
+
+       /* sa1100 doesn't have a third interrupt endpoint */
+       if (gadget_is_sa1100(c->cdev->gadget))
+               return false;
+
+       /* everything else is *probably* fine ... */
+       return true;
+}
+
+/**
+ * acm_bind_config - add a CDC ACM function to a configuration
+ * @c: the configuration to support the CDC ACM instance
+ * @port_num: /dev/ttyGS* port this interface will use
+ * Context: single threaded during gadget setup
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * Caller must have called @gserial_setup() with enough ports to
+ * handle all the ones it binds.  Caller is also responsible
+ * for calling @gserial_cleanup() before module unload.
+ */
+int __init acm_bind_config(struct usb_configuration *c, u8 port_num)
+{
+       struct f_acm    *acm;
+       int             status;
+
+       if (!can_support_cdc(c))
+               return -EINVAL;
+
+       /* REVISIT might want instance-specific strings to help
+        * distinguish instances ...
+        */
+
+       /* maybe allocate device-global string IDs, and patch descriptors */
+       if (acm_string_defs[ACM_CTRL_IDX].id == 0) {
+               status = usb_string_id(c->cdev);
+               if (status < 0)
+                       return status;
+               acm_string_defs[ACM_CTRL_IDX].id = status;
+
+               acm_control_interface_desc.iInterface = status;
+
+               status = usb_string_id(c->cdev);
+               if (status < 0)
+                       return status;
+               acm_string_defs[ACM_DATA_IDX].id = status;
+
+               acm_data_interface_desc.iInterface = status;
+       }
+
+       /* allocate and initialize one new instance */
+       acm = kzalloc(sizeof *acm, GFP_KERNEL);
+       if (!acm)
+               return -ENOMEM;
+
+       acm->port_num = port_num;
+
+       acm->port.func.name = "acm";
+       acm->port.func.strings = acm_strings;
+       /* descriptors are per-instance copies */
+       acm->port.func.bind = acm_bind;
+       acm->port.func.unbind = acm_unbind;
+       acm->port.func.set_alt = acm_set_alt;
+       acm->port.func.setup = acm_setup;
+       acm->port.func.disable = acm_disable;
+
+       status = usb_add_function(c, &acm->port.func);
+       if (status)
+               kfree(acm);
+       return status;
+}
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
new file mode 100644 (file)
index 0000000..0822e9d
--- /dev/null
@@ -0,0 +1,833 @@
+/*
+ * f_ecm.c -- USB CDC Ethernet (ECM) link function driver
+ *
+ * Copyright (C) 2003-2005,2008 David Brownell
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* #define VERBOSE_DEBUG */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+
+#include "u_ether.h"
+
+
+/*
+ * This function is a "CDC Ethernet Networking Control Model" (CDC ECM)
+ * Ethernet link.  The data transfer model is simple (packets sent and
+ * received over bulk endpoints using normal short packet termination),
+ * and the control model exposes various data and optional notifications.
+ *
+ * ECM is well standardized and (except for Microsoft) supported by most
+ * operating systems with USB host support.  It's the preferred interop
+ * solution for Ethernet over USB, at least for firmware based solutions.
+ * (Hardware solutions tend to be more minimalist.)  A newer and simpler
+ * "Ethernet Emulation Model" (CDC EEM) hasn't yet caught on.
+ *
+ * Note that ECM requires the use of "alternate settings" for its data
+ * interface.  This means that the set_alt() method has real work to do,
+ * and also means that a get_alt() method is required.
+ */
+
+struct ecm_ep_descs {
+       struct usb_endpoint_descriptor  *in;
+       struct usb_endpoint_descriptor  *out;
+       struct usb_endpoint_descriptor  *notify;
+};
+
+enum ecm_notify_state {
+       ECM_NOTIFY_NONE,                /* don't notify */
+       ECM_NOTIFY_CONNECT,             /* issue CONNECT next */
+       ECM_NOTIFY_SPEED,               /* issue SPEED_CHANGE next */
+};
+
+struct f_ecm {
+       struct gether                   port;
+       u8                              ctrl_id, data_id;
+
+       char                            ethaddr[14];
+
+       struct usb_descriptor_header    **fs_function;
+       struct ecm_ep_descs             fs;
+       struct usb_descriptor_header    **hs_function;
+       struct ecm_ep_descs             hs;
+
+       struct usb_ep                   *notify;
+       struct usb_endpoint_descriptor  *notify_desc;
+       struct usb_request              *notify_req;
+       u8                              notify_state;
+       bool                            is_open;
+
+       /* FIXME is_open needs some irq-ish locking
+        * ... possibly the same as port.ioport
+        */
+};
+
+static inline struct f_ecm *func_to_ecm(struct usb_function *f)
+{
+       return container_of(f, struct f_ecm, port.func);
+}
+
+/* peak (theoretical) bulk transfer rate in bits-per-second */
+static inline unsigned bitrate(struct usb_gadget *g)
+{
+       if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
+               return 13 * 512 * 8 * 1000 * 8;
+       else
+               return 19 *  64 * 1 * 1000 * 8;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Include the status endpoint if we can, even though it's optional.
+ *
+ * Use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one
+ * packet, to simplify cancellation; and a big transfer interval, to
+ * waste less bandwidth.
+ *
+ * Some drivers (like Linux 2.4 cdc-ether!) "need" it to exist even
+ * if they ignore the connect/disconnect notifications that real aether
+ * can provide.  More advanced cdc configurations might want to support
+ * encapsulated commands (vendor-specific, using control-OUT).
+ */
+
+#define LOG2_STATUS_INTERVAL_MSEC      5       /* 1 << 5 == 32 msec */
+#define STATUS_BYTECOUNT               16      /* 8 byte header + data */
+
+
+/* interface descriptor: */
+
+static struct usb_interface_descriptor ecm_control_intf __initdata = {
+       .bLength =              sizeof ecm_control_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+
+       /* .bInterfaceNumber = DYNAMIC */
+       /* status endpoint is optional; this could be patched later */
+       .bNumEndpoints =        1,
+       .bInterfaceClass =      USB_CLASS_COMM,
+       .bInterfaceSubClass =   USB_CDC_SUBCLASS_ETHERNET,
+       .bInterfaceProtocol =   USB_CDC_PROTO_NONE,
+       /* .iInterface = DYNAMIC */
+};
+
+static struct usb_cdc_header_desc header_desc __initdata = {
+       .bLength =              sizeof header_desc,
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
+
+       .bcdCDC =               __constant_cpu_to_le16(0x0110),
+};
+
+static struct usb_cdc_union_desc ecm_union_desc __initdata = {
+       .bLength =              sizeof(ecm_union_desc),
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_UNION_TYPE,
+       /* .bMasterInterface0 = DYNAMIC */
+       /* .bSlaveInterface0 =  DYNAMIC */
+};
+
+static struct usb_cdc_ether_desc ether_desc __initdata = {
+       .bLength =              sizeof ether_desc,
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_ETHERNET_TYPE,
+
+       /* this descriptor actually adds value, surprise! */
+       /* .iMACAddress = DYNAMIC */
+       .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
+       .wMaxSegmentSize =      __constant_cpu_to_le16(ETH_FRAME_LEN),
+       .wNumberMCFilters =     __constant_cpu_to_le16(0),
+       .bNumberPowerFilters =  0,
+};
+
+/* the default data interface has no endpoints ... */
+
+static struct usb_interface_descriptor ecm_data_nop_intf __initdata = {
+       .bLength =              sizeof ecm_data_nop_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+
+       .bInterfaceNumber =     1,
+       .bAlternateSetting =    0,
+       .bNumEndpoints =        0,
+       .bInterfaceClass =      USB_CLASS_CDC_DATA,
+       .bInterfaceSubClass =   0,
+       .bInterfaceProtocol =   0,
+       /* .iInterface = DYNAMIC */
+};
+
+/* ... but the "real" data interface has two bulk endpoints */
+
+static struct usb_interface_descriptor ecm_data_intf __initdata = {
+       .bLength =              sizeof ecm_data_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+
+       .bInterfaceNumber =     1,
+       .bAlternateSetting =    1,
+       .bNumEndpoints =        2,
+       .bInterfaceClass =      USB_CLASS_CDC_DATA,
+       .bInterfaceSubClass =   0,
+       .bInterfaceProtocol =   0,
+       /* .iInterface = DYNAMIC */
+};
+
+/* full speed support: */
+
+static struct usb_endpoint_descriptor fs_notify_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_INT,
+       .wMaxPacketSize =       __constant_cpu_to_le16(STATUS_BYTECOUNT),
+       .bInterval =            1 << LOG2_STATUS_INTERVAL_MSEC,
+};
+
+static struct usb_endpoint_descriptor fs_in_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_endpoint_descriptor fs_out_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_descriptor_header *eth_fs_function[] __initdata = {
+       /* CDC ECM control descriptors */
+       (struct usb_descriptor_header *) &ecm_control_intf,
+       (struct usb_descriptor_header *) &header_desc,
+       (struct usb_descriptor_header *) &ecm_union_desc,
+       (struct usb_descriptor_header *) &ether_desc,
+       /* NOTE: status endpoint might need to be removed */
+       (struct usb_descriptor_header *) &fs_notify_desc,
+       /* data interface, altsettings 0 and 1 */
+       (struct usb_descriptor_header *) &ecm_data_nop_intf,
+       (struct usb_descriptor_header *) &ecm_data_intf,
+       (struct usb_descriptor_header *) &fs_in_desc,
+       (struct usb_descriptor_header *) &fs_out_desc,
+       NULL,
+};
+
+/* high speed support: */
+
+static struct usb_endpoint_descriptor hs_notify_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_INT,
+       .wMaxPacketSize =       __constant_cpu_to_le16(STATUS_BYTECOUNT),
+       .bInterval =            LOG2_STATUS_INTERVAL_MSEC + 4,
+};
+static struct usb_endpoint_descriptor hs_in_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor hs_out_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_descriptor_header *eth_hs_function[] __initdata = {
+       /* CDC ECM control descriptors */
+       (struct usb_descriptor_header *) &ecm_control_intf,
+       (struct usb_descriptor_header *) &header_desc,
+       (struct usb_descriptor_header *) &ecm_union_desc,
+       (struct usb_descriptor_header *) &ether_desc,
+       /* NOTE: status endpoint might need to be removed */
+       (struct usb_descriptor_header *) &hs_notify_desc,
+       /* data interface, altsettings 0 and 1 */
+       (struct usb_descriptor_header *) &ecm_data_nop_intf,
+       (struct usb_descriptor_header *) &ecm_data_intf,
+       (struct usb_descriptor_header *) &hs_in_desc,
+       (struct usb_descriptor_header *) &hs_out_desc,
+       NULL,
+};
+
+/* string descriptors: */
+
+static struct usb_string ecm_string_defs[] = {
+       [0].s = "CDC Ethernet Control Model (ECM)",
+       [1].s = NULL /* DYNAMIC */,
+       [2].s = "CDC Ethernet Data",
+       {  } /* end of list */
+};
+
+static struct usb_gadget_strings ecm_string_table = {
+       .language =             0x0409, /* en-us */
+       .strings =              ecm_string_defs,
+};
+
+static struct usb_gadget_strings *ecm_strings[] = {
+       &ecm_string_table,
+       NULL,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static void ecm_do_notify(struct f_ecm *ecm)
+{
+       struct usb_request              *req = ecm->notify_req;
+       struct usb_cdc_notification     *event;
+       struct usb_composite_dev        *cdev = ecm->port.func.config->cdev;
+       __le32                          *data;
+       int                             status;
+
+       /* notification already in flight? */
+       if (!req)
+               return;
+
+       event = req->buf;
+       switch (ecm->notify_state) {
+       case ECM_NOTIFY_NONE:
+               return;
+
+       case ECM_NOTIFY_CONNECT:
+               event->bNotificationType = USB_CDC_NOTIFY_NETWORK_CONNECTION;
+               if (ecm->is_open)
+                       event->wValue = cpu_to_le16(1);
+               else
+                       event->wValue = cpu_to_le16(0);
+               event->wLength = 0;
+               req->length = sizeof *event;
+
+               DBG(cdev, "notify connect %s\n",
+                               ecm->is_open ? "true" : "false");
+               ecm->notify_state = ECM_NOTIFY_SPEED;
+               break;
+
+       case ECM_NOTIFY_SPEED:
+               event->bNotificationType = USB_CDC_NOTIFY_SPEED_CHANGE;
+               event->wValue = cpu_to_le16(0);
+               event->wLength = cpu_to_le16(8);
+               req->length = STATUS_BYTECOUNT;
+
+               /* SPEED_CHANGE data is up/down speeds in bits/sec */
+               data = req->buf + sizeof *event;
+               data[0] = cpu_to_le32(bitrate(cdev->gadget));
+               data[1] = data[0];
+
+               DBG(cdev, "notify speed %d\n", bitrate(cdev->gadget));
+               ecm->notify_state = ECM_NOTIFY_NONE;
+               break;
+       }
+       event->bmRequestType = 0xA1;
+       event->wIndex = cpu_to_le16(ecm->ctrl_id);
+
+       ecm->notify_req = NULL;
+       status = usb_ep_queue(ecm->notify, req, GFP_ATOMIC);
+       if (status < 0) {
+               ecm->notify_req = req;
+               DBG(cdev, "notify --> %d\n", status);
+       }
+}
+
+static void ecm_notify(struct f_ecm *ecm)
+{
+       /* NOTE on most versions of Linux, host side cdc-ethernet
+        * won't listen for notifications until its netdevice opens.
+        * The first notification then sits in the FIFO for a long
+        * time, and the second one is queued.
+        */
+       ecm->notify_state = ECM_NOTIFY_CONNECT;
+       ecm_do_notify(ecm);
+}
+
+static void ecm_notify_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct f_ecm                    *ecm = req->context;
+       struct usb_composite_dev        *cdev = ecm->port.func.config->cdev;
+       struct usb_cdc_notification     *event = req->buf;
+
+       switch (req->status) {
+       case 0:
+               /* no fault */
+               break;
+       case -ECONNRESET:
+       case -ESHUTDOWN:
+               ecm->notify_state = ECM_NOTIFY_NONE;
+               break;
+       default:
+               DBG(cdev, "event %02x --> %d\n",
+                       event->bNotificationType, req->status);
+               break;
+       }
+       ecm->notify_req = req;
+       ecm_do_notify(ecm);
+}
+
+static int ecm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
+{
+       struct f_ecm            *ecm = func_to_ecm(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+       struct usb_request      *req = cdev->req;
+       int                     value = -EOPNOTSUPP;
+       u16                     w_index = le16_to_cpu(ctrl->wIndex);
+       u16                     w_value = le16_to_cpu(ctrl->wValue);
+       u16                     w_length = le16_to_cpu(ctrl->wLength);
+
+       /* composite driver infrastructure handles everything except
+        * CDC class messages; interface activation uses set_alt().
+        */
+       switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
+       case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
+                       | USB_CDC_SET_ETHERNET_PACKET_FILTER:
+               /* see 6.2.30: no data, wIndex = interface,
+                * wValue = packet filter bitmap
+                */
+               if (w_length != 0 || w_index != ecm->ctrl_id)
+                       goto invalid;
+               DBG(cdev, "packet filter %02x\n", w_value);
+               /* REVISIT locking of cdc_filter.  This assumes the UDC
+                * driver won't have a concurrent packet TX irq running on
+                * another CPU; or that if it does, this write is atomic...
+                */
+               ecm->port.cdc_filter = w_value;
+               value = 0;
+               break;
+
+       /* and optionally:
+        * case USB_CDC_SEND_ENCAPSULATED_COMMAND:
+        * case USB_CDC_GET_ENCAPSULATED_RESPONSE:
+        * case USB_CDC_SET_ETHERNET_MULTICAST_FILTERS:
+        * case USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER:
+        * case USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER:
+        * case USB_CDC_GET_ETHERNET_STATISTIC:
+        */
+
+       default:
+invalid:
+               DBG(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n",
+                       ctrl->bRequestType, ctrl->bRequest,
+                       w_value, w_index, w_length);
+       }
+
+       /* respond with data transfer or status phase? */
+       if (value >= 0) {
+               DBG(cdev, "ecm req%02x.%02x v%04x i%04x l%d\n",
+                       ctrl->bRequestType, ctrl->bRequest,
+                       w_value, w_index, w_length);
+               req->zero = 0;
+               req->length = value;
+               value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
+               if (value < 0)
+                       ERROR(cdev, "ecm req %02x.%02x response err %d\n",
+                                       ctrl->bRequestType, ctrl->bRequest,
+                                       value);
+       }
+
+       /* device either stalls (value < 0) or reports success */
+       return value;
+}
+
+
+static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+{
+       struct f_ecm            *ecm = func_to_ecm(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+
+       /* Control interface has only altsetting 0 */
+       if (intf == ecm->ctrl_id) {
+               if (alt != 0)
+                       goto fail;
+
+               if (ecm->notify->driver_data) {
+                       VDBG(cdev, "reset ecm control %d\n", intf);
+                       usb_ep_disable(ecm->notify);
+               } else {
+                       VDBG(cdev, "init ecm ctrl %d\n", intf);
+                       ecm->notify_desc = ep_choose(cdev->gadget,
+                                       ecm->hs.notify,
+                                       ecm->fs.notify);
+               }
+               usb_ep_enable(ecm->notify, ecm->notify_desc);
+               ecm->notify->driver_data = ecm;
+
+       /* Data interface has two altsettings, 0 and 1 */
+       } else if (intf == ecm->data_id) {
+               if (alt > 1)
+                       goto fail;
+
+               if (ecm->port.in_ep->driver_data) {
+                       DBG(cdev, "reset ecm\n");
+                       gether_disconnect(&ecm->port);
+               }
+
+               if (!ecm->port.in) {
+                       DBG(cdev, "init ecm\n");
+                       ecm->port.in = ep_choose(cdev->gadget,
+                                       ecm->hs.in, ecm->fs.in);
+                       ecm->port.out = ep_choose(cdev->gadget,
+                                       ecm->hs.out, ecm->fs.out);
+               }
+
+               /* CDC Ethernet only sends data in non-default altsettings.
+                * Changing altsettings resets filters, statistics, etc.
+                */
+               if (alt == 1) {
+                       struct net_device       *net;
+
+                       /* Enable zlps by default for ECM conformance;
+                        * override for musb_hdrc (avoids txdma ovhead)
+                        * and sa1100 (can't).
+                        */
+                       ecm->port.is_zlp_ok = !(
+                                  gadget_is_sa1100(cdev->gadget)
+                               || gadget_is_musbhdrc(cdev->gadget)
+                               );
+                       ecm->port.cdc_filter = DEFAULT_FILTER;
+                       DBG(cdev, "activate ecm\n");
+                       net = gether_connect(&ecm->port);
+                       if (IS_ERR(net))
+                               return PTR_ERR(net);
+               }
+
+               /* NOTE this can be a minor disagreement with the ECM spec,
+                * which says speed notifications will "always" follow
+                * connection notifications.  But we allow one connect to
+                * follow another (if the first is in flight), and instead
+                * just guarantee that a speed notification is always sent.
+                */
+               ecm_notify(ecm);
+       } else
+               goto fail;
+
+       return 0;
+fail:
+       return -EINVAL;
+}
+
+/* Because the data interface supports multiple altsettings,
+ * this ECM function *MUST* implement a get_alt() method.
+ */
+static int ecm_get_alt(struct usb_function *f, unsigned intf)
+{
+       struct f_ecm            *ecm = func_to_ecm(f);
+
+       if (intf == ecm->ctrl_id)
+               return 0;
+       return ecm->port.in_ep->driver_data ? 1 : 0;
+}
+
+static void ecm_disable(struct usb_function *f)
+{
+       struct f_ecm            *ecm = func_to_ecm(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+
+       DBG(cdev, "ecm deactivated\n");
+
+       if (ecm->port.in_ep->driver_data)
+               gether_disconnect(&ecm->port);
+
+       if (ecm->notify->driver_data) {
+               usb_ep_disable(ecm->notify);
+               ecm->notify->driver_data = NULL;
+               ecm->notify_desc = NULL;
+       }
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Callbacks let us notify the host about connect/disconnect when the
+ * net device is opened or closed.
+ *
+ * For testing, note that link states on this side include both opened
+ * and closed variants of:
+ *
+ *   - disconnected/unconfigured
+ *   - configured but inactive (data alt 0)
+ *   - configured and active (data alt 1)
+ *
+ * Each needs to be tested with unplug, rmmod, SET_CONFIGURATION, and
+ * SET_INTERFACE (altsetting).  Remember also that "configured" doesn't
+ * imply the host is actually polling the notification endpoint, and
+ * likewise that "active" doesn't imply it's actually using the data
+ * endpoints for traffic.
+ */
+
+static void ecm_open(struct gether *geth)
+{
+       struct f_ecm            *ecm = func_to_ecm(&geth->func);
+
+       DBG(ecm->port.func.config->cdev, "%s\n", __func__);
+
+       ecm->is_open = true;
+       ecm_notify(ecm);
+}
+
+static void ecm_close(struct gether *geth)
+{
+       struct f_ecm            *ecm = func_to_ecm(&geth->func);
+
+       DBG(ecm->port.func.config->cdev, "%s\n", __func__);
+
+       ecm->is_open = false;
+       ecm_notify(ecm);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* ethernet function driver setup/binding */
+
+static int __init
+ecm_bind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_ecm            *ecm = func_to_ecm(f);
+       int                     status;
+       struct usb_ep           *ep;
+
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+       if (status < 0)
+               goto fail;
+       ecm->ctrl_id = status;
+
+       ecm_control_intf.bInterfaceNumber = status;
+       ecm_union_desc.bMasterInterface0 = status;
+
+       status = usb_interface_id(c, f);
+       if (status < 0)
+               goto fail;
+       ecm->data_id = status;
+
+       ecm_data_nop_intf.bInterfaceNumber = status;
+       ecm_data_intf.bInterfaceNumber = status;
+       ecm_union_desc.bSlaveInterface0 = status;
+
+       status = -ENODEV;
+
+       /* allocate instance-specific endpoints */
+       ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc);
+       if (!ep)
+               goto fail;
+       ecm->port.in_ep = ep;
+       ep->driver_data = cdev; /* claim */
+
+       ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
+       if (!ep)
+               goto fail;
+       ecm->port.out_ep = ep;
+       ep->driver_data = cdev; /* claim */
+
+       /* NOTE:  a status/notification endpoint is *OPTIONAL* but we
+        * don't treat it that way.  It's simpler, and some newer CDC
+        * profiles (wireless handsets) no longer treat it as optional.
+        */
+       ep = usb_ep_autoconfig(cdev->gadget, &fs_notify_desc);
+       if (!ep)
+               goto fail;
+       ecm->notify = ep;
+       ep->driver_data = cdev; /* claim */
+
+       status = -ENOMEM;
+
+       /* allocate notification request and buffer */
+       ecm->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL);
+       if (!ecm->notify_req)
+               goto fail;
+       ecm->notify_req->buf = kmalloc(STATUS_BYTECOUNT, GFP_KERNEL);
+       if (!ecm->notify_req->buf)
+               goto fail;
+       ecm->notify_req->context = ecm;
+       ecm->notify_req->complete = ecm_notify_complete;
+
+       /* copy descriptors, and track endpoint copies */
+       f->descriptors = usb_copy_descriptors(eth_fs_function);
+       if (!f->descriptors)
+               goto fail;
+
+       ecm->fs.in = usb_find_endpoint(eth_fs_function,
+                       f->descriptors, &fs_in_desc);
+       ecm->fs.out = usb_find_endpoint(eth_fs_function,
+                       f->descriptors, &fs_out_desc);
+       ecm->fs.notify = usb_find_endpoint(eth_fs_function,
+                       f->descriptors, &fs_notify_desc);
+
+       /* support all relevant hardware speeds... we expect that when
+        * hardware is dual speed, all bulk-capable endpoints work at
+        * both speeds
+        */
+       if (gadget_is_dualspeed(c->cdev->gadget)) {
+               hs_in_desc.bEndpointAddress =
+                               fs_in_desc.bEndpointAddress;
+               hs_out_desc.bEndpointAddress =
+                               fs_out_desc.bEndpointAddress;
+               hs_notify_desc.bEndpointAddress =
+                               fs_notify_desc.bEndpointAddress;
+
+               /* copy descriptors, and track endpoint copies */
+               f->hs_descriptors = usb_copy_descriptors(eth_hs_function);
+               if (!f->hs_descriptors)
+                       goto fail;
+
+               ecm->hs.in = usb_find_endpoint(eth_hs_function,
+                               f->hs_descriptors, &hs_in_desc);
+               ecm->hs.out = usb_find_endpoint(eth_hs_function,
+                               f->hs_descriptors, &hs_out_desc);
+               ecm->hs.notify = usb_find_endpoint(eth_hs_function,
+                               f->hs_descriptors, &hs_notify_desc);
+       }
+
+       /* NOTE:  all that is done without knowing or caring about
+        * the network link ... which is unavailable to this code
+        * until we're activated via set_alt().
+        */
+
+       ecm->port.open = ecm_open;
+       ecm->port.close = ecm_close;
+
+       DBG(cdev, "CDC Ethernet: %s speed IN/%s OUT/%s NOTIFY/%s\n",
+                       gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
+                       ecm->port.in_ep->name, ecm->port.out_ep->name,
+                       ecm->notify->name);
+       return 0;
+
+fail:
+       if (f->descriptors)
+               usb_free_descriptors(f->descriptors);
+
+       if (ecm->notify_req) {
+               kfree(ecm->notify_req->buf);
+               usb_ep_free_request(ecm->notify, ecm->notify_req);
+       }
+
+       /* we might as well release our claims on endpoints */
+       if (ecm->notify)
+               ecm->notify->driver_data = NULL;
+       if (ecm->port.out)
+               ecm->port.out_ep->driver_data = NULL;
+       if (ecm->port.in)
+               ecm->port.in_ep->driver_data = NULL;
+
+       ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
+
+       return status;
+}
+
+static void
+ecm_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct f_ecm            *ecm = func_to_ecm(f);
+
+       DBG(c->cdev, "ecm unbind\n");
+
+       if (gadget_is_dualspeed(c->cdev->gadget))
+               usb_free_descriptors(f->hs_descriptors);
+       usb_free_descriptors(f->descriptors);
+
+       kfree(ecm->notify_req->buf);
+       usb_ep_free_request(ecm->notify, ecm->notify_req);
+
+       ecm_string_defs[1].s = NULL;
+       kfree(ecm);
+}
+
+/**
+ * ecm_bind_config - add CDC Ethernet network link to a configuration
+ * @c: the configuration to support the network link
+ * @ethaddr: a buffer in which the ethernet address of the host side
+ *     side of the link was recorded
+ * Context: single threaded during gadget setup
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * Caller must have called @gether_setup().  Caller is also responsible
+ * for calling @gether_cleanup() before module unload.
+ */
+int __init ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
+{
+       struct f_ecm    *ecm;
+       int             status;
+
+       if (!can_support_ecm(c->cdev->gadget) || !ethaddr)
+               return -EINVAL;
+
+       /* maybe allocate device-global string IDs */
+       if (ecm_string_defs[0].id == 0) {
+
+               /* control interface label */
+               status = usb_string_id(c->cdev);
+               if (status < 0)
+                       return status;
+               ecm_string_defs[0].id = status;
+               ecm_control_intf.iInterface = status;
+
+               /* data interface label */
+               status = usb_string_id(c->cdev);
+               if (status < 0)
+                       return status;
+               ecm_string_defs[2].id = status;
+               ecm_data_intf.iInterface = status;
+
+               /* MAC address */
+               status = usb_string_id(c->cdev);
+               if (status < 0)
+                       return status;
+               ecm_string_defs[1].id = status;
+               ether_desc.iMACAddress = status;
+       }
+
+       /* allocate and initialize one new instance */
+       ecm = kzalloc(sizeof *ecm, GFP_KERNEL);
+       if (!ecm)
+               return -ENOMEM;
+
+       /* export host's Ethernet address in CDC format */
+       snprintf(ecm->ethaddr, sizeof ecm->ethaddr,
+               "%02X%02X%02X%02X%02X%02X",
+               ethaddr[0], ethaddr[1], ethaddr[2],
+               ethaddr[3], ethaddr[4], ethaddr[5]);
+       ecm_string_defs[1].s = ecm->ethaddr;
+
+       ecm->port.cdc_filter = DEFAULT_FILTER;
+
+       ecm->port.func.name = "cdc_ethernet";
+       ecm->port.func.strings = ecm_strings;
+       /* descriptors are per-instance copies */
+       ecm->port.func.bind = ecm_bind;
+       ecm->port.func.unbind = ecm_unbind;
+       ecm->port.func.set_alt = ecm_set_alt;
+       ecm->port.func.get_alt = ecm_get_alt;
+       ecm->port.func.setup = ecm_setup;
+       ecm->port.func.disable = ecm_disable;
+
+       status = usb_add_function(c, &ecm->port.func);
+       if (status) {
+               ecm_string_defs[1].s = NULL;
+               kfree(ecm);
+       }
+       return status;
+}
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
new file mode 100644 (file)
index 0000000..eda4cde
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * f_loopback.c - USB peripheral loopback configuration driver
+ *
+ * Copyright (C) 2003-2008 David Brownell
+ * Copyright (C) 2008 by Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* #define VERBOSE_DEBUG */
+
+#include <linux/kernel.h>
+#include <linux/utsname.h>
+#include <linux/device.h>
+
+#include "g_zero.h"
+#include "gadget_chips.h"
+
+
+/*
+ * LOOPBACK FUNCTION ... a testing vehicle for USB peripherals,
+ *
+ * This takes messages of various sizes written OUT to a device, and loops
+ * them back so they can be read IN from it.  It has been used by certain
+ * test applications.  It supports limited testing of data queueing logic.
+ *
+ *
+ * This is currently packaged as a configuration driver, which can't be
+ * combined with other functions to make composite devices.  However, it
+ * can be combined with other independent configurations.
+ */
+struct f_loopback {
+       struct usb_function     function;
+
+       struct usb_ep           *in_ep;
+       struct usb_ep           *out_ep;
+};
+
+static inline struct f_loopback *func_to_loop(struct usb_function *f)
+{
+       return container_of(f, struct f_loopback, function);
+}
+
+static unsigned qlen = 32;
+module_param(qlen, uint, 0);
+MODULE_PARM_DESC(qlenn, "depth of loopback queue");
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_interface_descriptor loopback_intf = {
+       .bLength =              sizeof loopback_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+
+       .bNumEndpoints =        2,
+       .bInterfaceClass =      USB_CLASS_VENDOR_SPEC,
+       /* .iInterface = DYNAMIC */
+};
+
+/* full speed support: */
+
+static struct usb_endpoint_descriptor fs_source_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_endpoint_descriptor fs_sink_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_descriptor_header *fs_loopback_descs[] = {
+       (struct usb_descriptor_header *) &loopback_intf,
+       (struct usb_descriptor_header *) &fs_sink_desc,
+       (struct usb_descriptor_header *) &fs_source_desc,
+       NULL,
+};
+
+/* high speed support: */
+
+static struct usb_endpoint_descriptor hs_source_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor hs_sink_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_descriptor_header *hs_loopback_descs[] = {
+       (struct usb_descriptor_header *) &loopback_intf,
+       (struct usb_descriptor_header *) &hs_source_desc,
+       (struct usb_descriptor_header *) &hs_sink_desc,
+       NULL,
+};
+
+/* function-specific strings: */
+
+static struct usb_string strings_loopback[] = {
+       [0].s = "loop input to output",
+       {  }                    /* end of list */
+};
+
+static struct usb_gadget_strings stringtab_loop = {
+       .language       = 0x0409,       /* en-us */
+       .strings        = strings_loopback,
+};
+
+static struct usb_gadget_strings *loopback_strings[] = {
+       &stringtab_loop,
+       NULL,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int __init
+loopback_bind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_loopback       *loop = func_to_loop(f);
+       int                     id;
+
+       /* allocate interface ID(s) */
+       id = usb_interface_id(c, f);
+       if (id < 0)
+               return id;
+       loopback_intf.bInterfaceNumber = id;
+
+       /* allocate endpoints */
+
+       loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
+       if (!loop->in_ep) {
+autoconf_fail:
+               ERROR(cdev, "%s: can't autoconfigure on %s\n",
+                       f->name, cdev->gadget->name);
+               return -ENODEV;
+       }
+       loop->in_ep->driver_data = cdev;        /* claim */
+
+       loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc);
+       if (!loop->out_ep)
+               goto autoconf_fail;
+       loop->out_ep->driver_data = cdev;       /* claim */
+
+       /* support high speed hardware */
+       if (gadget_is_dualspeed(c->cdev->gadget)) {
+               hs_source_desc.bEndpointAddress =
+                               fs_source_desc.bEndpointAddress;
+               hs_sink_desc.bEndpointAddress =
+                               fs_sink_desc.bEndpointAddress;
+               f->hs_descriptors = hs_loopback_descs;
+       }
+
+       DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
+                       gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
+                       f->name, loop->in_ep->name, loop->out_ep->name);
+       return 0;
+}
+
+static void
+loopback_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       kfree(func_to_loop(f));
+}
+
+static void loopback_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct f_loopback       *loop = ep->driver_data;
+       struct usb_composite_dev *cdev = loop->function.config->cdev;
+       int                     status = req->status;
+
+       switch (status) {
+
+       case 0:                         /* normal completion? */
+               if (ep == loop->out_ep) {
+                       /* loop this OUT packet back IN to the host */
+                       req->zero = (req->actual < req->length);
+                       req->length = req->actual;
+                       status = usb_ep_queue(loop->in_ep, req, GFP_ATOMIC);
+                       if (status == 0)
+                               return;
+
+                       /* "should never get here" */
+                       ERROR(cdev, "can't loop %s to %s: %d\n",
+                               ep->name, loop->in_ep->name,
+                               status);
+               }
+
+               /* queue the buffer for some later OUT packet */
+               req->length = buflen;
+               status = usb_ep_queue(loop->out_ep, req, GFP_ATOMIC);
+               if (status == 0)
+                       return;
+
+               /* "should never get here" */
+               /* FALLTHROUGH */
+
+       default:
+               ERROR(cdev, "%s loop complete --> %d, %d/%d\n", ep->name,
+                               status, req->actual, req->length);
+               /* FALLTHROUGH */
+
+       /* NOTE:  since this driver doesn't maintain an explicit record
+        * of requests it submitted (just maintains qlen count), we
+        * rely on the hardware driver to clean up on disconnect or
+        * endpoint disable.
+        */
+       case -ECONNABORTED:             /* hardware forced ep reset */
+       case -ECONNRESET:               /* request dequeued */
+       case -ESHUTDOWN:                /* disconnect from host */
+               free_ep_req(ep, req);
+               return;
+       }
+}
+
+static void disable_loopback(struct f_loopback *loop)
+{
+       struct usb_composite_dev        *cdev;
+
+       cdev = loop->function.config->cdev;
+       disable_endpoints(cdev, loop->in_ep, loop->out_ep);
+       VDBG(cdev, "%s disabled\n", loop->function.name);
+}
+
+static int
+enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop)
+{
+       int                                     result = 0;
+       const struct usb_endpoint_descriptor    *src, *sink;
+       struct usb_ep                           *ep;
+       struct usb_request                      *req;
+       unsigned                                i;
+
+       src = ep_choose(cdev->gadget, &hs_source_desc, &fs_source_desc);
+       sink = ep_choose(cdev->gadget, &hs_sink_desc, &fs_sink_desc);
+
+       /* one endpoint writes data back IN to the host */
+       ep = loop->in_ep;
+       result = usb_ep_enable(ep, src);
+       if (result < 0)
+               return result;
+       ep->driver_data = loop;
+
+       /* one endpoint just reads OUT packets */
+       ep = loop->out_ep;
+       result = usb_ep_enable(ep, sink);
+       if (result < 0) {
+fail0:
+               ep = loop->in_ep;
+               usb_ep_disable(ep);
+               ep->driver_data = NULL;
+               return result;
+       }
+       ep->driver_data = loop;
+
+       /* allocate a bunch of read buffers and queue them all at once.
+        * we buffer at most 'qlen' transfers; fewer if any need more
+        * than 'buflen' bytes each.
+        */
+       for (i = 0; i < qlen && result == 0; i++) {
+               req = alloc_ep_req(ep);
+               if (req) {
+                       req->complete = loopback_complete;
+                       result = usb_ep_queue(ep, req, GFP_ATOMIC);
+                       if (result)
+                               ERROR(cdev, "%s queue req --> %d\n",
+                                               ep->name, result);
+               } else {
+                       usb_ep_disable(ep);
+                       ep->driver_data = NULL;
+                       result = -ENOMEM;
+                       goto fail0;
+               }
+       }
+
+       DBG(cdev, "%s enabled\n", loop->function.name);
+       return result;
+}
+
+static int loopback_set_alt(struct usb_function *f,
+               unsigned intf, unsigned alt)
+{
+       struct f_loopback       *loop = func_to_loop(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+
+       /* we know alt is zero */
+       if (loop->in_ep->driver_data)
+               disable_loopback(loop);
+       return enable_loopback(cdev, loop);
+}
+
+static void loopback_disable(struct usb_function *f)
+{
+       struct f_loopback       *loop = func_to_loop(f);
+
+       disable_loopback(loop);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int __init loopback_bind_config(struct usb_configuration *c)
+{
+       struct f_loopback       *loop;
+       int                     status;
+
+       loop = kzalloc(sizeof *loop, GFP_KERNEL);
+       if (!loop)
+               return -ENOMEM;
+
+       loop->function.name = "loopback";
+       loop->function.descriptors = fs_loopback_descs;
+       loop->function.bind = loopback_bind;
+       loop->function.unbind = loopback_unbind;
+       loop->function.set_alt = loopback_set_alt;
+       loop->function.disable = loopback_disable;
+
+       status = usb_add_function(c, &loop->function);
+       if (status)
+               kfree(loop);
+       return status;
+}
+
+static struct usb_configuration loopback_driver = {
+       .label          = "loopback",
+       .strings        = loopback_strings,
+       .bind           = loopback_bind_config,
+       .bConfigurationValue = 2,
+       .bmAttributes   = USB_CONFIG_ATT_SELFPOWER,
+       .bMaxPower      = 1,    /* 2 mA, minimal */
+       /* .iConfiguration = DYNAMIC */
+};
+
+/**
+ * loopback_add - add a loopback testing configuration to a device
+ * @cdev: the device to support the loopback configuration
+ */
+int __init loopback_add(struct usb_composite_dev *cdev)
+{
+       int id;
+
+       /* allocate string ID(s) */
+       id = usb_string_id(cdev);
+       if (id < 0)
+               return id;
+       strings_loopback[0].id = id;
+
+       loopback_intf.iInterface = id;
+       loopback_driver.iConfiguration = id;
+
+       /* support OTG systems */
+       if (gadget_is_otg(cdev->gadget)) {
+               loopback_driver.descriptors = otg_desc;
+               loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+
+       return usb_add_config(cdev, &loopback_driver);
+}
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
new file mode 100644 (file)
index 0000000..61652f0
--- /dev/null
@@ -0,0 +1,827 @@
+/*
+ * f_rndis.c -- RNDIS link function driver
+ *
+ * Copyright (C) 2003-2005,2008 David Brownell
+ * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* #define VERBOSE_DEBUG */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+
+#include <asm/atomic.h>
+
+#include "u_ether.h"
+#include "rndis.h"
+
+
+/*
+ * This function is an RNDIS Ethernet port -- a Microsoft protocol that's
+ * been promoted instead of the standard CDC Ethernet.  The published RNDIS
+ * spec is ambiguous, incomplete, and needlessly complex.  Variants such as
+ * ActiveSync have even worse status in terms of specification.
+ *
+ * In short:  it's a protocol controlled by (and for) Microsoft, not for an
+ * Open ecosystem or markets.  Linux supports it *only* because Microsoft
+ * doesn't support the CDC Ethernet standard.
+ *
+ * The RNDIS data transfer model is complex, with multiple Ethernet packets
+ * per USB message, and out of band data.  The control model is built around
+ * what's essentially an "RNDIS RPC" protocol.  It's all wrapped in a CDC ACM
+ * (modem, not Ethernet) veneer, with those ACM descriptors being entirely
+ * useless (they're ignored).  RNDIS expects to be the only function in its
+ * configuration, so it's no real help if you need composite devices; and
+ * it expects to be the first configuration too.
+ *
+ * There is a single technical advantage of RNDIS over CDC Ethernet, if you
+ * discount the fluff that its RPC can be made to deliver: it doesn't need
+ * a NOP altsetting for the data interface.  That lets it work on some of the
+ * "so smart it's stupid" hardware which takes over configuration changes
+ * from the software, and adds restrictions like "no altsettings".
+ *
+ * Unfortunately MSFT's RNDIS drivers are buggy.  They hang or oops, and
+ * have all sorts of contrary-to-specification oddities that can prevent
+ * them from working sanely.  Since bugfixes (or accurate specs, letting
+ * Linux work around those bugs) are unlikely to ever come from MSFT, you
+ * may want to avoid using RNDIS on purely operational grounds.
+ *
+ * Omissions from the RNDIS 1.0 specification include:
+ *
+ *   - Power management ... references data that's scattered around lots
+ *     of other documentation, which is incorrect/incomplete there too.
+ *
+ *   - There are various undocumented protocol requirements, like the need
+ *     to send garbage in some control-OUT messages.
+ *
+ *   - MS-Windows drivers sometimes emit undocumented requests.
+ */
+
+struct rndis_ep_descs {
+       struct usb_endpoint_descriptor  *in;
+       struct usb_endpoint_descriptor  *out;
+       struct usb_endpoint_descriptor  *notify;
+};
+
+struct f_rndis {
+       struct gether                   port;
+       u8                              ctrl_id, data_id;
+       u8                              ethaddr[ETH_ALEN];
+       int                             config;
+
+       struct usb_descriptor_header    **fs_function;
+       struct rndis_ep_descs           fs;
+       struct usb_descriptor_header    **hs_function;
+       struct rndis_ep_descs           hs;
+
+       struct usb_ep                   *notify;
+       struct usb_endpoint_descriptor  *notify_desc;
+       struct usb_request              *notify_req;
+       atomic_t                        notify_count;
+};
+
+static inline struct f_rndis *func_to_rndis(struct usb_function *f)
+{
+       return container_of(f, struct f_rndis, port.func);
+}
+
+/* peak (theoretical) bulk transfer rate in bits-per-second */
+static unsigned int bitrate(struct usb_gadget *g)
+{
+       if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
+               return 13 * 512 * 8 * 1000 * 8;
+       else
+               return 19 *  64 * 1 * 1000 * 8;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ */
+
+#define LOG2_STATUS_INTERVAL_MSEC      5       /* 1 << 5 == 32 msec */
+#define STATUS_BYTECOUNT               8       /* 8 bytes data */
+
+
+/* interface descriptor: */
+
+static struct usb_interface_descriptor rndis_control_intf __initdata = {
+       .bLength =              sizeof rndis_control_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+
+       /* .bInterfaceNumber = DYNAMIC */
+       /* status endpoint is optional; this could be patched later */
+       .bNumEndpoints =        1,
+       .bInterfaceClass =      USB_CLASS_COMM,
+       .bInterfaceSubClass =   USB_CDC_SUBCLASS_ACM,
+       .bInterfaceProtocol =   USB_CDC_ACM_PROTO_VENDOR,
+       /* .iInterface = DYNAMIC */
+};
+
+static struct usb_cdc_header_desc header_desc __initdata = {
+       .bLength =              sizeof header_desc,
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
+
+       .bcdCDC =               __constant_cpu_to_le16(0x0110),
+};
+
+static struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor __initdata = {
+       .bLength =              sizeof call_mgmt_descriptor,
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_CALL_MANAGEMENT_TYPE,
+
+       .bmCapabilities =       0x00,
+       .bDataInterface =       0x01,
+};
+
+static struct usb_cdc_acm_descriptor acm_descriptor __initdata = {
+       .bLength =              sizeof acm_descriptor,
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_ACM_TYPE,
+
+       .bmCapabilities =       0x00,
+};
+
+static struct usb_cdc_union_desc rndis_union_desc __initdata = {
+       .bLength =              sizeof(rndis_union_desc),
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_UNION_TYPE,
+       /* .bMasterInterface0 = DYNAMIC */
+       /* .bSlaveInterface0 =  DYNAMIC */
+};
+
+/* the data interface has two bulk endpoints */
+
+static struct usb_interface_descriptor rndis_data_intf __initdata = {
+       .bLength =              sizeof rndis_data_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+
+       /* .bInterfaceNumber = DYNAMIC */
+       .bAlternateSetting =    1,
+       .bNumEndpoints =        2,
+       .bInterfaceClass =      USB_CLASS_CDC_DATA,
+       .bInterfaceSubClass =   0,
+       .bInterfaceProtocol =   0,
+       /* .iInterface = DYNAMIC */
+};
+
+/* full speed support: */
+
+static struct usb_endpoint_descriptor fs_notify_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_INT,
+       .wMaxPacketSize =       __constant_cpu_to_le16(STATUS_BYTECOUNT),
+       .bInterval =            1 << LOG2_STATUS_INTERVAL_MSEC,
+};
+
+static struct usb_endpoint_descriptor fs_in_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_endpoint_descriptor fs_out_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_descriptor_header *eth_fs_function[] __initdata = {
+       /* control interface matches ACM, not Ethernet */
+       (struct usb_descriptor_header *) &rndis_control_intf,
+       (struct usb_descriptor_header *) &header_desc,
+       (struct usb_descriptor_header *) &call_mgmt_descriptor,
+       (struct usb_descriptor_header *) &acm_descriptor,
+       (struct usb_descriptor_header *) &rndis_union_desc,
+       (struct usb_descriptor_header *) &fs_notify_desc,
+       /* data interface has no altsetting */
+       (struct usb_descriptor_header *) &rndis_data_intf,
+       (struct usb_descriptor_header *) &fs_in_desc,
+       (struct usb_descriptor_header *) &fs_out_desc,
+       NULL,
+};
+
+/* high speed support: */
+
+static struct usb_endpoint_descriptor hs_notify_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_INT,
+       .wMaxPacketSize =       __constant_cpu_to_le16(STATUS_BYTECOUNT),
+       .bInterval =            LOG2_STATUS_INTERVAL_MSEC + 4,
+};
+static struct usb_endpoint_descriptor hs_in_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor hs_out_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_descriptor_header *eth_hs_function[] __initdata = {
+       /* control interface matches ACM, not Ethernet */
+       (struct usb_descriptor_header *) &rndis_control_intf,
+       (struct usb_descriptor_header *) &header_desc,
+       (struct usb_descriptor_header *) &call_mgmt_descriptor,
+       (struct usb_descriptor_header *) &acm_descriptor,
+       (struct usb_descriptor_header *) &rndis_union_desc,
+       (struct usb_descriptor_header *) &hs_notify_desc,
+       /* data interface has no altsetting */
+       (struct usb_descriptor_header *) &rndis_data_intf,
+       (struct usb_descriptor_header *) &hs_in_desc,
+       (struct usb_descriptor_header *) &hs_out_desc,
+       NULL,
+};
+
+/* string descriptors: */
+
+static struct usb_string rndis_string_defs[] = {
+       [0].s = "RNDIS Communications Control",
+       [1].s = "RNDIS Ethernet Data",
+       {  } /* end of list */
+};
+
+static struct usb_gadget_strings rndis_string_table = {
+       .language =             0x0409, /* en-us */
+       .strings =              rndis_string_defs,
+};
+
+static struct usb_gadget_strings *rndis_strings[] = {
+       &rndis_string_table,
+       NULL,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static struct sk_buff *rndis_add_header(struct sk_buff *skb)
+{
+       skb = skb_realloc_headroom(skb, sizeof(struct rndis_packet_msg_type));
+       if (skb)
+               rndis_add_hdr(skb);
+       return skb;
+}
+
+static void rndis_response_available(void *_rndis)
+{
+       struct f_rndis                  *rndis = _rndis;
+       struct usb_request              *req = rndis->notify_req;
+       struct usb_composite_dev        *cdev = rndis->port.func.config->cdev;
+       __le32                          *data = req->buf;
+       int                             status;
+
+       if (atomic_inc_return(&rndis->notify_count))
+               return;
+
+       /* Send RNDIS RESPONSE_AVAILABLE notification; a
+        * USB_CDC_NOTIFY_RESPONSE_AVAILABLE "should" work too
+        *
+        * This is the only notification defined by RNDIS.
+        */
+       data[0] = cpu_to_le32(1);
+       data[1] = cpu_to_le32(0);
+
+       status = usb_ep_queue(rndis->notify, req, GFP_ATOMIC);
+       if (status) {
+               atomic_dec(&rndis->notify_count);
+               DBG(cdev, "notify/0 --> %d\n", status);
+       }
+}
+
+static void rndis_response_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct f_rndis                  *rndis = req->context;
+       struct usb_composite_dev        *cdev = rndis->port.func.config->cdev;
+       int                             status = req->status;
+
+       /* after TX:
+        *  - USB_CDC_GET_ENCAPSULATED_RESPONSE (ep0/control)
+        *  - RNDIS_RESPONSE_AVAILABLE (status/irq)
+        */
+       switch (status) {
+       case -ECONNRESET:
+       case -ESHUTDOWN:
+               /* connection gone */
+               atomic_set(&rndis->notify_count, 0);
+               break;
+       default:
+               DBG(cdev, "RNDIS %s response error %d, %d/%d\n",
+                       ep->name, status,
+                       req->actual, req->length);
+               /* FALLTHROUGH */
+       case 0:
+               if (ep != rndis->notify)
+                       break;
+
+               /* handle multiple pending RNDIS_RESPONSE_AVAILABLE
+                * notifications by resending until we're done
+                */
+               if (atomic_dec_and_test(&rndis->notify_count))
+                       break;
+               status = usb_ep_queue(rndis->notify, req, GFP_ATOMIC);
+               if (status) {
+                       atomic_dec(&rndis->notify_count);
+                       DBG(cdev, "notify/1 --> %d\n", status);
+               }
+               break;
+       }
+}
+
+static void rndis_command_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct f_rndis                  *rndis = req->context;
+       struct usb_composite_dev        *cdev = rndis->port.func.config->cdev;
+       int                             status;
+
+       /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
+//     spin_lock(&dev->lock);
+       status = rndis_msg_parser(rndis->config, (u8 *) req->buf);
+       if (status < 0)
+               ERROR(cdev, "RNDIS command error %d, %d/%d\n",
+                       status, req->actual, req->length);
+//     spin_unlock(&dev->lock);
+}
+
+static int
+rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
+{
+       struct f_rndis          *rndis = func_to_rndis(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+       struct usb_request      *req = cdev->req;
+       int                     value = -EOPNOTSUPP;
+       u16                     w_index = le16_to_cpu(ctrl->wIndex);
+       u16                     w_value = le16_to_cpu(ctrl->wValue);
+       u16                     w_length = le16_to_cpu(ctrl->wLength);
+
+       /* composite driver infrastructure handles everything except
+        * CDC class messages; interface activation uses set_alt().
+        */
+       switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
+
+       /* RNDIS uses the CDC command encapsulation mechanism to implement
+        * an RPC scheme, with much getting/setting of attributes by OID.
+        */
+       case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
+                       | USB_CDC_SEND_ENCAPSULATED_COMMAND:
+               if (w_length > req->length || w_value
+                               || w_index != rndis->ctrl_id)
+                       goto invalid;
+               /* read the request; process it later */
+               value = w_length;
+               req->complete = rndis_command_complete;
+               req->context = rndis;
+               /* later, rndis_response_available() sends a notification */
+               break;
+
+       case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
+                       | USB_CDC_GET_ENCAPSULATED_RESPONSE:
+               if (w_value || w_index != rndis->ctrl_id)
+                       goto invalid;
+               else {
+                       u8 *buf;
+                       u32 n;
+
+                       /* return the result */
+                       buf = rndis_get_next_response(rndis->config, &n);
+                       if (buf) {
+                               memcpy(req->buf, buf, n);
+                               req->complete = rndis_response_complete;
+                               rndis_free_response(rndis->config, buf);
+                               value = n;
+                       }
+                       /* else stalls ... spec says to avoid that */
+               }
+               break;
+
+       default:
+invalid:
+               VDBG(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n",
+                       ctrl->bRequestType, ctrl->bRequest,
+                       w_value, w_index, w_length);
+       }
+
+       /* respond with data transfer or status phase? */
+       if (value >= 0) {
+               DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n",
+                       ctrl->bRequestType, ctrl->bRequest,
+                       w_value, w_index, w_length);
+               req->zero = 0;
+               req->length = value;
+               value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
+               if (value < 0)
+                       ERROR(cdev, "rndis response on err %d\n", value);
+       }
+
+       /* device either stalls (value < 0) or reports success */
+       return value;
+}
+
+
+static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+{
+       struct f_rndis          *rndis = func_to_rndis(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+
+       /* we know alt == 0 */
+
+       if (intf == rndis->ctrl_id) {
+               if (rndis->notify->driver_data) {
+                       VDBG(cdev, "reset rndis control %d\n", intf);
+                       usb_ep_disable(rndis->notify);
+               } else {
+                       VDBG(cdev, "init rndis ctrl %d\n", intf);
+                       rndis->notify_desc = ep_choose(cdev->gadget,
+                                       rndis->hs.notify,
+                                       rndis->fs.notify);
+               }
+               usb_ep_enable(rndis->notify, rndis->notify_desc);
+               rndis->notify->driver_data = rndis;
+
+       } else if (intf == rndis->data_id) {
+               struct net_device       *net;
+
+               if (rndis->port.in_ep->driver_data) {
+                       DBG(cdev, "reset rndis\n");
+                       gether_disconnect(&rndis->port);
+               } else {
+                       DBG(cdev, "init rndis\n");
+                       rndis->port.in = ep_choose(cdev->gadget,
+                                       rndis->hs.in, rndis->fs.in);
+                       rndis->port.out = ep_choose(cdev->gadget,
+                                       rndis->hs.out, rndis->fs.out);
+               }
+
+               /* Avoid ZLPs; they can be troublesome. */
+               rndis->port.is_zlp_ok = false;
+
+               /* RNDIS should be in the "RNDIS uninitialized" state,
+                * either never activated or after rndis_uninit().
+                *
+                * We don't want data to flow here until a nonzero packet
+                * filter is set, at which point it enters "RNDIS data
+                * initialized" state ... but we do want the endpoints
+                * to be activated.  It's a strange little state.
+                *
+                * REVISIT the RNDIS gadget code has done this wrong for a
+                * very long time.  We need another call to the link layer
+                * code -- gether_updown(...bool) maybe -- to do it right.
+                */
+               rndis->port.cdc_filter = 0;
+
+               DBG(cdev, "RNDIS RX/TX early activation ... \n");
+               net = gether_connect(&rndis->port);
+               if (IS_ERR(net))
+                       return PTR_ERR(net);
+
+               rndis_set_param_dev(rndis->config, net,
+                               &rndis->port.cdc_filter);
+       } else
+               goto fail;
+
+       return 0;
+fail:
+       return -EINVAL;
+}
+
+static void rndis_disable(struct usb_function *f)
+{
+       struct f_rndis          *rndis = func_to_rndis(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+
+       if (!rndis->notify->driver_data)
+               return;
+
+       DBG(cdev, "rndis deactivated\n");
+
+       rndis_uninit(rndis->config);
+       gether_disconnect(&rndis->port);
+
+       usb_ep_disable(rndis->notify);
+       rndis->notify->driver_data = NULL;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * This isn't quite the same mechanism as CDC Ethernet, since the
+ * notification scheme passes less data, but the same set of link
+ * states must be tested.  A key difference is that altsettings are
+ * not used to tell whether the link should send packets or not.
+ */
+
+static void rndis_open(struct gether *geth)
+{
+       struct f_rndis          *rndis = func_to_rndis(&geth->func);
+       struct usb_composite_dev *cdev = geth->func.config->cdev;
+
+       DBG(cdev, "%s\n", __func__);
+
+       rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3,
+                               bitrate(cdev->gadget) / 100);
+       rndis_signal_connect(rndis->config);
+}
+
+static void rndis_close(struct gether *geth)
+{
+       struct f_rndis          *rndis = func_to_rndis(&geth->func);
+
+       DBG(geth->func.config->cdev, "%s\n", __func__);
+
+       rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, 0);
+       rndis_signal_disconnect(rndis->config);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* ethernet function driver setup/binding */
+
+static int __init
+rndis_bind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_rndis          *rndis = func_to_rndis(f);
+       int                     status;
+       struct usb_ep           *ep;
+
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+       if (status < 0)
+               goto fail;
+       rndis->ctrl_id = status;
+
+       rndis_control_intf.bInterfaceNumber = status;
+       rndis_union_desc.bMasterInterface0 = status;
+
+       status = usb_interface_id(c, f);
+       if (status < 0)
+               goto fail;
+       rndis->data_id = status;
+
+       rndis_data_intf.bInterfaceNumber = status;
+       rndis_union_desc.bSlaveInterface0 = status;
+
+       status = -ENODEV;
+
+       /* allocate instance-specific endpoints */
+       ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc);
+       if (!ep)
+               goto fail;
+       rndis->port.in_ep = ep;
+       ep->driver_data = cdev; /* claim */
+
+       ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
+       if (!ep)
+               goto fail;
+       rndis->port.out_ep = ep;
+       ep->driver_data = cdev; /* claim */
+
+       /* NOTE:  a status/notification endpoint is, strictly speaking,
+        * optional.  We don't treat it that way though!  It's simpler,
+        * and some newer profiles don't treat it as optional.
+        */
+       ep = usb_ep_autoconfig(cdev->gadget, &fs_notify_desc);
+       if (!ep)
+               goto fail;
+       rndis->notify = ep;
+       ep->driver_data = cdev; /* claim */
+
+       status = -ENOMEM;
+
+       /* allocate notification request and buffer */
+       rndis->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL);
+       if (!rndis->notify_req)
+               goto fail;
+       rndis->notify_req->buf = kmalloc(STATUS_BYTECOUNT, GFP_KERNEL);
+       if (!rndis->notify_req->buf)
+               goto fail;
+       rndis->notify_req->length = STATUS_BYTECOUNT;
+       rndis->notify_req->context = rndis;
+       rndis->notify_req->complete = rndis_response_complete;
+
+       /* copy descriptors, and track endpoint copies */
+       f->descriptors = usb_copy_descriptors(eth_fs_function);
+       if (!f->descriptors)
+               goto fail;
+
+       rndis->fs.in = usb_find_endpoint(eth_fs_function,
+                       f->descriptors, &fs_in_desc);
+       rndis->fs.out = usb_find_endpoint(eth_fs_function,
+                       f->descriptors, &fs_out_desc);
+       rndis->fs.notify = usb_find_endpoint(eth_fs_function,
+                       f->descriptors, &fs_notify_desc);
+
+       /* support all relevant hardware speeds... we expect that when
+        * hardware is dual speed, all bulk-capable endpoints work at
+        * both speeds
+        */
+       if (gadget_is_dualspeed(c->cdev->gadget)) {
+               hs_in_desc.bEndpointAddress =
+                               fs_in_desc.bEndpointAddress;
+               hs_out_desc.bEndpointAddress =
+                               fs_out_desc.bEndpointAddress;
+
+               /* copy descriptors, and track endpoint copies */
+               f->hs_descriptors = usb_copy_descriptors(eth_hs_function);
+
+               if (!f->hs_descriptors)
+                       goto fail;
+
+               rndis->hs.in = usb_find_endpoint(eth_hs_function,
+                               f->hs_descriptors, &hs_in_desc);
+               rndis->hs.out = usb_find_endpoint(eth_hs_function,
+                               f->hs_descriptors, &hs_out_desc);
+       }
+
+       rndis->port.open = rndis_open;
+       rndis->port.close = rndis_close;
+
+       status = rndis_register(rndis_response_available, rndis);
+       if (status < 0)
+               goto fail;
+       rndis->config = status;
+
+       rndis_set_param_medium(rndis->config, NDIS_MEDIUM_802_3, 0);
+       rndis_set_host_mac(rndis->config, rndis->ethaddr);
+
+#if 0
+// FIXME
+       if (rndis_set_param_vendor(rndis->config, vendorID,
+                               manufacturer))
+               goto fail0;
+#endif
+
+       /* NOTE:  all that is done without knowing or caring about
+        * the network link ... which is unavailable to this code
+        * until we're activated via set_alt().
+        */
+
+       DBG(cdev, "RNDIS: %s speed IN/%s OUT/%s NOTIFY/%s\n",
+                       gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
+                       rndis->port.in_ep->name, rndis->port.out_ep->name,
+                       rndis->notify->name);
+       return 0;
+
+fail:
+       if (gadget_is_dualspeed(c->cdev->gadget) && f->hs_descriptors)
+               usb_free_descriptors(f->hs_descriptors);
+       if (f->descriptors)
+               usb_free_descriptors(f->descriptors);
+
+       if (rndis->notify_req) {
+               kfree(rndis->notify_req->buf);
+               usb_ep_free_request(rndis->notify, rndis->notify_req);
+       }
+
+       /* we might as well release our claims on endpoints */
+       if (rndis->notify)
+               rndis->notify->driver_data = NULL;
+       if (rndis->port.out)
+               rndis->port.out_ep->driver_data = NULL;
+       if (rndis->port.in)
+               rndis->port.in_ep->driver_data = NULL;
+
+       ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
+
+       return status;
+}
+
+static void
+rndis_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct f_rndis          *rndis = func_to_rndis(f);
+
+       rndis_deregister(rndis->config);
+       rndis_exit();
+
+       if (gadget_is_dualspeed(c->cdev->gadget))
+               usb_free_descriptors(f->hs_descriptors);
+       usb_free_descriptors(f->descriptors);
+
+       kfree(rndis->notify_req->buf);
+       usb_ep_free_request(rndis->notify, rndis->notify_req);
+
+       kfree(rndis);
+}
+
+/* Some controllers can't support RNDIS ... */
+static inline bool can_support_rndis(struct usb_configuration *c)
+{
+       /* only two endpoints on sa1100 */
+       if (gadget_is_sa1100(c->cdev->gadget))
+               return false;
+
+       /* everything else is *presumably* fine */
+       return true;
+}
+
+/**
+ * rndis_bind_config - add RNDIS network link to a configuration
+ * @c: the configuration to support the network link
+ * @ethaddr: a buffer in which the ethernet address of the host side
+ *     side of the link was recorded
+ * Context: single threaded during gadget setup
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * Caller must have called @gether_setup().  Caller is also responsible
+ * for calling @gether_cleanup() before module unload.
+ */
+int __init rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
+{
+       struct f_rndis  *rndis;
+       int             status;
+
+       if (!can_support_rndis(c) || !ethaddr)
+               return -EINVAL;
+
+       /* maybe allocate device-global string IDs */
+       if (rndis_string_defs[0].id == 0) {
+
+               /* ... and setup RNDIS itself */
+               status = rndis_init();
+               if (status < 0)
+                       return status;
+
+               /* control interface label */
+               status = usb_string_id(c->cdev);
+               if (status < 0)
+                       return status;
+               rndis_string_defs[0].id = status;
+               rndis_control_intf.iInterface = status;
+
+               /* data interface label */
+               status = usb_string_id(c->cdev);
+               if (status < 0)
+                       return status;
+               rndis_string_defs[1].id = status;
+               rndis_data_intf.iInterface = status;
+       }
+
+       /* allocate and initialize one new instance */
+       status = -ENOMEM;
+       rndis = kzalloc(sizeof *rndis, GFP_KERNEL);
+       if (!rndis)
+               goto fail;
+
+       memcpy(rndis->ethaddr, ethaddr, ETH_ALEN);
+
+       /* RNDIS activates when the host changes this filter */
+       rndis->port.cdc_filter = 0;
+
+       /* RNDIS has special (and complex) framing */
+       rndis->port.header_len = sizeof(struct rndis_packet_msg_type);
+       rndis->port.wrap = rndis_add_header;
+       rndis->port.unwrap = rndis_rm_hdr;
+
+       rndis->port.func.name = "rndis";
+       rndis->port.func.strings = rndis_strings;
+       /* descriptors are per-instance copies */
+       rndis->port.func.bind = rndis_bind;
+       rndis->port.func.unbind = rndis_unbind;
+       rndis->port.func.set_alt = rndis_set_alt;
+       rndis->port.func.setup = rndis_setup;
+       rndis->port.func.disable = rndis_disable;
+
+       status = usb_add_function(c, &rndis->port.func);
+       if (status) {
+               kfree(rndis);
+fail:
+               rndis_exit();
+       }
+       return status;
+}
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
new file mode 100644 (file)
index 0000000..1b6bde9
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * f_serial.c - generic USB serial function driver
+ *
+ * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
+ * Copyright (C) 2008 by David Brownell
+ * Copyright (C) 2008 by Nokia Corporation
+ *
+ * This software is distributed under the terms of the GNU General
+ * Public License ("GPL") as published by the Free Software Foundation,
+ * either version 2 of that License or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+
+#include "u_serial.h"
+#include "gadget_chips.h"
+
+
+/*
+ * This function packages a simple "generic serial" port with no real
+ * control mechanisms, just raw data transfer over two bulk endpoints.
+ *
+ * Because it's not standardized, this isn't as interoperable as the
+ * CDC ACM driver.  However, for many purposes it's just as functional
+ * if you can arrange appropriate host side drivers.
+ */
+
+struct gser_descs {
+       struct usb_endpoint_descriptor  *in;
+       struct usb_endpoint_descriptor  *out;
+};
+
+struct f_gser {
+       struct gserial                  port;
+       u8                              data_id;
+       u8                              port_num;
+
+       struct usb_descriptor_header    **fs_function;
+       struct gser_descs               fs;
+       struct usb_descriptor_header    **hs_function;
+       struct gser_descs               hs;
+};
+
+static inline struct f_gser *func_to_gser(struct usb_function *f)
+{
+       return container_of(f, struct f_gser, port.func);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* interface descriptor: */
+
+static struct usb_interface_descriptor gser_interface_desc __initdata = {
+       .bLength =              USB_DT_INTERFACE_SIZE,
+       .bDescriptorType =      USB_DT_INTERFACE,
+       /* .bInterfaceNumber = DYNAMIC */
+       .bNumEndpoints =        2,
+       .bInterfaceClass =      USB_CLASS_VENDOR_SPEC,
+       .bInterfaceSubClass =   0,
+       .bInterfaceProtocol =   0,
+       /* .iInterface = DYNAMIC */
+};
+
+/* full speed support: */
+
+static struct usb_endpoint_descriptor gser_fs_in_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_endpoint_descriptor gser_fs_out_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_descriptor_header *gser_fs_function[] __initdata = {
+       (struct usb_descriptor_header *) &gser_interface_desc,
+       (struct usb_descriptor_header *) &gser_fs_in_desc,
+       (struct usb_descriptor_header *) &gser_fs_out_desc,
+       NULL,
+};
+
+/* high speed support: */
+
+static struct usb_endpoint_descriptor gser_hs_in_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor gser_hs_out_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_descriptor_header *gser_hs_function[] __initdata = {
+       (struct usb_descriptor_header *) &gser_interface_desc,
+       (struct usb_descriptor_header *) &gser_hs_in_desc,
+       (struct usb_descriptor_header *) &gser_hs_out_desc,
+       NULL,
+};
+
+/* string descriptors: */
+
+static struct usb_string gser_string_defs[] = {
+       [0].s = "Generic Serial",
+       {  } /* end of list */
+};
+
+static struct usb_gadget_strings gser_string_table = {
+       .language =             0x0409, /* en-us */
+       .strings =              gser_string_defs,
+};
+
+static struct usb_gadget_strings *gser_strings[] = {
+       &gser_string_table,
+       NULL,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+{
+       struct f_gser           *gser = func_to_gser(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+
+       /* we know alt == 0, so this is an activation or a reset */
+
+       if (gser->port.in->driver_data) {
+               DBG(cdev, "reset generic ttyGS%d\n", gser->port_num);
+               gserial_disconnect(&gser->port);
+       } else {
+               DBG(cdev, "activate generic ttyGS%d\n", gser->port_num);
+               gser->port.in_desc = ep_choose(cdev->gadget,
+                               gser->hs.in, gser->fs.in);
+               gser->port.out_desc = ep_choose(cdev->gadget,
+                               gser->hs.out, gser->fs.out);
+       }
+       gserial_connect(&gser->port, gser->port_num);
+       return 0;
+}
+
+static void gser_disable(struct usb_function *f)
+{
+       struct f_gser   *gser = func_to_gser(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+
+       DBG(cdev, "generic ttyGS%d deactivated\n", gser->port_num);
+       gserial_disconnect(&gser->port);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* serial function driver setup/binding */
+
+static int __init
+gser_bind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_gser           *gser = func_to_gser(f);
+       int                     status;
+       struct usb_ep           *ep;
+
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+       if (status < 0)
+               goto fail;
+       gser->data_id = status;
+       gser_interface_desc.bInterfaceNumber = status;
+
+       status = -ENODEV;
+
+       /* allocate instance-specific endpoints */
+       ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_in_desc);
+       if (!ep)
+               goto fail;
+       gser->port.in = ep;
+       ep->driver_data = cdev; /* claim */
+
+       ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_out_desc);
+       if (!ep)
+               goto fail;
+       gser->port.out = ep;
+       ep->driver_data = cdev; /* claim */
+
+       /* copy descriptors, and track endpoint copies */
+       f->descriptors = usb_copy_descriptors(gser_fs_function);
+
+       gser->fs.in = usb_find_endpoint(gser_fs_function,
+                       f->descriptors, &gser_fs_in_desc);
+       gser->fs.out = usb_find_endpoint(gser_fs_function,
+                       f->descriptors, &gser_fs_out_desc);
+
+
+       /* support all relevant hardware speeds... we expect that when
+        * hardware is dual speed, all bulk-capable endpoints work at
+        * both speeds
+        */
+       if (gadget_is_dualspeed(c->cdev->gadget)) {
+               gser_hs_in_desc.bEndpointAddress =
+                               gser_fs_in_desc.bEndpointAddress;
+               gser_hs_out_desc.bEndpointAddress =
+                               gser_fs_out_desc.bEndpointAddress;
+
+               /* copy descriptors, and track endpoint copies */
+               f->hs_descriptors = usb_copy_descriptors(gser_hs_function);
+
+               gser->hs.in = usb_find_endpoint(gser_hs_function,
+                               f->hs_descriptors, &gser_hs_in_desc);
+               gser->hs.out = usb_find_endpoint(gser_hs_function,
+                               f->hs_descriptors, &gser_hs_out_desc);
+       }
+
+       DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n",
+                       gser->port_num,
+                       gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
+                       gser->port.in->name, gser->port.out->name);
+       return 0;
+
+fail:
+       /* we might as well release our claims on endpoints */
+       if (gser->port.out)
+               gser->port.out->driver_data = NULL;
+       if (gser->port.in)
+               gser->port.in->driver_data = NULL;
+
+       ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
+
+       return status;
+}
+
+static void
+gser_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       if (gadget_is_dualspeed(c->cdev->gadget))
+               usb_free_descriptors(f->hs_descriptors);
+       usb_free_descriptors(f->descriptors);
+       kfree(func_to_gser(f));
+}
+
+/**
+ * gser_bind_config - add a generic serial function to a configuration
+ * @c: the configuration to support the serial instance
+ * @port_num: /dev/ttyGS* port this interface will use
+ * Context: single threaded during gadget setup
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * Caller must have called @gserial_setup() with enough ports to
+ * handle all the ones it binds.  Caller is also responsible
+ * for calling @gserial_cleanup() before module unload.
+ */
+int __init gser_bind_config(struct usb_configuration *c, u8 port_num)
+{
+       struct f_gser   *gser;
+       int             status;
+
+       /* REVISIT might want instance-specific strings to help
+        * distinguish instances ...
+        */
+
+       /* maybe allocate device-global string ID */
+       if (gser_string_defs[0].id == 0) {
+               status = usb_string_id(c->cdev);
+               if (status < 0)
+                       return status;
+               gser_string_defs[0].id = status;
+       }
+
+       /* allocate and initialize one new instance */
+       gser = kzalloc(sizeof *gser, GFP_KERNEL);
+       if (!gser)
+               return -ENOMEM;
+
+       gser->port_num = port_num;
+
+       gser->port.func.name = "gser";
+       gser->port.func.strings = gser_strings;
+       gser->port.func.bind = gser_bind;
+       gser->port.func.unbind = gser_unbind;
+       gser->port.func.set_alt = gser_set_alt;
+       gser->port.func.disable = gser_disable;
+
+       status = usb_add_function(c, &gser->port.func);
+       if (status)
+               kfree(gser);
+       return status;
+}
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
new file mode 100644 (file)
index 0000000..f18c3a1
--- /dev/null
@@ -0,0 +1,587 @@
+/*
+ * f_sourcesink.c - USB peripheral source/sink configuration driver
+ *
+ * Copyright (C) 2003-2008 David Brownell
+ * Copyright (C) 2008 by Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* #define VERBOSE_DEBUG */
+
+#include <linux/kernel.h>
+#include <linux/utsname.h>
+#include <linux/device.h>
+
+#include "g_zero.h"
+#include "gadget_chips.h"
+
+
+/*
+ * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral
+ * controller drivers.
+ *
+ * This just sinks bulk packets OUT to the peripheral and sources them IN
+ * to the host, optionally with specific data patterns for integrity tests.
+ * As such it supports basic functionality and load tests.
+ *
+ * In terms of control messaging, this supports all the standard requests
+ * plus two that support control-OUT tests.  If the optional "autoresume"
+ * mode is enabled, it provides good functional coverage for the "USBCV"
+ * test harness from USB-IF.
+ *
+ * Note that because this doesn't queue more than one request at a time,
+ * some other function must be used to test queueing logic.  The network
+ * link (g_ether) is the best overall option for that, since its TX and RX
+ * queues are relatively independent, will receive a range of packet sizes,
+ * and can often be made to run out completely.  Those issues are important
+ * when stress testing peripheral controller drivers.
+ *
+ *
+ * This is currently packaged as a configuration driver, which can't be
+ * combined with other functions to make composite devices.  However, it
+ * can be combined with other independent configurations.
+ */
+struct f_sourcesink {
+       struct usb_function     function;
+
+       struct usb_ep           *in_ep;
+       struct usb_ep           *out_ep;
+       struct timer_list       resume;
+};
+
+static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
+{
+       return container_of(f, struct f_sourcesink, function);
+}
+
+static unsigned autoresume;
+module_param(autoresume, uint, 0);
+MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
+
+static unsigned pattern;
+module_param(pattern, uint, 0);
+MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 ");
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_interface_descriptor source_sink_intf = {
+       .bLength =              sizeof source_sink_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+
+       .bNumEndpoints =        2,
+       .bInterfaceClass =      USB_CLASS_VENDOR_SPEC,
+       /* .iInterface = DYNAMIC */
+};
+
+/* full speed support: */
+
+static struct usb_endpoint_descriptor fs_source_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_endpoint_descriptor fs_sink_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_descriptor_header *fs_source_sink_descs[] = {
+       (struct usb_descriptor_header *) &source_sink_intf,
+       (struct usb_descriptor_header *) &fs_sink_desc,
+       (struct usb_descriptor_header *) &fs_source_desc,
+       NULL,
+};
+
+/* high speed support: */
+
+static struct usb_endpoint_descriptor hs_source_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor hs_sink_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_descriptor_header *hs_source_sink_descs[] = {
+       (struct usb_descriptor_header *) &source_sink_intf,
+       (struct usb_descriptor_header *) &hs_source_desc,
+       (struct usb_descriptor_header *) &hs_sink_desc,
+       NULL,
+};
+
+/* function-specific strings: */
+
+static struct usb_string strings_sourcesink[] = {
+       [0].s = "source and sink data",
+       {  }                    /* end of list */
+};
+
+static struct usb_gadget_strings stringtab_sourcesink = {
+       .language       = 0x0409,       /* en-us */
+       .strings        = strings_sourcesink,
+};
+
+static struct usb_gadget_strings *sourcesink_strings[] = {
+       &stringtab_sourcesink,
+       NULL,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static void sourcesink_autoresume(unsigned long _c)
+{
+       struct usb_composite_dev *cdev = (void *)_c;
+       struct usb_gadget       *g = cdev->gadget;
+
+       /* Normally the host would be woken up for something
+        * more significant than just a timer firing; likely
+        * because of some direct user request.
+        */
+       if (g->speed != USB_SPEED_UNKNOWN) {
+               int status = usb_gadget_wakeup(g);
+               DBG(cdev, "%s --> %d\n", __func__, status);
+       }
+}
+
+static int __init
+sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_sourcesink     *ss = func_to_ss(f);
+       int     id;
+
+       /* allocate interface ID(s) */
+       id = usb_interface_id(c, f);
+       if (id < 0)
+               return id;
+       source_sink_intf.bInterfaceNumber = id;
+
+       /* allocate endpoints */
+       ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
+       if (!ss->in_ep) {
+autoconf_fail:
+               ERROR(cdev, "%s: can't autoconfigure on %s\n",
+                       f->name, cdev->gadget->name);
+               return -ENODEV;
+       }
+       ss->in_ep->driver_data = cdev;  /* claim */
+
+       ss->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc);
+       if (!ss->out_ep)
+               goto autoconf_fail;
+       ss->out_ep->driver_data = cdev; /* claim */
+
+       setup_timer(&ss->resume, sourcesink_autoresume,
+                       (unsigned long) c->cdev);
+
+       /* support high speed hardware */
+       if (gadget_is_dualspeed(c->cdev->gadget)) {
+               hs_source_desc.bEndpointAddress =
+                               fs_source_desc.bEndpointAddress;
+               hs_sink_desc.bEndpointAddress =
+                               fs_sink_desc.bEndpointAddress;
+               f->hs_descriptors = hs_source_sink_descs;
+       }
+
+       DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
+                       gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
+                       f->name, ss->in_ep->name, ss->out_ep->name);
+       return 0;
+}
+
+static void
+sourcesink_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       kfree(func_to_ss(f));
+}
+
+/* optionally require specific source/sink data patterns  */
+static int check_read_data(struct f_sourcesink *ss, struct usb_request *req)
+{
+       unsigned                i;
+       u8                      *buf = req->buf;
+       struct usb_composite_dev *cdev = ss->function.config->cdev;
+
+       for (i = 0; i < req->actual; i++, buf++) {
+               switch (pattern) {
+
+               /* all-zeroes has no synchronization issues */
+               case 0:
+                       if (*buf == 0)
+                               continue;
+                       break;
+
+               /* "mod63" stays in sync with short-terminated transfers,
+                * OR otherwise when host and gadget agree on how large
+                * each usb transfer request should be.  Resync is done
+                * with set_interface or set_config.  (We *WANT* it to
+                * get quickly out of sync if controllers or their drivers
+                * stutter for any reason, including buffer duplcation...)
+                */
+               case 1:
+                       if (*buf == (u8)(i % 63))
+                               continue;
+                       break;
+               }
+               ERROR(cdev, "bad OUT byte, buf[%d] = %d\n", i, *buf);
+               usb_ep_set_halt(ss->out_ep);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static void reinit_write_data(struct usb_ep *ep, struct usb_request *req)
+{
+       unsigned        i;
+       u8              *buf = req->buf;
+
+       switch (pattern) {
+       case 0:
+               memset(req->buf, 0, req->length);
+               break;
+       case 1:
+               for  (i = 0; i < req->length; i++)
+                       *buf++ = (u8) (i % 63);
+               break;
+       }
+}
+
+static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct f_sourcesink     *ss = ep->driver_data;
+       struct usb_composite_dev *cdev = ss->function.config->cdev;
+       int                     status = req->status;
+
+       switch (status) {
+
+       case 0:                         /* normal completion? */
+               if (ep == ss->out_ep) {
+                       check_read_data(ss, req);
+                       memset(req->buf, 0x55, req->length);
+               } else
+                       reinit_write_data(ep, req);
+               break;
+
+       /* this endpoint is normally active while we're configured */
+       case -ECONNABORTED:             /* hardware forced ep reset */
+       case -ECONNRESET:               /* request dequeued */
+       case -ESHUTDOWN:                /* disconnect from host */
+               VDBG(cdev, "%s gone (%d), %d/%d\n", ep->name, status,
+                               req->actual, req->length);
+               if (ep == ss->out_ep)
+                       check_read_data(ss, req);
+               free_ep_req(ep, req);
+               return;
+
+       case -EOVERFLOW:                /* buffer overrun on read means that
+                                        * we didn't provide a big enough
+                                        * buffer.
+                                        */
+       default:
+#if 1
+               DBG(cdev, "%s complete --> %d, %d/%d\n", ep->name,
+                               status, req->actual, req->length);
+#endif
+       case -EREMOTEIO:                /* short read */
+               break;
+       }
+
+       status = usb_ep_queue(ep, req, GFP_ATOMIC);
+       if (status) {
+               ERROR(cdev, "kill %s:  resubmit %d bytes --> %d\n",
+                               ep->name, req->length, status);
+               usb_ep_set_halt(ep);
+               /* FIXME recover later ... somehow */
+       }
+}
+
+static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in)
+{
+       struct usb_ep           *ep;
+       struct usb_request      *req;
+       int                     status;
+
+       ep = is_in ? ss->in_ep : ss->out_ep;
+       req = alloc_ep_req(ep);
+       if (!req)
+               return -ENOMEM;
+
+       req->complete = source_sink_complete;
+       if (is_in)
+               reinit_write_data(ep, req);
+       else
+               memset(req->buf, 0x55, req->length);
+
+       status = usb_ep_queue(ep, req, GFP_ATOMIC);
+       if (status) {
+               struct usb_composite_dev        *cdev;
+
+               cdev = ss->function.config->cdev;
+               ERROR(cdev, "start %s %s --> %d\n",
+                               is_in ? "IN" : "OUT",
+                               ep->name, status);
+               free_ep_req(ep, req);
+       }
+
+       return status;
+}
+
+static void disable_source_sink(struct f_sourcesink *ss)
+{
+       struct usb_composite_dev        *cdev;
+
+       cdev = ss->function.config->cdev;
+       disable_endpoints(cdev, ss->in_ep, ss->out_ep);
+       del_timer(&ss->resume);
+       VDBG(cdev, "%s disabled\n", ss->function.name);
+}
+
+static int
+enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss)
+{
+       int                                     result = 0;
+       const struct usb_endpoint_descriptor    *src, *sink;
+       struct usb_ep                           *ep;
+
+       src = ep_choose(cdev->gadget, &hs_source_desc, &fs_source_desc);
+       sink = ep_choose(cdev->gadget, &hs_sink_desc, &fs_sink_desc);
+
+       /* one endpoint writes (sources) zeroes IN (to the host) */
+       ep = ss->in_ep;
+       result = usb_ep_enable(ep, src);
+       if (result < 0)
+               return result;
+       ep->driver_data = ss;
+
+       result = source_sink_start_ep(ss, true);
+       if (result < 0) {
+fail:
+               ep = ss->in_ep;
+               usb_ep_disable(ep);
+               ep->driver_data = NULL;
+               return result;
+       }
+
+       /* one endpoint reads (sinks) anything OUT (from the host) */
+       ep = ss->out_ep;
+       result = usb_ep_enable(ep, sink);
+       if (result < 0)
+               goto fail;
+       ep->driver_data = ss;
+
+       result = source_sink_start_ep(ss, false);
+       if (result < 0) {
+               usb_ep_disable(ep);
+               ep->driver_data = NULL;
+               goto fail;
+       }
+
+       DBG(cdev, "%s enabled\n", ss->function.name);
+       return result;
+}
+
+static int sourcesink_set_alt(struct usb_function *f,
+               unsigned intf, unsigned alt)
+{
+       struct f_sourcesink     *ss = func_to_ss(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+
+       /* we know alt is zero */
+       if (ss->in_ep->driver_data)
+               disable_source_sink(ss);
+       return enable_source_sink(cdev, ss);
+}
+
+static void sourcesink_disable(struct usb_function *f)
+{
+       struct f_sourcesink     *ss = func_to_ss(f);
+
+       disable_source_sink(ss);
+}
+
+static void sourcesink_suspend(struct usb_function *f)
+{
+       struct f_sourcesink     *ss = func_to_ss(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+
+       if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
+               return;
+
+       if (autoresume) {
+               mod_timer(&ss->resume, jiffies + (HZ * autoresume));
+               DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
+       } else
+               DBG(cdev, "%s\n", __func__);
+}
+
+static void sourcesink_resume(struct usb_function *f)
+{
+       struct f_sourcesink     *ss = func_to_ss(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+
+       DBG(cdev, "%s\n", __func__);
+       del_timer(&ss->resume);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int __init sourcesink_bind_config(struct usb_configuration *c)
+{
+       struct f_sourcesink     *ss;
+       int                     status;
+
+       ss = kzalloc(sizeof *ss, GFP_KERNEL);
+       if (!ss)
+               return -ENOMEM;
+
+       ss->function.name = "source/sink";
+       ss->function.descriptors = fs_source_sink_descs;
+       ss->function.bind = sourcesink_bind;
+       ss->function.unbind = sourcesink_unbind;
+       ss->function.set_alt = sourcesink_set_alt;
+       ss->function.disable = sourcesink_disable;
+       ss->function.suspend = sourcesink_suspend;
+       ss->function.resume = sourcesink_resume;
+
+       status = usb_add_function(c, &ss->function);
+       if (status)
+               kfree(ss);
+       return status;
+}
+
+static int sourcesink_setup(struct usb_configuration *c,
+               const struct usb_ctrlrequest *ctrl)
+{
+       struct usb_request      *req = c->cdev->req;
+       int                     value = -EOPNOTSUPP;
+       u16                     w_index = le16_to_cpu(ctrl->wIndex);
+       u16                     w_value = le16_to_cpu(ctrl->wValue);
+       u16                     w_length = le16_to_cpu(ctrl->wLength);
+
+       /* composite driver infrastructure handles everything except
+        * the two control test requests.
+        */
+       switch (ctrl->bRequest) {
+
+       /*
+        * These are the same vendor-specific requests supported by
+        * Intel's USB 2.0 compliance test devices.  We exceed that
+        * device spec by allowing multiple-packet requests.
+        *
+        * NOTE:  the Control-OUT data stays in req->buf ... better
+        * would be copying it into a scratch buffer, so that other
+        * requests may safely intervene.
+        */
+       case 0x5b:      /* control WRITE test -- fill the buffer */
+               if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR))
+                       goto unknown;
+               if (w_value || w_index)
+                       break;
+               /* just read that many bytes into the buffer */
+               if (w_length > req->length)
+                       break;
+               value = w_length;
+               break;
+       case 0x5c:      /* control READ test -- return the buffer */
+               if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR))
+                       goto unknown;
+               if (w_value || w_index)
+                       break;
+               /* expect those bytes are still in the buffer; send back */
+               if (w_length > req->length)
+                       break;
+               value = w_length;
+               break;
+
+       default:
+unknown:
+               VDBG(c->cdev,
+                       "unknown control req%02x.%02x v%04x i%04x l%d\n",
+                       ctrl->bRequestType, ctrl->bRequest,
+                       w_value, w_index, w_length);
+       }
+
+       /* respond with data transfer or status phase? */
+       if (value >= 0) {
+               VDBG(c->cdev, "source/sink req%02x.%02x v%04x i%04x l%d\n",
+                       ctrl->bRequestType, ctrl->bRequest,
+                       w_value, w_index, w_length);
+               req->zero = 0;
+               req->length = value;
+               value = usb_ep_queue(c->cdev->gadget->ep0, req, GFP_ATOMIC);
+               if (value < 0)
+                       ERROR(c->cdev, "source/sinkc response, err %d\n",
+                                       value);
+       }
+
+       /* device either stalls (value < 0) or reports success */
+       return value;
+}
+
+static struct usb_configuration sourcesink_driver = {
+       .label          = "source/sink",
+       .strings        = sourcesink_strings,
+       .bind           = sourcesink_bind_config,
+       .setup          = sourcesink_setup,
+       .bConfigurationValue = 3,
+       .bmAttributes   = USB_CONFIG_ATT_SELFPOWER,
+       .bMaxPower      = 1,    /* 2 mA, minimal */
+       /* .iConfiguration = DYNAMIC */
+};
+
+/**
+ * sourcesink_add - add a source/sink testing configuration to a device
+ * @cdev: the device to support the configuration
+ */
+int __init sourcesink_add(struct usb_composite_dev *cdev)
+{
+       int id;
+
+       /* allocate string ID(s) */
+       id = usb_string_id(cdev);
+       if (id < 0)
+               return id;
+       strings_sourcesink[0].id = id;
+
+       source_sink_intf.iInterface = id;
+       sourcesink_driver.iConfiguration = id;
+
+       /* support autoresume for remote wakeup testing */
+       if (autoresume)
+               sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+
+       /* support OTG systems */
+       if (gadget_is_otg(cdev->gadget)) {
+               sourcesink_driver.descriptors = otg_desc;
+               sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+       }
+
+       return usb_add_config(cdev, &sourcesink_driver);
+}
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
new file mode 100644 (file)
index 0000000..afeab9a
--- /dev/null
@@ -0,0 +1,423 @@
+/*
+ * f_subset.c -- "CDC Subset" Ethernet link function driver
+ *
+ * Copyright (C) 2003-2005,2008 David Brownell
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+
+#include "u_ether.h"
+
+
+/*
+ * This function packages a simple "CDC Subset" Ethernet port with no real
+ * control mechanisms; just raw data transfer over two bulk endpoints.
+ * The data transfer model is exactly that of CDC Ethernet, which is
+ * why we call it the "CDC Subset".
+ *
+ * Because it's not standardized, this has some interoperability issues.
+ * They mostly relate to driver binding, since the data transfer model is
+ * so simple (CDC Ethernet).  The original versions of this protocol used
+ * specific product/vendor IDs:  byteswapped IDs for Digital Equipment's
+ * SA-1100 "Itsy" board, which could run Linux 2.4 kernels and supported
+ * daughtercards with USB peripheral connectors.  (It was used more often
+ * with other boards, using the Itsy identifiers.)  Linux hosts recognized
+ * this with CONFIG_USB_ARMLINUX; these devices have only one configuration
+ * and one interface.
+ *
+ * At some point, MCCI defined a (nonconformant) CDC MDLM variant called
+ * "SAFE", which happens to have a mode which is identical to the "CDC
+ * Subset" in terms of data transfer and lack of control model.  This was
+ * adopted by later Sharp Zaurus models, and by some other software which
+ * Linux hosts recognize with CONFIG_USB_NET_ZAURUS.
+ *
+ * Because Microsoft's RNDIS drivers are far from robust, we added a few
+ * descriptors to the CDC Subset code, making this code look like a SAFE
+ * implementation.  This lets you use MCCI's host side MS-Windows drivers
+ * if you get fed up with RNDIS.  It also makes it easier for composite
+ * drivers to work, since they can use class based binding instead of
+ * caring about specific product and vendor IDs.
+ */
+
+struct geth_descs {
+       struct usb_endpoint_descriptor  *in;
+       struct usb_endpoint_descriptor  *out;
+};
+
+struct f_gether {
+       struct gether                   port;
+
+       char                            ethaddr[14];
+
+       struct usb_descriptor_header    **fs_function;
+       struct geth_descs               fs;
+       struct usb_descriptor_header    **hs_function;
+       struct geth_descs               hs;
+};
+
+static inline struct f_gether *func_to_geth(struct usb_function *f)
+{
+       return container_of(f, struct f_gether, port.func);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * "Simple" CDC-subset option is a simple vendor-neutral model that most
+ * full speed controllers can handle:  one interface, two bulk endpoints.
+ * To assist host side drivers, we fancy it up a bit, and add descriptors so
+ * some host side drivers will understand it as a "SAFE" variant.
+ *
+ * "SAFE" loosely follows CDC WMC MDLM, violating the spec in various ways.
+ * Data endpoints live in the control interface, there's no data interface.
+ * And it's not used to talk to a cell phone radio.
+ */
+
+/* interface descriptor: */
+
+static struct usb_interface_descriptor subset_data_intf __initdata = {
+       .bLength =              sizeof subset_data_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+
+       /* .bInterfaceNumber = DYNAMIC */
+       .bAlternateSetting =    0,
+       .bNumEndpoints =        2,
+       .bInterfaceClass =      USB_CLASS_COMM,
+       .bInterfaceSubClass =   USB_CDC_SUBCLASS_MDLM,
+       .bInterfaceProtocol =   0,
+       /* .iInterface = DYNAMIC */
+};
+
+static struct usb_cdc_header_desc header_desc __initdata = {
+       .bLength =              sizeof header_desc,
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
+
+       .bcdCDC =               __constant_cpu_to_le16(0x0110),
+};
+
+static struct usb_cdc_mdlm_desc mdlm_desc __initdata = {
+       .bLength =              sizeof mdlm_desc,
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_MDLM_TYPE,
+
+       .bcdVersion =           __constant_cpu_to_le16(0x0100),
+       .bGUID = {
+               0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
+               0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
+       },
+};
+
+/* since "usb_cdc_mdlm_detail_desc" is a variable length structure, we
+ * can't really use its struct.  All we do here is say that we're using
+ * the submode of "SAFE" which directly matches the CDC Subset.
+ */
+static u8 mdlm_detail_desc[] __initdata = {
+       6,
+       USB_DT_CS_INTERFACE,
+       USB_CDC_MDLM_DETAIL_TYPE,
+
+       0,      /* "SAFE" */
+       0,      /* network control capabilities (none) */
+       0,      /* network data capabilities ("raw" encapsulation) */
+};
+
+static struct usb_cdc_ether_desc ether_desc __initdata = {
+       .bLength =              sizeof ether_desc,
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_ETHERNET_TYPE,
+
+       /* this descriptor actually adds value, surprise! */
+       /* .iMACAddress = DYNAMIC */
+       .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
+       .wMaxSegmentSize =      __constant_cpu_to_le16(ETH_FRAME_LEN),
+       .wNumberMCFilters =     __constant_cpu_to_le16(0),
+       .bNumberPowerFilters =  0,
+};
+
+/* full speed support: */
+
+static struct usb_endpoint_descriptor fs_in_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_endpoint_descriptor fs_out_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bEndpointAddress =     USB_DIR_OUT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_descriptor_header *fs_eth_function[] __initdata = {
+       (struct usb_descriptor_header *) &subset_data_intf,
+       (struct usb_descriptor_header *) &header_desc,
+       (struct usb_descriptor_header *) &mdlm_desc,
+       (struct usb_descriptor_header *) &mdlm_detail_desc,
+       (struct usb_descriptor_header *) &ether_desc,
+       (struct usb_descriptor_header *) &fs_in_desc,
+       (struct usb_descriptor_header *) &fs_out_desc,
+       NULL,
+};
+
+/* high speed support: */
+
+static struct usb_endpoint_descriptor hs_in_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor hs_out_desc __initdata = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+};
+
+static struct usb_descriptor_header *hs_eth_function[] __initdata = {
+       (struct usb_descriptor_header *) &subset_data_intf,
+       (struct usb_descriptor_header *) &header_desc,
+       (struct usb_descriptor_header *) &mdlm_desc,
+       (struct usb_descriptor_header *) &mdlm_detail_desc,
+       (struct usb_descriptor_header *) &ether_desc,
+       (struct usb_descriptor_header *) &hs_in_desc,
+       (struct usb_descriptor_header *) &hs_out_desc,
+       NULL,
+};
+
+/* string descriptors: */
+
+static struct usb_string geth_string_defs[] = {
+       [0].s = "CDC Ethernet Subset/SAFE",
+       [1].s = NULL /* DYNAMIC */,
+       {  } /* end of list */
+};
+
+static struct usb_gadget_strings geth_string_table = {
+       .language =             0x0409, /* en-us */
+       .strings =              geth_string_defs,
+};
+
+static struct usb_gadget_strings *geth_strings[] = {
+       &geth_string_table,
+       NULL,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int geth_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+{
+       struct f_gether         *geth = func_to_geth(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+       struct net_device       *net;
+
+       /* we know alt == 0, so this is an activation or a reset */
+
+       if (geth->port.in_ep->driver_data) {
+               DBG(cdev, "reset cdc subset\n");
+               gether_disconnect(&geth->port);
+       }
+
+       DBG(cdev, "init + activate cdc subset\n");
+       geth->port.in = ep_choose(cdev->gadget,
+                       geth->hs.in, geth->fs.in);
+       geth->port.out = ep_choose(cdev->gadget,
+                       geth->hs.out, geth->fs.out);
+
+       net = gether_connect(&geth->port);
+       return IS_ERR(net) ? PTR_ERR(net) : 0;
+}
+
+static void geth_disable(struct usb_function *f)
+{
+       struct f_gether *geth = func_to_geth(f);
+       struct usb_composite_dev *cdev = f->config->cdev;
+
+       DBG(cdev, "net deactivated\n");
+       gether_disconnect(&geth->port);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* serial function driver setup/binding */
+
+static int __init
+geth_bind(struct usb_configuration *c, struct usb_function *f)
+{
+       struct usb_composite_dev *cdev = c->cdev;
+       struct f_gether         *geth = func_to_geth(f);
+       int                     status;
+       struct usb_ep           *ep;
+
+       /* allocate instance-specific interface IDs */
+       status = usb_interface_id(c, f);
+       if (status < 0)
+               goto fail;
+       subset_data_intf.bInterfaceNumber = status;
+
+       status = -ENODEV;
+
+       /* allocate instance-specific endpoints */
+       ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc);
+       if (!ep)
+               goto fail;
+       geth->port.in_ep = ep;
+       ep->driver_data = cdev; /* claim */
+
+       ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
+       if (!ep)
+               goto fail;
+       geth->port.out_ep = ep;
+       ep->driver_data = cdev; /* claim */
+
+       /* copy descriptors, and track endpoint copies */
+       f->descriptors = usb_copy_descriptors(fs_eth_function);
+
+       geth->fs.in = usb_find_endpoint(fs_eth_function,
+                       f->descriptors, &fs_in_desc);
+       geth->fs.out = usb_find_endpoint(fs_eth_function,
+                       f->descriptors, &fs_out_desc);
+
+
+       /* support all relevant hardware speeds... we expect that when
+        * hardware is dual speed, all bulk-capable endpoints work at
+        * both speeds
+        */
+       if (gadget_is_dualspeed(c->cdev->gadget)) {
+               hs_in_desc.bEndpointAddress =
+                               fs_in_desc.bEndpointAddress;
+               hs_out_desc.bEndpointAddress =
+                               fs_out_desc.bEndpointAddress;
+
+               /* copy descriptors, and track endpoint copies */
+               f->hs_descriptors = usb_copy_descriptors(hs_eth_function);
+
+               geth->hs.in = usb_find_endpoint(hs_eth_function,
+                               f->hs_descriptors, &hs_in_desc);
+               geth->hs.out = usb_find_endpoint(hs_eth_function,
+                               f->hs_descriptors, &hs_out_desc);
+       }
+
+       /* NOTE:  all that is done without knowing or caring about
+        * the network link ... which is unavailable to this code
+        * until we're activated via set_alt().
+        */
+
+       DBG(cdev, "CDC Subset: %s speed IN/%s OUT/%s\n",
+                       gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
+                       geth->port.in_ep->name, geth->port.out_ep->name);
+       return 0;
+
+fail:
+       /* we might as well release our claims on endpoints */
+       if (geth->port.out)
+               geth->port.out_ep->driver_data = NULL;
+       if (geth->port.in)
+               geth->port.in_ep->driver_data = NULL;
+
+       ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
+
+       return status;
+}
+
+static void
+geth_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+       if (gadget_is_dualspeed(c->cdev->gadget))
+               usb_free_descriptors(f->hs_descriptors);
+       usb_free_descriptors(f->descriptors);
+       geth_string_defs[1].s = NULL;
+       kfree(func_to_geth(f));
+}
+
+/**
+ * geth_bind_config - add CDC Subset network link to a configuration
+ * @c: the configuration to support the network link
+ * @ethaddr: a buffer in which the ethernet address of the host side
+ *     side of the link was recorded
+ * Context: single threaded during gadget setup
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * Caller must have called @gether_setup().  Caller is also responsible
+ * for calling @gether_cleanup() before module unload.
+ */
+int __init geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
+{
+       struct f_gether *geth;
+       int             status;
+
+       if (!ethaddr)
+               return -EINVAL;
+
+       /* maybe allocate device-global string IDs */
+       if (geth_string_defs[0].id == 0) {
+
+               /* interface label */
+               status = usb_string_id(c->cdev);
+               if (status < 0)
+                       return status;
+               geth_string_defs[0].id = status;
+               subset_data_intf.iInterface = status;
+
+               /* MAC address */
+               status = usb_string_id(c->cdev);
+               if (status < 0)
+                       return status;
+               geth_string_defs[1].id = status;
+               ether_desc.iMACAddress = status;
+       }
+
+       /* allocate and initialize one new instance */
+       geth = kzalloc(sizeof *geth, GFP_KERNEL);
+       if (!geth)
+               return -ENOMEM;
+
+       /* export host's Ethernet address in CDC format */
+       snprintf(geth->ethaddr, sizeof geth->ethaddr,
+               "%02X%02X%02X%02X%02X%02X",
+               ethaddr[0], ethaddr[1], ethaddr[2],
+               ethaddr[3], ethaddr[4], ethaddr[5]);
+       geth_string_defs[1].s = geth->ethaddr;
+
+       geth->port.cdc_filter = DEFAULT_FILTER;
+
+       geth->port.func.name = "cdc_subset";
+       geth->port.func.strings = geth_strings;
+       geth->port.func.bind = geth_bind;
+       geth->port.func.unbind = geth_unbind;
+       geth->port.func.set_alt = geth_set_alt;
+       geth->port.func.disable = geth_disable;
+
+       status = usb_add_function(c, &geth->port.func);
+       if (status) {
+               geth_string_defs[1].s = NULL;
+               kfree(geth);
+       }
+       return status;
+}
index 47bb9f09a1aa1c698dea76218bbe4fc589917989..15c24edbb61adb29a40db7a5e7c83dc63a4a777f 100644 (file)
@@ -3867,8 +3867,8 @@ static int __init fsg_bind(struct usb_gadget *gadget)
                curlun->dev.parent = &gadget->dev;
                curlun->dev.driver = &fsg_driver.driver;
                dev_set_drvdata(&curlun->dev, fsg);
-               snprintf(curlun->dev.bus_id, BUS_ID_SIZE,
-                               "%s-lun%d", gadget->dev.bus_id, i);
+               dev_set_name(&curlun->dev,"%s-lun%d",
+                            dev_name(&gadget->dev), i);
 
                if ((rc = device_register(&curlun->dev)) != 0) {
                        INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
index 18687543d7fa0ba3382f8da11f344fc713565923..1695382f30fe5ce3a4898f067b12b8a632429f96 100644 (file)
@@ -2331,7 +2331,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
        udc_controller->gadget.name = driver_name;
 
        /* Setup gadget.dev and register with kernel */
-       strcpy(udc_controller->gadget.dev.bus_id, "gadget");
+       dev_set_name(&udc_controller->gadget.dev, "gadget");
        udc_controller->gadget.dev.release = fsl_udc_release;
        udc_controller->gadget.dev.parent = &pdev->dev;
        ret = device_register(&udc_controller->gadget.dev);
diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h
new file mode 100644 (file)
index 0000000..dd2f16a
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * This header declares the utility functions used by "Gadget Zero", plus
+ * interfaces to its two single-configuration function drivers.
+ */
+
+#ifndef __G_ZERO_H
+#define __G_ZERO_H
+
+#include <linux/usb/composite.h>
+
+/* global state */
+extern unsigned buflen;
+extern const struct usb_descriptor_header *otg_desc[];
+
+/* common utilities */
+struct usb_request *alloc_ep_req(struct usb_ep *ep);
+void free_ep_req(struct usb_ep *ep, struct usb_request *req);
+void disable_endpoints(struct usb_composite_dev *cdev,
+               struct usb_ep *in, struct usb_ep *out);
+
+/* configuration-specific linkup */
+int sourcesink_add(struct usb_composite_dev *cdev);
+int loopback_add(struct usb_composite_dev *cdev);
+
+#endif /* __G_ZERO_H */
index ca5149ea73125ac9a97260b3e08eefc31b75ec9f..5246e8fef2b276b28d5e64095fa77493eae91232 100644 (file)
@@ -214,3 +214,26 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
                return 0x21;
        return -ENOENT;
 }
+
+
+/**
+ * gadget_supports_altsettings - return true if altsettings work
+ * @gadget: the gadget in question
+ */
+static inline bool gadget_supports_altsettings(struct usb_gadget *gadget)
+{
+       /* PXA 21x/25x/26x has no altsettings at all */
+       if (gadget_is_pxa(gadget))
+               return false;
+
+       /* PXA 27x and 3xx have *broken* altsetting support */
+       if (gadget_is_pxa27x(gadget))
+               return false;
+
+       /* SH3 hardware just doesn't do altsettings */
+       if (gadget_is_sh(gadget))
+               return false;
+
+       /* Everything else is *presumably* fine ... */
+       return true;
+}
index be6613afedbfd317f907a4d252973b4b9c73b787..48f1c63b70136ec17d458091e4ae7cba8528aaf5 100644 (file)
@@ -1790,7 +1790,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        dev->gadget.ops = &goku_ops;
 
        /* the "gadget" abstracts/virtualizes the controller */
-       strcpy(dev->gadget.dev.bus_id, "gadget");
+       dev_set_name(&dev->gadget.dev, "gadget");
        dev->gadget.dev.parent = &pdev->dev;
        dev->gadget.dev.dma_mask = pdev->dev.dma_mask;
        dev->gadget.dev.release = gadget_release;
index f132a9219e11d7c24719d9692f3a5607cf22d452..04692d59fc1cda8d22a883beaca7b7d976f49aa5 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/uaccess.h>
 #include <linux/slab.h>
 #include <linux/poll.h>
+#include <linux/smp_lock.h>
 
 #include <linux/device.h>
 #include <linux/moduleparam.h>
@@ -483,8 +484,7 @@ ep_release (struct inode *inode, struct file *fd)
        return 0;
 }
 
-static int ep_ioctl (struct inode *inode, struct file *fd,
-               unsigned code, unsigned long value)
+static long ep_ioctl(struct file *fd, unsigned code, unsigned long value)
 {
        struct ep_data          *data = fd->private_data;
        int                     status;
@@ -740,7 +740,7 @@ static const struct file_operations ep_io_operations = {
 
        .read =         ep_read,
        .write =        ep_write,
-       .ioctl =        ep_ioctl,
+       .unlocked_ioctl = ep_ioctl,
        .release =      ep_release,
 
        .aio_read =     ep_aio_read,
@@ -1294,15 +1294,18 @@ out:
        return mask;
 }
 
-static int dev_ioctl (struct inode *inode, struct file *fd,
-               unsigned code, unsigned long value)
+static long dev_ioctl (struct file *fd, unsigned code, unsigned long value)
 {
        struct dev_data         *dev = fd->private_data;
        struct usb_gadget       *gadget = dev->gadget;
+       long ret = -ENOTTY;
 
-       if (gadget->ops->ioctl)
-               return gadget->ops->ioctl (gadget, code, value);
-       return -ENOTTY;
+       if (gadget->ops->ioctl) {
+               lock_kernel();
+               ret = gadget->ops->ioctl (gadget, code, value);
+               unlock_kernel();
+       }
+       return ret;
 }
 
 /* used after device configuration */
@@ -1314,7 +1317,7 @@ static const struct file_operations ep0_io_operations = {
        .write =        ep0_write,
        .fasync =       ep0_fasync,
        .poll =         ep0_poll,
-       .ioctl =        dev_ioctl,
+       .unlocked_ioctl =       dev_ioctl,
        .release =      dev_release,
 };
 
@@ -1964,7 +1967,7 @@ static const struct file_operations dev_init_operations = {
        .open =         dev_open,
        .write =        dev_config,
        .fasync =       ep0_fasync,
-       .ioctl =        dev_ioctl,
+       .unlocked_ioctl = dev_ioctl,
        .release =      dev_release,
 };
 
index 825abd2621b397499a92e9d43b41b7e1d2862e98..c6e7df04c69ac36be2e32369a7d0fdb6738d1cf3 100644 (file)
@@ -1970,7 +1970,7 @@ static const struct usb_gadget_ops lh7a40x_udc_ops = {
 
 static void nop_release(struct device *dev)
 {
-       DEBUG("%s %s\n", __func__, dev->bus_id);
+       DEBUG("%s %s\n", __func__, dev_name(dev));
 }
 
 static struct lh7a40x_udc memory = {
index ee6b35fa870f9ef6ff9807b2abf33a7400da4861..8da7535c0c70c96b2988ac164e9655630472b362 100644 (file)
@@ -1593,7 +1593,7 @@ static int __init m66592_probe(struct platform_device *pdev)
 
        m66592->gadget.ops = &m66592_gadget_ops;
        device_initialize(&m66592->gadget.dev);
-       strcpy(m66592->gadget.dev.bus_id, "gadget");
+       dev_set_name(&m66592->gadget, "gadget");
        m66592->gadget.is_dualspeed = 1;
        m66592->gadget.dev.parent = &pdev->dev;
        m66592->gadget.dev.dma_mask = pdev->dev.dma_mask;
index 09e3ee4eeae1741e5313e2a1f6d50f8e972066ae..df886cec5ef4b0d6c34fdbff6d1a898299c047c3 100644 (file)
@@ -1,11 +1,11 @@
 /*
- * ndis.h 
- * 
+ * ndis.h
+ *
  * ntddndis.h modified by Benedikt Spranger <b.spranger@pengutronix.de>
- * 
- * Thanks to the cygwin development team, 
+ *
+ * Thanks to the cygwin development team,
  * espacially to Casper S. Hornstrup <chorns@users.sourceforge.net>
- * 
+ *
  * THIS SOFTWARE IS NOT COPYRIGHTED
  *
  * This source code is offered for use in the public domain. You may
index e01862300169772d714a6ab24a4db9938825fd9d..b67ab677af725dd2d5d685ed3f982651f085d5a6 100644 (file)
@@ -2768,7 +2768,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
        dev->gadget.is_dualspeed = 1;
 
        /* the "gadget" abstracts/virtualizes the controller */
-       strcpy (dev->gadget.dev.bus_id, "gadget");
+       dev_set_name(&dev->gadget.dev, "gadget");
        dev->gadget.dev.parent = &pdev->dev;
        dev->gadget.dev.dma_mask = pdev->dev.dma_mask;
        dev->gadget.dev.release = gadget_release;
index 03a7f49d207d5767c7ee129a12847e526e7eac48..4b79a8509e848e8ebb3d6d656d684d3d3af080f9 100644 (file)
@@ -2686,7 +2686,7 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv)
        udc->gadget.name = driver_name;
 
        device_initialize(&udc->gadget.dev);
-       strcpy (udc->gadget.dev.bus_id, "gadget");
+       dev_set_name(&udc->gadget.dev, "gadget");
        udc->gadget.dev.release = omap_udc_release;
        udc->gadget.dev.parent = &odev->dev;
        if (use_dma)
index ec8f2eb041ca97b258e4ae3a45700b0305f6caf1..49cd9e145a9bfbcdba12c76192f93ae3073b716d 100644 (file)
@@ -828,9 +828,8 @@ printer_poll(struct file *fd, poll_table *wait)
        return status;
 }
 
-static int
-printer_ioctl(struct inode *inode, struct file *fd, unsigned int code,
-               unsigned long arg)
+static long
+printer_ioctl(struct file *fd, unsigned int code, unsigned long arg)
 {
        struct printer_dev      *dev = fd->private_data;
        unsigned long           flags;
@@ -869,7 +868,7 @@ static struct file_operations printer_io_operations = {
        .write =        printer_write,
        .fsync =        printer_fsync,
        .poll =         printer_poll,
-       .ioctl =        printer_ioctl,
+       .unlocked_ioctl = printer_ioctl,
        .release =      printer_close
 };
 
@@ -1361,8 +1360,8 @@ printer_bind(struct usb_gadget *gadget)
 
 
        /* Setup the sysfs files for the printer gadget. */
-       dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno,
-                       "g_printer");
+       dev->pdev = device_create_drvdata(usb_gadget_class, NULL,
+                                         g_printer_devno, NULL, "g_printer");
        if (IS_ERR(dev->pdev)) {
                ERROR(dev, "Failed to create device: g_printer\n");
                goto fail;
index 031dceb93023bbc96b033b88a21881428a22ec5e..8fb0066609bb4a9db0e22a045e70b14909cc809c 100644 (file)
@@ -152,9 +152,10 @@ static int is_vbus_present(void)
 static void pullup_off(void)
 {
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
+       int off_level = mach->gpio_pullup_inverted;
 
        if (mach->gpio_pullup)
-               gpio_set_value(mach->gpio_pullup, 0);
+               gpio_set_value(mach->gpio_pullup, off_level);
        else if (mach->udc_command)
                mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
 }
@@ -162,9 +163,10 @@ static void pullup_off(void)
 static void pullup_on(void)
 {
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
+       int on_level = !mach->gpio_pullup_inverted;
 
        if (mach->gpio_pullup)
-               gpio_set_value(mach->gpio_pullup, 1);
+               gpio_set_value(mach->gpio_pullup, on_level);
        else if (mach->udc_command)
                mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
 }
@@ -1818,7 +1820,7 @@ pxa25x_udc_irq(int irq, void *_dev)
 
 static void nop_release (struct device *dev)
 {
-       DMSG("%s %s\n", __func__, dev->bus_id);
+       DMSG("%s %s\n", __func__, dev_name(dev));
 }
 
 /* this uses load-time allocation and initialization (instead of
index 9c0e82ec5c43b94fefbdc58cbfc0f88549cf01e1..9d447d8cfc0ca560040086056b3630d813c2dc92 100644 (file)
@@ -1575,7 +1575,6 @@ static void udc_enable(struct pxa_udc *udc)
 {
        udc_writel(udc, UDCICR0, 0);
        udc_writel(udc, UDCICR1, 0);
-       udc_writel(udc, UP2OCR, UP2OCR_HXOE);
        udc_clear_mask_UDCCR(udc, UDCCR_UDE);
 
        clk_enable(udc->clk);
index d0677f5d3cd5f3f8b88b5c73573113f7fed672d1..7228e856223626dab7e568eb0f1252391758a95b 100644 (file)
@@ -1,8 +1,6 @@
 /*
  * RNDIS MSG parser
  *
- * Version:     $Id: rndis.c,v 1.19 2004/03/25 21:33:46 robert Exp $
- *
  * Authors:    Benedikt Spranger, Pengutronix
  *             Robert Schwebel, Pengutronix
  *
@@ -30,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/netdevice.h>
 
 #include <asm/io.h>
@@ -38,9 +37,7 @@
 #include <asm/unaligned.h>
 
 
-#undef RNDIS_PM
-#undef RNDIS_WAKEUP
-#undef VERBOSE
+#undef VERBOSE_DEBUG
 
 #include "rndis.h"
 
@@ -96,9 +93,6 @@ static const u32 oid_supported_list [] =
        OID_GEN_MAXIMUM_TOTAL_SIZE,
        OID_GEN_MEDIA_CONNECT_STATUS,
        OID_GEN_PHYSICAL_MEDIUM,
-#if 0
-       OID_GEN_RNDIS_CONFIG_PARAMETER,
-#endif
 
        /* the statistical stuff */
        OID_GEN_XMIT_OK,
@@ -146,7 +140,14 @@ static const u32 oid_supported_list [] =
 #endif /* RNDIS_OPTIONAL_STATS */
 
 #ifdef RNDIS_PM
-       /* PM and wakeup are mandatory for USB: */
+       /* PM and wakeup are "mandatory" for USB, but the RNDIS specs
+        * don't say what they mean ... and the NDIS specs are often
+        * confusing and/or ambiguous in this context.  (That is, more
+        * so than their specs for the other OIDs.)
+        *
+        * FIXME someone who knows what these should do, please
+        * implement them!
+        */
 
        /* power management */
        OID_PNP_CAPABILITIES,
@@ -173,6 +174,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        __le32                  *outbuf;
        int                     i, count;
        rndis_query_cmplt_type  *resp;
+       struct net_device       *net;
+       struct net_device_stats *stats;
 
        if (!r) return -ENOMEM;
        resp = (rndis_query_cmplt_type *) r->buf;
@@ -194,6 +197,12 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        outbuf = (__le32 *) &resp[1];
        resp->InformationBufferOffset = __constant_cpu_to_le32 (16);
 
+       net = rndis_per_dev_params[configNr].dev;
+       if (net->get_stats)
+               stats = net->get_stats(net);
+       else
+               stats = NULL;
+
        switch (OID) {
 
        /* general oids (table 4-1) */
@@ -350,11 +359,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        case OID_GEN_XMIT_OK:
                if (rndis_debug > 1)
                        DBG("%s: OID_GEN_XMIT_OK\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (
-                           rndis_per_dev_params [configNr].stats->tx_packets -
-                           rndis_per_dev_params [configNr].stats->tx_errors -
-                           rndis_per_dev_params [configNr].stats->tx_dropped);
+               if (stats) {
+                       *outbuf = cpu_to_le32(stats->tx_packets
+                               - stats->tx_errors - stats->tx_dropped);
                        retval = 0;
                }
                break;
@@ -363,11 +370,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        case OID_GEN_RCV_OK:
                if (rndis_debug > 1)
                        DBG("%s: OID_GEN_RCV_OK\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (
-                           rndis_per_dev_params [configNr].stats->rx_packets -
-                           rndis_per_dev_params [configNr].stats->rx_errors -
-                           rndis_per_dev_params [configNr].stats->rx_dropped);
+               if (stats) {
+                       *outbuf = cpu_to_le32(stats->rx_packets
+                               - stats->rx_errors - stats->rx_dropped);
                        retval = 0;
                }
                break;
@@ -376,9 +381,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        case OID_GEN_XMIT_ERROR:
                if (rndis_debug > 1)
                        DBG("%s: OID_GEN_XMIT_ERROR\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
-                                       .stats->tx_errors);
+               if (stats) {
+                       *outbuf = cpu_to_le32(stats->tx_errors);
                        retval = 0;
                }
                break;
@@ -387,9 +391,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        case OID_GEN_RCV_ERROR:
                if (rndis_debug > 1)
                        DBG("%s: OID_GEN_RCV_ERROR\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
-                                       .stats->rx_errors);
+               if (stats) {
+                       *outbuf = cpu_to_le32(stats->rx_errors);
                        retval = 0;
                }
                break;
@@ -397,150 +400,12 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_GEN_RCV_NO_BUFFER:
                DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
-                                       .stats->rx_dropped);
-                       retval = 0;
-               }
-               break;
-
-#ifdef RNDIS_OPTIONAL_STATS
-       case OID_GEN_DIRECTED_BYTES_XMIT:
-               DBG("%s: OID_GEN_DIRECTED_BYTES_XMIT\n", __func__);
-               /*
-                * Aunt Tilly's size of shoes
-                * minus antarctica count of penguins
-                * divided by weight of Alpha Centauri
-                */
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (
-                               (rndis_per_dev_params [configNr]
-                                       .stats->tx_packets -
-                                rndis_per_dev_params [configNr]
-                                        .stats->tx_errors -
-                                rndis_per_dev_params [configNr]
-                                        .stats->tx_dropped)
-                               * 123);
-                       retval = 0;
-               }
-               break;
-
-       case OID_GEN_DIRECTED_FRAMES_XMIT:
-               DBG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __func__);
-               /* dito */
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (
-                               (rndis_per_dev_params [configNr]
-                                       .stats->tx_packets -
-                                rndis_per_dev_params [configNr]
-                                        .stats->tx_errors -
-                                rndis_per_dev_params [configNr]
-                                        .stats->tx_dropped)
-                               / 123);
-                       retval = 0;
-               }
-               break;
-
-       case OID_GEN_MULTICAST_BYTES_XMIT:
-               DBG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
-                                       .stats->multicast*1234);
-                       retval = 0;
-               }
-               break;
-
-       case OID_GEN_MULTICAST_FRAMES_XMIT:
-               DBG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
-                                       .stats->multicast);
-                       retval = 0;
-               }
-               break;
-
-       case OID_GEN_BROADCAST_BYTES_XMIT:
-               DBG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
-                                       .stats->tx_packets/42*255);
-                       retval = 0;
-               }
-               break;
-
-       case OID_GEN_BROADCAST_FRAMES_XMIT:
-               DBG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
-                                       .stats->tx_packets/42);
-                       retval = 0;
-               }
-               break;
-
-       case OID_GEN_DIRECTED_BYTES_RCV:
-               DBG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __func__);
-               *outbuf = __constant_cpu_to_le32 (0);
-               retval = 0;
-               break;
-
-       case OID_GEN_DIRECTED_FRAMES_RCV:
-               DBG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __func__);
-               *outbuf = __constant_cpu_to_le32 (0);
-               retval = 0;
-               break;
-
-       case OID_GEN_MULTICAST_BYTES_RCV:
-               DBG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
-                                       .stats->multicast * 1111);
-                       retval = 0;
-               }
-               break;
-
-       case OID_GEN_MULTICAST_FRAMES_RCV:
-               DBG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
-                                       .stats->multicast);
-                       retval = 0;
-               }
-               break;
-
-       case OID_GEN_BROADCAST_BYTES_RCV:
-               DBG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
-                                       .stats->rx_packets/42*255);
-                       retval = 0;
-               }
-               break;
-
-       case OID_GEN_BROADCAST_FRAMES_RCV:
-               DBG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
-                                       .stats->rx_packets/42);
+               if (stats) {
+                       *outbuf = cpu_to_le32(stats->rx_dropped);
                        retval = 0;
                }
                break;
 
-       case OID_GEN_RCV_CRC_ERROR:
-               DBG("%s: OID_GEN_RCV_CRC_ERROR\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
-                                       .stats->rx_crc_errors);
-                       retval = 0;
-               }
-               break;
-
-       case OID_GEN_TRANSMIT_QUEUE_LENGTH:
-               DBG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __func__);
-               *outbuf = __constant_cpu_to_le32 (0);
-               retval = 0;
-               break;
-#endif /* RNDIS_OPTIONAL_STATS */
-
        /* ieee802.3 OIDs (table 4-3) */
 
        /* mandatory */
@@ -592,9 +457,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
        /* mandatory */
        case OID_802_3_RCV_ERROR_ALIGNMENT:
                DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
-               if (rndis_per_dev_params [configNr].stats) {
-                       *outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
-                                       .stats->rx_frame_errors);
+               if (stats) {
+                       *outbuf = cpu_to_le32(stats->rx_frame_errors);
                        retval = 0;
                }
                break;
@@ -613,64 +477,6 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
                retval = 0;
                break;
 
-#ifdef RNDIS_OPTIONAL_STATS
-       case OID_802_3_XMIT_DEFERRED:
-               DBG("%s: OID_802_3_XMIT_DEFERRED\n", __func__);
-               /* TODO */
-               break;
-
-       case OID_802_3_XMIT_MAX_COLLISIONS:
-               DBG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __func__);
-               /* TODO */
-               break;
-
-       case OID_802_3_RCV_OVERRUN:
-               DBG("%s: OID_802_3_RCV_OVERRUN\n", __func__);
-               /* TODO */
-               break;
-
-       case OID_802_3_XMIT_UNDERRUN:
-               DBG("%s: OID_802_3_XMIT_UNDERRUN\n", __func__);
-               /* TODO */
-               break;
-
-       case OID_802_3_XMIT_HEARTBEAT_FAILURE:
-               DBG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __func__);
-               /* TODO */
-               break;
-
-       case OID_802_3_XMIT_TIMES_CRS_LOST:
-               DBG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __func__);
-               /* TODO */
-               break;
-
-       case OID_802_3_XMIT_LATE_COLLISIONS:
-               DBG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __func__);
-               /* TODO */
-               break;
-#endif /* RNDIS_OPTIONAL_STATS */
-
-#ifdef RNDIS_PM
-       /* power management OIDs (table 4-5) */
-       case OID_PNP_CAPABILITIES:
-               DBG("%s: OID_PNP_CAPABILITIES\n", __func__);
-
-               /* for now, no wakeup capabilities */
-               length = sizeof (struct NDIS_PNP_CAPABILITIES);
-               memset(outbuf, 0, length);
-               retval = 0;
-               break;
-       case OID_PNP_QUERY_POWER:
-               DBG("%s: OID_PNP_QUERY_POWER D%d\n", __func__,
-                               get_unaligned_le32(buf) - 1);
-               /* only suspend is a real power state, and
-                * it can't be entered by OID_PNP_SET_POWER...
-                */
-               length = 0;
-               retval = 0;
-               break;
-#endif
-
        default:
                pr_warning("%s: query unknown OID 0x%08X\n",
                         __func__, OID);
@@ -726,9 +532,6 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
                 * what makes the packet flow start and stop, like
                 * activating the CDC Ethernet altsetting.
                 */
-#ifdef RNDIS_PM
-update_linkstate:
-#endif
                retval = 0;
                if (*params->filter) {
                        params->state = RNDIS_DATA_INITIALIZED;
@@ -747,49 +550,6 @@ update_linkstate:
                DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__);
                retval = 0;
                break;
-#if 0
-       case OID_GEN_RNDIS_CONFIG_PARAMETER:
-               {
-               struct rndis_config_parameter   *param;
-               param = (struct rndis_config_parameter *) buf;
-               DBG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER '%*s'\n",
-                       __func__,
-                       min(cpu_to_le32(param->ParameterNameLength),80),
-                       buf + param->ParameterNameOffset);
-               retval = 0;
-               }
-               break;
-#endif
-
-#ifdef RNDIS_PM
-       case OID_PNP_SET_POWER:
-               /* The only real power state is USB suspend, and RNDIS requests
-                * can't enter it; this one isn't really about power.  After
-                * resuming, Windows forces a reset, and then SET_POWER D0.
-                * FIXME ... then things go batty; Windows wedges itself.
-                */
-               i = get_unaligned_le32(buf);
-               DBG("%s: OID_PNP_SET_POWER D%d\n", __func__, i - 1);
-               switch (i) {
-               case NdisDeviceStateD0:
-                       *params->filter = params->saved_filter;
-                       goto update_linkstate;
-               case NdisDeviceStateD3:
-               case NdisDeviceStateD2:
-               case NdisDeviceStateD1:
-                       params->saved_filter = *params->filter;
-                       retval = 0;
-                       break;
-               }
-               break;
-
-#ifdef RNDIS_WAKEUP
-       // no wakeup support advertised, so wakeup OIDs always fail:
-       //  - OID_PNP_ENABLE_WAKE_UP
-       //  - OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN
-#endif
-
-#endif /* RNDIS_PM */
 
        default:
                pr_warning("%s: set unknown OID 0x%08X, size %d\n",
@@ -807,8 +567,10 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
 {
        rndis_init_cmplt_type   *resp;
        rndis_resp_t            *r;
+       struct rndis_params     *params = rndis_per_dev_params + configNr;
 
-       if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
+       if (!params->dev)
+               return -ENOTSUPP;
 
        r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type));
        if (!r)
@@ -826,7 +588,7 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
        resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3);
        resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1);
        resp->MaxTransferSize = cpu_to_le32 (
-                 rndis_per_dev_params [configNr].dev->mtu
+                 params->dev->mtu
                + sizeof (struct ethhdr)
                + sizeof (struct rndis_packet_msg_type)
                + 22);
@@ -834,10 +596,7 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf)
        resp->AFListOffset = __constant_cpu_to_le32 (0);
        resp->AFListSize = __constant_cpu_to_le32 (0);
 
-       if (rndis_per_dev_params [configNr].ack)
-               rndis_per_dev_params [configNr].ack (
-                       rndis_per_dev_params [configNr].dev);
-
+       params->resp_avail(params->v);
        return 0;
 }
 
@@ -845,9 +604,11 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
 {
        rndis_query_cmplt_type *resp;
        rndis_resp_t            *r;
+       struct rndis_params     *params = rndis_per_dev_params + configNr;
 
        // DBG("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID));
-       if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
+       if (!params->dev)
+               return -ENOTSUPP;
 
        /*
         * we need more memory:
@@ -878,9 +639,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
        } else
                resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
 
-       if (rndis_per_dev_params [configNr].ack)
-               rndis_per_dev_params [configNr].ack (
-                       rndis_per_dev_params [configNr].dev);
+       params->resp_avail(params->v);
        return 0;
 }
 
@@ -889,6 +648,7 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
        u32                     BufLength, BufOffset;
        rndis_set_cmplt_type    *resp;
        rndis_resp_t            *r;
+       struct rndis_params     *params = rndis_per_dev_params + configNr;
 
        r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
        if (!r)
@@ -898,7 +658,7 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
        BufLength = le32_to_cpu (buf->InformationBufferLength);
        BufOffset = le32_to_cpu (buf->InformationBufferOffset);
 
-#ifdef VERBOSE
+#ifdef VERBOSE_DEBUG
        DBG("%s: Length: %d\n", __func__, BufLength);
        DBG("%s: Offset: %d\n", __func__, BufOffset);
        DBG("%s: InfoBuffer: ", __func__);
@@ -919,10 +679,7 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
        else
                resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
 
-       if (rndis_per_dev_params [configNr].ack)
-               rndis_per_dev_params [configNr].ack (
-                       rndis_per_dev_params [configNr].dev);
-
+       params->resp_avail(params->v);
        return 0;
 }
 
@@ -930,6 +687,7 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
 {
        rndis_reset_cmplt_type  *resp;
        rndis_resp_t            *r;
+       struct rndis_params     *params = rndis_per_dev_params + configNr;
 
        r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type));
        if (!r)
@@ -942,10 +700,7 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf)
        /* resent information */
        resp->AddressingReset = __constant_cpu_to_le32 (1);
 
-       if (rndis_per_dev_params [configNr].ack)
-               rndis_per_dev_params [configNr].ack (
-                       rndis_per_dev_params [configNr].dev);
-
+       params->resp_avail(params->v);
        return 0;
 }
 
@@ -954,6 +709,7 @@ static int rndis_keepalive_response (int configNr,
 {
        rndis_keepalive_cmplt_type      *resp;
        rndis_resp_t                    *r;
+       struct rndis_params     *params = rndis_per_dev_params + configNr;
 
        /* host "should" check only in RNDIS_DATA_INITIALIZED state */
 
@@ -968,10 +724,7 @@ static int rndis_keepalive_response (int configNr,
        resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
        resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS);
 
-       if (rndis_per_dev_params [configNr].ack)
-               rndis_per_dev_params [configNr].ack (
-                       rndis_per_dev_params [configNr].dev);
-
+       params->resp_avail(params->v);
        return 0;
 }
 
@@ -983,8 +736,9 @@ static int rndis_indicate_status_msg (int configNr, u32 status)
 {
        rndis_indicate_status_msg_type  *resp;
        rndis_resp_t                    *r;
+       struct rndis_params     *params = rndis_per_dev_params + configNr;
 
-       if (rndis_per_dev_params [configNr].state == RNDIS_UNINITIALIZED)
+       if (params->state == RNDIS_UNINITIALIZED)
                return -ENOTSUPP;
 
        r = rndis_add_response (configNr,
@@ -1000,9 +754,7 @@ static int rndis_indicate_status_msg (int configNr, u32 status)
        resp->StatusBufferLength = __constant_cpu_to_le32 (0);
        resp->StatusBufferOffset = __constant_cpu_to_le32 (0);
 
-       if (rndis_per_dev_params [configNr].ack)
-               rndis_per_dev_params [configNr].ack (
-                       rndis_per_dev_params [configNr].dev);
+       params->resp_avail(params->v);
        return 0;
 }
 
@@ -1029,7 +781,6 @@ void rndis_uninit (int configNr)
 
        if (configNr >= RNDIS_MAX_CONFIGS)
                return;
-       rndis_per_dev_params [configNr].used = 0;
        rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED;
 
        /* drain the response queue */
@@ -1142,21 +893,25 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
        return -ENOTSUPP;
 }
 
-int rndis_register (int (* rndis_control_ack) (struct net_device *))
+int rndis_register(void (*resp_avail)(void *v), void *v)
 {
        u8 i;
 
+       if (!resp_avail)
+               return -EINVAL;
+
        for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
                if (!rndis_per_dev_params [i].used) {
                        rndis_per_dev_params [i].used = 1;
-                       rndis_per_dev_params [i].ack = rndis_control_ack;
+                       rndis_per_dev_params [i].resp_avail = resp_avail;
+                       rndis_per_dev_params [i].v = v;
                        DBG("%s: configNr = %d\n", __func__, i);
                        return i;
                }
        }
        DBG("failed\n");
 
-       return -1;
+       return -ENODEV;
 }
 
 void rndis_deregister (int configNr)
@@ -1169,16 +924,14 @@ void rndis_deregister (int configNr)
        return;
 }
 
-int rndis_set_param_dev (u8 configNr, struct net_device *dev,
-                        struct net_device_stats *stats,
-                        u16 *cdc_filter)
+int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter)
 {
        DBG("%s:\n", __func__ );
-       if (!dev || !stats) return -1;
+       if (!dev)
+               return -EINVAL;
        if (configNr >= RNDIS_MAX_CONFIGS) return -1;
 
        rndis_per_dev_params [configNr].dev = dev;
-       rndis_per_dev_params [configNr].stats = stats;
        rndis_per_dev_params [configNr].filter = cdc_filter;
 
        return 0;
@@ -1296,14 +1049,11 @@ int rndis_rm_hdr(struct sk_buff *skb)
 
 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
 
-static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof,
-               void *data)
+static int rndis_proc_show(struct seq_file *m, void *v)
 {
-       char *out = page;
-       int len;
-       rndis_params *param = (rndis_params *) data;
+       rndis_params *param = m->private;
 
-       out += snprintf (out, count,
+       seq_printf(m,
                         "Config Nr. %d\n"
                         "used      : %s\n"
                         "state     : %s\n"
@@ -1326,25 +1076,13 @@ static int rndis_proc_read (char *page, char **start, off_t off, int count, int
                         (param->media_state) ? 0 : param->speed*100,
                         (param->media_state) ? "disconnected" : "connected",
                         param->vendorID, param->vendorDescr);
-
-       len = out - page;
-       len -= off;
-
-       if (len < count) {
-               *eof = 1;
-               if (len <= 0)
-                       return 0;
-       } else
-               len = count;
-
-       *start = page + off;
-       return len;
+       return 0;
 }
 
-static int rndis_proc_write (struct file *file, const char __user *buffer,
-               unsigned long count, void *data)
+static ssize_t rndis_proc_write(struct file *file, const char __user *buffer,
+               size_t count, loff_t *ppos)
 {
-       rndis_params *p = data;
+       rndis_params *p = PDE(file->f_path.dentry->d_inode)->data;
        u32 speed = 0;
        int i, fl_speed = 0;
 
@@ -1386,6 +1124,20 @@ static int rndis_proc_write (struct file *file, const char __user *buffer,
        return count;
 }
 
+static int rndis_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, rndis_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations rndis_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = rndis_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+       .write          = rndis_proc_write,
+};
+
 #define        NAME_TEMPLATE   "driver/rndis-%03d"
 
 static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
@@ -1403,7 +1155,9 @@ int __init rndis_init (void)
 
                sprintf (name, NAME_TEMPLATE, i);
                if (!(rndis_connect_state [i]
-                               = create_proc_entry (name, 0660, NULL)))
+                               = proc_create_data(name, 0660, NULL,
+                                       &rndis_proc_fops,
+                                       (void *)(rndis_per_dev_params + i))))
                {
                        DBG("%s :remove entries", __func__);
                        while (i) {
@@ -1413,11 +1167,6 @@ int __init rndis_init (void)
                        DBG("\n");
                        return -EIO;
                }
-
-               rndis_connect_state [i]->write_proc = rndis_proc_write;
-               rndis_connect_state [i]->read_proc = rndis_proc_read;
-               rndis_connect_state [i]->data = (void *)
-                               (rndis_per_dev_params + i);
 #endif
                rndis_per_dev_params [i].confignr = i;
                rndis_per_dev_params [i].used = 0;
index 397b149f3ca78bd24ea9209b9c5d0b815c61ec69..aac61dfe0f034d170a74151bb1070b1260341fa4 100644 (file)
@@ -1,8 +1,6 @@
 /*
  * RNDIS       Definitions for Remote NDIS
  *
- * Version:    $Id: rndis.h,v 1.15 2004/03/25 21:33:46 robert Exp $
- *
  * Authors:    Benedikt Spranger, Pengutronix
  *             Robert Schwebel, Pengutronix
  *
@@ -235,20 +233,19 @@ typedef struct rndis_params
        const u8                *host_mac;
        u16                     *filter;
        struct net_device       *dev;
-       struct net_device_stats *stats;
 
        u32                     vendorID;
        const char              *vendorDescr;
-       int                     (*ack) (struct net_device *);
+       void                    (*resp_avail)(void *v);
+       void                    *v;
        struct list_head        resp_queue;
 } rndis_params;
 
 /* RNDIS Message parser and other useless functions */
 int  rndis_msg_parser (u8 configNr, u8 *buf);
-int  rndis_register (int (*rndis_control_ack) (struct net_device *));
+int  rndis_register(void (*resp_avail)(void *v), void *v);
 void rndis_deregister (int configNr);
 int  rndis_set_param_dev (u8 configNr, struct net_device *dev,
-                        struct net_device_stats *stats,
                         u16 *cdc_filter);
 int  rndis_set_param_vendor (u8 configNr, u32 vendorID,
                            const char *vendorDescr);
index fa019fa733346591a1c3c0a16a458f52ee9b423c..b3699afff002f4115b4c3ffaf1b975638aa88f1f 100644 (file)
@@ -1,15 +1,9 @@
 /*
- * g_serial.c -- USB gadget serial driver
+ * serial.c -- USB gadget serial driver
  *
- * Copyright 2003 (C) Al Borchers (alborchers@steinerpoint.com)
- *
- * This code is based in part on the Gadget Zero driver, which
- * is Copyright (C) 2003 by David Brownell, all rights reserved.
- *
- * This code also borrows from usbserial.c, which is
- * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2000 Peter Berger (pberger@brimson.com)
- * Copyright (C) 2000 Al Borchers (alborchers@steinerpoint.com)
+ * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
+ * Copyright (C) 2008 by David Brownell
+ * Copyright (C) 2008 by Nokia Corporation
  *
  * This software is distributed under the terms of the GNU General
  * Public License ("GPL") as published by the Free Software Foundation,
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 
-#include <linux/usb/ch9.h>
-#include <linux/usb/cdc.h>
-#include <linux/usb/gadget.h>
-
+#include "u_serial.h"
 #include "gadget_chips.h"
 
 
 /* Defines */
 
-#define GS_VERSION_STR                 "v2.2"
-#define GS_VERSION_NUM                 0x2200
+#define GS_VERSION_STR                 "v2.4"
+#define GS_VERSION_NUM                 0x2400
 
 #define GS_LONG_NAME                   "Gadget Serial"
-#define GS_SHORT_NAME                  "g_serial"
-
-#define GS_MAJOR                       127
-#define GS_MINOR_START                 0
-
-/* REVISIT only one port is supported for now;
- * see gs_{send,recv}_packet() ... no multiplexing,
- * and no support for multiple ACM devices.
- */
-#define GS_NUM_PORTS                   1
-
-#define GS_NUM_CONFIGS                 1
-#define GS_NO_CONFIG_ID                        0
-#define GS_BULK_CONFIG_ID              1
-#define GS_ACM_CONFIG_ID               2
-
-#define GS_MAX_NUM_INTERFACES          2
-#define GS_BULK_INTERFACE_ID           0
-#define GS_CONTROL_INTERFACE_ID                0
-#define GS_DATA_INTERFACE_ID           1
-
-#define GS_MAX_DESC_LEN                        256
-
-#define GS_DEFAULT_READ_Q_SIZE         32
-#define GS_DEFAULT_WRITE_Q_SIZE                32
-
-#define GS_DEFAULT_WRITE_BUF_SIZE      8192
-#define GS_TMP_BUF_SIZE                        8192
-
-#define GS_CLOSE_TIMEOUT               15
-
-#define GS_DEFAULT_USE_ACM             0
-
-/* 9600-8-N-1 ... matches init_termios.c_cflag and defaults
- * expected by "usbser.sys" on MS-Windows.
- */
-#define GS_DEFAULT_DTE_RATE            9600
-#define GS_DEFAULT_DATA_BITS           8
-#define GS_DEFAULT_PARITY              USB_CDC_NO_PARITY
-#define GS_DEFAULT_CHAR_FORMAT         USB_CDC_1_STOP_BITS
-
-/* maxpacket and other transfer characteristics vary by speed. */
-static inline struct usb_endpoint_descriptor *
-choose_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,
-               struct usb_endpoint_descriptor *fs)
-{
-       if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
-               return hs;
-       return fs;
-}
-
-
-/* debug settings */
-#ifdef DEBUG
-static int debug = 1;
-#else
-#define        debug 0
-#endif
-
-#define gs_debug(format, arg...) \
-       do { if (debug) pr_debug(format, ## arg); } while (0)
-#define gs_debug_level(level, format, arg...) \
-       do { if (debug >= level) pr_debug(format, ## arg); } while (0)
+#define GS_VERSION_NAME                        GS_LONG_NAME " " GS_VERSION_STR
 
+/*-------------------------------------------------------------------------*/
 
 /* Thanks to NetChip Technologies for donating this product ID.
- *
- * DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
- * Instead:  allocate your own, using normal USB-IF procedures.
- */
+*
+* DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
+* Instead:  allocate your own, using normal USB-IF procedures.
+*/
 #define GS_VENDOR_ID                   0x0525  /* NetChip */
 #define GS_PRODUCT_ID                  0xa4a6  /* Linux-USB Serial Gadget */
 #define GS_CDC_PRODUCT_ID              0xa4a7  /* ... as CDC-ACM */
 
-#define GS_LOG2_NOTIFY_INTERVAL                5       /* 1 << 5 == 32 msec */
-#define GS_NOTIFY_MAXPACKET            8
+/* string IDs are assigned dynamically */
 
+#define STRING_MANUFACTURER_IDX                0
+#define STRING_PRODUCT_IDX             1
+#define STRING_DESCRIPTION_IDX         2
 
-/* circular buffer */
-struct gs_buf {
-       unsigned int            buf_size;
-       char                    *buf_buf;
-       char                    *buf_get;
-       char                    *buf_put;
-};
-
-/* the port structure holds info for each port, one for each minor number */
-struct gs_port {
-       struct gs_dev           *port_dev;      /* pointer to device struct */
-       struct tty_struct       *port_tty;      /* pointer to tty struct */
-       spinlock_t              port_lock;
-       int                     port_num;
-       int                     port_open_count;
-       int                     port_in_use;    /* open/close in progress */
-       wait_queue_head_t       port_write_wait;/* waiting to write */
-       struct gs_buf           *port_write_buf;
-       struct usb_cdc_line_coding port_line_coding;    /* 8-N-1 etc */
-       u16                     port_handshake_bits;
-#define RS232_RTS      (1 << 1)
-#define RS232_DTE      (1 << 0)
-};
+static char manufacturer[50];
 
-/* the device structure holds info for the USB device */
-struct gs_dev {
-       struct usb_gadget       *dev_gadget;    /* gadget device pointer */
-       spinlock_t              dev_lock;       /* lock for set/reset config */
-       int                     dev_config;     /* configuration number */
-       struct usb_ep           *dev_notify_ep; /* address of notify endpoint */
-       struct usb_ep           *dev_in_ep;     /* address of in endpoint */
-       struct usb_ep           *dev_out_ep;    /* address of out endpoint */
-       struct usb_endpoint_descriptor          /* descriptor of notify ep */
-                               *dev_notify_ep_desc;
-       struct usb_endpoint_descriptor          /* descriptor of in endpoint */
-                               *dev_in_ep_desc;
-       struct usb_endpoint_descriptor          /* descriptor of out endpoint */
-                               *dev_out_ep_desc;
-       struct usb_request      *dev_ctrl_req;  /* control request */
-       struct list_head        dev_req_list;   /* list of write requests */
-       int                     dev_sched_port; /* round robin port scheduled */
-       struct gs_port          *dev_port[GS_NUM_PORTS]; /* the ports */
+static struct usb_string strings_dev[] = {
+       [STRING_MANUFACTURER_IDX].s = manufacturer,
+       [STRING_PRODUCT_IDX].s = GS_VERSION_NAME,
+       [STRING_DESCRIPTION_IDX].s = NULL /* updated; f(use_acm) */,
+       {  } /* end of list */
 };
 
-
-/* Functions */
-
-/* tty driver internals */
-static int gs_send(struct gs_dev *dev);
-static int gs_send_packet(struct gs_dev *dev, char *packet,
-       unsigned int size);
-static int gs_recv_packet(struct gs_dev *dev, char *packet,
-       unsigned int size);
-static void gs_read_complete(struct usb_ep *ep, struct usb_request *req);
-static void gs_write_complete(struct usb_ep *ep, struct usb_request *req);
-
-/* gadget driver internals */
-static int gs_set_config(struct gs_dev *dev, unsigned config);
-static void gs_reset_config(struct gs_dev *dev);
-static int gs_build_config_buf(u8 *buf, struct usb_gadget *g,
-               u8 type, unsigned int index, int is_otg);
-
-static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len,
-       gfp_t kmalloc_flags);
-static void gs_free_req(struct usb_ep *ep, struct usb_request *req);
-
-static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags);
-static void gs_free_ports(struct gs_dev *dev);
-
-/* circular buffer */
-static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags);
-static void gs_buf_free(struct gs_buf *gb);
-static void gs_buf_clear(struct gs_buf *gb);
-static unsigned int gs_buf_data_avail(struct gs_buf *gb);
-static unsigned int gs_buf_space_avail(struct gs_buf *gb);
-static unsigned int gs_buf_put(struct gs_buf *gb, const char *buf,
-       unsigned int count);
-static unsigned int gs_buf_get(struct gs_buf *gb, char *buf,
-       unsigned int count);
-
-
-/* Globals */
-
-static struct gs_dev *gs_device;
-
-static struct mutex gs_open_close_lock[GS_NUM_PORTS];
-
-
-/*-------------------------------------------------------------------------*/
-
-/* USB descriptors */
-
-#define GS_MANUFACTURER_STR_ID 1
-#define GS_PRODUCT_STR_ID      2
-#define GS_SERIAL_STR_ID       3
-#define GS_BULK_CONFIG_STR_ID  4
-#define GS_ACM_CONFIG_STR_ID   5
-#define GS_CONTROL_STR_ID      6
-#define GS_DATA_STR_ID         7
-
-/* static strings, in UTF-8 */
-static char manufacturer[50];
-static struct usb_string gs_strings[] = {
-       { GS_MANUFACTURER_STR_ID, manufacturer },
-       { GS_PRODUCT_STR_ID, GS_LONG_NAME },
-       { GS_BULK_CONFIG_STR_ID, "Gadget Serial Bulk" },
-       { GS_ACM_CONFIG_STR_ID, "Gadget Serial CDC ACM" },
-       { GS_CONTROL_STR_ID, "Gadget Serial Control" },
-       { GS_DATA_STR_ID, "Gadget Serial Data" },
-       {  } /* end of list */
+static struct usb_gadget_strings stringtab_dev = {
+       .language       = 0x0409,       /* en-us */
+       .strings        = strings_dev,
 };
 
-static struct usb_gadget_strings gs_string_table = {
-       .language =             0x0409, /* en-us */
-       .strings =              gs_strings,
+static struct usb_gadget_strings *dev_strings[] = {
+       &stringtab_dev,
+       NULL,
 };
 
-static struct usb_device_descriptor gs_device_desc = {
+static struct usb_device_descriptor device_desc = {
        .bLength =              USB_DT_DEVICE_SIZE,
        .bDescriptorType =      USB_DT_DEVICE,
        .bcdUSB =               __constant_cpu_to_le16(0x0200),
+       /* .bDeviceClass = f(use_acm) */
        .bDeviceSubClass =      0,
        .bDeviceProtocol =      0,
+       /* .bMaxPacketSize0 = f(hardware) */
        .idVendor =             __constant_cpu_to_le16(GS_VENDOR_ID),
-       .idProduct =            __constant_cpu_to_le16(GS_PRODUCT_ID),
-       .iManufacturer =        GS_MANUFACTURER_STR_ID,
-       .iProduct =             GS_PRODUCT_STR_ID,
-       .bNumConfigurations =   GS_NUM_CONFIGS,
+       /* .idProduct = f(use_acm) */
+       /* .bcdDevice = f(hardware) */
+       /* .iManufacturer = DYNAMIC */
+       /* .iProduct = DYNAMIC */
+       .bNumConfigurations =   1,
 };
 
-static struct usb_otg_descriptor gs_otg_descriptor = {
-       .bLength =              sizeof(gs_otg_descriptor),
+static struct usb_otg_descriptor otg_descriptor = {
+       .bLength =              sizeof otg_descriptor,
        .bDescriptorType =      USB_DT_OTG,
-       .bmAttributes =         USB_OTG_SRP,
-};
-
-static struct usb_config_descriptor gs_bulk_config_desc = {
-       .bLength =              USB_DT_CONFIG_SIZE,
-       .bDescriptorType =      USB_DT_CONFIG,
-       /* .wTotalLength computed dynamically */
-       .bNumInterfaces =       1,
-       .bConfigurationValue =  GS_BULK_CONFIG_ID,
-       .iConfiguration =       GS_BULK_CONFIG_STR_ID,
-       .bmAttributes =         USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-       .bMaxPower =            1,
-};
-
-static struct usb_config_descriptor gs_acm_config_desc = {
-       .bLength =              USB_DT_CONFIG_SIZE,
-       .bDescriptorType =      USB_DT_CONFIG,
-       /* .wTotalLength computed dynamically */
-       .bNumInterfaces =       2,
-       .bConfigurationValue =  GS_ACM_CONFIG_ID,
-       .iConfiguration =       GS_ACM_CONFIG_STR_ID,
-       .bmAttributes =         USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-       .bMaxPower =            1,
-};
-
-static const struct usb_interface_descriptor gs_bulk_interface_desc = {
-       .bLength =              USB_DT_INTERFACE_SIZE,
-       .bDescriptorType =      USB_DT_INTERFACE,
-       .bInterfaceNumber =     GS_BULK_INTERFACE_ID,
-       .bNumEndpoints =        2,
-       .bInterfaceClass =      USB_CLASS_VENDOR_SPEC,
-       .bInterfaceSubClass =   0,
-       .bInterfaceProtocol =   0,
-       .iInterface =           GS_DATA_STR_ID,
-};
-
-static const struct usb_interface_descriptor gs_control_interface_desc = {
-       .bLength =              USB_DT_INTERFACE_SIZE,
-       .bDescriptorType =      USB_DT_INTERFACE,
-       .bInterfaceNumber =     GS_CONTROL_INTERFACE_ID,
-       .bNumEndpoints =        1,
-       .bInterfaceClass =      USB_CLASS_COMM,
-       .bInterfaceSubClass =   USB_CDC_SUBCLASS_ACM,
-       .bInterfaceProtocol =   USB_CDC_ACM_PROTO_AT_V25TER,
-       .iInterface =           GS_CONTROL_STR_ID,
-};
-
-static const struct usb_interface_descriptor gs_data_interface_desc = {
-       .bLength =              USB_DT_INTERFACE_SIZE,
-       .bDescriptorType =      USB_DT_INTERFACE,
-       .bInterfaceNumber =     GS_DATA_INTERFACE_ID,
-       .bNumEndpoints =        2,
-       .bInterfaceClass =      USB_CLASS_CDC_DATA,
-       .bInterfaceSubClass =   0,
-       .bInterfaceProtocol =   0,
-       .iInterface =           GS_DATA_STR_ID,
-};
-
-static const struct usb_cdc_header_desc gs_header_desc = {
-       .bLength =              sizeof(gs_header_desc),
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
-       .bcdCDC =               __constant_cpu_to_le16(0x0110),
-};
-
-static const struct usb_cdc_call_mgmt_descriptor gs_call_mgmt_descriptor = {
-       .bLength =              sizeof(gs_call_mgmt_descriptor),
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubType =   USB_CDC_CALL_MANAGEMENT_TYPE,
-       .bmCapabilities =       0,
-       .bDataInterface =       1,      /* index of data interface */
-};
-
-static struct usb_cdc_acm_descriptor gs_acm_descriptor = {
-       .bLength =              sizeof(gs_acm_descriptor),
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubType =   USB_CDC_ACM_TYPE,
-       .bmCapabilities =       (1 << 1),
-};
-
-static const struct usb_cdc_union_desc gs_union_desc = {
-       .bLength =              sizeof(gs_union_desc),
-       .bDescriptorType =      USB_DT_CS_INTERFACE,
-       .bDescriptorSubType =   USB_CDC_UNION_TYPE,
-       .bMasterInterface0 =    0,      /* index of control interface */
-       .bSlaveInterface0 =     1,      /* index of data interface */
-};
-
-static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
-       .bInterval =            1 << GS_LOG2_NOTIFY_INTERVAL,
-};
-
-static struct usb_endpoint_descriptor gs_fullspeed_in_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-};
-
-static struct usb_endpoint_descriptor gs_fullspeed_out_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_OUT,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-};
-
-static const struct usb_descriptor_header *gs_bulk_fullspeed_function[] = {
-       (struct usb_descriptor_header *) &gs_otg_descriptor,
-       (struct usb_descriptor_header *) &gs_bulk_interface_desc,
-       (struct usb_descriptor_header *) &gs_fullspeed_in_desc,
-       (struct usb_descriptor_header *) &gs_fullspeed_out_desc,
-       NULL,
-};
-
-static const struct usb_descriptor_header *gs_acm_fullspeed_function[] = {
-       (struct usb_descriptor_header *) &gs_otg_descriptor,
-       (struct usb_descriptor_header *) &gs_control_interface_desc,
-       (struct usb_descriptor_header *) &gs_header_desc,
-       (struct usb_descriptor_header *) &gs_call_mgmt_descriptor,
-       (struct usb_descriptor_header *) &gs_acm_descriptor,
-       (struct usb_descriptor_header *) &gs_union_desc,
-       (struct usb_descriptor_header *) &gs_fullspeed_notify_desc,
-       (struct usb_descriptor_header *) &gs_data_interface_desc,
-       (struct usb_descriptor_header *) &gs_fullspeed_in_desc,
-       (struct usb_descriptor_header *) &gs_fullspeed_out_desc,
-       NULL,
-};
-
-static struct usb_endpoint_descriptor gs_highspeed_notify_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_INT,
-       .wMaxPacketSize =       __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
-       .bInterval =            GS_LOG2_NOTIFY_INTERVAL+4,
-};
-
-static struct usb_endpoint_descriptor gs_highspeed_in_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
-};
-
-static struct usb_endpoint_descriptor gs_highspeed_out_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
-};
-
-static struct usb_qualifier_descriptor gs_qualifier_desc = {
-       .bLength =              sizeof(struct usb_qualifier_descriptor),
-       .bDescriptorType =      USB_DT_DEVICE_QUALIFIER,
-       .bcdUSB =               __constant_cpu_to_le16 (0x0200),
-       /* assumes ep0 uses the same value for both speeds ... */
-       .bNumConfigurations =   GS_NUM_CONFIGS,
-};
 
-static const struct usb_descriptor_header *gs_bulk_highspeed_function[] = {
-       (struct usb_descriptor_header *) &gs_otg_descriptor,
-       (struct usb_descriptor_header *) &gs_bulk_interface_desc,
-       (struct usb_descriptor_header *) &gs_highspeed_in_desc,
-       (struct usb_descriptor_header *) &gs_highspeed_out_desc,
-       NULL,
+       /* REVISIT SRP-only hardware is possible, although
+        * it would not be called "OTG" ...
+        */
+       .bmAttributes =         USB_OTG_SRP | USB_OTG_HNP,
 };
 
-static const struct usb_descriptor_header *gs_acm_highspeed_function[] = {
-       (struct usb_descriptor_header *) &gs_otg_descriptor,
-       (struct usb_descriptor_header *) &gs_control_interface_desc,
-       (struct usb_descriptor_header *) &gs_header_desc,
-       (struct usb_descriptor_header *) &gs_call_mgmt_descriptor,
-       (struct usb_descriptor_header *) &gs_acm_descriptor,
-       (struct usb_descriptor_header *) &gs_union_desc,
-       (struct usb_descriptor_header *) &gs_highspeed_notify_desc,
-       (struct usb_descriptor_header *) &gs_data_interface_desc,
-       (struct usb_descriptor_header *) &gs_highspeed_in_desc,
-       (struct usb_descriptor_header *) &gs_highspeed_out_desc,
+static const struct usb_descriptor_header *otg_desc[] = {
+       (struct usb_descriptor_header *) &otg_descriptor,
        NULL,
 };
 
-
 /*-------------------------------------------------------------------------*/
 
 /* Module */
-MODULE_DESCRIPTION(GS_LONG_NAME);
+MODULE_DESCRIPTION(GS_VERSION_NAME);
 MODULE_AUTHOR("Al Borchers");
+MODULE_AUTHOR("David Brownell");
 MODULE_LICENSE("GPL");
 
-#ifdef DEBUG
-module_param(debug, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on");
-#endif
+static int use_acm = true;
+module_param(use_acm, bool, 0);
+MODULE_PARM_DESC(use_acm, "Use CDC ACM, default=yes");
 
-static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE;
-module_param(read_q_size, uint, S_IRUGO);
-MODULE_PARM_DESC(read_q_size, "Read request queue size, default=32");
-
-static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE;
-module_param(write_q_size, uint, S_IRUGO);
-MODULE_PARM_DESC(write_q_size, "Write request queue size, default=32");
-
-static unsigned int write_buf_size = GS_DEFAULT_WRITE_BUF_SIZE;
-module_param(write_buf_size, uint, S_IRUGO);
-MODULE_PARM_DESC(write_buf_size, "Write buffer size, default=8192");
-
-static unsigned int use_acm = GS_DEFAULT_USE_ACM;
-module_param(use_acm, uint, S_IRUGO);
-MODULE_PARM_DESC(use_acm, "Use CDC ACM, 0=no, 1=yes, default=no");
+static unsigned n_ports = 1;
+module_param(n_ports, uint, 0);
+MODULE_PARM_DESC(n_ports, "number of ports to create, default=1");
 
 /*-------------------------------------------------------------------------*/
 
-/* TTY Driver */
-
-/*
- * gs_open
- */
-static int gs_open(struct tty_struct *tty, struct file *file)
-{
-       int port_num;
-       unsigned long flags;
-       struct gs_port *port;
-       struct gs_dev *dev;
-       struct gs_buf *buf;
-       struct mutex *mtx;
-       int ret;
-
-       port_num = tty->index;
-
-       gs_debug("gs_open: (%d,%p,%p)\n", port_num, tty, file);
-
-       if (port_num < 0 || port_num >= GS_NUM_PORTS) {
-               pr_err("gs_open: (%d,%p,%p) invalid port number\n",
-                       port_num, tty, file);
-               return -ENODEV;
-       }
-
-       dev = gs_device;
-
-       if (dev == NULL) {
-               pr_err("gs_open: (%d,%p,%p) NULL device pointer\n",
-                       port_num, tty, file);
-               return -ENODEV;
-       }
-
-       mtx = &gs_open_close_lock[port_num];
-       if (mutex_lock_interruptible(mtx)) {
-               pr_err("gs_open: (%d,%p,%p) interrupted waiting for mutex\n",
-                       port_num, tty, file);
-               return -ERESTARTSYS;
-       }
-
-       spin_lock_irqsave(&dev->dev_lock, flags);
-
-       if (dev->dev_config == GS_NO_CONFIG_ID) {
-               pr_err("gs_open: (%d,%p,%p) device is not connected\n",
-                       port_num, tty, file);
-               ret = -ENODEV;
-               goto exit_unlock_dev;
-       }
-
-       port = dev->dev_port[port_num];
-
-       if (port == NULL) {
-               pr_err("gs_open: (%d,%p,%p) NULL port pointer\n",
-                       port_num, tty, file);
-               ret = -ENODEV;
-               goto exit_unlock_dev;
-       }
-
-       spin_lock(&port->port_lock);
-       spin_unlock(&dev->dev_lock);
-
-       if (port->port_dev == NULL) {
-               pr_err("gs_open: (%d,%p,%p) port disconnected (1)\n",
-                       port_num, tty, file);
-               ret = -EIO;
-               goto exit_unlock_port;
-       }
-
-       if (port->port_open_count > 0) {
-               ++port->port_open_count;
-               gs_debug("gs_open: (%d,%p,%p) already open\n",
-                       port_num, tty, file);
-               ret = 0;
-               goto exit_unlock_port;
-       }
-
-       tty->driver_data = NULL;
-
-       /* mark port as in use, we can drop port lock and sleep if necessary */
-       port->port_in_use = 1;
-
-       /* allocate write buffer on first open */
-       if (port->port_write_buf == NULL) {
-               spin_unlock_irqrestore(&port->port_lock, flags);
-               buf = gs_buf_alloc(write_buf_size, GFP_KERNEL);
-               spin_lock_irqsave(&port->port_lock, flags);
-
-               /* might have been disconnected while asleep, check */
-               if (port->port_dev == NULL) {
-                       pr_err("gs_open: (%d,%p,%p) port disconnected (2)\n",
-                               port_num, tty, file);
-                       port->port_in_use = 0;
-                       ret = -EIO;
-                       goto exit_unlock_port;
-               }
-
-               if ((port->port_write_buf=buf) == NULL) {
-                       pr_err("gs_open: (%d,%p,%p) cannot allocate "
-                               "port write buffer\n",
-                               port_num, tty, file);
-                       port->port_in_use = 0;
-                       ret = -ENOMEM;
-                       goto exit_unlock_port;
-               }
-
-       }
-
-       /* wait for carrier detect (not implemented) */
-
-       /* might have been disconnected while asleep, check */
-       if (port->port_dev == NULL) {
-               pr_err("gs_open: (%d,%p,%p) port disconnected (3)\n",
-                       port_num, tty, file);
-               port->port_in_use = 0;
-               ret = -EIO;
-               goto exit_unlock_port;
-       }
-
-       tty->driver_data = port;
-       port->port_tty = tty;
-       port->port_open_count = 1;
-       port->port_in_use = 0;
-
-       gs_debug("gs_open: (%d,%p,%p) completed\n", port_num, tty, file);
-
-       ret = 0;
-
-exit_unlock_port:
-       spin_unlock_irqrestore(&port->port_lock, flags);
-       mutex_unlock(mtx);
-       return ret;
-
-exit_unlock_dev:
-       spin_unlock_irqrestore(&dev->dev_lock, flags);
-       mutex_unlock(mtx);
-       return ret;
-
-}
-
-/*
- * gs_close
- */
-
-static int gs_write_finished_event_safely(struct gs_port *p)
-{
-       int cond;
-
-       spin_lock_irq(&(p)->port_lock);
-       cond = !(p)->port_dev || !gs_buf_data_avail((p)->port_write_buf);
-       spin_unlock_irq(&(p)->port_lock);
-       return cond;
-}
-
-static void gs_close(struct tty_struct *tty, struct file *file)
+static int __init serial_bind_config(struct usb_configuration *c)
 {
-       struct gs_port *port = tty->driver_data;
-       struct mutex *mtx;
+       unsigned i;
+       int status = 0;
 
-       if (port == NULL) {
-               pr_err("gs_close: NULL port pointer\n");
-               return;
-       }
-
-       gs_debug("gs_close: (%d,%p,%p)\n", port->port_num, tty, file);
-
-       mtx = &gs_open_close_lock[port->port_num];
-       mutex_lock(mtx);
-
-       spin_lock_irq(&port->port_lock);
-
-       if (port->port_open_count == 0) {
-               pr_err("gs_close: (%d,%p,%p) port is already closed\n",
-                       port->port_num, tty, file);
-               goto exit;
-       }
-
-       if (port->port_open_count > 1) {
-               --port->port_open_count;
-               goto exit;
-       }
-
-       /* free disconnected port on final close */
-       if (port->port_dev == NULL) {
-               kfree(port);
-               goto exit;
-       }
-
-       /* mark port as closed but in use, we can drop port lock */
-       /* and sleep if necessary */
-       port->port_in_use = 1;
-       port->port_open_count = 0;
-
-       /* wait for write buffer to drain, or */
-       /* at most GS_CLOSE_TIMEOUT seconds */
-       if (gs_buf_data_avail(port->port_write_buf) > 0) {
-               spin_unlock_irq(&port->port_lock);
-               wait_event_interruptible_timeout(port->port_write_wait,
-                                       gs_write_finished_event_safely(port),
-                                       GS_CLOSE_TIMEOUT * HZ);
-               spin_lock_irq(&port->port_lock);
-       }
-
-       /* free disconnected port on final close */
-       /* (might have happened during the above sleep) */
-       if (port->port_dev == NULL) {
-               kfree(port);
-               goto exit;
+       for (i = 0; i < n_ports && status == 0; i++) {
+               if (use_acm)
+                       status = acm_bind_config(c, i);
+               else
+                       status = gser_bind_config(c, i);
        }
-
-       gs_buf_clear(port->port_write_buf);
-
-       tty->driver_data = NULL;
-       port->port_tty = NULL;
-       port->port_in_use = 0;
-
-       gs_debug("gs_close: (%d,%p,%p) completed\n",
-               port->port_num, tty, file);
-
-exit:
-       spin_unlock_irq(&port->port_lock);
-       mutex_unlock(mtx);
+       return status;
 }
 
-/*
- * gs_write
- */
-static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count)
-{
-       unsigned long flags;
-       struct gs_port *port = tty->driver_data;
-       int ret;
-
-       if (port == NULL) {
-               pr_err("gs_write: NULL port pointer\n");
-               return -EIO;
-       }
-
-       gs_debug("gs_write: (%d,%p) writing %d bytes\n", port->port_num, tty,
-               count);
-
-       if (count == 0)
-               return 0;
-
-       spin_lock_irqsave(&port->port_lock, flags);
-
-       if (port->port_dev == NULL) {
-               pr_err("gs_write: (%d,%p) port is not connected\n",
-                       port->port_num, tty);
-               ret = -EIO;
-               goto exit;
-       }
-
-       if (port->port_open_count == 0) {
-               pr_err("gs_write: (%d,%p) port is closed\n",
-                       port->port_num, tty);
-               ret = -EBADF;
-               goto exit;
-       }
-
-       count = gs_buf_put(port->port_write_buf, buf, count);
-
-       spin_unlock_irqrestore(&port->port_lock, flags);
-
-       gs_send(gs_device);
-
-       gs_debug("gs_write: (%d,%p) wrote %d bytes\n", port->port_num, tty,
-               count);
-
-       return count;
-
-exit:
-       spin_unlock_irqrestore(&port->port_lock, flags);
-       return ret;
-}
+static struct usb_configuration serial_config_driver = {
+       /* .label = f(use_acm) */
+       .bind           = serial_bind_config,
+       /* .bConfigurationValue = f(use_acm) */
+       /* .iConfiguration = DYNAMIC */
+       .bmAttributes   = USB_CONFIG_ATT_SELFPOWER,
+       .bMaxPower      = 1,    /* 2 mA, minimal */
+};
 
-/*
- * gs_put_char
- */
-static int gs_put_char(struct tty_struct *tty, unsigned char ch)
+static int __init gs_bind(struct usb_composite_dev *cdev)
 {
-       unsigned long flags;
-       struct gs_port *port = tty->driver_data;
-       int ret = 0;
-
-       if (port == NULL) {
-               pr_err("gs_put_char: NULL port pointer\n");
-               return 0;
-       }
-
-       gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p\n",
-               port->port_num, tty, ch, __builtin_return_address(0));
+       int                     gcnum;
+       struct usb_gadget       *gadget = cdev->gadget;
+       int                     status;
 
-       spin_lock_irqsave(&port->port_lock, flags);
+       status = gserial_setup(cdev->gadget, n_ports);
+       if (status < 0)
+               return status;
 
-       if (port->port_dev == NULL) {
-               pr_err("gs_put_char: (%d,%p) port is not connected\n",
-                       port->port_num, tty);
-               goto exit;
-       }
-
-       if (port->port_open_count == 0) {
-               pr_err("gs_put_char: (%d,%p) port is closed\n",
-                       port->port_num, tty);
-               goto exit;
-       }
+       /* Allocate string descriptor numbers ... note that string
+        * contents can be overridden by the composite_dev glue.
+        */
 
-       ret = gs_buf_put(port->port_write_buf, &ch, 1);
+       /* device description: manufacturer, product */
+       snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
+               init_utsname()->sysname, init_utsname()->release,
+               gadget->name);
+       status = usb_string_id(cdev);
+       if (status < 0)
+               goto fail;
+       strings_dev[STRING_MANUFACTURER_IDX].id = status;
 
-exit:
-       spin_unlock_irqrestore(&port->port_lock, flags);
-       return ret;
-}
+       device_desc.iManufacturer = status;
 
-/*
- * gs_flush_chars
- */
-static void gs_flush_chars(struct tty_struct *tty)
-{
-       unsigned long flags;
-       struct gs_port *port = tty->driver_data;
+       status = usb_string_id(cdev);
+       if (status < 0)
+               goto fail;
+       strings_dev[STRING_PRODUCT_IDX].id = status;
 
-       if (port == NULL) {
-               pr_err("gs_flush_chars: NULL port pointer\n");
-               return;
-       }
+       device_desc.iProduct = status;
 
-       gs_debug("gs_flush_chars: (%d,%p)\n", port->port_num, tty);
+       /* config description */
+       status = usb_string_id(cdev);
+       if (status < 0)
+               goto fail;
+       strings_dev[STRING_DESCRIPTION_IDX].id = status;
 
-       spin_lock_irqsave(&port->port_lock, flags);
+       serial_config_driver.iConfiguration = status;
 
-       if (port->port_dev == NULL) {
-               pr_err("gs_flush_chars: (%d,%p) port is not connected\n",
-                       port->port_num, tty);
-               goto exit;
+       /* set up other descriptors */
+       gcnum = usb_gadget_controller_number(gadget);
+       if (gcnum >= 0)
+               device_desc.bcdDevice = cpu_to_le16(GS_VERSION_NUM | gcnum);
+       else {
+               /* this is so simple (for now, no altsettings) that it
+                * SHOULD NOT have problems with bulk-capable hardware.
+                * so warn about unrcognized controllers -- don't panic.
+                *
+                * things like configuration and altsetting numbering
+                * can need hardware-specific attention though.
+                */
+               pr_warning("gs_bind: controller '%s' not recognized\n",
+                       gadget->name);
+               device_desc.bcdDevice =
+                       __constant_cpu_to_le16(GS_VERSION_NUM | 0x0099);
        }
 
-       if (port->port_open_count == 0) {
-               pr_err("gs_flush_chars: (%d,%p) port is closed\n",
-                       port->port_num, tty);
-               goto exit;
+       if (gadget_is_otg(cdev->gadget)) {
+               serial_config_driver.descriptors = otg_desc;
+               serial_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
        }
 
-       spin_unlock_irqrestore(&port->port_lock, flags);
-
-       gs_send(gs_device);
-
-       return;
-
-exit:
-       spin_unlock_irqrestore(&port->port_lock, flags);
-}
-
-/*
- * gs_write_room
- */
-static int gs_write_room(struct tty_struct *tty)
-{
-
-       int room = 0;
-       unsigned long flags;
-       struct gs_port *port = tty->driver_data;
-
-
-       if (port == NULL)
-               return 0;
-
-       spin_lock_irqsave(&port->port_lock, flags);
-
-       if (port->port_dev != NULL && port->port_open_count > 0
-       && port->port_write_buf != NULL)
-               room = gs_buf_space_avail(port->port_write_buf);
-
-       spin_unlock_irqrestore(&port->port_lock, flags);
-
-       gs_debug("gs_write_room: (%d,%p) room=%d\n",
-               port->port_num, tty, room);
-
-       return room;
-}
-
-/*
- * gs_chars_in_buffer
- */
-static int gs_chars_in_buffer(struct tty_struct *tty)
-{
-       int chars = 0;
-       unsigned long flags;
-       struct gs_port *port = tty->driver_data;
-
-       if (port == NULL)
-               return 0;
-
-       spin_lock_irqsave(&port->port_lock, flags);
+       /* register our configuration */
+       status = usb_add_config(cdev, &serial_config_driver);
+       if (status < 0)
+               goto fail;
 
-       if (port->port_dev != NULL && port->port_open_count > 0
-       && port->port_write_buf != NULL)
-               chars = gs_buf_data_avail(port->port_write_buf);
-
-       spin_unlock_irqrestore(&port->port_lock, flags);
-
-       gs_debug("gs_chars_in_buffer: (%d,%p) chars=%d\n",
-               port->port_num, tty, chars);
-
-       return chars;
-}
+       INFO(cdev, "%s\n", GS_VERSION_NAME);
 
-/*
- * gs_throttle
- */
-static void gs_throttle(struct tty_struct *tty)
-{
-}
+       return 0;
 
-/*
- * gs_unthrottle
- */
-static void gs_unthrottle(struct tty_struct *tty)
-{
+fail:
+       gserial_cleanup();
+       return status;
 }
 
-/*
- * gs_break
- */
-static void gs_break(struct tty_struct *tty, int break_state)
-{
-}
+static struct usb_composite_driver gserial_driver = {
+       .name           = "g_serial",
+       .dev            = &device_desc,
+       .strings        = dev_strings,
+       .bind           = gs_bind,
+};
 
-/*
- * gs_ioctl
- */
-static int gs_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
+static int __init init(void)
 {
-       struct gs_port *port = tty->driver_data;
-
-       if (port == NULL) {
-               pr_err("gs_ioctl: NULL port pointer\n");
-               return -EIO;
+       /* We *could* export two configs; that'd be much cleaner...
+        * but neither of these product IDs was defined that way.
+        */
+       if (use_acm) {
+               serial_config_driver.label = "CDC ACM config";
+               serial_config_driver.bConfigurationValue = 2;
+               device_desc.bDeviceClass = USB_CLASS_COMM;
+               device_desc.idProduct =
+                               __constant_cpu_to_le16(GS_CDC_PRODUCT_ID);
+       } else {
+               serial_config_driver.label = "Generic Serial config";
+               serial_config_driver.bConfigurationValue = 1;
+               device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+               device_desc.idProduct =
+                               __constant_cpu_to_le16(GS_PRODUCT_ID);
        }
+       strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label;
 
-       gs_debug("gs_ioctl: (%d,%p,%p) cmd=0x%4.4x, arg=%lu\n",
-               port->port_num, tty, file, cmd, arg);
-
-       /* handle ioctls */
-
-       /* could not handle ioctl */
-       return -ENOIOCTLCMD;
+       return usb_composite_register(&gserial_driver);
 }
+module_init(init);
 
-/*
- * gs_set_termios
- */
-static void gs_set_termios(struct tty_struct *tty, struct ktermios *old)
+static void __exit cleanup(void)
 {
+       usb_composite_unregister(&gserial_driver);
+       gserial_cleanup();
 }
-
-static const struct tty_operations gs_tty_ops = {
-       .open =                 gs_open,
-       .close =                gs_close,
-       .write =                gs_write,
-       .put_char =             gs_put_char,
-       .flush_chars =          gs_flush_chars,
-       .write_room =           gs_write_room,
-       .ioctl =                gs_ioctl,
-       .set_termios =          gs_set_termios,
-       .throttle =             gs_throttle,
-       .unthrottle =           gs_unthrottle,
-       .break_ctl =            gs_break,
-       .chars_in_buffer =      gs_chars_in_buffer,
-};
-
-/*-------------------------------------------------------------------------*/
-
-/*
-* gs_send
-*
-* This function finds available write requests, calls
-* gs_send_packet to fill these packets with data, and
-* continues until either there are no more write requests
-* available or no more data to send.  This function is
-* run whenever data arrives or write requests are available.
-*/
-static int gs_send(struct gs_dev *dev)
-{
-       int ret,len;
-       unsigned long flags;
-       struct usb_ep *ep;
-       struct usb_request *req;
-
-       if (dev == NULL) {
-               pr_err("gs_send: NULL device pointer\n");
-               return -ENODEV;
-       }
-
-       spin_lock_irqsave(&dev->dev_lock, flags);
-
-       ep = dev->dev_in_ep;
-
-       while(!list_empty(&dev->dev_req_list)) {
-
-               req = list_entry(dev->dev_req_list.next,
-                               struct usb_request, list);
-
-               len = gs_send_packet(dev, req->buf, ep->maxpacket);
-
-               if (len > 0) {
-                       gs_debug_level(3, "gs_send: len=%d, 0x%2.2x "
-                                       "0x%2.2x 0x%2.2x ...\n", len,
-                                       *((unsigned char *)req->buf),
-                                       *((unsigned char *)req->buf+1),
-                                       *((unsigned char *)req->buf+2));
-                       list_del(&req->list);
-                       req->length = len;
-                       spin_unlock_irqrestore(&dev->dev_lock, flags);
-                       if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
-                               pr_err(
-                               "gs_send: cannot queue read request, ret=%d\n",
-                                       ret);
-                               spin_lock_irqsave(&dev->dev_lock, flags);
-                               break;
-                       }
-                       spin_lock_irqsave(&dev->dev_lock, flags);
-               } else {
-                       break;
-               }
-
-       }
-
-       spin_unlock_irqrestore(&dev->dev_lock, flags);
-
-       return 0;
-}
-
-/*
- * gs_send_packet
- *
- * If there is data to send, a packet is built in the given
- * buffer and the size is returned.  If there is no data to
- * send, 0 is returned.  If there is any error a negative
- * error number is returned.
- *
- * Called during USB completion routine, on interrupt time.
- *
- * We assume that disconnect will not happen until all completion
- * routines have completed, so we can assume that the dev_port
- * array does not change during the lifetime of this function.
- */
-static int gs_send_packet(struct gs_dev *dev, char *packet, unsigned int size)
-{
-       unsigned int len;
-       struct gs_port *port;
-
-       /* TEMPORARY -- only port 0 is supported right now */
-       port = dev->dev_port[0];
-
-       if (port == NULL) {
-               pr_err("gs_send_packet: port=%d, NULL port pointer\n", 0);
-               return -EIO;
-       }
-
-       spin_lock(&port->port_lock);
-
-       len = gs_buf_data_avail(port->port_write_buf);
-       if (len < size)
-               size = len;
-
-       if (size == 0)
-               goto exit;
-
-       size = gs_buf_get(port->port_write_buf, packet, size);
-
-       if (port->port_tty)
-               wake_up_interruptible(&port->port_tty->write_wait);
-
-exit:
-       spin_unlock(&port->port_lock);
-       return size;
-}
-
-/*
- * gs_recv_packet
- *
- * Called for each USB packet received.  Reads the packet
- * header and stuffs the data in the appropriate tty buffer.
- * Returns 0 if successful, or a negative error number.
- *
- * Called during USB completion routine, on interrupt time.
- *
- * We assume that disconnect will not happen until all completion
- * routines have completed, so we can assume that the dev_port
- * array does not change during the lifetime of this function.
- */
-static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size)
-{
-       unsigned int len;
-       struct gs_port *port;
-       int ret;
-       struct tty_struct *tty;
-
-       /* TEMPORARY -- only port 0 is supported right now */
-       port = dev->dev_port[0];
-
-       if (port == NULL) {
-               pr_err("gs_recv_packet: port=%d, NULL port pointer\n",
-                       port->port_num);
-               return -EIO;
-       }
-
-       spin_lock(&port->port_lock);
-
-       if (port->port_open_count == 0) {
-               pr_err("gs_recv_packet: port=%d, port is closed\n",
-                       port->port_num);
-               ret = -EIO;
-               goto exit;
-       }
-
-
-       tty = port->port_tty;
-
-       if (tty == NULL) {
-               pr_err("gs_recv_packet: port=%d, NULL tty pointer\n",
-                       port->port_num);
-               ret = -EIO;
-               goto exit;
-       }
-
-       if (port->port_tty->magic != TTY_MAGIC) {
-               pr_err("gs_recv_packet: port=%d, bad tty magic\n",
-                       port->port_num);
-               ret = -EIO;
-               goto exit;
-       }
-
-       len = tty_buffer_request_room(tty, size);
-       if (len > 0) {
-               tty_insert_flip_string(tty, packet, len);
-               tty_flip_buffer_push(port->port_tty);
-               wake_up_interruptible(&port->port_tty->read_wait);
-       }
-       ret = 0;
-exit:
-       spin_unlock(&port->port_lock);
-       return ret;
-}
-
-/*
-* gs_read_complete
-*/
-static void gs_read_complete(struct usb_ep *ep, struct usb_request *req)
-{
-       int ret;
-       struct gs_dev *dev = ep->driver_data;
-
-       if (dev == NULL) {
-               pr_err("gs_read_complete: NULL device pointer\n");
-               return;
-       }
-
-       switch(req->status) {
-       case 0:
-               /* normal completion */
-               gs_recv_packet(dev, req->buf, req->actual);
-requeue:
-               req->length = ep->maxpacket;
-               if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
-                       pr_err(
-                       "gs_read_complete: cannot queue read request, ret=%d\n",
-                               ret);
-               }
-               break;
-
-       case -ESHUTDOWN:
-               /* disconnect */
-               gs_debug("gs_read_complete: shutdown\n");
-               gs_free_req(ep, req);
-               break;
-
-       default:
-               /* unexpected */
-               pr_err(
-               "gs_read_complete: unexpected status error, status=%d\n",
-                       req->status);
-               goto requeue;
-               break;
-       }
-}
-
-/*
-* gs_write_complete
-*/
-static void gs_write_complete(struct usb_ep *ep, struct usb_request *req)
-{
-       struct gs_dev *dev = ep->driver_data;
-
-       if (dev == NULL) {
-               pr_err("gs_write_complete: NULL device pointer\n");
-               return;
-       }
-
-       switch(req->status) {
-       case 0:
-               /* normal completion */
-requeue:
-               spin_lock(&dev->dev_lock);
-               list_add(&req->list, &dev->dev_req_list);
-               spin_unlock(&dev->dev_lock);
-
-               gs_send(dev);
-
-               break;
-
-       case -ESHUTDOWN:
-               /* disconnect */
-               gs_debug("gs_write_complete: shutdown\n");
-               gs_free_req(ep, req);
-               break;
-
-       default:
-               pr_err(
-               "gs_write_complete: unexpected status error, status=%d\n",
-                       req->status);
-               goto requeue;
-               break;
-       }
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* Gadget Driver */
-
-/*
- * gs_unbind
- *
- * Called on module unload.  Frees the control request and device
- * structure.
- */
-static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget)
-{
-       struct gs_dev *dev = get_gadget_data(gadget);
-
-       gs_device = NULL;
-
-       /* read/write requests already freed, only control request remains */
-       if (dev != NULL) {
-               if (dev->dev_ctrl_req != NULL) {
-                       gs_free_req(gadget->ep0, dev->dev_ctrl_req);
-                       dev->dev_ctrl_req = NULL;
-               }
-               gs_reset_config(dev);
-               gs_free_ports(dev);
-               kfree(dev);
-               set_gadget_data(gadget, NULL);
-       }
-
-       pr_info("gs_unbind: %s %s unbound\n", GS_LONG_NAME,
-               GS_VERSION_STR);
-}
-
-/*
- * gs_bind
- *
- * Called on module load.  Allocates and initializes the device
- * structure and a control request.
- */
-static int __init gs_bind(struct usb_gadget *gadget)
-{
-       int ret;
-       struct usb_ep *ep;
-       struct gs_dev *dev;
-       int gcnum;
-
-       /* Some controllers can't support CDC ACM:
-        * - sh doesn't support multiple interfaces or configs;
-        * - sa1100 doesn't have a third interrupt endpoint
-        */
-       if (gadget_is_sh(gadget) || gadget_is_sa1100(gadget))
-               use_acm = 0;
-
-       gcnum = usb_gadget_controller_number(gadget);
-       if (gcnum >= 0)
-               gs_device_desc.bcdDevice =
-                               cpu_to_le16(GS_VERSION_NUM | gcnum);
-       else {
-               pr_warning("gs_bind: controller '%s' not recognized\n",
-                       gadget->name);
-               /* unrecognized, but safe unless bulk is REALLY quirky */
-               gs_device_desc.bcdDevice =
-                       __constant_cpu_to_le16(GS_VERSION_NUM|0x0099);
-       }
-
-       dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL);
-       if (dev == NULL)
-               return -ENOMEM;
-
-       usb_ep_autoconfig_reset(gadget);
-
-       ep = usb_ep_autoconfig(gadget, &gs_fullspeed_in_desc);
-       if (!ep)
-               goto autoconf_fail;
-       dev->dev_in_ep = ep;
-       ep->driver_data = dev;  /* claim the endpoint */
-
-       ep = usb_ep_autoconfig(gadget, &gs_fullspeed_out_desc);
-       if (!ep)
-               goto autoconf_fail;
-       dev->dev_out_ep = ep;
-       ep->driver_data = dev;  /* claim the endpoint */
-
-       if (use_acm) {
-               ep = usb_ep_autoconfig(gadget, &gs_fullspeed_notify_desc);
-               if (!ep) {
-                       pr_err("gs_bind: cannot run ACM on %s\n", gadget->name);
-                       goto autoconf_fail;
-               }
-               gs_device_desc.idProduct = __constant_cpu_to_le16(
-                                               GS_CDC_PRODUCT_ID),
-               dev->dev_notify_ep = ep;
-               ep->driver_data = dev;  /* claim the endpoint */
-       }
-
-       gs_device_desc.bDeviceClass = use_acm
-               ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC;
-       gs_device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
-
-       if (gadget_is_dualspeed(gadget)) {
-               gs_qualifier_desc.bDeviceClass = use_acm
-                       ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC;
-               /* assume ep0 uses the same packet size for both speeds */
-               gs_qualifier_desc.bMaxPacketSize0 =
-                       gs_device_desc.bMaxPacketSize0;
-               /* assume endpoints are dual-speed */
-               gs_highspeed_notify_desc.bEndpointAddress =
-                       gs_fullspeed_notify_desc.bEndpointAddress;
-               gs_highspeed_in_desc.bEndpointAddress =
-                       gs_fullspeed_in_desc.bEndpointAddress;
-               gs_highspeed_out_desc.bEndpointAddress =
-                       gs_fullspeed_out_desc.bEndpointAddress;
-       }
-
-       usb_gadget_set_selfpowered(gadget);
-
-       if (gadget_is_otg(gadget)) {
-               gs_otg_descriptor.bmAttributes |= USB_OTG_HNP,
-               gs_bulk_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
-               gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
-       }
-
-       gs_device = dev;
-
-       snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
-               init_utsname()->sysname, init_utsname()->release,
-               gadget->name);
-
-       dev->dev_gadget = gadget;
-       spin_lock_init(&dev->dev_lock);
-       INIT_LIST_HEAD(&dev->dev_req_list);
-       set_gadget_data(gadget, dev);
-
-       if ((ret=gs_alloc_ports(dev, GFP_KERNEL)) != 0) {
-               pr_err("gs_bind: cannot allocate ports\n");
-               gs_unbind(gadget);
-               return ret;
-       }
-
-       /* preallocate control response and buffer */
-       dev->dev_ctrl_req = gs_alloc_req(gadget->ep0, GS_MAX_DESC_LEN,
-               GFP_KERNEL);
-       if (dev->dev_ctrl_req == NULL) {
-               gs_unbind(gadget);
-               return -ENOMEM;
-       }
-       gadget->ep0->driver_data = dev;
-
-       pr_info("gs_bind: %s %s bound\n",
-               GS_LONG_NAME, GS_VERSION_STR);
-
-       return 0;
-
-autoconf_fail:
-       kfree(dev);
-       pr_err("gs_bind: cannot autoconfigure on %s\n", gadget->name);
-       return -ENODEV;
-}
-
-static int gs_setup_standard(struct usb_gadget *gadget,
-       const struct usb_ctrlrequest *ctrl)
-{
-       int ret = -EOPNOTSUPP;
-       struct gs_dev *dev = get_gadget_data(gadget);
-       struct usb_request *req = dev->dev_ctrl_req;
-       u16 wIndex = le16_to_cpu(ctrl->wIndex);
-       u16 wValue = le16_to_cpu(ctrl->wValue);
-       u16 wLength = le16_to_cpu(ctrl->wLength);
-
-       switch (ctrl->bRequest) {
-       case USB_REQ_GET_DESCRIPTOR:
-               if (ctrl->bRequestType != USB_DIR_IN)
-                       break;
-
-               switch (wValue >> 8) {
-               case USB_DT_DEVICE:
-                       ret = min(wLength,
-                               (u16)sizeof(struct usb_device_descriptor));
-                       memcpy(req->buf, &gs_device_desc, ret);
-                       break;
-
-               case USB_DT_DEVICE_QUALIFIER:
-                       if (!gadget_is_dualspeed(gadget))
-                               break;
-                       ret = min(wLength,
-                               (u16)sizeof(struct usb_qualifier_descriptor));
-                       memcpy(req->buf, &gs_qualifier_desc, ret);
-                       break;
-
-               case USB_DT_OTHER_SPEED_CONFIG:
-                       if (!gadget_is_dualspeed(gadget))
-                               break;
-                       /* fall through */
-               case USB_DT_CONFIG:
-                       ret = gs_build_config_buf(req->buf, gadget,
-                               wValue >> 8, wValue & 0xff,
-                               gadget_is_otg(gadget));
-                       if (ret >= 0)
-                               ret = min(wLength, (u16)ret);
-                       break;
-
-               case USB_DT_STRING:
-                       /* wIndex == language code. */
-                       ret = usb_gadget_get_string(&gs_string_table,
-                               wValue & 0xff, req->buf);
-                       if (ret >= 0)
-                               ret = min(wLength, (u16)ret);
-                       break;
-               }
-               break;
-
-       case USB_REQ_SET_CONFIGURATION:
-               if (ctrl->bRequestType != 0)
-                       break;
-               spin_lock(&dev->dev_lock);
-               ret = gs_set_config(dev, wValue);
-               spin_unlock(&dev->dev_lock);
-               break;
-
-       case USB_REQ_GET_CONFIGURATION:
-               if (ctrl->bRequestType != USB_DIR_IN)
-                       break;
-               *(u8 *)req->buf = dev->dev_config;
-               ret = min(wLength, (u16)1);
-               break;
-
-       case USB_REQ_SET_INTERFACE:
-               if (ctrl->bRequestType != USB_RECIP_INTERFACE
-                               || !dev->dev_config
-                               || wIndex >= GS_MAX_NUM_INTERFACES)
-                       break;
-               if (dev->dev_config == GS_BULK_CONFIG_ID
-                               && wIndex != GS_BULK_INTERFACE_ID)
-                       break;
-               /* no alternate interface settings */
-               if (wValue != 0)
-                       break;
-               spin_lock(&dev->dev_lock);
-               /* PXA hardware partially handles SET_INTERFACE;
-                * we need to kluge around that interference.  */
-               if (gadget_is_pxa(gadget)) {
-                       ret = gs_set_config(dev, use_acm ?
-                               GS_ACM_CONFIG_ID : GS_BULK_CONFIG_ID);
-                       goto set_interface_done;
-               }
-               if (dev->dev_config != GS_BULK_CONFIG_ID
-                               && wIndex == GS_CONTROL_INTERFACE_ID) {
-                       if (dev->dev_notify_ep) {
-                               usb_ep_disable(dev->dev_notify_ep);
-                               usb_ep_enable(dev->dev_notify_ep, dev->dev_notify_ep_desc);
-                       }
-               } else {
-                       usb_ep_disable(dev->dev_in_ep);
-                       usb_ep_disable(dev->dev_out_ep);
-                       usb_ep_enable(dev->dev_in_ep, dev->dev_in_ep_desc);
-                       usb_ep_enable(dev->dev_out_ep, dev->dev_out_ep_desc);
-               }
-               ret = 0;
-set_interface_done:
-               spin_unlock(&dev->dev_lock);
-               break;
-
-       case USB_REQ_GET_INTERFACE:
-               if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)
-               || dev->dev_config == GS_NO_CONFIG_ID)
-                       break;
-               if (wIndex >= GS_MAX_NUM_INTERFACES
-                               || (dev->dev_config == GS_BULK_CONFIG_ID
-                               && wIndex != GS_BULK_INTERFACE_ID)) {
-                       ret = -EDOM;
-                       break;
-               }
-               /* no alternate interface settings */
-               *(u8 *)req->buf = 0;
-               ret = min(wLength, (u16)1);
-               break;
-
-       default:
-               pr_err("gs_setup: unknown standard request, type=%02x, "
-                       "request=%02x, value=%04x, index=%04x, length=%d\n",
-                       ctrl->bRequestType, ctrl->bRequest,
-                       wValue, wIndex, wLength);
-               break;
-       }
-
-       return ret;
-}
-
-static void gs_setup_complete_set_line_coding(struct usb_ep *ep,
-               struct usb_request *req)
-{
-       struct gs_dev *dev = ep->driver_data;
-       struct gs_port *port = dev->dev_port[0]; /* ACM only has one port */
-
-       switch (req->status) {
-       case 0:
-               /* normal completion */
-               if (req->actual != sizeof(port->port_line_coding))
-                       usb_ep_set_halt(ep);
-               else if (port) {
-                       struct usb_cdc_line_coding      *value = req->buf;
-
-                       /* REVISIT:  we currently just remember this data.
-                        * If we change that, (a) validate it first, then
-                        * (b) update whatever hardware needs updating.
-                        */
-                       spin_lock(&port->port_lock);
-                       port->port_line_coding = *value;
-                       spin_unlock(&port->port_lock);
-               }
-               break;
-
-       case -ESHUTDOWN:
-               /* disconnect */
-               gs_free_req(ep, req);
-               break;
-
-       default:
-               /* unexpected */
-               break;
-       }
-       return;
-}
-
-static int gs_setup_class(struct usb_gadget *gadget,
-       const struct usb_ctrlrequest *ctrl)
-{
-       int ret = -EOPNOTSUPP;
-       struct gs_dev *dev = get_gadget_data(gadget);
-       struct gs_port *port = dev->dev_port[0];        /* ACM only has one port */
-       struct usb_request *req = dev->dev_ctrl_req;
-       u16 wIndex = le16_to_cpu(ctrl->wIndex);
-       u16 wValue = le16_to_cpu(ctrl->wValue);
-       u16 wLength = le16_to_cpu(ctrl->wLength);
-
-       switch (ctrl->bRequest) {
-       case USB_CDC_REQ_SET_LINE_CODING:
-               if (wLength != sizeof(struct usb_cdc_line_coding))
-                       break;
-               ret = wLength;
-               req->complete = gs_setup_complete_set_line_coding;
-               break;
-
-       case USB_CDC_REQ_GET_LINE_CODING:
-               ret = min_t(int, wLength, sizeof(struct usb_cdc_line_coding));
-               if (port) {
-                       spin_lock(&port->port_lock);
-                       memcpy(req->buf, &port->port_line_coding, ret);
-                       spin_unlock(&port->port_lock);
-               }
-               break;
-
-       case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
-               if (wLength != 0)
-                       break;
-               ret = 0;
-               if (port) {
-                       /* REVISIT:  we currently just remember this data.
-                        * If we change that, update whatever hardware needs
-                        * updating.
-                        */
-                       spin_lock(&port->port_lock);
-                       port->port_handshake_bits = wValue;
-                       spin_unlock(&port->port_lock);
-               }
-               break;
-
-       default:
-               /* NOTE:  strictly speaking, we should accept AT-commands
-                * using SEND_ENCPSULATED_COMMAND/GET_ENCAPSULATED_RESPONSE.
-                * But our call management descriptor says we don't handle
-                * call management, so we should be able to get by without
-                * handling those "required" commands (except by stalling).
-                */
-               pr_err("gs_setup: unknown class request, "
-                               "type=%02x, request=%02x, value=%04x, "
-                               "index=%04x, length=%d\n",
-                       ctrl->bRequestType, ctrl->bRequest,
-                       wValue, wIndex, wLength);
-               break;
-       }
-
-       return ret;
-}
-
-/*
- * gs_setup_complete
- */
-static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req)
-{
-       if (req->status || req->actual != req->length) {
-               pr_err("gs_setup_complete: status error, status=%d, "
-                       "actual=%d, length=%d\n",
-                       req->status, req->actual, req->length);
-       }
-}
-
-/*
- * gs_setup
- *
- * Implements all the control endpoint functionality that's not
- * handled in hardware or the hardware driver.
- *
- * Returns the size of the data sent to the host, or a negative
- * error number.
- */
-static int gs_setup(struct usb_gadget *gadget,
-       const struct usb_ctrlrequest *ctrl)
-{
-       int             ret = -EOPNOTSUPP;
-       struct gs_dev   *dev = get_gadget_data(gadget);
-       struct usb_request *req = dev->dev_ctrl_req;
-       u16             wIndex = le16_to_cpu(ctrl->wIndex);
-       u16             wValue = le16_to_cpu(ctrl->wValue);
-       u16             wLength = le16_to_cpu(ctrl->wLength);
-
-       req->complete = gs_setup_complete;
-
-       switch (ctrl->bRequestType & USB_TYPE_MASK) {
-       case USB_TYPE_STANDARD:
-               ret = gs_setup_standard(gadget, ctrl);
-               break;
-
-       case USB_TYPE_CLASS:
-               ret = gs_setup_class(gadget, ctrl);
-               break;
-
-       default:
-               pr_err("gs_setup: unknown request, type=%02x, request=%02x, "
-                       "value=%04x, index=%04x, length=%d\n",
-                       ctrl->bRequestType, ctrl->bRequest,
-                       wValue, wIndex, wLength);
-               break;
-       }
-
-       /* respond with data transfer before status phase? */
-       if (ret >= 0) {
-               req->length = ret;
-               req->zero = ret < wLength
-                               && (ret % gadget->ep0->maxpacket) == 0;
-               ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
-               if (ret < 0) {
-                       pr_err("gs_setup: cannot queue response, ret=%d\n",
-                               ret);
-                       req->status = 0;
-                       gs_setup_complete(gadget->ep0, req);
-               }
-       }
-
-       /* device either stalls (ret < 0) or reports success */
-       return ret;
-}
-
-/*
- * gs_disconnect
- *
- * Called when the device is disconnected.  Frees the closed
- * ports and disconnects open ports.  Open ports will be freed
- * on close.  Then reallocates the ports for the next connection.
- */
-static void gs_disconnect(struct usb_gadget *gadget)
-{
-       unsigned long flags;
-       struct gs_dev *dev = get_gadget_data(gadget);
-
-       spin_lock_irqsave(&dev->dev_lock, flags);
-
-       gs_reset_config(dev);
-
-       /* free closed ports and disconnect open ports */
-       /* (open ports will be freed when closed) */
-       gs_free_ports(dev);
-
-       /* re-allocate ports for the next connection */
-       if (gs_alloc_ports(dev, GFP_ATOMIC) != 0)
-               pr_err("gs_disconnect: cannot re-allocate ports\n");
-
-       spin_unlock_irqrestore(&dev->dev_lock, flags);
-
-       pr_info("gs_disconnect: %s disconnected\n", GS_LONG_NAME);
-}
-
-static struct usb_gadget_driver gs_gadget_driver = {
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-       .speed =                USB_SPEED_HIGH,
-#else
-       .speed =                USB_SPEED_FULL,
-#endif /* CONFIG_USB_GADGET_DUALSPEED */
-       .function =             GS_LONG_NAME,
-       .bind =                 gs_bind,
-       .unbind =               gs_unbind,
-       .setup =                gs_setup,
-       .disconnect =           gs_disconnect,
-       .driver = {
-               .name =         GS_SHORT_NAME,
-               .owner =        THIS_MODULE,
-       },
-};
-
-/*
- * gs_set_config
- *
- * Configures the device by enabling device specific
- * optimizations, setting up the endpoints, allocating
- * read and write requests and queuing read requests.
- *
- * The device lock must be held when calling this function.
- */
-static int gs_set_config(struct gs_dev *dev, unsigned config)
-{
-       int i;
-       int ret = 0;
-       struct usb_gadget *gadget = dev->dev_gadget;
-       struct usb_ep *ep;
-       struct usb_endpoint_descriptor *out, *in, *notify;
-       struct usb_request *req;
-
-       if (dev == NULL) {
-               pr_err("gs_set_config: NULL device pointer\n");
-               return 0;
-       }
-
-       if (config == dev->dev_config)
-               return 0;
-
-       gs_reset_config(dev);
-
-       switch (config) {
-       case GS_NO_CONFIG_ID:
-               return 0;
-       case GS_BULK_CONFIG_ID:
-               if (use_acm)
-                       return -EINVAL;
-               break;
-       case GS_ACM_CONFIG_ID:
-               if (!use_acm)
-                       return -EINVAL;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       in = choose_ep_desc(gadget,
-                       &gs_highspeed_in_desc,
-                       &gs_fullspeed_in_desc);
-       out = choose_ep_desc(gadget,
-                       &gs_highspeed_out_desc,
-                       &gs_fullspeed_out_desc);
-       notify = dev->dev_notify_ep
-               ? choose_ep_desc(gadget,
-                               &gs_highspeed_notify_desc,
-                               &gs_fullspeed_notify_desc)
-               : NULL;
-
-       ret = usb_ep_enable(dev->dev_in_ep, in);
-       if (ret == 0) {
-               dev->dev_in_ep_desc = in;
-       } else {
-               pr_debug("%s: cannot enable %s %s, ret=%d\n",
-                       __func__, "IN", dev->dev_in_ep->name, ret);
-               return ret;
-       }
-
-       ret = usb_ep_enable(dev->dev_out_ep, out);
-       if (ret == 0) {
-               dev->dev_out_ep_desc = out;
-       } else {
-               pr_debug("%s: cannot enable %s %s, ret=%d\n",
-                       __func__, "OUT", dev->dev_out_ep->name, ret);
-fail0:
-               usb_ep_disable(dev->dev_in_ep);
-               return ret;
-       }
-
-       if (notify) {
-               ret = usb_ep_enable(dev->dev_notify_ep, notify);
-               if (ret == 0) {
-                       dev->dev_notify_ep_desc = notify;
-               } else {
-                       pr_debug("%s: cannot enable %s %s, ret=%d\n",
-                               __func__, "NOTIFY",
-                               dev->dev_notify_ep->name, ret);
-                       usb_ep_disable(dev->dev_out_ep);
-                       goto fail0;
-               }
-       }
-
-       dev->dev_config = config;
-
-       /* allocate and queue read requests */
-       ep = dev->dev_out_ep;
-       for (i=0; i<read_q_size && ret == 0; i++) {
-               if ((req=gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC))) {
-                       req->complete = gs_read_complete;
-                       if ((ret=usb_ep_queue(ep, req, GFP_ATOMIC))) {
-                               pr_err("gs_set_config: cannot queue read "
-                                       "request, ret=%d\n", ret);
-                       }
-               } else {
-                       pr_err("gs_set_config: cannot allocate "
-                                       "read requests\n");
-                       ret = -ENOMEM;
-                       goto exit_reset_config;
-               }
-       }
-
-       /* allocate write requests, and put on free list */
-       ep = dev->dev_in_ep;
-       for (i=0; i<write_q_size; i++) {
-               req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC);
-               if (req) {
-                       req->complete = gs_write_complete;
-                       list_add(&req->list, &dev->dev_req_list);
-               } else {
-                       pr_err("gs_set_config: cannot allocate "
-                                       "write requests\n");
-                       ret = -ENOMEM;
-                       goto exit_reset_config;
-               }
-       }
-
-       /* REVISIT the ACM mode should be able to actually *issue* some
-        * notifications, for at least serial state change events if
-        * not also for network connection; say so in bmCapabilities.
-        */
-
-       pr_info("gs_set_config: %s configured, %s speed %s config\n",
-               GS_LONG_NAME,
-               gadget->speed == USB_SPEED_HIGH ? "high" : "full",
-               config == GS_BULK_CONFIG_ID ? "BULK" : "CDC-ACM");
-
-       return 0;
-
-exit_reset_config:
-       gs_reset_config(dev);
-       return ret;
-}
-
-/*
- * gs_reset_config
- *
- * Mark the device as not configured, disable all endpoints,
- * which forces completion of pending I/O and frees queued
- * requests, and free the remaining write requests on the
- * free list.
- *
- * The device lock must be held when calling this function.
- */
-static void gs_reset_config(struct gs_dev *dev)
-{
-       struct usb_request *req;
-
-       if (dev == NULL) {
-               pr_err("gs_reset_config: NULL device pointer\n");
-               return;
-       }
-
-       if (dev->dev_config == GS_NO_CONFIG_ID)
-               return;
-
-       dev->dev_config = GS_NO_CONFIG_ID;
-
-       /* free write requests on the free list */
-       while(!list_empty(&dev->dev_req_list)) {
-               req = list_entry(dev->dev_req_list.next,
-                               struct usb_request, list);
-               list_del(&req->list);
-               gs_free_req(dev->dev_in_ep, req);
-       }
-
-       /* disable endpoints, forcing completion of pending i/o; */
-       /* completion handlers free their requests in this case */
-       if (dev->dev_notify_ep)
-               usb_ep_disable(dev->dev_notify_ep);
-       usb_ep_disable(dev->dev_in_ep);
-       usb_ep_disable(dev->dev_out_ep);
-}
-
-/*
- * gs_build_config_buf
- *
- * Builds the config descriptors in the given buffer and returns the
- * length, or a negative error number.
- */
-static int gs_build_config_buf(u8 *buf, struct usb_gadget *g,
-       u8 type, unsigned int index, int is_otg)
-{
-       int len;
-       int high_speed = 0;
-       const struct usb_config_descriptor *config_desc;
-       const struct usb_descriptor_header **function;
-
-       if (index >= gs_device_desc.bNumConfigurations)
-               return -EINVAL;
-
-       /* other speed switches high and full speed */
-       if (gadget_is_dualspeed(g)) {
-               high_speed = (g->speed == USB_SPEED_HIGH);
-               if (type == USB_DT_OTHER_SPEED_CONFIG)
-                       high_speed = !high_speed;
-       }
-
-       if (use_acm) {
-               config_desc = &gs_acm_config_desc;
-               function = high_speed
-                       ? gs_acm_highspeed_function
-                       : gs_acm_fullspeed_function;
-       } else {
-               config_desc = &gs_bulk_config_desc;
-               function = high_speed
-                       ? gs_bulk_highspeed_function
-                       : gs_bulk_fullspeed_function;
-       }
-
-       /* for now, don't advertise srp-only devices */
-       if (!is_otg)
-               function++;
-
-       len = usb_gadget_config_buf(config_desc, buf, GS_MAX_DESC_LEN, function);
-       if (len < 0)
-               return len;
-
-       ((struct usb_config_descriptor *)buf)->bDescriptorType = type;
-
-       return len;
-}
-
-/*
- * gs_alloc_req
- *
- * Allocate a usb_request and its buffer.  Returns a pointer to the
- * usb_request or NULL if there is an error.
- */
-static struct usb_request *
-gs_alloc_req(struct usb_ep *ep, unsigned int len, gfp_t kmalloc_flags)
-{
-       struct usb_request *req;
-
-       if (ep == NULL)
-               return NULL;
-
-       req = usb_ep_alloc_request(ep, kmalloc_flags);
-
-       if (req != NULL) {
-               req->length = len;
-               req->buf = kmalloc(len, kmalloc_flags);
-               if (req->buf == NULL) {
-                       usb_ep_free_request(ep, req);
-                       return NULL;
-               }
-       }
-
-       return req;
-}
-
-/*
- * gs_free_req
- *
- * Free a usb_request and its buffer.
- */
-static void gs_free_req(struct usb_ep *ep, struct usb_request *req)
-{
-       if (ep != NULL && req != NULL) {
-               kfree(req->buf);
-               usb_ep_free_request(ep, req);
-       }
-}
-
-/*
- * gs_alloc_ports
- *
- * Allocate all ports and set the gs_dev struct to point to them.
- * Return 0 if successful, or a negative error number.
- *
- * The device lock is normally held when calling this function.
- */
-static int gs_alloc_ports(struct gs_dev *dev, gfp_t kmalloc_flags)
-{
-       int i;
-       struct gs_port *port;
-
-       if (dev == NULL)
-               return -EIO;
-
-       for (i=0; i<GS_NUM_PORTS; i++) {
-               if ((port=kzalloc(sizeof(struct gs_port), kmalloc_flags)) == NULL)
-                       return -ENOMEM;
-
-               port->port_dev = dev;
-               port->port_num = i;
-               port->port_line_coding.dwDTERate = cpu_to_le32(GS_DEFAULT_DTE_RATE);
-               port->port_line_coding.bCharFormat = GS_DEFAULT_CHAR_FORMAT;
-               port->port_line_coding.bParityType = GS_DEFAULT_PARITY;
-               port->port_line_coding.bDataBits = GS_DEFAULT_DATA_BITS;
-               spin_lock_init(&port->port_lock);
-               init_waitqueue_head(&port->port_write_wait);
-
-               dev->dev_port[i] = port;
-       }
-
-       return 0;
-}
-
-/*
- * gs_free_ports
- *
- * Free all closed ports.  Open ports are disconnected by
- * freeing their write buffers, setting their device pointers
- * and the pointers to them in the device to NULL.  These
- * ports will be freed when closed.
- *
- * The device lock is normally held when calling this function.
- */
-static void gs_free_ports(struct gs_dev *dev)
-{
-       int i;
-       unsigned long flags;
-       struct gs_port *port;
-
-       if (dev == NULL)
-               return;
-
-       for (i=0; i<GS_NUM_PORTS; i++) {
-               if ((port=dev->dev_port[i]) != NULL) {
-                       dev->dev_port[i] = NULL;
-
-                       spin_lock_irqsave(&port->port_lock, flags);
-
-                       if (port->port_write_buf != NULL) {
-                               gs_buf_free(port->port_write_buf);
-                               port->port_write_buf = NULL;
-                       }
-
-                       if (port->port_open_count > 0 || port->port_in_use) {
-                               port->port_dev = NULL;
-                               wake_up_interruptible(&port->port_write_wait);
-                               if (port->port_tty) {
-                                       tty_hangup(port->port_tty);
-                               }
-                               spin_unlock_irqrestore(&port->port_lock, flags);
-                       } else {
-                               spin_unlock_irqrestore(&port->port_lock, flags);
-                               kfree(port);
-                       }
-
-               }
-       }
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* Circular Buffer */
-
-/*
- * gs_buf_alloc
- *
- * Allocate a circular buffer and all associated memory.
- */
-static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags)
-{
-       struct gs_buf *gb;
-
-       if (size == 0)
-               return NULL;
-
-       gb = kmalloc(sizeof(struct gs_buf), kmalloc_flags);
-       if (gb == NULL)
-               return NULL;
-
-       gb->buf_buf = kmalloc(size, kmalloc_flags);
-       if (gb->buf_buf == NULL) {
-               kfree(gb);
-               return NULL;
-       }
-
-       gb->buf_size = size;
-       gb->buf_get = gb->buf_put = gb->buf_buf;
-
-       return gb;
-}
-
-/*
- * gs_buf_free
- *
- * Free the buffer and all associated memory.
- */
-static void gs_buf_free(struct gs_buf *gb)
-{
-       if (gb) {
-               kfree(gb->buf_buf);
-               kfree(gb);
-       }
-}
-
-/*
- * gs_buf_clear
- *
- * Clear out all data in the circular buffer.
- */
-static void gs_buf_clear(struct gs_buf *gb)
-{
-       if (gb != NULL)
-               gb->buf_get = gb->buf_put;
-               /* equivalent to a get of all data available */
-}
-
-/*
- * gs_buf_data_avail
- *
- * Return the number of bytes of data available in the circular
- * buffer.
- */
-static unsigned int gs_buf_data_avail(struct gs_buf *gb)
-{
-       if (gb != NULL)
-               return (gb->buf_size + gb->buf_put - gb->buf_get) % gb->buf_size;
-       else
-               return 0;
-}
-
-/*
- * gs_buf_space_avail
- *
- * Return the number of bytes of space available in the circular
- * buffer.
- */
-static unsigned int gs_buf_space_avail(struct gs_buf *gb)
-{
-       if (gb != NULL)
-               return (gb->buf_size + gb->buf_get - gb->buf_put - 1) % gb->buf_size;
-       else
-               return 0;
-}
-
-/*
- * gs_buf_put
- *
- * Copy data data from a user buffer and put it into the circular buffer.
- * Restrict to the amount of space available.
- *
- * Return the number of bytes copied.
- */
-static unsigned int
-gs_buf_put(struct gs_buf *gb, const char *buf, unsigned int count)
-{
-       unsigned int len;
-
-       if (gb == NULL)
-               return 0;
-
-       len  = gs_buf_space_avail(gb);
-       if (count > len)
-               count = len;
-
-       if (count == 0)
-               return 0;
-
-       len = gb->buf_buf + gb->buf_size - gb->buf_put;
-       if (count > len) {
-               memcpy(gb->buf_put, buf, len);
-               memcpy(gb->buf_buf, buf+len, count - len);
-               gb->buf_put = gb->buf_buf + count - len;
-       } else {
-               memcpy(gb->buf_put, buf, count);
-               if (count < len)
-                       gb->buf_put += count;
-               else /* count == len */
-                       gb->buf_put = gb->buf_buf;
-       }
-
-       return count;
-}
-
-/*
- * gs_buf_get
- *
- * Get data from the circular buffer and copy to the given buffer.
- * Restrict to the amount of data available.
- *
- * Return the number of bytes copied.
- */
-static unsigned int
-gs_buf_get(struct gs_buf *gb, char *buf, unsigned int count)
-{
-       unsigned int len;
-
-       if (gb == NULL)
-               return 0;
-
-       len = gs_buf_data_avail(gb);
-       if (count > len)
-               count = len;
-
-       if (count == 0)
-               return 0;
-
-       len = gb->buf_buf + gb->buf_size - gb->buf_get;
-       if (count > len) {
-               memcpy(buf, gb->buf_get, len);
-               memcpy(buf+len, gb->buf_buf, count - len);
-               gb->buf_get = gb->buf_buf + count - len;
-       } else {
-               memcpy(buf, gb->buf_get, count);
-               if (count < len)
-                       gb->buf_get += count;
-               else /* count == len */
-                       gb->buf_get = gb->buf_buf;
-       }
-
-       return count;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static struct tty_driver *gs_tty_driver;
-
-/*
- *  gs_module_init
- *
- *  Register as a USB gadget driver and a tty driver.
- */
-static int __init gs_module_init(void)
-{
-       int i;
-       int retval;
-
-       retval = usb_gadget_register_driver(&gs_gadget_driver);
-       if (retval) {
-               pr_err("gs_module_init: cannot register gadget driver, "
-                       "ret=%d\n", retval);
-               return retval;
-       }
-
-       gs_tty_driver = alloc_tty_driver(GS_NUM_PORTS);
-       if (!gs_tty_driver)
-               return -ENOMEM;
-       gs_tty_driver->owner = THIS_MODULE;
-       gs_tty_driver->driver_name = GS_SHORT_NAME;
-       gs_tty_driver->name = "ttygs";
-       gs_tty_driver->major = GS_MAJOR;
-       gs_tty_driver->minor_start = GS_MINOR_START;
-       gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
-       gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
-       gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
-       gs_tty_driver->init_termios = tty_std_termios;
-       /* must match GS_DEFAULT_DTE_RATE and friends */
-       gs_tty_driver->init_termios.c_cflag =
-               B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-       gs_tty_driver->init_termios.c_ispeed = GS_DEFAULT_DTE_RATE;
-       gs_tty_driver->init_termios.c_ospeed = GS_DEFAULT_DTE_RATE;
-       tty_set_operations(gs_tty_driver, &gs_tty_ops);
-
-       for (i = 0; i < GS_NUM_PORTS; i++)
-               mutex_init(&gs_open_close_lock[i]);
-
-       retval = tty_register_driver(gs_tty_driver);
-       if (retval) {
-               usb_gadget_unregister_driver(&gs_gadget_driver);
-               put_tty_driver(gs_tty_driver);
-               pr_err("gs_module_init: cannot register tty driver, "
-                               "ret=%d\n", retval);
-               return retval;
-       }
-
-       pr_info("gs_module_init: %s %s loaded\n",
-                       GS_LONG_NAME, GS_VERSION_STR);
-       return 0;
-}
-module_init(gs_module_init);
-
-/*
- * gs_module_exit
- *
- * Unregister as a tty driver and a USB gadget driver.
- */
-static void __exit gs_module_exit(void)
-{
-       tty_unregister_driver(gs_tty_driver);
-       put_tty_driver(gs_tty_driver);
-       usb_gadget_unregister_driver(&gs_gadget_driver);
-
-       pr_info("gs_module_exit: %s %s unloaded\n",
-                       GS_LONG_NAME, GS_VERSION_STR);
-}
-module_exit(gs_module_exit);
+module_exit(cleanup);
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
new file mode 100644 (file)
index 0000000..5458f43
--- /dev/null
@@ -0,0 +1,967 @@
+/*
+ * u_ether.c -- Ethernet-over-USB link layer utilities for Gadget stack
+ *
+ * Copyright (C) 2003-2005,2008 David Brownell
+ * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* #define VERBOSE_DEBUG */
+
+#include <linux/kernel.h>
+#include <linux/utsname.h>
+#include <linux/device.h>
+#include <linux/ctype.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+
+#include "u_ether.h"
+
+
+/*
+ * This component encapsulates the Ethernet link glue needed to provide
+ * one (!) network link through the USB gadget stack, normally "usb0".
+ *
+ * The control and data models are handled by the function driver which
+ * connects to this code; such as CDC Ethernet, "CDC Subset", or RNDIS.
+ * That includes all descriptor and endpoint management.
+ *
+ * Link level addressing is handled by this component using module
+ * parameters; if no such parameters are provided, random link level
+ * addresses are used.  Each end of the link uses one address.  The
+ * host end address is exported in various ways, and is often recorded
+ * in configuration databases.
+ *
+ * The driver which assembles each configuration using such a link is
+ * responsible for ensuring that each configuration includes at most one
+ * instance of is network link.  (The network layer provides ways for
+ * this single "physical" link to be used by multiple virtual links.)
+ */
+
+#define DRIVER_VERSION "29-May-2008"
+
+struct eth_dev {
+       /* lock is held while accessing port_usb
+        * or updating its backlink port_usb->ioport
+        */
+       spinlock_t              lock;
+       struct gether           *port_usb;
+
+       struct net_device       *net;
+       struct usb_gadget       *gadget;
+
+       spinlock_t              req_lock;       /* guard {rx,tx}_reqs */
+       struct list_head        tx_reqs, rx_reqs;
+       atomic_t                tx_qlen;
+
+       unsigned                header_len;
+       struct sk_buff          *(*wrap)(struct sk_buff *skb);
+       int                     (*unwrap)(struct sk_buff *skb);
+
+       struct work_struct      work;
+
+       unsigned long           todo;
+#define        WORK_RX_MEMORY          0
+
+       bool                    zlp;
+       u8                      host_mac[ETH_ALEN];
+};
+
+/*-------------------------------------------------------------------------*/
+
+#define RX_EXTRA       20      /* bytes guarding against rx overflows */
+
+#define DEFAULT_QLEN   2       /* double buffering by default */
+
+
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+
+static unsigned qmult = 5;
+module_param(qmult, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(qmult, "queue length multiplier at high speed");
+
+#else  /* full speed (low speed doesn't do bulk) */
+#define qmult          1
+#endif
+
+/* for dual-speed hardware, use deeper queues at highspeed */
+static inline int qlen(struct usb_gadget *gadget)
+{
+       if (gadget_is_dualspeed(gadget) && gadget->speed == USB_SPEED_HIGH)
+               return qmult * DEFAULT_QLEN;
+       else
+               return DEFAULT_QLEN;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* REVISIT there must be a better way than having two sets
+ * of debug calls ...
+ */
+
+#undef DBG
+#undef VDBG
+#undef ERROR
+#undef WARN
+#undef INFO
+
+#define xprintk(d, level, fmt, args...) \
+       printk(level "%s: " fmt , (d)->net->name , ## args)
+
+#ifdef DEBUG
+#undef DEBUG
+#define DBG(dev, fmt, args...) \
+       xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DBG(dev, fmt, args...) \
+       do { } while (0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE_DEBUG
+#define VDBG   DBG
+#else
+#define VDBG(dev, fmt, args...) \
+       do { } while (0)
+#endif /* DEBUG */
+
+#define ERROR(dev, fmt, args...) \
+       xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev, fmt, args...) \
+       xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev, fmt, args...) \
+       xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-------------------------------------------------------------------------*/
+
+/* NETWORK DRIVER HOOKUP (to the layer above this driver) */
+
+static int eth_change_mtu(struct net_device *net, int new_mtu)
+{
+       struct eth_dev  *dev = netdev_priv(net);
+       unsigned long   flags;
+       int             status = 0;
+
+       /* don't change MTU on "live" link (peer won't know) */
+       spin_lock_irqsave(&dev->lock, flags);
+       if (dev->port_usb)
+               status = -EBUSY;
+       else if (new_mtu <= ETH_HLEN || new_mtu > ETH_FRAME_LEN)
+               status = -ERANGE;
+       else
+               net->mtu = new_mtu;
+       spin_unlock_irqrestore(&dev->lock, flags);
+
+       return status;
+}
+
+static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p)
+{
+       struct eth_dev  *dev = netdev_priv(net);
+
+       strlcpy(p->driver, "g_ether", sizeof p->driver);
+       strlcpy(p->version, DRIVER_VERSION, sizeof p->version);
+       strlcpy(p->fw_version, dev->gadget->name, sizeof p->fw_version);
+       strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info);
+}
+
+static u32 eth_get_link(struct net_device *net)
+{
+       struct eth_dev  *dev = netdev_priv(net);
+       return dev->gadget->speed != USB_SPEED_UNKNOWN;
+}
+
+/* REVISIT can also support:
+ *   - WOL (by tracking suspends and issuing remote wakeup)
+ *   - msglevel (implies updated messaging)
+ *   - ... probably more ethtool ops
+ */
+
+static struct ethtool_ops ops = {
+       .get_drvinfo = eth_get_drvinfo,
+       .get_link = eth_get_link
+};
+
+static void defer_kevent(struct eth_dev *dev, int flag)
+{
+       if (test_and_set_bit(flag, &dev->todo))
+               return;
+       if (!schedule_work(&dev->work))
+               ERROR(dev, "kevent %d may have been dropped\n", flag);
+       else
+               DBG(dev, "kevent %d scheduled\n", flag);
+}
+
+static void rx_complete(struct usb_ep *ep, struct usb_request *req);
+
+static int
+rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
+{
+       struct sk_buff  *skb;
+       int             retval = -ENOMEM;
+       size_t          size = 0;
+       struct usb_ep   *out;
+       unsigned long   flags;
+
+       spin_lock_irqsave(&dev->lock, flags);
+       if (dev->port_usb)
+               out = dev->port_usb->out_ep;
+       else
+               out = NULL;
+       spin_unlock_irqrestore(&dev->lock, flags);
+
+       if (!out)
+               return -ENOTCONN;
+
+
+       /* Padding up to RX_EXTRA handles minor disagreements with host.
+        * Normally we use the USB "terminate on short read" convention;
+        * so allow up to (N*maxpacket), since that memory is normally
+        * already allocated.  Some hardware doesn't deal well with short
+        * reads (e.g. DMA must be N*maxpacket), so for now don't trim a
+        * byte off the end (to force hardware errors on overflow).
+        *
+        * RNDIS uses internal framing, and explicitly allows senders to
+        * pad to end-of-packet.  That's potentially nice for speed, but
+        * means receivers can't recover lost synch on their own (because
+        * new packets don't only start after a short RX).
+        */
+       size += sizeof(struct ethhdr) + dev->net->mtu + RX_EXTRA;
+       size += dev->port_usb->header_len;
+       size += out->maxpacket - 1;
+       size -= size % out->maxpacket;
+
+       skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags);
+       if (skb == NULL) {
+               DBG(dev, "no rx skb\n");
+               goto enomem;
+       }
+
+       /* Some platforms perform better when IP packets are aligned,
+        * but on at least one, checksumming fails otherwise.  Note:
+        * RNDIS headers involve variable numbers of LE32 values.
+        */
+       skb_reserve(skb, NET_IP_ALIGN);
+
+       req->buf = skb->data;
+       req->length = size;
+       req->complete = rx_complete;
+       req->context = skb;
+
+       retval = usb_ep_queue(out, req, gfp_flags);
+       if (retval == -ENOMEM)
+enomem:
+               defer_kevent(dev, WORK_RX_MEMORY);
+       if (retval) {
+               DBG(dev, "rx submit --> %d\n", retval);
+               if (skb)
+                       dev_kfree_skb_any(skb);
+               spin_lock_irqsave(&dev->req_lock, flags);
+               list_add(&req->list, &dev->rx_reqs);
+               spin_unlock_irqrestore(&dev->req_lock, flags);
+       }
+       return retval;
+}
+
+static void rx_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct sk_buff  *skb = req->context;
+       struct eth_dev  *dev = ep->driver_data;
+       int             status = req->status;
+
+       switch (status) {
+
+       /* normal completion */
+       case 0:
+               skb_put(skb, req->actual);
+               if (dev->unwrap)
+                       status = dev->unwrap(skb);
+               if (status < 0
+                               || ETH_HLEN > skb->len
+                               || skb->len > ETH_FRAME_LEN) {
+                       dev->net->stats.rx_errors++;
+                       dev->net->stats.rx_length_errors++;
+                       DBG(dev, "rx length %d\n", skb->len);
+                       break;
+               }
+
+               skb->protocol = eth_type_trans(skb, dev->net);
+               dev->net->stats.rx_packets++;
+               dev->net->stats.rx_bytes += skb->len;
+
+               /* no buffer copies needed, unless hardware can't
+                * use skb buffers.
+                */
+               status = netif_rx(skb);
+               skb = NULL;
+               break;
+
+       /* software-driven interface shutdown */
+       case -ECONNRESET:               /* unlink */
+       case -ESHUTDOWN:                /* disconnect etc */
+               VDBG(dev, "rx shutdown, code %d\n", status);
+               goto quiesce;
+
+       /* for hardware automagic (such as pxa) */
+       case -ECONNABORTED:             /* endpoint reset */
+               DBG(dev, "rx %s reset\n", ep->name);
+               defer_kevent(dev, WORK_RX_MEMORY);
+quiesce:
+               dev_kfree_skb_any(skb);
+               goto clean;
+
+       /* data overrun */
+       case -EOVERFLOW:
+               dev->net->stats.rx_over_errors++;
+               /* FALLTHROUGH */
+
+       default:
+               dev->net->stats.rx_errors++;
+               DBG(dev, "rx status %d\n", status);
+               break;
+       }
+
+       if (skb)
+               dev_kfree_skb_any(skb);
+       if (!netif_running(dev->net)) {
+clean:
+               spin_lock(&dev->req_lock);
+               list_add(&req->list, &dev->rx_reqs);
+               spin_unlock(&dev->req_lock);
+               req = NULL;
+       }
+       if (req)
+               rx_submit(dev, req, GFP_ATOMIC);
+}
+
+static int prealloc(struct list_head *list, struct usb_ep *ep, unsigned n)
+{
+       unsigned                i;
+       struct usb_request      *req;
+
+       if (!n)
+               return -ENOMEM;
+
+       /* queue/recycle up to N requests */
+       i = n;
+       list_for_each_entry(req, list, list) {
+               if (i-- == 0)
+                       goto extra;
+       }
+       while (i--) {
+               req = usb_ep_alloc_request(ep, GFP_ATOMIC);
+               if (!req)
+                       return list_empty(list) ? -ENOMEM : 0;
+               list_add(&req->list, list);
+       }
+       return 0;
+
+extra:
+       /* free extras */
+       for (;;) {
+               struct list_head        *next;
+
+               next = req->list.next;
+               list_del(&req->list);
+               usb_ep_free_request(ep, req);
+
+               if (next == list)
+                       break;
+
+               req = container_of(next, struct usb_request, list);
+       }
+       return 0;
+}
+
+static int alloc_requests(struct eth_dev *dev, struct gether *link, unsigned n)
+{
+       int     status;
+
+       spin_lock(&dev->req_lock);
+       status = prealloc(&dev->tx_reqs, link->in_ep, n);
+       if (status < 0)
+               goto fail;
+       status = prealloc(&dev->rx_reqs, link->out_ep, n);
+       if (status < 0)
+               goto fail;
+       goto done;
+fail:
+       DBG(dev, "can't alloc requests\n");
+done:
+       spin_unlock(&dev->req_lock);
+       return status;
+}
+
+static void rx_fill(struct eth_dev *dev, gfp_t gfp_flags)
+{
+       struct usb_request      *req;
+       unsigned long           flags;
+
+       /* fill unused rxq slots with some skb */
+       spin_lock_irqsave(&dev->req_lock, flags);
+       while (!list_empty(&dev->rx_reqs)) {
+               req = container_of(dev->rx_reqs.next,
+                               struct usb_request, list);
+               list_del_init(&req->list);
+               spin_unlock_irqrestore(&dev->req_lock, flags);
+
+               if (rx_submit(dev, req, gfp_flags) < 0) {
+                       defer_kevent(dev, WORK_RX_MEMORY);
+                       return;
+               }
+
+               spin_lock_irqsave(&dev->req_lock, flags);
+       }
+       spin_unlock_irqrestore(&dev->req_lock, flags);
+}
+
+static void eth_work(struct work_struct *work)
+{
+       struct eth_dev  *dev = container_of(work, struct eth_dev, work);
+
+       if (test_and_clear_bit(WORK_RX_MEMORY, &dev->todo)) {
+               if (netif_running(dev->net))
+                       rx_fill(dev, GFP_KERNEL);
+       }
+
+       if (dev->todo)
+               DBG(dev, "work done, flags = 0x%lx\n", dev->todo);
+}
+
+static void tx_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct sk_buff  *skb = req->context;
+       struct eth_dev  *dev = ep->driver_data;
+
+       switch (req->status) {
+       default:
+               dev->net->stats.tx_errors++;
+               VDBG(dev, "tx err %d\n", req->status);
+               /* FALLTHROUGH */
+       case -ECONNRESET:               /* unlink */
+       case -ESHUTDOWN:                /* disconnect etc */
+               break;
+       case 0:
+               dev->net->stats.tx_bytes += skb->len;
+       }
+       dev->net->stats.tx_packets++;
+
+       spin_lock(&dev->req_lock);
+       list_add(&req->list, &dev->tx_reqs);
+       spin_unlock(&dev->req_lock);
+       dev_kfree_skb_any(skb);
+
+       atomic_dec(&dev->tx_qlen);
+       if (netif_carrier_ok(dev->net))
+               netif_wake_queue(dev->net);
+}
+
+static inline int is_promisc(u16 cdc_filter)
+{
+       return cdc_filter & USB_CDC_PACKET_TYPE_PROMISCUOUS;
+}
+
+static int eth_start_xmit(struct sk_buff *skb, struct net_device *net)
+{
+       struct eth_dev          *dev = netdev_priv(net);
+       int                     length = skb->len;
+       int                     retval;
+       struct usb_request      *req = NULL;
+       unsigned long           flags;
+       struct usb_ep           *in;
+       u16                     cdc_filter;
+
+       spin_lock_irqsave(&dev->lock, flags);
+       if (dev->port_usb) {
+               in = dev->port_usb->in_ep;
+               cdc_filter = dev->port_usb->cdc_filter;
+       } else {
+               in = NULL;
+               cdc_filter = 0;
+       }
+       spin_unlock_irqrestore(&dev->lock, flags);
+
+       if (!in) {
+               dev_kfree_skb_any(skb);
+               return 0;
+       }
+
+       /* apply outgoing CDC or RNDIS filters */
+       if (!is_promisc(cdc_filter)) {
+               u8              *dest = skb->data;
+
+               if (is_multicast_ether_addr(dest)) {
+                       u16     type;
+
+                       /* ignores USB_CDC_PACKET_TYPE_MULTICAST and host
+                        * SET_ETHERNET_MULTICAST_FILTERS requests
+                        */
+                       if (is_broadcast_ether_addr(dest))
+                               type = USB_CDC_PACKET_TYPE_BROADCAST;
+                       else
+                               type = USB_CDC_PACKET_TYPE_ALL_MULTICAST;
+                       if (!(cdc_filter & type)) {
+                               dev_kfree_skb_any(skb);
+                               return 0;
+                       }
+               }
+               /* ignores USB_CDC_PACKET_TYPE_DIRECTED */
+       }
+
+       spin_lock_irqsave(&dev->req_lock, flags);
+       /*
+        * this freelist can be empty if an interrupt triggered disconnect()
+        * and reconfigured the gadget (shutting down this queue) after the
+        * network stack decided to xmit but before we got the spinlock.
+        */
+       if (list_empty(&dev->tx_reqs)) {
+               spin_unlock_irqrestore(&dev->req_lock, flags);
+               return 1;
+       }
+
+       req = container_of(dev->tx_reqs.next, struct usb_request, list);
+       list_del(&req->list);
+
+       /* temporarily stop TX queue when the freelist empties */
+       if (list_empty(&dev->tx_reqs))
+               netif_stop_queue(net);
+       spin_unlock_irqrestore(&dev->req_lock, flags);
+
+       /* no buffer copies needed, unless the network stack did it
+        * or the hardware can't use skb buffers.
+        * or there's not enough space for extra headers we need
+        */
+       if (dev->wrap) {
+               struct sk_buff  *skb_new;
+
+               skb_new = dev->wrap(skb);
+               if (!skb_new)
+                       goto drop;
+
+               dev_kfree_skb_any(skb);
+               skb = skb_new;
+               length = skb->len;
+       }
+       req->buf = skb->data;
+       req->context = skb;
+       req->complete = tx_complete;
+
+       /* use zlp framing on tx for strict CDC-Ether conformance,
+        * though any robust network rx path ignores extra padding.
+        * and some hardware doesn't like to write zlps.
+        */
+       req->zero = 1;
+       if (!dev->zlp && (length % in->maxpacket) == 0)
+               length++;
+
+       req->length = length;
+
+       /* throttle highspeed IRQ rate back slightly */
+       if (gadget_is_dualspeed(dev->gadget))
+               req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH)
+                       ? ((atomic_read(&dev->tx_qlen) % qmult) != 0)
+                       : 0;
+
+       retval = usb_ep_queue(in, req, GFP_ATOMIC);
+       switch (retval) {
+       default:
+               DBG(dev, "tx queue err %d\n", retval);
+               break;
+       case 0:
+               net->trans_start = jiffies;
+               atomic_inc(&dev->tx_qlen);
+       }
+
+       if (retval) {
+drop:
+               dev->net->stats.tx_dropped++;
+               dev_kfree_skb_any(skb);
+               spin_lock_irqsave(&dev->req_lock, flags);
+               if (list_empty(&dev->tx_reqs))
+                       netif_start_queue(net);
+               list_add(&req->list, &dev->tx_reqs);
+               spin_unlock_irqrestore(&dev->req_lock, flags);
+       }
+       return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void eth_start(struct eth_dev *dev, gfp_t gfp_flags)
+{
+       DBG(dev, "%s\n", __func__);
+
+       /* fill the rx queue */
+       rx_fill(dev, gfp_flags);
+
+       /* and open the tx floodgates */
+       atomic_set(&dev->tx_qlen, 0);
+       netif_wake_queue(dev->net);
+}
+
+static int eth_open(struct net_device *net)
+{
+       struct eth_dev  *dev = netdev_priv(net);
+       struct gether   *link;
+
+       DBG(dev, "%s\n", __func__);
+       if (netif_carrier_ok(dev->net))
+               eth_start(dev, GFP_KERNEL);
+
+       spin_lock_irq(&dev->lock);
+       link = dev->port_usb;
+       if (link && link->open)
+               link->open(link);
+       spin_unlock_irq(&dev->lock);
+
+       return 0;
+}
+
+static int eth_stop(struct net_device *net)
+{
+       struct eth_dev  *dev = netdev_priv(net);
+       unsigned long   flags;
+
+       VDBG(dev, "%s\n", __func__);
+       netif_stop_queue(net);
+
+       DBG(dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n",
+               dev->net->stats.rx_packets, dev->net->stats.tx_packets,
+               dev->net->stats.rx_errors, dev->net->stats.tx_errors
+               );
+
+       /* ensure there are no more active requests */
+       spin_lock_irqsave(&dev->lock, flags);
+       if (dev->port_usb) {
+               struct gether   *link = dev->port_usb;
+
+               if (link->close)
+                       link->close(link);
+
+               /* NOTE:  we have no abort-queue primitive we could use
+                * to cancel all pending I/O.  Instead, we disable then
+                * reenable the endpoints ... this idiom may leave toggle
+                * wrong, but that's a self-correcting error.
+                *
+                * REVISIT:  we *COULD* just let the transfers complete at
+                * their own pace; the network stack can handle old packets.
+                * For the moment we leave this here, since it works.
+                */
+               usb_ep_disable(link->in_ep);
+               usb_ep_disable(link->out_ep);
+               if (netif_carrier_ok(net)) {
+                       DBG(dev, "host still using in/out endpoints\n");
+                       usb_ep_enable(link->in_ep, link->in);
+                       usb_ep_enable(link->out_ep, link->out);
+               }
+       }
+       spin_unlock_irqrestore(&dev->lock, flags);
+
+       return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* initial value, changed by "ifconfig usb0 hw ether xx:xx:xx:xx:xx:xx" */
+static char *dev_addr;
+module_param(dev_addr, charp, S_IRUGO);
+MODULE_PARM_DESC(dev_addr, "Device Ethernet Address");
+
+/* this address is invisible to ifconfig */
+static char *host_addr;
+module_param(host_addr, charp, S_IRUGO);
+MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
+
+
+static u8 __init nibble(unsigned char c)
+{
+       if (isdigit(c))
+               return c - '0';
+       c = toupper(c);
+       if (isxdigit(c))
+               return 10 + c - 'A';
+       return 0;
+}
+
+static int __init get_ether_addr(const char *str, u8 *dev_addr)
+{
+       if (str) {
+               unsigned        i;
+
+               for (i = 0; i < 6; i++) {
+                       unsigned char num;
+
+                       if ((*str == '.') || (*str == ':'))
+                               str++;
+                       num = nibble(*str++) << 4;
+                       num |= (nibble(*str++));
+                       dev_addr [i] = num;
+               }
+               if (is_valid_ether_addr(dev_addr))
+                       return 0;
+       }
+       random_ether_addr(dev_addr);
+       return 1;
+}
+
+static struct eth_dev *the_dev;
+
+
+/**
+ * gether_setup - initialize one ethernet-over-usb link
+ * @g: gadget to associated with these links
+ * @ethaddr: NULL, or a buffer in which the ethernet address of the
+ *     host side of the link is recorded
+ * Context: may sleep
+ *
+ * This sets up the single network link that may be exported by a
+ * gadget driver using this framework.  The link layer addresses are
+ * set up using module parameters.
+ *
+ * Returns negative errno, or zero on success
+ */
+int __init gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN])
+{
+       struct eth_dev          *dev;
+       struct net_device       *net;
+       int                     status;
+
+       if (the_dev)
+               return -EBUSY;
+
+       net = alloc_etherdev(sizeof *dev);
+       if (!net)
+               return -ENOMEM;
+
+       dev = netdev_priv(net);
+       spin_lock_init(&dev->lock);
+       spin_lock_init(&dev->req_lock);
+       INIT_WORK(&dev->work, eth_work);
+       INIT_LIST_HEAD(&dev->tx_reqs);
+       INIT_LIST_HEAD(&dev->rx_reqs);
+
+       /* network device setup */
+       dev->net = net;
+       strcpy(net->name, "usb%d");
+
+       if (get_ether_addr(dev_addr, net->dev_addr))
+               dev_warn(&g->dev,
+                       "using random %s ethernet address\n", "self");
+       if (get_ether_addr(host_addr, dev->host_mac))
+               dev_warn(&g->dev,
+                       "using random %s ethernet address\n", "host");
+
+       if (ethaddr)
+               memcpy(ethaddr, dev->host_mac, ETH_ALEN);
+
+       net->change_mtu = eth_change_mtu;
+       net->hard_start_xmit = eth_start_xmit;
+       net->open = eth_open;
+       net->stop = eth_stop;
+       /* watchdog_timeo, tx_timeout ... */
+       /* set_multicast_list */
+       SET_ETHTOOL_OPS(net, &ops);
+
+       /* two kinds of host-initiated state changes:
+        *  - iff DATA transfer is active, carrier is "on"
+        *  - tx queueing enabled if open *and* carrier is "on"
+        */
+       netif_stop_queue(net);
+       netif_carrier_off(net);
+
+       dev->gadget = g;
+       SET_NETDEV_DEV(net, &g->dev);
+
+       status = register_netdev(net);
+       if (status < 0) {
+               dev_dbg(&g->dev, "register_netdev failed, %d\n", status);
+               free_netdev(net);
+       } else {
+               DECLARE_MAC_BUF(tmp);
+
+               INFO(dev, "MAC %s\n", print_mac(tmp, net->dev_addr));
+               INFO(dev, "HOST MAC %s\n", print_mac(tmp, dev->host_mac));
+
+               the_dev = dev;
+       }
+
+       return status;
+}
+
+/**
+ * gether_cleanup - remove Ethernet-over-USB device
+ * Context: may sleep
+ *
+ * This is called to free all resources allocated by @gether_setup().
+ */
+void gether_cleanup(void)
+{
+       if (!the_dev)
+               return;
+
+       unregister_netdev(the_dev->net);
+       free_netdev(the_dev->net);
+
+       /* assuming we used keventd, it must quiesce too */
+       flush_scheduled_work();
+
+       the_dev = NULL;
+}
+
+
+/**
+ * gether_connect - notify network layer that USB link is active
+ * @link: the USB link, set up with endpoints, descriptors matching
+ *     current device speed, and any framing wrapper(s) set up.
+ * Context: irqs blocked
+ *
+ * This is called to activate endpoints and let the network layer know
+ * the connection is active ("carrier detect").  It may cause the I/O
+ * queues to open and start letting network packets flow, but will in
+ * any case activate the endpoints so that they respond properly to the
+ * USB host.
+ *
+ * Verify net_device pointer returned using IS_ERR().  If it doesn't
+ * indicate some error code (negative errno), ep->driver_data values
+ * have been overwritten.
+ */
+struct net_device *gether_connect(struct gether *link)
+{
+       struct eth_dev          *dev = the_dev;
+       int                     result = 0;
+
+       if (!dev)
+               return ERR_PTR(-EINVAL);
+
+       link->in_ep->driver_data = dev;
+       result = usb_ep_enable(link->in_ep, link->in);
+       if (result != 0) {
+               DBG(dev, "enable %s --> %d\n",
+                       link->in_ep->name, result);
+               goto fail0;
+       }
+
+       link->out_ep->driver_data = dev;
+       result = usb_ep_enable(link->out_ep, link->out);
+       if (result != 0) {
+               DBG(dev, "enable %s --> %d\n",
+                       link->out_ep->name, result);
+               goto fail1;
+       }
+
+       if (result == 0)
+               result = alloc_requests(dev, link, qlen(dev->gadget));
+
+       if (result == 0) {
+               dev->zlp = link->is_zlp_ok;
+               DBG(dev, "qlen %d\n", qlen(dev->gadget));
+
+               dev->header_len = link->header_len;
+               dev->unwrap = link->unwrap;
+               dev->wrap = link->wrap;
+
+               spin_lock(&dev->lock);
+               dev->port_usb = link;
+               link->ioport = dev;
+               spin_unlock(&dev->lock);
+
+               netif_carrier_on(dev->net);
+               if (netif_running(dev->net))
+                       eth_start(dev, GFP_ATOMIC);
+
+       /* on error, disable any endpoints  */
+       } else {
+               (void) usb_ep_disable(link->out_ep);
+fail1:
+               (void) usb_ep_disable(link->in_ep);
+       }
+fail0:
+       /* caller is responsible for cleanup on error */
+       if (result < 0)
+               return ERR_PTR(result);
+       return dev->net;
+}
+
+/**
+ * gether_disconnect - notify network layer that USB link is inactive
+ * @link: the USB link, on which gether_connect() was called
+ * Context: irqs blocked
+ *
+ * This is called to deactivate endpoints and let the network layer know
+ * the connection went inactive ("no carrier").
+ *
+ * On return, the state is as if gether_connect() had never been called.
+ * The endpoints are inactive, and accordingly without active USB I/O.
+ * Pointers to endpoint descriptors and endpoint private data are nulled.
+ */
+void gether_disconnect(struct gether *link)
+{
+       struct eth_dev          *dev = link->ioport;
+       struct usb_request      *req;
+
+       WARN_ON(!dev);
+       if (!dev)
+               return;
+
+       DBG(dev, "%s\n", __func__);
+
+       netif_stop_queue(dev->net);
+       netif_carrier_off(dev->net);
+
+       /* disable endpoints, forcing (synchronous) completion
+        * of all pending i/o.  then free the request objects
+        * and forget about the endpoints.
+        */
+       usb_ep_disable(link->in_ep);
+       spin_lock(&dev->req_lock);
+       while (!list_empty(&dev->tx_reqs)) {
+               req = container_of(dev->tx_reqs.next,
+                                       struct usb_request, list);
+               list_del(&req->list);
+
+               spin_unlock(&dev->req_lock);
+               usb_ep_free_request(link->in_ep, req);
+               spin_lock(&dev->req_lock);
+       }
+       spin_unlock(&dev->req_lock);
+       link->in_ep->driver_data = NULL;
+       link->in = NULL;
+
+       usb_ep_disable(link->out_ep);
+       spin_lock(&dev->req_lock);
+       while (!list_empty(&dev->rx_reqs)) {
+               req = container_of(dev->rx_reqs.next,
+                                       struct usb_request, list);
+               list_del(&req->list);
+
+               spin_unlock(&dev->req_lock);
+               usb_ep_free_request(link->out_ep, req);
+               spin_lock(&dev->req_lock);
+       }
+       spin_unlock(&dev->req_lock);
+       link->out_ep->driver_data = NULL;
+       link->out = NULL;
+
+       /* finish forgetting about this USB link episode */
+       dev->header_len = 0;
+       dev->unwrap = NULL;
+       dev->wrap = NULL;
+
+       spin_lock(&dev->lock);
+       dev->port_usb = NULL;
+       link->ioport = NULL;
+       spin_unlock(&dev->lock);
+}
diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
new file mode 100644 (file)
index 0000000..0d1f7ae
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * u_ether.h -- interface to USB gadget "ethernet link" utilities
+ *
+ * Copyright (C) 2003-2005,2008 David Brownell
+ * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __U_ETHER_H
+#define __U_ETHER_H
+
+#include <linux/err.h>
+#include <linux/if_ether.h>
+#include <linux/usb/composite.h>
+#include <linux/usb/cdc.h>
+
+#include "gadget_chips.h"
+
+
+/*
+ * This represents the USB side of an "ethernet" link, managed by a USB
+ * function which provides control and (maybe) framing.  Two functions
+ * in different configurations could share the same ethernet link/netdev,
+ * using different host interaction models.
+ *
+ * There is a current limitation that only one instance of this link may
+ * be present in any given configuration.  When that's a problem, network
+ * layer facilities can be used to package multiple logical links on this
+ * single "physical" one.
+ */
+struct gether {
+       struct usb_function             func;
+
+       /* updated by gether_{connect,disconnect} */
+       struct eth_dev                  *ioport;
+
+       /* endpoints handle full and/or high speeds */
+       struct usb_ep                   *in_ep;
+       struct usb_ep                   *out_ep;
+
+       /* descriptors match device speed at gether_connect() time */
+       struct usb_endpoint_descriptor  *in;
+       struct usb_endpoint_descriptor  *out;
+
+       bool                            is_zlp_ok;
+
+       u16                             cdc_filter;
+
+       /* hooks for added framing, as needed for RNDIS and EEM.
+        * we currently don't support multiple frames per SKB.
+        */
+       u32                             header_len;
+       struct sk_buff                  *(*wrap)(struct sk_buff *skb);
+       int                             (*unwrap)(struct sk_buff *skb);
+
+       /* called on network open/close */
+       void                            (*open)(struct gether *);
+       void                            (*close)(struct gether *);
+};
+
+#define        DEFAULT_FILTER  (USB_CDC_PACKET_TYPE_BROADCAST \
+                       |USB_CDC_PACKET_TYPE_ALL_MULTICAST \
+                       |USB_CDC_PACKET_TYPE_PROMISCUOUS \
+                       |USB_CDC_PACKET_TYPE_DIRECTED)
+
+
+/* netdev setup/teardown as directed by the gadget driver */
+int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]);
+void gether_cleanup(void);
+
+/* connect/disconnect is handled by individual functions */
+struct net_device *gether_connect(struct gether *);
+void gether_disconnect(struct gether *);
+
+/* Some controllers can't support CDC Ethernet (ECM) ... */
+static inline bool can_support_ecm(struct usb_gadget *gadget)
+{
+       if (!gadget_supports_altsettings(gadget))
+               return false;
+
+       /* SA1100 can do ECM, *without* status endpoint ... but we'll
+        * only use it in non-ECM mode for backwards compatibility
+        * (and since we currently require a status endpoint)
+        */
+       if (gadget_is_sa1100(gadget))
+               return false;
+
+       /* Everything else is *presumably* fine ... but this is a bit
+        * chancy, so be **CERTAIN** there are no hardware issues with
+        * your controller.  Add it above if it can't handle CDC.
+        */
+       return true;
+}
+
+/* each configuration may bind one instance of an ethernet link */
+int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]);
+int ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]);
+
+#ifdef CONFIG_USB_ETH_RNDIS
+
+int rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]);
+
+#else
+
+static inline int
+rndis_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
+{
+       return 0;
+}
+
+#endif
+
+#endif /* __U_ETHER_H */
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
new file mode 100644 (file)
index 0000000..abf9505
--- /dev/null
@@ -0,0 +1,1246 @@
+/*
+ * u_serial.c - utilities for USB gadget "serial port"/TTY support
+ *
+ * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
+ * Copyright (C) 2008 David Brownell
+ * Copyright (C) 2008 by Nokia Corporation
+ *
+ * This code also borrows from usbserial.c, which is
+ * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2000 Peter Berger (pberger@brimson.com)
+ * Copyright (C) 2000 Al Borchers (alborchers@steinerpoint.com)
+ *
+ * This software is distributed under the terms of the GNU General
+ * Public License ("GPL") as published by the Free Software Foundation,
+ * either version 2 of that License or (at your option) any later version.
+ */
+
+/* #define VERBOSE_DEBUG */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+
+#include "u_serial.h"
+
+
+/*
+ * This component encapsulates the TTY layer glue needed to provide basic
+ * "serial port" functionality through the USB gadget stack.  Each such
+ * port is exposed through a /dev/ttyGS* node.
+ *
+ * After initialization (gserial_setup), these TTY port devices stay
+ * available until they are removed (gserial_cleanup).  Each one may be
+ * connected to a USB function (gserial_connect), or disconnected (with
+ * gserial_disconnect) when the USB host issues a config change event.
+ * Data can only flow when the port is connected to the host.
+ *
+ * A given TTY port can be made available in multiple configurations.
+ * For example, each one might expose a ttyGS0 node which provides a
+ * login application.  In one case that might use CDC ACM interface 0,
+ * while another configuration might use interface 3 for that.  The
+ * work to handle that (including descriptor management) is not part
+ * of this component.
+ *
+ * Configurations may expose more than one TTY port.  For example, if
+ * ttyGS0 provides login service, then ttyGS1 might provide dialer access
+ * for a telephone or fax link.  And ttyGS2 might be something that just
+ * needs a simple byte stream interface for some messaging protocol that
+ * is managed in userspace ... OBEX, PTP, and MTP have been mentioned.
+ */
+
+/*
+ * gserial is the lifecycle interface, used by USB functions
+ * gs_port is the I/O nexus, used by the tty driver
+ * tty_struct links to the tty/filesystem framework
+ *
+ * gserial <---> gs_port ... links will be null when the USB link is
+ * inactive; managed by gserial_{connect,disconnect}().
+ *     gserial->ioport == usb_ep->driver_data ... gs_port
+ *     gs_port->port_usb ... gserial
+ *
+ * gs_port <---> tty_struct ... links will be null when the TTY file
+ * isn't opened; managed by gs_open()/gs_close()
+ *     gserial->port_tty ... tty_struct
+ *     tty_struct->driver_data ... gserial
+ */
+
+/* RX and TX queues can buffer QUEUE_SIZE packets before they hit the
+ * next layer of buffering.  For TX that's a circular buffer; for RX
+ * consider it a NOP.  A third layer is provided by the TTY code.
+ */
+#define QUEUE_SIZE             16
+#define WRITE_BUF_SIZE         8192            /* TX only */
+
+/* circular buffer */
+struct gs_buf {
+       unsigned                buf_size;
+       char                    *buf_buf;
+       char                    *buf_get;
+       char                    *buf_put;
+};
+
+/*
+ * The port structure holds info for each port, one for each minor number
+ * (and thus for each /dev/ node).
+ */
+struct gs_port {
+       spinlock_t              port_lock;      /* guard port_* access */
+
+       struct gserial          *port_usb;
+       struct tty_struct       *port_tty;
+
+       unsigned                open_count;
+       bool                    openclose;      /* open/close in progress */
+       u8                      port_num;
+
+       wait_queue_head_t       close_wait;     /* wait for last close */
+
+       struct list_head        read_pool;
+       struct tasklet_struct   push;
+
+       struct list_head        write_pool;
+       struct gs_buf           port_write_buf;
+       wait_queue_head_t       drain_wait;     /* wait while writes drain */
+
+       /* REVISIT this state ... */
+       struct usb_cdc_line_coding port_line_coding;    /* 8-N-1 etc */
+};
+
+/* increase N_PORTS if you need more */
+#define N_PORTS                4
+static struct portmaster {
+       struct mutex    lock;                   /* protect open/close */
+       struct gs_port  *port;
+} ports[N_PORTS];
+static unsigned        n_ports;
+
+#define GS_CLOSE_TIMEOUT               15              /* seconds */
+
+
+
+#ifdef VERBOSE_DEBUG
+#define pr_vdebug(fmt, arg...) \
+       pr_debug(fmt, ##arg)
+#else
+#define pr_vdebug(fmt, arg...) \
+       ({ if (0) pr_debug(fmt, ##arg); })
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/* Circular Buffer */
+
+/*
+ * gs_buf_alloc
+ *
+ * Allocate a circular buffer and all associated memory.
+ */
+static int gs_buf_alloc(struct gs_buf *gb, unsigned size)
+{
+       gb->buf_buf = kmalloc(size, GFP_KERNEL);
+       if (gb->buf_buf == NULL)
+               return -ENOMEM;
+
+       gb->buf_size = size;
+       gb->buf_put = gb->buf_buf;
+       gb->buf_get = gb->buf_buf;
+
+       return 0;
+}
+
+/*
+ * gs_buf_free
+ *
+ * Free the buffer and all associated memory.
+ */
+static void gs_buf_free(struct gs_buf *gb)
+{
+       kfree(gb->buf_buf);
+       gb->buf_buf = NULL;
+}
+
+/*
+ * gs_buf_clear
+ *
+ * Clear out all data in the circular buffer.
+ */
+static void gs_buf_clear(struct gs_buf *gb)
+{
+       gb->buf_get = gb->buf_put;
+       /* equivalent to a get of all data available */
+}
+
+/*
+ * gs_buf_data_avail
+ *
+ * Return the number of bytes of data available in the circular
+ * buffer.
+ */
+static unsigned gs_buf_data_avail(struct gs_buf *gb)
+{
+       return (gb->buf_size + gb->buf_put - gb->buf_get) % gb->buf_size;
+}
+
+/*
+ * gs_buf_space_avail
+ *
+ * Return the number of bytes of space available in the circular
+ * buffer.
+ */
+static unsigned gs_buf_space_avail(struct gs_buf *gb)
+{
+       return (gb->buf_size + gb->buf_get - gb->buf_put - 1) % gb->buf_size;
+}
+
+/*
+ * gs_buf_put
+ *
+ * Copy data data from a user buffer and put it into the circular buffer.
+ * Restrict to the amount of space available.
+ *
+ * Return the number of bytes copied.
+ */
+static unsigned
+gs_buf_put(struct gs_buf *gb, const char *buf, unsigned count)
+{
+       unsigned len;
+
+       len  = gs_buf_space_avail(gb);
+       if (count > len)
+               count = len;
+
+       if (count == 0)
+               return 0;
+
+       len = gb->buf_buf + gb->buf_size - gb->buf_put;
+       if (count > len) {
+               memcpy(gb->buf_put, buf, len);
+               memcpy(gb->buf_buf, buf+len, count - len);
+               gb->buf_put = gb->buf_buf + count - len;
+       } else {
+               memcpy(gb->buf_put, buf, count);
+               if (count < len)
+                       gb->buf_put += count;
+               else /* count == len */
+                       gb->buf_put = gb->buf_buf;
+       }
+
+       return count;
+}
+
+/*
+ * gs_buf_get
+ *
+ * Get data from the circular buffer and copy to the given buffer.
+ * Restrict to the amount of data available.
+ *
+ * Return the number of bytes copied.
+ */
+static unsigned
+gs_buf_get(struct gs_buf *gb, char *buf, unsigned count)
+{
+       unsigned len;
+
+       len = gs_buf_data_avail(gb);
+       if (count > len)
+               count = len;
+
+       if (count == 0)
+               return 0;
+
+       len = gb->buf_buf + gb->buf_size - gb->buf_get;
+       if (count > len) {
+               memcpy(buf, gb->buf_get, len);
+               memcpy(buf+len, gb->buf_buf, count - len);
+               gb->buf_get = gb->buf_buf + count - len;
+       } else {
+               memcpy(buf, gb->buf_get, count);
+               if (count < len)
+                       gb->buf_get += count;
+               else /* count == len */
+                       gb->buf_get = gb->buf_buf;
+       }
+
+       return count;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* I/O glue between TTY (upper) and USB function (lower) driver layers */
+
+/*
+ * gs_alloc_req
+ *
+ * Allocate a usb_request and its buffer.  Returns a pointer to the
+ * usb_request or NULL if there is an error.
+ */
+static struct usb_request *
+gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags)
+{
+       struct usb_request *req;
+
+       req = usb_ep_alloc_request(ep, kmalloc_flags);
+
+       if (req != NULL) {
+               req->length = len;
+               req->buf = kmalloc(len, kmalloc_flags);
+               if (req->buf == NULL) {
+                       usb_ep_free_request(ep, req);
+                       return NULL;
+               }
+       }
+
+       return req;
+}
+
+/*
+ * gs_free_req
+ *
+ * Free a usb_request and its buffer.
+ */
+static void gs_free_req(struct usb_ep *ep, struct usb_request *req)
+{
+       kfree(req->buf);
+       usb_ep_free_request(ep, req);
+}
+
+/*
+ * gs_send_packet
+ *
+ * If there is data to send, a packet is built in the given
+ * buffer and the size is returned.  If there is no data to
+ * send, 0 is returned.
+ *
+ * Called with port_lock held.
+ */
+static unsigned
+gs_send_packet(struct gs_port *port, char *packet, unsigned size)
+{
+       unsigned len;
+
+       len = gs_buf_data_avail(&port->port_write_buf);
+       if (len < size)
+               size = len;
+       if (size != 0)
+               size = gs_buf_get(&port->port_write_buf, packet, size);
+       return size;
+}
+
+/*
+ * gs_start_tx
+ *
+ * This function finds available write requests, calls
+ * gs_send_packet to fill these packets with data, and
+ * continues until either there are no more write requests
+ * available or no more data to send.  This function is
+ * run whenever data arrives or write requests are available.
+ *
+ * Context: caller owns port_lock; port_usb is non-null.
+ */
+static int gs_start_tx(struct gs_port *port)
+/*
+__releases(&port->port_lock)
+__acquires(&port->port_lock)
+*/
+{
+       struct list_head        *pool = &port->write_pool;
+       struct usb_ep           *in = port->port_usb->in;
+       int                     status = 0;
+       bool                    do_tty_wake = false;
+
+       while (!list_empty(pool)) {
+               struct usb_request      *req;
+               int                     len;
+
+               req = list_entry(pool->next, struct usb_request, list);
+               len = gs_send_packet(port, req->buf, in->maxpacket);
+               if (len == 0) {
+                       wake_up_interruptible(&port->drain_wait);
+                       break;
+               }
+               do_tty_wake = true;
+
+               req->length = len;
+               list_del(&req->list);
+
+#ifdef VERBOSE_DEBUG
+               pr_debug("%s: %s, len=%d, 0x%02x 0x%02x 0x%02x ...\n",
+                               __func__, in->name, len, *((u8 *)req->buf),
+                               *((u8 *)req->buf+1), *((u8 *)req->buf+2));
+#endif
+
+               /* Drop lock while we call out of driver; completions
+                * could be issued while we do so.  Disconnection may
+                * happen too; maybe immediately before we queue this!
+                *
+                * NOTE that we may keep sending data for a while after
+                * the TTY closed (dev->ioport->port_tty is NULL).
+                */
+               spin_unlock(&port->port_lock);
+               status = usb_ep_queue(in, req, GFP_ATOMIC);
+               spin_lock(&port->port_lock);
+
+               if (status) {
+                       pr_debug("%s: %s %s err %d\n",
+                                       __func__, "queue", in->name, status);
+                       list_add(&req->list, pool);
+                       break;
+               }
+
+               /* abort immediately after disconnect */
+               if (!port->port_usb)
+                       break;
+       }
+
+       if (do_tty_wake && port->port_tty)
+               tty_wakeup(port->port_tty);
+       return status;
+}
+
+static void gs_rx_push(unsigned long _port)
+{
+       struct gs_port          *port = (void *)_port;
+       struct tty_struct       *tty = port->port_tty;
+
+       /* With low_latency, tty_flip_buffer_push() doesn't put its
+        * real work through a workqueue, so the ldisc has a better
+        * chance to keep up with peak USB data rates.
+        */
+       if (tty) {
+               tty_flip_buffer_push(tty);
+               wake_up_interruptible(&tty->read_wait);
+       }
+}
+
+/*
+ * gs_recv_packet
+ *
+ * Called for each USB packet received.  Reads the packet
+ * header and stuffs the data in the appropriate tty buffer.
+ * Returns 0 if successful, or a negative error number.
+ *
+ * Called during USB completion routine, on interrupt time.
+ * With port_lock.
+ */
+static int gs_recv_packet(struct gs_port *port, char *packet, unsigned size)
+{
+       unsigned                len;
+       struct tty_struct       *tty;
+
+       /* I/O completions can continue for a while after close(), until the
+        * request queue empties.  Just discard any data we receive, until
+        * something reopens this TTY ... as if there were no HW flow control.
+        */
+       tty = port->port_tty;
+       if (tty == NULL) {
+               pr_vdebug("%s: ttyGS%d, after close\n",
+                               __func__, port->port_num);
+               return -EIO;
+       }
+
+       len = tty_insert_flip_string(tty, packet, size);
+       if (len > 0)
+               tasklet_schedule(&port->push);
+       if (len < size)
+               pr_debug("%s: ttyGS%d, drop %d bytes\n",
+                               __func__, port->port_num, size - len);
+       return 0;
+}
+
+/*
+ * Context: caller owns port_lock, and port_usb is set
+ */
+static unsigned gs_start_rx(struct gs_port *port)
+/*
+__releases(&port->port_lock)
+__acquires(&port->port_lock)
+*/
+{
+       struct list_head        *pool = &port->read_pool;
+       struct usb_ep           *out = port->port_usb->out;
+       unsigned                started = 0;
+
+       while (!list_empty(pool)) {
+               struct usb_request      *req;
+               int                     status;
+               struct tty_struct       *tty;
+
+               /* no more rx if closed or throttled */
+               tty = port->port_tty;
+               if (!tty || test_bit(TTY_THROTTLED, &tty->flags))
+                       break;
+
+               req = list_entry(pool->next, struct usb_request, list);
+               list_del(&req->list);
+               req->length = out->maxpacket;
+
+               /* drop lock while we call out; the controller driver
+                * may need to call us back (e.g. for disconnect)
+                */
+               spin_unlock(&port->port_lock);
+               status = usb_ep_queue(out, req, GFP_ATOMIC);
+               spin_lock(&port->port_lock);
+
+               if (status) {
+                       pr_debug("%s: %s %s err %d\n",
+                                       __func__, "queue", out->name, status);
+                       list_add(&req->list, pool);
+                       break;
+               }
+               started++;
+
+               /* abort immediately after disconnect */
+               if (!port->port_usb)
+                       break;
+       }
+       return started;
+}
+
+static void gs_read_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       int             status;
+       struct gs_port  *port = ep->driver_data;
+
+       spin_lock(&port->port_lock);
+       list_add(&req->list, &port->read_pool);
+
+       switch (req->status) {
+       case 0:
+               /* normal completion */
+               status = gs_recv_packet(port, req->buf, req->actual);
+               if (status && status != -EIO)
+                       pr_debug("%s: %s %s err %d\n",
+                               __func__, "recv", ep->name, status);
+               gs_start_rx(port);
+               break;
+
+       case -ESHUTDOWN:
+               /* disconnect */
+               pr_vdebug("%s: %s shutdown\n", __func__, ep->name);
+               break;
+
+       default:
+               /* presumably a transient fault */
+               pr_warning("%s: unexpected %s status %d\n",
+                               __func__, ep->name, req->status);
+               gs_start_rx(port);
+               break;
+       }
+       spin_unlock(&port->port_lock);
+}
+
+static void gs_write_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       struct gs_port  *port = ep->driver_data;
+
+       spin_lock(&port->port_lock);
+       list_add(&req->list, &port->write_pool);
+
+       switch (req->status) {
+       default:
+               /* presumably a transient fault */
+               pr_warning("%s: unexpected %s status %d\n",
+                               __func__, ep->name, req->status);
+               /* FALL THROUGH */
+       case 0:
+               /* normal completion */
+               gs_start_tx(port);
+               break;
+
+       case -ESHUTDOWN:
+               /* disconnect */
+               pr_vdebug("%s: %s shutdown\n", __func__, ep->name);
+               break;
+       }
+
+       spin_unlock(&port->port_lock);
+}
+
+static void gs_free_requests(struct usb_ep *ep, struct list_head *head)
+{
+       struct usb_request      *req;
+
+       while (!list_empty(head)) {
+               req = list_entry(head->next, struct usb_request, list);
+               list_del(&req->list);
+               gs_free_req(ep, req);
+       }
+}
+
+static int gs_alloc_requests(struct usb_ep *ep, struct list_head *head,
+               void (*fn)(struct usb_ep *, struct usb_request *))
+{
+       int                     i;
+       struct usb_request      *req;
+
+       /* Pre-allocate up to QUEUE_SIZE transfers, but if we can't
+        * do quite that many this time, don't fail ... we just won't
+        * be as speedy as we might otherwise be.
+        */
+       for (i = 0; i < QUEUE_SIZE; i++) {
+               req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC);
+               if (!req)
+                       return list_empty(head) ? -ENOMEM : 0;
+               req->complete = fn;
+               list_add_tail(&req->list, head);
+       }
+       return 0;
+}
+
+/**
+ * gs_start_io - start USB I/O streams
+ * @dev: encapsulates endpoints to use
+ * Context: holding port_lock; port_tty and port_usb are non-null
+ *
+ * We only start I/O when something is connected to both sides of
+ * this port.  If nothing is listening on the host side, we may
+ * be pointlessly filling up our TX buffers and FIFO.
+ */
+static int gs_start_io(struct gs_port *port)
+{
+       struct list_head        *head = &port->read_pool;
+       struct usb_ep           *ep = port->port_usb->out;
+       int                     status;
+       unsigned                started;
+
+       /* Allocate RX and TX I/O buffers.  We can't easily do this much
+        * earlier (with GFP_KERNEL) because the requests are coupled to
+        * endpoints, as are the packet sizes we'll be using.  Different
+        * configurations may use different endpoints with a given port;
+        * and high speed vs full speed changes packet sizes too.
+        */
+       status = gs_alloc_requests(ep, head, gs_read_complete);
+       if (status)
+               return status;
+
+       status = gs_alloc_requests(port->port_usb->in, &port->write_pool,
+                       gs_write_complete);
+       if (status) {
+               gs_free_requests(ep, head);
+               return status;
+       }
+
+       /* queue read requests */
+       started = gs_start_rx(port);
+
+       /* unblock any pending writes into our circular buffer */
+       if (started) {
+               tty_wakeup(port->port_tty);
+       } else {
+               gs_free_requests(ep, head);
+               gs_free_requests(port->port_usb->in, &port->write_pool);
+       }
+
+       return started ? 0 : status;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* TTY Driver */
+
+/*
+ * gs_open sets up the link between a gs_port and its associated TTY.
+ * That link is broken *only* by TTY close(), and all driver methods
+ * know that.
+ */
+static int gs_open(struct tty_struct *tty, struct file *file)
+{
+       int             port_num = tty->index;
+       struct gs_port  *port;
+       int             status;
+
+       if (port_num < 0 || port_num >= n_ports)
+               return -ENXIO;
+
+       do {
+               mutex_lock(&ports[port_num].lock);
+               port = ports[port_num].port;
+               if (!port)
+                       status = -ENODEV;
+               else {
+                       spin_lock_irq(&port->port_lock);
+
+                       /* already open?  Great. */
+                       if (port->open_count) {
+                               status = 0;
+                               port->open_count++;
+
+                       /* currently opening/closing? wait ... */
+                       } else if (port->openclose) {
+                               status = -EBUSY;
+
+                       /* ... else we do the work */
+                       } else {
+                               status = -EAGAIN;
+                               port->openclose = true;
+                       }
+                       spin_unlock_irq(&port->port_lock);
+               }
+               mutex_unlock(&ports[port_num].lock);
+
+               switch (status) {
+               default:
+                       /* fully handled */
+                       return status;
+               case -EAGAIN:
+                       /* must do the work */
+                       break;
+               case -EBUSY:
+                       /* wait for EAGAIN task to finish */
+                       msleep(1);
+                       /* REVISIT could have a waitchannel here, if
+                        * concurrent open performance is important
+                        */
+                       break;
+               }
+       } while (status != -EAGAIN);
+
+       /* Do the "real open" */
+       spin_lock_irq(&port->port_lock);
+
+       /* allocate circular buffer on first open */
+       if (port->port_write_buf.buf_buf == NULL) {
+
+               spin_unlock_irq(&port->port_lock);
+               status = gs_buf_alloc(&port->port_write_buf, WRITE_BUF_SIZE);
+               spin_lock_irq(&port->port_lock);
+
+               if (status) {
+                       pr_debug("gs_open: ttyGS%d (%p,%p) no buffer\n",
+                               port->port_num, tty, file);
+                       port->openclose = false;
+                       goto exit_unlock_port;
+               }
+       }
+
+       /* REVISIT if REMOVED (ports[].port NULL), abort the open
+        * to let rmmod work faster (but this way isn't wrong).
+        */
+
+       /* REVISIT maybe wait for "carrier detect" */
+
+       tty->driver_data = port;
+       port->port_tty = tty;
+
+       port->open_count = 1;
+       port->openclose = false;
+
+       /* low_latency means ldiscs work in tasklet context, without
+        * needing a workqueue schedule ... easier to keep up.
+        */
+       tty->low_latency = 1;
+
+       /* if connected, start the I/O stream */
+       if (port->port_usb) {
+               pr_debug("gs_open: start ttyGS%d\n", port->port_num);
+               gs_start_io(port);
+
+               /* REVISIT for ACM, issue "network connected" event */
+       }
+
+       pr_debug("gs_open: ttyGS%d (%p,%p)\n", port->port_num, tty, file);
+
+       status = 0;
+
+exit_unlock_port:
+       spin_unlock_irq(&port->port_lock);
+       return status;
+}
+
+static int gs_writes_finished(struct gs_port *p)
+{
+       int cond;
+
+       /* return true on disconnect or empty buffer */
+       spin_lock_irq(&p->port_lock);
+       cond = (p->port_usb == NULL) || !gs_buf_data_avail(&p->port_write_buf);
+       spin_unlock_irq(&p->port_lock);
+
+       return cond;
+}
+
+static void gs_close(struct tty_struct *tty, struct file *file)
+{
+       struct gs_port *port = tty->driver_data;
+
+       spin_lock_irq(&port->port_lock);
+
+       if (port->open_count != 1) {
+               if (port->open_count == 0)
+                       WARN_ON(1);
+               else
+                       --port->open_count;
+               goto exit;
+       }
+
+       pr_debug("gs_close: ttyGS%d (%p,%p) ...\n", port->port_num, tty, file);
+
+       /* mark port as closing but in use; we can drop port lock
+        * and sleep if necessary
+        */
+       port->openclose = true;
+       port->open_count = 0;
+
+       if (port->port_usb)
+               /* REVISIT for ACM, issue "network disconnected" event */;
+
+       /* wait for circular write buffer to drain, disconnect, or at
+        * most GS_CLOSE_TIMEOUT seconds; then discard the rest
+        */
+       if (gs_buf_data_avail(&port->port_write_buf) > 0
+                       && port->port_usb) {
+               spin_unlock_irq(&port->port_lock);
+               wait_event_interruptible_timeout(port->drain_wait,
+                                       gs_writes_finished(port),
+                                       GS_CLOSE_TIMEOUT * HZ);
+               spin_lock_irq(&port->port_lock);
+       }
+
+       /* Iff we're disconnected, there can be no I/O in flight so it's
+        * ok to free the circular buffer; else just scrub it.  And don't
+        * let the push tasklet fire again until we're re-opened.
+        */
+       if (port->port_usb == NULL)
+               gs_buf_free(&port->port_write_buf);
+       else
+               gs_buf_clear(&port->port_write_buf);
+
+       tasklet_kill(&port->push);
+
+       tty->driver_data = NULL;
+       port->port_tty = NULL;
+
+       port->openclose = false;
+
+       pr_debug("gs_close: ttyGS%d (%p,%p) done!\n",
+                       port->port_num, tty, file);
+
+       wake_up_interruptible(&port->close_wait);
+exit:
+       spin_unlock_irq(&port->port_lock);
+}
+
+static int gs_write(struct tty_struct *tty, const unsigned char *buf, int count)
+{
+       struct gs_port  *port = tty->driver_data;
+       unsigned long   flags;
+       int             status;
+
+       pr_vdebug("gs_write: ttyGS%d (%p) writing %d bytes\n",
+                       port->port_num, tty, count);
+
+       spin_lock_irqsave(&port->port_lock, flags);
+       if (count)
+               count = gs_buf_put(&port->port_write_buf, buf, count);
+       /* treat count == 0 as flush_chars() */
+       if (port->port_usb)
+               status = gs_start_tx(port);
+       spin_unlock_irqrestore(&port->port_lock, flags);
+
+       return count;
+}
+
+static int gs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+       struct gs_port  *port = tty->driver_data;
+       unsigned long   flags;
+       int             status;
+
+       pr_vdebug("gs_put_char: (%d,%p) char=0x%x, called from %p\n",
+               port->port_num, tty, ch, __builtin_return_address(0));
+
+       spin_lock_irqsave(&port->port_lock, flags);
+       status = gs_buf_put(&port->port_write_buf, &ch, 1);
+       spin_unlock_irqrestore(&port->port_lock, flags);
+
+       return status;
+}
+
+static void gs_flush_chars(struct tty_struct *tty)
+{
+       struct gs_port  *port = tty->driver_data;
+       unsigned long   flags;
+
+       pr_vdebug("gs_flush_chars: (%d,%p)\n", port->port_num, tty);
+
+       spin_lock_irqsave(&port->port_lock, flags);
+       if (port->port_usb)
+               gs_start_tx(port);
+       spin_unlock_irqrestore(&port->port_lock, flags);
+}
+
+static int gs_write_room(struct tty_struct *tty)
+{
+       struct gs_port  *port = tty->driver_data;
+       unsigned long   flags;
+       int             room = 0;
+
+       spin_lock_irqsave(&port->port_lock, flags);
+       if (port->port_usb)
+               room = gs_buf_space_avail(&port->port_write_buf);
+       spin_unlock_irqrestore(&port->port_lock, flags);
+
+       pr_vdebug("gs_write_room: (%d,%p) room=%d\n",
+               port->port_num, tty, room);
+
+       return room;
+}
+
+static int gs_chars_in_buffer(struct tty_struct *tty)
+{
+       struct gs_port  *port = tty->driver_data;
+       unsigned long   flags;
+       int             chars = 0;
+
+       spin_lock_irqsave(&port->port_lock, flags);
+       chars = gs_buf_data_avail(&port->port_write_buf);
+       spin_unlock_irqrestore(&port->port_lock, flags);
+
+       pr_vdebug("gs_chars_in_buffer: (%d,%p) chars=%d\n",
+               port->port_num, tty, chars);
+
+       return chars;
+}
+
+/* undo side effects of setting TTY_THROTTLED */
+static void gs_unthrottle(struct tty_struct *tty)
+{
+       struct gs_port          *port = tty->driver_data;
+       unsigned long           flags;
+       unsigned                started = 0;
+
+       spin_lock_irqsave(&port->port_lock, flags);
+       if (port->port_usb)
+               started = gs_start_rx(port);
+       spin_unlock_irqrestore(&port->port_lock, flags);
+
+       pr_vdebug("gs_unthrottle: ttyGS%d, %d packets\n",
+                       port->port_num, started);
+}
+
+static const struct tty_operations gs_tty_ops = {
+       .open =                 gs_open,
+       .close =                gs_close,
+       .write =                gs_write,
+       .put_char =             gs_put_char,
+       .flush_chars =          gs_flush_chars,
+       .write_room =           gs_write_room,
+       .chars_in_buffer =      gs_chars_in_buffer,
+       .unthrottle =           gs_unthrottle,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static struct tty_driver *gs_tty_driver;
+
+static int __init
+gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding)
+{
+       struct gs_port  *port;
+
+       port = kzalloc(sizeof(struct gs_port), GFP_KERNEL);
+       if (port == NULL)
+               return -ENOMEM;
+
+       spin_lock_init(&port->port_lock);
+       init_waitqueue_head(&port->close_wait);
+       init_waitqueue_head(&port->drain_wait);
+
+       tasklet_init(&port->push, gs_rx_push, (unsigned long) port);
+
+       INIT_LIST_HEAD(&port->read_pool);
+       INIT_LIST_HEAD(&port->write_pool);
+
+       port->port_num = port_num;
+       port->port_line_coding = *coding;
+
+       ports[port_num].port = port;
+
+       return 0;
+}
+
+/**
+ * gserial_setup - initialize TTY driver for one or more ports
+ * @g: gadget to associate with these ports
+ * @count: how many ports to support
+ * Context: may sleep
+ *
+ * The TTY stack needs to know in advance how many devices it should
+ * plan to manage.  Use this call to set up the ports you will be
+ * exporting through USB.  Later, connect them to functions based
+ * on what configuration is activated by the USB host; and disconnect
+ * them as appropriate.
+ *
+ * An example would be a two-configuration device in which both
+ * configurations expose port 0, but through different functions.
+ * One configuration could even expose port 1 while the other
+ * one doesn't.
+ *
+ * Returns negative errno or zero.
+ */
+int __init gserial_setup(struct usb_gadget *g, unsigned count)
+{
+       unsigned                        i;
+       struct usb_cdc_line_coding      coding;
+       int                             status;
+
+       if (count == 0 || count > N_PORTS)
+               return -EINVAL;
+
+       gs_tty_driver = alloc_tty_driver(count);
+       if (!gs_tty_driver)
+               return -ENOMEM;
+
+       gs_tty_driver->owner = THIS_MODULE;
+       gs_tty_driver->driver_name = "g_serial";
+       gs_tty_driver->name = "ttyGS";
+       /* uses dynamically assigned dev_t values */
+
+       gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
+       gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
+       gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+       gs_tty_driver->init_termios = tty_std_termios;
+
+       /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on
+        * MS-Windows.  Otherwise, most of these flags shouldn't affect
+        * anything unless we were to actually hook up to a serial line.
+        */
+       gs_tty_driver->init_termios.c_cflag =
+                       B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+       gs_tty_driver->init_termios.c_ispeed = 9600;
+       gs_tty_driver->init_termios.c_ospeed = 9600;
+
+       coding.dwDTERate = __constant_cpu_to_le32(9600);
+       coding.bCharFormat = 8;
+       coding.bParityType = USB_CDC_NO_PARITY;
+       coding.bDataBits = USB_CDC_1_STOP_BITS;
+
+       tty_set_operations(gs_tty_driver, &gs_tty_ops);
+
+       /* make devices be openable */
+       for (i = 0; i < count; i++) {
+               mutex_init(&ports[i].lock);
+               status = gs_port_alloc(i, &coding);
+               if (status) {
+                       count = i;
+                       goto fail;
+               }
+       }
+       n_ports = count;
+
+       /* export the driver ... */
+       status = tty_register_driver(gs_tty_driver);
+       if (status) {
+               put_tty_driver(gs_tty_driver);
+               pr_err("%s: cannot register, err %d\n",
+                               __func__, status);
+               goto fail;
+       }
+
+       /* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */
+       for (i = 0; i < count; i++) {
+               struct device   *tty_dev;
+
+               tty_dev = tty_register_device(gs_tty_driver, i, &g->dev);
+               if (IS_ERR(tty_dev))
+                       pr_warning("%s: no classdev for port %d, err %ld\n",
+                               __func__, i, PTR_ERR(tty_dev));
+       }
+
+       pr_debug("%s: registered %d ttyGS* device%s\n", __func__,
+                       count, (count == 1) ? "" : "s");
+
+       return status;
+fail:
+       while (count--)
+               kfree(ports[count].port);
+       put_tty_driver(gs_tty_driver);
+       gs_tty_driver = NULL;
+       return status;
+}
+
+static int gs_closed(struct gs_port *port)
+{
+       int cond;
+
+       spin_lock_irq(&port->port_lock);
+       cond = (port->open_count == 0) && !port->openclose;
+       spin_unlock_irq(&port->port_lock);
+       return cond;
+}
+
+/**
+ * gserial_cleanup - remove TTY-over-USB driver and devices
+ * Context: may sleep
+ *
+ * This is called to free all resources allocated by @gserial_setup().
+ * Accordingly, it may need to wait until some open /dev/ files have
+ * closed.
+ *
+ * The caller must have issued @gserial_disconnect() for any ports
+ * that had previously been connected, so that there is never any
+ * I/O pending when it's called.
+ */
+void gserial_cleanup(void)
+{
+       unsigned        i;
+       struct gs_port  *port;
+
+       if (!gs_tty_driver)
+               return;
+
+       /* start sysfs and /dev/ttyGS* node removal */
+       for (i = 0; i < n_ports; i++)
+               tty_unregister_device(gs_tty_driver, i);
+
+       for (i = 0; i < n_ports; i++) {
+               /* prevent new opens */
+               mutex_lock(&ports[i].lock);
+               port = ports[i].port;
+               ports[i].port = NULL;
+               mutex_unlock(&ports[i].lock);
+
+               /* wait for old opens to finish */
+               wait_event(port->close_wait, gs_closed(port));
+
+               WARN_ON(port->port_usb != NULL);
+
+               kfree(port);
+       }
+       n_ports = 0;
+
+       tty_unregister_driver(gs_tty_driver);
+       gs_tty_driver = NULL;
+
+       pr_debug("%s: cleaned up ttyGS* support\n", __func__);
+}
+
+/**
+ * gserial_connect - notify TTY I/O glue that USB link is active
+ * @gser: the function, set up with endpoints and descriptors
+ * @port_num: which port is active
+ * Context: any (usually from irq)
+ *
+ * This is called activate endpoints and let the TTY layer know that
+ * the connection is active ... not unlike "carrier detect".  It won't
+ * necessarily start I/O queues; unless the TTY is held open by any
+ * task, there would be no point.  However, the endpoints will be
+ * activated so the USB host can perform I/O, subject to basic USB
+ * hardware flow control.
+ *
+ * Caller needs to have set up the endpoints and USB function in @dev
+ * before calling this, as well as the appropriate (speed-specific)
+ * endpoint descriptors, and also have set up the TTY driver by calling
+ * @gserial_setup().
+ *
+ * Returns negative errno or zero.
+ * On success, ep->driver_data will be overwritten.
+ */
+int gserial_connect(struct gserial *gser, u8 port_num)
+{
+       struct gs_port  *port;
+       unsigned long   flags;
+       int             status;
+
+       if (!gs_tty_driver || port_num >= n_ports)
+               return -ENXIO;
+
+       /* we "know" gserial_cleanup() hasn't been called */
+       port = ports[port_num].port;
+
+       /* activate the endpoints */
+       status = usb_ep_enable(gser->in, gser->in_desc);
+       if (status < 0)
+               return status;
+       gser->in->driver_data = port;
+
+       status = usb_ep_enable(gser->out, gser->out_desc);
+       if (status < 0)
+               goto fail_out;
+       gser->out->driver_data = port;
+
+       /* then tell the tty glue that I/O can work */
+       spin_lock_irqsave(&port->port_lock, flags);
+       gser->ioport = port;
+       port->port_usb = gser;
+
+       /* REVISIT unclear how best to handle this state...
+        * we don't really couple it with the Linux TTY.
+        */
+       gser->port_line_coding = port->port_line_coding;
+
+       /* REVISIT if waiting on "carrier detect", signal. */
+
+       /* REVISIT for ACM, issue "network connection" status notification:
+        * connected if open_count, else disconnected.
+        */
+
+       /* if it's already open, start I/O */
+       if (port->open_count) {
+               pr_debug("gserial_connect: start ttyGS%d\n", port->port_num);
+               gs_start_io(port);
+       }
+
+       spin_unlock_irqrestore(&port->port_lock, flags);
+
+       return status;
+
+fail_out:
+       usb_ep_disable(gser->in);
+       gser->in->driver_data = NULL;
+       return status;
+}
+
+/**
+ * gserial_disconnect - notify TTY I/O glue that USB link is inactive
+ * @gser: the function, on which gserial_connect() was called
+ * Context: any (usually from irq)
+ *
+ * This is called to deactivate endpoints and let the TTY layer know
+ * that the connection went inactive ... not unlike "hangup".
+ *
+ * On return, the state is as if gserial_connect() had never been called;
+ * there is no active USB I/O on these endpoints.
+ */
+void gserial_disconnect(struct gserial *gser)
+{
+       struct gs_port  *port = gser->ioport;
+       unsigned long   flags;
+
+       if (!port)
+               return;
+
+       /* tell the TTY glue not to do I/O here any more */
+       spin_lock_irqsave(&port->port_lock, flags);
+
+       /* REVISIT as above: how best to track this? */
+       port->port_line_coding = gser->port_line_coding;
+
+       port->port_usb = NULL;
+       gser->ioport = NULL;
+       if (port->open_count > 0 || port->openclose) {
+               wake_up_interruptible(&port->drain_wait);
+               if (port->port_tty)
+                       tty_hangup(port->port_tty);
+       }
+       spin_unlock_irqrestore(&port->port_lock, flags);
+
+       /* disable endpoints, aborting down any active I/O */
+       usb_ep_disable(gser->out);
+       gser->out->driver_data = NULL;
+
+       usb_ep_disable(gser->in);
+       gser->in->driver_data = NULL;
+
+       /* finally, free any unused/unusable I/O buffers */
+       spin_lock_irqsave(&port->port_lock, flags);
+       if (port->open_count == 0 && !port->openclose)
+               gs_buf_free(&port->port_write_buf);
+       gs_free_requests(gser->out, &port->read_pool);
+       gs_free_requests(gser->in, &port->write_pool);
+       spin_unlock_irqrestore(&port->port_lock, flags);
+}
diff --git a/drivers/usb/gadget/u_serial.h b/drivers/usb/gadget/u_serial.h
new file mode 100644 (file)
index 0000000..7b56113
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * u_serial.h - interface to USB gadget "serial port"/TTY utilities
+ *
+ * Copyright (C) 2008 David Brownell
+ * Copyright (C) 2008 by Nokia Corporation
+ *
+ * This software is distributed under the terms of the GNU General
+ * Public License ("GPL") as published by the Free Software Foundation,
+ * either version 2 of that License or (at your option) any later version.
+ */
+
+#ifndef __U_SERIAL_H
+#define __U_SERIAL_H
+
+#include <linux/usb/composite.h>
+#include <linux/usb/cdc.h>
+
+/*
+ * One non-multiplexed "serial" I/O port ... there can be several of these
+ * on any given USB peripheral device, if it provides enough endpoints.
+ *
+ * The "u_serial" utility component exists to do one thing:  manage TTY
+ * style I/O using the USB peripheral endpoints listed here, including
+ * hookups to sysfs and /dev for each logical "tty" device.
+ *
+ * REVISIT need TTY --> USB event flow too, so ACM can report open/close
+ * as carrier detect events.  Model after ECM.  There's more ACM state too.
+ *
+ * REVISIT someday, allow multiplexing several TTYs over these endpoints.
+ */
+struct gserial {
+       struct usb_function             func;
+
+       /* port is managed by gserial_{connect,disconnect} */
+       struct gs_port                  *ioport;
+
+       struct usb_ep                   *in;
+       struct usb_ep                   *out;
+       struct usb_endpoint_descriptor  *in_desc;
+       struct usb_endpoint_descriptor  *out_desc;
+
+       /* REVISIT avoid this CDC-ACM support harder ... */
+       struct usb_cdc_line_coding port_line_coding;    /* 9600-8-N-1 etc */
+};
+
+/* port setup/teardown is handled by gadget driver */
+int gserial_setup(struct usb_gadget *g, unsigned n_ports);
+void gserial_cleanup(void);
+
+/* connect/disconnect is handled by individual functions */
+int gserial_connect(struct gserial *, u8 port_num);
+void gserial_disconnect(struct gserial *);
+
+/* functions are bound to configurations by a config or gadget driver */
+int acm_bind_config(struct usb_configuration *c, u8 port_num);
+int gser_bind_config(struct usb_configuration *c, u8 port_num);
+
+#endif /* __U_SERIAL_H */
index fce4924dbbe88b6c49dbea3fe33221e224aece05..aa0bd4f126a1e5f7892e1ce645b187d88e4ea7f1 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * zero.c -- Gadget Zero, for USB development
  *
- * Copyright (C) 2003-2007 David Brownell
- * All rights reserved.
+ * Copyright (C) 2003-2008 David Brownell
+ * Copyright (C) 2008 by Nokia Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  *
  * It supports two similar configurations.  One sinks whatever the usb host
  * writes, and in return sources zeroes.  The other loops whatever the host
- * writes back, so the host can read it.  Module options include:
- *
- *   buflen=N          default N=4096, buffer size used
- *   qlen=N            default N=32, how many buffers in the loopback queue
- *   loopdefault       default false, list loopback config first
- *   autoresume=N      default N=0, seconds before triggering remote wakeup
+ * writes back, so the host can read it.
  *
  * Many drivers will only have one configuration, letting them be much
  * simpler if they also don't support high speed operation (like this
  * work with low capability USB controllers without four bulk endpoints.
  */
 
+/*
+ * driver assumes self-powered hardware, and
+ * has no way for users to trigger remote wakeup.
+ */
+
 /* #define VERBOSE_DEBUG */
 
 #include <linux/kernel.h>
 #include <linux/utsname.h>
 #include <linux/device.h>
 
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-
+#include "g_zero.h"
 #include "gadget_chips.h"
 
 
 /*-------------------------------------------------------------------------*/
 
-#define DRIVER_VERSION         "Earth Day 2008"
+#define DRIVER_VERSION         "Cinco de Mayo 2008"
 
-static const char shortname[] = "zero";
 static const char longname[] = "Gadget Zero";
 
-static const char source_sink[] = "source and sink data";
-static const char loopback[] = "loop input to output";
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * driver assumes self-powered hardware, and
- * has no way for users to trigger remote wakeup.
- *
- * this version autoconfigures as much as possible,
- * which is reasonable for most "bulk-only" drivers.
- */
-static const char *EP_IN_NAME;         /* source */
-static const char *EP_OUT_NAME;                /* sink */
-
-/*-------------------------------------------------------------------------*/
-
-/* big enough to hold our biggest descriptor */
-#define USB_BUFSIZ     256
-
-struct zero_dev {
-       spinlock_t              lock;
-       struct usb_gadget       *gadget;
-       struct usb_request      *req;           /* for control responses */
-
-       /* when configured, we have one of two configs:
-        * - source data (in to host) and sink it (out from host)
-        * - or loop it back (out from host back in to host)
-        */
-       u8                      config;
-       struct usb_ep           *in_ep, *out_ep;
-
-       /* autoresume timer */
-       struct timer_list       resume;
-};
-
-#define DBG(d, fmt, args...) \
-       dev_dbg(&(d)->gadget->dev , fmt , ## args)
-#define VDBG(d, fmt, args...) \
-       dev_vdbg(&(d)->gadget->dev , fmt , ## args)
-#define ERROR(d, fmt, args...) \
-       dev_err(&(d)->gadget->dev , fmt , ## args)
-#define WARN(d, fmt, args...) \
-       dev_warn(&(d)->gadget->dev , fmt , ## args)
-#define INFO(d, fmt, args...) \
-       dev_info(&(d)->gadget->dev , fmt , ## args)
-
-/*-------------------------------------------------------------------------*/
-
-static unsigned buflen = 4096;
-static unsigned qlen = 32;
-static unsigned pattern = 0;
-
-module_param(buflen, uint, S_IRUGO);
-module_param(qlen, uint, S_IRUGO);
-module_param(pattern, uint, S_IRUGO|S_IWUSR);
-
-/*
- * if it's nonzero, autoresume says how many seconds to wait
- * before trying to wake up the host after suspend.
- */
-static unsigned autoresume = 0;
-module_param(autoresume, uint, 0);
+unsigned buflen = 4096;
+module_param(buflen, uint, 0);
 
 /*
  * Normally the "loopback" configuration is second (index 1) so
  * it's not the default.  Here's where to change that order, to
- * work better with hosts where config changes are problematic.
- * Or controllers (like superh) that only support one config.
+ * work better with hosts where config changes are problematic or
+ * controllers (like original superh) that only support one config.
  */
 static int loopdefault = 0;
 module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
@@ -156,24 +92,6 @@ module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
 
 /*-------------------------------------------------------------------------*/
 
-/*
- * DESCRIPTORS ... most are static, but strings and (full)
- * configuration descriptors are built on demand.
- */
-
-#define STRING_MANUFACTURER            25
-#define STRING_PRODUCT                 42
-#define STRING_SERIAL                  101
-#define STRING_SOURCE_SINK             250
-#define STRING_LOOPBACK                        251
-
-/*
- * This device advertises two configurations; these numbers work
- * on a pxa250 as well as more flexible hardware.
- */
-#define        CONFIG_SOURCE_SINK      3
-#define        CONFIG_LOOPBACK         2
-
 static struct usb_device_descriptor device_desc = {
        .bLength =              sizeof device_desc,
        .bDescriptorType =      USB_DT_DEVICE,
@@ -183,248 +101,64 @@ static struct usb_device_descriptor device_desc = {
 
        .idVendor =             __constant_cpu_to_le16(DRIVER_VENDOR_NUM),
        .idProduct =            __constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
-       .iManufacturer =        STRING_MANUFACTURER,
-       .iProduct =             STRING_PRODUCT,
-       .iSerialNumber =        STRING_SERIAL,
        .bNumConfigurations =   2,
 };
 
-static struct usb_config_descriptor source_sink_config = {
-       .bLength =              sizeof source_sink_config,
-       .bDescriptorType =      USB_DT_CONFIG,
-
-       /* compute wTotalLength on the fly */
-       .bNumInterfaces =       1,
-       .bConfigurationValue =  CONFIG_SOURCE_SINK,
-       .iConfiguration =       STRING_SOURCE_SINK,
-       .bmAttributes =         USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-       .bMaxPower =            1,      /* self-powered */
-};
-
-static struct usb_config_descriptor loopback_config = {
-       .bLength =              sizeof loopback_config,
-       .bDescriptorType =      USB_DT_CONFIG,
-
-       /* compute wTotalLength on the fly */
-       .bNumInterfaces =       1,
-       .bConfigurationValue =  CONFIG_LOOPBACK,
-       .iConfiguration =       STRING_LOOPBACK,
-       .bmAttributes =         USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-       .bMaxPower =            1,      /* self-powered */
-};
-
+#ifdef CONFIG_USB_OTG
 static struct usb_otg_descriptor otg_descriptor = {
        .bLength =              sizeof otg_descriptor,
        .bDescriptorType =      USB_DT_OTG,
 
-       .bmAttributes =         USB_OTG_SRP,
-};
-
-/* one interface in each configuration */
-
-static const struct usb_interface_descriptor source_sink_intf = {
-       .bLength =              sizeof source_sink_intf,
-       .bDescriptorType =      USB_DT_INTERFACE,
-
-       .bNumEndpoints =        2,
-       .bInterfaceClass =      USB_CLASS_VENDOR_SPEC,
-       .iInterface =           STRING_SOURCE_SINK,
-};
-
-static const struct usb_interface_descriptor loopback_intf = {
-       .bLength =              sizeof loopback_intf,
-       .bDescriptorType =      USB_DT_INTERFACE,
-
-       .bNumEndpoints =        2,
-       .bInterfaceClass =      USB_CLASS_VENDOR_SPEC,
-       .iInterface =           STRING_LOOPBACK,
-};
-
-/* two full speed bulk endpoints; their use is config-dependent */
-
-static struct usb_endpoint_descriptor fs_source_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       .bEndpointAddress =     USB_DIR_IN,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-};
-
-static struct usb_endpoint_descriptor fs_sink_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       .bEndpointAddress =     USB_DIR_OUT,
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-};
-
-static const struct usb_descriptor_header *fs_source_sink_function[] = {
-       (struct usb_descriptor_header *) &otg_descriptor,
-       (struct usb_descriptor_header *) &source_sink_intf,
-       (struct usb_descriptor_header *) &fs_sink_desc,
-       (struct usb_descriptor_header *) &fs_source_desc,
-       NULL,
-};
-
-static const struct usb_descriptor_header *fs_loopback_function[] = {
-       (struct usb_descriptor_header *) &otg_descriptor,
-       (struct usb_descriptor_header *) &loopback_intf,
-       (struct usb_descriptor_header *) &fs_sink_desc,
-       (struct usb_descriptor_header *) &fs_source_desc,
-       NULL,
-};
-
-/*
- * usb 2.0 devices need to expose both high speed and full speed
- * descriptors, unless they only run at full speed.
- *
- * that means alternate endpoint descriptors (bigger packets)
- * and a "device qualifier" ... plus more construction options
- * for the config descriptor.
- */
-
-static struct usb_endpoint_descriptor hs_source_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
-};
-
-static struct usb_endpoint_descriptor hs_sink_desc = {
-       .bLength =              USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType =      USB_DT_ENDPOINT,
-
-       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
-       .wMaxPacketSize =       __constant_cpu_to_le16(512),
-};
-
-static struct usb_qualifier_descriptor dev_qualifier = {
-       .bLength =              sizeof dev_qualifier,
-       .bDescriptorType =      USB_DT_DEVICE_QUALIFIER,
-
-       .bcdUSB =               __constant_cpu_to_le16(0x0200),
-       .bDeviceClass =         USB_CLASS_VENDOR_SPEC,
-
-       .bNumConfigurations =   2,
+       /* REVISIT SRP-only hardware is possible, although
+        * it would not be called "OTG" ...
+        */
+       .bmAttributes =         USB_OTG_SRP | USB_OTG_HNP,
 };
 
-static const struct usb_descriptor_header *hs_source_sink_function[] = {
+const struct usb_descriptor_header *otg_desc[] = {
        (struct usb_descriptor_header *) &otg_descriptor,
-       (struct usb_descriptor_header *) &source_sink_intf,
-       (struct usb_descriptor_header *) &hs_source_desc,
-       (struct usb_descriptor_header *) &hs_sink_desc,
        NULL,
 };
+#endif
 
-static const struct usb_descriptor_header *hs_loopback_function[] = {
-       (struct usb_descriptor_header *) &otg_descriptor,
-       (struct usb_descriptor_header *) &loopback_intf,
-       (struct usb_descriptor_header *) &hs_source_desc,
-       (struct usb_descriptor_header *) &hs_sink_desc,
-       NULL,
-};
+/* string IDs are assigned dynamically */
 
-/* maxpacket and other transfer characteristics vary by speed. */
-static inline struct usb_endpoint_descriptor *
-ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,
-               struct usb_endpoint_descriptor *fs)
-{
-       if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
-               return hs;
-       return fs;
-}
+#define STRING_MANUFACTURER_IDX                0
+#define STRING_PRODUCT_IDX             1
+#define STRING_SERIAL_IDX              2
 
 static char manufacturer[50];
 
 /* default serial number takes at least two packets */
 static char serial[] = "0123456789.0123456789.0123456789";
 
-
-/* static strings, in UTF-8 */
-static struct usb_string strings[] = {
-       { STRING_MANUFACTURER, manufacturer, },
-       { STRING_PRODUCT, longname, },
-       { STRING_SERIAL, serial, },
-       { STRING_LOOPBACK, loopback, },
-       { STRING_SOURCE_SINK, source_sink, },
+static struct usb_string strings_dev[] = {
+       [STRING_MANUFACTURER_IDX].s = manufacturer,
+       [STRING_PRODUCT_IDX].s = longname,
+       [STRING_SERIAL_IDX].s = serial,
        {  }                    /* end of list */
 };
 
-static struct usb_gadget_strings stringtab = {
+static struct usb_gadget_strings stringtab_dev = {
        .language       = 0x0409,       /* en-us */
-       .strings        = strings,
+       .strings        = strings_dev,
 };
 
-/*
- * config descriptors are also handcrafted.  these must agree with code
- * that sets configurations, and with code managing interfaces and their
- * altsettings.  other complexity may come from:
- *
- *  - high speed support, including "other speed config" rules
- *  - multiple configurations
- *  - interfaces with alternate settings
- *  - embedded class or vendor-specific descriptors
- *
- * this handles high speed, and has a second config that could as easily
- * have been an alternate interface setting (on most hardware).
- *
- * NOTE:  to demonstrate (and test) more USB capabilities, this driver
- * should include an altsetting to test interrupt transfers, including
- * high bandwidth modes at high speed.  (Maybe work like Intel's test
- * device?)
- */
-static int config_buf(struct usb_gadget *gadget,
-               u8 *buf, u8 type, unsigned index)
-{
-       int                             is_source_sink;
-       int                             len;
-       const struct usb_descriptor_header **function;
-       int                             hs = 0;
-
-       /* two configurations will always be index 0 and index 1 */
-       if (index > 1)
-               return -EINVAL;
-       is_source_sink = loopdefault ? (index == 1) : (index == 0);
-
-       if (gadget_is_dualspeed(gadget)) {
-               hs = (gadget->speed == USB_SPEED_HIGH);
-               if (type == USB_DT_OTHER_SPEED_CONFIG)
-                       hs = !hs;
-       }
-       if (hs)
-               function = is_source_sink
-                       ? hs_source_sink_function
-                       : hs_loopback_function;
-       else
-               function = is_source_sink
-                       ? fs_source_sink_function
-                       : fs_loopback_function;
-
-       /* for now, don't advertise srp-only devices */
-       if (!gadget_is_otg(gadget))
-               function++;
-
-       len = usb_gadget_config_buf(is_source_sink
-                                       ? &source_sink_config
-                                       : &loopback_config,
-                       buf, USB_BUFSIZ, function);
-       if (len < 0)
-               return len;
-       ((struct usb_config_descriptor *) buf)->bDescriptorType = type;
-       return len;
-}
+static struct usb_gadget_strings *dev_strings[] = {
+       &stringtab_dev,
+       NULL,
+};
 
 /*-------------------------------------------------------------------------*/
 
-static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)
+struct usb_request *alloc_ep_req(struct usb_ep *ep)
 {
        struct usb_request      *req;
 
        req = usb_ep_alloc_request(ep, GFP_ATOMIC);
        if (req) {
-               req->length = length;
-               req->buf = kmalloc(length, GFP_ATOMIC);
+               req->length = buflen;
+               req->buf = kmalloc(buflen, GFP_ATOMIC);
                if (!req->buf) {
                        usb_ep_free_request(ep, req);
                        req = NULL;
@@ -433,681 +167,73 @@ static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)
        return req;
 }
 
-static void free_ep_req(struct usb_ep *ep, struct usb_request *req)
+void free_ep_req(struct usb_ep *ep, struct usb_request *req)
 {
        kfree(req->buf);
        usb_ep_free_request(ep, req);
 }
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripherals,
- * this just sinks bulk packets OUT to the peripheral and sources them IN
- * to the host, optionally with specific data patterns.
- *
- * In terms of control messaging, this supports all the standard requests
- * plus two that support control-OUT tests.
- *
- * Note that because this doesn't queue more than one request at a time,
- * some other function must be used to test queueing logic.  The network
- * link (g_ether) is probably the best option for that.
- */
-
-/* optionally require specific source/sink data patterns  */
-
-static int
-check_read_data(
-       struct zero_dev         *dev,
-       struct usb_ep           *ep,
-       struct usb_request      *req
-)
+static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
 {
-       unsigned        i;
-       u8              *buf = req->buf;
-
-       for (i = 0; i < req->actual; i++, buf++) {
-               switch (pattern) {
-               /* all-zeroes has no synchronization issues */
-               case 0:
-                       if (*buf == 0)
-                               continue;
-                       break;
-               /* mod63 stays in sync with short-terminated transfers,
-                * or otherwise when host and gadget agree on how large
-                * each usb transfer request should be.  resync is done
-                * with set_interface or set_config.
-                */
-               case 1:
-                       if (*buf == (u8)(i % 63))
-                               continue;
-                       break;
-               }
-               ERROR(dev, "bad OUT byte, buf[%d] = %d\n", i, *buf);
-               usb_ep_set_halt(ep);
-               return -EINVAL;
+       int                     value;
+
+       if (ep->driver_data) {
+               value = usb_ep_disable(ep);
+               if (value < 0)
+                       DBG(cdev, "disable %s --> %d\n",
+                                       ep->name, value);
+               ep->driver_data = NULL;
        }
-       return 0;
 }
 
-static void reinit_write_data(struct usb_ep *ep, struct usb_request *req)
+void disable_endpoints(struct usb_composite_dev *cdev,
+               struct usb_ep *in, struct usb_ep *out)
 {
-       unsigned        i;
-       u8              *buf = req->buf;
-
-       switch (pattern) {
-       case 0:
-               memset(req->buf, 0, req->length);
-               break;
-       case 1:
-               for  (i = 0; i < req->length; i++)
-                       *buf++ = (u8) (i % 63);
-               break;
-       }
-}
-
-/* if there is only one request in the queue, there'll always be an
- * irq delay between end of one request and start of the next.
- * that prevents using hardware dma queues.
- */
-static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
-{
-       struct zero_dev *dev = ep->driver_data;
-       int             status = req->status;
-
-       switch (status) {
-
-       case 0:                         /* normal completion? */
-               if (ep == dev->out_ep) {
-                       check_read_data(dev, ep, req);
-                       memset(req->buf, 0x55, req->length);
-               } else
-                       reinit_write_data(ep, req);
-               break;
-
-       /* this endpoint is normally active while we're configured */
-       case -ECONNABORTED:             /* hardware forced ep reset */
-       case -ECONNRESET:               /* request dequeued */
-       case -ESHUTDOWN:                /* disconnect from host */
-               VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status,
-                               req->actual, req->length);
-               if (ep == dev->out_ep)
-                       check_read_data(dev, ep, req);
-               free_ep_req(ep, req);
-               return;
-
-       case -EOVERFLOW:                /* buffer overrun on read means that
-                                        * we didn't provide a big enough
-                                        * buffer.
-                                        */
-       default:
-#if 1
-               DBG(dev, "%s complete --> %d, %d/%d\n", ep->name,
-                               status, req->actual, req->length);
-#endif
-       case -EREMOTEIO:                /* short read */
-               break;
-       }
-
-       status = usb_ep_queue(ep, req, GFP_ATOMIC);
-       if (status) {
-               ERROR(dev, "kill %s:  resubmit %d bytes --> %d\n",
-                               ep->name, req->length, status);
-               usb_ep_set_halt(ep);
-               /* FIXME recover later ... somehow */
-       }
-}
-
-static struct usb_request *source_sink_start_ep(struct usb_ep *ep)
-{
-       struct usb_request      *req;
-       int                     status;
-
-       req = alloc_ep_req(ep, buflen);
-       if (!req)
-               return NULL;
-
-       memset(req->buf, 0, req->length);
-       req->complete = source_sink_complete;
-
-       if (strcmp(ep->name, EP_IN_NAME) == 0)
-               reinit_write_data(ep, req);
-       else
-               memset(req->buf, 0x55, req->length);
-
-       status = usb_ep_queue(ep, req, GFP_ATOMIC);
-       if (status) {
-               struct zero_dev *dev = ep->driver_data;
-
-               ERROR(dev, "start %s --> %d\n", ep->name, status);
-               free_ep_req(ep, req);
-               req = NULL;
-       }
-
-       return req;
-}
-
-static int set_source_sink_config(struct zero_dev *dev)
-{
-       int                     result = 0;
-       struct usb_ep           *ep;
-       struct usb_gadget       *gadget = dev->gadget;
-
-       gadget_for_each_ep(ep, gadget) {
-               const struct usb_endpoint_descriptor    *d;
-
-               /* one endpoint writes (sources) zeroes in (to the host) */
-               if (strcmp(ep->name, EP_IN_NAME) == 0) {
-                       d = ep_desc(gadget, &hs_source_desc, &fs_source_desc);
-                       result = usb_ep_enable(ep, d);
-                       if (result == 0) {
-                               ep->driver_data = dev;
-                               if (source_sink_start_ep(ep) != NULL) {
-                                       dev->in_ep = ep;
-                                       continue;
-                               }
-                               usb_ep_disable(ep);
-                               result = -EIO;
-                       }
-
-               /* one endpoint reads (sinks) anything out (from the host) */
-               } else if (strcmp(ep->name, EP_OUT_NAME) == 0) {
-                       d = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc);
-                       result = usb_ep_enable(ep, d);
-                       if (result == 0) {
-                               ep->driver_data = dev;
-                               if (source_sink_start_ep(ep) != NULL) {
-                                       dev->out_ep = ep;
-                                       continue;
-                               }
-                               usb_ep_disable(ep);
-                               result = -EIO;
-                       }
-
-               /* ignore any other endpoints */
-               } else
-                       continue;
-
-               /* stop on error */
-               ERROR(dev, "can't start %s, result %d\n", ep->name, result);
-               break;
-       }
-       if (result == 0)
-               DBG(dev, "buflen %d\n", buflen);
-
-       /* caller is responsible for cleanup on error */
-       return result;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void loopback_complete(struct usb_ep *ep, struct usb_request *req)
-{
-       struct zero_dev *dev = ep->driver_data;
-       int             status = req->status;
-
-       switch (status) {
-
-       case 0:                         /* normal completion? */
-               if (ep == dev->out_ep) {
-                       /* loop this OUT packet back IN to the host */
-                       req->zero = (req->actual < req->length);
-                       req->length = req->actual;
-                       status = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC);
-                       if (status == 0)
-                               return;
-
-                       /* "should never get here" */
-                       ERROR(dev, "can't loop %s to %s: %d\n",
-                               ep->name, dev->in_ep->name,
-                               status);
-               }
-
-               /* queue the buffer for some later OUT packet */
-               req->length = buflen;
-               status = usb_ep_queue(dev->out_ep, req, GFP_ATOMIC);
-               if (status == 0)
-                       return;
-
-               /* "should never get here" */
-               /* FALLTHROUGH */
-
-       default:
-               ERROR(dev, "%s loop complete --> %d, %d/%d\n", ep->name,
-                               status, req->actual, req->length);
-               /* FALLTHROUGH */
-
-       /* NOTE:  since this driver doesn't maintain an explicit record
-        * of requests it submitted (just maintains qlen count), we
-        * rely on the hardware driver to clean up on disconnect or
-        * endpoint disable.
-        */
-       case -ECONNABORTED:             /* hardware forced ep reset */
-       case -ECONNRESET:               /* request dequeued */
-       case -ESHUTDOWN:                /* disconnect from host */
-               free_ep_req(ep, req);
-               return;
-       }
-}
-
-static int set_loopback_config(struct zero_dev *dev)
-{
-       int                     result = 0;
-       struct usb_ep           *ep;
-       struct usb_gadget       *gadget = dev->gadget;
-
-       gadget_for_each_ep(ep, gadget) {
-               const struct usb_endpoint_descriptor    *d;
-
-               /* one endpoint writes data back IN to the host */
-               if (strcmp(ep->name, EP_IN_NAME) == 0) {
-                       d = ep_desc(gadget, &hs_source_desc, &fs_source_desc);
-                       result = usb_ep_enable(ep, d);
-                       if (result == 0) {
-                               ep->driver_data = dev;
-                               dev->in_ep = ep;
-                               continue;
-                       }
-
-               /* one endpoint just reads OUT packets */
-               } else if (strcmp(ep->name, EP_OUT_NAME) == 0) {
-                       d = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc);
-                       result = usb_ep_enable(ep, d);
-                       if (result == 0) {
-                               ep->driver_data = dev;
-                               dev->out_ep = ep;
-                               continue;
-                       }
-
-               /* ignore any other endpoints */
-               } else
-                       continue;
-
-               /* stop on error */
-               ERROR(dev, "can't enable %s, result %d\n", ep->name, result);
-               break;
-       }
-
-       /* allocate a bunch of read buffers and queue them all at once.
-        * we buffer at most 'qlen' transfers; fewer if any need more
-        * than 'buflen' bytes each.
-        */
-       if (result == 0) {
-               struct usb_request      *req;
-               unsigned                i;
-
-               ep = dev->out_ep;
-               for (i = 0; i < qlen && result == 0; i++) {
-                       req = alloc_ep_req(ep, buflen);
-                       if (req) {
-                               req->complete = loopback_complete;
-                               result = usb_ep_queue(ep, req, GFP_ATOMIC);
-                               if (result)
-                                       DBG(dev, "%s queue req --> %d\n",
-                                                       ep->name, result);
-                       } else
-                               result = -ENOMEM;
-               }
-       }
-       if (result == 0)
-               DBG(dev, "qlen %d, buflen %d\n", qlen, buflen);
-
-       /* caller is responsible for cleanup on error */
-       return result;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void zero_reset_config(struct zero_dev *dev)
-{
-       if (dev->config == 0)
-               return;
-
-       DBG(dev, "reset config\n");
-
-       /* just disable endpoints, forcing completion of pending i/o.
-        * all our completion handlers free their requests in this case.
-        */
-       if (dev->in_ep) {
-               usb_ep_disable(dev->in_ep);
-               dev->in_ep = NULL;
-       }
-       if (dev->out_ep) {
-               usb_ep_disable(dev->out_ep);
-               dev->out_ep = NULL;
-       }
-       dev->config = 0;
-       del_timer(&dev->resume);
-}
-
-/* change our operational config.  this code must agree with the code
- * that returns config descriptors, and altsetting code.
- *
- * it's also responsible for power management interactions. some
- * configurations might not work with our current power sources.
- *
- * note that some device controller hardware will constrain what this
- * code can do, perhaps by disallowing more than one configuration or
- * by limiting configuration choices (like the pxa2xx).
- */
-static int zero_set_config(struct zero_dev *dev, unsigned number)
-{
-       int                     result = 0;
-       struct usb_gadget       *gadget = dev->gadget;
-
-       if (number == dev->config)
-               return 0;
-
-       if (gadget_is_sa1100(gadget) && dev->config) {
-               /* tx fifo is full, but we can't clear it...*/
-               ERROR(dev, "can't change configurations\n");
-               return -ESPIPE;
-       }
-       zero_reset_config(dev);
-
-       switch (number) {
-       case CONFIG_SOURCE_SINK:
-               result = set_source_sink_config(dev);
-               break;
-       case CONFIG_LOOPBACK:
-               result = set_loopback_config(dev);
-               break;
-       default:
-               result = -EINVAL;
-               /* FALL THROUGH */
-       case 0:
-               return result;
-       }
-
-       if (!result && (!dev->in_ep || !dev->out_ep))
-               result = -ENODEV;
-       if (result)
-               zero_reset_config(dev);
-       else {
-               char *speed;
-
-               switch (gadget->speed) {
-               case USB_SPEED_LOW:     speed = "low"; break;
-               case USB_SPEED_FULL:    speed = "full"; break;
-               case USB_SPEED_HIGH:    speed = "high"; break;
-               default:                speed = "?"; break;
-               }
-
-               dev->config = number;
-               INFO(dev, "%s speed config #%d: %s\n", speed, number,
-                               (number == CONFIG_SOURCE_SINK)
-                                       ? source_sink : loopback);
-       }
-       return result;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void zero_setup_complete(struct usb_ep *ep, struct usb_request *req)
-{
-       if (req->status || req->actual != req->length)
-               DBG((struct zero_dev *) ep->driver_data,
-                               "setup complete --> %d, %d/%d\n",
-                               req->status, req->actual, req->length);
-}
-
-/*
- * The setup() callback implements all the ep0 functionality that's
- * not handled lower down, in hardware or the hardware driver (like
- * device and endpoint feature flags, and their status).  It's all
- * housekeeping for the gadget function we're implementing.  Most of
- * the work is in config-specific setup.
- */
-static int
-zero_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
-{
-       struct zero_dev         *dev = get_gadget_data(gadget);
-       struct usb_request      *req = dev->req;
-       int                     value = -EOPNOTSUPP;
-       u16                     w_index = le16_to_cpu(ctrl->wIndex);
-       u16                     w_value = le16_to_cpu(ctrl->wValue);
-       u16                     w_length = le16_to_cpu(ctrl->wLength);
-
-       /* usually this stores reply data in the pre-allocated ep0 buffer,
-        * but config change events will reconfigure hardware.
-        */
-       req->zero = 0;
-       switch (ctrl->bRequest) {
-
-       case USB_REQ_GET_DESCRIPTOR:
-               if (ctrl->bRequestType != USB_DIR_IN)
-                       goto unknown;
-               switch (w_value >> 8) {
-
-               case USB_DT_DEVICE:
-                       value = min(w_length, (u16) sizeof device_desc);
-                       memcpy(req->buf, &device_desc, value);
-                       break;
-               case USB_DT_DEVICE_QUALIFIER:
-                       if (!gadget_is_dualspeed(gadget))
-                               break;
-                       value = min(w_length, (u16) sizeof dev_qualifier);
-                       memcpy(req->buf, &dev_qualifier, value);
-                       break;
-
-               case USB_DT_OTHER_SPEED_CONFIG:
-                       if (!gadget_is_dualspeed(gadget))
-                               break;
-                       // FALLTHROUGH
-               case USB_DT_CONFIG:
-                       value = config_buf(gadget, req->buf,
-                                       w_value >> 8,
-                                       w_value & 0xff);
-                       if (value >= 0)
-                               value = min(w_length, (u16) value);
-                       break;
-
-               case USB_DT_STRING:
-                       /* wIndex == language code.
-                        * this driver only handles one language, you can
-                        * add string tables for other languages, using
-                        * any UTF-8 characters
-                        */
-                       value = usb_gadget_get_string(&stringtab,
-                                       w_value & 0xff, req->buf);
-                       if (value >= 0)
-                               value = min(w_length, (u16) value);
-                       break;
-               }
-               break;
-
-       /* currently two configs, two speeds */
-       case USB_REQ_SET_CONFIGURATION:
-               if (ctrl->bRequestType != 0)
-                       goto unknown;
-               if (gadget->a_hnp_support)
-                       DBG(dev, "HNP available\n");
-               else if (gadget->a_alt_hnp_support)
-                       DBG(dev, "HNP needs a different root port\n");
-               else
-                       VDBG(dev, "HNP inactive\n");
-               spin_lock(&dev->lock);
-               value = zero_set_config(dev, w_value);
-               spin_unlock(&dev->lock);
-               break;
-       case USB_REQ_GET_CONFIGURATION:
-               if (ctrl->bRequestType != USB_DIR_IN)
-                       goto unknown;
-               *(u8 *)req->buf = dev->config;
-               value = min(w_length, (u16) 1);
-               break;
-
-       /* until we add altsetting support, or other interfaces,
-        * only 0/0 are possible.  pxa2xx only supports 0/0 (poorly)
-        * and already killed pending endpoint I/O.
-        */
-       case USB_REQ_SET_INTERFACE:
-               if (ctrl->bRequestType != USB_RECIP_INTERFACE)
-                       goto unknown;
-               spin_lock(&dev->lock);
-               if (dev->config && w_index == 0 && w_value == 0) {
-                       u8              config = dev->config;
-
-                       /* resets interface configuration, forgets about
-                        * previous transaction state (queued bufs, etc)
-                        * and re-inits endpoint state (toggle etc)
-                        * no response queued, just zero status == success.
-                        * if we had more than one interface we couldn't
-                        * use this "reset the config" shortcut.
-                        */
-                       zero_reset_config(dev);
-                       zero_set_config(dev, config);
-                       value = 0;
-               }
-               spin_unlock(&dev->lock);
-               break;
-       case USB_REQ_GET_INTERFACE:
-               if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE))
-                       goto unknown;
-               if (!dev->config)
-                       break;
-               if (w_index != 0) {
-                       value = -EDOM;
-                       break;
-               }
-               *(u8 *)req->buf = 0;
-               value = min(w_length, (u16) 1);
-               break;
-
-       /*
-        * These are the same vendor-specific requests supported by
-        * Intel's USB 2.0 compliance test devices.  We exceed that
-        * device spec by allowing multiple-packet requests.
-        */
-       case 0x5b:      /* control WRITE test -- fill the buffer */
-               if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR))
-                       goto unknown;
-               if (w_value || w_index)
-                       break;
-               /* just read that many bytes into the buffer */
-               if (w_length > USB_BUFSIZ)
-                       break;
-               value = w_length;
-               break;
-       case 0x5c:      /* control READ test -- return the buffer */
-               if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR))
-                       goto unknown;
-               if (w_value || w_index)
-                       break;
-               /* expect those bytes are still in the buffer; send back */
-               if (w_length > USB_BUFSIZ
-                               || w_length != req->length)
-                       break;
-               value = w_length;
-               break;
-
-       default:
-unknown:
-               VDBG(dev,
-                       "unknown control req%02x.%02x v%04x i%04x l%d\n",
-                       ctrl->bRequestType, ctrl->bRequest,
-                       w_value, w_index, w_length);
-       }
-
-       /* respond with data transfer before status phase? */
-       if (value >= 0) {
-               req->length = value;
-               req->zero = value < w_length;
-               value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
-               if (value < 0) {
-                       DBG(dev, "ep_queue --> %d\n", value);
-                       req->status = 0;
-                       zero_setup_complete(gadget->ep0, req);
-               }
-       }
-
-       /* device either stalls (value < 0) or reports success */
-       return value;
-}
-
-static void zero_disconnect(struct usb_gadget *gadget)
-{
-       struct zero_dev         *dev = get_gadget_data(gadget);
-       unsigned long           flags;
-
-       spin_lock_irqsave(&dev->lock, flags);
-       zero_reset_config(dev);
-
-       /* a more significant application might have some non-usb
-        * activities to quiesce here, saving resources like power
-        * or pushing the notification up a network stack.
-        */
-       spin_unlock_irqrestore(&dev->lock, flags);
-
-       /* next we may get setup() calls to enumerate new connections;
-        * or an unbind() during shutdown (including removing module).
-        */
-}
-
-static void zero_autoresume(unsigned long _dev)
-{
-       struct zero_dev *dev = (struct zero_dev *) _dev;
-       int             status;
-
-       /* normally the host would be woken up for something
-        * more significant than just a timer firing...
-        */
-       if (dev->gadget->speed != USB_SPEED_UNKNOWN) {
-               status = usb_gadget_wakeup(dev->gadget);
-               DBG(dev, "wakeup --> %d\n", status);
-       }
+       disable_ep(cdev, in);
+       disable_ep(cdev, out);
 }
 
 /*-------------------------------------------------------------------------*/
 
-static void zero_unbind(struct usb_gadget *gadget)
+static int __init zero_bind(struct usb_composite_dev *cdev)
 {
-       struct zero_dev         *dev = get_gadget_data(gadget);
-
-       DBG(dev, "unbind\n");
-
-       /* we've already been disconnected ... no i/o is active */
-       if (dev->req) {
-               dev->req->length = USB_BUFSIZ;
-               free_ep_req(gadget->ep0, dev->req);
-       }
-       del_timer_sync(&dev->resume);
-       kfree(dev);
-       set_gadget_data(gadget, NULL);
-}
-
-static int __init zero_bind(struct usb_gadget *gadget)
-{
-       struct zero_dev         *dev;
-       struct usb_ep           *ep;
        int                     gcnum;
+       struct usb_gadget       *gadget = cdev->gadget;
+       int                     id;
 
-       /* FIXME this can't yet work right with SH ... it has only
-        * one configuration, numbered one.
+       /* Allocate string descriptor numbers ... note that string
+        * contents can be overridden by the composite_dev glue.
         */
-       if (gadget_is_sh(gadget))
-               return -ENODEV;
-
-       /* Bulk-only drivers like this one SHOULD be able to
-        * autoconfigure on any sane usb controller driver,
-        * but there may also be important quirks to address.
+       id = usb_string_id(cdev);
+       if (id < 0)
+               return id;
+       strings_dev[STRING_MANUFACTURER_IDX].id = id;
+       device_desc.iManufacturer = id;
+
+       id = usb_string_id(cdev);
+       if (id < 0)
+               return id;
+       strings_dev[STRING_PRODUCT_IDX].id = id;
+       device_desc.iProduct = id;
+
+       id = usb_string_id(cdev);
+       if (id < 0)
+               return id;
+       strings_dev[STRING_SERIAL_IDX].id = id;
+       device_desc.iSerialNumber = id;
+
+       /* Register primary, then secondary configuration.  Note that
+        * SH3 only allows one config...
         */
-       usb_ep_autoconfig_reset(gadget);
-       ep = usb_ep_autoconfig(gadget, &fs_source_desc);
-       if (!ep) {
-autoconf_fail:
-               pr_err("%s: can't autoconfigure on %s\n",
-                       shortname, gadget->name);
-               return -ENODEV;
+       if (loopdefault) {
+               loopback_add(cdev);
+               if (!gadget_is_sh(gadget))
+                       sourcesink_add(cdev);
+       } else {
+               sourcesink_add(cdev);
+               if (!gadget_is_sh(gadget))
+                       loopback_add(cdev);
        }
-       EP_IN_NAME = ep->name;
-       ep->driver_data = ep;   /* claim */
-
-       ep = usb_ep_autoconfig(gadget, &fs_sink_desc);
-       if (!ep)
-               goto autoconf_fail;
-       EP_OUT_NAME = ep->name;
-       ep->driver_data = ep;   /* claim */
 
        gcnum = usb_gadget_controller_number(gadget);
        if (gcnum >= 0)
@@ -1115,144 +241,44 @@ autoconf_fail:
        else {
                /* gadget zero is so simple (for now, no altsettings) that
                 * it SHOULD NOT have problems with bulk-capable hardware.
-                * so warn about unrcognized controllers, don't panic.
+                * so just warn about unrcognized controllers -- don't panic.
                 *
                 * things like configuration and altsetting numbering
                 * can need hardware-specific attention though.
                 */
                pr_warning("%s: controller '%s' not recognized\n",
-                       shortname, gadget->name);
+                       longname, gadget->name);
                device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
        }
 
 
-       /* ok, we made sense of the hardware ... */
-       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-       if (!dev)
-               return -ENOMEM;
-       spin_lock_init(&dev->lock);
-       dev->gadget = gadget;
-       set_gadget_data(gadget, dev);
-
-       init_timer(&dev->resume);
-       dev->resume.function = zero_autoresume;
-       dev->resume.data = (unsigned long) dev;
-
-       /* preallocate control response and buffer */
-       dev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL);
-       if (!dev->req)
-               goto enomem;
-       dev->req->buf = kmalloc(USB_BUFSIZ, GFP_KERNEL);
-       if (!dev->req->buf)
-               goto enomem;
-
-       dev->req->complete = zero_setup_complete;
-
-       device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
-
-       if (gadget_is_dualspeed(gadget)) {
-               /* assume ep0 uses the same value for both speeds ... */
-               dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;
-
-               /* and that all endpoints are dual-speed */
-               hs_source_desc.bEndpointAddress =
-                               fs_source_desc.bEndpointAddress;
-               hs_sink_desc.bEndpointAddress =
-                               fs_sink_desc.bEndpointAddress;
-       }
-
-       if (gadget_is_otg(gadget)) {
-               otg_descriptor.bmAttributes |= USB_OTG_HNP,
-               source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
-               loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
-       }
-
-       usb_gadget_set_selfpowered(gadget);
-
-       if (autoresume) {
-               source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
-               loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
-       }
-
-       gadget->ep0->driver_data = dev;
-
-       INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname);
-       INFO(dev, "using %s, OUT %s IN %s\n", gadget->name,
-               EP_OUT_NAME, EP_IN_NAME);
+       INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname);
 
        snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
                init_utsname()->sysname, init_utsname()->release,
                gadget->name);
 
        return 0;
-
-enomem:
-       zero_unbind(gadget);
-       return -ENOMEM;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static void zero_suspend(struct usb_gadget *gadget)
-{
-       struct zero_dev         *dev = get_gadget_data(gadget);
-
-       if (gadget->speed == USB_SPEED_UNKNOWN)
-               return;
-
-       if (autoresume) {
-               mod_timer(&dev->resume, jiffies + (HZ * autoresume));
-               DBG(dev, "suspend, wakeup in %d seconds\n", autoresume);
-       } else
-               DBG(dev, "suspend\n");
-}
-
-static void zero_resume(struct usb_gadget *gadget)
-{
-       struct zero_dev         *dev = get_gadget_data(gadget);
-
-       DBG(dev, "resume\n");
-       del_timer(&dev->resume);
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static struct usb_gadget_driver zero_driver = {
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-       .speed          = USB_SPEED_HIGH,
-#else
-       .speed          = USB_SPEED_FULL,
-#endif
-       .function       = (char *) longname,
+static struct usb_composite_driver zero_driver = {
+       .name           = "zero",
+       .dev            = &device_desc,
+       .strings        = dev_strings,
        .bind           = zero_bind,
-       .unbind         = __exit_p(zero_unbind),
-
-       .setup          = zero_setup,
-       .disconnect     = zero_disconnect,
-
-       .suspend        = zero_suspend,
-       .resume         = zero_resume,
-
-       .driver         = {
-               .name           = (char *) shortname,
-               .owner          = THIS_MODULE,
-       },
 };
 
 MODULE_AUTHOR("David Brownell");
 MODULE_LICENSE("GPL");
 
-
 static int __init init(void)
 {
-       return usb_gadget_register_driver(&zero_driver);
+       return usb_composite_register(&zero_driver);
 }
 module_init(init);
 
 static void __exit cleanup(void)
 {
-       usb_gadget_unregister_driver(&zero_driver);
+       usb_composite_unregister(&zero_driver);
 }
 module_exit(cleanup);
-
index 08a4335401a9cf815f229b5a07bc3d4fd0a1ad76..bf69f473910785465c8c20ef4be46ea7acab2946 100644 (file)
 #define USB_MCFG_RDCOMB   (1<<30)
 #define USB_MCFG_SSDEN    (1<<23)
 #define USB_MCFG_PHYPLLEN (1<<19)
+#define USB_MCFG_UCECLKEN (1<<18)
 #define USB_MCFG_EHCCLKEN (1<<17)
+#ifdef CONFIG_DMA_COHERENT
 #define USB_MCFG_UCAM     (1<<7)
+#else
+#define USB_MCFG_UCAM     (0)
+#endif
 #define USB_MCFG_EBMEN    (1<<3)
 #define USB_MCFG_EMEMEN   (1<<2)
 
-#define USBH_ENABLE_CE    (USB_MCFG_PHYPLLEN | USB_MCFG_EHCCLKEN)
+#define USBH_ENABLE_CE (USB_MCFG_PHYPLLEN | USB_MCFG_EHCCLKEN)
+#define USBH_ENABLE_INIT (USB_MCFG_PFEN  | USB_MCFG_RDCOMB |   \
+                         USBH_ENABLE_CE | USB_MCFG_SSDEN  |    \
+                         USB_MCFG_UCAM  | USB_MCFG_EBMEN  |    \
+                         USB_MCFG_EMEMEN)
 
-#ifdef CONFIG_DMA_COHERENT
-#define USBH_ENABLE_INIT  (USBH_ENABLE_CE \
-                         | USB_MCFG_PFEN | USB_MCFG_RDCOMB \
-                         | USB_MCFG_SSDEN | USB_MCFG_UCAM \
-                         | USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
-#else
-#define USBH_ENABLE_INIT  (USBH_ENABLE_CE \
-                         | USB_MCFG_PFEN | USB_MCFG_RDCOMB \
-                         | USB_MCFG_SSDEN \
-                         | USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
-#endif
 #define USBH_DISABLE      (USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
 
 extern int usb_disabled(void);
 
-/*-------------------------------------------------------------------------*/
-
-static void au1xxx_start_ehc(struct platform_device *dev)
+static void au1xxx_start_ehc(void)
 {
-       pr_debug(__FILE__ ": starting Au1xxx EHCI USB Controller\n");
-
-       /* write HW defaults again in case Yamon cleared them */
-       if (au_readl(USB_HOST_CONFIG) == 0) {
-               au_writel(0x00d02000, USB_HOST_CONFIG);
-               au_readl(USB_HOST_CONFIG);
-               udelay(1000);
-       }
-       /* enable host controller */
-       au_writel(USBH_ENABLE_CE | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
-       au_readl(USB_HOST_CONFIG);
-       udelay(1000);
-       au_writel(USBH_ENABLE_INIT | au_readl(USB_HOST_CONFIG),
-                 USB_HOST_CONFIG);
-       au_readl(USB_HOST_CONFIG);
+       /* enable clock to EHCI block and HS PHY PLL*/
+       au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_CE, USB_HOST_CONFIG);
+       au_sync();
        udelay(1000);
 
-       pr_debug(__FILE__ ": Clock to USB host has been enabled\n");
+       /* enable EHCI mmio */
+       au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG);
+       au_sync();
+       udelay(1000);
 }
 
-static void au1xxx_stop_ehc(struct platform_device *dev)
+static void au1xxx_stop_ehc(void)
 {
-       pr_debug(__FILE__ ": stopping Au1xxx EHCI USB Controller\n");
+       unsigned long c;
 
        /* Disable mem */
-       au_writel(~USBH_DISABLE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
+       au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_DISABLE, USB_HOST_CONFIG);
+       au_sync();
        udelay(1000);
-       /* Disable clock */
-       au_writel(~USB_MCFG_EHCCLKEN & au_readl(USB_HOST_CONFIG),
-                 USB_HOST_CONFIG);
-       au_readl(USB_HOST_CONFIG);
+
+       /* Disable EHC clock. If the HS PHY is unused disable it too. */
+       c = au_readl(USB_HOST_CONFIG) & ~USB_MCFG_EHCCLKEN;
+       if (!(c & USB_MCFG_UCECLKEN))           /* UDC disabled? */
+               c &= ~USB_MCFG_PHYPLLEN;        /* yes: disable HS PHY PLL */
+       au_writel(c, USB_HOST_CONFIG);
+       au_sync();
 }
 
-/*-------------------------------------------------------------------------*/
+static const struct hc_driver ehci_au1xxx_hc_driver = {
+       .description            = hcd_name,
+       .product_desc           = "Au1xxx EHCI",
+       .hcd_priv_size          = sizeof(struct ehci_hcd),
+
+       /*
+        * generic hardware linkage
+        */
+       .irq                    = ehci_irq,
+       .flags                  = HCD_MEMORY | HCD_USB2,
+
+       /*
+        * basic lifecycle operations
+        *
+        * FIXME -- ehci_init() doesn't do enough here.
+        * See ehci-ppc-soc for a complete implementation.
+        */
+       .reset                  = ehci_init,
+       .start                  = ehci_run,
+       .stop                   = ehci_stop,
+       .shutdown               = ehci_shutdown,
 
-/* configure so an HC device and id are always provided */
-/* always called with process context; sleeping is OK */
+       /*
+        * managing i/o requests and associated device resources
+        */
+       .urb_enqueue            = ehci_urb_enqueue,
+       .urb_dequeue            = ehci_urb_dequeue,
+       .endpoint_disable       = ehci_endpoint_disable,
 
-/**
- * usb_ehci_au1xxx_probe - initialize Au1xxx-based HCDs
- * Context: !in_interrupt()
- *
- * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- *
- */
-int usb_ehci_au1xxx_probe(const struct hc_driver *driver,
-                         struct usb_hcd **hcd_out, struct platform_device *dev)
+       /*
+        * scheduling support
+        */
+       .get_frame_number       = ehci_get_frame,
+
+       /*
+        * root hub support
+        */
+       .hub_status_data        = ehci_hub_status_data,
+       .hub_control            = ehci_hub_control,
+       .bus_suspend            = ehci_bus_suspend,
+       .bus_resume             = ehci_bus_resume,
+       .relinquish_port        = ehci_relinquish_port,
+       .port_handed_over       = ehci_port_handed_over,
+};
+
+static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
 {
-       int retval;
        struct usb_hcd *hcd;
        struct ehci_hcd *ehci;
+       int ret;
 
-#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT)
+       if (usb_disabled())
+               return -ENODEV;
 
+#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT)
        /* Au1200 AB USB does not support coherent memory */
        if (!(read_c0_prid() & 0xff)) {
-               pr_info("%s: this is chip revision AB!\n", dev->name);
-               pr_info("%s: update your board or re-configure the kernel\n",
-                       dev->name);
+               printk(KERN_INFO "%s: this is chip revision AB!\n", pdev->name);
+               printk(KERN_INFO "%s: update your board or re-configure"
+                                " the kernel\n", pdev->name);
                return -ENODEV;
        }
 #endif
 
-       au1xxx_start_ehc(dev);
-
-       if (dev->resource[1].flags != IORESOURCE_IRQ) {
+       if (pdev->resource[1].flags != IORESOURCE_IRQ) {
                pr_debug("resource[1] is not IORESOURCE_IRQ");
-               retval = -ENOMEM;
+               return -ENOMEM;
        }
-       hcd = usb_create_hcd(driver, &dev->dev, "Au1xxx");
+       hcd = usb_create_hcd(&ehci_au1xxx_hc_driver, &pdev->dev, "Au1xxx");
        if (!hcd)
                return -ENOMEM;
-       hcd->rsrc_start = dev->resource[0].start;
-       hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
+
+       hcd->rsrc_start = pdev->resource[0].start;
+       hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
 
        if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
                pr_debug("request_mem_region failed");
-               retval = -EBUSY;
+               ret = -EBUSY;
                goto err1;
        }
 
        hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
        if (!hcd->regs) {
                pr_debug("ioremap failed");
-               retval = -ENOMEM;
+               ret = -ENOMEM;
                goto err2;
        }
 
+       au1xxx_start_ehc();
+
        ehci = hcd_to_ehci(hcd);
        ehci->caps = hcd->regs;
        ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase));
        /* cache this readonly data; minimize chip reads */
        ehci->hcs_params = readl(&ehci->caps->hcs_params);
 
-       /* ehci_hcd_init(hcd_to_ehci(hcd)); */
-
-       retval =
-           usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED | IRQF_SHARED);
-       if (retval == 0)
-               return retval;
+       ret = usb_add_hcd(hcd, pdev->resource[1].start,
+                         IRQF_DISABLED | IRQF_SHARED);
+       if (ret == 0) {
+               platform_set_drvdata(pdev, hcd);
+               return ret;
+       }
 
-       au1xxx_stop_ehc(dev);
+       au1xxx_stop_ehc();
        iounmap(hcd->regs);
 err2:
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 err1:
        usb_put_hcd(hcd);
-       return retval;
+       return ret;
 }
 
-/* may be called without controller electrically present */
-/* may be called with controller, bus, and devices active */
-
-/**
- * usb_ehci_hcd_au1xxx_remove - shutdown processing for Au1xxx-based HCDs
- * @dev: USB Host Controller being removed
- * Context: !in_interrupt()
- *
- * Reverses the effect of usb_ehci_hcd_au1xxx_probe(), first invoking
- * the HCD's stop() method.  It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
- *
- */
-void usb_ehci_au1xxx_remove(struct usb_hcd *hcd, struct platform_device *dev)
+static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
 {
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
        usb_remove_hcd(hcd);
        iounmap(hcd->regs);
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
        usb_put_hcd(hcd);
-       au1xxx_stop_ehc(dev);
+       au1xxx_stop_ehc();
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
 }
 
-/*-------------------------------------------------------------------------*/
+#ifdef CONFIG_PM
+static int ehci_hcd_au1xxx_drv_suspend(struct platform_device *pdev,
+                                       pm_message_t message)
+{
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+       unsigned long flags;
+       int rc;
 
-static const struct hc_driver ehci_au1xxx_hc_driver = {
-       .description = hcd_name,
-       .product_desc = "Au1xxx EHCI",
-       .hcd_priv_size = sizeof(struct ehci_hcd),
+       return 0;
+       rc = 0;
 
-       /*
-        * generic hardware linkage
-        */
-       .irq = ehci_irq,
-       .flags = HCD_MEMORY | HCD_USB2,
+       if (time_before(jiffies, ehci->next_statechange))
+               msleep(10);
 
-       /*
-        * basic lifecycle operations
+       /* Root hub was already suspended. Disable irq emission and
+        * mark HW unaccessible, bail out if RH has been resumed. Use
+        * the spinlock to properly synchronize with possible pending
+        * RH suspend or resume activity.
         *
-        * FIXME -- ehci_init() doesn't do enough here.
-        * See ehci-ppc-soc for a complete implementation.
-        */
-       .reset = ehci_init,
-       .start = ehci_run,
-       .stop = ehci_stop,
-       .shutdown = ehci_shutdown,
-
-       /*
-        * managing i/o requests and associated device resources
+        * This is still racy as hcd->state is manipulated outside of
+        * any locks =P But that will be a different fix.
         */
-       .urb_enqueue = ehci_urb_enqueue,
-       .urb_dequeue = ehci_urb_dequeue,
-       .endpoint_disable = ehci_endpoint_disable,
+       spin_lock_irqsave(&ehci->lock, flags);
+       if (hcd->state != HC_STATE_SUSPENDED) {
+               rc = -EINVAL;
+               goto bail;
+       }
+       ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+       (void)ehci_readl(ehci, &ehci->regs->intr_enable);
 
-       /*
-        * scheduling support
-        */
-       .get_frame_number = ehci_get_frame,
+       /* make sure snapshot being resumed re-enumerates everything */
+       if (message.event == PM_EVENT_PRETHAW) {
+               ehci_halt(ehci);
+               ehci_reset(ehci);
+       }
 
-       /*
-        * root hub support
-        */
-       .hub_status_data = ehci_hub_status_data,
-       .hub_control = ehci_hub_control,
-       .bus_suspend = ehci_bus_suspend,
-       .bus_resume = ehci_bus_resume,
-       .relinquish_port = ehci_relinquish_port,
-       .port_handed_over = ehci_port_handed_over,
-};
+       clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
-/*-------------------------------------------------------------------------*/
+       au1xxx_stop_ehc();
 
-static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
-{
-       struct usb_hcd *hcd = NULL;
-       int ret;
+bail:
+       spin_unlock_irqrestore(&ehci->lock, flags);
 
-       pr_debug("In ehci_hcd_au1xxx_drv_probe\n");
+       // could save FLADJ in case of Vaux power loss
+       // ... we'd only use it to handle clock skew
 
-       if (usb_disabled())
-               return -ENODEV;
-
-       /* FIXME we only want one one probe() not two */
-       ret = usb_ehci_au1xxx_probe(&ehci_au1xxx_hc_driver, &hcd, pdev);
-       return ret;
+       return rc;
 }
 
-static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
+
+static int ehci_hcd_au1xxx_drv_resume(struct platform_device *pdev)
 {
        struct usb_hcd *hcd = platform_get_drvdata(pdev);
+       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 
-       /* FIXME we only want one one remove() not two */
-       usb_ehci_au1xxx_remove(hcd, pdev);
-       return 0;
-}
+       au1xxx_start_ehc();
 
- /*TBD*/
-/*static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct usb_hcd *hcd = dev_get_drvdata(dev);
+       // maybe restore FLADJ
 
-       return 0;
-}
-static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct usb_hcd *hcd = dev_get_drvdata(dev);
+       if (time_before(jiffies, ehci->next_statechange))
+               msleep(100);
+
+       /* Mark hardware accessible again as we are out of D3 state by now */
+       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+       /* If CF is still set, we maintained PCI Vaux power.
+        * Just undo the effect of ehci_pci_suspend().
+        */
+       if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
+               int     mask = INTR_MASK;
+
+               if (!hcd->self.root_hub->do_remote_wakeup)
+                       mask &= ~STS_PCD;
+               ehci_writel(ehci, mask, &ehci->regs->intr_enable);
+               ehci_readl(ehci, &ehci->regs->intr_enable);
+               return 0;
+       }
+
+       ehci_dbg(ehci, "lost power, restarting\n");
+       usb_root_hub_lost_power(hcd->self.root_hub);
+
+       /* Else reset, to cope with power loss or flush-to-storage
+        * style "resume" having let BIOS kick in during reboot.
+        */
+       (void) ehci_halt(ehci);
+       (void) ehci_reset(ehci);
+
+       /* emptying the schedule aborts any urbs */
+       spin_lock_irq(&ehci->lock);
+       if (ehci->reclaim)
+               end_unlink_async(ehci);
+       ehci_work(ehci);
+       spin_unlock_irq(&ehci->lock);
+
+       ehci_writel(ehci, ehci->command, &ehci->regs->command);
+       ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
+       ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
+
+       /* here we "know" root ports should always stay powered */
+       ehci_port_power(ehci, 1);
+
+       hcd->state = HC_STATE_SUSPENDED;
 
        return 0;
 }
-*/
-MODULE_ALIAS("platform:au1xxx-ehci");
+
+#else
+#define ehci_hcd_au1xxx_drv_suspend NULL
+#define ehci_hcd_au1xxx_drv_resume NULL
+#endif
+
 static struct platform_driver ehci_hcd_au1xxx_driver = {
-       .probe = ehci_hcd_au1xxx_drv_probe,
-       .remove = ehci_hcd_au1xxx_drv_remove,
-       .shutdown = usb_hcd_platform_shutdown,
-       /*.suspend      = ehci_hcd_au1xxx_drv_suspend, */
-       /*.resume       = ehci_hcd_au1xxx_drv_resume, */
+       .probe          = ehci_hcd_au1xxx_drv_probe,
+       .remove         = ehci_hcd_au1xxx_drv_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
+       .suspend        = ehci_hcd_au1xxx_drv_suspend,
+       .resume         = ehci_hcd_au1xxx_drv_resume,
        .driver = {
-               .name = "au1xxx-ehci",
+               .name   = "au1xxx-ehci",
+               .owner  = THIS_MODULE,
        }
 };
+
+MODULE_ALIAS("platform:au1xxx-ehci");
index 0f82fdcaef096b65e384ab07312e7e001d211a56..b0f8ed5a7fb9dce367ad6d24feeea7fd5c8315c9 100644 (file)
@@ -676,7 +676,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
                        "%s\n"
                        "SUSPENDED (no register access)\n",
                        hcd->self.controller->bus->name,
-                       hcd->self.controller->bus_id,
+                       dev_name(hcd->self.controller),
                        hcd->product_desc);
                goto done;
        }
@@ -688,7 +688,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
                "%s\n"
                "EHCI %x.%02x, hcd state %d\n",
                hcd->self.controller->bus->name,
-               hcd->self.controller->bus_id,
+               dev_name(hcd->self.controller),
                hcd->product_desc,
                i >> 8, i & 0x0ff, hcd->state);
        size -= temp;
index 7370d6187c64620260850fefc18e2054838108c3..01c3da34f678e4a52107f64bca1674bb7e64c807 100644 (file)
@@ -56,7 +56,7 @@ int usb_hcd_fsl_probe(const struct hc_driver *driver,
        pdata = (struct fsl_usb2_platform_data *)pdev->dev.platform_data;
        if (!pdata) {
                dev_err(&pdev->dev,
-                       "No platform data for %s.\n", pdev->dev.bus_id);
+                       "No platform data for %s.\n", dev_name(&pdev->dev));
                return -ENODEV;
        }
 
@@ -69,7 +69,7 @@ int usb_hcd_fsl_probe(const struct hc_driver *driver,
              (pdata->operating_mode == FSL_USB2_DR_OTG))) {
                dev_err(&pdev->dev,
                        "Non Host Mode configured for %s. Wrong driver linked.\n",
-                       pdev->dev.bus_id);
+                       dev_name(&pdev->dev));
                return -ENODEV;
        }
 
@@ -77,12 +77,12 @@ int usb_hcd_fsl_probe(const struct hc_driver *driver,
        if (!res) {
                dev_err(&pdev->dev,
                        "Found HC with no IRQ. Check %s setup!\n",
-                       pdev->dev.bus_id);
+                       dev_name(&pdev->dev));
                return -ENODEV;
        }
        irq = res->start;
 
-       hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id);
+       hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
        if (!hcd) {
                retval = -ENOMEM;
                goto err1;
@@ -92,7 +92,7 @@ int usb_hcd_fsl_probe(const struct hc_driver *driver,
        if (!res) {
                dev_err(&pdev->dev,
                        "Found HC with no register addr. Check %s setup!\n",
-                       pdev->dev.bus_id);
+                       dev_name(&pdev->dev));
                retval = -ENODEV;
                goto err2;
        }
@@ -132,7 +132,7 @@ int usb_hcd_fsl_probe(const struct hc_driver *driver,
       err2:
        usb_put_hcd(hcd);
       err1:
-       dev_err(&pdev->dev, "init %s fail, %d\n", pdev->dev.bus_id, retval);
+       dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
        return retval;
 }
 
@@ -230,8 +230,13 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
 
        /* put controller in host mode. */
        ehci_writel(ehci, 0x00000003, non_ehci + FSL_SOC_USB_USBMODE);
+#ifdef CONFIG_PPC_85xx
+       out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008);
+       out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080);
+#else
        out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c);
        out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040);
+#endif
        out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
 }
 
index 369a8a5ea7bb374da2776dd3a02587b0f58b06fb..d9d53f289caf48b83001b42321e1bbaf9ca00886 100644 (file)
@@ -84,7 +84,7 @@ static const char     hcd_name [] = "ehci_hcd";
 #define EHCI_IAA_MSECS         10              /* arbitrary */
 #define EHCI_IO_JIFFIES                (HZ/10)         /* io watchdog > irq_thresh */
 #define EHCI_ASYNC_JIFFIES     (HZ/20)         /* async idle timeout */
-#define EHCI_SHRINK_JIFFIES    (HZ/200)        /* async qh unlink delay */
+#define EHCI_SHRINK_FRAMES     5               /* async qh unlink delay */
 
 /* Initial IRQ latency:  faster than hw default */
 static int log2_irq_thresh = 0;                // 0 to 6
index 9d042f220097c874286e5e2322fc7367418a3361..f9575c4091240ef364a4ca0b2d1bfac5099ccf25 100644 (file)
@@ -77,12 +77,12 @@ static int ixp4xx_ehci_probe(struct platform_device *pdev)
        if (!res) {
                dev_err(&pdev->dev,
                        "Found HC with no IRQ. Check %s setup!\n",
-                       pdev->dev.bus_id);
+                       dev_name(&pdev->dev));
                return -ENODEV;
        }
        irq = res->start;
 
-       hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id);
+       hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
        if (!hcd) {
                retval = -ENOMEM;
                goto fail_create_hcd;
@@ -92,7 +92,7 @@ static int ixp4xx_ehci_probe(struct platform_device *pdev)
        if (!res) {
                dev_err(&pdev->dev,
                        "Found HC with no register addr. Check %s setup!\n",
-                       pdev->dev.bus_id);
+                       dev_name(&pdev->dev));
                retval = -ENODEV;
                goto fail_request_resource;
        }
@@ -126,7 +126,7 @@ fail_ioremap:
 fail_request_resource:
        usb_put_hcd(hcd);
 fail_create_hcd:
-       dev_err(&pdev->dev, "init %s fail, %d\n", pdev->dev.bus_id, retval);
+       dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
        return retval;
 }
 
index ab625f0ba1d92da4fa26d4dcb4516ce2a4403ef7..5fbdc14e63b32d7d5f6df1ebf314df6bdbb35b5b 100644 (file)
@@ -204,7 +204,7 @@ static int __init ehci_orion_drv_probe(struct platform_device *pdev)
        if (irq <= 0) {
                dev_err(&pdev->dev,
                        "Found HC with no IRQ. Check %s setup!\n",
-                       pdev->dev.bus_id);
+                       dev_name(&pdev->dev));
                err = -ENODEV;
                goto err1;
        }
@@ -213,7 +213,7 @@ static int __init ehci_orion_drv_probe(struct platform_device *pdev)
        if (!res) {
                dev_err(&pdev->dev,
                        "Found HC with no register addr. Check %s setup!\n",
-                       pdev->dev.bus_id);
+                       dev_name(&pdev->dev));
                err = -ENODEV;
                goto err1;
        }
@@ -233,7 +233,7 @@ static int __init ehci_orion_drv_probe(struct platform_device *pdev)
        }
 
        hcd = usb_create_hcd(&ehci_orion_hc_driver,
-                       &pdev->dev, pdev->dev.bus_id);
+                       &pdev->dev, dev_name(&pdev->dev));
        if (!hcd) {
                err = -ENOMEM;
                goto err3;
@@ -276,7 +276,7 @@ err2:
        release_mem_region(res->start, res->end - res->start + 1);
 err1:
        dev_err(&pdev->dev, "init %s fail, %d\n",
-               pdev->dev.bus_id, err);
+               dev_name(&pdev->dev), err);
 
        return err;
 }
index 37e6abeb794c62026af0e23d6a5b914c9c250450..0eba894bcb017aa0706f5e60224149e76338d99a 100644 (file)
@@ -128,7 +128,7 @@ static int ps3_ehci_probe(struct ps3_system_bus_device *dev)
 
        dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */
 
-       hcd = usb_create_hcd(&ps3_ehci_hc_driver, &dev->core, dev->core.bus_id);
+       hcd = usb_create_hcd(&ps3_ehci_hc_driver, &dev->core, dev_name(&dev->core));
 
        if (!hcd) {
                dev_dbg(&dev->core, "%s:%d: usb_create_hcd failed\n", __func__,
index b85b54160cdaeade20792ad9878d9751606f3b50..2622b6596d7cc6283f6e0b34f2513826a25b0105 100644 (file)
@@ -1116,8 +1116,7 @@ static void scan_async (struct ehci_hcd *ehci)
        struct ehci_qh          *qh;
        enum ehci_timer_action  action = TIMER_IO_WATCHDOG;
 
-       if (!++(ehci->stamp))
-               ehci->stamp++;
+       ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index);
        timer_action_done (ehci, TIMER_ASYNC_SHRINK);
 rescan:
        qh = ehci->async->qh_next.qh;
@@ -1142,18 +1141,20 @@ rescan:
                                }
                        }
 
-                       /* unlink idle entries, reducing HC PCI usage as well
+                       /* unlink idle entries, reducing DMA usage as well
                         * as HCD schedule-scanning costs.  delay for any qh
                         * we just scanned, there's a not-unusual case that it
                         * doesn't stay idle for long.
                         * (plus, avoids some kind of re-activation race.)
                         */
-                       if (list_empty (&qh->qtd_list)) {
-                               if (qh->stamp == ehci->stamp)
+                       if (list_empty(&qh->qtd_list)
+                                       && qh->qh_state == QH_STATE_LINKED) {
+                               if (!ehci->reclaim
+                                       && ((ehci->stamp - qh->stamp) & 0x1fff)
+                                               >= (EHCI_SHRINK_FRAMES * 8))
+                                       start_unlink_async(ehci, qh);
+                               else
                                        action = TIMER_ASYNC_SHRINK;
-                               else if (!ehci->reclaim
-                                           && qh->qh_state == QH_STATE_LINKED)
-                                       start_unlink_async (ehci, qh);
                        }
 
                        qh = qh->qh_next.qh;
index 90245fd8bac4dd234390ec96e636570ef4e98c73..5799298364fb8dc1763f4530ca05ff99cec91b38 100644 (file)
@@ -198,7 +198,10 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
                        break;
                // case TIMER_ASYNC_SHRINK:
                default:
-                       t = EHCI_SHRINK_JIFFIES;
+                       /* add a jiffie since we synch against the
+                        * 8 KHz uframe counter.
+                        */
+                       t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
                        break;
                }
                mod_timer(&ehci->watchdog, t + jiffies);
index 20b9a0d07420d986f7dfc1e2edb9329a175083cc..31178e10cbbecca030561792a4ae97f457f877ed 100644 (file)
@@ -94,6 +94,10 @@ static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
        u16 w;
        int quot = len % 4;
 
+       /* buffer is already in 'usb data order', which is LE. */
+       /* When reading buffer as u16, we have to take care byte order */
+       /* doesn't get mixed up */
+
        if ((unsigned long)dp2 & 1) {
                /* not aligned */
                for (; len > 1; len -= 2) {
@@ -105,8 +109,11 @@ static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
                        isp116x_write_data16(isp116x, (u16) * dp);
        } else {
                /* aligned */
-               for (; len > 1; len -= 2)
-                       isp116x_raw_write_data16(isp116x, *dp2++);
+               for (; len > 1; len -= 2) {
+                       /* Keep byte order ! */
+                       isp116x_raw_write_data16(isp116x, cpu_to_le16(*dp2++));
+               }
+
                if (len)
                        isp116x_write_data16(isp116x, 0xff & *((u8 *) dp2));
        }
@@ -124,6 +131,10 @@ static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
        u16 w;
        int quot = len % 4;
 
+       /* buffer is already in 'usb data order', which is LE. */
+       /* When reading buffer as u16, we have to take care byte order */
+       /* doesn't get mixed up */
+
        if ((unsigned long)dp2 & 1) {
                /* not aligned */
                for (; len > 1; len -= 2) {
@@ -131,12 +142,16 @@ static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
                        *dp++ = w & 0xff;
                        *dp++ = (w >> 8) & 0xff;
                }
+
                if (len)
                        *dp = 0xff & isp116x_read_data16(isp116x);
        } else {
                /* aligned */
-               for (; len > 1; len -= 2)
-                       *dp2++ = isp116x_raw_read_data16(isp116x);
+               for (; len > 1; len -= 2) {
+                       /* Keep byte order! */
+                       *dp2++ = le16_to_cpu(isp116x_raw_read_data16(isp116x));
+               }
+
                if (len)
                        *(u8 *) dp2 = 0xff & isp116x_read_data16(isp116x);
        }
@@ -1592,7 +1607,7 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
        }
 
        /* allocate and initialize hcd */
-       hcd = usb_create_hcd(&isp116x_hc_driver, &pdev->dev, pdev->dev.bus_id);
+       hcd = usb_create_hcd(&isp116x_hc_driver, &pdev->dev, dev_name(&pdev->dev));
        if (!hcd) {
                ret = -ENOMEM;
                goto err5;
index 65aa5ecf569aca520473c59e4f86e5e5b7f63fb6..c858f2adb929904631746151469696c73b22cd22 100644 (file)
@@ -38,6 +38,7 @@ struct isp1760_hcd {
        unsigned                i_thresh;
        unsigned long           reset_done;
        unsigned long           next_statechange;
+       unsigned int            devflags;
 };
 
 static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd)
@@ -378,9 +379,31 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
 {
        struct isp1760_hcd *priv = hcd_to_priv(hcd);
        int result;
-       u32 scratch;
+       u32 scratch, hwmode;
+
+       /* Setup HW Mode Control: This assumes a level active-low interrupt */
+       hwmode = HW_DATA_BUS_32BIT;
+
+       if (priv->devflags & ISP1760_FLAG_BUS_WIDTH_16)
+               hwmode &= ~HW_DATA_BUS_32BIT;
+       if (priv->devflags & ISP1760_FLAG_ANALOG_OC)
+               hwmode |= HW_ANA_DIGI_OC;
+       if (priv->devflags & ISP1760_FLAG_DACK_POL_HIGH)
+               hwmode |= HW_DACK_POL_HIGH;
+       if (priv->devflags & ISP1760_FLAG_DREQ_POL_HIGH)
+               hwmode |= HW_DREQ_POL_HIGH;
+
+       /*
+        * We have to set this first in case we're in 16-bit mode.
+        * Write it twice to ensure correct upper bits if switching
+        * to 16-bit mode.
+        */
+       isp1760_writel(hwmode, hcd->regs + HC_HW_MODE_CTRL);
+       isp1760_writel(hwmode, hcd->regs + HC_HW_MODE_CTRL);
 
        isp1760_writel(0xdeadbabe, hcd->regs + HC_SCRATCH_REG);
+       /* Change bus pattern */
+       scratch = isp1760_readl(hcd->regs + HC_CHIP_ID_REG);
        scratch = isp1760_readl(hcd->regs + HC_SCRATCH_REG);
        if (scratch != 0xdeadbabe) {
                printk(KERN_ERR "ISP1760: Scratch test failed.\n");
@@ -403,17 +426,29 @@ static int isp1760_hc_setup(struct usb_hcd *hcd)
 
        /* Step 11 passed */
 
-       isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_REG);
-       isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_ENABLE);
+       isp1760_info(priv, "bus width: %d, oc: %s\n",
+                          (priv->devflags & ISP1760_FLAG_BUS_WIDTH_16) ?
+                          16 : 32, (priv->devflags & ISP1760_FLAG_ANALOG_OC) ?
+                          "analog" : "digital");
 
        /* ATL reset */
-       scratch = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL);
-       isp1760_writel(scratch | ALL_ATX_RESET, hcd->regs + HC_HW_MODE_CTRL);
+       isp1760_writel(hwmode | ALL_ATX_RESET, hcd->regs + HC_HW_MODE_CTRL);
        mdelay(10);
-       isp1760_writel(scratch, hcd->regs + HC_HW_MODE_CTRL);
+       isp1760_writel(hwmode, hcd->regs + HC_HW_MODE_CTRL);
 
-       isp1760_writel(PORT1_POWER | PORT1_INIT2, hcd->regs + HC_PORT1_CTRL);
-       mdelay(10);
+       isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_REG);
+       isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_ENABLE);
+
+       /*
+        * PORT 1 Control register of the ISP1760 is the OTG control
+        * register on ISP1761.
+        */
+       if (!(priv->devflags & ISP1760_FLAG_ISP1761) &&
+           !(priv->devflags & ISP1760_FLAG_PORT1_DIS)) {
+               isp1760_writel(PORT1_POWER | PORT1_INIT2,
+                              hcd->regs + HC_PORT1_CTRL);
+               mdelay(10);
+       }
 
        priv->hcs_params = isp1760_readl(hcd->regs + HC_HCSPARAMS);
 
@@ -453,8 +488,7 @@ static int isp1760_run(struct usb_hcd *hcd)
        hcd->state = HC_STATE_RUNNING;
        isp1760_enable_interrupts(hcd);
        temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL);
-       temp |= FINAL_HW_CONFIG;
-       isp1760_writel(temp, hcd->regs + HC_HW_MODE_CTRL);
+       isp1760_writel(temp | HW_GLOBAL_INTR_EN, hcd->regs + HC_HW_MODE_CTRL);
 
        command = isp1760_readl(hcd->regs + HC_USBCMD);
        command &= ~(CMD_LRESET|CMD_RESET);
@@ -782,8 +816,8 @@ static void enqueue_one_int_qtd(u32 int_regs, u32 payload,
        qtd->status |= slot << 16;
 }
 
-void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
-               struct isp1760_qtd *qtd)
+static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
+                                 struct isp1760_qtd *qtd)
 {
        struct isp1760_hcd *priv = hcd_to_priv(hcd);
        u32 skip_map, or_map;
@@ -816,8 +850,8 @@ void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
        isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG);
 }
 
-void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
-               struct isp1760_qtd *qtd)
+static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh,
+                                 struct isp1760_qtd *qtd)
 {
        struct isp1760_hcd *priv = hcd_to_priv(hcd);
        u32 skip_map, or_map;
@@ -1592,7 +1626,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
        struct inter_packet_info *ints;
        u32 i;
        u32 reg_base, or_reg, skip_reg;
-       int flags;
+       unsigned long flags;
        struct ptd ptd;
 
        switch (usb_pipetype(urb->pipe)) {
@@ -2061,7 +2095,7 @@ static void isp1760_endpoint_disable(struct usb_hcd *usb_hcd,
        struct isp1760_hcd *priv = hcd_to_priv(usb_hcd);
        struct isp1760_qh *qh;
        struct isp1760_qtd *qtd;
-       u32 flags;
+       unsigned long flags;
 
        spin_lock_irqsave(&priv->lock, flags);
        qh = ep->hcpriv;
@@ -2112,6 +2146,7 @@ static int isp1760_get_frame(struct usb_hcd *hcd)
 static void isp1760_stop(struct usb_hcd *hcd)
 {
        struct isp1760_hcd *priv = hcd_to_priv(hcd);
+       u32 temp;
 
        isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1,
                        NULL, 0);
@@ -2120,7 +2155,8 @@ static void isp1760_stop(struct usb_hcd *hcd)
        spin_lock_irq(&priv->lock);
        ehci_reset(priv);
        /* Disable IRQ */
-       isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL);
+       temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL);
+       isp1760_writel(temp &= ~HW_GLOBAL_INTR_EN, hcd->regs + HC_HW_MODE_CTRL);
        spin_unlock_irq(&priv->lock);
 
        isp1760_writel(0, hcd->regs + HC_CONFIGFLAG);
@@ -2128,10 +2164,11 @@ static void isp1760_stop(struct usb_hcd *hcd)
 
 static void isp1760_shutdown(struct usb_hcd *hcd)
 {
-       u32 command;
+       u32 command, temp;
 
        isp1760_stop(hcd);
-       isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL);
+       temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL);
+       isp1760_writel(temp &= ~HW_GLOBAL_INTR_EN, hcd->regs + HC_HW_MODE_CTRL);
 
        command = isp1760_readl(hcd->regs + HC_USBCMD);
        command &= ~CMD_RUN;
@@ -2183,7 +2220,8 @@ void deinit_kmem_cache(void)
 }
 
 struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
-               u64 irqflags, struct device *dev, const char *busname)
+               u64 irqflags, struct device *dev, const char *busname,
+               unsigned int devflags)
 {
        struct usb_hcd *hcd;
        struct isp1760_hcd *priv;
@@ -2195,11 +2233,12 @@ struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
        /* prevent usb-core allocating DMA pages */
        dev->dma_mask = NULL;
 
-       hcd = usb_create_hcd(&isp1760_hc_driver, dev, dev->bus_id);
+       hcd = usb_create_hcd(&isp1760_hc_driver, dev, dev_name(dev));
        if (!hcd)
                return ERR_PTR(-ENOMEM);
 
        priv = hcd_to_priv(hcd);
+       priv->devflags = devflags;
        init_memory(priv);
        hcd->regs = ioremap(res_start, res_len);
        if (!hcd->regs) {
index 3d86d0f6b1471346f33bb5c846c121f1f802a8f1..6473dd86993cb8d19b288dbdcae926e723c5f9c9 100644 (file)
@@ -3,7 +3,8 @@
 
 /* exports for if */
 struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq,
-               u64 irqflags, struct device *dev, const char *busname);
+               u64 irqflags, struct device *dev, const char *busname,
+               unsigned int devflags);
 int init_kmem_once(void);
 void deinit_kmem_cache(void);
 
@@ -31,6 +32,7 @@ void deinit_kmem_cache(void);
 /* Configuration Register */
 #define HC_HW_MODE_CTRL                0x300
 #define ALL_ATX_RESET          (1 << 31)
+#define HW_ANA_DIGI_OC         (1 << 15)
 #define HW_DATA_BUS_32BIT      (1 << 8)
 #define HW_DACK_POL_HIGH       (1 << 6)
 #define HW_DREQ_POL_HIGH       (1 << 5)
@@ -56,13 +58,14 @@ void deinit_kmem_cache(void);
 #define PORT1_POWER            (3 << 3)
 #define PORT1_INIT1            (1 << 7)
 #define PORT1_INIT2            (1 << 23)
+#define HW_OTG_CTRL_SET                0x374
+#define HW_OTG_CTRL_CLR                0x376
 
 /* Interrupt Register */
 #define HC_INTERRUPT_REG       0x310
 
 #define HC_INTERRUPT_ENABLE    0x314
 #define INTERRUPT_ENABLE_MASK  (HC_INTL_INT | HC_ATL_INT | HC_EOT_INT)
-#define FINAL_HW_CONFIG        (HW_GLOBAL_INTR_EN | HW_DATA_BUS_32BIT)
 
 #define HC_ISO_INT             (1 << 9)
 #define HC_ATL_INT             (1 << 8)
@@ -122,6 +125,19 @@ typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh,
 #define isp1760_err(priv, fmt, args...) \
        dev_err(priv_to_hcd(priv)->self.controller, fmt, ##args)
 
+/*
+ * Device flags that can vary from board to board.  All of these
+ * indicate the most "atypical" case, so that a devflags of 0 is
+ * a sane default configuration.
+ */
+#define ISP1760_FLAG_PORT1_DIS         0x00000001 /* Port 1 disabled */
+#define ISP1760_FLAG_BUS_WIDTH_16      0x00000002 /* 16-bit data bus width */
+#define ISP1760_FLAG_OTG_EN            0x00000004 /* Port 1 supports OTG */
+#define ISP1760_FLAG_ANALOG_OC         0x00000008 /* Analog overcurrent */
+#define ISP1760_FLAG_DACK_POL_HIGH     0x00000010 /* DACK active high */
+#define ISP1760_FLAG_DREQ_POL_HIGH     0x00000020 /* DREQ active high */
+#define ISP1760_FLAG_ISP1761           0x00000040 /* Chip is ISP1761 */
+
 /* chip memory management */
 struct memory_chunk {
        unsigned int start;
index c9db3fe98726472debc8741e0c14f790eb83e18b..051ef7b6bdc640f99e0e17f2079b3929e73cab6f 100644 (file)
@@ -35,13 +35,15 @@ static int of_isp1760_probe(struct of_device *dev,
        int virq;
        u64 res_len;
        int ret;
+       const unsigned int *prop;
+       unsigned int devflags = 0;
 
        ret = of_address_to_resource(dp, 0, &memory);
        if (ret)
                return -ENXIO;
 
        res = request_mem_region(memory.start, memory.end - memory.start + 1,
-                       dev->dev.bus_id);
+                       dev_name(&dev->dev));
        if (!res)
                return -EBUSY;
 
@@ -55,8 +57,32 @@ static int of_isp1760_probe(struct of_device *dev,
        virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
                        oirq.size);
 
+       if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
+               devflags |= ISP1760_FLAG_ISP1761;
+
+       if (of_get_property(dp, "port1-disable", NULL) != NULL)
+               devflags |= ISP1760_FLAG_PORT1_DIS;
+
+       /* Some systems wire up only 16 of the 32 data lines */
+       prop = of_get_property(dp, "bus-width", NULL);
+       if (prop && *prop == 16)
+               devflags |= ISP1760_FLAG_BUS_WIDTH_16;
+
+       if (of_get_property(dp, "port1-otg", NULL) != NULL)
+               devflags |= ISP1760_FLAG_OTG_EN;
+
+       if (of_get_property(dp, "analog-oc", NULL) != NULL)
+               devflags |= ISP1760_FLAG_ANALOG_OC;
+
+       if (of_get_property(dp, "dack-polarity", NULL) != NULL)
+               devflags |= ISP1760_FLAG_DACK_POL_HIGH;
+
+       if (of_get_property(dp, "dreq-polarity", NULL) != NULL)
+               devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
+
        hcd = isp1760_register(memory.start, res_len, virq,
-               IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev->dev.bus_id);
+               IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
+               devflags);
        if (IS_ERR(hcd)) {
                ret = PTR_ERR(hcd);
                goto release_reg;
@@ -87,6 +113,9 @@ static struct of_device_id of_isp1760_match[] = {
        {
                .compatible = "nxp,usb-isp1760",
        },
+       {
+               .compatible = "nxp,usb-isp1761",
+       },
        { },
 };
 MODULE_DEVICE_TABLE(of, of_isp1760_match);
@@ -116,6 +145,7 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
        int length;
        int status = 1;
        struct usb_hcd *hcd;
+       unsigned int devflags = 0;
 
        if (usb_disabled())
                return -ENODEV;
@@ -200,7 +230,8 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
 
        dev->dev.dma_mask = NULL;
        hcd = isp1760_register(pci_mem_phy0, length, dev->irq,
-               IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev->dev.bus_id);
+               IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
+               devflags);
        pci_set_drvdata(dev, hcd);
        if (!hcd)
                return 0;
index e534f9de0f05f9bbfc20c4f9938cb29c66a31f7a..a5d8e550d897e31f888bb398a62c7008dc54d16a 100644 (file)
@@ -91,7 +91,7 @@ static void at91_stop_hc(struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
+static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 
 /* configure so an HC device and id are always provided */
 /* always called with process context; sleeping is OK */
@@ -184,13 +184,14 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
  * context, "rmmod" or something similar.
  *
  */
-static int usb_hcd_at91_remove(struct usb_hcd *hcd,
+static void usb_hcd_at91_remove(struct usb_hcd *hcd,
                                struct platform_device *pdev)
 {
        usb_remove_hcd(hcd);
        at91_stop_hc(pdev);
        iounmap(hcd->regs);
        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+       usb_put_hcd(hcd);
 
        if (cpu_is_at91sam9261())
                clk_put(hclk);
@@ -199,7 +200,6 @@ static int usb_hcd_at91_remove(struct usb_hcd *hcd,
        fclk = iclk = hclk = NULL;
 
        dev_set_drvdata(&pdev->dev, NULL);
-       return 0;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -309,7 +309,8 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
        }
 
        device_init_wakeup(&pdev->dev, 0);
-       return usb_hcd_at91_remove(platform_get_drvdata(pdev), pdev);
+       usb_hcd_at91_remove(platform_get_drvdata(pdev), pdev);
+       return 0;
 }
 
 #ifdef CONFIG_PM
index 68c17f5ea8ea15c4ebfcc34e95ff4fb625978309..c0948008fe3d17c068c47d83b768b2e7fc365bff 100644 (file)
@@ -34,7 +34,8 @@
 #ifdef __LITTLE_ENDIAN
 #define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C)
 #elif __BIG_ENDIAN
-#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | USBH_ENABLE_BE)
+#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | \
+                         USBH_ENABLE_BE)
 #else
 #error not byte order defined
 #endif
 #define USB_MCFG_RDCOMB   (1<<30)
 #define USB_MCFG_SSDEN    (1<<23)
 #define USB_MCFG_OHCCLKEN (1<<16)
+#ifdef CONFIG_DMA_COHERENT
 #define USB_MCFG_UCAM     (1<<7)
+#else
+#define USB_MCFG_UCAM     (0)
+#endif
 #define USB_MCFG_OBMEN    (1<<1)
 #define USB_MCFG_OMEMEN   (1<<0)
 
 #define USBH_ENABLE_CE    USB_MCFG_OHCCLKEN
-#ifdef CONFIG_DMA_COHERENT
-#define USBH_ENABLE_INIT  (USB_MCFG_OHCCLKEN \
-                         | USB_MCFG_PFEN | USB_MCFG_RDCOMB \
-                         | USB_MCFG_SSDEN | USB_MCFG_UCAM \
-                         | USB_MCFG_OBMEN | USB_MCFG_OMEMEN)
-#else
-#define USBH_ENABLE_INIT  (USB_MCFG_OHCCLKEN \
-                         | USB_MCFG_PFEN | USB_MCFG_RDCOMB \
-                         | USB_MCFG_SSDEN \
-                         | USB_MCFG_OBMEN | USB_MCFG_OMEMEN)
-#endif
+
+#define USBH_ENABLE_INIT  (USB_MCFG_PFEN  | USB_MCFG_RDCOMB    |       \
+                          USBH_ENABLE_CE | USB_MCFG_SSDEN      |       \
+                          USB_MCFG_UCAM  |                             \
+                          USB_MCFG_OBMEN | USB_MCFG_OMEMEN)
+
 #define USBH_DISABLE      (USB_MCFG_OBMEN | USB_MCFG_OMEMEN)
 
 #endif  /* Au1200 */
 
 extern int usb_disabled(void);
 
-/*-------------------------------------------------------------------------*/
-
-static void au1xxx_start_ohc(struct platform_device *dev)
+static void au1xxx_start_ohc(void)
 {
-       printk(KERN_DEBUG __FILE__
-               ": starting Au1xxx OHCI USB Controller\n");
-
        /* enable host controller */
-
 #ifndef CONFIG_SOC_AU1200
-
        au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG);
+       au_sync();
        udelay(1000);
-       au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG);
-       udelay(1000);
-
-#else   /* Au1200 */
 
-       /* write HW defaults again in case Yamon cleared them */
-       if (au_readl(USB_HOST_CONFIG) == 0) {
-               au_writel(0x00d02000, USB_HOST_CONFIG);
-               au_readl(USB_HOST_CONFIG);
-               udelay(1000);
-       }
-       au_writel(USBH_ENABLE_CE | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
-       au_readl(USB_HOST_CONFIG);
+       au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG);
+       au_sync();
        udelay(1000);
-       au_writel(USBH_ENABLE_INIT | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
-       au_readl(USB_HOST_CONFIG);
-       udelay(1000);
-
-#endif  /* Au1200 */
 
-#ifndef CONFIG_SOC_AU1200
        /* wait for reset complete (read register twice; see au1500 errata) */
        while (au_readl(USB_HOST_CONFIG),
                !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD))
-#endif
                udelay(1000);
 
-       printk(KERN_DEBUG __FILE__
-       ": Clock to USB host has been enabled \n");
-}
-
-static void au1xxx_stop_ohc(struct platform_device *dev)
-{
-       printk(KERN_DEBUG __FILE__
-              ": stopping Au1xxx OHCI USB Controller\n");
-
-#ifndef CONFIG_SOC_AU1200
-
-       /* Disable clock */
-       au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
-
 #else   /* Au1200 */
-
-       /* Disable mem */
-       au_writel(~USBH_DISABLE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
+       au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_CE, USB_HOST_CONFIG);
+       au_sync();
        udelay(1000);
-       /* Disable clock */
-       au_writel(~USBH_ENABLE_CE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
-       au_readl(USB_HOST_CONFIG);
+
+       au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG);
+       au_sync();
+       udelay(2000);
 #endif  /* Au1200 */
 }
 
-
-/*-------------------------------------------------------------------------*/
-
-/* configure so an HC device and id are always provided */
-/* always called with process context; sleeping is OK */
-
-
-/**
- * usb_ohci_au1xxx_probe - initialize Au1xxx-based HCDs
- * Context: !in_interrupt()
- *
- * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- *
- */
-static int usb_ohci_au1xxx_probe(const struct hc_driver *driver,
-                         struct platform_device *dev)
+static void au1xxx_stop_ohc(void)
 {
-       int retval;
-       struct usb_hcd *hcd;
-
-#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT)
-       /* Au1200 AB USB does not support coherent memory */
-       if (!(read_c0_prid() & 0xff)) {
-               pr_info("%s: this is chip revision AB !!\n",
-                       dev->name);
-               pr_info("%s: update your board or re-configure the kernel\n",
-                       dev->name);
-               return -ENODEV;
-       }
+#ifdef CONFIG_SOC_AU1200
+       /* Disable mem */
+       au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_DISABLE, USB_HOST_CONFIG);
+       au_sync();
+       udelay(1000);
 #endif
-
-       if (dev->resource[1].flags != IORESOURCE_IRQ) {
-               pr_debug("resource[1] is not IORESOURCE_IRQ\n");
-               return -ENOMEM;
-       }
-
-       hcd = usb_create_hcd(driver, &dev->dev, "au1xxx");
-       if (!hcd)
-               return -ENOMEM;
-       hcd->rsrc_start = dev->resource[0].start;
-       hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
-
-       if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-               pr_debug("request_mem_region failed\n");
-               retval = -EBUSY;
-               goto err1;
-       }
-
-       hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
-       if (!hcd->regs) {
-               pr_debug("ioremap failed\n");
-               retval = -ENOMEM;
-               goto err2;
-       }
-
-       au1xxx_start_ohc(dev);
-       ohci_hcd_init(hcd_to_ohci(hcd));
-
-       retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED | IRQF_SHARED);
-       if (retval == 0)
-               return retval;
-
-       au1xxx_stop_ohc(dev);
-       iounmap(hcd->regs);
- err2:
-       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- err1:
-       usb_put_hcd(hcd);
-       return retval;
-}
-
-
-/* may be called without controller electrically present */
-/* may be called with controller, bus, and devices active */
-
-/**
- * usb_hcd_au1xxx_remove - shutdown processing for Au1xxx-based HCDs
- * @dev: USB Host Controller being removed
- * Context: !in_interrupt()
- *
- * Reverses the effect of usb_hcd_au1xxx_probe(), first invoking
- * the HCD's stop() method.  It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
- *
- */
-static void usb_ohci_au1xxx_remove(struct usb_hcd *hcd, struct platform_device *dev)
-{
-       usb_remove_hcd(hcd);
-       au1xxx_stop_ohc(dev);
-       iounmap(hcd->regs);
-       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-       usb_put_hcd(hcd);
+       /* Disable clock */
+       au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
+       au_sync();
 }
 
-/*-------------------------------------------------------------------------*/
-
-static int __devinit
-ohci_au1xxx_start (struct usb_hcd *hcd)
+static int __devinit ohci_au1xxx_start(struct usb_hcd *hcd)
 {
-       struct ohci_hcd *ohci = hcd_to_ohci (hcd);
-       int             ret;
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       int ret;
 
-       ohci_dbg (ohci, "ohci_au1xxx_start, ohci:%p", ohci);
+       ohci_dbg(ohci, "ohci_au1xxx_start, ohci:%p", ohci);
 
-       if ((ret = ohci_init (ohci)) < 0)
+       if ((ret = ohci_init(ohci)) < 0)
                return ret;
 
-       if ((ret = ohci_run (ohci)) < 0) {
+       if ((ret = ohci_run(ohci)) < 0) {
                err ("can't start %s", hcd->self.bus_name);
-               ohci_stop (hcd);
+               ohci_stop(hcd);
                return ret;
        }
 
        return 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static const struct hc_driver ohci_au1xxx_hc_driver = {
        .description =          hcd_name,
        .product_desc =         "Au1xxx OHCI",
@@ -296,18 +171,66 @@ static const struct hc_driver ohci_au1xxx_hc_driver = {
        .start_port_reset =     ohci_start_port_reset,
 };
 
-/*-------------------------------------------------------------------------*/
-
 static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
 {
        int ret;
-
-       pr_debug ("In ohci_hcd_au1xxx_drv_probe");
+       struct usb_hcd *hcd;
 
        if (usb_disabled())
                return -ENODEV;
 
-       ret = usb_ohci_au1xxx_probe(&ohci_au1xxx_hc_driver, pdev);
+#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT)
+       /* Au1200 AB USB does not support coherent memory */
+       if (!(read_c0_prid() & 0xff)) {
+               printk(KERN_INFO "%s: this is chip revision AB !!\n",
+                       pdev->name);
+               printk(KERN_INFO "%s: update your board or re-configure "
+                                "the kernel\n", pdev->name);
+               return -ENODEV;
+       }
+#endif
+
+       if (pdev->resource[1].flags != IORESOURCE_IRQ) {
+               pr_debug("resource[1] is not IORESOURCE_IRQ\n");
+               return -ENOMEM;
+       }
+
+       hcd = usb_create_hcd(&ohci_au1xxx_hc_driver, &pdev->dev, "au1xxx");
+       if (!hcd)
+               return -ENOMEM;
+
+       hcd->rsrc_start = pdev->resource[0].start;
+       hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
+
+       if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+               pr_debug("request_mem_region failed\n");
+               ret = -EBUSY;
+               goto err1;
+       }
+
+       hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+       if (!hcd->regs) {
+               pr_debug("ioremap failed\n");
+               ret = -ENOMEM;
+               goto err2;
+       }
+
+       au1xxx_start_ohc();
+       ohci_hcd_init(hcd_to_ohci(hcd));
+
+       ret = usb_add_hcd(hcd, pdev->resource[1].start,
+                         IRQF_DISABLED | IRQF_SHARED);
+       if (ret == 0) {
+               platform_set_drvdata(pdev, hcd);
+               return ret;
+       }
+
+       au1xxx_stop_ohc();
+       iounmap(hcd->regs);
+err2:
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err1:
+       usb_put_hcd(hcd);
        return ret;
 }
 
@@ -315,30 +238,78 @@ static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
 {
        struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
-       usb_ohci_au1xxx_remove(hcd, pdev);
+       usb_remove_hcd(hcd);
+       au1xxx_stop_ohc();
+       iounmap(hcd->regs);
+       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+       usb_put_hcd(hcd);
+       platform_set_drvdata(pdev, NULL);
+
        return 0;
 }
-       /*TBD*/
-/*static int ohci_hcd_au1xxx_drv_suspend(struct platform_device *dev)
+
+#ifdef CONFIG_PM
+static int ohci_hcd_au1xxx_drv_suspend(struct platform_device *pdev,
+                                       pm_message_t message)
 {
-       struct usb_hcd *hcd = platform_get_drvdata(dev);
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       unsigned long flags;
+       int rc;
+
+       rc = 0;
+
+       /* Root hub was already suspended. Disable irq emission and
+        * mark HW unaccessible, bail out if RH has been resumed. Use
+        * the spinlock to properly synchronize with possible pending
+        * RH suspend or resume activity.
+        *
+        * This is still racy as hcd->state is manipulated outside of
+        * any locks =P But that will be a different fix.
+        */
+       spin_lock_irqsave(&ohci->lock, flags);
+       if (hcd->state != HC_STATE_SUSPENDED) {
+               rc = -EINVAL;
+               goto bail;
+       }
+       ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
+       (void)ohci_readl(ohci, &ohci->regs->intrdisable);
 
-       return 0;
+       /* make sure snapshot being resumed re-enumerates everything */
+       if (message.event == PM_EVENT_PRETHAW)
+               ohci_usb_reset(ohci);
+
+       clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+       au1xxx_stop_ohc();
+bail:
+       spin_unlock_irqrestore(&ohci->lock, flags);
+
+       return rc;
 }
-static int ohci_hcd_au1xxx_drv_resume(struct platform_device *dev)
+
+static int ohci_hcd_au1xxx_drv_resume(struct platform_device *pdev)
 {
-       struct usb_hcd *hcd = platform_get_drvdata(dev);
+       struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+       au1xxx_start_ohc();
+
+       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+       ohci_finish_controller_resume(hcd);
 
        return 0;
 }
-*/
+#else
+#define ohci_hcd_au1xxx_drv_suspend NULL
+#define ohci_hcd_au1xxx_drv_resume NULL
+#endif
 
 static struct platform_driver ohci_hcd_au1xxx_driver = {
        .probe          = ohci_hcd_au1xxx_drv_probe,
        .remove         = ohci_hcd_au1xxx_drv_remove,
        .shutdown       = usb_hcd_platform_shutdown,
-       /*.suspend      = ohci_hcd_au1xxx_drv_suspend, */
-       /*.resume       = ohci_hcd_au1xxx_drv_resume, */
+       .suspend        = ohci_hcd_au1xxx_drv_suspend,
+       .resume         = ohci_hcd_au1xxx_drv_resume,
        .driver         = {
                .name   = "au1xxx-ohci",
                .owner  = THIS_MODULE,
index e06bfaebec5416d52e1510d472ebc62a219f52ed..7cef1d2f7cccc9417672e1fc77d209b978154a41 100644 (file)
@@ -651,7 +651,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
                "%s\n"
                "%s version " DRIVER_VERSION "\n",
                hcd->self.controller->bus->name,
-               hcd->self.controller->bus_id,
+               dev_name(hcd->self.controller),
                hcd->product_desc,
                hcd_name);
 
index a8160d65f32be3f3be08fc4f2813f7b2c5b3def6..26bc47941d0132f46badea48da3855daf7dedfff 100644 (file)
@@ -974,7 +974,7 @@ MODULE_LICENSE ("GPL");
 #define PCI_DRIVER             ohci_pci_driver
 #endif
 
-#ifdef CONFIG_SA1111
+#if defined(CONFIG_ARCH_SA1100) && defined(CONFIG_SA1111)
 #include "ohci-sa1111.c"
 #define SA1111_DRIVER          ohci_hcd_sa1111_driver
 #endif
index a19a4f80a6e1e02c70d0af713bde957e9cb408ce..6e5e5f81ac905b89ad50fe61317611c3ab3aa3cf 100644 (file)
@@ -329,7 +329,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
        }
 
 
-       hcd = usb_create_hcd (driver, &pdev->dev, pdev->dev.bus_id);
+       hcd = usb_create_hcd (driver, &pdev->dev, dev_name(&pdev->dev));
        if (!hcd) {
                retval = -ENOMEM;
                goto err0;
index 28b458f20cc3013749503821119e5e741e58a85f..6ad8f2fc57b92b819e873292c3c0bfe08141995b 100644 (file)
@@ -109,8 +109,6 @@ static struct clk *usb_clk;
 
 static int isp1301_probe(struct i2c_adapter *adap);
 static int isp1301_detach(struct i2c_client *client);
-static int isp1301_command(struct i2c_client *client, unsigned int cmd,
-                          void *arg);
 
 static const unsigned short normal_i2c[] =
     { ISP1301_I2C_ADDR, ISP1301_I2C_ADDR + 1, I2C_CLIENT_END };
@@ -123,30 +121,37 @@ static struct i2c_client_address_data addr_data = {
 };
 
 struct i2c_driver isp1301_driver = {
-       .class = I2C_CLASS_HWMON,
+       .driver = {
+               .name = "isp1301_pnx",
+       },
        .attach_adapter = isp1301_probe,
        .detach_client = isp1301_detach,
-       .command = isp1301_command
 };
 
 static int isp1301_attach(struct i2c_adapter *adap, int addr, int kind)
 {
        struct i2c_client *c;
+       int err;
 
        c = kzalloc(sizeof(*c), GFP_KERNEL);
-
        if (!c)
                return -ENOMEM;
 
-       strcpy(c->name, "isp1301");
+       strlcpy(c->name, "isp1301_pnx", I2C_NAME_SIZE);
        c->flags = 0;
        c->addr = addr;
        c->adapter = adap;
        c->driver = &isp1301_driver;
 
+       err = i2c_attach_client(c);
+       if (err) {
+               kfree(c);
+               return err;
+       }
+
        isp1301_i2c_client = c;
 
-       return i2c_attach_client(c);
+       return 0;
 }
 
 static int isp1301_probe(struct i2c_adapter *adap)
@@ -161,13 +166,6 @@ static int isp1301_detach(struct i2c_client *client)
        return 0;
 }
 
-/* No commands defined */
-static int isp1301_command(struct i2c_client *client, unsigned int cmd,
-                          void *arg)
-{
-       return 0;
-}
-
 static void i2c_write(u8 buf, u8 subaddr)
 {
        char tmpbuf[2];
@@ -389,7 +387,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
        while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) !=
               USB_CLOCK_MASK) ;
 
-       hcd = usb_create_hcd (driver, &pdev->dev, pdev->dev.bus_id);
+       hcd = usb_create_hcd (driver, &pdev->dev, dev_name(&pdev->dev));
        if (!hcd) {
                err("Failed to allocate HC buffer");
                ret = -ENOMEM;
index a6725279122315bf7566b255164d29c7f8130bbd..91e6e101a4cc987feae9591a4926f6a35aef95a0 100644 (file)
@@ -14,8 +14,8 @@
  */
 
 #include <linux/signal.h>
+#include <linux/of_platform.h>
 
-#include <asm/of_platform.h>
 #include <asm/prom.h>
 
 
index c1935ae537f80a90779d6eaea502dd4d02ee267d..55c95647f008d7eec7eb6991a6a5f19212f4fd59 100644 (file)
@@ -129,7 +129,7 @@ static int ps3_ohci_probe(struct ps3_system_bus_device *dev)
 
        dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */
 
-       hcd = usb_create_hcd(&ps3_ohci_hc_driver, &dev->core, dev->core.bus_id);
+       hcd = usb_create_hcd(&ps3_ohci_hc_driver, &dev->core, dev_name(&dev->core));
 
        if (!hcd) {
                dev_dbg(&dev->core, "%s:%d: usb_create_hcd failed\n", __func__,
index 9b547407c9342fd41b02700adda126c0382cd74e..6a9b4c5579536e161b596e824adccf3b81805922 100644 (file)
@@ -159,9 +159,6 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
 {
        int     branch;
 
-       if (ohci_to_hcd(ohci)->state == HC_STATE_QUIESCING)
-               return -EAGAIN;
-
        ed->state = ED_OPER;
        ed->ed_prev = NULL;
        ed->ed_next = NULL;
index e610698c6b60ca55eadf234599f3a3b254e5309b..21b164e4abebf8bc71d12611b4356bb97e038718 100644 (file)
@@ -143,7 +143,7 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev)
                goto err2;
        }
 
-       hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id);
+       hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
        if (!hcd) {
                retval = -ENOMEM;
                goto err2;
index 7275186db31556baf8278ec300da9d0d8600a98f..3660c83d80af44b269bfa9c32311846db1878105 100644 (file)
@@ -113,7 +113,7 @@ static int ssb_ohci_attach(struct ssb_device *dev)
        ssb_device_enable(dev, flags);
 
        hcd = usb_create_hcd(&ssb_ohci_hc_driver, dev->dev,
-                       dev->dev->bus_id);
+                       dev_name(dev->dev));
        if (!hcd)
                goto err_dev_disable;
        ohcidev = hcd_to_ssb_ohci(hcd);
index 16667342b3c324f694300c54d3d3532674c417c5..d5f02dddb1203ec31c151401aab80208388d1235 100644 (file)
@@ -312,9 +312,9 @@ static void put_child_connect_map(struct r8a66597 *r8a66597, int address)
 static void set_pipe_reg_addr(struct r8a66597_pipe *pipe, u8 dma_ch)
 {
        u16 pipenum = pipe->info.pipenum;
-       unsigned long fifoaddr[] = {D0FIFO, D1FIFO, CFIFO};
-       unsigned long fifosel[] = {D0FIFOSEL, D1FIFOSEL, CFIFOSEL};
-       unsigned long fifoctr[] = {D0FIFOCTR, D1FIFOCTR, CFIFOCTR};
+       const unsigned long fifoaddr[] = {D0FIFO, D1FIFO, CFIFO};
+       const unsigned long fifosel[] = {D0FIFOSEL, D1FIFOSEL, CFIFOSEL};
+       const unsigned long fifoctr[] = {D0FIFOCTR, D1FIFOCTR, CFIFOCTR};
 
        if (dma_ch > R8A66597_PIPE_NO_DMA)      /* dma fifo not use? */
                dma_ch = R8A66597_PIPE_NO_DMA;
@@ -863,6 +863,32 @@ static void disable_r8a66597_pipe_all(struct r8a66597 *r8a66597,
        dev->dma_map = 0;
 }
 
+static u16 get_interval(struct urb *urb, __u8 interval)
+{
+       u16 time = 1;
+       int i;
+
+       if (urb->dev->speed == USB_SPEED_HIGH) {
+               if (interval > IITV)
+                       time = IITV;
+               else
+                       time = interval ? interval - 1 : 0;
+       } else {
+               if (interval > 128) {
+                       time = IITV;
+               } else {
+                       /* calculate the nearest value for PIPEPERI */
+                       for (i = 0; i < 7; i++) {
+                               if ((1 << i) < interval &&
+                                   (1 << (i + 1) > interval))
+                                       time = 1 << i;
+                       }
+               }
+       }
+
+       return time;
+}
+
 static unsigned long get_timer_interval(struct urb *urb, __u8 interval)
 {
        __u8 i;
@@ -901,10 +927,7 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb,
                info.interval = 0;
                info.timer_interval = 0;
        } else {
-               if (ep->bInterval > IITV)
-                       info.interval = IITV;
-               else
-                       info.interval = ep->bInterval ? ep->bInterval - 1 : 0;
+               info.interval = get_interval(urb, ep->bInterval);
                info.timer_interval = get_timer_interval(urb, ep->bInterval);
        }
        if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
@@ -2244,6 +2267,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
        struct r8a66597 *r8a66597;
        int ret = 0;
        int i;
+       unsigned long irq_trigger;
 
        if (pdev->dev.dma_mask) {
                ret = -EINVAL;
@@ -2302,7 +2326,11 @@ static int __init r8a66597_probe(struct platform_device *pdev)
        INIT_LIST_HEAD(&r8a66597->child_device);
 
        hcd->rsrc_start = res->start;
-       ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+       if (irq_sense == INTL)
+               irq_trigger = IRQF_TRIGGER_LOW;
+       else
+               irq_trigger = IRQF_TRIGGER_FALLING;
+       ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger);
        if (ret != 0) {
                err("Failed to add hcd");
                goto clean_up;
index 426575247b23697265487a995e2551371f88361b..340d72da554ad8e545defea9778874de2f0ff5bb 100644 (file)
@@ -1674,7 +1674,7 @@ sl811h_probe(struct platform_device *dev)
        }
 
        /* allocate and initialize hcd */
-       hcd = usb_create_hcd(&sl811h_hc_driver, &dev->dev, dev->dev.bus_id);
+       hcd = usb_create_hcd(&sl811h_hc_driver, &dev->dev, dev_name(&dev->dev));
        if (!hcd) {
                retval = -ENOMEM;
                goto err5;
index 9b6323f768b242523495d352134f5533c423566d..20ad3c48fcb2966fb20e2bc36fc49971b239110b 100644 (file)
@@ -3124,7 +3124,7 @@ static int __devinit u132_probe(struct platform_device *pdev)
        if (pdev->dev.dma_mask)
                return -EINVAL;
 
-       hcd = usb_create_hcd(&u132_hc_driver, &pdev->dev, pdev->dev.bus_id);
+       hcd = usb_create_hcd(&u132_hc_driver, &pdev->dev, dev_name(&pdev->dev));
        if (!hcd) {
                printk(KERN_ERR "failed to create the usb hcd struct for U132\n"
                        );
index 8e4427aebb142e00d79b83e4624697b8d746ce33..885b585360b967f23661c015dd8945371f5fa058 100644 (file)
@@ -12,7 +12,7 @@
  * (C) Copyright 2004 Alan Stern, stern@rowland.harvard.edu
  */
 
-static __u8 root_hub_hub_des[] =
+static const __u8 root_hub_hub_des[] =
 {
        0x09,                   /*  __u8  bLength; */
        0x29,                   /*  __u8  bDescriptorType; Hub-descriptor */
index 093938697426c3d2209b73754fa4341b519d672f..d2f61d5510e780ddd1c21fe10deca4fc3dadc660 100644 (file)
@@ -1421,7 +1421,8 @@ ofail:    mutex_unlock(&cp->mutex);
 
 
 /* IOCTL functions */
-static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long auerchar_ioctl(struct file *file, unsigned int cmd,
+                                                       unsigned long arg)
 {
        pauerchar_t ccp = (pauerchar_t) file->private_data;
        int ret = 0;
@@ -1452,7 +1453,7 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int
                mutex_unlock(&ccp->mutex);
                 return -ENODEV;
        }
-
+       lock_kernel();
        switch (cmd) {
 
        /* return != 0 if Transmitt channel ready to send */
@@ -1547,9 +1548,10 @@ static int auerchar_ioctl (struct inode *inode, struct file *file, unsigned int
 
        default:
                dbg ("IOCTL_AU_UNKNOWN");
-               ret = -ENOIOCTLCMD;
+               ret = -ENOTTY;
                break;
         }
+        unlock_kernel();
        /* release the mutexes */
        mutex_unlock(&cp->mutex);
        mutex_unlock(&ccp->mutex);
@@ -1860,7 +1862,7 @@ static const struct file_operations auerswald_fops =
        .llseek =       no_llseek,
        .read =         auerchar_read,
        .write =        auerchar_write,
-       .ioctl =        auerchar_ioctl,
+       .unlocked_ioctl = auerchar_ioctl,
        .open =         auerchar_open,
        .release =      auerchar_release,
 };
index 20886c21e7397b7cc5d2ea121399dd761e2bd773..5d859ded5bbf4dbb19ed0b2cd6ab89035015d92c 100644 (file)
@@ -6,8 +6,6 @@
  * This program is free software; 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.
- * 
- * $Id: emi62.c,v 1.15 2002/04/23 06:13:59 tapio Exp $
  */
 #include <linux/kernel.h>
 #include <linux/errno.h>
index ec88b3bfee465cfa9b18633345cfd075c93355a1..97c280971532b5f72c396e6ca70752126e8e30b3 100644 (file)
@@ -656,29 +656,6 @@ static int ftdi_elan_release(struct inode *inode, struct file *file)
 }
 
 
-#define FTDI_ELAN_IOC_MAGIC 0xA1
-#define FTDI_ELAN_IOCDEBUG _IOC(_IOC_WRITE, FTDI_ELAN_IOC_MAGIC, 1, 132)
-static int ftdi_elan_ioctl(struct inode *inode, struct file *file,
-        unsigned int cmd, unsigned long arg)
-{
-        switch (cmd) {
-        case FTDI_ELAN_IOCDEBUG:{
-                        char line[132];
-                        int size = strncpy_from_user(line,
-                                (const char __user *)arg, sizeof(line));
-                        if (size < 0) {
-                                return -EINVAL;
-                        } else {
-                                printk(KERN_ERR "TODO: ioctl %s\n", line);
-                                return 0;
-                        }
-                }
-        default:
-                return -EFAULT;
-        }
-}
-
-
 /*
 *
 * blocking bulk reads are used to get data from the device
@@ -1222,7 +1199,6 @@ error_1:
 static const struct file_operations ftdi_elan_fops = {
         .owner = THIS_MODULE,
         .llseek = no_llseek,
-        .ioctl = ftdi_elan_ioctl,
         .read = ftdi_elan_read,
         .write = ftdi_elan_write,
         .open = ftdi_elan_open,
index 1cb54a28347f0fe332363df6c3dcac7d11770573..e6ca9979e3ae5eece2a693207f2e7426ca8fc1dc 100644 (file)
@@ -474,8 +474,8 @@ exit:
 /**
  *     iowarrior_ioctl
  */
-static int iowarrior_ioctl(struct inode *inode, struct file *file,
-                          unsigned int cmd, unsigned long arg)
+static long iowarrior_ioctl(struct file *file, unsigned int cmd,
+                                                       unsigned long arg)
 {
        struct iowarrior *dev = NULL;
        __u8 *buffer;
@@ -493,6 +493,7 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file,
                return -ENOMEM;
 
        /* lock this object */
+       lock_kernel();
        mutex_lock(&dev->mutex);
 
        /* verify that the device wasn't unplugged */
@@ -584,6 +585,7 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file,
 error_out:
        /* unlock the device */
        mutex_unlock(&dev->mutex);
+       unlock_kernel();
        kfree(buffer);
        return retval;
 }
@@ -719,7 +721,7 @@ static const struct file_operations iowarrior_fops = {
        .owner = THIS_MODULE,
        .write = iowarrior_write,
        .read = iowarrior_read,
-       .ioctl = iowarrior_ioctl,
+       .unlocked_ioctl = iowarrior_ioctl,
        .open = iowarrior_open,
        .release = iowarrior_release,
        .poll = iowarrior_poll,
index 330c18e390b8f101ef45ad38ec5a283d20e42f7e..248a12aacef6e7dfd5da9fbaa4a6745328d9a287 100644 (file)
@@ -104,9 +104,7 @@ static int close_rio(struct inode *inode, struct file *file)
        return 0;
 }
 
-static int
-ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
-         unsigned long arg)
+static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct RioCommand rio_cmd;
        struct rio_usb_data *rio = &rio_instance;
@@ -116,6 +114,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
        int retries;
        int retval=0;
 
+       lock_kernel();
        mutex_lock(&(rio->lock));
         /* Sanity check to make sure rio is connected, powered, etc */
         if (rio->present == 0 || rio->rio_dev == NULL) {
@@ -254,6 +253,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
 
 err_out:
        mutex_unlock(&(rio->lock));
+       unlock_kernel();
        return retval;
 }
 
@@ -433,7 +433,7 @@ file_operations usb_rio_fops = {
        .owner =        THIS_MODULE,
        .read =         read_rio,
        .write =        write_rio,
-       .ioctl =        ioctl_rio,
+       .unlocked_ioctl = ioctl_rio,
        .open =         open_rio,
        .release =      close_rio,
 };
index 33182f4c2267ad69ddab0106e76cf39e2bff8436..fbace41a7cba4418dc8602f70eae8614b0db33c7 100644 (file)
@@ -2982,9 +2982,8 @@ sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y,
        return retval;
 }
 
-static int
-sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-                                                       unsigned long arg)
+static long
+sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct sisusb_usb_data *sisusb;
        struct sisusb_info x;
@@ -2995,6 +2994,7 @@ sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        if (!(sisusb = (struct sisusb_usb_data *)file->private_data))
                return -ENODEV;
 
+       lock_kernel();
        mutex_lock(&sisusb->lock);
 
        /* Sanity check */
@@ -3053,6 +3053,7 @@ sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
 err_out:
        mutex_unlock(&sisusb->lock);
+       unlock_kernel();
        return retval;
 }
 
@@ -3066,9 +3067,7 @@ sisusb_compat_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
                case SISUSB_GET_CONFIG_SIZE:
                case SISUSB_GET_CONFIG:
                case SISUSB_COMMAND:
-                       lock_kernel();
-                       retval = sisusb_ioctl(f->f_path.dentry->d_inode, f, cmd, arg);
-                       unlock_kernel();
+                       retval = sisusb_ioctl(f, cmd, arg);
                        return retval;
 
                default:
@@ -3087,7 +3086,7 @@ static const struct file_operations usb_sisusb_fops = {
 #ifdef SISUSB_NEW_CONFIG_COMPAT
        .compat_ioctl = sisusb_compat_ioctl,
 #endif
-       .ioctl =        sisusb_ioctl
+       .unlocked_ioctl = sisusb_ioctl
 };
 
 static struct usb_class_driver usb_sisusb_class = {
index 7f7021ee4189f4604ae971eec82dfe17a65267ce..2db4228fbb016bce9548e899bad64a17dc428f7e 100644 (file)
@@ -146,7 +146,7 @@ static ssize_t lcd_read(struct file *file, char __user * buffer, size_t count, l
        return retval;
 }
 
-static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long lcd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct usb_lcd *dev;
        u16 bcdDevice;
@@ -158,12 +158,14 @@ static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
        
        switch (cmd) {
        case IOCTL_GET_HARD_VERSION:
+               lock_kernel();
                bcdDevice = le16_to_cpu((dev->udev)->descriptor.bcdDevice);
                sprintf(buf,"%1d%1d.%1d%1d",
                        (bcdDevice & 0xF000)>>12,
                        (bcdDevice & 0xF00)>>8,
                        (bcdDevice & 0xF0)>>4,
                        (bcdDevice & 0xF));
+               unlock_kernel();
                if (copy_to_user((void __user *)arg,buf,strlen(buf))!=0)
                        return -EFAULT;
                break;
@@ -272,7 +274,7 @@ static const struct file_operations lcd_fops = {
         .read =         lcd_read,
         .write =        lcd_write,
         .open =         lcd_open,
-       .ioctl =        lcd_ioctl,
+       .unlocked_ioctl = lcd_ioctl,
         .release =      lcd_release,
 };
 
index 293a46247c3b3bc8e4c731ca45fac0493d526778..6566fc0a322853a50b8f212d6b82df868da9b4d5 100644 (file)
@@ -1162,8 +1162,9 @@ int mon_bin_add(struct mon_bus *mbus, const struct usb_bus *ubus)
        if (minor >= MON_BIN_MAX_MINOR)
                return 0;
 
-       dev = device_create(mon_bin_class, ubus? ubus->controller: NULL,
-                       MKDEV(MAJOR(mon_bin_dev0), minor), "usbmon%d", minor);
+       dev = device_create_drvdata(mon_bin_class, ubus? ubus->controller: NULL,
+                                   MKDEV(MAJOR(mon_bin_dev0), minor), NULL,
+                                   "usbmon%d", minor);
        if (IS_ERR(dev))
                return 0;
 
index c7a595cd648ae2b2f473390b94d0f89b0fb2214f..ac8b0d5ce7f852c663dca9af9fbb8dc389348591 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/usb.h>
+#include <linux/fs.h>
 #include <asm/uaccess.h>
 
 #include "usb_mon.h"
@@ -42,19 +43,8 @@ static ssize_t mon_stat_read(struct file *file, char __user *buf,
                                size_t nbytes, loff_t *ppos)
 {
        struct snap *sp = file->private_data;
-       loff_t pos = *ppos;
-       int cnt;
 
-       if (pos < 0 || pos >= sp->slen)
-               return 0;
-       if (nbytes == 0)
-               return 0;
-       if ((cnt = sp->slen - pos) > nbytes)
-               cnt = nbytes;
-       if (copy_to_user(buf, sp->str + pos, cnt))
-               return -EFAULT;
-       *ppos = pos + cnt;
-       return cnt;
+       return simple_read_from_buffer(buf, nbytes, ppos, sp->str, sp->slen);
 }
 
 static int mon_stat_release(struct inode *inode, struct file *file)
index 9a7681b55266979521135b403884c4c03f16d82d..8878c1767fc88aedbcbb1e3035c0c7edf30af304 100644 (file)
@@ -64,14 +64,6 @@ config USB_SERIAL_AIRCABLE
            To compile this driver as a module, choose M here: the module
            will be called aircable.
 
-config USB_SERIAL_AIRPRIME
-       tristate "USB AirPrime CDMA Wireless Driver"
-       help
-         Say Y here if you want to use a AirPrime CDMA Wireless PC card.
-
-         To compile this driver as a module, choose M here: the
-         module will be called airprime.
-
 config USB_SERIAL_ARK3116
        tristate "USB ARK Micro 3116 USB Serial Driver"
        help
index 17a762ab67697b0b04cc943af8e673fff6e3cc5e..6047f818adfeb70501f72bd2536d23e6fbd8d895 100644 (file)
@@ -12,7 +12,6 @@ usbserial-obj-$(CONFIG_USB_EZUSB)             += ezusb.o
 usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y)
 
 obj-$(CONFIG_USB_SERIAL_AIRCABLE)              += aircable.o
-obj-$(CONFIG_USB_SERIAL_AIRPRIME)              += airprime.o
 obj-$(CONFIG_USB_SERIAL_ARK3116)               += ark3116.o
 obj-$(CONFIG_USB_SERIAL_BELKIN)                        += belkin_sa.o
 obj-$(CONFIG_USB_SERIAL_CH341)                 += ch341.o
index db6f97a93c02c3b813e8feafd17ba6cb2acb1efc..79ea98c66fa8d8c1f91ef2b045e9fc19d52375de 100644 (file)
@@ -272,7 +272,7 @@ static void aircable_read(struct work_struct *work)
         * 64 bytes, to ensure I do not get throttled.
         * Ask USB mailing list for better aproach.
         */
-       tty = port->tty;
+       tty = port->port.tty;
 
        if (!tty) {
                schedule_work(&priv->rx_work);
@@ -378,13 +378,14 @@ static void aircable_shutdown(struct usb_serial *serial)
        }
 }
 
-static int aircable_write_room(struct usb_serial_port *port)
+static int aircable_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct aircable_private *priv = usb_get_serial_port_data(port);
        return serial_buf_data_avail(priv->tx_buf);
 }
 
-static int aircable_write(struct usb_serial_port *port,
+static int aircable_write(struct tty_struct *tty, struct usb_serial_port *port,
                          const unsigned char *source, int count)
 {
        struct aircable_private *priv = usb_get_serial_port_data(port);
@@ -466,7 +467,7 @@ static void aircable_read_bulk_callback(struct urb *urb)
 
        if (status) {
                dbg("%s - urb status = %d", __func__, status);
-               if (!port->open_count) {
+               if (!port->port.count) {
                        dbg("%s - port is closed, exiting.", __func__);
                        return;
                }
@@ -494,7 +495,7 @@ static void aircable_read_bulk_callback(struct urb *urb)
        usb_serial_debug_data(debug, &port->dev, __func__,
                                urb->actual_length, urb->transfer_buffer);
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (tty && urb->actual_length) {
                if (urb->actual_length <= 2) {
                        /* This is an incomplete package */
@@ -528,7 +529,7 @@ static void aircable_read_bulk_callback(struct urb *urb)
        }
 
        /* Schedule the next read _if_ we are still open */
-       if (port->open_count) {
+       if (port->port.count) {
                usb_fill_bulk_urb(port->read_urb, port->serial->dev,
                                  usb_rcvbulkpipe(port->serial->dev,
                                          port->bulk_in_endpointAddress),
@@ -547,8 +548,9 @@ static void aircable_read_bulk_callback(struct urb *urb)
 }
 
 /* Based on ftdi_sio.c throttle */
-static void aircable_throttle(struct usb_serial_port *port)
+static void aircable_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct aircable_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
 
@@ -560,8 +562,9 @@ static void aircable_throttle(struct usb_serial_port *port)
 }
 
 /* Based on ftdi_sio.c unthrottle */
-static void aircable_unthrottle(struct usb_serial_port *port)
+static void aircable_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct aircable_private *priv = usb_get_serial_port_data(port);
        int actually_throttled;
        unsigned long flags;
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
deleted file mode 100644 (file)
index 0798c14..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * AirPrime CDMA Wireless Serial USB driver
- *
- * Copyright (C) 2005-2006 Greg Kroah-Hartman <gregkh@suse.de>
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License version
- *     2 as published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-#include <linux/usb/serial.h>
-
-static struct usb_device_id id_table [] = {
-       { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
-       { },
-};
-MODULE_DEVICE_TABLE(usb, id_table);
-
-#define URB_TRANSFER_BUFFER_SIZE       4096
-#define NUM_READ_URBS                  4
-#define NUM_WRITE_URBS                 4
-#define NUM_BULK_EPS                   3
-#define MAX_BULK_EPS                   6
-
-/* if overridden by the user, then use their value for the size of the
- * read and write urbs, and the number of endpoints */
-static int buffer_size = URB_TRANSFER_BUFFER_SIZE;
-static int endpoints = NUM_BULK_EPS;
-static int debug;
-struct airprime_private {
-       spinlock_t lock;
-       int outstanding_urbs;
-       int throttled;
-       struct urb *read_urbp[NUM_READ_URBS];
-
-       /* Settings for the port */
-       int rts_state;  /* Handshaking pins (outputs) */
-       int dtr_state;
-       int cts_state;  /* Handshaking pins (inputs) */
-       int dsr_state;
-       int dcd_state;
-       int ri_state;
-};
-
-static int airprime_send_setup(struct usb_serial_port *port)
-{
-       struct usb_serial *serial = port->serial;
-       struct airprime_private *priv;
-
-       dbg("%s", __func__);
-
-       if (port->number != 0)
-               return 0;
-
-       priv = usb_get_serial_port_data(port);
-
-       if (port->tty) {
-               int val = 0;
-               if (priv->dtr_state)
-                       val |= 0x01;
-               if (priv->rts_state)
-                       val |= 0x02;
-
-               return usb_control_msg(serial->dev,
-                                       usb_rcvctrlpipe(serial->dev, 0),
-                                       0x22, 0x21, val, 0, NULL, 0,
-                                       USB_CTRL_SET_TIMEOUT);
-       }
-
-       return 0;
-}
-
-static void airprime_read_bulk_callback(struct urb *urb)
-{
-       struct usb_serial_port *port = urb->context;
-       unsigned char *data = urb->transfer_buffer;
-       struct tty_struct *tty;
-       int result;
-       int status = urb->status;
-
-       dbg("%s - port %d", __func__, port->number);
-
-       if (status) {
-               dbg("%s - nonzero read bulk status received: %d",
-                   __func__, status);
-               return;
-       }
-       usb_serial_debug_data(debug, &port->dev, __func__,
-                                               urb->actual_length, data);
-
-       tty = port->tty;
-       if (tty && urb->actual_length) {
-               tty_insert_flip_string(tty, data, urb->actual_length);
-               tty_flip_buffer_push(tty);
-       }
-
-       result = usb_submit_urb(urb, GFP_ATOMIC);
-       if (result)
-               dev_err(&port->dev,
-                       "%s - failed resubmitting read urb, error %d\n",
-                       __func__, result);
-       return;
-}
-
-static void airprime_write_bulk_callback(struct urb *urb)
-{
-       struct usb_serial_port *port = urb->context;
-       struct airprime_private *priv = usb_get_serial_port_data(port);
-       int status = urb->status;
-       unsigned long flags;
-
-       dbg("%s - port %d", __func__, port->number);
-
-       /* free up the transfer buffer, as usb_free_urb() does not do this */
-       kfree(urb->transfer_buffer);
-
-       if (status)
-               dbg("%s - nonzero write bulk status received: %d",
-                   __func__, status);
-       spin_lock_irqsave(&priv->lock, flags);
-       --priv->outstanding_urbs;
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       usb_serial_port_softint(port);
-}
-
-static int airprime_open(struct usb_serial_port *port, struct file *filp)
-{
-       struct airprime_private *priv = usb_get_serial_port_data(port);
-       struct usb_serial *serial = port->serial;
-       struct urb *urb;
-       char *buffer = NULL;
-       int i;
-       int result = 0;
-
-       dbg("%s - port %d", __func__, port->number);
-
-       /* initialize our private data structure if it isn't already created */
-       if (!priv) {
-               priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-               if (!priv) {
-                       result = -ENOMEM;
-                       goto out;
-               }
-               spin_lock_init(&priv->lock);
-               usb_set_serial_port_data(port, priv);
-       }
-
-       /* Set some sane defaults */
-       priv->rts_state = 1;
-       priv->dtr_state = 1;
-
-       for (i = 0; i < NUM_READ_URBS; ++i) {
-               buffer = kmalloc(buffer_size, GFP_KERNEL);
-               if (!buffer) {
-                       dev_err(&port->dev, "%s - out of memory.\n",
-                               __func__);
-                       result = -ENOMEM;
-                       goto errout;
-               }
-               urb = usb_alloc_urb(0, GFP_KERNEL);
-               if (!urb) {
-                       kfree(buffer);
-                       dev_err(&port->dev, "%s - no more urbs?\n",
-                               __func__);
-                       result = -ENOMEM;
-                       goto errout;
-               }
-               usb_fill_bulk_urb(urb, serial->dev,
-                                 usb_rcvbulkpipe(serial->dev,
-                                         port->bulk_out_endpointAddress),
-                                 buffer, buffer_size,
-                                 airprime_read_bulk_callback, port);
-               result = usb_submit_urb(urb, GFP_KERNEL);
-               if (result) {
-                       usb_free_urb(urb);
-                       kfree(buffer);
-                       dev_err(&port->dev,
-                               "%s - failed submitting read urb %d for port %d, error %d\n",
-                               __func__, i, port->number, result);
-                       goto errout;
-               }
-               /* remember this urb so we can kill it when the
-                  port is closed */
-               priv->read_urbp[i] = urb;
-       }
-
-       airprime_send_setup(port);
-
-       goto out;
-
- errout:
-       /* some error happened, cancel any submitted urbs and clean up
-          anything that got allocated successfully */
-
-       while (i-- != 0) {
-               urb = priv->read_urbp[i];
-               buffer = urb->transfer_buffer;
-               usb_kill_urb(urb);
-               usb_free_urb(urb);
-               kfree(buffer);
-       }
-
- out:
-       return result;
-}
-
-static void airprime_close(struct usb_serial_port *port, struct file *filp)
-{
-       struct airprime_private *priv = usb_get_serial_port_data(port);
-       int i;
-
-       dbg("%s - port %d", __func__, port->number);
-
-       priv->rts_state = 0;
-       priv->dtr_state = 0;
-
-       mutex_lock(&port->serial->disc_mutex);
-       if (!port->serial->disconnected)
-               airprime_send_setup(port);
-       mutex_unlock(&port->serial->disc_mutex);
-
-       for (i = 0; i < NUM_READ_URBS; ++i) {
-               usb_kill_urb(priv->read_urbp[i]);
-               kfree(priv->read_urbp[i]->transfer_buffer);
-               usb_free_urb(priv->read_urbp[i]);
-       }
-
-       /* free up private structure */
-       kfree(priv);
-       usb_set_serial_port_data(port, NULL);
-}
-
-static int airprime_write(struct usb_serial_port *port,
-                         const unsigned char *buf, int count)
-{
-       struct airprime_private *priv = usb_get_serial_port_data(port);
-       struct usb_serial *serial = port->serial;
-       struct urb *urb;
-       unsigned char *buffer;
-       unsigned long flags;
-       int status;
-       dbg("%s - port %d", __func__, port->number);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       if (priv->outstanding_urbs > NUM_WRITE_URBS) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               dbg("%s - write limit hit\n", __func__);
-               return 0;
-       }
-       spin_unlock_irqrestore(&priv->lock, flags);
-       buffer = kmalloc(count, GFP_ATOMIC);
-       if (!buffer) {
-               dev_err(&port->dev, "out of memory\n");
-               return -ENOMEM;
-       }
-       urb = usb_alloc_urb(0, GFP_ATOMIC);
-       if (!urb) {
-               dev_err(&port->dev, "no more free urbs\n");
-               kfree(buffer);
-               return -ENOMEM;
-       }
-       memcpy(buffer, buf, count);
-
-       usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);
-
-       usb_fill_bulk_urb(urb, serial->dev,
-                         usb_sndbulkpipe(serial->dev,
-                                         port->bulk_out_endpointAddress),
-                         buffer, count,
-                         airprime_write_bulk_callback, port);
-
-       /* send it down the pipe */
-       status = usb_submit_urb(urb, GFP_ATOMIC);
-       if (status) {
-               dev_err(&port->dev,
-                       "%s - usb_submit_urb(write bulk) failed with status = %d\n",
-                       __func__, status);
-               count = status;
-               kfree(buffer);
-       } else {
-               spin_lock_irqsave(&priv->lock, flags);
-               ++priv->outstanding_urbs;
-               spin_unlock_irqrestore(&priv->lock, flags);
-       }
-       /* we are done with this urb, so let the host driver
-        * really free it when it is finished with it */
-       usb_free_urb(urb);
-       return count;
-}
-
-static struct usb_driver airprime_driver = {
-       .name =         "airprime",
-       .probe =        usb_serial_probe,
-       .disconnect =   usb_serial_disconnect,
-       .id_table =     id_table,
-       .no_dynamic_id =        1,
-};
-
-static struct usb_serial_driver airprime_device = {
-       .driver = {
-               .owner =        THIS_MODULE,
-               .name =         "airprime",
-       },
-       .usb_driver =           &airprime_driver,
-       .id_table =             id_table,
-       .open =                 airprime_open,
-       .close =                airprime_close,
-       .write =                airprime_write,
-};
-
-static int __init airprime_init(void)
-{
-       int retval;
-
-       airprime_device.num_ports = endpoints;
-       if (endpoints < 0 || endpoints >= MAX_BULK_EPS)
-               airprime_device.num_ports = NUM_BULK_EPS;
-
-       retval = usb_serial_register(&airprime_device);
-       if (retval)
-               return retval;
-       retval = usb_register(&airprime_driver);
-       if (retval)
-               usb_serial_deregister(&airprime_device);
-       return retval;
-}
-
-static void __exit airprime_exit(void)
-{
-       dbg("%s", __func__);
-
-       usb_deregister(&airprime_driver);
-       usb_serial_deregister(&airprime_device);
-}
-
-module_init(airprime_init);
-module_exit(airprime_exit);
-MODULE_LICENSE("GPL");
-
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug enabled");
-module_param(buffer_size, int, 0);
-MODULE_PARM_DESC(buffer_size,
-               "Size of the transfer buffers in bytes (default 4096)");
-module_param(endpoints, int, 0);
-MODULE_PARM_DESC(endpoints, "Number of bulk EPs to configure (default 3)");
index 77895c8f8f3189fb774acb59cad0f3f3a324cbad..aec61880f36c0485be60ad6774447937ecc14d42 100644 (file)
@@ -158,12 +158,13 @@ cleanup:
        return -ENOMEM;
 }
 
-static void ark3116_set_termios(struct usb_serial_port *port,
+static void ark3116_set_termios(struct tty_struct *tty,
+                               struct usb_serial_port *port,
                                struct ktermios *old_termios)
 {
        struct usb_serial *serial = port->serial;
        struct ark3116_private *priv = usb_get_serial_port_data(port);
-       struct ktermios *termios = port->tty->termios;
+       struct ktermios *termios = tty->termios;
        unsigned int cflag = termios->c_cflag;
        unsigned long flags;
        int baud;
@@ -177,8 +178,8 @@ static void ark3116_set_termios(struct usb_serial_port *port,
 
        spin_lock_irqsave(&priv->lock, flags);
        if (!priv->termios_initialized) {
-               *(port->tty->termios) = tty_std_termios;
-               port->tty->termios->c_cflag = B9600 | CS8
+               *termios = tty_std_termios;
+               termios->c_cflag = B9600 | CS8
                                              | CREAD | HUPCL | CLOCAL;
                termios->c_ispeed = 9600;
                termios->c_ospeed = 9600;
@@ -192,7 +193,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
        buf = kmalloc(1, GFP_KERNEL);
        if (!buf) {
                dbg("error kmalloc");
-               *port->tty->termios = *old_termios;
+               *termios = *old_termios;
                return;
        }
 
@@ -243,7 +244,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
        }
 
        /* set baudrate */
-       baud = tty_get_baud_rate(port->tty);
+       baud = tty_get_baud_rate(tty);
 
        switch (baud) {
        case 75:
@@ -262,11 +263,11 @@ static void ark3116_set_termios(struct usb_serial_port *port,
        case 230400:
        case 460800:
                /* Report the resulting rate back to the caller */
-               tty_encode_baud_rate(port->tty, baud, baud);
+               tty_encode_baud_rate(tty, baud, baud);
                break;
        /* set 9600 as default (if given baudrate is invalid for example) */
        default:
-               tty_encode_baud_rate(port->tty, 9600, 9600);
+               tty_encode_baud_rate(tty, 9600, 9600);
        case 0:
                baud = 9600;
        }
@@ -317,7 +318,8 @@ static void ark3116_set_termios(struct usb_serial_port *port,
        return;
 }
 
-static int ark3116_open(struct usb_serial_port *port, struct file *filp)
+static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port,
+                                       struct file *filp)
 {
        struct ktermios tmp_termios;
        struct usb_serial *serial = port->serial;
@@ -332,7 +334,7 @@ static int ark3116_open(struct usb_serial_port *port, struct file *filp)
                return -ENOMEM;
        }
 
-       result = usb_serial_generic_open(port, filp);
+       result = usb_serial_generic_open(tty, port, filp);
        if (result)
                goto err_out;
 
@@ -362,8 +364,8 @@ static int ark3116_open(struct usb_serial_port *port, struct file *filp)
        ARK3116_RCV(serial, 124, 0xFE, 0xC0, 0x0000, 0x0006, 0xFF, buf);
 
        /* initialise termios */
-       if (port->tty)
-               ark3116_set_termios(port, &tmp_termios);
+       if (tty)
+               ark3116_set_termios(tty, port, &tmp_termios);
 
 err_out:
        kfree(buf);
@@ -371,9 +373,10 @@ err_out:
        return result;
 }
 
-static int ark3116_ioctl(struct usb_serial_port *port, struct file *file,
+static int ark3116_ioctl(struct tty_struct *tty, struct file *file,
                         unsigned int cmd, unsigned long arg)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct serial_struct serstruct;
        void __user *user_arg = (void __user *)arg;
 
@@ -403,8 +406,9 @@ static int ark3116_ioctl(struct usb_serial_port *port, struct file *file,
        return -ENOIOCTLCMD;
 }
 
-static int ark3116_tiocmget(struct usb_serial_port *port, struct file *file)
+static int ark3116_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
        char *buf;
        char temp;
index 0a322fc53d6e23694e612eb9184e55d005caad31..2ebe06c3405a219d7d6a7200f0956baf2c466555 100644 (file)
@@ -7,13 +7,14 @@
  *  This program is largely derived from work by the linux-usb group
  *  and associated source files.  Please see the usb/serial files for
  *  individual credits and copyrights.
- *  
+ *
  *     This program is free software; you can redistribute it and/or modify
  *     it under the terms of the GNU General Public License as published by
  *     the Free Software Foundation; either version 2 of the License, or
  *     (at your option) any later version.
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
  *
  * TODO:
  * -- Add true modem contol line query capability.  Currently we track the
@@ -28,7 +29,8 @@
  *     compressed all the differnent device entries into 1.
  *
  * 30-May-2001 gkh
- *     switched from using spinlock to a semaphore, which fixes lots of problems.
+ *     switched from using spinlock to a semaphore, which fixes lots of
+ *     problems.
  *
  * 08-Apr-2001 gb
  *     - Identify version on module load.
@@ -41,7 +43,7 @@
  *     - Added support for the old Belkin and Peracom devices.
  *     - Made the port able to be opened multiple times.
  *     - Added some defaults incase the line settings are things these devices
- *       can't support. 
+ *       can't support.
  *
  * 18-Oct-2000 William Greathouse
  *    Released into the wild (linux-usb-devel)
@@ -72,7 +74,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include "belkin_sa.h"
@@ -87,16 +89,19 @@ static int debug;
 #define DRIVER_DESC "USB Belkin Serial converter driver"
 
 /* function prototypes for a Belkin USB Serial Adapter F5U103 */
-static int  belkin_sa_startup          (struct usb_serial *serial);
-static void belkin_sa_shutdown         (struct usb_serial *serial);
-static int  belkin_sa_open             (struct usb_serial_port *port, struct file *filp);
-static void belkin_sa_close            (struct usb_serial_port *port, struct file *filp);
-static void belkin_sa_read_int_callback (struct urb *urb);
-static void belkin_sa_set_termios      (struct usb_serial_port *port, struct ktermios * old);
-static int  belkin_sa_ioctl            (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void belkin_sa_break_ctl                (struct usb_serial_port *port, int break_state );
-static int  belkin_sa_tiocmget         (struct usb_serial_port *port, struct file *file);
-static int  belkin_sa_tiocmset         (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
+static int  belkin_sa_startup(struct usb_serial *serial);
+static void belkin_sa_shutdown(struct usb_serial *serial);
+static int  belkin_sa_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static void belkin_sa_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static void belkin_sa_read_int_callback(struct urb *urb);
+static void belkin_sa_set_termios(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct ktermios * old);
+static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state);
+static int  belkin_sa_tiocmget(struct tty_struct *tty, struct file *file);
+static int  belkin_sa_tiocmset(struct tty_struct *tty, struct file *file,
+                                       unsigned int set, unsigned int clear);
 
 
 static struct usb_device_id id_table_combined [] = {
@@ -106,10 +111,10 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(GOHUBS_VID, GOHUBS_PID) },
        { USB_DEVICE(GOHUBS_VID, HANDYLINK_PID) },
        { USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) },
-       { }                                                     /* Terminating entry */
+       { }     /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
 
 static struct usb_driver belkin_driver = {
        .name =         "belkin",
@@ -131,8 +136,8 @@ static struct usb_serial_driver belkin_device = {
        .num_ports =            1,
        .open =                 belkin_sa_open,
        .close =                belkin_sa_close,
-       .read_int_callback =    belkin_sa_read_int_callback,    /* How we get the status info */
-       .ioctl =                belkin_sa_ioctl,
+       .read_int_callback =    belkin_sa_read_int_callback,
+                                       /* How we get the status info */
        .set_termios =          belkin_sa_set_termios,
        .break_ctl =            belkin_sa_break_ctl,
        .tiocmget =             belkin_sa_tiocmget,
@@ -160,12 +165,12 @@ struct belkin_sa_private {
 #define WDR_TIMEOUT 5000 /* default urb timeout */
 
 /* assumes that struct usb_serial *serial is available */
-#define BSA_USB_CMD(c,v) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), \
+#define BSA_USB_CMD(c, v) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), \
                                            (c), BELKIN_SA_SET_REQUEST_TYPE, \
                                            (v), 0, NULL, 0, WDR_TIMEOUT)
 
 /* do some startup allocations not currently performed by usb_serial_probe() */
-static int belkin_sa_startup (struct usb_serial *serial)
+static int belkin_sa_startup(struct usb_serial *serial)
 {
        struct usb_device *dev = serial->dev;
        struct belkin_sa_private *priv;
@@ -173,32 +178,35 @@ static int belkin_sa_startup (struct usb_serial *serial)
        /* allocate the private data structure */
        priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL);
        if (!priv)
-               return (-1); /* error */
+               return -1; /* error */
        /* set initial values for control structures */
        spin_lock_init(&priv->lock);
        priv->control_state = 0;
        priv->last_lsr = 0;
        priv->last_msr = 0;
        /* see comments at top of file */
-       priv->bad_flow_control = (le16_to_cpu(dev->descriptor.bcdDevice) <= 0x0206) ? 1 : 0;
-       info("bcdDevice: %04x, bfc: %d", le16_to_cpu(dev->descriptor.bcdDevice), priv->bad_flow_control);
+       priv->bad_flow_control =
+               (le16_to_cpu(dev->descriptor.bcdDevice) <= 0x0206) ? 1 : 0;
+       info("bcdDevice: %04x, bfc: %d",
+                                       le16_to_cpu(dev->descriptor.bcdDevice),
+                                       priv->bad_flow_control);
 
        init_waitqueue_head(&serial->port[0]->write_wait);
        usb_set_serial_port_data(serial->port[0], priv);
-       
-       return (0);
+
+       return 0;
 }
 
 
-static void belkin_sa_shutdown (struct usb_serial *serial)
+static void belkin_sa_shutdown(struct usb_serial *serial)
 {
        struct belkin_sa_private *priv;
        int i;
-       
-       dbg ("%s", __func__);
+
+       dbg("%s", __func__);
 
        /* stop reads and writes on all ports */
-       for (i=0; i < serial->num_ports; ++i) {
+       for (i = 0; i < serial->num_ports; ++i) {
                /* My special items, the standard routines free my urbs */
                priv = usb_get_serial_port_data(serial->port[i]);
                kfree(priv);
@@ -206,7 +214,8 @@ static void belkin_sa_shutdown (struct usb_serial *serial)
 }
 
 
-static int  belkin_sa_open (struct usb_serial_port *port, struct file *filp)
+static int  belkin_sa_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        int retval = 0;
 
@@ -235,7 +244,8 @@ exit:
 } /* belkin_sa_open */
 
 
-static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
+static void belkin_sa_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        dbg("%s port %d", __func__, port->number);
 
@@ -246,7 +256,7 @@ static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
 } /* belkin_sa_close */
 
 
-static void belkin_sa_read_int_callback (struct urb *urb)
+static void belkin_sa_read_int_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct belkin_sa_private *priv;
@@ -272,7 +282,8 @@ static void belkin_sa_read_int_callback (struct urb *urb)
                goto exit;
        }
 
-       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                                       urb->actual_length, data);
 
        /* Handle known interrupt data */
        /* ignore data[0] and data[1] */
@@ -280,7 +291,7 @@ static void belkin_sa_read_int_callback (struct urb *urb)
        priv = usb_get_serial_port_data(port);
        spin_lock_irqsave(&priv->lock, flags);
        priv->last_msr = data[BELKIN_SA_MSR_INDEX];
-       
+
        /* Record Control Line states */
        if (priv->last_msr & BELKIN_SA_MSR_DSR)
                priv->control_state |= TIOCM_DSR;
@@ -311,7 +322,7 @@ static void belkin_sa_read_int_callback (struct urb *urb)
         * to look in to this before committing any code.
         */
        if (priv->last_lsr & BELKIN_SA_LSR_ERR) {
-               tty = port->tty;
+               tty = port->port.tty;
                /* Overrun Error */
                if (priv->last_lsr & BELKIN_SA_LSR_OE) {
                }
@@ -328,13 +339,14 @@ static void belkin_sa_read_int_callback (struct urb *urb)
 #endif
        spin_unlock_irqrestore(&priv->lock, flags);
 exit:
-       retval = usb_submit_urb (urb, GFP_ATOMIC);
+       retval = usb_submit_urb(urb, GFP_ATOMIC);
        if (retval)
-               err ("%s - usb_submit_urb failed with result %d",
+               err("%s - usb_submit_urb failed with result %d",
                     __func__, retval);
 }
 
-static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
+static void belkin_sa_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        struct usb_serial *serial = port->serial;
        struct belkin_sa_private *priv = usb_get_serial_port_data(port);
@@ -347,8 +359,8 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
        unsigned long control_state;
        int bad_flow_control;
        speed_t baud;
-       struct ktermios *termios = port->tty->termios;
-       
+       struct ktermios *termios = tty->termios;
+
        iflag = termios->c_iflag;
        cflag = termios->c_cflag;
 
@@ -359,25 +371,26 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
        control_state = priv->control_state;
        bad_flow_control = priv->bad_flow_control;
        spin_unlock_irqrestore(&priv->lock, flags);
-       
+
        old_iflag = old_termios->c_iflag;
        old_cflag = old_termios->c_cflag;
 
        /* Set the baud rate */
        if ((cflag & CBAUD) != (old_cflag & CBAUD)) {
                /* reassert DTR and (maybe) RTS on transition from B0 */
-               if( (old_cflag&CBAUD) == B0 ) {
+               if ((old_cflag & CBAUD) == B0) {
                        control_state |= (TIOCM_DTR|TIOCM_RTS);
                        if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0)
                                err("Set DTR error");
                        /* don't set RTS if using hardware flow control */
                        if (!(old_cflag & CRTSCTS))
-                               if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 1) < 0)
+                               if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST
+                                                               , 1) < 0)
                                        err("Set RTS error");
                }
        }
 
-       baud = tty_get_baud_rate(port->tty);
+       baud = tty_get_baud_rate(tty);
        if (baud) {
                urb_value = BELKIN_SA_BAUD(baud);
                /* Clip to maximum speed */
@@ -387,12 +400,13 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
                baud = BELKIN_SA_BAUD(urb_value);
 
                /* Report the actual baud rate back to the caller */
-               tty_encode_baud_rate(port->tty, baud, baud);
+               tty_encode_baud_rate(tty, baud, baud);
                if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0)
                        err("Set baudrate error");
        } else {
                /* Disable flow control */
-               if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, BELKIN_SA_FLOW_NONE) < 0)
+               if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST,
+                                               BELKIN_SA_FLOW_NONE) < 0)
                        err("Disable flowcontrol error");
                /* Drop RTS and DTR */
                control_state &= ~(TIOCM_DTR | TIOCM_RTS);
@@ -403,9 +417,10 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
        }
 
        /* set the parity */
-       if( (cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD)) ) {
+       if ((cflag ^ old_cflag) & (PARENB | PARODD)) {
                if (cflag & PARENB)
-                       urb_value = (cflag & PARODD) ?  BELKIN_SA_PARITY_ODD : BELKIN_SA_PARITY_EVEN;
+                       urb_value = (cflag & PARODD) ?  BELKIN_SA_PARITY_ODD
+                                               : BELKIN_SA_PARITY_EVEN;
                else
                        urb_value = BELKIN_SA_PARITY_NONE;
                if (BSA_USB_CMD(BELKIN_SA_SET_PARITY_REQUEST, urb_value) < 0)
@@ -413,31 +428,40 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
        }
 
        /* set the number of data bits */
-       if( (cflag&CSIZE) != (old_cflag&CSIZE) ) {
+       if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
                switch (cflag & CSIZE) {
-                       case CS5: urb_value = BELKIN_SA_DATA_BITS(5); break;
-                       case CS6: urb_value = BELKIN_SA_DATA_BITS(6); break;
-                       case CS7: urb_value = BELKIN_SA_DATA_BITS(7); break;
-                       case CS8: urb_value = BELKIN_SA_DATA_BITS(8); break;
-                       default: dbg("CSIZE was not CS5-CS8, using default of 8");
-                               urb_value = BELKIN_SA_DATA_BITS(8);
-                               break;
+               case CS5:
+                       urb_value = BELKIN_SA_DATA_BITS(5);
+                       break;
+               case CS6:
+                       urb_value = BELKIN_SA_DATA_BITS(6);
+                       break;
+               case CS7:
+                       urb_value = BELKIN_SA_DATA_BITS(7);
+                       break;
+               case CS8:
+                       urb_value = BELKIN_SA_DATA_BITS(8);
+                       break;
+               default: dbg("CSIZE was not CS5-CS8, using default of 8");
+                       urb_value = BELKIN_SA_DATA_BITS(8);
+                       break;
                }
                if (BSA_USB_CMD(BELKIN_SA_SET_DATA_BITS_REQUEST, urb_value) < 0)
                        err("Set data bits error");
        }
 
        /* set the number of stop bits */
-       if( (cflag&CSTOPB) != (old_cflag&CSTOPB) ) {
-               urb_value = (cflag & CSTOPB) ? BELKIN_SA_STOP_BITS(2) : BELKIN_SA_STOP_BITS(1);
-               if (BSA_USB_CMD(BELKIN_SA_SET_STOP_BITS_REQUEST, urb_value) < 0)
+       if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) {
+               urb_value = (cflag & CSTOPB) ? BELKIN_SA_STOP_BITS(2)
+                                               : BELKIN_SA_STOP_BITS(1);
+               if (BSA_USB_CMD(BELKIN_SA_SET_STOP_BITS_REQUEST,
+                                                       urb_value) < 0)
                        err("Set stop bits error");
        }
 
        /* Set flow control */
-       if( (iflag&IXOFF)   != (old_iflag&IXOFF)
-       ||      (iflag&IXON)    != (old_iflag&IXON)
-       ||  (cflag&CRTSCTS) != (old_cflag&CRTSCTS) ) {
+       if (((iflag ^ old_iflag) & (IXOFF | IXON)) ||
+               ((cflag ^ old_cflag) & CRTSCTS)) {
                urb_value = 0;
                if ((iflag & IXOFF) || (iflag & IXON))
                        urb_value |= (BELKIN_SA_FLOW_OXON | BELKIN_SA_FLOW_IXON);
@@ -463,8 +487,9 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
 } /* belkin_sa_set_termios */
 
 
-static void belkin_sa_break_ctl( struct usb_serial_port *port, int break_state )
+static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
 
        if (BSA_USB_CMD(BELKIN_SA_SET_BREAK_REQUEST, break_state ? 1 : 0) < 0)
@@ -472,12 +497,13 @@ static void belkin_sa_break_ctl( struct usb_serial_port *port, int break_state )
 }
 
 
-static int belkin_sa_tiocmget (struct usb_serial_port *port, struct file *file)
+static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct belkin_sa_private *priv = usb_get_serial_port_data(port);
        unsigned long control_state;
        unsigned long flags;
-       
+
        dbg("%s", __func__);
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -488,9 +514,10 @@ static int belkin_sa_tiocmget (struct usb_serial_port *port, struct file *file)
 }
 
 
-static int belkin_sa_tiocmset (struct usb_serial_port *port, struct file *file,
+static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file,
                               unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
        struct belkin_sa_private *priv = usb_get_serial_port_data(port);
        unsigned long control_state;
@@ -498,7 +525,7 @@ static int belkin_sa_tiocmset (struct usb_serial_port *port, struct file *file,
        int retval;
        int rts = 0;
        int dtr = 0;
-       
+
        dbg("%s", __func__);
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -540,29 +567,7 @@ exit:
 }
 
 
-static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
-{
-       switch (cmd) {
-       case TIOCMIWAIT:
-               /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
-               /* TODO */
-               return( 0 );
-
-       case TIOCGICOUNT:
-               /* return count of modemline transitions */
-               /* TODO */
-               return 0;
-
-       default:
-               dbg("belkin_sa_ioctl arg not supported - 0x%04x",cmd);
-               return(-ENOIOCTLCMD);
-               break;
-       }
-       return 0;
-} /* belkin_sa_ioctl */
-
-
-static int __init belkin_sa_init (void)
+static int __init belkin_sa_init(void)
 {
        int retval;
        retval = usb_serial_register(&belkin_device);
@@ -582,17 +587,17 @@ failed_usb_serial_register:
 
 static void __exit belkin_sa_exit (void)
 {
-       usb_deregister (&belkin_driver);
-       usb_serial_deregister (&belkin_device);
+       usb_deregister(&belkin_driver);
+       usb_serial_deregister(&belkin_device);
 }
 
 
-module_init (belkin_sa_init);
-module_exit (belkin_sa_exit);
+module_init(belkin_sa_init);
+module_exit(belkin_sa_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_VERSION( DRIVER_VERSION );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
index 9116b92f46229ace2de3275266aea565fcd8abeb..c66a6730d38c159d4a51b2772d6274986d76bf6c 100644 (file)
@@ -7,13 +7,14 @@
  *  This program is largely derived from work by the linux-usb group
  *  and associated source files.  Please see the usb/serial files for
  *  individual credits and copyrights.
- *  
+ *
  *     This program is free software; you can redistribute it and/or modify
  *     it under the terms of the GNU General Public License as published by
  *     the Free Software Foundation; either version 2 of the License, or
  *     (at your option) any later version.
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
  *
  * 12-Mar-2001 gkh
  *     Added GoHubs GO-COM232 device id.
@@ -27,7 +28,7 @@
  *    adapter, so pardon any stupid mistakes.  All of the information
  *    I am using to write this driver was acquired by using a modified
  *    UsbSnoop on Windows2000.
- *    
+ *
  */
 
 #ifndef __LINUX_USB_SERIAL_BSA_H
 
 /*
  * It seems that the interrupt pipe is closely modelled after the
- * 16550 register layout.  This is probably because the adapter can 
+ * 16550 register layout.  This is probably because the adapter can
  * be used in a "DOS" environment to simulate a standard hardware port.
  */
-#define BELKIN_SA_LSR_INDEX            2               /* Line Status Register */
+#define BELKIN_SA_LSR_INDEX            2       /*     Line Status Register */
 #define BELKIN_SA_LSR_RDR              0x01    /* receive data ready */
 #define BELKIN_SA_LSR_OE               0x02    /* overrun error */
 #define BELKIN_SA_LSR_PE               0x04    /* parity error */
 #define BELKIN_SA_LSR_FE               0x08    /* framing error */
 #define BELKIN_SA_LSR_BI               0x10    /* break indicator */
-#define BELKIN_SA_LSR_THE              0x20    /* transmit holding register empty */
+#define BELKIN_SA_LSR_THE              0x20    /* tx holding register empty */
 #define BELKIN_SA_LSR_TE               0x40    /* transmit register empty */
 #define BELKIN_SA_LSR_ERR              0x80    /* OE | PE | FE | BI */
 
-#define BELKIN_SA_MSR_INDEX            3               /* Modem Status Register */
+#define BELKIN_SA_MSR_INDEX            3       /*     Modem Status Register */
 #define BELKIN_SA_MSR_DCTS             0x01    /* Delta CTS */
 #define BELKIN_SA_MSR_DDSR             0x02    /* Delta DSR */
 #define BELKIN_SA_MSR_DRI              0x04    /* Delta RI */
index 0b14aea8ebd52891015e32963784a048e7472ca1..83bbb5bca2efcc05af2aba7023f7a846f8fafa0a 100644 (file)
@@ -15,7 +15,8 @@
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
-static int usb_serial_device_match (struct device *dev, struct device_driver *drv)
+static int usb_serial_device_match(struct device *dev,
+                                               struct device_driver *drv)
 {
        struct usb_serial_driver *driver;
        const struct usb_serial_port *port;
@@ -46,7 +47,7 @@ static ssize_t show_port_number(struct device *dev,
 
 static DEVICE_ATTR(port_number, S_IRUGO, show_port_number, NULL);
 
-static int usb_serial_device_probe (struct device *dev)
+static int usb_serial_device_probe(struct device *dev)
 {
        struct usb_serial_driver *driver;
        struct usb_serial_port *port;
@@ -66,7 +67,7 @@ static int usb_serial_device_probe (struct device *dev)
                        retval = -EIO;
                        goto exit;
                }
-               retval = driver->port_probe (port);
+               retval = driver->port_probe(port);
                module_put(driver->driver.owner);
                if (retval)
                        goto exit;
@@ -77,8 +78,8 @@ static int usb_serial_device_probe (struct device *dev)
                goto exit;
 
        minor = port->number;
-       tty_register_device (usb_serial_tty_driver, minor, dev);
-       dev_info(&port->serial->dev->dev, 
+       tty_register_device(usb_serial_tty_driver, minor, dev);
+       dev_info(&port->serial->dev->dev,
                 "%s converter now attached to ttyUSB%d\n",
                 driver->description, minor);
 
@@ -86,7 +87,7 @@ exit:
        return retval;
 }
 
-static int usb_serial_device_remove (struct device *dev)
+static int usb_serial_device_remove(struct device *dev)
 {
        struct usb_serial_driver *driver;
        struct usb_serial_port *port;
@@ -94,9 +95,8 @@ static int usb_serial_device_remove (struct device *dev)
        int minor;
 
        port = to_usb_serial_port(dev);
-       if (!port) {
+       if (!port)
                return -ENODEV;
-       }
 
        device_remove_file(&port->dev, &dev_attr_port_number);
 
@@ -107,12 +107,12 @@ static int usb_serial_device_remove (struct device *dev)
                        retval = -EIO;
                        goto exit;
                }
-               retval = driver->port_remove (port);
+               retval = driver->port_remove(port);
                module_put(driver->driver.owner);
        }
 exit:
        minor = port->number;
-       tty_unregister_device (usb_serial_tty_driver, minor);
+       tty_unregister_device(usb_serial_tty_driver, minor);
        dev_info(dev, "%s converter now disconnected from ttyUSB%d\n",
                 driver->description, minor);
 
index 1f7c86bd8297c85e21a72451c5abed5e647a38a2..f61e3ca64305abb3d7bbefda787c073bb30c77ee 100644 (file)
@@ -232,7 +232,8 @@ error:      kfree(priv);
 }
 
 /* open this device, set default parameters */
-static int ch341_open(struct usb_serial_port *port, struct file *filp)
+static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
+                               struct file *filp)
 {
        struct usb_serial *serial = port->serial;
        struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]);
@@ -256,7 +257,7 @@ static int ch341_open(struct usb_serial_port *port, struct file *filp)
        if (r)
                goto out;
 
-       r = usb_serial_generic_open(port, filp);
+       r = usb_serial_generic_open(tty, port, filp);
 
 out:   return r;
 }
@@ -264,11 +265,10 @@ out:      return r;
 /* Old_termios contains the original termios settings and
  * tty->termios contains the new setting to be used.
  */
-static void ch341_set_termios(struct usb_serial_port *port,
-                             struct ktermios *old_termios)
+static void ch341_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        struct ch341_private *priv = usb_get_serial_port_data(port);
-       struct tty_struct *tty = port->tty;
        unsigned baud_rate;
 
        dbg("ch341_set_termios()");
index 201184c3fb87ebc271db45d244b44ab884745ef6..7b74238ad1c7a2ab1aed27bc219b94f23b997c9e 100644 (file)
@@ -6,7 +6,7 @@
  *     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.
- * 
+ *
  * Thanks to Randy Dunlap for the original version of this code.
  *
  */
@@ -67,7 +67,7 @@ static int usb_console_setup(struct console *co, char *options)
        struct tty_struct *tty = NULL;
        struct ktermios *termios = NULL, dummy;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        if (options) {
                baud = simple_strtoul(options, NULL, 10);
@@ -81,55 +81,27 @@ static int usb_console_setup(struct console *co, char *options)
                if (*s)
                        doflow = (*s++ == 'r');
        }
+       
+       /* Sane default */
+       if (baud == 0)
+               baud = 9600;
 
-       /* build a cflag setting */
-       switch (baud) {
-               case 1200:
-                       cflag |= B1200;
-                       break;
-               case 2400:
-                       cflag |= B2400;
-                       break;
-               case 4800:
-                       cflag |= B4800;
-                       break;
-               case 19200:
-                       cflag |= B19200;
-                       break;
-               case 38400:
-                       cflag |= B38400;
-                       break;
-               case 57600:
-                       cflag |= B57600;
-                       break;
-               case 115200:
-                       cflag |= B115200;
-                       break;
-               case 9600:
-               default:
-                       cflag |= B9600;
-                       /*
-                        * Set this to a sane value to prevent a divide error
-                        */
-                       baud  = 9600;
-                       break;
-       }
        switch (bits) {
-               case 7:
-                       cflag |= CS7;
-                       break;
-               default:
-               case 8:
-                       cflag |= CS8;
-                       break;
+       case 7:
+               cflag |= CS7;
+               break;
+       default:
+       case 8:
+               cflag |= CS8;
+               break;
        }
        switch (parity) {
-               case 'o': case 'O':
-                       cflag |= PARODD;
-                       break;
-               case 'e': case 'E':
-                       cflag |= PARENB;
-                       break;
+       case 'o': case 'O':
+               cflag |= PARODD;
+               break;
+       case 'e': case 'E':
+               cflag |= PARENB;
+               break;
        }
        co->cflag = cflag;
 
@@ -140,17 +112,17 @@ static int usb_console_setup(struct console *co, char *options)
        serial = usb_serial_get_by_index(co->index);
        if (serial == NULL) {
                /* no device is connected yet, sorry :( */
-               err ("No USB device connected to ttyUSB%i", co->index);
+               err("No USB device connected to ttyUSB%i", co->index);
                return -ENODEV;
        }
 
        port = serial->port[0];
-       port->tty = NULL;
+       port->port.tty = NULL;
 
        info->port = port;
-        
-       ++port->open_count;
-       if (port->open_count == 1) {
+
+       ++port->port.count;
+       if (port->port.count == 1) {
                if (serial->type->set_termios) {
                        /*
                         * allocate a fake tty so the driver can initialize
@@ -171,15 +143,15 @@ static int usb_console_setup(struct console *co, char *options)
                        }
                        memset(&dummy, 0, sizeof(struct ktermios));
                        tty->termios = termios;
-                       port->tty = tty;
+                       port->port.tty = tty;
                }
 
-               /* only call the device specific open if this 
+               /* only call the device specific open if this
                 * is the first time the port is opened */
                if (serial->type->open)
-                       retval = serial->type->open(port, NULL);
+                       retval = serial->type->open(NULL, port, NULL);
                else
-                       retval = usb_serial_generic_open(port, NULL);
+                       retval = usb_serial_generic_open(NULL, port, NULL);
 
                if (retval) {
                        err("could not open USB console port");
@@ -188,9 +160,10 @@ static int usb_console_setup(struct console *co, char *options)
 
                if (serial->type->set_termios) {
                        termios->c_cflag = cflag;
-                       serial->type->set_termios(port, &dummy);
+                       tty_termios_encode_baud_rate(termios, baud, baud);
+                       serial->type->set_termios(NULL, port, &dummy);
 
-                       port->tty = NULL;
+                       port->port.tty = NULL;
                        kfree(termios);
                        kfree(tty);
                }
@@ -203,15 +176,16 @@ out:
        return retval;
 free_termios:
        kfree(termios);
-       port->tty = NULL;
+       port->port.tty = NULL;
 free_tty:
        kfree(tty);
 reset_open_count:
-       port->open_count = 0;
+       port->port.count = 0;
 goto out;
 }
 
-static void usb_console_write(struct console *co, const char *buf, unsigned count)
+static void usb_console_write(struct console *co,
+                                       const char *buf, unsigned count)
 {
        static struct usbcons_info *info = &usbcons_info;
        struct usb_serial_port *port = info->port;
@@ -227,8 +201,8 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun
 
        dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
 
-       if (!port->open_count) {
-               dbg ("%s - port not opened", __func__);
+       if (!port->port.count) {
+               dbg("%s - port not opened", __func__);
                return;
        }
 
@@ -236,26 +210,29 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun
                unsigned int i;
                unsigned int lf;
                /* search for LF so we can insert CR if necessary */
-               for (i=0, lf=0 ; i < count ; i++) {
+               for (i = 0, lf = 0 ; i < count ; i++) {
                        if (*(buf + i) == 10) {
                                lf = 1;
                                i++;
                                break;
                        }
                }
-               /* pass on to the driver specific version of this function if it is available */
+               /* pass on to the driver specific version of this function if
+                  it is available */
                if (serial->type->write)
-                       retval = serial->type->write(port, buf, i);
+                       retval = serial->type->write(NULL, port, buf, i);
                else
-                       retval = usb_serial_generic_write(port, buf, i);
+                       retval = usb_serial_generic_write(NULL, port, buf, i);
                dbg("%s - return value : %d", __func__, retval);
                if (lf) {
                        /* append CR after LF */
                        unsigned char cr = 13;
                        if (serial->type->write)
-                               retval = serial->type->write(port, &cr, 1);
+                               retval = serial->type->write(NULL,
+                                                               port, &cr, 1);
                        else
-                               retval = usb_serial_generic_write(port, &cr, 1);
+                               retval = usb_serial_generic_write(NULL,
+                                                               port, &cr, 1);
                        dbg("%s - return value : %d", __func__, retval);
                }
                buf += i;
@@ -273,18 +250,19 @@ static struct console usbcons = {
 
 void usb_serial_console_disconnect(struct usb_serial *serial)
 {
-       if (serial && serial->port && serial->port[0] && serial->port[0] == usbcons_info.port) {
+       if (serial && serial->port && serial->port[0]
+                               && serial->port[0] == usbcons_info.port) {
                usb_serial_console_exit();
                usb_serial_put(serial);
        }
 }
 
-void usb_serial_console_init (int serial_debug, int minor)
+void usb_serial_console_init(int serial_debug, int minor)
 {
        debug = serial_debug;
 
        if (minor == 0) {
-               /* 
+               /*
                 * Call register_console() if this is the first device plugged
                 * in.  If we call it earlier, then the callback to
                 * console_setup() will fail, as there is not a device seen by
@@ -293,21 +271,21 @@ void usb_serial_console_init (int serial_debug, int minor)
                /*
                 * Register console.
                 * NOTES:
-                * console_setup() is called (back) immediately (from register_console).
-                * console_write() is called immediately from register_console iff
-                * CON_PRINTBUFFER is set in flags.
+                * console_setup() is called (back) immediately (from
+                * register_console). console_write() is called immediately
+                * from register_console iff CON_PRINTBUFFER is set in flags.
                 */
-               dbg ("registering the USB serial console.");
+               dbg("registering the USB serial console.");
                register_console(&usbcons);
        }
 }
 
-void usb_serial_console_exit (void)
+void usb_serial_console_exit(void)
 {
        if (usbcons_info.port) {
                unregister_console(&usbcons);
-               if (usbcons_info.port->open_count)
-                       usbcons_info.port->open_count--;
+               if (usbcons_info.port->port.count)
+                       usbcons_info.port->port.count--;
                usbcons_info.port = NULL;
        }
 }
index f5b57b196c5a0821845209b9ff74052f9eb2bb5a..442cba69cce5b9742aa883872122522d0e525925 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/usb.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb/serial.h>
 
 /*
 /*
  * Function Prototypes
  */
-static int cp2101_open(struct usb_serial_port*, struct file*);
-static void cp2101_cleanup(struct usb_serial_port*);
-static void cp2101_close(struct usb_serial_port*, struct file*);
-static void cp2101_get_termios(struct usb_serial_port*);
-static void cp2101_set_termios(struct usb_serial_port*, struct ktermios*);
-static int cp2101_tiocmget (struct usb_serial_port *, struct file *);
-static int cp2101_tiocmset (struct usb_serial_port *, struct file *,
+static int cp2101_open(struct tty_struct *, struct usb_serial_port *,
+                                                       struct file *);
+static void cp2101_cleanup(struct usb_serial_port *);
+static void cp2101_close(struct tty_struct *, struct usb_serial_port *,
+                                                       struct file*);
+static void cp2101_get_termios(struct tty_struct *);
+static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *,
+                                                       struct ktermios*);
+static int cp2101_tiocmget(struct tty_struct *, struct file *);
+static int cp2101_tiocmset(struct tty_struct *, struct file *,
                unsigned int, unsigned int);
-static void cp2101_break_ctl(struct usb_serial_port*, int);
-static int cp2101_startup (struct usb_serial *);
-static void cp2101_shutdown(struct usb_serial*);
+static void cp2101_break_ctl(struct tty_struct *, int);
+static int cp2101_startup(struct usb_serial *);
+static void cp2101_shutdown(struct usb_serial *);
 
 
 static int debug;
@@ -93,7 +96,7 @@ static struct usb_device_id id_table [] = {
        { } /* Terminating Entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver cp2101_driver = {
        .name           = "cp2101",
@@ -182,7 +185,7 @@ static struct usb_serial_driver cp2101_device = {
  * 'data' is a pointer to a pre-allocated array of integers large
  * enough to hold 'size' bytes (with 4 bytes to each integer)
  */
-static int cp2101_get_config(struct usb_serial_portport, u8 request,
+static int cp2101_get_config(struct usb_serial_port *port, u8 request,
                unsigned int *data, int size)
 {
        struct usb_serial *serial = port->serial;
@@ -202,12 +205,12 @@ static int cp2101_get_config(struct usb_serial_port* port, u8 request,
        request++;
 
        /* Issue the request, attempting to read 'size' bytes */
-       result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0),
+       result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                                request, REQTYPE_DEVICE_TO_HOST, 0x0000,
                                0, buf, size, 300);
 
        /* Convert data into an array of integers */
-       for (i=0; i<length; i++)
+       for (i = 0; i < length; i++)
                data[i] = le32_to_cpu(buf[i]);
 
        kfree(buf);
@@ -228,7 +231,7 @@ static int cp2101_get_config(struct usb_serial_port* port, u8 request,
  * Values less than 16 bits wide are sent directly
  * 'size' is specified in bytes.
  */
-static int cp2101_set_config(struct usb_serial_portport, u8 request,
+static int cp2101_set_config(struct usb_serial_port *port, u8 request,
                unsigned int *data, int size)
 {
        struct usb_serial *serial = port->serial;
@@ -250,12 +253,12 @@ static int cp2101_set_config(struct usb_serial_port* port, u8 request,
                buf[i] = cpu_to_le32(data[i]);
 
        if (size > 2) {
-               result = usb_control_msg (serial->dev,
+               result = usb_control_msg(serial->dev,
                                usb_sndctrlpipe(serial->dev, 0),
                                request, REQTYPE_HOST_TO_DEVICE, 0x0000,
                                0, buf, size, 300);
        } else {
-               result = usb_control_msg (serial->dev,
+               result = usb_control_msg(serial->dev,
                                usb_sndctrlpipe(serial->dev, 0),
                                request, REQTYPE_HOST_TO_DEVICE, data[0],
                                0, NULL, 0, 300);
@@ -271,7 +274,7 @@ static int cp2101_set_config(struct usb_serial_port* port, u8 request,
        }
 
        /* Single data value */
-       result = usb_control_msg (serial->dev,
+       result = usb_control_msg(serial->dev,
                        usb_sndctrlpipe(serial->dev, 0),
                        request, REQTYPE_HOST_TO_DEVICE, data[0],
                        0, NULL, 0, 300);
@@ -283,13 +286,14 @@ static int cp2101_set_config(struct usb_serial_port* port, u8 request,
  * Convenience function for calling cp2101_set_config on single data values
  * without requiring an integer pointer
  */
-static inline int cp2101_set_config_single(struct usb_serial_portport,
+static inline int cp2101_set_config_single(struct usb_serial_port *port,
                u8 request, unsigned int data)
 {
        return cp2101_set_config(port, request, &data, 2);
 }
 
-static int cp2101_open (struct usb_serial_port *port, struct file *filp)
+static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port,
+                               struct file *filp)
 {
        struct usb_serial *serial = port->serial;
        int result;
@@ -303,7 +307,7 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp)
        }
 
        /* Start reading from the device */
-       usb_fill_bulk_urb (port->read_urb, serial->dev,
+       usb_fill_bulk_urb(port->read_urb, serial->dev,
                        usb_rcvbulkpipe(serial->dev,
                        port->bulk_in_endpointAddress),
                        port->read_urb->transfer_buffer,
@@ -318,15 +322,15 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp)
        }
 
        /* Configure the termios structure */
-       cp2101_get_termios(port);
+       cp2101_get_termios(tty);
 
        /* Set the DTR and RTS pins low */
-       cp2101_tiocmset(port, NULL, TIOCM_DTR | TIOCM_RTS, 0);
+       cp2101_tiocmset(tty, NULL, TIOCM_DTR | TIOCM_RTS, 0);
 
        return 0;
 }
 
-static void cp2101_cleanup (struct usb_serial_port *port)
+static void cp2101_cleanup(struct usb_serial_port *port)
 {
        struct usb_serial *serial = port->serial;
 
@@ -341,7 +345,8 @@ static void cp2101_cleanup (struct usb_serial_port *port)
        }
 }
 
-static void cp2101_close (struct usb_serial_port *port, struct file * filp)
+static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port,
+                                       struct file *filp)
 {
        dbg("%s - port %d", __func__, port->number);
 
@@ -362,19 +367,15 @@ static void cp2101_close (struct usb_serial_port *port, struct file * filp)
  * from the device, corrects any unsupported values, and configures the
  * termios structure to reflect the state of the device
  */
-static void cp2101_get_termios (struct usb_serial_port *port)
+static void cp2101_get_termios (struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        unsigned int cflag, modem_ctl[4];
-       int baud;
-       int bits;
+       unsigned int baud;
+       unsigned int bits;
 
        dbg("%s - port %d", __func__, port->number);
 
-       if (!port->tty || !port->tty->termios) {
-               dbg("%s - no tty structures", __func__);
-               return;
-       }
-
        cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
        /* Convert to baudrate */
        if (baud)
@@ -382,104 +383,102 @@ static void cp2101_get_termios (struct usb_serial_port *port)
 
        dbg("%s - baud rate = %d", __func__, baud);
 
-       tty_encode_baud_rate(port->tty, baud, baud);
-       cflag = port->tty->termios->c_cflag;
+       tty_encode_baud_rate(tty, baud, baud);
+       cflag = tty->termios->c_cflag;
 
        cp2101_get_config(port, CP2101_BITS, &bits, 2);
        cflag &= ~CSIZE;
-       switch(bits & BITS_DATA_MASK) {
-               case BITS_DATA_5:
-                       dbg("%s - data bits = 5", __func__);
-                       cflag |= CS5;
-                       break;
-               case BITS_DATA_6:
-                       dbg("%s - data bits = 6", __func__);
-                       cflag |= CS6;
-                       break;
-               case BITS_DATA_7:
-                       dbg("%s - data bits = 7", __func__);
-                       cflag |= CS7;
-                       break;
-               case BITS_DATA_8:
-                       dbg("%s - data bits = 8", __func__);
-                       cflag |= CS8;
-                       break;
-               case BITS_DATA_9:
-                       dbg("%s - data bits = 9 (not supported, "
-                                       "using 8 data bits)", __func__);
-                       cflag |= CS8;
-                       bits &= ~BITS_DATA_MASK;
-                       bits |= BITS_DATA_8;
-                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
-                       break;
-               default:
-                       dbg("%s - Unknown number of data bits, "
-                                       "using 8", __func__);
-                       cflag |= CS8;
-                       bits &= ~BITS_DATA_MASK;
-                       bits |= BITS_DATA_8;
-                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
-                       break;
+       switch (bits & BITS_DATA_MASK) {
+       case BITS_DATA_5:
+               dbg("%s - data bits = 5", __func__);
+               cflag |= CS5;
+               break;
+       case BITS_DATA_6:
+               dbg("%s - data bits = 6", __func__);
+               cflag |= CS6;
+               break;
+       case BITS_DATA_7:
+               dbg("%s - data bits = 7", __func__);
+               cflag |= CS7;
+               break;
+       case BITS_DATA_8:
+               dbg("%s - data bits = 8", __func__);
+               cflag |= CS8;
+               break;
+       case BITS_DATA_9:
+               dbg("%s - data bits = 9 (not supported, using 8 data bits)",
+                                                               __func__);
+               cflag |= CS8;
+               bits &= ~BITS_DATA_MASK;
+               bits |= BITS_DATA_8;
+               cp2101_set_config(port, CP2101_BITS, &bits, 2);
+               break;
+       default:
+               dbg("%s - Unknown number of data bits, using 8", __func__);
+               cflag |= CS8;
+               bits &= ~BITS_DATA_MASK;
+               bits |= BITS_DATA_8;
+               cp2101_set_config(port, CP2101_BITS, &bits, 2);
+               break;
        }
 
-       switch(bits & BITS_PARITY_MASK) {
-               case BITS_PARITY_NONE:
-                       dbg("%s - parity = NONE", __func__);
-                       cflag &= ~PARENB;
-                       break;
-               case BITS_PARITY_ODD:
-                       dbg("%s - parity = ODD", __func__);
-                       cflag |= (PARENB|PARODD);
-                       break;
-               case BITS_PARITY_EVEN:
-                       dbg("%s - parity = EVEN", __func__);
-                       cflag &= ~PARODD;
-                       cflag |= PARENB;
-                       break;
-               case BITS_PARITY_MARK:
-                       dbg("%s - parity = MARK (not supported, "
-                                       "disabling parity)", __func__);
-                       cflag &= ~PARENB;
-                       bits &= ~BITS_PARITY_MASK;
-                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
-                       break;
-               case BITS_PARITY_SPACE:
-                       dbg("%s - parity = SPACE (not supported, "
-                                       "disabling parity)", __func__);
-                       cflag &= ~PARENB;
-                       bits &= ~BITS_PARITY_MASK;
-                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
-                       break;
-               default:
-                       dbg("%s - Unknown parity mode, "
-                                       "disabling parity", __func__);
-                       cflag &= ~PARENB;
-                       bits &= ~BITS_PARITY_MASK;
-                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
-                       break;
+       switch (bits & BITS_PARITY_MASK) {
+       case BITS_PARITY_NONE:
+               dbg("%s - parity = NONE", __func__);
+               cflag &= ~PARENB;
+               break;
+       case BITS_PARITY_ODD:
+               dbg("%s - parity = ODD", __func__);
+               cflag |= (PARENB|PARODD);
+               break;
+       case BITS_PARITY_EVEN:
+               dbg("%s - parity = EVEN", __func__);
+               cflag &= ~PARODD;
+               cflag |= PARENB;
+               break;
+       case BITS_PARITY_MARK:
+               dbg("%s - parity = MARK (not supported, disabling parity)",
+                               __func__);
+               cflag &= ~PARENB;
+               bits &= ~BITS_PARITY_MASK;
+               cp2101_set_config(port, CP2101_BITS, &bits, 2);
+               break;
+       case BITS_PARITY_SPACE:
+               dbg("%s - parity = SPACE (not supported, disabling parity)",
+                               __func__);
+               cflag &= ~PARENB;
+               bits &= ~BITS_PARITY_MASK;
+               cp2101_set_config(port, CP2101_BITS, &bits, 2);
+               break;
+       default:
+               dbg("%s - Unknown parity mode, disabling parity", __func__);
+               cflag &= ~PARENB;
+               bits &= ~BITS_PARITY_MASK;
+               cp2101_set_config(port, CP2101_BITS, &bits, 2);
+               break;
        }
 
        cflag &= ~CSTOPB;
-       switch(bits & BITS_STOP_MASK) {
-               case BITS_STOP_1:
-                       dbg("%s - stop bits = 1", __func__);
-                       break;
-               case BITS_STOP_1_5:
-                       dbg("%s - stop bits = 1.5 (not supported, "
-                                       "using 1 stop bit)", __func__);
-                       bits &= ~BITS_STOP_MASK;
-                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
-                       break;
-               case BITS_STOP_2:
-                       dbg("%s - stop bits = 2", __func__);
-                       cflag |= CSTOPB;
-                       break;
-               default:
-                       dbg("%s - Unknown number of stop bits, "
-                                       "using 1 stop bit", __func__);
-                       bits &= ~BITS_STOP_MASK;
-                       cp2101_set_config(port, CP2101_BITS, &bits, 2);
-                       break;
+       switch (bits & BITS_STOP_MASK) {
+       case BITS_STOP_1:
+               dbg("%s - stop bits = 1", __func__);
+               break;
+       case BITS_STOP_1_5:
+               dbg("%s - stop bits = 1.5 (not supported, using 1 stop bit)",
+                                                               __func__);
+               bits &= ~BITS_STOP_MASK;
+               cp2101_set_config(port, CP2101_BITS, &bits, 2);
+               break;
+       case BITS_STOP_2:
+               dbg("%s - stop bits = 2", __func__);
+               cflag |= CSTOPB;
+               break;
+       default:
+               dbg("%s - Unknown number of stop bits, using 1 stop bit",
+                                                               __func__);
+               bits &= ~BITS_STOP_MASK;
+               cp2101_set_config(port, CP2101_BITS, &bits, 2);
+               break;
        }
 
        cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16);
@@ -491,55 +490,53 @@ static void cp2101_get_termios (struct usb_serial_port *port)
                cflag &= ~CRTSCTS;
        }
 
-       port->tty->termios->c_cflag = cflag;
+       tty->termios->c_cflag = cflag;
 }
 
-static void cp2101_set_termios (struct usb_serial_port *port,
-               struct ktermios *old_termios)
+static void cp2101_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        unsigned int cflag, old_cflag;
-       int baud=0, bits;
+       unsigned int baud = 0, bits;
        unsigned int modem_ctl[4];
 
        dbg("%s - port %d", __func__, port->number);
 
-       if (!port->tty || !port->tty->termios) {
-               dbg("%s - no tty structures", __func__);
+       if (!tty)
                return;
-       }
-       port->tty->termios->c_cflag &= ~CMSPAR;
 
-       cflag = port->tty->termios->c_cflag;
+       tty->termios->c_cflag &= ~CMSPAR;
+       cflag = tty->termios->c_cflag;
        old_cflag = old_termios->c_cflag;
-       baud = tty_get_baud_rate(port->tty);
+       baud = tty_get_baud_rate(tty);
 
        /* If the baud rate is to be updated*/
        if (baud != tty_termios_baud_rate(old_termios)) {
                switch (baud) {
-                       case 0:
-                       case 600:
-                       case 1200:
-                       case 1800:
-                       case 2400:
-                       case 4800:
-                       case 7200:
-                       case 9600:
-                       case 14400:
-                       case 19200:
-                       case 28800:
-                       case 38400:
-                       case 55854:
-                       case 57600:
-                       case 115200:
-                       case 127117:
-                       case 230400:
-                       case 460800:
-                       case 921600:
-                       case 3686400:
-                               break;
-                       default:
-                               baud = 9600;
-                               break;
+               case 0:
+               case 600:
+               case 1200:
+               case 1800:
+               case 2400:
+               case 4800:
+               case 7200:
+               case 9600:
+               case 14400:
+               case 19200:
+               case 28800:
+               case 38400:
+               case 55854:
+               case 57600:
+               case 115200:
+               case 127117:
+               case 230400:
+               case 460800:
+               case 921600:
+               case 3686400:
+                       break;
+               default:
+                       baud = 9600;
+                       break;
                }
 
                if (baud) {
@@ -554,35 +551,35 @@ static void cp2101_set_termios (struct usb_serial_port *port,
                }
        }
        /* Report back the resulting baud rate */
-       tty_encode_baud_rate(port->tty, baud, baud);
+       tty_encode_baud_rate(tty, baud, baud);
 
        /* If the number of data bits is to be updated */
        if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
                cp2101_get_config(port, CP2101_BITS, &bits, 2);
                bits &= ~BITS_DATA_MASK;
                switch (cflag & CSIZE) {
-                       case CS5:
-                               bits |= BITS_DATA_5;
-                               dbg("%s - data bits = 5", __func__);
-                               break;
-                       case CS6:
-                               bits |= BITS_DATA_6;
-                               dbg("%s - data bits = 6", __func__);
-                               break;
-                       case CS7:
-                               bits |= BITS_DATA_7;
-                               dbg("%s - data bits = 7", __func__);
-                               break;
-                       case CS8:
-                               bits |= BITS_DATA_8;
-                               dbg("%s - data bits = 8", __func__);
-                               break;
-                       /*case CS9:
-                               bits |= BITS_DATA_9;
-                               dbg("%s - data bits = 9", __func__);
-                               break;*/
-                       default:
-                               dev_err(&port->dev, "cp2101 driver does not "
+               case CS5:
+                       bits |= BITS_DATA_5;
+                       dbg("%s - data bits = 5", __func__);
+                       break;
+               case CS6:
+                       bits |= BITS_DATA_6;
+                       dbg("%s - data bits = 6", __func__);
+                       break;
+               case CS7:
+                       bits |= BITS_DATA_7;
+                       dbg("%s - data bits = 7", __func__);
+                       break;
+               case CS8:
+                       bits |= BITS_DATA_8;
+                       dbg("%s - data bits = 8", __func__);
+                       break;
+               /*case CS9:
+                       bits |= BITS_DATA_9;
+                       dbg("%s - data bits = 9", __func__);
+                       break;*/
+               default:
+                       dev_err(&port->dev, "cp2101 driver does not "
                                        "support the number of bits requested,"
                                        " using 8 bit mode\n");
                                bits |= BITS_DATA_8;
@@ -651,10 +648,11 @@ static void cp2101_set_termios (struct usb_serial_port *port,
 
 }
 
-static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file,
+static int cp2101_tiocmset (struct tty_struct *tty, struct file *file,
                unsigned int set, unsigned int clear)
 {
-       int control = 0;
+       struct usb_serial_port *port = tty->driver_data;
+       unsigned int control = 0;
 
        dbg("%s - port %d", __func__, port->number);
 
@@ -681,9 +679,11 @@ static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file,
 
 }
 
-static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file)
+static int cp2101_tiocmget (struct tty_struct *tty, struct file *file)
 {
-       int control, result;
+       struct usb_serial_port *port = tty->driver_data;
+       unsigned int control;
+       int result;
 
        dbg("%s - port %d", __func__, port->number);
 
@@ -701,9 +701,10 @@ static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file)
        return result;
 }
 
-static void cp2101_break_ctl (struct usb_serial_port *port, int break_state)
+static void cp2101_break_ctl (struct tty_struct *tty, int break_state)
 {
-       int state;
+       struct usb_serial_port *port = tty->driver_data;
+       unsigned int state;
 
        dbg("%s - port %d", __func__, port->number);
        if (break_state == 0)
@@ -711,30 +712,29 @@ static void cp2101_break_ctl (struct usb_serial_port *port, int break_state)
        else
                state = BREAK_ON;
        dbg("%s - turning break %s", __func__,
-                       state==BREAK_OFF ? "off" : "on");
+                       state == BREAK_OFF ? "off" : "on");
        cp2101_set_config(port, CP2101_BREAK, &state, 2);
 }
 
-static int cp2101_startup (struct usb_serial *serial)
+static int cp2101_startup(struct usb_serial *serial)
 {
        /* CP2101 buffers behave strangely unless device is reset */
        usb_reset_device(serial->dev);
        return 0;
 }
 
-static void cp2101_shutdown (struct usb_serial *serial)
+static void cp2101_shutdown(struct usb_serial *serial)
 {
        int i;
 
        dbg("%s", __func__);
 
        /* Stop reads and writes on all ports */
-       for (i=0; i < serial->num_ports; ++i) {
+       for (i = 0; i < serial->num_ports; ++i)
                cp2101_cleanup(serial->port[i]);
-       }
 }
 
-static int __init cp2101_init (void)
+static int __init cp2101_init(void)
 {
        int retval;
 
@@ -754,10 +754,10 @@ static int __init cp2101_init (void)
        return 0;
 }
 
-static void __exit cp2101_exit (void)
+static void __exit cp2101_exit(void)
 {
-       usb_deregister (&cp2101_driver);
-       usb_serial_deregister (&cp2101_device);
+       usb_deregister(&cp2101_driver);
+       usb_serial_deregister(&cp2101_device);
 }
 
 module_init(cp2101_init);
index c164e2cf2752169e65a063e861557cf1d107ba60..b4d72351cb9697964fafc3ac8f2f1a4bf90cc15b 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
@@ -57,22 +57,25 @@ static int debug;
 #define CYBERJACK_PRODUCT_ID   0x0100
 
 /* Function prototypes */
-static int cyberjack_startup (struct usb_serial *serial);
-static void cyberjack_shutdown (struct usb_serial *serial);
-static int  cyberjack_open (struct usb_serial_port *port, struct file *filp);
-static void cyberjack_close (struct usb_serial_port *port, struct file *filp);
-static int cyberjack_write (struct usb_serial_port *port, const unsigned char *buf, int count);
-static int cyberjack_write_room( struct usb_serial_port *port );
-static void cyberjack_read_int_callback (struct urb *urb);
-static void cyberjack_read_bulk_callback (struct urb *urb);
-static void cyberjack_write_bulk_callback (struct urb *urb);
+static int cyberjack_startup(struct usb_serial *serial);
+static void cyberjack_shutdown(struct usb_serial *serial);
+static int  cyberjack_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static void cyberjack_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static int cyberjack_write(struct tty_struct *tty,
+       struct usb_serial_port *port, const unsigned char *buf, int count);
+static int cyberjack_write_room(struct tty_struct *tty);
+static void cyberjack_read_int_callback(struct urb *urb);
+static void cyberjack_read_bulk_callback(struct urb *urb);
+static void cyberjack_write_bulk_callback(struct urb *urb);
 
 static struct usb_device_id id_table [] = {
        { USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) },
        { }                     /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver cyberjack_driver = {
        .name =         "cyberjack",
@@ -111,7 +114,7 @@ struct cyberjack_private {
 };
 
 /* do some startup allocations not currently performed by usb_serial_probe() */
-static int cyberjack_startup (struct usb_serial *serial)
+static int cyberjack_startup(struct usb_serial *serial)
 {
        struct cyberjack_private *priv;
        int i;
@@ -135,20 +138,20 @@ static int cyberjack_startup (struct usb_serial *serial)
        for (i = 0; i < serial->num_ports; ++i) {
                int result;
                serial->port[i]->interrupt_in_urb->dev = serial->dev;
-               result = usb_submit_urb(serial->port[i]->interrupt_in_urb, 
+               result = usb_submit_urb(serial->port[i]->interrupt_in_urb,
                                        GFP_KERNEL);
                if (result)
                        err(" usb_submit_urb(read int) failed");
                dbg("%s - usb_submit_urb(int urb)", __func__);
        }
 
-       return( 0 );
+       return 0;
 }
 
-static void cyberjack_shutdown (struct usb_serial *serial)
+static void cyberjack_shutdown(struct usb_serial *serial)
 {
        int i;
-       
+
        dbg("%s", __func__);
 
        for (i = 0; i < serial->num_ports; ++i) {
@@ -158,8 +161,9 @@ static void cyberjack_shutdown (struct usb_serial *serial)
                usb_set_serial_port_data(serial->port[i], NULL);
        }
 }
-       
-static int  cyberjack_open (struct usb_serial_port *port, struct file *filp)
+
+static int  cyberjack_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct cyberjack_private *priv;
        unsigned long flags;
@@ -167,14 +171,15 @@ static int  cyberjack_open (struct usb_serial_port *port, struct file *filp)
 
        dbg("%s - port %d", __func__, port->number);
 
-       dbg("%s - usb_clear_halt", __func__ );
+       dbg("%s - usb_clear_halt", __func__);
        usb_clear_halt(port->serial->dev, port->write_urb->pipe);
 
        /* force low_latency on so that our tty_push actually forces
         * the data through, otherwise it is scheduled, and with high
         * data rates (like with OHCI) data can get lost.
         */
-       port->tty->low_latency = 1;
+       if (tty)
+               tty->low_latency = 1;
 
        priv = usb_get_serial_port_data(port);
        spin_lock_irqsave(&priv->lock, flags);
@@ -186,7 +191,8 @@ static int  cyberjack_open (struct usb_serial_port *port, struct file *filp)
        return result;
 }
 
-static void cyberjack_close (struct usb_serial_port *port, struct file *filp)
+static void cyberjack_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        dbg("%s - port %d", __func__, port->number);
 
@@ -197,7 +203,8 @@ static void cyberjack_close (struct usb_serial_port *port, struct file *filp)
        }
 }
 
-static int cyberjack_write (struct usb_serial_port *port, const unsigned char *buf, int count)
+static int cyberjack_write(struct tty_struct *tty,
+       struct usb_serial_port *port, const unsigned char *buf, int count)
 {
        struct usb_serial *serial = port->serial;
        struct cyberjack_private *priv = usb_get_serial_port_data(port);
@@ -223,7 +230,7 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       if( (count+priv->wrfilled) > sizeof(priv->wrbuf) ) {
+       if (count+priv->wrfilled > sizeof(priv->wrbuf)) {
                /* To much data for buffer. Reset buffer. */
                priv->wrfilled = 0;
                port->write_urb_busy = 0;
@@ -232,42 +239,43 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b
        }
 
        /* Copy data */
-       memcpy (priv->wrbuf+priv->wrfilled, buf, count);
+       memcpy(priv->wrbuf + priv->wrfilled, buf, count);
 
        usb_serial_debug_data(debug, &port->dev, __func__, count,
-               priv->wrbuf+priv->wrfilled);
+               priv->wrbuf + priv->wrfilled);
        priv->wrfilled += count;
 
-       if( priv->wrfilled >= 3 ) {
+       if (priv->wrfilled >= 3) {
                wrexpected = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
                dbg("%s - expected data: %d", __func__, wrexpected);
-       } else {
+       } else
                wrexpected = sizeof(priv->wrbuf);
-       }
 
-       if( priv->wrfilled >= wrexpected ) {
+       if (priv->wrfilled >= wrexpected) {
                /* We have enough data to begin transmission */
                int length;
 
                dbg("%s - transmitting data (frame 1)", __func__);
-               length = (wrexpected > port->bulk_out_size) ? port->bulk_out_size : wrexpected;
+               length = (wrexpected > port->bulk_out_size) ?
+                                       port->bulk_out_size : wrexpected;
 
-               memcpy (port->write_urb->transfer_buffer, priv->wrbuf, length );
-               priv->wrsent=length;
+               memcpy(port->write_urb->transfer_buffer, priv->wrbuf, length);
+               priv->wrsent = length;
 
                /* set up our urb */
-               usb_fill_bulk_urb(port->write_urb, serial->dev, 
+               usb_fill_bulk_urb(port->write_urb, serial->dev,
                              usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
                              port->write_urb->transfer_buffer, length,
-                             ((serial->type->write_bulk_callback) ? 
-                              serial->type->write_bulk_callback : 
-                              cyberjack_write_bulk_callback), 
+                             ((serial->type->write_bulk_callback) ?
+                              serial->type->write_bulk_callback :
+                              cyberjack_write_bulk_callback),
                              port);
 
                /* send the data out the bulk port */
                result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
                if (result) {
-                       err("%s - failed submitting write urb, error %d", __func__, result);
+                       err("%s - failed submitting write urb, error %d",
+                                                       __func__, result);
                        /* Throw away data. No better idea what to do with it. */
                        priv->wrfilled = 0;
                        priv->wrsent = 0;
@@ -276,12 +284,12 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b
                        return 0;
                }
 
-               dbg("%s - priv->wrsent=%d", __func__,priv->wrsent);
-               dbg("%s - priv->wrfilled=%d", __func__,priv->wrfilled);
+               dbg("%s - priv->wrsent=%d", __func__, priv->wrsent);
+               dbg("%s - priv->wrfilled=%d", __func__, priv->wrfilled);
 
-               if( priv->wrsent>=priv->wrfilled ) {
+               if (priv->wrsent >= priv->wrfilled) {
                        dbg("%s - buffer cleaned", __func__);
-                       memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
+                       memset(priv->wrbuf, 0, sizeof(priv->wrbuf));
                        priv->wrfilled = 0;
                        priv->wrsent = 0;
                }
@@ -289,16 +297,16 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       return (count);
-} 
+       return count;
+}
 
-static int cyberjack_write_room( struct usb_serial_port *port )
+static int cyberjack_write_room(struct tty_struct *tty)
 {
        /* FIXME: .... */
        return CYBERJACK_LOCAL_BUF_SIZE;
 }
 
-static void cyberjack_read_int_callback( struct urb *urb )
+static void cyberjack_read_int_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct cyberjack_private *priv = usb_get_serial_port_data(port);
@@ -312,10 +320,11 @@ static void cyberjack_read_int_callback( struct urb *urb )
        if (status)
                return;
 
-       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                                               urb->actual_length, data);
 
        /* React only to interrupts signaling a bulk_in transfer */
-       if( (urb->actual_length == 4) && (data[0] == 0x01) ) {
+       if (urb->actual_length == 4 && data[0] == 0x01) {
                short old_rdtodo;
 
                /* This is a announcement of coming bulk_ins. */
@@ -325,8 +334,8 @@ static void cyberjack_read_int_callback( struct urb *urb )
 
                old_rdtodo = priv->rdtodo;
 
-               if( (old_rdtodo+size)<(old_rdtodo) ) {
-                       dbg( "To many bulk_in urbs to do." );
+               if (old_rdtodo + size < old_rdtodo) {
+                       dbg("To many bulk_in urbs to do.");
                        spin_unlock(&priv->lock);
                        goto resubmit;
                }
@@ -338,10 +347,10 @@ static void cyberjack_read_int_callback( struct urb *urb )
 
                spin_unlock(&priv->lock);
 
-               if( !old_rdtodo ) {
+               if (!old_rdtodo) {
                        port->read_urb->dev = port->serial->dev;
                        result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
-                       if( result )
+                       if (result)
                                err("%s - failed resubmitting read urb, error %d", __func__, result);
                        dbg("%s - usb_submit_urb(read urb)", __func__);
                }
@@ -355,7 +364,7 @@ resubmit:
        dbg("%s - usb_submit_urb(int urb)", __func__);
 }
 
-static void cyberjack_read_bulk_callback (struct urb *urb)
+static void cyberjack_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct cyberjack_private *priv = usb_get_serial_port_data(port);
@@ -367,14 +376,15 @@ static void cyberjack_read_bulk_callback (struct urb *urb)
 
        dbg("%s - port %d", __func__, port->number);
 
-       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                                               urb->actual_length, data);
        if (status) {
                dbg("%s - nonzero read bulk status received: %d",
                    __func__, status);
                return;
        }
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (!tty) {
                dbg("%s - ignoring since device not open\n", __func__);
                return;
@@ -382,15 +392,16 @@ static void cyberjack_read_bulk_callback (struct urb *urb)
        if (urb->actual_length) {
                tty_buffer_request_room(tty, urb->actual_length);
                tty_insert_flip_string(tty, data, urb->actual_length);
-               tty_flip_buffer_push(tty);
+               tty_flip_buffer_push(tty);
        }
 
        spin_lock(&priv->lock);
 
        /* Reduce urbs to do by one. */
-       priv->rdtodo-=urb->actual_length;
+       priv->rdtodo -= urb->actual_length;
        /* Just to be sure */
-       if ( priv->rdtodo<0 ) priv->rdtodo = 0;
+       if (priv->rdtodo < 0)
+               priv->rdtodo = 0;
        todo = priv->rdtodo;
 
        spin_unlock(&priv->lock);
@@ -398,16 +409,17 @@ static void cyberjack_read_bulk_callback (struct urb *urb)
        dbg("%s - rdtodo: %d", __func__, todo);
 
        /* Continue to read if we have still urbs to do. */
-       if( todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) {
+       if (todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/) {
                port->read_urb->dev = port->serial->dev;
                result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
                if (result)
-                       err("%s - failed resubmitting read urb, error %d", __func__, result);
+                       err("%s - failed resubmitting read urb, error %d",
+                               __func__, result);
                dbg("%s - usb_submit_urb(read urb)", __func__);
        }
 }
 
-static void cyberjack_write_bulk_callback (struct urb *urb)
+static void cyberjack_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct cyberjack_private *priv = usb_get_serial_port_data(port);
@@ -425,7 +437,7 @@ static void cyberjack_write_bulk_callback (struct urb *urb)
        spin_lock(&priv->lock);
 
        /* only do something if we have more data to send */
-       if( priv->wrfilled ) {
+       if (priv->wrfilled) {
                int length, blksize, result;
 
                dbg("%s - transmitting data (frame n)", __func__);
@@ -433,37 +445,39 @@ static void cyberjack_write_bulk_callback (struct urb *urb)
                length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ?
                        port->bulk_out_size : (priv->wrfilled - priv->wrsent);
 
-               memcpy (port->write_urb->transfer_buffer, priv->wrbuf + priv->wrsent,
-                       length );
-               priv->wrsent+=length;
+               memcpy(port->write_urb->transfer_buffer,
+                                       priv->wrbuf + priv->wrsent, length);
+               priv->wrsent += length;
 
                /* set up our urb */
-               usb_fill_bulk_urb(port->write_urb, port->serial->dev, 
+               usb_fill_bulk_urb(port->write_urb, port->serial->dev,
                              usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress),
                              port->write_urb->transfer_buffer, length,
-                             ((port->serial->type->write_bulk_callback) ? 
-                              port->serial->type->write_bulk_callback : 
-                              cyberjack_write_bulk_callback), 
+                             ((port->serial->type->write_bulk_callback) ?
+                              port->serial->type->write_bulk_callback :
+                              cyberjack_write_bulk_callback),
                              port);
 
                /* send the data out the bulk port */
                result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
                if (result) {
-                       err("%s - failed submitting write urb, error %d", __func__, result);
+                       err("%s - failed submitting write urb, error %d",
+                                                               __func__, result);
                        /* Throw away data. No better idea what to do with it. */
                        priv->wrfilled = 0;
                        priv->wrsent = 0;
                        goto exit;
                }
 
-               dbg("%s - priv->wrsent=%d", __func__,priv->wrsent);
-               dbg("%s - priv->wrfilled=%d", __func__,priv->wrfilled);
+               dbg("%s - priv->wrsent=%d", __func__, priv->wrsent);
+               dbg("%s - priv->wrfilled=%d", __func__, priv->wrfilled);
 
                blksize = ((int)priv->wrbuf[2]<<8)+priv->wrbuf[1]+3;
 
-               if( (priv->wrsent>=priv->wrfilled) || (priv->wrsent>=blksize) ) {
+               if (priv->wrsent >= priv->wrfilled ||
+                                       priv->wrsent >= blksize) {
                        dbg("%s - buffer cleaned", __func__);
-                       memset( priv->wrbuf, 0, sizeof(priv->wrbuf) );
+                       memset(priv->wrbuf, 0, sizeof(priv->wrbuf));
                        priv->wrfilled = 0;
                        priv->wrsent = 0;
                }
@@ -474,14 +488,14 @@ exit:
        usb_serial_port_softint(port);
 }
 
-static int __init cyberjack_init (void)
+static int __init cyberjack_init(void)
 {
        int retval;
        retval  = usb_serial_register(&cyberjack_device);
        if (retval)
                goto failed_usb_serial_register;
        retval = usb_register(&cyberjack_driver);
-       if (retval) 
+       if (retval)
                goto failed_usb_register;
 
        info(DRIVER_VERSION " " DRIVER_AUTHOR);
@@ -494,18 +508,18 @@ failed_usb_serial_register:
        return retval;
 }
 
-static void __exit cyberjack_exit (void)
+static void __exit cyberjack_exit(void)
 {
-       usb_deregister (&cyberjack_driver);
-       usb_serial_deregister (&cyberjack_device);
+       usb_deregister(&cyberjack_driver);
+       usb_serial_deregister(&cyberjack_device);
 }
 
 module_init(cyberjack_init);
 module_exit(cyberjack_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_VERSION( DRIVER_VERSION );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
index 0230d3c0888af92e816d2d432f60a7171c4f547d..22837a3f2f899e963f0d944814d222bcd2e494f5 100644 (file)
@@ -2,7 +2,7 @@
  * USB Cypress M8 driver
  *
  *     Copyright (C) 2004
- *         Lonnie Mendez (dignome@gmail.com) 
+ *         Lonnie Mendez (dignome@gmail.com)
  *     Copyright (C) 2003,2004
  *         Neil Whelchel (koyama@firstlight.net)
  *
  *     the Free Software Foundation; either version 2 of the License, or
  *     (at your option) any later version.
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
  *
  * See http://geocities.com/i0xox0i for information on this driver and the
  * earthmate usb device.
  *
  *  Lonnie Mendez <dignome@gmail.com>
  *  4-29-2005
- *     Fixed problem where setting or retreiving the serial config would fail with
- *     EPIPE.  Removed CRTS toggling so the driver behaves more like other usbserial
- *     adapters.  Issued new interval of 1ms instead of the default 10ms.  As a
- *     result, transfer speed has been substantially increased.  From avg. 850bps to
- *     avg. 3300bps.  initial termios has also been modified.  Cleaned up code and
- *     formatting issues so it is more readable.  Replaced the C++ style comments.
+ *     Fixed problem where setting or retreiving the serial config would fail
+ *     with EPIPE.  Removed CRTS toggling so the driver behaves more like
+ *     other usbserial adapters.  Issued new interval of 1ms instead of the
+ *     default 10ms.  As a result, transfer speed has been substantially
+ *     increased from avg. 850bps to avg. 3300bps.  initial termios has also
+ *     been modified.  Cleaned up code and formatting issues so it is more
+ *     readable.  Replaced the C++ style comments.
  *
  *  Lonnie Mendez <dignome@gmail.com>
  *  12-15-2004
  *
  */
 
-/* Thanks to Neil Whelchel for writing the first cypress m8 implementation for linux. */
+/* Thanks to Neil Whelchel for writing the first cypress m8 implementation
+   for linux. */
 /* Thanks to cypress for providing references for the hid reports. */
 /* Thanks to Jiang Zhang for providing links and for general help. */
-/* Code originates and was built up from ftdi_sio, belkin, pl2303 and others. */
+/* Code originates and was built up from ftdi_sio, belkin, pl2303 and others.*/
 
 
 #include <linux/kernel.h>
@@ -62,7 +65,7 @@
 #include <linux/usb/serial.h>
 #include <linux/serial.h>
 #include <linux/delay.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 #include "cypress_m8.h"
 
@@ -112,7 +115,7 @@ static struct usb_device_id id_table_combined [] = {
        { }                                             /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
 
 static struct usb_driver cypress_driver = {
        .name =         "cypress",
@@ -146,11 +149,13 @@ struct cypress_private {
        __u8 rx_flags;                     /* throttling - used from whiteheat/ftdi_sio */
        enum packet_format pkt_fmt;        /* format to use for packet send / receive */
        int get_cfg_unsafe;                /* If true, the CYPRESS_GET_CONFIG is unsafe */
-       int baud_rate;                     /* stores current baud rate in integer form */
+       int baud_rate;                     /* stores current baud rate in
+                                             integer form */
        int isthrottled;                   /* if throttled, discard reads */
        wait_queue_head_t delta_msr_wait;  /* used for TIOCMIWAIT */
        char prev_status, diff_status;     /* used for TIOCMIWAIT */
-       /* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */
+       /* we pass a pointer to this as the arguement sent to
+          cypress_set_termios old_termios */
        struct ktermios tmp_termios;       /* stores the old termios settings */
 };
 
@@ -163,33 +168,41 @@ struct cypress_buf {
 };
 
 /* function prototypes for the Cypress USB to serial device */
-static int  cypress_earthmate_startup  (struct usb_serial *serial);
-static int  cypress_hidcom_startup     (struct usb_serial *serial);
-static int  cypress_ca42v2_startup     (struct usb_serial *serial);
-static void cypress_shutdown           (struct usb_serial *serial);
-static int  cypress_open               (struct usb_serial_port *port, struct file *filp);
-static void cypress_close              (struct usb_serial_port *port, struct file *filp);
-static int  cypress_write              (struct usb_serial_port *port, const unsigned char *buf, int count);
-static void cypress_send               (struct usb_serial_port *port);
-static int  cypress_write_room         (struct usb_serial_port *port);
-static int  cypress_ioctl              (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void cypress_set_termios                (struct usb_serial_port *port, struct ktermios * old);
-static int  cypress_tiocmget           (struct usb_serial_port *port, struct file *file);
-static int  cypress_tiocmset           (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
-static int  cypress_chars_in_buffer    (struct usb_serial_port *port);
-static void cypress_throttle           (struct usb_serial_port *port);
-static void cypress_unthrottle         (struct usb_serial_port *port);
-static void cypress_set_dead           (struct usb_serial_port *port);
-static void cypress_read_int_callback  (struct urb *urb);
-static void cypress_write_int_callback (struct urb *urb);
+static int  cypress_earthmate_startup(struct usb_serial *serial);
+static int  cypress_hidcom_startup(struct usb_serial *serial);
+static int  cypress_ca42v2_startup(struct usb_serial *serial);
+static void cypress_shutdown(struct usb_serial *serial);
+static int  cypress_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static void cypress_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static int  cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
+                       const unsigned char *buf, int count);
+static void cypress_send(struct usb_serial_port *port);
+static int  cypress_write_room(struct tty_struct *tty);
+static int  cypress_ioctl(struct tty_struct *tty, struct file *file,
+                       unsigned int cmd, unsigned long arg);
+static void cypress_set_termios(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct ktermios *old);
+static int  cypress_tiocmget(struct tty_struct *tty, struct file *file);
+static int  cypress_tiocmset(struct tty_struct *tty, struct file *file,
+                       unsigned int set, unsigned int clear);
+static int  cypress_chars_in_buffer(struct tty_struct *tty);
+static void cypress_throttle(struct tty_struct *tty);
+static void cypress_unthrottle(struct tty_struct *tty);
+static void cypress_set_dead(struct usb_serial_port *port);
+static void cypress_read_int_callback(struct urb *urb);
+static void cypress_write_int_callback(struct urb *urb);
 /* write buffer functions */
 static struct cypress_buf *cypress_buf_alloc(unsigned int size);
-static void              cypress_buf_free(struct cypress_buf *cb);
-static void              cypress_buf_clear(struct cypress_buf *cb);
-static unsigned int      cypress_buf_data_avail(struct cypress_buf *cb);
-static unsigned int      cypress_buf_space_avail(struct cypress_buf *cb);
-static unsigned int      cypress_buf_put(struct cypress_buf *cb, const char *buf, unsigned int count);
-static unsigned int      cypress_buf_get(struct cypress_buf *cb, char *buf, unsigned int count);
+static void cypress_buf_free(struct cypress_buf *cb);
+static void cypress_buf_clear(struct cypress_buf *cb);
+static unsigned int cypress_buf_data_avail(struct cypress_buf *cb);
+static unsigned int cypress_buf_space_avail(struct cypress_buf *cb);
+static unsigned int cypress_buf_put(struct cypress_buf *cb,
+                                       const char *buf, unsigned int count);
+static unsigned int cypress_buf_get(struct cypress_buf *cb,
+                                       char *buf, unsigned int count);
 
 
 static struct usb_serial_driver cypress_earthmate_device = {
@@ -247,7 +260,7 @@ static struct usb_serial_driver cypress_hidcom_device = {
 static struct usb_serial_driver cypress_ca42v2_device = {
        .driver = {
                .owner =                THIS_MODULE,
-                .name =                        "nokiaca42v2",
+               .name =                 "nokiaca42v2",
        },
        .description =                  "Nokia CA-42 V2 Adapter",
        .usb_driver =                   &cypress_driver,
@@ -322,8 +335,10 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate)
 
 
 /* This function can either set or retrieve the current serial line settings */
-static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_rate, int data_bits, int stop_bits,
-                                  int parity_enable, int parity_type, int reset, int cypress_request_type)
+static int cypress_serial_control(struct tty_struct *tty,
+       struct usb_serial_port *port, speed_t baud_rate, int data_bits,
+       int stop_bits, int parity_enable, int parity_type, int reset,
+       int cypress_request_type)
 {
        int new_baudrate = 0, retval = 0, tries = 0;
        struct cypress_private *priv;
@@ -331,111 +346,114 @@ static int cypress_serial_control (struct usb_serial_port *port, speed_t baud_ra
        unsigned long flags;
 
        dbg("%s", __func__);
-       
+
        priv = usb_get_serial_port_data(port);
 
        if (!priv->comm_is_ok)
                return -ENODEV;
 
-       switch(cypress_request_type) {
-               case CYPRESS_SET_CONFIG:
+       switch (cypress_request_type) {
+       case CYPRESS_SET_CONFIG:
+               new_baudrate = priv->baud_rate;
+               /* 0 means 'Hang up' so doesn't change the true bit rate */
+               if (baud_rate == 0)
                        new_baudrate = priv->baud_rate;
-                       /* 0 means 'Hang up' so doesn't change the true bit rate */
-                       if (baud_rate == 0)
-                               new_baudrate = priv->baud_rate;
-                       /* Change of speed ? */
-                       else if (baud_rate != priv->baud_rate) {
-                               dbg("%s - baud rate is changing", __func__);
-                               retval = analyze_baud_rate(port, baud_rate);
-                               if (retval >=  0) {
-                                       new_baudrate = retval;
-                                       dbg("%s - New baud rate set to %d",
-                                           __func__, new_baudrate);
-                               }
-                       }
-                       dbg("%s - baud rate is being sent as %d", __func__, new_baudrate);
-                       
-                       memset(feature_buffer, 0, sizeof(feature_buffer));
-                       /* fill the feature_buffer with new configuration */
-                       *((u_int32_t *)feature_buffer) = new_baudrate;
-
-                       feature_buffer[4] |= data_bits;   /* assign data bits in 2 bit space ( max 3 ) */
-                       /* 1 bit gap */
-                       feature_buffer[4] |= (stop_bits << 3);   /* assign stop bits in 1 bit space */
-                       feature_buffer[4] |= (parity_enable << 4);   /* assign parity flag in 1 bit space */
-                       feature_buffer[4] |= (parity_type << 5);   /* assign parity type in 1 bit space */
-                       /* 1 bit gap */
-                       feature_buffer[4] |= (reset << 7);   /* assign reset at end of byte, 1 bit space */
-                               
-                       dbg("%s - device is being sent this feature report:", __func__);
-                       dbg("%s - %02X - %02X - %02X - %02X - %02X", __func__, feature_buffer[0], feature_buffer[1],
-                           feature_buffer[2], feature_buffer[3], feature_buffer[4]);
-                       
-                       do {
-                               retval = usb_control_msg(port->serial->dev,
-                                               usb_sndctrlpipe(port->serial->dev, 0),
-                                               HID_REQ_SET_REPORT,
-                                               USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
-                                               0x0300, 0, feature_buffer,
-                                               sizeof(feature_buffer), 500);
-
-                               if (tries++ >= 3)
-                                       break;
-
-                       } while (retval != sizeof(feature_buffer) &&
-                                retval != -ENODEV);
-
-                       if (retval != sizeof(feature_buffer)) {
-                               err("%s - failed sending serial line settings - %d", __func__, retval);
-                               cypress_set_dead(port);
-                       } else {
-                               spin_lock_irqsave(&priv->lock, flags);
-                               priv->baud_rate = new_baudrate;
-                               priv->current_config = feature_buffer[4];
-                               spin_unlock_irqrestore(&priv->lock, flags);
-                               /* If we asked for a speed change encode it */
-                               if (baud_rate)
-                                       tty_encode_baud_rate(port->tty,
-                                                       new_baudrate, new_baudrate);
-                       }
-               break;
-               case CYPRESS_GET_CONFIG:
-                       if (priv->get_cfg_unsafe) {
-                               /* Not implemented for this device,
-                                  and if we try to do it we're likely
-                                  to crash the hardware. */
-                               return -ENOTTY;
-                       }
-                       dbg("%s - retreiving serial line settings", __func__);
-                       /* set initial values in feature buffer */
-                       memset(feature_buffer, 0, sizeof(feature_buffer));
-
-                       do {
-                               retval = usb_control_msg(port->serial->dev,
-                                               usb_rcvctrlpipe(port->serial->dev, 0),
-                                               HID_REQ_GET_REPORT,
-                                               USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
-                                               0x0300, 0, feature_buffer,
-                                               sizeof(feature_buffer), 500);
-
-                               if (tries++ >= 3)
-                                       break;
-
-                       } while (retval != sizeof(feature_buffer) &&
-                                retval != -ENODEV);
-
-                       if (retval != sizeof(feature_buffer)) {
-                               err("%s - failed to retrieve serial line settings - %d", __func__, retval);
-                               cypress_set_dead(port);
-                               return retval;
-                       } else {
-                               spin_lock_irqsave(&priv->lock, flags);
-
-                               /* store the config in one byte, and later use bit masks to check values */
-                               priv->current_config = feature_buffer[4];
-                               priv->baud_rate = *((u_int32_t *)feature_buffer);
-                               spin_unlock_irqrestore(&priv->lock, flags);
+               /* Change of speed ? */
+               else if (baud_rate != priv->baud_rate) {
+                       dbg("%s - baud rate is changing", __func__);
+                       retval = analyze_baud_rate(port, baud_rate);
+                       if (retval >=  0) {
+                               new_baudrate = retval;
+                               dbg("%s - New baud rate set to %d",
+                                   __func__, new_baudrate);
                        }
+               }
+               dbg("%s - baud rate is being sent as %d",
+                                       __func__, new_baudrate);
+
+               memset(feature_buffer, 0, sizeof(feature_buffer));
+               /* fill the feature_buffer with new configuration */
+               *((u_int32_t *)feature_buffer) = new_baudrate;
+               feature_buffer[4] |= data_bits;   /* assign data bits in 2 bit space ( max 3 ) */
+               /* 1 bit gap */
+               feature_buffer[4] |= (stop_bits << 3);   /* assign stop bits in 1 bit space */
+               feature_buffer[4] |= (parity_enable << 4);   /* assign parity flag in 1 bit space */
+               feature_buffer[4] |= (parity_type << 5);   /* assign parity type in 1 bit space */
+               /* 1 bit gap */
+               feature_buffer[4] |= (reset << 7);   /* assign reset at end of byte, 1 bit space */
+
+               dbg("%s - device is being sent this feature report:",
+                                                               __func__);
+               dbg("%s - %02X - %02X - %02X - %02X - %02X", __func__,
+                       feature_buffer[0], feature_buffer[1],
+                       feature_buffer[2], feature_buffer[3],
+                       feature_buffer[4]);
+
+               do {
+                       retval = usb_control_msg(port->serial->dev,
+                                       usb_sndctrlpipe(port->serial->dev, 0),
+                                       HID_REQ_SET_REPORT,
+                                       USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
+                                       0x0300, 0, feature_buffer,
+                                       sizeof(feature_buffer), 500);
+
+                       if (tries++ >= 3)
+                               break;
+
+               } while (retval != sizeof(feature_buffer) &&
+                        retval != -ENODEV);
+
+               if (retval != sizeof(feature_buffer)) {
+                       err("%s - failed sending serial line settings - %d",
+                                                       __func__, retval);
+                       cypress_set_dead(port);
+               } else {
+                       spin_lock_irqsave(&priv->lock, flags);
+                       priv->baud_rate = new_baudrate;
+                       priv->current_config = feature_buffer[4];
+                       spin_unlock_irqrestore(&priv->lock, flags);
+                       /* If we asked for a speed change encode it */
+                       if (baud_rate)
+                               tty_encode_baud_rate(tty,
+                                       new_baudrate, new_baudrate);
+               }
+       break;
+       case CYPRESS_GET_CONFIG:
+               if (priv->get_cfg_unsafe) {
+                       /* Not implemented for this device,
+                          and if we try to do it we're likely
+                          to crash the hardware. */
+                       return -ENOTTY;
+               }
+               dbg("%s - retreiving serial line settings", __func__);
+               /* set initial values in feature buffer */
+               memset(feature_buffer, 0, sizeof(feature_buffer));
+
+               do {
+                       retval = usb_control_msg(port->serial->dev,
+                                       usb_rcvctrlpipe(port->serial->dev, 0),
+                                       HID_REQ_GET_REPORT,
+                                       USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
+                                       0x0300, 0, feature_buffer,
+                                       sizeof(feature_buffer), 500);
+
+                       if (tries++ >= 3)
+                               break;
+               } while (retval != sizeof(feature_buffer)
+                                               && retval != -ENODEV);
+
+               if (retval != sizeof(feature_buffer)) {
+                       err("%s - failed to retrieve serial line settings - %d", __func__, retval);
+                       cypress_set_dead(port);
+                       return retval;
+               } else {
+                       spin_lock_irqsave(&priv->lock, flags);
+                       /* store the config in one byte, and later
+                          use bit masks to check values */
+                       priv->current_config = feature_buffer[4];
+                       priv->baud_rate = *((u_int32_t *)feature_buffer);
+                       spin_unlock_irqrestore(&priv->lock, flags);
+               }
        }
        spin_lock_irqsave(&priv->lock, flags);
        ++priv->cmd_count;
@@ -468,14 +486,14 @@ static void cypress_set_dead(struct usb_serial_port *port)
  *****************************************************************************/
 
 
-static int generic_startup (struct usb_serial *serial)
+static int generic_startup(struct usb_serial *serial)
 {
        struct cypress_private *priv;
        struct usb_serial_port *port = serial->port[0];
 
        dbg("%s - port %d", __func__, port->number);
 
-       priv = kzalloc(sizeof (struct cypress_private), GFP_KERNEL);
+       priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
@@ -487,9 +505,9 @@ static int generic_startup (struct usb_serial *serial)
                return -ENOMEM;
        }
        init_waitqueue_head(&priv->delta_msr_wait);
-       
-       usb_reset_configuration (serial->dev);
-       
+
+       usb_reset_configuration(serial->dev);
+
        priv->cmd_ctrl = 0;
        priv->line_control = 0;
        priv->termios_initialized = 0;
@@ -500,30 +518,30 @@ static int generic_startup (struct usb_serial *serial)
           small.  Otherwise we can use the slightly more compact
           format.  This is in accordance with the cypress_m8 serial
           converter app note. */
-       if (port->interrupt_out_size > 9) {
+       if (port->interrupt_out_size > 9)
                priv->pkt_fmt = packet_format_1;
-       } else {
+       else
                priv->pkt_fmt = packet_format_2;
-       }
+
        if (interval > 0) {
                priv->write_urb_interval = interval;
                priv->read_urb_interval = interval;
                dbg("%s - port %d read & write intervals forced to %d",
-                   __func__,port->number,interval);
+                   __func__, port->number, interval);
        } else {
                priv->write_urb_interval = port->interrupt_out_urb->interval;
                priv->read_urb_interval = port->interrupt_in_urb->interval;
                dbg("%s - port %d intervals: read=%d write=%d",
-                   __func__,port->number,
-                   priv->read_urb_interval,priv->write_urb_interval);
+                   __func__, port->number,
+                   priv->read_urb_interval, priv->write_urb_interval);
        }
        usb_set_serial_port_data(port, priv);
-       
+
        return 0;
 }
 
 
-static int cypress_earthmate_startup (struct usb_serial *serial)
+static int cypress_earthmate_startup(struct usb_serial *serial)
 {
        struct cypress_private *priv;
        struct usb_serial_port *port = serial->port[0];
@@ -541,7 +559,8 @@ static int cypress_earthmate_startup (struct usb_serial *serial)
        /* All Earthmate devices use the separated-count packet
           format!  Idiotic. */
        priv->pkt_fmt = packet_format_1;
-       if (serial->dev->descriptor.idProduct != cpu_to_le16(PRODUCT_ID_EARTHMATEUSB)) {
+       if (serial->dev->descriptor.idProduct !=
+                               cpu_to_le16(PRODUCT_ID_EARTHMATEUSB)) {
                /* The old original USB Earthmate seemed able to
                   handle GET_CONFIG requests; everything they've
                   produced since that time crashes if this command is
@@ -555,7 +574,7 @@ static int cypress_earthmate_startup (struct usb_serial *serial)
 } /* cypress_earthmate_startup */
 
 
-static int cypress_hidcom_startup (struct usb_serial *serial)
+static int cypress_hidcom_startup(struct usb_serial *serial)
 {
        struct cypress_private *priv;
 
@@ -569,12 +588,12 @@ static int cypress_hidcom_startup (struct usb_serial *serial)
 
        priv = usb_get_serial_port_data(serial->port[0]);
        priv->chiptype = CT_CYPHIDCOM;
-       
+
        return 0;
 } /* cypress_hidcom_startup */
 
 
-static int cypress_ca42v2_startup (struct usb_serial *serial)
+static int cypress_ca42v2_startup(struct usb_serial *serial)
 {
        struct cypress_private *priv;
 
@@ -593,11 +612,11 @@ static int cypress_ca42v2_startup (struct usb_serial *serial)
 } /* cypress_ca42v2_startup */
 
 
-static void cypress_shutdown (struct usb_serial *serial)
+static void cypress_shutdown(struct usb_serial *serial)
 {
        struct cypress_private *priv;
 
-       dbg ("%s - port %d", __func__, serial->port[0]->number);
+       dbg("%s - port %d", __func__, serial->port[0]->number);
 
        /* all open ports are closed at this point */
 
@@ -611,7 +630,8 @@ static void cypress_shutdown (struct usb_serial *serial)
 }
 
 
-static int cypress_open (struct usb_serial_port *port, struct file *filp)
+static int cypress_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct cypress_private *priv = usb_get_serial_port_data(port);
        struct usb_serial *serial = port->serial;
@@ -636,37 +656,44 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
        spin_unlock_irqrestore(&priv->lock, flags);
 
        /* setting to zero could cause data loss */
-       port->tty->low_latency = 1;
+       if (tty)
+               tty->low_latency = 1;
 
        /* raise both lines and set termios */
        spin_lock_irqsave(&priv->lock, flags);
        priv->line_control = CONTROL_DTR | CONTROL_RTS;
        priv->cmd_ctrl = 1;
        spin_unlock_irqrestore(&priv->lock, flags);
-       result = cypress_write(port, NULL, 0);
+       result = cypress_write(tty, port, NULL, 0);
 
        if (result) {
-               dev_err(&port->dev, "%s - failed setting the control lines - error %d\n", __func__, result);
+               dev_err(&port->dev,
+                       "%s - failed setting the control lines - error %d\n",
+                                                       __func__, result);
                return result;
        } else
                dbg("%s - success setting the control lines", __func__);
 
-       cypress_set_termios(port, &priv->tmp_termios);
+       if (tty)
+               cypress_set_termios(tty, port, &priv->tmp_termios);
 
        /* setup the port and start reading from the device */
-       if(!port->interrupt_in_urb){
+       if (!port->interrupt_in_urb) {
                err("%s - interrupt_in_urb is empty!", __func__);
-               return(-1);
+               return -1;
        }
 
        usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
                usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
-               port->interrupt_in_urb->transfer_buffer, port->interrupt_in_urb->transfer_buffer_length,
+               port->interrupt_in_urb->transfer_buffer,
+               port->interrupt_in_urb->transfer_buffer_length,
                cypress_read_int_callback, port, priv->read_urb_interval);
        result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 
-       if (result){
-               dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result);
+       if (result) {
+               dev_err(&port->dev,
+                       "%s - failed submitting read urb, error %d\n",
+                                                       __func__, result);
                cypress_set_dead(port);
        }
 
@@ -674,7 +701,8 @@ static int cypress_open (struct usb_serial_port *port, struct file *filp)
 } /* cypress_open */
 
 
-static void cypress_close(struct usb_serial_port *port, struct file * filp)
+static void cypress_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct cypress_private *priv = usb_get_serial_port_data(port);
        unsigned int c_cflag;
@@ -688,7 +716,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
        spin_lock_irq(&priv->lock);
        timeout = CYPRESS_CLOSING_WAIT;
        init_waitqueue_entry(&wait, current);
-       add_wait_queue(&port->tty->write_wait, &wait);
+       add_wait_queue(&tty->write_wait, &wait);
        for (;;) {
                set_current_state(TASK_INTERRUPTIBLE);
                if (cypress_buf_data_avail(priv->buf) == 0
@@ -701,7 +729,7 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
                spin_lock_irq(&priv->lock);
        }
        set_current_state(TASK_RUNNING);
-       remove_wait_queue(&port->tty->write_wait, &wait);
+       remove_wait_queue(&tty->write_wait, &wait);
        /* clear out any remaining data in the buffer */
        cypress_buf_clear(priv->buf);
        spin_unlock_irq(&priv->lock);
@@ -713,19 +741,21 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
                return;
        }
        /* wait for characters to drain from device */
-       bps = tty_get_baud_rate(port->tty);
-       if (bps > 1200)
-               timeout = max((HZ*2560)/bps,HZ/10);
-       else
-               timeout = 2*HZ;
-       schedule_timeout_interruptible(timeout);
+       if (tty) {
+               bps = tty_get_baud_rate(tty);
+               if (bps > 1200)
+                       timeout = max((HZ * 2560) / bps, HZ / 10);
+               else
+                       timeout = 2 * HZ;
+               schedule_timeout_interruptible(timeout);
+       }
 
        dbg("%s - stopping urbs", __func__);
-       usb_kill_urb (port->interrupt_in_urb);
-       usb_kill_urb (port->interrupt_out_urb);
+       usb_kill_urb(port->interrupt_in_urb);
+       usb_kill_urb(port->interrupt_out_urb);
 
-       if (port->tty) {
-               c_cflag = port->tty->termios->c_cflag;
+       if (tty) {
+               c_cflag = tty->termios->c_cflag;
                if (c_cflag & HUPCL) {
                        /* drop dtr and rts */
                        priv = usb_get_serial_port_data(port);
@@ -733,22 +763,23 @@ static void cypress_close(struct usb_serial_port *port, struct file * filp)
                        priv->line_control = 0;
                        priv->cmd_ctrl = 1;
                        spin_unlock_irq(&priv->lock);
-                       cypress_write(port, NULL, 0);
+                       cypress_write(tty, port, NULL, 0);
                }
        }
 
        if (stats)
-               dev_info (&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",
-                         priv->bytes_in, priv->bytes_out, priv->cmd_count);
+               dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",
+                       priv->bytes_in, priv->bytes_out, priv->cmd_count);
        mutex_unlock(&port->serial->disc_mutex);
 } /* cypress_close */
 
 
-static int cypress_write(struct usb_serial_port *port, const unsigned char *buf, int count)
+static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                       const unsigned char *buf, int count)
 {
        struct cypress_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
-       
+
        dbg("%s - port %d, %d bytes", __func__, port->number, count);
 
        /* line control commands, which need to be executed immediately,
@@ -758,10 +789,10 @@ static int cypress_write(struct usb_serial_port *port, const unsigned char *buf,
                count = 0;
                goto finish;
        }
-       
+
        if (!count)
                return count;
-       
+
        spin_lock_irqsave(&priv->lock, flags);
        count = cypress_buf_put(priv->buf, buf, count);
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -778,13 +809,14 @@ static void cypress_send(struct usb_serial_port *port)
        int count = 0, result, offset, actual_size;
        struct cypress_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
-       
+
        if (!priv->comm_is_ok)
                return;
 
        dbg("%s - port %d", __func__, port->number);
-       dbg("%s - interrupt out size is %d", __func__, port->interrupt_out_size);
-       
+       dbg("%s - interrupt out size is %d", __func__,
+                                               port->interrupt_out_size);
+
        spin_lock_irqsave(&priv->lock, flags);
        if (priv->write_urb_in_use) {
                dbg("%s - can't write, urb in use", __func__);
@@ -794,7 +826,8 @@ static void cypress_send(struct usb_serial_port *port)
        spin_unlock_irqrestore(&priv->lock, flags);
 
        /* clear buffer */
-       memset(port->interrupt_out_urb->transfer_buffer, 0, port->interrupt_out_size);
+       memset(port->interrupt_out_urb->transfer_buffer, 0,
+                                               port->interrupt_out_size);
 
        spin_lock_irqsave(&priv->lock, flags);
        switch (priv->pkt_fmt) {
@@ -825,9 +858,8 @@ static void cypress_send(struct usb_serial_port *port)
        count = cypress_buf_get(priv->buf, &port->interrupt_out_buffer[offset],
                                port->interrupt_out_size-offset);
 
-       if (count == 0) {
+       if (count == 0)
                return;
-       }
 
        switch (priv->pkt_fmt) {
        default:
@@ -851,26 +883,29 @@ send:
                actual_size = count +
                              (priv->pkt_fmt == packet_format_1 ? 2 : 1);
 
-       usb_serial_debug_data(debug, &port->dev, __func__, port->interrupt_out_size,
-                             port->interrupt_out_urb->transfer_buffer);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+               port->interrupt_out_size,
+               port->interrupt_out_urb->transfer_buffer);
 
        usb_fill_int_urb(port->interrupt_out_urb, port->serial->dev,
                usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress),
                port->interrupt_out_buffer, port->interrupt_out_size,
                cypress_write_int_callback, port, priv->write_urb_interval);
-       result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC);
+       result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
        if (result) {
-               dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__,
-                       result);
+               dev_err(&port->dev,
+                               "%s - failed submitting write urb, error %d\n",
+                                                       __func__, result);
                priv->write_urb_in_use = 0;
                cypress_set_dead(port);
        }
 
        spin_lock_irqsave(&priv->lock, flags);
-       if (priv->cmd_ctrl) {
+       if (priv->cmd_ctrl)
                priv->cmd_ctrl = 0;
-       }
-       priv->bytes_out += count; /* do not count the line control and size bytes */
+
+       /* do not count the line control and size bytes */
+       priv->bytes_out += count;
        spin_unlock_irqrestore(&priv->lock, flags);
 
        usb_serial_port_softint(port);
@@ -878,8 +913,9 @@ send:
 
 
 /* returns how much space is available in the soft buffer */
-static int cypress_write_room(struct usb_serial_port *port)
+static int cypress_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct cypress_private *priv = usb_get_serial_port_data(port);
        int room = 0;
        unsigned long flags;
@@ -895,13 +931,14 @@ static int cypress_write_room(struct usb_serial_port *port)
 }
 
 
-static int cypress_tiocmget (struct usb_serial_port *port, struct file *file)
+static int cypress_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct cypress_private *priv = usb_get_serial_port_data(port);
        __u8 status, control;
        unsigned int result = 0;
        unsigned long flags;
-       
+
        dbg("%s - port %d", __func__, port->number);
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -922,12 +959,13 @@ static int cypress_tiocmget (struct usb_serial_port *port, struct file *file)
 }
 
 
-static int cypress_tiocmset (struct usb_serial_port *port, struct file *file,
+static int cypress_tiocmset(struct tty_struct *tty, struct file *file,
                               unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct cypress_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
-       
+
        dbg("%s - port %d", __func__, port->number);
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -942,63 +980,60 @@ static int cypress_tiocmset (struct usb_serial_port *port, struct file *file,
        priv->cmd_ctrl = 1;
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       return cypress_write(port, NULL, 0);
+       return cypress_write(tty, port, NULL, 0);
 }
 
 
-static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
+static int cypress_ioctl(struct tty_struct *tty, struct file *file,
+                                       unsigned int cmd, unsigned long arg)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct cypress_private *priv = usb_get_serial_port_data(port);
 
        dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
 
        switch (cmd) {
-               /* This code comes from drivers/char/serial.c and ftdi_sio.c */
-               case TIOCMIWAIT:
-                       while (priv != NULL) {
-                               interruptible_sleep_on(&priv->delta_msr_wait);
-                               /* see if a signal did it */
-                               if (signal_pending(current))
-                                       return -ERESTARTSYS;
-                               else {
-                                       char diff = priv->diff_status;
-
-                                       if (diff == 0) {
-                                               return -EIO; /* no change => error */
-                                       }
-                                       
-                                       /* consume all events */
-                                       priv->diff_status = 0;
-
-                                       /* return 0 if caller wanted to know about these bits */
-                                       if ( ((arg & TIOCM_RNG) && (diff & UART_RI)) ||
-                                            ((arg & TIOCM_DSR) && (diff & UART_DSR)) ||
-                                            ((arg & TIOCM_CD) && (diff & UART_CD)) ||
-                                            ((arg & TIOCM_CTS) && (diff & UART_CTS)) ) {
-                                               return 0;
-                                       }
-                                       /* otherwise caller can't care less about what happened,
-                                        * and so we continue to wait for more events.
-                                        */
-                               }
+       /* This code comes from drivers/char/serial.c and ftdi_sio.c */
+       case TIOCMIWAIT:
+               while (priv != NULL) {
+                       interruptible_sleep_on(&priv->delta_msr_wait);
+                       /* see if a signal did it */
+                       if (signal_pending(current))
+                               return -ERESTARTSYS;
+                       else {
+                               char diff = priv->diff_status;
+                               if (diff == 0)
+                                       return -EIO; /* no change => error */
+
+                               /* consume all events */
+                               priv->diff_status = 0;
+
+                               /* return 0 if caller wanted to know about
+                                  these bits */
+                               if (((arg & TIOCM_RNG) && (diff & UART_RI)) ||
+                                   ((arg & TIOCM_DSR) && (diff & UART_DSR)) ||
+                                   ((arg & TIOCM_CD) && (diff & UART_CD)) ||
+                                   ((arg & TIOCM_CTS) && (diff & UART_CTS)))
+                                       return 0;
+                               /* otherwise caller can't care less about what
+                                * happened, and so we continue to wait for
+                                * more events.
+                                */
                        }
-                       return 0;
-                       break;
-               default:
-                       break;
+               }
+               return 0;
+       default:
+               break;
        }
-
        dbg("%s - arg not supported - it was 0x%04x - check include/asm/ioctls.h", __func__, cmd);
-
        return -ENOIOCTLCMD;
 } /* cypress_ioctl */
 
 
-static void cypress_set_termios (struct usb_serial_port *port,
-               struct ktermios *old_termios)
+static void cypress_set_termios(struct tty_struct *tty,
+       struct usb_serial_port *port, struct ktermios *old_termios)
 {
        struct cypress_private *priv = usb_get_serial_port_data(port);
-       struct tty_struct *tty;
        int data_bits, stop_bits, parity_type, parity_enable;
        unsigned cflag, iflag;
        unsigned long flags;
@@ -1007,8 +1042,6 @@ static void cypress_set_termios (struct usb_serial_port *port,
 
        dbg("%s - port %d", __func__, port->number);
 
-       tty = port->tty;
-
        spin_lock_irqsave(&priv->lock, flags);
        if (!priv->termios_initialized) {
                if (priv->chiptype == CT_EARTHMATE) {
@@ -1060,28 +1093,24 @@ static void cypress_set_termios (struct usb_serial_port *port,
        } else
                parity_enable = parity_type = 0;
 
-       if (cflag & CSIZE) {
-               switch (cflag & CSIZE) {
-                       case CS5:
-                               data_bits = 0;
-                               break;
-                       case CS6:
-                               data_bits = 1;
-                               break;
-                       case CS7:
-                               data_bits = 2;
-                               break;
-                       case CS8:
-                               data_bits = 3;
-                               break;
-                       default:
-                               err("%s - CSIZE was set, but not CS5-CS8",
-                                               __func__);
-                               data_bits = 3;
-               }
-       } else
+       switch (cflag & CSIZE) {
+       case CS5:
+               data_bits = 0;
+               break;
+       case CS6:
+               data_bits = 1;
+               break;
+       case CS7:
+               data_bits = 2;
+               break;
+       case CS8:
                data_bits = 3;
-
+               break;
+       default:
+               err("%s - CSIZE was set, but not CS5-CS8",
+                               __func__);
+               data_bits = 3;
+       }
        spin_lock_irqsave(&priv->lock, flags);
        oldlines = priv->line_control;
        if ((cflag & CBAUD) == B0) {
@@ -1096,19 +1125,21 @@ static void cypress_set_termios (struct usb_serial_port *port,
                        "%d data_bits (+5)", __func__, stop_bits,
                        parity_enable, parity_type, data_bits);
 
-       cypress_serial_control(port, tty_get_baud_rate(tty), data_bits, stop_bits,
-                       parity_enable, parity_type, 0, CYPRESS_SET_CONFIG);
+       cypress_serial_control(tty, port, tty_get_baud_rate(tty),
+                       data_bits, stop_bits,
+                       parity_enable, parity_type,
+                       0, CYPRESS_SET_CONFIG);
 
        /* we perform a CYPRESS_GET_CONFIG so that the current settings are
         * filled into the private structure this should confirm that all is
         * working if it returns what we just set */
-       cypress_serial_control(port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
+       cypress_serial_control(tty, port, 0, 0, 0, 0, 0, 0, CYPRESS_GET_CONFIG);
 
        /* Here we can define custom tty settings for devices; the main tty
         * termios flag base comes from empeg.c */
 
        spin_lock_irqsave(&priv->lock, flags);
-       if ( (priv->chiptype == CT_EARTHMATE) && (priv->baud_rate == 4800) ) {
+       if (priv->chiptype == CT_EARTHMATE && priv->baud_rate == 4800) {
                dbg("Using custom termios settings for a baud rate of "
                                "4800bps.");
                /* define custom termios settings for NMEA protocol */
@@ -1142,20 +1173,21 @@ static void cypress_set_termios (struct usb_serial_port *port,
        /* if necessary, set lines */
        if (linechange) {
                priv->cmd_ctrl = 1;
-               cypress_write(port, NULL, 0);
+               cypress_write(tty, port, NULL, 0);
        }
 } /* cypress_set_termios */
 
 
 /* returns amount of data still left in soft buffer */
-static int cypress_chars_in_buffer(struct usb_serial_port *port)
+static int cypress_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct cypress_private *priv = usb_get_serial_port_data(port);
        int chars = 0;
        unsigned long flags;
 
        dbg("%s - port %d", __func__, port->number);
-       
+
        spin_lock_irqsave(&priv->lock, flags);
        chars = cypress_buf_data_avail(priv->buf);
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -1165,8 +1197,9 @@ static int cypress_chars_in_buffer(struct usb_serial_port *port)
 }
 
 
-static void cypress_throttle (struct usb_serial_port *port)
+static void cypress_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct cypress_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
 
@@ -1178,8 +1211,9 @@ static void cypress_throttle (struct usb_serial_port *port)
 }
 
 
-static void cypress_unthrottle (struct usb_serial_port *port)
+static void cypress_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct cypress_private *priv = usb_get_serial_port_data(port);
        int actually_throttled, result;
        unsigned long flags;
@@ -1232,12 +1266,13 @@ static void cypress_read_int_callback(struct urb *urb)
                /* precursor to disconnect so just go away */
                return;
        case -EPIPE:
-               usb_clear_halt(port->serial->dev,0x81);
+               usb_clear_halt(port->serial->dev, 0x81);
                break;
        default:
                /* something ugly is going on... */
-               dev_err(&urb->dev->dev,"%s - unexpected nonzero read status received: %d\n",
-                       __func__, status);
+               dev_err(&urb->dev->dev,
+                       "%s - unexpected nonzero read status received: %d\n",
+                                                       __func__, status);
                cypress_set_dead(port);
                return;
        }
@@ -1251,7 +1286,7 @@ static void cypress_read_int_callback(struct urb *urb)
        }
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (!tty) {
                dbg("%s - bad tty pointer - exiting", __func__);
                return;
@@ -1285,8 +1320,8 @@ static void cypress_read_int_callback(struct urb *urb)
                goto continue_read;
        }
 
-       usb_serial_debug_data (debug, &port->dev, __func__,
-                       urb->actual_length, data);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                                               urb->actual_length, data);
 
        spin_lock_irqsave(&priv->lock, flags);
        /* check to see if status has changed */
@@ -1327,7 +1362,7 @@ static void cypress_read_int_callback(struct urb *urb)
                                        data[i]);
                        tty_insert_flip_char(tty, data[i], tty_flag);
                }
-               tty_flip_buffer_push(port->tty);
+               tty_flip_buffer_push(port->port.tty);
        }
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -1339,13 +1374,14 @@ continue_read:
 
        /* Continue trying to always read... unless the port has closed. */
 
-       if (port->open_count > 0 && priv->comm_is_ok) {
+       if (port->port.count > 0 && priv->comm_is_ok) {
                usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev,
                                usb_rcvintpipe(port->serial->dev,
                                        port->interrupt_in_endpointAddress),
                                port->interrupt_in_urb->transfer_buffer,
                                port->interrupt_in_urb->transfer_buffer_length,
-                               cypress_read_int_callback, port, priv->read_urb_interval);
+                               cypress_read_int_callback, port,
+                               priv->read_urb_interval);
                result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
                if (result) {
                        dev_err(&urb->dev->dev, "%s - failed resubmitting "
@@ -1369,42 +1405,43 @@ static void cypress_write_int_callback(struct urb *urb)
        dbg("%s - port %d", __func__, port->number);
 
        switch (status) {
-               case 0:
-                       /* success */
+       case 0:
+               /* success */
+               break;
+       case -ECONNRESET:
+       case -ENOENT:
+       case -ESHUTDOWN:
+               /* this urb is terminated, clean up */
+               dbg("%s - urb shutting down with status: %d",
+                                               __func__, status);
+               priv->write_urb_in_use = 0;
+               return;
+       case -EPIPE: /* no break needed; clear halt and resubmit */
+               if (!priv->comm_is_ok)
                        break;
-               case -ECONNRESET:
-               case -ENOENT:
-               case -ESHUTDOWN:
-                       /* this urb is terminated, clean up */
-                       dbg("%s - urb shutting down with status: %d",
-                           __func__, status);
-                       priv->write_urb_in_use = 0;
+               usb_clear_halt(port->serial->dev, 0x02);
+               /* error in the urb, so we have to resubmit it */
+               dbg("%s - nonzero write bulk status received: %d",
+                       __func__, status);
+               port->interrupt_out_urb->transfer_buffer_length = 1;
+               port->interrupt_out_urb->dev = port->serial->dev;
+               result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
+               if (!result)
                        return;
-               case -EPIPE: /* no break needed; clear halt and resubmit */
-                       if (!priv->comm_is_ok)
-                               break;
-                       usb_clear_halt(port->serial->dev, 0x02);
-                       /* error in the urb, so we have to resubmit it */
-                       dbg("%s - nonzero write bulk status received: %d",
-                           __func__, status);
-                       port->interrupt_out_urb->transfer_buffer_length = 1;
-                       port->interrupt_out_urb->dev = port->serial->dev;
-                       result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
-                       if (!result)
-                               return;
-                       dev_err(&urb->dev->dev, "%s - failed resubmitting write urb, error %d\n",
-                               __func__, result);
-                       cypress_set_dead(port);
-                       break;
-               default:
-                       dev_err(&urb->dev->dev,"%s - unexpected nonzero write status received: %d\n",
-                               __func__, status);
-                       cypress_set_dead(port);
-                       break;
+               dev_err(&urb->dev->dev,
+                       "%s - failed resubmitting write urb, error %d\n",
+                                                       __func__, result);
+               cypress_set_dead(port);
+               break;
+       default:
+               dev_err(&urb->dev->dev,
+                        "%s - unexpected nonzero write status received: %d\n",
+                                                       __func__, status);
+               cypress_set_dead(port);
+               break;
        }
-       
        priv->write_urb_in_use = 0;
-       
+
        /* send any buffered data */
        cypress_send(port);
 }
@@ -1486,7 +1523,8 @@ static void cypress_buf_clear(struct cypress_buf *cb)
 static unsigned int cypress_buf_data_avail(struct cypress_buf *cb)
 {
        if (cb != NULL)
-               return ((cb->buf_size + cb->buf_put - cb->buf_get) % cb->buf_size);
+               return (cb->buf_size + cb->buf_put - cb->buf_get)
+                                                       % cb->buf_size;
        else
                return 0;
 }
@@ -1502,7 +1540,8 @@ static unsigned int cypress_buf_data_avail(struct cypress_buf *cb)
 static unsigned int cypress_buf_space_avail(struct cypress_buf *cb)
 {
        if (cb != NULL)
-               return ((cb->buf_size + cb->buf_get - cb->buf_put - 1) % cb->buf_size);
+               return (cb->buf_size + cb->buf_get - cb->buf_put - 1)
+                                                       % cb->buf_size;
        else
                return 0;
 }
@@ -1602,9 +1641,9 @@ static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf,
 static int __init cypress_init(void)
 {
        int retval;
-       
+
        dbg("%s", __func__);
-       
+
        retval = usb_serial_register(&cypress_earthmate_device);
        if (retval)
                goto failed_em_register;
@@ -1632,23 +1671,23 @@ failed_em_register:
 }
 
 
-static void __exit cypress_exit (void)
+static void __exit cypress_exit(void)
 {
        dbg("%s", __func__);
 
-       usb_deregister (&cypress_driver);
-       usb_serial_deregister (&cypress_earthmate_device);
-       usb_serial_deregister (&cypress_hidcom_device);
-       usb_serial_deregister (&cypress_ca42v2_device);
+       usb_deregister(&cypress_driver);
+       usb_serial_deregister(&cypress_earthmate_device);
+       usb_serial_deregister(&cypress_hidcom_device);
+       usb_serial_deregister(&cypress_ca42v2_device);
 }
 
 
 module_init(cypress_init);
 module_exit(cypress_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_VERSION( DRIVER_VERSION );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
index 0388065bb79451997f35edbdc7cd52f004d683ea..e772b01ac3ac0a6159b508dced9cb2132d0b8222 100644 (file)
@@ -54,7 +54,7 @@
 #define UART_DSR       0x20    /* data set ready - flow control - device to host */
 #define CONTROL_RTS    0x10    /* request to send - flow control - host to device */
 #define UART_CTS       0x10    /* clear to send - flow control - device to host */
-#define        UART_RI         0x10    /* ring indicator - modem - device to host */ 
+#define        UART_RI         0x10    /* ring indicator - modem - device to host */
 #define UART_CD                0x40    /* carrier detect - modem - device to host */
 #define CYP_ERROR      0x08    /* received from input report - device to host */
 /* Note - the below has nothing to to with the "feature report" reset */
index 04a56f300ea68059ce54d7f803408737562855ab..240aad1acaab80f8a802b6b67cd4f3ffed911a9d 100644 (file)
@@ -15,7 +15,7 @@
 *  Al Borchers (borchers@steinerpoint.com)
 * 
 * (12/03/2001) gkh
-*      switched to using port->open_count instead of private version.
+*      switched to using port->port.count instead of private version.
 *      Removed port->active
 *
 * (04/08/2001) gb
 *    in case a wake up is lost.
 *  - Following Documentation/DocBook/kernel-locking.pdf no spin locks
 *    are held when calling copy_to/from_user or printk.
-*    
-*  $Id: digi_acceleport.c,v 1.80.1.2 2000/11/02 05:45:08 root Exp $
 */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/wait.h>
 #include <linux/usb/serial.h>
@@ -443,22 +441,23 @@ static int digi_set_modem_signals(struct usb_serial_port *port,
        unsigned int modem_signals, int interruptible);
 static int digi_transmit_idle(struct usb_serial_port *port,
        unsigned long timeout);
-static void digi_rx_throttle (struct usb_serial_port *port);
-static void digi_rx_unthrottle (struct usb_serial_port *port);
-static void digi_set_termios(struct usb_serial_port *port,
-       struct ktermios *old_termios);
-static void digi_break_ctl(struct usb_serial_port *port, int break_state);
-static int digi_ioctl(struct usb_serial_port *port, struct file *file,
-       unsigned int cmd, unsigned long arg);
-static int digi_tiocmget(struct usb_serial_port *port, struct file *file);
-static int digi_tiocmset(struct usb_serial_port *port, struct file *file,
+static void digi_rx_throttle(struct tty_struct *tty);
+static void digi_rx_unthrottle(struct tty_struct *tty);
+static void digi_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios);
+static void digi_break_ctl(struct tty_struct *tty, int break_state);
+static int digi_tiocmget(struct tty_struct *tty, struct file *file);
+static int digi_tiocmset(struct tty_struct *tty, struct file *file,
        unsigned int set, unsigned int clear);
-static int digi_write(struct usb_serial_port *port, const unsigned char *buf, int count);
+static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
+       const unsigned char *buf, int count);
 static void digi_write_bulk_callback(struct urb *urb);
-static int digi_write_room(struct usb_serial_port *port);
-static int digi_chars_in_buffer(struct usb_serial_port *port);
-static int digi_open(struct usb_serial_port *port, struct file *filp);
-static void digi_close(struct usb_serial_port *port, struct file *filp);
+static int digi_write_room(struct tty_struct *tty);
+static int digi_chars_in_buffer(struct tty_struct *tty);
+static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
+       struct file *filp);
+static void digi_close(struct tty_struct *tty, struct usb_serial_port *port,
+       struct file *filp);
 static int digi_startup_device(struct usb_serial *serial);
 static int digi_startup(struct usb_serial *serial);
 static void digi_shutdown(struct usb_serial *serial);
@@ -487,7 +486,7 @@ static struct usb_device_id id_table_4 [] = {
        { }                                             /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
 
 static struct usb_driver digi_driver = {
        .name =         "digi_acceleport",
@@ -518,7 +517,6 @@ static struct usb_serial_driver digi_acceleport_2_device = {
        .chars_in_buffer =              digi_chars_in_buffer,
        .throttle =                     digi_rx_throttle,
        .unthrottle =                   digi_rx_unthrottle,
-       .ioctl =                        digi_ioctl,
        .set_termios =                  digi_set_termios,
        .break_ctl =                    digi_break_ctl,
        .tiocmget =                     digi_tiocmget,
@@ -545,7 +543,6 @@ static struct usb_serial_driver digi_acceleport_4_device = {
        .chars_in_buffer =              digi_chars_in_buffer,
        .throttle =                     digi_rx_throttle,
        .unthrottle =                   digi_rx_unthrottle,
-       .ioctl =                        digi_ioctl,
        .set_termios =                  digi_set_termios,
        .break_ctl =                    digi_break_ctl,
        .tiocmget =                     digi_tiocmget,
@@ -558,21 +555,22 @@ static struct usb_serial_driver digi_acceleport_4_device = {
 /* Functions */
 
 /*
-*  Cond Wait Interruptible Timeout Irqrestore
-*
-*  Do spin_unlock_irqrestore and interruptible_sleep_on_timeout
-*  so that wake ups are not lost if they occur between the unlock
-*  and the sleep.  In other words, spin_unlock_irqrestore and
-*  interruptible_sleep_on_timeout are "atomic" with respect to
-*  wake ups.  This is used to implement condition variables.
-*
-*  interruptible_sleep_on_timeout is deprecated and has been replaced
-*  with the equivalent code.
-*/
+ *  Cond Wait Interruptible Timeout Irqrestore
+ *
+ *  Do spin_unlock_irqrestore and interruptible_sleep_on_timeout
+ *  so that wake ups are not lost if they occur between the unlock
+ *  and the sleep.  In other words, spin_unlock_irqrestore and
+ *  interruptible_sleep_on_timeout are "atomic" with respect to
+ *  wake ups.  This is used to implement condition variables.
+ *
+ *  interruptible_sleep_on_timeout is deprecated and has been replaced
+ *  with the equivalent code.
+ */
 
 static long cond_wait_interruptible_timeout_irqrestore(
        wait_queue_head_t *q, long timeout,
        spinlock_t *lock, unsigned long flags)
+__releases(lock)
 {
        DEFINE_WAIT(wait);
 
@@ -586,15 +584,16 @@ static long cond_wait_interruptible_timeout_irqrestore(
 
 
 /*
-*  Digi Wakeup Write
-*
-*  Wake up port, line discipline, and tty processes sleeping
-*  on writes.
-*/
+ *  Digi Wakeup Write
+ *
+ *  Wake up port, line discipline, and tty processes sleeping
+ *  on writes.
+ */
 
 static void digi_wakeup_write_lock(struct work_struct *work)
 {
-       struct digi_port *priv = container_of(work, struct digi_port, dp_wakeup_work);
+       struct digi_port *priv =
+                       container_of(work, struct digi_port, dp_wakeup_work);
        struct usb_serial_port *port = priv->dp_port;
        unsigned long flags;
 
@@ -605,20 +604,20 @@ static void digi_wakeup_write_lock(struct work_struct *work)
 
 static void digi_wakeup_write(struct usb_serial_port *port)
 {
-       tty_wakeup(port->tty);
+       tty_wakeup(port->port.tty);
 }
 
 
 /*
-*  Digi Write OOB Command
-*
-*  Write commands on the out of band port.  Commands are 4
-*  bytes each, multiple commands can be sent at once, and
-*  no command will be split across USB packets.  Returns 0
-*  if successful, -EINTR if interrupted while sleeping and
-*  the interruptible flag is true, or a negative error
-*  returned by usb_submit_urb.
-*/
+ *  Digi Write OOB Command
+ *
+ *  Write commands on the out of band port.  Commands are 4
+ *  bytes each, multiple commands can be sent at once, and
+ *  no command will be split across USB packets.  Returns 0
+ *  if successful, -EINTR if interrupted while sleeping and
+ *  the interruptible flag is true, or a negative error
+ *  returned by usb_submit_urb.
+ */
 
 static int digi_write_oob_command(struct usb_serial_port *port,
        unsigned char *buf, int count, int interruptible)
@@ -633,8 +632,8 @@ static int digi_write_oob_command(struct usb_serial_port *port,
        dbg("digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, count);
 
        spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
-       while(count > 0) {
-               while(oob_port->write_urb->status == -EINPROGRESS
+       while (count > 0) {
+               while (oob_port->write_urb->status == -EINPROGRESS
                        || oob_priv->dp_write_urb_in_use) {
                        cond_wait_interruptible_timeout_irqrestore(
                                &oob_port->write_wait, DIGI_RETRY_TIMEOUT,
@@ -651,7 +650,8 @@ static int digi_write_oob_command(struct usb_serial_port *port,
                memcpy(oob_port->write_urb->transfer_buffer, buf, len);
                oob_port->write_urb->transfer_buffer_length = len;
                oob_port->write_urb->dev = port->serial->dev;
-               if ((ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0) {
+               ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);
+               if (ret == 0) {
                        oob_priv->dp_write_urb_in_use = 1;
                        count -= len;
                        buf += len;
@@ -666,16 +666,16 @@ static int digi_write_oob_command(struct usb_serial_port *port,
 
 
 /*
-*  Digi Write In Band Command
-*
-*  Write commands on the given port.  Commands are 4
-*  bytes each, multiple commands can be sent at once, and
-*  no command will be split across USB packets.  If timeout
-*  is non-zero, write in band command will return after
-*  waiting unsuccessfully for the URB status to clear for
-*  timeout ticks.  Returns 0 if successful, or a negative
-*  error returned by digi_write.
-*/
+ *  Digi Write In Band Command
+ *
+ *  Write commands on the given port.  Commands are 4
+ *  bytes each, multiple commands can be sent at once, and
+ *  no command will be split across USB packets.  If timeout
+ *  is non-zero, write in band command will return after
+ *  waiting unsuccessfully for the URB status to clear for
+ *  timeout ticks.  Returns 0 if successful, or a negative
+ *  error returned by digi_write.
+ */
 
 static int digi_write_inb_command(struct usb_serial_port *port,
        unsigned char *buf, int count, unsigned long timeout)
@@ -695,9 +695,10 @@ static int digi_write_inb_command(struct usb_serial_port *port,
                timeout = ULONG_MAX;
 
        spin_lock_irqsave(&priv->dp_port_lock, flags);
-       while(count > 0 && ret == 0) {
-               while((port->write_urb->status == -EINPROGRESS
-                       || priv->dp_write_urb_in_use) && time_before(jiffies, timeout)) {
+       while (count > 0 && ret == 0) {
+               while ((port->write_urb->status == -EINPROGRESS
+                               || priv->dp_write_urb_in_use)
+                                       && time_before(jiffies, timeout)) {
                        cond_wait_interruptible_timeout_irqrestore(
                                &port->write_wait, DIGI_RETRY_TIMEOUT,
                                &priv->dp_port_lock, flags);
@@ -728,7 +729,8 @@ static int digi_write_inb_command(struct usb_serial_port *port,
                }
                port->write_urb->dev = port->serial->dev;
 
-               if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) {
+               ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+               if (ret == 0) {
                        priv->dp_write_urb_in_use = 1;
                        priv->dp_out_buf_len = 0;
                        count -= len;
@@ -746,14 +748,14 @@ static int digi_write_inb_command(struct usb_serial_port *port,
 
 
 /*
-*  Digi Set Modem Signals
-*
-*  Sets or clears DTR and RTS on the port, according to the
-*  modem_signals argument.  Use TIOCM_DTR and TIOCM_RTS flags
-*  for the modem_signals argument.  Returns 0 if successful,
-*  -EINTR if interrupted while sleeping, or a non-zero error
-*  returned by usb_submit_urb.
-*/
+ *  Digi Set Modem Signals
+ *
+ *  Sets or clears DTR and RTS on the port, according to the
+ *  modem_signals argument.  Use TIOCM_DTR and TIOCM_RTS flags
+ *  for the modem_signals argument.  Returns 0 if successful,
+ *  -EINTR if interrupted while sleeping, or a non-zero error
+ *  returned by usb_submit_urb.
+ */
 
 static int digi_set_modem_signals(struct usb_serial_port *port,
        unsigned int modem_signals, int interruptible)
@@ -761,7 +763,7 @@ static int digi_set_modem_signals(struct usb_serial_port *port,
 
        int ret;
        struct digi_port *port_priv = usb_get_serial_port_data(port);
-       struct usb_serial_port *oob_port = (struct usb_serial_port *)((struct digi_serial *)(usb_get_serial_data(port->serial)))->ds_oob_port;
+       struct usb_serial_port *oob_port = (struct usb_serial_port *) ((struct digi_serial *)(usb_get_serial_data(port->serial)))->ds_oob_port;
        struct digi_port *oob_priv = usb_get_serial_port_data(oob_port);
        unsigned char *data = oob_port->write_urb->transfer_buffer;
        unsigned long flags = 0;
@@ -773,7 +775,8 @@ static int digi_set_modem_signals(struct usb_serial_port *port,
        spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
        spin_lock(&port_priv->dp_port_lock);
 
-       while(oob_port->write_urb->status == -EINPROGRESS || oob_priv->dp_write_urb_in_use) {
+       while (oob_port->write_urb->status == -EINPROGRESS ||
+                                       oob_priv->dp_write_urb_in_use) {
                spin_unlock(&port_priv->dp_port_lock);
                cond_wait_interruptible_timeout_irqrestore(
                        &oob_port->write_wait, DIGI_RETRY_TIMEOUT,
@@ -785,17 +788,20 @@ static int digi_set_modem_signals(struct usb_serial_port *port,
        }
        data[0] = DIGI_CMD_SET_DTR_SIGNAL;
        data[1] = port_priv->dp_port_num;
-       data[2] = (modem_signals&TIOCM_DTR) ? DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE;
+       data[2] = (modem_signals & TIOCM_DTR) ?
+                                       DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE;
        data[3] = 0;
        data[4] = DIGI_CMD_SET_RTS_SIGNAL;
        data[5] = port_priv->dp_port_num;
-       data[6] = (modem_signals&TIOCM_RTS) ? DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE;
+       data[6] = (modem_signals & TIOCM_RTS) ?
+                                       DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE;
        data[7] = 0;
 
        oob_port->write_urb->transfer_buffer_length = 8;
        oob_port->write_urb->dev = port->serial->dev;
 
-       if ((ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0) {
+       ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);
+       if (ret == 0) {
                oob_priv->dp_write_urb_in_use = 1;
                port_priv->dp_modem_signals =
                        (port_priv->dp_modem_signals&~(TIOCM_DTR|TIOCM_RTS))
@@ -809,16 +815,16 @@ static int digi_set_modem_signals(struct usb_serial_port *port,
 }
 
 /*
-*  Digi Transmit Idle
-*
-*  Digi transmit idle waits, up to timeout ticks, for the transmitter
-*  to go idle.  It returns 0 if successful or a negative error.
-*
-*  There are race conditions here if more than one process is calling
-*  digi_transmit_idle on the same port at the same time.  However, this
-*  is only called from close, and only one process can be in close on a
-*  port at a time, so its ok.
-*/
+ *  Digi Transmit Idle
+ *
+ *  Digi transmit idle waits, up to timeout ticks, for the transmitter
+ *  to go idle.  It returns 0 if successful or a negative error.
+ *
+ *  There are race conditions here if more than one process is calling
+ *  digi_transmit_idle on the same port at the same time.  However, this
+ *  is only called from close, and only one process can be in close on a
+ *  port at a time, so its ok.
+ */
 
 static int digi_transmit_idle(struct usb_serial_port *port,
        unsigned long timeout)
@@ -837,12 +843,13 @@ static int digi_transmit_idle(struct usb_serial_port *port,
 
        timeout += jiffies;
 
-       if ((ret = digi_write_inb_command(port, buf, 2, timeout - jiffies)) != 0)
+       ret = digi_write_inb_command(port, buf, 2, timeout - jiffies);
+       if (ret != 0)
                return ret;
 
        spin_lock_irqsave(&priv->dp_port_lock, flags);
 
-       while(time_before(jiffies, timeout) && !priv->dp_transmit_idle) {
+       while (time_before(jiffies, timeout) && !priv->dp_transmit_idle) {
                cond_wait_interruptible_timeout_irqrestore(
                        &priv->dp_transmit_idle_wait, DIGI_RETRY_TIMEOUT,
                        &priv->dp_port_lock, flags);
@@ -857,9 +864,10 @@ static int digi_transmit_idle(struct usb_serial_port *port,
 }
 
 
-static void digi_rx_throttle(struct usb_serial_port *port)
+static void digi_rx_throttle(struct tty_struct *tty)
 {
        unsigned long flags;
+       struct usb_serial_port *port = tty->driver_data;
        struct digi_port *priv = usb_get_serial_port_data(port);
 
 
@@ -873,10 +881,11 @@ static void digi_rx_throttle(struct usb_serial_port *port)
 }
 
 
-static void digi_rx_unthrottle(struct usb_serial_port *port)
+static void digi_rx_unthrottle(struct tty_struct *tty)
 {
        int ret = 0;
        unsigned long flags;
+       struct usb_serial_port *port = tty->driver_data;
        struct digi_port *priv = usb_get_serial_port_data(port);
 
        dbg("digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num);
@@ -901,26 +910,25 @@ static void digi_rx_unthrottle(struct usb_serial_port *port)
 }
 
 
-static void digi_set_termios(struct usb_serial_port *port,
-                                       struct ktermios *old_termios)
+static void digi_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
-
        struct digi_port *priv = usb_get_serial_port_data(port);
-       struct tty_struct *tty = port->tty;
        unsigned int iflag = tty->termios->c_iflag;
        unsigned int cflag = tty->termios->c_cflag;
        unsigned int old_iflag = old_termios->c_iflag;
        unsigned int old_cflag = old_termios->c_cflag;
        unsigned char buf[32];
        unsigned int modem_signals;
-       int arg,ret;
+       int arg, ret;
        int i = 0;
        speed_t baud;
 
        dbg("digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, old_cflag=0x%x", priv->dp_port_num, iflag, old_iflag, cflag, old_cflag);
 
        /* set baud rate */
-       if ((baud = tty_get_baud_rate(tty)) != tty_termios_baud_rate(old_termios)) {
+       baud = tty_get_baud_rate(tty);
+       if (baud != tty_termios_baud_rate(old_termios)) {
                arg = -1;
 
                /* reassert DTR and (maybe) RTS on transition from B0 */
@@ -934,30 +942,30 @@ static void digi_set_termios(struct usb_serial_port *port,
                        digi_set_modem_signals(port, modem_signals, 1);
                }
                switch (baud) {
-                       /* drop DTR and RTS on transition to B0 */
-                       case 0: digi_set_modem_signals(port, 0, 1); break;
-                       case 50: arg = DIGI_BAUD_50; break;
-                       case 75: arg = DIGI_BAUD_75; break;
-                       case 110: arg = DIGI_BAUD_110; break;
-                       case 150: arg = DIGI_BAUD_150; break;
-                       case 200: arg = DIGI_BAUD_200; break;
-                       case 300: arg = DIGI_BAUD_300; break;
-                       case 600: arg = DIGI_BAUD_600; break;
-                       case 1200: arg = DIGI_BAUD_1200; break;
-                       case 1800: arg = DIGI_BAUD_1800; break;
-                       case 2400: arg = DIGI_BAUD_2400; break;
-                       case 4800: arg = DIGI_BAUD_4800; break;
-                       case 9600: arg = DIGI_BAUD_9600; break;
-                       case 19200: arg = DIGI_BAUD_19200; break;
-                       case 38400: arg = DIGI_BAUD_38400; break;
-                       case 57600: arg = DIGI_BAUD_57600; break;
-                       case 115200: arg = DIGI_BAUD_115200; break;
-                       case 230400: arg = DIGI_BAUD_230400; break;
-                       case 460800: arg = DIGI_BAUD_460800; break;
-                       default:
-                               arg = DIGI_BAUD_9600;
-                               baud = 9600;
-                               break;
+               /* drop DTR and RTS on transition to B0 */
+               case 0: digi_set_modem_signals(port, 0, 1); break;
+               case 50: arg = DIGI_BAUD_50; break;
+               case 75: arg = DIGI_BAUD_75; break;
+               case 110: arg = DIGI_BAUD_110; break;
+               case 150: arg = DIGI_BAUD_150; break;
+               case 200: arg = DIGI_BAUD_200; break;
+               case 300: arg = DIGI_BAUD_300; break;
+               case 600: arg = DIGI_BAUD_600; break;
+               case 1200: arg = DIGI_BAUD_1200; break;
+               case 1800: arg = DIGI_BAUD_1800; break;
+               case 2400: arg = DIGI_BAUD_2400; break;
+               case 4800: arg = DIGI_BAUD_4800; break;
+               case 9600: arg = DIGI_BAUD_9600; break;
+               case 19200: arg = DIGI_BAUD_19200; break;
+               case 38400: arg = DIGI_BAUD_38400; break;
+               case 57600: arg = DIGI_BAUD_57600; break;
+               case 115200: arg = DIGI_BAUD_115200; break;
+               case 230400: arg = DIGI_BAUD_230400; break;
+               case 460800: arg = DIGI_BAUD_460800; break;
+               default:
+                       arg = DIGI_BAUD_9600;
+                       baud = 9600;
+                       break;
                }
                if (arg != -1) {
                        buf[i++] = DIGI_CMD_SET_BAUD_RATE;
@@ -1083,14 +1091,16 @@ static void digi_set_termios(struct usb_serial_port *port,
                buf[i++] = arg;
                buf[i++] = 0;
        }
-       if ((ret = digi_write_oob_command(port, buf, i, 1)) != 0)
+       ret = digi_write_oob_command(port, buf, i, 1);
+       if (ret != 0)
                dbg("digi_set_termios: write oob failed, ret=%d", ret);
        tty_encode_baud_rate(tty, baud, baud);
 }
 
 
-static void digi_break_ctl(struct usb_serial_port *port, int break_state)
+static void digi_break_ctl(struct tty_struct *tty, int break_state)
 {
+       struct usb_serial_port *port = tty->driver_data;
        unsigned char buf[4];
 
        buf[0] = DIGI_CMD_BREAK_CONTROL;
@@ -1101,8 +1111,9 @@ static void digi_break_ctl(struct usb_serial_port *port, int break_state)
 }
 
 
-static int digi_tiocmget(struct usb_serial_port *port, struct file *file)
+static int digi_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct digi_port *priv = usb_get_serial_port_data(port);
        unsigned int val;
        unsigned long flags;
@@ -1116,9 +1127,10 @@ static int digi_tiocmget(struct usb_serial_port *port, struct file *file)
 }
 
 
-static int digi_tiocmset(struct usb_serial_port *port, struct file *file,
+static int digi_tiocmset(struct tty_struct *tty, struct file *file,
        unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct digi_port *priv = usb_get_serial_port_data(port);
        unsigned int val;
        unsigned long flags;
@@ -1132,30 +1144,11 @@ static int digi_tiocmset(struct usb_serial_port *port, struct file *file,
 }
 
 
-static int digi_ioctl(struct usb_serial_port *port, struct file *file,
-       unsigned int cmd, unsigned long arg)
-{
-       struct digi_port *priv = usb_get_serial_port_data(port);
-       dbg("digi_ioctl: TOP: port=%d, cmd=0x%x", priv->dp_port_num, cmd);
-
-       switch (cmd) {
-       case TIOCMIWAIT:
-               /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
-               /* TODO */
-               return 0;
-       case TIOCGICOUNT:
-               /* return count of modemline transitions */
-               /* TODO */
-               return 0;
-       }
-       return -ENOIOCTLCMD;
-
-}
-
-static int digi_write(struct usb_serial_port *port, const unsigned char *buf, int count)
+static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                       const unsigned char *buf, int count)
 {
 
-       int ret,data_len,new_len;
+       int ret, data_len, new_len;
        struct digi_port *priv = usb_get_serial_port_data(port);
        unsigned char *data = port->write_urb->transfer_buffer;
        unsigned long flags = 0;
@@ -1173,7 +1166,8 @@ static int digi_write(struct usb_serial_port *port, const unsigned char *buf, in
        spin_lock_irqsave(&priv->dp_port_lock, flags);
 
        /* wait for urb status clear to submit another urb */
-       if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use) {
+       if (port->write_urb->status == -EINPROGRESS ||
+                                       priv->dp_write_urb_in_use) {
                /* buffer data if count is 1 (probably put_char) if possible */
                if (count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE) {
                        priv->dp_out_buf[priv->dp_out_buf_len++] = *buf;
@@ -1208,7 +1202,8 @@ static int digi_write(struct usb_serial_port *port, const unsigned char *buf, in
        /* copy in new data */
        memcpy(data, buf, new_len);
 
-       if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) {
+       ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+       if (ret == 0) {
                priv->dp_write_urb_in_use = 1;
                ret = new_len;
                priv->dp_out_buf_len = 0;
@@ -1222,7 +1217,7 @@ static int digi_write(struct usb_serial_port *port, const unsigned char *buf, in
        dbg("digi_write: returning %d", ret);
        return ret;
 
-} 
+}
 
 static void digi_write_bulk_callback(struct urb *urb)
 {
@@ -1237,13 +1232,13 @@ static void digi_write_bulk_callback(struct urb *urb)
        dbg("digi_write_bulk_callback: TOP, urb->status=%d", status);
 
        /* port and serial sanity check */
-       if (port == NULL || (priv=usb_get_serial_port_data(port)) == NULL) {
+       if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) {
                err("%s: port or port->private is NULL, status=%d",
                    __func__, status);
                return;
        }
        serial = port->serial;
-       if (serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL) {
+       if (serial == NULL || (serial_priv = usb_get_serial_data(serial)) == NULL) {
                err("%s: serial or serial->private is NULL, status=%d",
                    __func__, status);
                return;
@@ -1262,17 +1257,19 @@ static void digi_write_bulk_callback(struct urb *urb)
        /* try to send any buffered data on this port, if it is open */
        spin_lock(&priv->dp_port_lock);
        priv->dp_write_urb_in_use = 0;
-       if (port->open_count && port->write_urb->status != -EINPROGRESS
+       if (port->port.count && port->write_urb->status != -EINPROGRESS
            && priv->dp_out_buf_len > 0) {
                *((unsigned char *)(port->write_urb->transfer_buffer))
                        = (unsigned char)DIGI_CMD_SEND_DATA;
-               *((unsigned char *)(port->write_urb->transfer_buffer)+1)
+               *((unsigned char *)(port->write_urb->transfer_buffer) + 1)
                        = (unsigned char)priv->dp_out_buf_len;
-               port->write_urb->transfer_buffer_length = priv->dp_out_buf_len+2;
+               port->write_urb->transfer_buffer_length =
+                                               priv->dp_out_buf_len + 2;
                port->write_urb->dev = serial->dev;
-               memcpy(port->write_urb->transfer_buffer+2, priv->dp_out_buf,
+               memcpy(port->write_urb->transfer_buffer + 2, priv->dp_out_buf,
                        priv->dp_out_buf_len);
-               if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) {
+               ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+               if (ret == 0) {
                        priv->dp_write_urb_in_use = 1;
                        priv->dp_out_buf_len = 0;
                }
@@ -1289,16 +1286,17 @@ static void digi_write_bulk_callback(struct urb *urb)
                        __func__, ret, priv->dp_port_num);
 }
 
-static int digi_write_room(struct usb_serial_port *port)
+static int digi_write_room(struct tty_struct *tty)
 {
-
-       int room;
+       struct usb_serial_port *port = tty->driver_data;
        struct digi_port *priv = usb_get_serial_port_data(port);
+       int room;
        unsigned long flags = 0;
 
        spin_lock_irqsave(&priv->dp_port_lock, flags);
 
-       if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use)
+       if (port->write_urb->status == -EINPROGRESS ||
+                                       priv->dp_write_urb_in_use)
                room = 0;
        else
                room = port->bulk_out_size - 2 - priv->dp_out_buf_len;
@@ -1309,12 +1307,11 @@ static int digi_write_room(struct usb_serial_port *port)
 
 }
 
-static int digi_chars_in_buffer(struct usb_serial_port *port)
+static int digi_chars_in_buffer(struct tty_struct *tty)
 {
-
+       struct usb_serial_port *port = tty->driver_data;
        struct digi_port *priv = usb_get_serial_port_data(port);
 
-
        if (port->write_urb->status == -EINPROGRESS
            || priv->dp_write_urb_in_use) {
                dbg("digi_chars_in_buffer: port=%d, chars=%d",
@@ -1330,7 +1327,8 @@ static int digi_chars_in_buffer(struct usb_serial_port *port)
 }
 
 
-static int digi_open(struct usb_serial_port *port, struct file *filp)
+static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
+                               struct file *filp)
 {
        int ret;
        unsigned char buf[32];
@@ -1339,7 +1337,7 @@ static int digi_open(struct usb_serial_port *port, struct file *filp)
        unsigned long flags = 0;
 
        dbg("digi_open: TOP: port=%d, open_count=%d",
-               priv->dp_port_num, port->open_count);
+               priv->dp_port_num, port->port.count);
 
        /* be sure the device is started up */
        if (digi_startup_device(port->serial) != 0)
@@ -1354,7 +1352,7 @@ static int digi_open(struct usb_serial_port *port, struct file *filp)
        }
 
        /* wait for a close in progress to finish */
-       while(priv->dp_in_close) {
+       while (priv->dp_in_close) {
                cond_wait_interruptible_timeout_irqrestore(
                        &priv->dp_close_wait, DIGI_RETRY_TIMEOUT,
                        &priv->dp_port_lock, flags);
@@ -1364,7 +1362,7 @@ static int digi_open(struct usb_serial_port *port, struct file *filp)
        }
 
        spin_unlock_irqrestore(&priv->dp_port_lock, flags);
+
        /* read modem signals automatically whenever they change */
        buf[0] = DIGI_CMD_READ_INPUT_SIGNALS;
        buf[1] = priv->dp_port_num;
@@ -1377,13 +1375,16 @@ static int digi_open(struct usb_serial_port *port, struct file *filp)
        buf[6] = DIGI_FLUSH_TX | DIGI_FLUSH_RX;
        buf[7] = 0;
 
-       if ((ret = digi_write_oob_command(port, buf, 8, 1)) != 0)
+       ret = digi_write_oob_command(port, buf, 8, 1);
+       if (ret != 0)
                dbg("digi_open: write oob failed, ret=%d", ret);
 
        /* set termios settings */
-       not_termios.c_cflag = ~port->tty->termios->c_cflag;
-       not_termios.c_iflag = ~port->tty->termios->c_iflag;
-       digi_set_termios(port, &not_termios);
+       if (tty) {
+               not_termios.c_cflag = ~tty->termios->c_cflag;
+               not_termios.c_iflag = ~tty->termios->c_iflag;
+               digi_set_termios(tty, port, &not_termios);
+       }
 
        /* set DTR and RTS */
        digi_set_modem_signals(port, TIOCM_DTR|TIOCM_RTS, 1);
@@ -1392,16 +1393,16 @@ static int digi_open(struct usb_serial_port *port, struct file *filp)
 }
 
 
-static void digi_close(struct usb_serial_port *port, struct file *filp)
+static void digi_close(struct tty_struct *tty, struct usb_serial_port *port,
+                               struct file *filp)
 {
        DEFINE_WAIT(wait);
        int ret;
        unsigned char buf[32];
-       struct tty_struct *tty = port->tty;
        struct digi_port *priv = usb_get_serial_port_data(port);
 
        dbg("digi_close: TOP: port=%d, open_count=%d",
-               priv->dp_port_num, port->open_count);
+               priv->dp_port_num, port->port.count);
 
        mutex_lock(&port->serial->disc_mutex);
        /* if disconnected, just clear flags */
@@ -1426,9 +1427,8 @@ static void digi_close(struct usb_serial_port *port, struct file *filp)
 
        if (port->serial->dev) {
                /* wait for transmit idle */
-               if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) {
+               if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0)
                        digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT);
-               }
                /* drop DTR and RTS */
                digi_set_modem_signals(port, 0, 0);
 
@@ -1462,11 +1462,13 @@ static void digi_close(struct usb_serial_port *port, struct file *filp)
                buf[18] = DIGI_FLUSH_TX | DIGI_FLUSH_RX;
                buf[19] = 0;
 
-               if ((ret = digi_write_oob_command(port, buf, 20, 0)) != 0)
+               ret = digi_write_oob_command(port, buf, 20, 0);
+               if (ret != 0)
                        dbg("digi_close: write oob failed, ret=%d", ret);
 
                /* wait for final commands on oob port to complete */
-               prepare_to_wait(&priv->dp_flush_wait, &wait, TASK_INTERRUPTIBLE);
+               prepare_to_wait(&priv->dp_flush_wait, &wait,
+                                                       TASK_INTERRUPTIBLE);
                schedule_timeout(DIGI_CLOSE_TIMEOUT);
                finish_wait(&priv->dp_flush_wait, &wait);
 
@@ -1486,15 +1488,15 @@ exit:
 
 
 /*
-*  Digi Startup Device
-*
-*  Starts reads on all ports.  Must be called AFTER startup, with
-*  urbs initialized.  Returns 0 if successful, non-zero error otherwise.
-*/
+ *  Digi Startup Device
+ *
+ *  Starts reads on all ports.  Must be called AFTER startup, with
+ *  urbs initialized.  Returns 0 if successful, non-zero error otherwise.
+ */
 
 static int digi_startup_device(struct usb_serial *serial)
 {
-       int i,ret = 0;
+       int i, ret = 0;
        struct digi_serial *serial_priv = usb_get_serial_data(serial);
        struct usb_serial_port *port;
 
@@ -1512,7 +1514,8 @@ static int digi_startup_device(struct usb_serial *serial)
        for (i = 0; i < serial->type->num_ports + 1; i++) {
                port = serial->port[i];
                port->write_urb->dev = port->serial->dev;
-               if ((ret = usb_submit_urb(port->read_urb, GFP_KERNEL)) != 0) {
+               ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
+               if (ret != 0) {
                        err("%s: usb_submit_urb failed, ret=%d, port=%d",
                                        __func__, ret, i);
                        break;
@@ -1533,7 +1536,7 @@ static int digi_startup(struct usb_serial *serial)
 
        /* allocate the private data structures for all ports */
        /* number of regular ports + 1 for the out-of-band port */
-       for(i = 0; i < serial->type->num_ports + 1; i++) {
+       for (i = 0; i < serial->type->num_ports + 1; i++) {
                /* allocate port private structure */
                priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL);
                if (priv == NULL) {
@@ -1596,7 +1599,7 @@ static void digi_shutdown(struct usb_serial *serial)
 
        /* free the private data structures for all ports */
        /* number of regular ports + 1 for the out-of-band port */
-       for(i = 0; i < serial->type->num_ports + 1; i++)
+       for (i = 0; i < serial->type->num_ports + 1; i++)
                kfree(usb_get_serial_port_data(serial->port[i]));
        kfree(usb_get_serial_data(serial));
 }
@@ -1619,7 +1622,7 @@ static void digi_read_bulk_callback(struct urb *urb)
                return;
        }
        if (port->serial == NULL ||
-               (serial_priv=usb_get_serial_data(port->serial)) == NULL) {
+               (serial_priv = usb_get_serial_data(port->serial)) == NULL) {
                err("%s: serial is bad or serial->private is NULL, status=%d",
                        __func__, status);
                return;
@@ -1643,45 +1646,46 @@ static void digi_read_bulk_callback(struct urb *urb)
 
        /* continue read */
        urb->dev = port->serial->dev;
-       if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
+       ret = usb_submit_urb(urb, GFP_ATOMIC);
+       if (ret != 0) {
                err("%s: failed resubmitting urb, ret=%d, port=%d",
                    __func__, ret, priv->dp_port_num);
        }
 
 }
 
-/* 
-*  Digi Read INB Callback
-*
-*  Digi Read INB Callback handles reads on the in band ports, sending
-*  the data on to the tty subsystem.  When called we know port and
-*  port->private are not NULL and port->serial has been validated.
-*  It returns 0 if successful, 1 if successful but the port is
-*  throttled, and -1 if the sanity checks failed.
-*/
+/*
+ *  Digi Read INB Callback
+ *
+ *  Digi Read INB Callback handles reads on the in band ports, sending
+ *  the data on to the tty subsystem.  When called we know port and
+ *  port->private are not NULL and port->serial has been validated.
+ *  It returns 0 if successful, 1 if successful but the port is
+ *  throttled, and -1 if the sanity checks failed.
+ */
 
 static int digi_read_inb_callback(struct urb *urb)
 {
 
        struct usb_serial_port *port = urb->context;
-       struct tty_struct *tty = port->tty;
+       struct tty_struct *tty = port->port.tty;
        struct digi_port *priv = usb_get_serial_port_data(port);
        int opcode = ((unsigned char *)urb->transfer_buffer)[0];
        int len = ((unsigned char *)urb->transfer_buffer)[1];
        int port_status = ((unsigned char *)urb->transfer_buffer)[2];
-       unsigned char *data = ((unsigned char *)urb->transfer_buffer)+3;
-       int flag,throttled;
+       unsigned char *data = ((unsigned char *)urb->transfer_buffer) + 3;
+       int flag, throttled;
        int i;
        int status = urb->status;
 
        /* do not process callbacks on closed ports */
        /* but do continue the read chain */
-       if (port->open_count == 0)
+       if (port->port.count == 0)
                return 0;
 
        /* short/multiple packet check */
        if (urb->actual_length != len + 2) {
-               err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, "
+               err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, "
                    "port=%d, opcode=%d, len=%d, actual_length=%d, "
                    "status=%d", __func__, status, priv->dp_port_num,
                    opcode, len, urb->actual_length, port_status);
@@ -1723,8 +1727,9 @@ static int digi_read_inb_callback(struct urb *urb)
                        if (flag == TTY_NORMAL)
                                tty_insert_flip_string(tty, data, len);
                        else {
-                               for(i = 0; i < len; i++)
-                                       tty_insert_flip_char(tty, data[i], flag);
+                               for (i = 0; i < len; i++)
+                                       tty_insert_flip_char(tty,
+                                                               data[i], flag);
                        }
                        tty_flip_buffer_push(tty);
                }
@@ -1736,19 +1741,19 @@ static int digi_read_inb_callback(struct urb *urb)
        else if (opcode != DIGI_CMD_RECEIVE_DATA)
                dbg("%s: unknown opcode: %d", __func__, opcode);
 
-       return(throttled ? 1 : 0);
+       return throttled ? 1 : 0;
 
 }
 
 
-/* 
-*  Digi Read OOB Callback
-*
-*  Digi Read OOB Callback handles reads on the out of band port.
-*  When called we know port and port->private are not NULL and
-*  the port->serial is valid.  It returns 0 if successful, and
-*  -1 if the sanity checks failed.
-*/
+/*
+ *  Digi Read OOB Callback
+ *
+ *  Digi Read OOB Callback handles reads on the out of band port.
+ *  When called we know port and port->private are not NULL and
+ *  the port->serial is valid.  It returns 0 if successful, and
+ *  -1 if the sanity checks failed.
+ */
 
 static int digi_read_oob_callback(struct urb *urb)
 {
@@ -1758,12 +1763,13 @@ static int digi_read_oob_callback(struct urb *urb)
        struct digi_port *priv = usb_get_serial_port_data(port);
        int opcode, line, status, val;
        int i;
+       unsigned int rts;
 
        dbg("digi_read_oob_callback: port=%d, len=%d",
                        priv->dp_port_num, urb->actual_length);
 
        /* handle each oob command */
-       for(i = 0; i < urb->actual_length - 3;) {
+       for (i = 0; i < urb->actual_length - 3;) {
                opcode = ((unsigned char *)urb->transfer_buffer)[i++];
                line = ((unsigned char *)urb->transfer_buffer)[i++];
                status = ((unsigned char *)urb->transfer_buffer)[i++];
@@ -1777,27 +1783,29 @@ static int digi_read_oob_callback(struct urb *urb)
 
                port = serial->port[line];
 
-               if ((priv=usb_get_serial_port_data(port)) == NULL)
+               priv = usb_get_serial_port_data(port);
+               if (priv == NULL)
                        return -1;
 
+               rts = 0;
+               if (port->port.count)
+                       rts = port->port.tty->termios->c_cflag & CRTSCTS;
+
                if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) {
                        spin_lock(&priv->dp_port_lock);
                        /* convert from digi flags to termiox flags */
                        if (val & DIGI_READ_INPUT_SIGNALS_CTS) {
                                priv->dp_modem_signals |= TIOCM_CTS;
                                /* port must be open to use tty struct */
-                               if (port->open_count
-                                       && port->tty->termios->c_cflag & CRTSCTS) {
-                                       port->tty->hw_stopped = 0;
+                               if (rts) {
+                                       port->port.tty->hw_stopped = 0;
                                        digi_wakeup_write(port);
                                }
                        } else {
                                priv->dp_modem_signals &= ~TIOCM_CTS;
                                /* port must be open to use tty struct */
-                               if (port->open_count
-                                       && port->tty->termios->c_cflag & CRTSCTS) {
-                                       port->tty->hw_stopped = 1;
-                               }
+                               if (rts)
+                                       port->port.tty->hw_stopped = 1;
                        }
                        if (val & DIGI_READ_INPUT_SIGNALS_DSR)
                                priv->dp_modem_signals |= TIOCM_DSR;
@@ -1834,7 +1842,7 @@ static int __init digi_init(void)
        if (retval)
                goto failed_acceleport_2_device;
        retval = usb_serial_register(&digi_acceleport_4_device);
-       if (retval) 
+       if (retval)
                goto failed_acceleport_4_device;
        retval = usb_register(&digi_driver);
        if (retval)
index c5ec309a3cb1434014a1f4f8df801d047099633f..a6ab5b58d9ca5c6456a9a56eb7606e4fb18c4b0e 100644 (file)
  *     it under the terms of the GNU General Public License, as published by
  *     the Free Software Foundation, version 2.
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
- * 
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
+ *
  * (07/16/2001) gb
- *     remove unused code in empeg_close() (thanks to Oliver Neukum for pointing this
- *     out) and rewrote empeg_set_termios().
- * 
+ *     remove unused code in empeg_close() (thanks to Oliver Neukum for
+ *     pointing this out) and rewrote empeg_set_termios().
+ *
  * (05/30/2001) gkh
- *     switched from using spinlock to a semaphore, which fixes lots of problems.
+ *     switched from using spinlock to a semaphore, which fixes lots of
+ * problems.
  *
  * (04/08/2001) gb
  *      Identify version on module load.
- * 
+ *
  * (01/22/2001) gb
- *     Added write_room() and chars_in_buffer() support. 
- * 
+ *     Added write_room() and chars_in_buffer() support.
+ *
  * (12/21/2000) gb
  *     Moved termio stuff inside the port->active check.
  *     Moved MOD_DEC_USE_COUNT to end of empeg_close().
- * 
+ *
  * (12/03/2000) gb
- *     Added port->tty->ldisc.set_termios(port->tty, NULL) to empeg_open()
- *     This notifies the tty driver that the termios have changed.
- * 
+ *     Added port->port.tty->ldisc.set_termios(port->port.tty, NULL) to
+ *     empeg_open(). This notifies the tty driver that the termios have
+ *     changed.
+ *
  * (11/13/2000) gb
- *     Moved tty->low_latency = 1 from empeg_read_bulk_callback() to empeg_open()
- *     (It only needs to be set once - Doh!)
- * 
+ *     Moved tty->low_latency = 1 from empeg_read_bulk_callback() to
+ *     empeg_open() (It only needs to be set once - Doh!)
+ *
  * (11/11/2000) gb
  *     Updated to work with id_table structure.
- * 
+ *
  * (11/04/2000) gb
  *     Forked this from visor.c, and hacked it up to work with an
  *     Empeg ltd. empeg-car player.  Constructive criticism welcomed.
@@ -48,7 +51,7 @@
  *     use of his code, and for his guidance, advice and patience. :)
  *     A 'Thank You' is in order for John Ripley of Empeg ltd for his
  *     advice, and patience too.
- * 
+ *
  */
 
 #include <linux/kernel.h>
@@ -60,7 +63,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
@@ -77,31 +80,30 @@ static int debug;
 #define EMPEG_PRODUCT_ID               0x0001
 
 /* function prototypes for an empeg-car player */
-static int  empeg_open                 (struct usb_serial_port *port, struct file *filp);
-static void empeg_close                        (struct usb_serial_port *port, struct file *filp);
-static int  empeg_write                        (struct usb_serial_port *port,
-                                       const unsigned char *buf,
-                                       int count);
-static int  empeg_write_room           (struct usb_serial_port *port);
-static int  empeg_chars_in_buffer      (struct usb_serial_port *port);
-static void empeg_throttle             (struct usb_serial_port *port);
-static void empeg_unthrottle           (struct usb_serial_port *port);
-static int  empeg_startup              (struct usb_serial *serial);
-static void empeg_shutdown             (struct usb_serial *serial);
-static int  empeg_ioctl                        (struct usb_serial_port *port,
-                                       struct file * file,
-                                       unsigned int cmd,
-                                       unsigned long arg);
-static void empeg_set_termios          (struct usb_serial_port *port, struct ktermios *old_termios);
-static void empeg_write_bulk_callback  (struct urb *urb);
-static void empeg_read_bulk_callback   (struct urb *urb);
+static int  empeg_open(struct tty_struct *tty, struct usb_serial_port *port,
+                                               struct file *filp);
+static void empeg_close(struct tty_struct *tty, struct usb_serial_port *port,
+                                               struct file *filp);
+static int  empeg_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                               const unsigned char *buf,
+                                               int count);
+static int  empeg_write_room(struct tty_struct *tty);
+static int  empeg_chars_in_buffer(struct tty_struct *tty);
+static void empeg_throttle(struct tty_struct *tty);
+static void empeg_unthrottle(struct tty_struct *tty);
+static int  empeg_startup(struct usb_serial *serial);
+static void empeg_shutdown(struct usb_serial *serial);
+static void empeg_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios);
+static void empeg_write_bulk_callback(struct urb *urb);
+static void empeg_read_bulk_callback(struct urb *urb);
 
 static struct usb_device_id id_table [] = {
        { USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) },
        { }                                     /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver empeg_driver = {
        .name =         "empeg",
@@ -125,7 +127,6 @@ static struct usb_serial_driver empeg_device = {
        .unthrottle =           empeg_unthrottle,
        .attach =               empeg_startup,
        .shutdown =             empeg_shutdown,
-       .ioctl =                empeg_ioctl,
        .set_termios =          empeg_set_termios,
        .write =                empeg_write,
        .write_room =           empeg_write_room,
@@ -145,7 +146,8 @@ static int          bytes_out;
 /******************************************************************************
  * Empeg specific driver functions
  ******************************************************************************/
-static int empeg_open (struct usb_serial_port *port, struct file *filp)
+static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port,
+                               struct file *filp)
 {
        struct usb_serial *serial = port->serial;
        int result = 0;
@@ -153,7 +155,7 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp)
        dbg("%s - port %d", __func__, port->number);
 
        /* Force default termio settings */
-       empeg_set_termios (port, NULL) ;
+       empeg_set_termios(tty, port, NULL) ;
 
        bytes_in = 0;
        bytes_out = 0;
@@ -161,7 +163,7 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp)
        /* Start reading from the device */
        usb_fill_bulk_urb(
                port->read_urb,
-               serial->dev, 
+               serial->dev,
                usb_rcvbulkpipe(serial->dev,
                        port->bulk_in_endpointAddress),
                port->read_urb->transfer_buffer,
@@ -172,13 +174,16 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp)
        result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 
        if (result)
-               dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result);
+               dev_err(&port->dev,
+                       "%s - failed submitting read urb, error %d\n",
+                                                       __func__, result);
 
        return result;
 }
 
 
-static void empeg_close (struct usb_serial_port *port, struct file * filp)
+static void empeg_close(struct tty_struct *tty, struct usb_serial_port *port,
+                               struct file *filp)
 {
        dbg("%s - port %d", __func__, port->number);
 
@@ -189,7 +194,8 @@ static void empeg_close (struct usb_serial_port *port, struct file * filp)
 }
 
 
-static int empeg_write (struct usb_serial_port *port, const unsigned char *buf, int count)
+static int empeg_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                       const unsigned char *buf, int count)
 {
        struct usb_serial *serial = port->serial;
        struct urb *urb;
@@ -203,11 +209,10 @@ static int empeg_write (struct usb_serial_port *port, const unsigned char *buf,
        dbg("%s - port %d", __func__, port->number);
 
        while (count > 0) {
-
                /* try to find a free urb in our list of them */
                urb = NULL;
 
-               spin_lock_irqsave (&write_urb_pool_lock, flags);
+               spin_lock_irqsave(&write_urb_pool_lock, flags);
 
                for (i = 0; i < NUM_URBS; ++i) {
                        if (write_urb_pool[i]->status != -EINPROGRESS) {
@@ -216,7 +221,7 @@ static int empeg_write (struct usb_serial_port *port, const unsigned char *buf,
                        }
                }
 
-               spin_unlock_irqrestore (&write_urb_pool_lock, flags);
+               spin_unlock_irqrestore(&write_urb_pool_lock, flags);
 
                if (urb == NULL) {
                        dbg("%s - no more free urbs", __func__);
@@ -224,25 +229,27 @@ static int empeg_write (struct usb_serial_port *port, const unsigned char *buf,
                }
 
                if (urb->transfer_buffer == NULL) {
-                       urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC);
+                       urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC);
                        if (urb->transfer_buffer == NULL) {
-                               dev_err(&port->dev, "%s no more kernel memory...\n", __func__);
+                               dev_err(&port->dev,
+                                       "%s no more kernel memory...\n",
+                                                               __func__);
                                goto exit;
                        }
                }
 
-               transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE);
+               transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
 
-               memcpy (urb->transfer_buffer, current_position, transfer_size);
+               memcpy(urb->transfer_buffer, current_position, transfer_size);
 
                usb_serial_debug_data(debug, &port->dev, __func__, transfer_size, urb->transfer_buffer);
 
                /* build up our urb */
-               usb_fill_bulk_urb (
+               usb_fill_bulk_urb(
                        urb,
                        serial->dev,
                        usb_sndbulkpipe(serial->dev,
-                               port->bulk_out_endpointAddress), 
+                                       port->bulk_out_endpointAddress),
                        urb->transfer_buffer,
                        transfer_size,
                        empeg_write_bulk_callback,
@@ -262,66 +269,57 @@ static int empeg_write (struct usb_serial_port *port, const unsigned char *buf,
                bytes_out += transfer_size;
 
        }
-
 exit:
        return bytes_sent;
-
-} 
+}
 
 
-static int empeg_write_room (struct usb_serial_port *port)
+static int empeg_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        unsigned long flags;
        int i;
        int room = 0;
 
        dbg("%s - port %d", __func__, port->number);
 
-       spin_lock_irqsave (&write_urb_pool_lock, flags);
-
+       spin_lock_irqsave(&write_urb_pool_lock, flags);
        /* tally up the number of bytes available */
        for (i = 0; i < NUM_URBS; ++i) {
-               if (write_urb_pool[i]->status != -EINPROGRESS) {
+               if (write_urb_pool[i]->status != -EINPROGRESS)
                        room += URB_TRANSFER_BUFFER_SIZE;
-               }
-       } 
-
-       spin_unlock_irqrestore (&write_urb_pool_lock, flags);
-
+       }
+       spin_unlock_irqrestore(&write_urb_pool_lock, flags);
        dbg("%s - returns %d", __func__, room);
-
-       return (room);
+       return room;
 
 }
 
 
-static int empeg_chars_in_buffer (struct usb_serial_port *port)
+static int empeg_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        unsigned long flags;
        int i;
        int chars = 0;
 
        dbg("%s - port %d", __func__, port->number);
 
-       spin_lock_irqsave (&write_urb_pool_lock, flags);
+       spin_lock_irqsave(&write_urb_pool_lock, flags);
 
        /* tally up the number of bytes waiting */
        for (i = 0; i < NUM_URBS; ++i) {
-               if (write_urb_pool[i]->status == -EINPROGRESS) {
+               if (write_urb_pool[i]->status == -EINPROGRESS)
                        chars += URB_TRANSFER_BUFFER_SIZE;
-               }
        }
 
-       spin_unlock_irqrestore (&write_urb_pool_lock, flags);
-
+       spin_unlock_irqrestore(&write_urb_pool_lock, flags);
        dbg("%s - returns %d", __func__, chars);
-
-       return (chars);
-
+       return chars;
 }
 
 
-static void empeg_write_bulk_callback (struct urb *urb)
+static void empeg_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        int status = urb->status;
@@ -338,7 +336,7 @@ static void empeg_write_bulk_callback (struct urb *urb)
 }
 
 
-static void empeg_read_bulk_callback (struct urb *urb)
+static void empeg_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct tty_struct *tty;
@@ -354,9 +352,9 @@ static void empeg_read_bulk_callback (struct urb *urb)
                return;
        }
 
-       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
-
-       tty = port->tty;
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                                               urb->actual_length, data);
+       tty = port->port.tty;
 
        if (urb->actual_length) {
                tty_buffer_request_room(tty, urb->actual_length);
@@ -368,7 +366,7 @@ static void empeg_read_bulk_callback (struct urb *urb)
        /* Continue trying to always read  */
        usb_fill_bulk_urb(
                port->read_urb,
-               port->serial->dev, 
+               port->serial->dev,
                usb_rcvbulkpipe(port->serial->dev,
                        port->bulk_in_endpointAddress),
                port->read_urb->transfer_buffer,
@@ -379,38 +377,39 @@ static void empeg_read_bulk_callback (struct urb *urb)
        result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
 
        if (result)
-               dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result);
+               dev_err(&urb->dev->dev,
+                       "%s - failed resubmitting read urb, error %d\n",
+                                                       __func__, result);
 
        return;
 
 }
 
 
-static void empeg_throttle (struct usb_serial_port *port)
+static void empeg_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        dbg("%s - port %d", __func__, port->number);
        usb_kill_urb(port->read_urb);
 }
 
 
-static void empeg_unthrottle (struct usb_serial_port *port)
+static void empeg_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        int result;
-
        dbg("%s - port %d", __func__, port->number);
 
        port->read_urb->dev = port->serial->dev;
-
        result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
-
        if (result)
-               dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result);
-
-       return;
+               dev_err(&port->dev,
+                       "%s - failed submitting read urb, error %d\n",
+                                                       __func__, result);
 }
 
 
-static int  empeg_startup (struct usb_serial *serial)
+static int  empeg_startup(struct usb_serial *serial)
 {
        int r;
 
@@ -422,7 +421,7 @@ static int  empeg_startup (struct usb_serial *serial)
                return -ENODEV;
        }
        dbg("%s - reset config", __func__);
-       r = usb_reset_configuration (serial->dev);
+       r = usb_reset_configuration(serial->dev);
 
        /* continue on with initialization */
        return r;
@@ -430,34 +429,27 @@ static int  empeg_startup (struct usb_serial *serial)
 }
 
 
-static void empeg_shutdown (struct usb_serial *serial)
+static void empeg_shutdown(struct usb_serial *serial)
 {
-       dbg ("%s", __func__);
-}
-
-
-static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
-{
-       dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
-
-       return -ENOIOCTLCMD;
+       dbg("%s", __func__);
 }
 
 
-static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
+static void empeg_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
-       struct ktermios *termios = port->tty->termios;
+       struct ktermios *termios = tty->termios;
        dbg("%s - port %d", __func__, port->number);
 
        /*
-         * The empeg-car player wants these particular tty settings.
-         * You could, for example, change the baud rate, however the
-         * player only supports 115200 (currently), so there is really
-         * no point in support for changes to the tty settings.
-         * (at least for now)
-         *
-         * The default requirements for this device are:
-         */
+        * The empeg-car player wants these particular tty settings.
+        * You could, for example, change the baud rate, however the
+        * player only supports 115200 (currently), so there is really
+        * no point in support for changes to the tty settings.
+        * (at least for now)
+        *
+        * The default requirements for this device are:
+        */
        termios->c_iflag
                &= ~(IGNBRK     /* disable ignore break */
                | BRKINT        /* disable break causes interrupt */
@@ -491,18 +483,18 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol
         * this is bad as it opens up the possibility of dropping bytes
         * on the floor.  We don't want to drop bytes on the floor. :)
         */
-       port->tty->low_latency = 1;
-       tty_encode_baud_rate(port->tty, 115200, 115200);
+       tty->low_latency = 1;
+       tty_encode_baud_rate(tty, 115200, 115200);
 }
 
 
-static int __init empeg_init (void)
+static int __init empeg_init(void)
 {
        struct urb *urb;
        int i, retval;
 
-       /* create our write urb pool and transfer buffers */ 
-       spin_lock_init (&write_urb_pool_lock);
+       /* create our write urb pool and transfer buffers */
+       spin_lock_init(&write_urb_pool_lock);
        for (i = 0; i < NUM_URBS; ++i) {
                urb = usb_alloc_urb(0, GFP_KERNEL);
                write_urb_pool[i] = urb;
@@ -511,9 +503,10 @@ static int __init empeg_init (void)
                        continue;
                }
 
-               urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+               urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
+                                                               GFP_KERNEL);
                if (!urb->transfer_buffer) {
-                       err("%s - out of memory for urb buffers.", 
+                       err("%s - out of memory for urb buffers.",
                            __func__);
                        continue;
                }
@@ -542,36 +535,36 @@ failed_usb_serial_register:
 }
 
 
-static void __exit empeg_exit (void)
+static void __exit empeg_exit(void)
 {
        int i;
        unsigned long flags;
 
        usb_deregister(&empeg_driver);
-       usb_serial_deregister (&empeg_device);
+       usb_serial_deregister(&empeg_device);
 
-       spin_lock_irqsave (&write_urb_pool_lock, flags);
+       spin_lock_irqsave(&write_urb_pool_lock, flags);
 
        for (i = 0; i < NUM_URBS; ++i) {
                if (write_urb_pool[i]) {
-                       /* FIXME - uncomment the following usb_kill_urb call when
-                        * the host controllers get fixed to set urb->dev = NULL after
-                        * the urb is finished.  Otherwise this call oopses. */
+                       /* FIXME - uncomment the following usb_kill_urb call
+                        * when the host controllers get fixed to set urb->dev
+                        * = NULL after the urb is finished.  Otherwise this
+                        * call oopses. */
                        /* usb_kill_urb(write_urb_pool[i]); */
                        kfree(write_urb_pool[i]->transfer_buffer);
-                       usb_free_urb (write_urb_pool[i]);
+                       usb_free_urb(write_urb_pool[i]);
                }
        }
-
-       spin_unlock_irqrestore (&write_urb_pool_lock, flags);
+       spin_unlock_irqrestore(&write_urb_pool_lock, flags);
 }
 
 
 module_init(empeg_init);
 module_exit(empeg_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
index cc4fbd9d60be9620532ca5c18da43d9ff406b705..711e84f6ed82d8d0c0d80d50da5f5b4ec057014f 100644 (file)
@@ -20,7 +20,8 @@
 /* EZ-USB Control and Status Register.  Bit 0 controls 8051 reset */
 #define CPUCS_REG    0x7F92
 
-int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest)
+int ezusb_writememory(struct usb_serial *serial, int address,
+                               unsigned char *data, int length, __u8 request)
 {
        int result;
        unsigned char *transfer_buffer;
@@ -33,26 +34,27 @@ int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *da
 
        transfer_buffer = kmemdup(data, length, GFP_KERNEL);
        if (!transfer_buffer) {
-               dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __func__, length);
+               dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n",
+                                                       __func__, length);
                return -ENOMEM;
        }
-       result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 3000);
-       kfree (transfer_buffer);
+       result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+                    request, 0x40, address, 0, transfer_buffer, length, 3000);
+       kfree(transfer_buffer);
        return result;
 }
+EXPORT_SYMBOL_GPL(ezusb_writememory);
 
-int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit)
+int ezusb_set_reset(struct usb_serial *serial, unsigned char reset_bit)
 {
        int response;
 
        /* dbg("%s - %d", __func__, reset_bit); */
-       response = ezusb_writememory (serial, CPUCS_REG, &reset_bit, 1, 0xa0);
+       response = ezusb_writememory(serial, CPUCS_REG, &reset_bit, 1, 0xa0);
        if (response < 0)
-               dev_err(&serial->dev->dev, "%s- %d failed\n", __func__, reset_bit);
+               dev_err(&serial->dev->dev, "%s- %d failed\n",
+                                               __func__, reset_bit);
        return response;
 }
-
-
-EXPORT_SYMBOL_GPL(ezusb_writememory);
 EXPORT_SYMBOL_GPL(ezusb_set_reset);
 
index 0ff4a3971e45a95ce0e7047a0e6bb7411646c493..83871725014575d391acf77f6d27bf6aadc27c53 100644 (file)
@@ -12,7 +12,8 @@
  *     the Free Software Foundation; either version 2 of the License, or
  *     (at your option) any later version.
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
  *
  * See http://ftdi-usb-sio.sourceforge.net for upto date testing info
  *     and extra documentation
@@ -25,7 +26,8 @@
 /* Bill Ryder - bryder@sgi.com - wrote the FTDI_SIO implementation */
 /* Thanx to FTDI for so kindly providing details of the protocol required */
 /*   to talk to the device */
-/* Thanx to gkh and the rest of the usb dev group for all code I have assimilated :-) */
+/* Thanx to gkh and the rest of the usb dev group for all code I have
+   assimilated :-) */
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -36,7 +38,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/serial.h>
 #include <linux/usb/serial.h>
@@ -55,17 +57,22 @@ static __u16 product;
 
 struct ftdi_private {
        ftdi_chip_type_t chip_type;
-                               /* type of the device, either SIO or FT8U232AM */
+                               /* type of device, either SIO or FT8U232AM */
        int baud_base;          /* baud base clock for divisor setting */
-       int custom_divisor;     /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */
+       int custom_divisor;     /* custom_divisor kludge, this is for
+                                  baud_base (different from what goes to the
+                                  chip!) */
        __u16 last_set_data_urb_value ;
-                               /* the last data state set - needed for doing a break */
-        int write_offset;       /* This is the offset in the usb data block to write the serial data -
-                                * it is different between devices
+                               /* the last data state set - needed for doing
+                                * a break
+                                */
+       int write_offset;       /* This is the offset in the usb data block to
+                                * write the serial data - it varies between
+                                * devices
                                 */
        int flags;              /* some ASYNC_xxxx flags are supported */
        unsigned long last_dtr_rts;     /* saved modem control outputs */
-        wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
+       wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
        char prev_status, diff_status;        /* Used for TIOCMIWAIT */
        __u8 rx_flags;          /* receive state flags (throttling) */
        spinlock_t rx_lock;     /* spinlock for receive state */
@@ -76,8 +83,10 @@ struct ftdi_private {
 
        __u16 interface;        /* FT2232C port interface (0 for FT232/245) */
 
-       speed_t force_baud;     /* if non-zero, force the baud rate to this value */
-       int force_rtscts;       /* if non-zero, force RTS-CTS to always be enabled */
+       speed_t force_baud;     /* if non-zero, force the baud rate to
+                                  this value */
+       int force_rtscts;       /* if non-zero, force RTS-CTS to always
+                                  be enabled */
 
        spinlock_t tx_lock;     /* spinlock for transmit state */
        unsigned long tx_bytes;
@@ -88,13 +97,14 @@ struct ftdi_private {
 /* struct ftdi_sio_quirk is used by devices requiring special attention. */
 struct ftdi_sio_quirk {
        int (*probe)(struct usb_serial *);
-       void (*port_probe)(struct ftdi_private *); /* Special settings for probed ports. */
+       /* Special settings for probed ports. */
+       void (*port_probe)(struct ftdi_private *);
 };
 
-static int   ftdi_jtag_probe           (struct usb_serial *serial);
-static int   ftdi_mtxorb_hack_setup    (struct usb_serial *serial);
-static void  ftdi_USB_UIRT_setup       (struct ftdi_private *priv);
-static void  ftdi_HE_TIRA1_setup       (struct ftdi_private *priv);
+static int   ftdi_jtag_probe(struct usb_serial *serial);
+static int   ftdi_mtxorb_hack_setup(struct usb_serial *serial);
+static void  ftdi_USB_UIRT_setup(struct ftdi_private *priv);
+static void  ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
 
 static struct ftdi_sio_quirk ftdi_jtag_quirk = {
        .probe  = ftdi_jtag_probe,
@@ -174,270 +184,270 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0100_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0101_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0102_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0103_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0104_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0105_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0106_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0107_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0108_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0109_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010A_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010B_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010C_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010D_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010E_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_010F_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0110_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0111_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0112_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0113_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0114_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0115_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0116_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0117_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0118_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0119_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011A_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011B_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011C_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011D_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011E_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_011F_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0120_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0121_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0122_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0123_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0124_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0125_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0126_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0127_PID),
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0103_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0104_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0105_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0106_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0107_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0108_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0109_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010A_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010B_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010C_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010D_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010E_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_010F_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0110_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0111_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0112_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0113_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0114_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0115_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0116_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0117_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0118_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0119_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011A_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011B_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011C_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011D_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011E_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_011F_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0120_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0121_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0122_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0123_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0124_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0125_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0126_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0127_PID),
                .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0128_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0129_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012A_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012B_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012C_PID),
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0128_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0129_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012A_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012B_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012C_PID),
                .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012D_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012E_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_012F_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0130_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0131_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0132_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0133_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0134_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0135_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0136_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0137_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0138_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0139_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013A_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013B_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013C_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013D_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013E_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_013F_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0140_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0141_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0142_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0143_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0144_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0145_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0146_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0147_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0148_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0149_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014A_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014B_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014C_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014D_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014E_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_014F_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0150_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0151_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0152_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0153_PID),
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012D_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012E_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_012F_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0130_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0131_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0132_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0133_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0134_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0135_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0136_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0137_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0138_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0139_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013A_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013B_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013C_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013D_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013E_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_013F_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0140_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0141_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0142_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0143_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0144_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0145_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0146_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0147_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0148_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0149_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014A_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014B_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014C_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014D_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014E_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_014F_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0150_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0151_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0152_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0153_PID),
                .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0154_PID),
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0154_PID),
                .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0155_PID),
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0155_PID),
                .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0156_PID),
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0156_PID),
                .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0157_PID),
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0157_PID),
                .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0158_PID),
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0158_PID),
                .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0159_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015A_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015B_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015C_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015D_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015E_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_015F_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0160_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0161_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0162_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0163_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0164_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0165_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0166_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0167_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0168_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0169_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016A_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016B_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016C_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016D_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016E_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_016F_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0170_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0171_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0172_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0173_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0174_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0175_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0176_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0177_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0178_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0179_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017A_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017B_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017C_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017D_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017E_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_017F_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0180_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0181_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0182_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0183_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0184_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0185_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0186_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0187_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0188_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0189_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018A_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018B_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018C_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018D_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018E_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_018F_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0190_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0191_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0192_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0193_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0194_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0195_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0196_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0197_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0198_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_0199_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019A_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019B_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019C_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019D_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019E_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_019F_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A0_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A1_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A2_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A3_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A4_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A5_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A6_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A7_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A8_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01A9_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AA_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AB_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AC_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AD_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AE_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01AF_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B0_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B1_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B2_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B3_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B4_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B5_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B6_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B7_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B8_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01B9_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BA_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BB_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BC_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BD_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BE_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01BF_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C0_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C1_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C2_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C3_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C4_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C5_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C6_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C7_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C8_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01C9_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CA_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CB_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CC_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CD_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CE_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01CF_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D0_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D1_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D2_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D3_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D4_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D5_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D6_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D7_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D8_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01D9_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DA_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DB_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DC_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DD_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DE_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01DF_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E0_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E1_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E2_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E3_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E4_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E5_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E6_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E7_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E8_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01E9_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EA_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EB_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EC_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01ED_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EE_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01EF_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F0_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F1_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F2_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F3_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F4_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F5_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F6_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F7_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F8_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01F9_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FA_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FB_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FC_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FD_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FE_PID) },
-       { USB_DEVICE(MTXORB_VID,MTXORB_FTDI_RANGE_01FF_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0159_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015A_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015B_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015C_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015D_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015E_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_015F_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0160_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0161_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0162_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0163_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0164_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0165_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0166_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0167_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0168_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0169_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016A_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016B_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016C_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016D_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016E_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_016F_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0170_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0171_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0172_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0173_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0174_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0175_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0176_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0177_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0178_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0179_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017A_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017B_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017C_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017D_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017E_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_017F_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0180_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0181_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0182_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0183_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0184_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0185_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0186_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0187_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0188_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0189_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018A_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018B_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018C_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018D_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018E_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_018F_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0190_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0191_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0192_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0193_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0194_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0195_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0196_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0197_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0198_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0199_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019A_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019B_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019C_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019D_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019E_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_019F_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A0_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A1_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A2_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A3_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A4_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A5_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A6_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A7_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A8_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01A9_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AA_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AB_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AC_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AD_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AE_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01AF_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B0_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B1_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B2_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B3_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B4_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B5_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B6_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B7_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B8_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01B9_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BA_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BB_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BC_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BD_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BE_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01BF_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C0_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C1_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C2_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C3_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C4_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C5_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C6_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C7_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C8_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01C9_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CA_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CB_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CC_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CD_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CE_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01CF_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D0_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D1_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D2_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D3_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D4_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D5_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D6_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D7_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D8_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01D9_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DA_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DB_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DC_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DD_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DE_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01DF_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E0_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E1_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E2_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E3_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E4_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E5_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E6_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E7_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E8_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01E9_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EA_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EB_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EC_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01ED_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EE_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01EF_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F0_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F1_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F2_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F3_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F4_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F5_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F6_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F7_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F8_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01F9_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FA_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FB_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FC_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FD_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FE_PID) },
+       { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_01FF_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) },
@@ -642,7 +652,7 @@ static struct usb_device_id id_table_combined [] = {
        { }                                     /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
 
 static struct usb_driver ftdi_driver = {
        .name =         "ftdi_sio",
@@ -678,30 +688,37 @@ static const char *ftdi_chip_name[] = {
  | ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP)
 
 /* function prototypes for a FTDI serial converter */
-static int  ftdi_sio_probe     (struct usb_serial *serial, const struct usb_device_id *id);
-static void ftdi_shutdown              (struct usb_serial *serial);
-static int  ftdi_sio_port_probe        (struct usb_serial_port *port);
-static int  ftdi_sio_port_remove       (struct usb_serial_port *port);
-static int  ftdi_open                  (struct usb_serial_port *port, struct file *filp);
-static void ftdi_close                 (struct usb_serial_port *port, struct file *filp);
-static int  ftdi_write                 (struct usb_serial_port *port, const unsigned char *buf, int count);
-static int  ftdi_write_room            (struct usb_serial_port *port);
-static int  ftdi_chars_in_buffer       (struct usb_serial_port *port);
-static void ftdi_write_bulk_callback   (struct urb *urb);
-static void ftdi_read_bulk_callback    (struct urb *urb);
-static void ftdi_process_read          (struct work_struct *work);
-static void ftdi_set_termios           (struct usb_serial_port *port, struct ktermios * old);
-static int  ftdi_tiocmget               (struct usb_serial_port *port, struct file *file);
-static int  ftdi_tiocmset              (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear);
-static int  ftdi_ioctl                 (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void ftdi_break_ctl             (struct usb_serial_port *port, int break_state );
-static void ftdi_throttle              (struct usb_serial_port *port);
-static void ftdi_unthrottle            (struct usb_serial_port *port);
-
-static unsigned short int ftdi_232am_baud_base_to_divisor (int baud, int base);
-static unsigned short int ftdi_232am_baud_to_divisor (int baud);
-static __u32 ftdi_232bm_baud_base_to_divisor (int baud, int base);
-static __u32 ftdi_232bm_baud_to_divisor (int baud);
+static int  ftdi_sio_probe(struct usb_serial *serial,
+                                       const struct usb_device_id *id);
+static void ftdi_shutdown(struct usb_serial *serial);
+static int  ftdi_sio_port_probe(struct usb_serial_port *port);
+static int  ftdi_sio_port_remove(struct usb_serial_port *port);
+static int  ftdi_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static void ftdi_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static int  ftdi_write(struct tty_struct *tty, struct usb_serial_port *port,
+                       const unsigned char *buf, int count);
+static int  ftdi_write_room(struct tty_struct *tty);
+static int  ftdi_chars_in_buffer(struct tty_struct *tty);
+static void ftdi_write_bulk_callback(struct urb *urb);
+static void ftdi_read_bulk_callback(struct urb *urb);
+static void ftdi_process_read(struct work_struct *work);
+static void ftdi_set_termios(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct ktermios *old);
+static int  ftdi_tiocmget(struct tty_struct *tty, struct file *file);
+static int  ftdi_tiocmset(struct tty_struct *tty, struct file *file,
+                       unsigned int set, unsigned int clear);
+static int  ftdi_ioctl(struct tty_struct *tty, struct file *file,
+                       unsigned int cmd, unsigned long arg);
+static void ftdi_break_ctl(struct tty_struct *tty, int break_state);
+static void ftdi_throttle(struct tty_struct *tty);
+static void ftdi_unthrottle(struct tty_struct *tty);
+
+static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base);
+static unsigned short int ftdi_232am_baud_to_divisor(int baud);
+static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base);
+static __u32 ftdi_232bm_baud_to_divisor(int baud);
 
 static struct usb_serial_driver ftdi_sio_device = {
        .driver = {
@@ -752,44 +769,54 @@ static struct usb_serial_driver ftdi_sio_device = {
 static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base)
 {
        unsigned short int divisor;
-       int divisor3 = base / 2 / baud; // divisor shifted 3 bits to the left
-       if ((divisor3 & 0x7) == 7) divisor3 ++; // round x.7/8 up to x+1
+       /* divisor shifted 3 bits to the left */
+       int divisor3 = base / 2 / baud;
+       if ((divisor3 & 0x7) == 7)
+               divisor3++; /* round x.7/8 up to x+1 */
        divisor = divisor3 >> 3;
        divisor3 &= 0x7;
-       if (divisor3 == 1) divisor |= 0xc000; else // 0.125
-       if (divisor3 >= 4) divisor |= 0x4000; else // 0.5
-       if (divisor3 != 0) divisor |= 0x8000;      // 0.25
-       if (divisor == 1) divisor = 0;  /* special case for maximum baud rate */
+       if (divisor3 == 1)
+               divisor |= 0xc000;
+       else if (divisor3 >= 4)
+               divisor |= 0x4000;
+       else if (divisor3 != 0)
+               divisor |= 0x8000;
+       else if (divisor == 1)
+               divisor = 0;    /* special case for maximum baud rate */
        return divisor;
 }
 
 static unsigned short int ftdi_232am_baud_to_divisor(int baud)
 {
-        return(ftdi_232am_baud_base_to_divisor(baud, 48000000));
+        return ftdi_232am_baud_base_to_divisor(baud, 48000000);
 }
 
 static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base)
 {
        static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };
        __u32 divisor;
-       int divisor3 = base / 2 / baud; // divisor shifted 3 bits to the left
+       /* divisor shifted 3 bits to the left */
+       int divisor3 = base / 2 / baud;
        divisor = divisor3 >> 3;
        divisor |= (__u32)divfrac[divisor3 & 0x7] << 14;
        /* Deal with special cases for highest baud rates. */
-       if (divisor == 1) divisor = 0; else     // 1.0
-       if (divisor == 0x4001) divisor = 1;     // 1.5
+       if (divisor == 1)
+               divisor = 0;
+       else if (divisor == 0x4001)
+               divisor = 1;
        return divisor;
 }
 
 static __u32 ftdi_232bm_baud_to_divisor(int baud)
 {
-        return(ftdi_232bm_baud_base_to_divisor(baud, 48000000));
+        return ftdi_232bm_baud_base_to_divisor(baud, 48000000);
 }
 
 #define set_mctrl(port, set)           update_mctrl((port), (set), 0)
 #define clear_mctrl(port, clear)       update_mctrl((port), 0, (clear))
 
-static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned int clear)
+static int update_mctrl(struct usb_serial_port *port, unsigned int set,
+                                                       unsigned int clear)
 {
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        char *buf;
@@ -843,42 +870,8 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned
 }
 
 
-static __u32 get_ftdi_divisor(struct usb_serial_port * port);
-
-
-static int change_speed(struct usb_serial_port *port)
-{
-       struct ftdi_private *priv = usb_get_serial_port_data(port);
-       char *buf;
-        __u16 urb_value;
-       __u16 urb_index;
-       __u32 urb_index_value;
-       int rv;
-
-       buf = kmalloc(1, GFP_NOIO);
-       if (!buf)
-               return -ENOMEM;
-
-       urb_index_value = get_ftdi_divisor(port);
-       urb_value = (__u16)urb_index_value;
-       urb_index = (__u16)(urb_index_value >> 16);
-       if (priv->interface) {  /* FT2232C */
-               urb_index = (__u16)((urb_index << 8) | priv->interface);
-       }
-
-       rv = usb_control_msg(port->serial->dev,
-                           usb_sndctrlpipe(port->serial->dev, 0),
-                           FTDI_SIO_SET_BAUDRATE_REQUEST,
-                           FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE,
-                           urb_value, urb_index,
-                           buf, 0, WDR_SHORT_TIMEOUT);
-
-       kfree(buf);
-       return rv;
-}
-
-
-static __u32 get_ftdi_divisor(struct usb_serial_port * port)
+static __u32 get_ftdi_divisor(struct tty_struct *tty,
+                                               struct usb_serial_port *port)
 { /* get_ftdi_divisor */
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        __u32 div_value = 0;
@@ -886,48 +879,56 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
        int baud;
 
        /*
-        * The logic involved in setting the baudrate can be cleanly split in 3 steps.
-        * Obtaining the actual baud rate is a little tricky since unix traditionally
-        * somehow ignored the possibility to set non-standard baud rates.
+        * The logic involved in setting the baudrate can be cleanly split into
+        * 3 steps.
         * 1. Standard baud rates are set in tty->termios->c_cflag
-        * 2. If these are not enough, you can set any speed using alt_speed as follows:
+        * 2. If these are not enough, you can set any speed using alt_speed as
+        * follows:
         *    - set tty->termios->c_cflag speed to B38400
         *    - set your real speed in tty->alt_speed; it gets ignored when
         *      alt_speed==0, (or)
-        *    - call TIOCSSERIAL ioctl with (struct serial_struct) set as follows:
-        *      flags & ASYNC_SPD_MASK == ASYNC_SPD_[HI, VHI, SHI, WARP], this just
-        *      sets alt_speed to (HI: 57600, VHI: 115200, SHI: 230400, WARP: 460800)
+        *    - call TIOCSSERIAL ioctl with (struct serial_struct) set as
+        *      follows:
+        *      flags & ASYNC_SPD_MASK == ASYNC_SPD_[HI, VHI, SHI, WARP],
+        *      this just sets alt_speed to (HI: 57600, VHI: 115200,
+        *      SHI: 230400, WARP: 460800)
         * ** Steps 1, 2 are done courtesy of tty_get_baud_rate
         * 3. You can also set baud rate by setting custom divisor as follows
         *    - set tty->termios->c_cflag speed to B38400
-        *    - call TIOCSSERIAL ioctl with (struct serial_struct) set as follows:
+        *    - call TIOCSSERIAL ioctl with (struct serial_struct) set as
+        *      follows:
         *      o flags & ASYNC_SPD_MASK == ASYNC_SPD_CUST
         *      o custom_divisor set to baud_base / your_new_baudrate
-        * ** Step 3 is done courtesy of code borrowed from serial.c - I should really
-        *    spend some time and separate+move this common code to serial.c, it is
-        *    replicated in nearly every serial driver you see.
+        * ** Step 3 is done courtesy of code borrowed from serial.c
+        *    I should really spend some time and separate + move this common
+        *    code to serial.c, it is replicated in nearly every serial driver
+        *    you see.
         */
 
-       /* 1. Get the baud rate from the tty settings, this observes alt_speed hack */
+       /* 1. Get the baud rate from the tty settings, this observes
+             alt_speed hack */
 
-       baud = tty_get_baud_rate(port->tty);
+       baud = tty_get_baud_rate(tty);
        dbg("%s - tty_get_baud_rate reports speed %d", __func__, baud);
 
-       /* 2. Observe async-compatible custom_divisor hack, update baudrate if needed */
+       /* 2. Observe async-compatible custom_divisor hack, update baudrate
+          if needed */
 
        if (baud == 38400 &&
            ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) &&
             (priv->custom_divisor)) {
                baud = priv->baud_base / priv->custom_divisor;
-               dbg("%s - custom divisor %d sets baud rate to %d", __func__, priv->custom_divisor, baud);
+               dbg("%s - custom divisor %d sets baud rate to %d",
+                               __func__, priv->custom_divisor, baud);
        }
 
        /* 3. Convert baudrate to device-specific divisor */
 
-       if (!baud) baud = 9600;
-       switch(priv->chip_type) {
+       if (!baud)
+               baud = 9600;
+       switch (priv->chip_type) {
        case SIO: /* SIO chip */
-               switch(baud) {
+               switch (baud) {
                case 300: div_value = ftdi_sio_b300; break;
                case 600: div_value = ftdi_sio_b600; break;
                case 1200: div_value = ftdi_sio_b1200; break;
@@ -940,7 +941,8 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
                case 115200: div_value = ftdi_sio_b115200; break;
                } /* baud */
                if (div_value == 0) {
-                       dbg("%s - Baudrate (%d) requested is not supported", __func__,  baud);
+                       dbg("%s - Baudrate (%d) requested is not supported",
+                                                       __func__,  baud);
                        div_value = ftdi_sio_b9600;
                        baud = 9600;
                        div_okay = 0;
@@ -950,7 +952,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
                if (baud <= 3000000) {
                        div_value = ftdi_232am_baud_to_divisor(baud);
                } else {
-                       dbg("%s - Baud rate too high!", __func__);
+                       dbg("%s - Baud rate too high!", __func__);
                        baud = 9600;
                        div_value = ftdi_232am_baud_to_divisor(9600);
                        div_okay = 0;
@@ -962,7 +964,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
                if (baud <= 3000000) {
                        div_value = ftdi_232bm_baud_to_divisor(baud);
                } else {
-                       dbg("%s - Baud rate too high!", __func__);
+                       dbg("%s - Baud rate too high!", __func__);
                        div_value = ftdi_232bm_baud_to_divisor(9600);
                        div_okay = 0;
                        baud = 9600;
@@ -976,12 +978,45 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
                        ftdi_chip_name[priv->chip_type]);
        }
 
-       tty_encode_baud_rate(port->tty, baud, baud);
-       return(div_value);
+       tty_encode_baud_rate(tty, baud, baud);
+       return div_value;
+}
+
+static int change_speed(struct tty_struct *tty, struct usb_serial_port *port)
+{
+       struct ftdi_private *priv = usb_get_serial_port_data(port);
+       char *buf;
+       __u16 urb_value;
+       __u16 urb_index;
+       __u32 urb_index_value;
+       int rv;
+
+       buf = kmalloc(1, GFP_NOIO);
+       if (!buf)
+               return -ENOMEM;
+
+       urb_index_value = get_ftdi_divisor(tty, port);
+       urb_value = (__u16)urb_index_value;
+       urb_index = (__u16)(urb_index_value >> 16);
+       if (priv->interface) {  /* FT2232C */
+               urb_index = (__u16)((urb_index << 8) | priv->interface);
+       }
+
+       rv = usb_control_msg(port->serial->dev,
+                           usb_sndctrlpipe(port->serial->dev, 0),
+                           FTDI_SIO_SET_BAUDRATE_REQUEST,
+                           FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE,
+                           urb_value, urb_index,
+                           buf, 0, WDR_SHORT_TIMEOUT);
+
+       kfree(buf);
+       return rv;
 }
 
 
-static int get_serial_info(struct usb_serial_port * port, struct serial_struct __user * retinfo)
+
+static int get_serial_info(struct usb_serial_port *port,
+                               struct serial_struct __user *retinfo)
 {
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        struct serial_struct tmp;
@@ -998,7 +1033,8 @@ static int get_serial_info(struct usb_serial_port * port, struct serial_struct _
 } /* get_serial_info */
 
 
-static int set_serial_info(struct usb_serial_port * port, struct serial_struct __user * newinfo)
+static int set_serial_info(struct tty_struct *tty,
+       struct usb_serial_port *port, struct serial_struct __user *newinfo)
 { /* set_serial_info */
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        struct serial_struct new_serial;
@@ -1006,7 +1042,7 @@ static int set_serial_info(struct usb_serial_port * port, struct serial_struct _
 
        if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
                return -EFAULT;
-       old_priv = * priv;
+       old_priv = *priv;
 
        /* Do error checking and permission checking */
 
@@ -1027,33 +1063,32 @@ static int set_serial_info(struct usb_serial_port * port, struct serial_struct _
        /* Make the changes - these are privileged changes! */
 
        priv->flags = ((priv->flags & ~ASYNC_FLAGS) |
-                      (new_serial.flags & ASYNC_FLAGS));
+                                       (new_serial.flags & ASYNC_FLAGS));
        priv->custom_divisor = new_serial.custom_divisor;
 
-       port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+       tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 
 check_and_exit:
        if ((old_priv.flags & ASYNC_SPD_MASK) !=
             (priv->flags & ASYNC_SPD_MASK)) {
                if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-                       port->tty->alt_speed = 57600;
+                       tty->alt_speed = 57600;
                else if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-                       port->tty->alt_speed = 115200;
+                       tty->alt_speed = 115200;
                else if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-                       port->tty->alt_speed = 230400;
+                       tty->alt_speed = 230400;
                else if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-                       port->tty->alt_speed = 460800;
+                       tty->alt_speed = 460800;
                else
-                       port->tty->alt_speed = 0;
+                       tty->alt_speed = 0;
        }
        if (((old_priv.flags & ASYNC_SPD_MASK) !=
             (priv->flags & ASYNC_SPD_MASK)) ||
            (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) &&
             (old_priv.custom_divisor != priv->custom_divisor))) {
-               change_speed(port);
+               change_speed(tty, port);
        }
-
-       return (0);
+       return 0;
 
 } /* set_serial_info */
 
@@ -1082,11 +1117,10 @@ static void ftdi_determine_type(struct usb_serial_port *port)
                priv->chip_type = FT2232C;
                /* Determine interface code. */
                inter = serial->interface->altsetting->desc.bInterfaceNumber;
-               if (inter == 0) {
+               if (inter == 0)
                        priv->interface = PIT_SIOA;
-               } else {
+               else
                        priv->interface = PIT_SIOB;
-               }
                /* BM-type devices have a bug where bcdDevice gets set
                 * to 0x200 when iSerialNumber is 0.  */
                if (version < 0x500) {
@@ -1120,7 +1154,8 @@ static void ftdi_determine_type(struct usb_serial_port *port)
  * ***************************************************************************
  */
 
-static ssize_t show_latency_timer(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_latency_timer(struct device *dev,
+                               struct device_attribute *attr, char *buf)
 {
        struct usb_serial_port *port = to_usb_serial_port(dev);
        struct ftdi_private *priv = usb_get_serial_port_data(port);
@@ -1129,14 +1164,14 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a
        int rv = 0;
 
 
-       dbg("%s",__func__);
+       dbg("%s", __func__);
 
        rv = usb_control_msg(udev,
                             usb_rcvctrlpipe(udev, 0),
                             FTDI_SIO_GET_LATENCY_TIMER_REQUEST,
                             FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
                             0, priv->interface,
-                            (char*) &latency, 1, WDR_TIMEOUT);
+                            (char *) &latency, 1, WDR_TIMEOUT);
 
        if (rv < 0) {
                dev_err(dev, "Unable to read latency timer: %i\n", rv);
@@ -1146,8 +1181,9 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a
 }
 
 /* Write a new value of the latency timer, in units of milliseconds. */
-static ssize_t store_latency_timer(struct device *dev, struct device_attribute *attr, const char *valbuf,
-                                  size_t count)
+static ssize_t store_latency_timer(struct device *dev,
+                       struct device_attribute *attr, const char *valbuf,
+                       size_t count)
 {
        struct usb_serial_port *port = to_usb_serial_port(dev);
        struct ftdi_private *priv = usb_get_serial_port_data(port);
@@ -1175,8 +1211,8 @@ static ssize_t store_latency_timer(struct device *dev, struct device_attribute *
 
 /* Write an event character directly to the FTDI register.  The ASCII
    value is in the low 8 bits, with the enable bit in the 9th bit. */
-static ssize_t store_event_char(struct device *dev, struct device_attribute *attr, const char *valbuf,
-                               size_t count)
+static ssize_t store_event_char(struct device *dev,
+       struct device_attribute *attr, const char *valbuf, size_t count)
 {
        struct usb_serial_port *port = to_usb_serial_port(dev);
        struct ftdi_private *priv = usb_get_serial_port_data(port);
@@ -1202,7 +1238,8 @@ static ssize_t store_event_char(struct device *dev, struct device_attribute *att
        return count;
 }
 
-static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer, store_latency_timer);
+static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer,
+                                                       store_latency_timer);
 static DEVICE_ATTR(event_char, S_IWUSR, NULL, store_event_char);
 
 static int create_sysfs_attrs(struct usb_serial_port *port)
@@ -1210,7 +1247,7 @@ static int create_sysfs_attrs(struct usb_serial_port *port)
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        int retval = 0;
 
-       dbg("%s",__func__);
+       dbg("%s", __func__);
 
        /* XXX I've no idea if the original SIO supports the event_char
         * sysfs parameter, so I'm playing it safe.  */
@@ -1232,7 +1269,7 @@ static void remove_sysfs_attrs(struct usb_serial_port *port)
 {
        struct ftdi_private *priv = usb_get_serial_port_data(port);
 
-       dbg("%s",__func__);
+       dbg("%s", __func__);
 
        /* XXX see create_sysfs_attrs */
        if (priv->chip_type != SIO) {
@@ -1253,9 +1290,11 @@ static void remove_sysfs_attrs(struct usb_serial_port *port)
  */
 
 /* Probe function to check for special devices */
-static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id)
+static int ftdi_sio_probe(struct usb_serial *serial,
+                                       const struct usb_device_id *id)
 {
-       struct ftdi_sio_quirk *quirk = (struct ftdi_sio_quirk *)id->driver_info;
+       struct ftdi_sio_quirk *quirk =
+                               (struct ftdi_sio_quirk *)id->driver_info;
 
        if (quirk && quirk->probe) {
                int ret = quirk->probe(serial);
@@ -1274,17 +1313,18 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
        struct ftdi_sio_quirk *quirk = usb_get_serial_data(port->serial);
 
 
-       dbg("%s",__func__);
+       dbg("%s", __func__);
 
        priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL);
-       if (!priv){
-               err("%s- kmalloc(%Zd) failed.", __func__, sizeof(struct ftdi_private));
+       if (!priv) {
+               err("%s- kmalloc(%Zd) failed.", __func__,
+                                       sizeof(struct ftdi_private));
                return -ENOMEM;
        }
 
        spin_lock_init(&priv->rx_lock);
        spin_lock_init(&priv->tx_lock);
-        init_waitqueue_head(&priv->delta_msr_wait);
+       init_waitqueue_head(&priv->delta_msr_wait);
        /* This will push the characters through immediately rather
           than queue a task to deliver them */
        priv->flags = ASYNC_LOW_LATENCY;
@@ -1294,9 +1334,9 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
 
        /* Increase the size of read buffers */
        kfree(port->bulk_in_buffer);
-       port->bulk_in_buffer = kmalloc (BUFSZ, GFP_KERNEL);
+       port->bulk_in_buffer = kmalloc(BUFSZ, GFP_KERNEL);
        if (!port->bulk_in_buffer) {
-               kfree (priv);
+               kfree(priv);
                return -ENOMEM;
        }
        if (port->read_urb) {
@@ -1309,7 +1349,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
 
        /* Free port's existing write urb and transfer buffer. */
        if (port->write_urb) {
-               usb_free_urb (port->write_urb);
+               usb_free_urb(port->write_urb);
                port->write_urb = NULL;
        }
        kfree(port->bulk_out_buffer);
@@ -1317,7 +1357,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
 
        usb_set_serial_port_data(port, priv);
 
-       ftdi_determine_type (port);
+       ftdi_determine_type(port);
        create_sysfs_attrs(port);
        return 0;
 }
@@ -1325,9 +1365,9 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
 /* Setup for the USB-UIRT device, which requires hardwired
  * baudrate (38400 gets mapped to 312500) */
 /* Called from usbserial:serial_probe */
-static void ftdi_USB_UIRT_setup (struct ftdi_private *priv)
+static void ftdi_USB_UIRT_setup(struct ftdi_private *priv)
 {
-       dbg("%s",__func__);
+       dbg("%s", __func__);
 
        priv->flags |= ASYNC_SPD_CUST;
        priv->custom_divisor = 77;
@@ -1336,9 +1376,10 @@ static void ftdi_USB_UIRT_setup (struct ftdi_private *priv)
 
 /* Setup for the HE-TIRA1 device, which requires hardwired
  * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled.  */
-static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv)
+
+static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv)
 {
-       dbg("%s",__func__);
+       dbg("%s", __func__);
 
        priv->flags |= ASYNC_SPD_CUST;
        priv->custom_divisor = 240;
@@ -1356,7 +1397,7 @@ static int ftdi_jtag_probe(struct usb_serial *serial)
        struct usb_device *udev = serial->dev;
        struct usb_interface *interface = serial->interface;
 
-       dbg("%s",__func__);
+       dbg("%s", __func__);
 
        if (interface == udev->actconfig->interface[0]) {
                info("Ignoring serial port reserved for JTAG");
@@ -1390,7 +1431,7 @@ static int ftdi_mtxorb_hack_setup(struct usb_serial *serial)
  *      calls __serial_close for each open of the port
  *      shutdown is called then (ie ftdi_shutdown)
  */
-static void ftdi_shutdown (struct usb_serial *serial)
+static void ftdi_shutdown(struct usb_serial *serial)
 {
        dbg("%s", __func__);
 }
@@ -1404,7 +1445,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
        remove_sysfs_attrs(port);
 
        /* all open ports are closed at this point
-         *    (by usbserial.c:__serial_close, which calls ftdi_close)
+        *    (by usbserial.c:__serial_close, which calls ftdi_close)
         */
 
        if (priv) {
@@ -1415,7 +1456,8 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
        return 0;
 }
 
-static int  ftdi_open (struct usb_serial_port *port, struct file *filp)
+static int ftdi_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 { /* ftdi_open */
        struct usb_device *dev = port->serial->dev;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
@@ -1433,8 +1475,8 @@ static int  ftdi_open (struct usb_serial_port *port, struct file *filp)
        priv->rx_bytes = 0;
        spin_unlock_irqrestore(&priv->rx_lock, flags);
 
-       if (port->tty)
-               port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+       if (tty)
+               tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 
        /* No error checking for this (will get errors later anyway) */
        /* See ftdi_sio.h for description of what is reset */
@@ -1448,8 +1490,8 @@ static int  ftdi_open (struct usb_serial_port *port, struct file *filp)
           This is same behaviour as serial.c/rs_open() - Kuba */
 
        /* ftdi_set_termios  will send usb control messages */
-       if (port->tty)
-               ftdi_set_termios(port, port->tty->termios);
+       if (tty)
+               ftdi_set_termios(tty, port, tty->termios);
 
        /* FIXME: Flow control might be enabled, so it should be checked -
           we have no control of defaults! */
@@ -1464,12 +1506,14 @@ static int  ftdi_open (struct usb_serial_port *port, struct file *filp)
        /* Start reading from the device */
        priv->rx_processed = 0;
        usb_fill_bulk_urb(port->read_urb, dev,
-                     usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress),
-                     port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
-                     ftdi_read_bulk_callback, port);
+                       usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress),
+                       port->read_urb->transfer_buffer,
+                               port->read_urb->transfer_buffer_length,
+                       ftdi_read_bulk_callback, port);
        result = usb_submit_urb(port->read_urb, GFP_KERNEL);
        if (result)
-               err("%s - failed submitting read urb, error %d", __func__, result);
+               err("%s - failed submitting read urb, error %d",
+                                                       __func__, result);
 
 
        return result;
@@ -1485,16 +1529,17 @@ static int  ftdi_open (struct usb_serial_port *port, struct file *filp)
  *
  */
 
-static void ftdi_close (struct usb_serial_port *port, struct file *filp)
+static void ftdi_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 { /* ftdi_close */
-       unsigned int c_cflag = port->tty->termios->c_cflag;
+       unsigned int c_cflag = tty->termios->c_cflag;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        char buf[1];
 
        dbg("%s", __func__);
 
        mutex_lock(&port->serial->disc_mutex);
-       if (c_cflag & HUPCL && !port->serial->disconnected){
+       if (c_cflag & HUPCL && !port->serial->disconnected) {
                /* Disable flow control */
                if (usb_control_msg(port->serial->dev,
                                    usb_sndctrlpipe(port->serial->dev, 0),
@@ -1527,7 +1572,7 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp)
  *
  * The new devices do not require this byte
  */
-static int ftdi_write (struct usb_serial_port *port,
+static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port,
                           const unsigned char *buf, int count)
 { /* ftdi_write */
        struct ftdi_private *priv = usb_get_serial_port_data(port);
@@ -1554,7 +1599,7 @@ static int ftdi_write (struct usb_serial_port *port,
        spin_unlock_irqrestore(&priv->tx_lock, flags);
 
        data_offset = priv->write_offset;
-        dbg("data_offset set to %d",data_offset);
+       dbg("data_offset set to %d", data_offset);
 
        /* Determine total transfer size */
        transfer_size = count;
@@ -1565,7 +1610,7 @@ static int ftdi_write (struct usb_serial_port *port,
                                 (PKTSZ - data_offset)));
        }
 
-       buffer = kmalloc (transfer_size, GFP_ATOMIC);
+       buffer = kmalloc(transfer_size, GFP_ATOMIC);
        if (!buffer) {
                err("%s ran out of kernel memory for urb ...", __func__);
                count = -ENOMEM;
@@ -1581,20 +1626,20 @@ static int ftdi_write (struct usb_serial_port *port,
 
        /* Copy data */
        if (data_offset > 0) {
-               /* Original sio requires control byte at start of each packet. */
+               /* Original sio requires control byte at start of
+                  each packet. */
                int user_pktsz = PKTSZ - data_offset;
                int todo = count;
                unsigned char *first_byte = buffer;
                const unsigned char *current_position = buf;
 
                while (todo > 0) {
-                       if (user_pktsz > todo) {
+                       if (user_pktsz > todo)
                                user_pktsz = todo;
-                       }
                        /* Write the control byte at the front of the packet*/
                        *first_byte = 1 | ((user_pktsz) << 2);
                        /* Copy data for packet */
-                       memcpy (first_byte + data_offset,
+                       memcpy(first_byte + data_offset,
                                current_position, user_pktsz);
                        first_byte += user_pktsz + data_offset;
                        current_position += user_pktsz;
@@ -1603,20 +1648,23 @@ static int ftdi_write (struct usb_serial_port *port,
        } else {
                /* No control byte required. */
                /* Copy in the data to send */
-               memcpy (buffer, buf, count);
+               memcpy(buffer, buf, count);
        }
 
-       usb_serial_debug_data(debug, &port->dev, __func__, transfer_size, buffer);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                                               transfer_size, buffer);
 
        /* fill the buffer and send it */
        usb_fill_bulk_urb(urb, port->serial->dev,
-                     usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress),
-                     buffer, transfer_size,
-                     ftdi_write_bulk_callback, port);
+                       usb_sndbulkpipe(port->serial->dev,
+                                       port->bulk_out_endpointAddress),
+                       buffer, transfer_size,
+                       ftdi_write_bulk_callback, port);
 
        status = usb_submit_urb(urb, GFP_ATOMIC);
        if (status) {
-               err("%s - failed submitting write urb, error %d", __func__, status);
+               err("%s - failed submitting write urb, error %d",
+                                                       __func__, status);
                count = status;
                goto error;
        } else {
@@ -1635,7 +1683,7 @@ static int ftdi_write (struct usb_serial_port *port,
 error:
        usb_free_urb(urb);
 error_no_urb:
-       kfree (buffer);
+       kfree(buffer);
 error_no_buffer:
        spin_lock_irqsave(&priv->tx_lock, flags);
        priv->tx_outstanding_urbs--;
@@ -1646,7 +1694,7 @@ error_no_buffer:
 
 /* This function may get called when the device is closed */
 
-static void ftdi_write_bulk_callback (struct urb *urb)
+static void ftdi_write_bulk_callback(struct urb *urb)
 {
        unsigned long flags;
        struct usb_serial_port *port = urb->context;
@@ -1656,7 +1704,7 @@ static void ftdi_write_bulk_callback (struct urb *urb)
        int status = urb->status;
 
        /* free up the transfer buffer, as usb_free_urb() does not do this */
-       kfree (urb->transfer_buffer);
+       kfree(urb->transfer_buffer);
 
        dbg("%s - port %d", __func__, port->number);
 
@@ -1686,8 +1734,9 @@ static void ftdi_write_bulk_callback (struct urb *urb)
 } /* ftdi_write_bulk_callback */
 
 
-static int ftdi_write_room( struct usb_serial_port *port )
+static int ftdi_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        int room;
        unsigned long flags;
@@ -1707,11 +1756,11 @@ static int ftdi_write_room( struct usb_serial_port *port )
        }
        spin_unlock_irqrestore(&priv->tx_lock, flags);
        return room;
-} /* ftdi_write_room */
-
+}
 
-static int ftdi_chars_in_buffer (struct usb_serial_port *port)
-{ /* ftdi_chars_in_buffer */
+static int ftdi_chars_in_buffer(struct tty_struct *tty)
+{
+       struct usb_serial_port *port = tty->driver_data;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        int buffered;
        unsigned long flags;
@@ -1726,12 +1775,10 @@ static int ftdi_chars_in_buffer (struct usb_serial_port *port)
                buffered = 0;
        }
        return buffered;
-} /* ftdi_chars_in_buffer */
-
-
+}
 
-static void ftdi_read_bulk_callback (struct urb *urb)
-{ /* ftdi_read_bulk_callback */
+static void ftdi_read_bulk_callback(struct urb *urb)
+{
        struct usb_serial_port *port = urb->context;
        struct tty_struct *tty;
        struct ftdi_private *priv;
@@ -1740,19 +1787,21 @@ static void ftdi_read_bulk_callback (struct urb *urb)
        int status = urb->status;
 
        if (urb->number_of_packets > 0) {
-               err("%s transfer_buffer_length %d actual_length %d number of packets %d",__func__,
-                   urb->transfer_buffer_length, urb->actual_length, urb->number_of_packets );
-               err("%s transfer_flags %x ", __func__,urb->transfer_flags );
+               err("%s transfer_buffer_length %d actual_length %d number of packets %d",
+                               __func__,
+                               urb->transfer_buffer_length,
+                               urb->actual_length, urb->number_of_packets);
+               err("%s transfer_flags %x ", __func__, urb->transfer_flags);
        }
 
        dbg("%s - port %d", __func__, port->number);
 
-       if (port->open_count <= 0)
+       if (port->port.count <= 0)
                return;
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (!tty) {
-               dbg("%s - bad tty pointer - exiting",__func__);
+               dbg("%s - bad tty pointer - exiting", __func__);
                return;
        }
 
@@ -1762,14 +1811,13 @@ static void ftdi_read_bulk_callback (struct urb *urb)
                return;
        }
 
-       if (urb != port->read_urb) {
+       if (urb != port->read_urb)
                err("%s - Not my urb!", __func__);
-       }
 
        if (status) {
-               /* This will happen at close every time so it is a dbg not an err */
-               dbg("(this is ok on close) nonzero read bulk status received: "
-                   "%d", status);
+               /* This will happen at close every time so it is a dbg not an
+                  err */
+               dbg("(this is ok on close) nonzero read bulk status received: %d", status);
                return;
        }
 
@@ -1785,7 +1833,7 @@ static void ftdi_read_bulk_callback (struct urb *urb)
 } /* ftdi_read_bulk_callback */
 
 
-static void ftdi_process_read (struct work_struct *work)
+static void ftdi_process_read(struct work_struct *work)
 { /* ftdi_process_read */
        struct ftdi_private *priv =
                container_of(work, struct ftdi_private, rx_work.work);
@@ -1803,12 +1851,12 @@ static void ftdi_process_read (struct work_struct *work)
 
        dbg("%s - port %d", __func__, port->number);
 
-       if (port->open_count <= 0)
+       if (port->port.count <= 0)
                return;
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (!tty) {
-               dbg("%s - bad tty pointer - exiting",__func__);
+               dbg("%s - bad tty pointer - exiting", __func__);
                return;
        }
 
@@ -1832,11 +1880,11 @@ static void ftdi_process_read (struct work_struct *work)
                                urb->actual_length - priv->rx_processed);
        } else {
                /* The first two bytes of every read packet are status */
-               if (urb->actual_length > 2) {
-                       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
-               } else {
-                       dbg("Status only: %03oo %03oo",data[0],data[1]);
-               }
+               if (urb->actual_length > 2)
+                       usb_serial_debug_data(debug, &port->dev, __func__,
+                                               urb->actual_length, data);
+               else
+                       dbg("Status only: %03oo %03oo", data[0], data[1]);
        }
 
 
@@ -1846,16 +1894,19 @@ static void ftdi_process_read (struct work_struct *work)
        /* if CD is dropped and the line is not CLOCAL then we should hangup */
 
        need_flip = 0;
-       for (packet_offset = priv->rx_processed; packet_offset < urb->actual_length; packet_offset += PKTSZ) {
+       for (packet_offset = priv->rx_processed;
+               packet_offset < urb->actual_length; packet_offset += PKTSZ) {
                int length;
 
-               /* Compare new line status to the old one, signal if different */
-               /* N.B. packet may be processed more than once, but differences
-                * are only processed once.  */
+               /* Compare new line status to the old one, signal if different/
+                  N.B. packet may be processed more than once, but differences
+                  are only processed once.  */
                if (priv != NULL) {
-                       char new_status = data[packet_offset+0] & FTDI_STATUS_B0_MASK;
+                       char new_status = data[packet_offset + 0] &
+                                                       FTDI_STATUS_B0_MASK;
                        if (new_status != priv->prev_status) {
-                               priv->diff_status |= new_status ^ priv->prev_status;
+                               priv->diff_status |=
+                                       new_status ^ priv->prev_status;
                                wake_up_interruptible(&priv->delta_msr_wait);
                                priv->prev_status = new_status;
                        }
@@ -1872,30 +1923,31 @@ static void ftdi_process_read (struct work_struct *work)
                        break;
                }
                if (tty_buffer_request_room(tty, length) < length) {
-                       /* break out & wait for throttling/unthrottling to happen */
+                       /* break out & wait for throttling/unthrottling to
+                          happen */
                        dbg("%s - receive room low", __func__);
                        break;
                }
 
                /* Handle errors and break */
                error_flag = TTY_NORMAL;
-               /* Although the device uses a bitmask and hence can have multiple */
-               /* errors on a packet - the order here sets the priority the */
-               /* error is returned to the tty layer  */
+               /* Although the device uses a bitmask and hence can have
+                  multiple errors on a packet - the order here sets the
+                  priority the error is returned to the tty layer  */
 
-               if ( data[packet_offset+1] & FTDI_RS_OE ) {
+               if (data[packet_offset+1] & FTDI_RS_OE) {
                        error_flag = TTY_OVERRUN;
                        dbg("OVERRRUN error");
                }
-               if ( data[packet_offset+1] & FTDI_RS_BI ) {
+               if (data[packet_offset+1] & FTDI_RS_BI) {
                        error_flag = TTY_BREAK;
                        dbg("BREAK received");
                }
-               if ( data[packet_offset+1] & FTDI_RS_PE ) {
+               if (data[packet_offset+1] & FTDI_RS_PE) {
                        error_flag = TTY_PARITY;
                        dbg("PARITY error");
                }
-               if ( data[packet_offset+1] & FTDI_RS_FE ) {
+               if (data[packet_offset+1] & FTDI_RS_FE) {
                        error_flag = TTY_FRAME;
                        dbg("FRAMING error");
                }
@@ -1904,7 +1956,8 @@ static void ftdi_process_read (struct work_struct *work)
                                /* Note that the error flag is duplicated for
                                   every character received since we don't know
                                   which character it applied to */
-                               tty_insert_flip_char(tty, data[packet_offset+i], error_flag);
+                               tty_insert_flip_char(tty,
+                                       data[packet_offset + i], error_flag);
                        }
                        need_flip = 1;
                }
@@ -1912,19 +1965,19 @@ static void ftdi_process_read (struct work_struct *work)
 #ifdef NOT_CORRECT_BUT_KEEPING_IT_FOR_NOW
                /* if a parity error is detected you get status packets forever
                   until a character is sent without a parity error.
-                  This doesn't work well since the application receives a never
-                  ending stream of bad data - even though new data hasn't been sent.
-                  Therefore I (bill) have taken this out.
+                  This doesn't work well since the application receives a
+                  never ending stream of bad data - even though new data
+                  hasn't been sent. Therefore I (bill) have taken this out.
                   However - this might make sense for framing errors and so on
                   so I am leaving the code in for now.
                */
                else {
-                       if (error_flag != TTY_NORMAL){
+                       if (error_flag != TTY_NORMAL) {
                                dbg("error_flag is not normal");
-                               /* In this case it is just status - if that is an error send a bad character */
-                               if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
+                               /* In this case it is just status - if that is
+                                  an error send a bad character */
+                               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
                                        tty_flip_buffer_push(tty);
-                               }
                                tty_insert_flip_char(tty, 0xff, error_flag);
                                need_flip = 1;
                        }
@@ -1933,9 +1986,8 @@ static void ftdi_process_read (struct work_struct *work)
        } /* "for(packet_offset=0..." */
 
        /* Low latency */
-       if (need_flip) {
+       if (need_flip)
                tty_flip_buffer_push(tty);
-       }
 
        if (packet_offset < urb->actual_length) {
                /* not completely processed - record progress */
@@ -1954,12 +2006,11 @@ static void ftdi_process_read (struct work_struct *work)
                }
                spin_unlock_irqrestore(&priv->rx_lock, flags);
                /* if the port is closed stop trying to read */
-               if (port->open_count > 0){
+               if (port->port.count > 0)
                        /* delay processing of remainder */
                        schedule_delayed_work(&priv->rx_work, 1);
-               } else {
+               else
                        dbg("%s - port is closed", __func__);
-               }
                return;
        }
 
@@ -1967,24 +2018,26 @@ static void ftdi_process_read (struct work_struct *work)
        priv->rx_processed = 0;
 
        /* if the port is closed stop trying to read */
-       if (port->open_count > 0){
+       if (port->port.count > 0) {
                /* Continue trying to always read  */
                usb_fill_bulk_urb(port->read_urb, port->serial->dev,
-                             usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress),
-                             port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
-                             ftdi_read_bulk_callback, port);
+                       usb_rcvbulkpipe(port->serial->dev,
+                                       port->bulk_in_endpointAddress),
+                       port->read_urb->transfer_buffer,
+                       port->read_urb->transfer_buffer_length,
+                       ftdi_read_bulk_callback, port);
 
                result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
                if (result)
-                       err("%s - failed resubmitting read urb, error %d", __func__, result);
+                       err("%s - failed resubmitting read urb, error %d",
+                                                       __func__, result);
        }
-
-       return;
 } /* ftdi_process_read */
 
 
-static void ftdi_break_ctl( struct usb_serial_port *port, int break_state )
+static void ftdi_break_ctl(struct tty_struct *tty, int break_state)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        __u16 urb_value = 0;
        char buf[1];
@@ -1993,22 +2046,23 @@ static void ftdi_break_ctl( struct usb_serial_port *port, int break_state )
        /* see drivers/char/tty_io.c to see it used */
        /* last_set_data_urb_value NEVER has the break bit set in it */
 
-       if (break_state) {
+       if (break_state)
                urb_value = priv->last_set_data_urb_value | FTDI_SIO_SET_BREAK;
-       } else {
+       else
                urb_value = priv->last_set_data_urb_value;
-       }
 
-
-       if (usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
-                           FTDI_SIO_SET_DATA_REQUEST,
-                           FTDI_SIO_SET_DATA_REQUEST_TYPE,
-                           urb_value , priv->interface,
-                           buf, 0, WDR_TIMEOUT) < 0) {
-               err("%s FAILED to enable/disable break state (state was %d)", __func__,break_state);
+       if (usb_control_msg(port->serial->dev,
+                       usb_sndctrlpipe(port->serial->dev, 0),
+                       FTDI_SIO_SET_DATA_REQUEST,
+                       FTDI_SIO_SET_DATA_REQUEST_TYPE,
+                       urb_value , priv->interface,
+                       buf, 0, WDR_TIMEOUT) < 0) {
+               err("%s FAILED to enable/disable break state (state was %d)",
+                                                       __func__, break_state);
        }
 
-       dbg("%s break state is %d - urb is %d", __func__,break_state, urb_value);
+       dbg("%s break state is %d - urb is %d", __func__,
+                                               break_state, urb_value);
 
 }
 
@@ -2018,26 +2072,28 @@ static void ftdi_break_ctl( struct usb_serial_port *port, int break_state )
  * WARNING: set_termios calls this with old_termios in kernel space
  */
 
-static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
+static void ftdi_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 { /* ftdi_termios */
        struct usb_device *dev = port->serial->dev;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
-       struct ktermios *termios = port->tty->termios;
+       struct ktermios *termios = tty->termios;
        unsigned int cflag = termios->c_cflag;
        __u16 urb_value; /* will hold the new flags */
        char buf[1]; /* Perhaps I should dynamically alloc this? */
 
-       // Added for xon/xoff support
+       /* Added for xon/xoff support */
        unsigned int iflag = termios->c_iflag;
        unsigned char vstop;
        unsigned char vstart;
 
        dbg("%s", __func__);
 
-       /* Force baud rate if this device requires it, unless it is set to B0. */
+       /* Force baud rate if this device requires it, unless it is set to
+          B0. */
        if (priv->force_baud && ((termios->c_cflag & CBAUD) != B0)) {
                dbg("%s: forcing baud rate for this device", __func__);
-               tty_encode_baud_rate(port->tty, priv->force_baud,
+               tty_encode_baud_rate(tty, priv->force_baud,
                                        priv->force_baud);
        }
 
@@ -2053,8 +2109,8 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old
           not  - so just do the change regardless  - should be able to
           compare old_termios and tty->termios */
        /* NOTE These routines can get interrupted by
-          ftdi_sio_read_bulk_callback  - need to examine what this
-           means - don't see any problems yet */
+          ftdi_sio_read_bulk_callback  - need to examine what this means -
+          don't see any problems yet */
 
        /* Set number of data bits, parity, stop bits */
 
@@ -2078,8 +2134,8 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old
                }
        }
 
-       /* This is needed by the break command since it uses the same command - but is
-         or'ed with this value  */
+       /* This is needed by the break command since it uses the same command
+          - but is or'ed with this value  */
        priv->last_set_data_urb_value = urb_value;
 
        if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
@@ -2091,7 +2147,7 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old
        }
 
        /* Now do the baudrate */
-       if ((cflag & CBAUD) == B0 ) {
+       if ((cflag & CBAUD) == B0) {
                /* Disable flow control */
                if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
                                    FTDI_SIO_SET_FLOW_CTRL_REQUEST,
@@ -2104,13 +2160,11 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old
                clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
        } else {
                /* set the baudrate determined before */
-               if (change_speed(port)) {
+               if (change_speed(tty, port))
                        err("%s urb failed to set baudrate", __func__);
-               }
                /* Ensure RTS and DTR are raised when baudrate changed from 0 */
-               if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) {
+               if (!old_termios || (old_termios->c_cflag & CBAUD) == B0)
                        set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
-               }
        }
 
        /* Set flow control */
@@ -2130,18 +2184,22 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old
                /*
                 * Xon/Xoff code
                 *
-                * Check the IXOFF status in the iflag component of the termios structure
-                * if IXOFF is not set, the pre-xon/xoff code is executed.
-               */
+                * Check the IXOFF status in the iflag component of the
+                * termios structure. If IXOFF is not set, the pre-xon/xoff
+                * code is executed.
+                */
                if (iflag & IXOFF) {
-                       dbg("%s  request to enable xonxoff iflag=%04x",__func__,iflag);
-                       // Try to enable the XON/XOFF on the ftdi_sio
-                       // Set the vstart and vstop -- could have been done up above where
-                       // a lot of other dereferencing is done but that would be very
-                       // inefficient as vstart and vstop are not always needed
+                       dbg("%s  request to enable xonxoff iflag=%04x",
+                                                       __func__, iflag);
+                       /* Try to enable the XON/XOFF on the ftdi_sio
+                        * Set the vstart and vstop -- could have been done up
+                        * above where a lot of other dereferencing is done but
+                        * that would be very inefficient as vstart and vstop
+                        * are not always needed.
+                        */
                        vstart = termios->c_cc[VSTART];
                        vstop = termios->c_cc[VSTOP];
-                       urb_value=(vstop << 8) | (vstart);
+                       urb_value = (vstop << 8) | (vstart);
 
                        if (usb_control_msg(dev,
                                            usb_sndctrlpipe(dev, 0),
@@ -2153,8 +2211,9 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old
                                err("urb failed to set to xon/xoff flow control");
                        }
                } else {
-                       /* else clause to only run if cfag ! CRTSCTS and iflag ! XOFF */
-                       /* CHECKME Assuming XON/XOFF handled by tty stack - not by device */
+                       /* else clause to only run if cflag ! CRTSCTS and iflag
+                        * ! XOFF. CHECKME Assuming XON/XOFF handled by tty
+                        * stack - not by device */
                        dbg("%s Turning off hardware flow control", __func__);
                        if (usb_control_msg(dev,
                                            usb_sndctrlpipe(dev, 0),
@@ -2168,11 +2227,11 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old
 
        }
        return;
-} /* ftdi_termios */
-
+}
 
-static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file)
+static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        unsigned char buf[2];
        int ret;
@@ -2181,32 +2240,35 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file)
        switch (priv->chip_type) {
        case SIO:
                /* Request the status from the device */
-               if ((ret = usb_control_msg(port->serial->dev,
-                                          usb_rcvctrlpipe(port->serial->dev, 0),
-                                          FTDI_SIO_GET_MODEM_STATUS_REQUEST,
-                                          FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
-                                          0, 0,
-                                          buf, 1, WDR_TIMEOUT)) < 0 ) {
+               ret = usb_control_msg(port->serial->dev,
+                          usb_rcvctrlpipe(port->serial->dev, 0),
+                          FTDI_SIO_GET_MODEM_STATUS_REQUEST,
+                          FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
+                          0, 0,
+                          buf, 1, WDR_TIMEOUT);
+               if (ret < 0) {
                        err("%s Could not get modem status of device - err: %d", __func__,
                            ret);
-                       return(ret);
+                       return ret;
                }
                break;
        case FT8U232AM:
        case FT232BM:
        case FT2232C:
        case FT232RL:
-               /* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same
-                  format as the data returned from the in point */
-               if ((ret = usb_control_msg(port->serial->dev,
-                                          usb_rcvctrlpipe(port->serial->dev, 0),
-                                          FTDI_SIO_GET_MODEM_STATUS_REQUEST,
-                                          FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
-                                          0, priv->interface,
-                                          buf, 2, WDR_TIMEOUT)) < 0 ) {
+               /* the 8U232AM returns a two byte value (the sio is a 1 byte
+                  value) - in the same format as the data returned from the in
+                  point */
+               ret = usb_control_msg(port->serial->dev,
+                                  usb_rcvctrlpipe(port->serial->dev, 0),
+                                  FTDI_SIO_GET_MODEM_STATUS_REQUEST,
+                                  FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
+                                  0, priv->interface,
+                                  buf, 2, WDR_TIMEOUT);
+               if (ret < 0) {
                        err("%s Could not get modem status of device - err: %d", __func__,
                            ret);
-                       return(ret);
+                       return ret;
                }
                break;
        default:
@@ -2221,15 +2283,19 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file)
                priv->last_dtr_rts;
 }
 
-static int ftdi_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear)
+static int ftdi_tiocmset(struct tty_struct *tty, struct file *file,
+                       unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        dbg("%s TIOCMSET", __func__);
        return update_mctrl(port, set, clear);
 }
 
 
-static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
+static int ftdi_ioctl(struct tty_struct *tty, struct file *file,
+                                       unsigned int cmd, unsigned long arg)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
 
        dbg("%s cmd 0x%04x", __func__, cmd);
@@ -2238,10 +2304,12 @@ static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigne
        switch (cmd) {
 
        case TIOCGSERIAL: /* gets serial port data */
-               return get_serial_info(port, (struct serial_struct __user *) arg);
+               return get_serial_info(port,
+                                       (struct serial_struct __user *) arg);
 
        case TIOCSSERIAL: /* sets serial port data */
-               return set_serial_info(port, (struct serial_struct __user *) arg);
+               return set_serial_info(tty, port,
+                                       (struct serial_struct __user *) arg);
 
        /*
         * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
@@ -2260,45 +2328,41 @@ static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigne
                        else {
                                char diff = priv->diff_status;
 
-                               if (diff == 0) {
+                               if (diff == 0)
                                        return -EIO; /* no change => error */
-                               }
 
                                /* Consume all events */
                                priv->diff_status = 0;
 
-                               /* Return 0 if caller wanted to know about these bits */
-                               if ( ((arg & TIOCM_RNG) && (diff & FTDI_RS0_RI)) ||
-                                    ((arg & TIOCM_DSR) && (diff & FTDI_RS0_DSR)) ||
-                                    ((arg & TIOCM_CD)  && (diff & FTDI_RS0_RLSD)) ||
-                                    ((arg & TIOCM_CTS) && (diff & FTDI_RS0_CTS)) ) {
+                               /* Return 0 if caller wanted to know about
+                                  these bits */
+                               if (((arg & TIOCM_RNG) && (diff & FTDI_RS0_RI)) ||
+                                   ((arg & TIOCM_DSR) && (diff & FTDI_RS0_DSR)) ||
+                                   ((arg & TIOCM_CD)  && (diff & FTDI_RS0_RLSD)) ||
+                                   ((arg & TIOCM_CTS) && (diff & FTDI_RS0_CTS))) {
                                        return 0;
                                }
                                /*
-                                * Otherwise caller can't care less about what happened,
-                                * and so we continue to wait for more events.
+                                * Otherwise caller can't care less about what
+                                * happened,and so we continue to wait for more
+                                * events.
                                 */
                        }
                }
-               return(0);
-               break;
+               return 0;
        default:
                break;
-
        }
-
-
-       /* This is not necessarily an error - turns out the higher layers will do
-        *  some ioctls itself (see comment above)
+       /* This is not necessarily an error - turns out the higher layers
+        * will do some ioctls themselves (see comment above)
         */
        dbg("%s arg not supported - it was 0x%04x - check /usr/include/asm/ioctls.h", __func__, cmd);
+       return -ENOIOCTLCMD;
+}
 
-       return(-ENOIOCTLCMD);
-} /* ftdi_ioctl */
-
-
-static void ftdi_throttle (struct usb_serial_port *port)
+static void ftdi_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
 
@@ -2310,8 +2374,9 @@ static void ftdi_throttle (struct usb_serial_port *port)
 }
 
 
-static void ftdi_unthrottle (struct usb_serial_port *port)
+static void ftdi_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        int actually_throttled;
        unsigned long flags;
@@ -2327,7 +2392,7 @@ static void ftdi_unthrottle (struct usb_serial_port *port)
                schedule_delayed_work(&priv->rx_work, 0);
 }
 
-static int __init ftdi_init (void)
+static int __init ftdi_init(void)
 {
        int retval;
 
@@ -2357,13 +2422,13 @@ failed_sio_register:
 }
 
 
-static void __exit ftdi_exit (void)
+static void __exit ftdi_exit(void)
 {
 
        dbg("%s", __func__);
 
-       usb_deregister (&ftdi_driver);
-       usb_serial_deregister (&ftdi_sio_device);
+       usb_deregister(&ftdi_driver);
+       usb_serial_deregister(&ftdi_sio_device);
 
 }
 
@@ -2371,8 +2436,8 @@ static void __exit ftdi_exit (void)
 module_init(ftdi_init);
 module_exit(ftdi_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
index 8302eca893ea334f61c5d0d64c2b3a0ccfad91fa..a577ea44dcf9dceb13d2d5644feb73015451a428 100644 (file)
@@ -1,20 +1,20 @@
 /*
- * Definitions for the FTDI USB Single Port Serial Converter - 
- * known as FTDI_SIO (Serial Input/Output application of the chipset) 
+ * Definitions for the FTDI USB Single Port Serial Converter -
+ * known as FTDI_SIO (Serial Input/Output application of the chipset)
  *
  * The example I have is known as the USC-1000 which is available from
  * http://www.dse.co.nz - cat no XH4214 It looks similar to this:
  * http://www.dansdata.com/usbser.htm but I can't be sure There are other
  * USC-1000s which don't look like my device though so beware!
  *
- * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side, 
+ * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side,
  * USB on the other.
  *
  * Thanx to FTDI (http://www.ftdi.co.uk) for so kindly providing details
  * of the protocol required to talk to the device and ongoing assistence
  * during development.
  *
- * Bill Ryder - bryder@sgi.com formerly of Silicon Graphics, Inc.- wrote the 
+ * Bill Ryder - bryder@sgi.com formerly of Silicon Graphics, Inc.- wrote the
  * FTDI_SIO implementation.
  *
  * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais
 /*
  * DSS-20 Sync Station for Sony Ericsson P800
  */
-#define FTDI_DSS20_PID          0xFC82  
+#define FTDI_DSS20_PID          0xFC82
 
 /*
  * Home Electronics (www.home-electro.com) USB gadgets
 /*
  * BmRequestType:  0100 0000B
  * bRequest:       FTDI_SIO_RESET
- * wValue:         Control Value 
+ * wValue:         Control Value
  *                   0 = Reset SIO
  *                   1 = Purge RX buffer
  *                   2 = Purge TX buffer
  *   101 - add .625 to divisor
  *   110 - add .750 to divisor
  *   111 - add .875 to divisor
- * Bits 15 to 0 of the 17-bit divisor are placed in the urb value.  Bit 16 is 
+ * Bits 15 to 0 of the 17-bit divisor are placed in the urb value.  Bit 16 is
  * placed in bit 0 of the urb index.
  *
  * Note that there are a couple of special cases to support the highest baud
@@ -971,8 +971,8 @@ typedef enum {
 } ftdi_chip_type_t;
 
 typedef enum {
- ftdi_sio_b300 = 0, 
- ftdi_sio_b600 = 1, 
+ ftdi_sio_b300 = 0,
+ ftdi_sio_b600 = 1,
  ftdi_sio_b1200 = 2,
  ftdi_sio_b2400 = 3,
  ftdi_sio_b4800 = 4,
@@ -981,7 +981,7 @@ typedef enum {
  ftdi_sio_b38400 = 7,
  ftdi_sio_b57600 = 8,
  ftdi_sio_b115200 = 9
-} FTDI_SIO_baudrate_t ;
+} FTDI_SIO_baudrate_t;
 
 /*
  * The ftdi_8U232AM_xxMHz_byyy constants have been removed. The encoded divisor values
@@ -990,19 +990,19 @@ typedef enum {
 
 #define FTDI_SIO_SET_DATA_REQUEST FTDI_SIO_SET_DATA
 #define FTDI_SIO_SET_DATA_REQUEST_TYPE 0x40
-#define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8 )
-#define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8 )
-#define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8 )
-#define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8 )
-#define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8 )
-#define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11 )
-#define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11 )
-#define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11 )
+#define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8)
+#define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8)
+#define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8)
+#define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8)
+#define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8)
+#define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11)
+#define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11)
+#define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11)
 #define FTDI_SIO_SET_BREAK (0x1 << 14)
 /* FTDI_SIO_SET_DATA */
 
 /*
- * BmRequestType:  0100 0000B 
+ * BmRequestType:  0100 0000B
  * bRequest:       FTDI_SIO_SET_DATA
  * wValue:         Data characteristics (see below)
  * wIndex:         Port
@@ -1035,7 +1035,7 @@ typedef enum {
 #define FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE 0x40
 #define FTDI_SIO_SET_MODEM_CTRL_REQUEST FTDI_SIO_MODEM_CTRL
 
-/* 
+/*
  * BmRequestType:   0100 0000B
  * bRequest:        FTDI_SIO_MODEM_CTRL
  * wValue:          ControlValue (see below)
@@ -1049,11 +1049,11 @@ typedef enum {
  */
 
 #define FTDI_SIO_SET_DTR_MASK 0x1
-#define FTDI_SIO_SET_DTR_HIGH ( 1 | ( FTDI_SIO_SET_DTR_MASK  << 8))
-#define FTDI_SIO_SET_DTR_LOW  ( 0 | ( FTDI_SIO_SET_DTR_MASK  << 8))
+#define FTDI_SIO_SET_DTR_HIGH (1 | (FTDI_SIO_SET_DTR_MASK  << 8))
+#define FTDI_SIO_SET_DTR_LOW  (0 | (FTDI_SIO_SET_DTR_MASK  << 8))
 #define FTDI_SIO_SET_RTS_MASK 0x2
-#define FTDI_SIO_SET_RTS_HIGH ( 2 | ( FTDI_SIO_SET_RTS_MASK << 8 ))
-#define FTDI_SIO_SET_RTS_LOW ( 0 | ( FTDI_SIO_SET_RTS_MASK << 8 ))
+#define FTDI_SIO_SET_RTS_HIGH (2 | (FTDI_SIO_SET_RTS_MASK << 8))
+#define FTDI_SIO_SET_RTS_LOW (0 | (FTDI_SIO_SET_RTS_MASK << 8))
 
 /*
  * ControlValue
@@ -1076,7 +1076,7 @@ typedef enum {
 /* FTDI_SIO_SET_FLOW_CTRL */
 #define FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE 0x40
 #define FTDI_SIO_SET_FLOW_CTRL_REQUEST FTDI_SIO_SET_FLOW_CTRL
-#define FTDI_SIO_DISABLE_FLOW_CTRL 0x0 
+#define FTDI_SIO_DISABLE_FLOW_CTRL 0x0
 #define FTDI_SIO_RTS_CTS_HS (0x1 << 8)
 #define FTDI_SIO_DTR_DSR_HS (0x2 << 8)
 #define FTDI_SIO_XON_XOFF_HS (0x4 << 8)
@@ -1085,7 +1085,7 @@ typedef enum {
  *   bRequest:       FTDI_SIO_SET_FLOW_CTRL
  *   wValue:         Xoff/Xon
  *   wIndex:         Protocol/Port - hIndex is protocl / lIndex is port
- *   wLength:        0 
+ *   wLength:        0
  *   Data:           None
  *
  * hIndex protocol is:
@@ -1101,10 +1101,10 @@ typedef enum {
  *
  * A value of zero in the hIndex field disables handshaking
  *
- * If Xon/Xoff handshaking is specified, the hValue field should contain the XOFF character 
+ * If Xon/Xoff handshaking is specified, the hValue field should contain the XOFF character
  * and the lValue field contains the XON character.
- */  
+ */
+
 /*
  * FTDI_SIO_GET_LATENCY_TIMER
  *
@@ -1118,7 +1118,7 @@ typedef enum {
 #define  FTDI_SIO_GET_LATENCY_TIMER_REQUEST FTDI_SIO_GET_LATENCY_TIMER
 #define  FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE 0xC0
 
-/* 
+/*
  *  BmRequestType:   1100 0000b
  *  bRequest:        FTDI_SIO_GET_LATENCY_TIMER
  *  wValue:          0
@@ -1127,7 +1127,7 @@ typedef enum {
  *  Data:            latency (on return)
  */
 
-/* 
+/*
  * FTDI_SIO_SET_LATENCY_TIMER
  *
  * Set the timeout interval. The FTDI collects data from the slave
@@ -1140,7 +1140,7 @@ typedef enum {
 #define  FTDI_SIO_SET_LATENCY_TIMER_REQUEST FTDI_SIO_SET_LATENCY_TIMER
 #define  FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE 0x40
 
-/* 
+/*
  *  BmRequestType:   0100 0000b
  *  bRequest:        FTDI_SIO_SET_LATENCY_TIMER
  *  wValue:          Latency (milliseconds)
@@ -1155,7 +1155,7 @@ typedef enum {
  */
 
 /*
- * FTDI_SIO_SET_EVENT_CHAR 
+ * FTDI_SIO_SET_EVENT_CHAR
  *
  * Set the special event character for the specified communications port.
  * If the device sees this character it will immediately return the
@@ -1168,7 +1168,7 @@ typedef enum {
 #define  FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE 0x40
 
 
-/* 
+/*
  *  BmRequestType:   0100 0000b
  *  bRequest:        FTDI_SIO_SET_EVENT_CHAR
  *  wValue:          EventChar
@@ -1184,12 +1184,12 @@ typedef enum {
  *   B9..15  Reserved
  *
  */
-          
+
 /* FTDI_SIO_SET_ERROR_CHAR */
 
 /* Set the parity error replacement character for the specified communications port */
 
-/* 
+/*
  *  BmRequestType:  0100 0000b
  *  bRequest:       FTDI_SIO_SET_EVENT_CHAR
  *  wValue:         Error Char
@@ -1215,15 +1215,15 @@ typedef enum {
 #define FTDI_SIO_DSR_MASK 0x20
 #define FTDI_SIO_RI_MASK  0x40
 #define FTDI_SIO_RLSD_MASK 0x80
-/* 
+/*
  *   BmRequestType:   1100 0000b
  *   bRequest:        FTDI_SIO_GET_MODEM_STATUS
  *   wValue:          zero
  *   wIndex:          Port
  *   wLength:         1
  *   Data:            Status
- * 
- * One byte of data is returned 
+ *
+ * One byte of data is returned
  * B0..3 0
  * B4    CTS
  *         0 = inactive
@@ -1236,15 +1236,15 @@ typedef enum {
  *         1 = active
  * B7    Receive Line Signal Detect (RLSD)
  *         0 = inactive
- *         1 = active 
+ *         1 = active
  */
 
 
 
-/* Descriptors returned by the device 
- * 
+/* Descriptors returned by the device
+ *
  *  Device Descriptor
- * 
+ *
  * Offset      Field           Size    Value   Description
  * 0   bLength         1       0x12    Size of descriptor in bytes
  * 1   bDescriptorType 1       0x01    DEVICE Descriptor Type
@@ -1260,9 +1260,9 @@ typedef enum {
  * 15  iProduct        1       0x02    Index of prod string desc
  * 16  iSerialNumber   1       0x02    Index of serial nmr string desc
  * 17  bNumConfigurations 1    0x01    Number of possible configurations
- * 
+ *
  * Configuration Descriptor
- * 
+ *
  * Offset      Field                   Size    Value
  * 0   bLength                 1       0x09    Size of descriptor in bytes
  * 1   bDescriptorType         1       0x02    CONFIGURATION Descriptor Type
@@ -1272,9 +1272,9 @@ typedef enum {
  * 6   iConfiguration          1       0x02    Index of config string descriptor
  * 7   bmAttributes            1       0x20    Config characteristics Remote Wakeup
  * 8   MaxPower                1       0x1E    Max power consumption
- * 
+ *
  * Interface Descriptor
- * 
+ *
  * Offset      Field                   Size    Value
  * 0   bLength                 1       0x09    Size of descriptor in bytes
  * 1   bDescriptorType         1       0x04    INTERFACE Descriptor Type
@@ -1285,9 +1285,9 @@ typedef enum {
  * 6   bInterfaceSubClass      1       0xFF    Subclass Code
  * 7   bInterfaceProtocol      1       0xFF    Protocol Code
  * 8   iInterface              1       0x02    Index of interface string description
- * 
+ *
  * IN Endpoint Descriptor
- * 
+ *
  * Offset      Field                   Size    Value
  * 0   bLength                 1       0x07    Size of descriptor in bytes
  * 1   bDescriptorType         1       0x05    ENDPOINT descriptor type
@@ -1295,9 +1295,9 @@ typedef enum {
  * 3   bmAttributes            1       0x02    Endpoint attributes - Bulk
  * 4   bNumEndpoints           2       0x0040  maximum packet size
  * 5   bInterval               1       0x00    Interval for polling endpoint
- * 
+ *
  * OUT Endpoint Descriptor
- * 
+ *
  * Offset      Field                   Size    Value
  * 0   bLength                 1       0x07    Size of descriptor in bytes
  * 1   bDescriptorType         1       0x05    ENDPOINT descriptor type
@@ -1305,17 +1305,17 @@ typedef enum {
  * 3   bmAttributes            1       0x02    Endpoint attributes - Bulk
  * 4   bNumEndpoints           2       0x0040  maximum packet size
  * 5   bInterval               1       0x00    Interval for polling endpoint
- *     
+ *
  * DATA FORMAT
- * 
+ *
  * IN Endpoint
- * 
+ *
  * The device reserves the first two bytes of data on this endpoint to contain the current
  * values of the modem and line status registers. In the absence of data, the device 
  * generates a message consisting of these two status bytes every 40 ms
- * 
+ *
  * Byte 0: Modem Status
- * 
+ *
  * Offset      Description
  * B0  Reserved - must be 1
  * B1  Reserved - must be 0
@@ -1325,9 +1325,9 @@ typedef enum {
  * B5  Data Set Ready (DSR)
  * B6  Ring Indicator (RI)
  * B7  Receive Line Signal Detect (RLSD)
- * 
+ *
  * Byte 1: Line Status
- * 
+ *
  * Offset      Description
  * B0  Data Ready (DR)
  * B1  Overrun Error (OE)
@@ -1337,7 +1337,7 @@ typedef enum {
  * B5  Transmitter Holding Register (THRE)
  * B6  Transmitter Empty (TEMT)
  * B7  Error in RCVR FIFO
- * 
+ *
  */
 #define FTDI_RS0_CTS   (1 << 4)
 #define FTDI_RS0_DSR   (1 << 5)
@@ -1355,17 +1355,17 @@ typedef enum {
 
 /*
  * OUT Endpoint
- * 
+ *
  * This device reserves the first bytes of data on this endpoint contain the length
  * and port identifier of the message. For the FTDI USB Serial converter the port 
  * identifier is always 1.
- * 
+ *
  * Byte 0: Line Status
- * 
+ *
  * Offset      Description
  * B0  Reserved - must be 1
  * B1  Reserved - must be 0
  * B2..7       Length of message - (not including Byte 0)
- * 
+ *
  */
 
index e8ba2cb5995db1eefc0073607facf9ade1d15599..d30f736d2cc51a604b095e333f09d7b1201bd859 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 static int debug;
 
index 8ce5a56a48e30ec1da010705a093262993c172bb..2e663f1afd5e4ea85fa170f2d387f06d817bac5a 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <asm/atomic.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
@@ -44,7 +44,7 @@
 static int initial_mode = 1;
 
 /* debug flag */
-static int debug = 0;
+static int debug;
 
 #define GARMIN_VENDOR_ID             0x091E
 
@@ -56,7 +56,7 @@ static int debug = 0;
 #define VERSION_MINOR  31
 
 #define _STR(s) #s
-#define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b)
+#define _DRIVER_VERSION(a, b) "v" _STR(a) "." _STR(b)
 #define DRIVER_VERSION _DRIVER_VERSION(VERSION_MAJOR, VERSION_MINOR)
 #define DRIVER_AUTHOR "hermann kneissel"
 #define DRIVER_DESC "garmin gps driver"
@@ -65,37 +65,37 @@ static int debug = 0;
 #define EINVPKT        1000    /* invalid packet structure */
 
 
-// size of the header of a packet using the usb protocol
+/* size of the header of a packet using the usb protocol */
 #define GARMIN_PKTHDR_LENGTH   12
 
-// max. possible size of a packet using the serial protocol 
-#define MAX_SERIAL_PKT_SIZ (3+255+3)
+/* max. possible size of a packet using the serial protocol */
+#define MAX_SERIAL_PKT_SIZ (3 + 255 + 3)
 
-// max. possible size of a packet with worst case stuffing
-#define MAX_SERIAL_PKT_SIZ_STUFFED MAX_SERIAL_PKT_SIZ+256
+/*  max. possible size of a packet with worst case stuffing */
+#define MAX_SERIAL_PKT_SIZ_STUFFED (MAX_SERIAL_PKT_SIZ + 256)
 
-// size of a buffer able to hold a complete (no stuffing) packet
-// (the document protocol does not contain packets with a larger
-//  size, but in theory a packet may be 64k+12 bytes - if in
-//  later protocol versions larger packet sizes occur, this value
-//  should be increased accordingly, so the input buffer is always 
-//  large enough the store a complete packet inclusive header)
-#define GPS_IN_BUFSIZ  (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ) 
+/* size of a buffer able to hold a complete (no stuffing) packet
+ * (the document protocol does not contain packets with a larger
+ *  size, but in theory a packet may be 64k+12 bytes - if in
+ *  later protocol versions larger packet sizes occur, this value
+ *  should be increased accordingly, so the input buffer is always
+ *  large enough the store a complete packet inclusive header) */
+#define GPS_IN_BUFSIZ  (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ)
 
-// size of a buffer able to hold a complete (incl. stuffing) packet
-#define GPS_OUT_BUFSIZ (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ_STUFFED) 
+/* size of a buffer able to hold a complete (incl. stuffing) packet */
+#define GPS_OUT_BUFSIZ (GARMIN_PKTHDR_LENGTH+MAX_SERIAL_PKT_SIZ_STUFFED)
 
-// where to place the packet id of a serial packet, so we can
-// prepend the usb-packet header without the need to move the
-// packets data
+/* where to place the packet id of a serial packet, so we can
+ * prepend the usb-packet header without the need to move the
+ * packets data */
 #define GSP_INITIAL_OFFSET (GARMIN_PKTHDR_LENGTH-2)
 
-// max. size of incoming private packets (header+1 param)
+/* max. size of incoming private packets (header+1 param) */
 #define PRIVPKTSIZ (GARMIN_PKTHDR_LENGTH+4)
 
 #define GARMIN_LAYERID_TRANSPORT  0
 #define GARMIN_LAYERID_APPL      20
-// our own layer-id to use for some control mechanisms
+/* our own layer-id to use for some control mechanisms */
 #define GARMIN_LAYERID_PRIVATE 0x01106E4B
 
 #define GARMIN_PKTID_PVT_DATA  51
@@ -103,7 +103,7 @@ static int debug = 0;
 
 #define CMND_ABORT_TRANSFER 0
 
-// packet ids used in private layer
+/* packet ids used in private layer */
 #define PRIV_PKTID_SET_DEBUG   1
 #define PRIV_PKTID_SET_MODE    2
 #define PRIV_PKTID_INFO_REQ    3
@@ -121,7 +121,8 @@ static int debug = 0;
 struct garmin_packet {
        struct list_head  list;
        int               seq;
-       int               size; // the real size of the data array, always > 0
+       /* the real size of the data array, always > 0 */
+       int               size;
        __u8              data[1];
 };
 
@@ -164,7 +165,7 @@ struct garmin_data {
 #define MODE_NATIVE          0
 #define MODE_GARMIN_SERIAL   1
 
-// Flags used in garmin_data.flags:
+/* Flags used in garmin_data.flags: */
 #define FLAGS_SESSION_REPLY_MASK  0x00C0
 #define FLAGS_SESSION_REPLY1_SEEN 0x0080
 #define FLAGS_SESSION_REPLY2_SEEN 0x0040
@@ -185,7 +186,7 @@ struct garmin_data {
 
 
 /* function prototypes */
-static void gsp_next_packet(struct garmin_data * garmin_data_p);
+static void gsp_next_packet(struct garmin_data *garmin_data_p);
 static int  garmin_write_bulk(struct usb_serial_port *port,
                             const unsigned char *buf, int count,
                             int dismiss_ack);
@@ -217,12 +218,13 @@ static unsigned char const PRIVATE_REQ[]
 
 
 static struct usb_device_id id_table [] = {
-       /* the same device id seems to be used by all usb enabled gps devices */
-       { USB_DEVICE(GARMIN_VENDOR_ID, 3 ) },
+       /* the same device id seems to be used by all
+          usb enabled GPS devices */
+       { USB_DEVICE(GARMIN_VENDOR_ID, 3) },
        { }                                     /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver garmin_driver = {
        .name =         "garmin_gps",
@@ -233,9 +235,10 @@ static struct usb_driver garmin_driver = {
 };
 
 
-static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p)
+static inline int noResponseFromAppLayer(struct garmin_data *garmin_data_p)
 {
-       return atomic_read(&garmin_data_p->req_count) == atomic_read(&garmin_data_p->resp_count);
+       return atomic_read(&garmin_data_p->req_count) ==
+                               atomic_read(&garmin_data_p->resp_count);
 }
 
 
@@ -261,10 +264,10 @@ static inline int getDataLength(const __u8 *usbPacket)
  */
 static inline int isAbortTrfCmnd(const unsigned char *buf)
 {
-       if (0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ, 
-                       sizeof(GARMIN_STOP_TRANSFER_REQ)) ||
-           0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ_V2, 
-                       sizeof(GARMIN_STOP_TRANSFER_REQ_V2)))
+       if (0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ,
+                                       sizeof(GARMIN_STOP_TRANSFER_REQ)) ||
+           0 == memcmp(buf, GARMIN_STOP_TRANSFER_REQ_V2,
+                                       sizeof(GARMIN_STOP_TRANSFER_REQ_V2)))
                return 1;
        else
                return 0;
@@ -275,11 +278,11 @@ static inline int isAbortTrfCmnd(const unsigned char *buf)
 static void send_to_tty(struct usb_serial_port *port,
                        char *data, unsigned int actual_length)
 {
-       struct tty_struct *tty = port->tty;
+       struct tty_struct *tty = port->port.tty;
 
        if (tty && actual_length) {
 
-               usb_serial_debug_data(debug, &port->dev, 
+               usb_serial_debug_data(debug, &port->dev,
                                        __func__, actual_length, data);
 
                tty_buffer_request_room(tty, actual_length);
@@ -296,7 +299,7 @@ static void send_to_tty(struct usb_serial_port *port,
 /*
  * queue a received (usb-)packet for later processing
  */
-static int pkt_add(struct garmin_data * garmin_data_p,
+static int pkt_add(struct garmin_data *garmin_data_p,
                   unsigned char *data, unsigned int data_length)
 {
        int state = 0;
@@ -307,7 +310,7 @@ static int pkt_add(struct garmin_data * garmin_data_p,
        /* process only packets containg data ... */
        if (data_length) {
                pkt = kmalloc(sizeof(struct garmin_packet)+data_length,
-                             GFP_ATOMIC);
+                                                               GFP_ATOMIC);
                if (pkt == NULL) {
                        dev_err(&garmin_data_p->port->dev, "out of memory\n");
                        return 0;
@@ -325,16 +328,15 @@ static int pkt_add(struct garmin_data * garmin_data_p,
 
                /* in serial mode, if someone is waiting for data from
                   the device, iconvert and send the next packet to tty. */
-               if (result && (state == STATE_GSP_WAIT_DATA)) {
+               if (result && (state == STATE_GSP_WAIT_DATA))
                        gsp_next_packet(garmin_data_p);
-               }
        }
        return result;
 }
 
 
 /* get the next pending packet */
-static struct garmin_packet *pkt_pop(struct garmin_data * garmin_data_p)
+static struct garmin_packet *pkt_pop(struct garmin_data *garmin_data_p)
 {
        unsigned long flags;
        struct garmin_packet *result = NULL;
@@ -350,7 +352,7 @@ static struct garmin_packet *pkt_pop(struct garmin_data * garmin_data_p)
 
 
 /* free up all queued data */
-static void pkt_clear(struct garmin_data * garmin_data_p)
+static void pkt_clear(struct garmin_data *garmin_data_p)
 {
        unsigned long flags;
        struct garmin_packet *result = NULL;
@@ -372,7 +374,7 @@ static void pkt_clear(struct garmin_data * garmin_data_p)
  ******************************************************************************/
 
 /* send an ack packet back to the tty */
-static int gsp_send_ack(struct garmin_data * garmin_data_p, __u8 pkt_id)
+static int gsp_send_ack(struct garmin_data *garmin_data_p, __u8 pkt_id)
 {
        __u8 pkt[10];
        __u8 cksum = 0;
@@ -391,9 +393,8 @@ static int gsp_send_ack(struct garmin_data * garmin_data_p, __u8 pkt_id)
        *ptr++ = pkt_id;
        cksum += pkt_id;
 
-       if (pkt_id == DLE) {
+       if (pkt_id == DLE)
                *ptr++ = DLE;
-       }
 
        *ptr++ = 0;
        *ptr++ = 0xFF & (-cksum);
@@ -415,12 +416,12 @@ static int gsp_send_ack(struct garmin_data * garmin_data_p, __u8 pkt_id)
  * at GSP_INITIAL_OFFSET.
  *
  * count - number of bytes in the input buffer including space reserved for
- *         the usb header: GSP_INITIAL_OFFSET + number of bytes in packet 
+ *         the usb header: GSP_INITIAL_OFFSET + number of bytes in packet
  *         (including pkt-id, data-length a. cksum)
  */
-static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count)
+static int gsp_rec_packet(struct garmin_data *garmin_data_p, int count)
 {
-       const __u8recpkt = garmin_data_p->inbuffer+GSP_INITIAL_OFFSET;
+       const __u8 *recpkt = garmin_data_p->inbuffer+GSP_INITIAL_OFFSET;
        __le32 *usbdata = (__le32 *) garmin_data_p->inbuffer;
 
        int cksum = 0;
@@ -440,8 +441,8 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count)
        cksum += *recpkt++;
        cksum += *recpkt++;
 
-       // sanity check, remove after test ...
-       if ((__u8*)&(usbdata[3]) != recpkt) {
+       /* sanity check, remove after test ... */
+       if ((__u8 *)&(usbdata[3]) != recpkt) {
                dbg("%s - ptr mismatch %p - %p",
                        __func__, &(usbdata[4]), recpkt);
                return -EINVPKT;
@@ -462,7 +463,7 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count)
        usbdata[1] = __cpu_to_le32(pktid);
        usbdata[2] = __cpu_to_le32(size);
 
-       garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer,
+       garmin_write_bulk(garmin_data_p->port, garmin_data_p->inbuffer,
                           GARMIN_PKTHDR_LENGTH+size, 0);
 
        /* if this was an abort-transfer command, flush all
@@ -495,7 +496,7 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count)
  * if the input is an abort command, drop all queued data.
  */
 
-static int gsp_receive(struct garmin_data * garmin_data_p,
+static int gsp_receive(struct garmin_data *garmin_data_p,
                       const unsigned char *buf, int count)
 {
        unsigned long flags;
@@ -504,10 +505,11 @@ static int gsp_receive(struct garmin_data * garmin_data_p,
        int i = 0;
        __u8 *dest;
        int size;
-       // dleSeen: set if last byte read was a DLE
+       /* dleSeen: set if last byte read was a DLE */
        int dleSeen;
-       // skip: if set, skip incoming data until possible start of
-       //       new packet
+       /* skip: if set, skip incoming data until possible start of
+        *       new packet
+        */
        int skip;
        __u8 data;
 
@@ -521,14 +523,13 @@ static int gsp_receive(struct garmin_data * garmin_data_p,
        dbg("%s - dle=%d skip=%d size=%d count=%d",
                __func__, dleSeen, skip, size, count);
 
-       if (size == 0) {
+       if (size == 0)
                size = GSP_INITIAL_OFFSET;
-       }
 
        while (offs < count) {
 
                data = *(buf+offs);
-               offs ++;
+               offs++;
 
                if (data == DLE) {
                        if (skip) { /* start of a new pkt */
@@ -554,9 +555,8 @@ static int gsp_receive(struct garmin_data * garmin_data_p,
                                        ack_or_nak_seen = NAK;
                                        dbg("NAK packet complete.");
                                } else {
-                                       dbg("packet complete "
-                                                       "- id=0x%X.",
-                                                       0xFF & data);
+                                       dbg("packet complete - id=0x%X.",
+                                               0xFF & data);
                                        gsp_rec_packet(garmin_data_p, size);
                                }
 
@@ -589,7 +589,7 @@ static int gsp_receive(struct garmin_data * garmin_data_p,
 
        garmin_data_p->insize = size;
 
-       // copy flags back to structure
+       /* copy flags back to structure */
        if (skip)
                garmin_data_p->flags |= FLAGS_GSP_SKIP;
        else
@@ -600,16 +600,13 @@ static int gsp_receive(struct garmin_data * garmin_data_p,
        else
                garmin_data_p->flags &= ~FLAGS_GSP_DLESEEN;
 
-       if (ack_or_nak_seen) {
+       if (ack_or_nak_seen)
                garmin_data_p->state = STATE_GSP_WAIT_DATA;
-       }
 
        spin_unlock_irqrestore(&garmin_data_p->lock, flags);
 
-       if (ack_or_nak_seen) {
+       if (ack_or_nak_seen)
                gsp_next_packet(garmin_data_p);
-       }
-
        return count;
 }
 
@@ -623,7 +620,7 @@ static int gsp_receive(struct garmin_data * garmin_data_p,
  *
  * return <0 on error, 0 if packet is incomplete or > 0 if packet was sent
  */
-static int gsp_send(struct garmin_data * garmin_data_p,
+static int gsp_send(struct garmin_data *garmin_data_p,
                    const unsigned char *buf, int count)
 {
        const unsigned char *src;
@@ -631,11 +628,11 @@ static int gsp_send(struct garmin_data * garmin_data_p,
        int pktid = 0;
        int datalen = 0;
        int cksum = 0;
-       int i=0;
+       int i = 0;
        int k;
 
        dbg("%s - state %d - %d bytes.", __func__,
-                garmin_data_p->state, count);
+                                       garmin_data_p->state, count);
 
        k = garmin_data_p->outsize;
        if ((k+count) > GPS_OUT_BUFSIZ) {
@@ -650,7 +647,7 @@ static int gsp_send(struct garmin_data * garmin_data_p,
 
        if (k >= GARMIN_PKTHDR_LENGTH) {
                pktid  = getPacketId(garmin_data_p->outbuffer);
-               datalen= getDataLength(garmin_data_p->outbuffer);
+               datalen = getDataLength(garmin_data_p->outbuffer);
                i = GARMIN_PKTHDR_LENGTH + datalen;
                if (k < i)
                        return 0;
@@ -658,19 +655,18 @@ static int gsp_send(struct garmin_data * garmin_data_p,
                return 0;
        }
 
-       dbg("%s - %d bytes in buffer, %d bytes in pkt.", __func__,
-                k, i);
+       dbg("%s - %d bytes in buffer, %d bytes in pkt.", __func__, k, i);
 
        /* garmin_data_p->outbuffer now contains a complete packet */
 
        usb_serial_debug_data(debug, &garmin_data_p->port->dev,
-                                  __func__, k, garmin_data_p->outbuffer);
+                               __func__, k, garmin_data_p->outbuffer);
 
        garmin_data_p->outsize = 0;
 
        if (GARMIN_LAYERID_APPL != getLayerId(garmin_data_p->outbuffer)) {
-               dbg("not an application packet (%d)", 
-                       getLayerId(garmin_data_p->outbuffer));
+               dbg("not an application packet (%d)",
+                               getLayerId(garmin_data_p->outbuffer));
                return -1;
        }
 
@@ -688,14 +684,14 @@ static int gsp_send(struct garmin_data * garmin_data_p,
 
        k = 0;
        src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH;
-       for (i=0; i<datalen; i++) {
+       for (i = 0; i < datalen; i++) {
                if (*src++ == DLE)
                        k++;
        }
 
        src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH;
        if (k > (GARMIN_PKTHDR_LENGTH-2)) {
-               /* can't add stuffing DLEs in place, move data to end 
+               /* can't add stuffing DLEs in place, move data to end
                   of buffer ... */
                dst = garmin_data_p->outbuffer+GPS_OUT_BUFSIZ-datalen;
                memcpy(dst, src, datalen);
@@ -712,14 +708,14 @@ static int gsp_send(struct garmin_data * garmin_data_p,
        if (datalen == DLE)
                *dst++ = DLE;
 
-       for (i=0; i<datalen; i++) {
+       for (i = 0; i < datalen; i++) {
                __u8 c = *src++;
                *dst++ = c;
                cksum += c;
                if (c == DLE)
                        *dst++ = DLE;
        }
-               
+
        cksum = 0xFF & -cksum;
        *dst++ = cksum;
        if (cksum == DLE)
@@ -744,7 +740,7 @@ static int gsp_send(struct garmin_data * garmin_data_p,
 /*
  * Process the next pending data packet - if there is one
  */
-static void gsp_next_packet(struct garmin_data * garmin_data_p)
+static void gsp_next_packet(struct garmin_data *garmin_data_p)
 {
        struct garmin_packet *pkt = NULL;
 
@@ -774,17 +770,17 @@ static void gsp_next_packet(struct garmin_data * garmin_data_p)
  * buf contains the data read, it may span more than one packet
  * or even incomplete packets
  */
-static int nat_receive(struct garmin_data * garmin_data_p,
+static int nat_receive(struct garmin_data *garmin_data_p,
                       const unsigned char *buf, int count)
 {
        unsigned long flags;
-       __u8 * dest;
+       __u8 *dest;
        int offs = 0;
        int result = count;
        int len;
 
        while (offs < count) {
-               // if buffer contains header, copy rest of data
+               /* if buffer contains header, copy rest of data */
                if (garmin_data_p->insize >= GARMIN_PKTHDR_LENGTH)
                        len = GARMIN_PKTHDR_LENGTH
                              +getDataLength(garmin_data_p->inbuffer);
@@ -792,9 +788,9 @@ static int nat_receive(struct garmin_data * garmin_data_p,
                        len = GARMIN_PKTHDR_LENGTH;
 
                if (len >= GPS_IN_BUFSIZ) {
-                       /* seem to be an invalid packet, ignore rest of input */
-                       dbg("%s - packet size too large: %d",
-                               __func__, len);
+                       /* seems to be an invalid packet, ignore rest
+                          of input */
+                       dbg("%s - packet size too large: %d", __func__, len);
                        garmin_data_p->insize = 0;
                        count = 0;
                        result = -EINVPKT;
@@ -804,7 +800,7 @@ static int nat_receive(struct garmin_data * garmin_data_p,
                                len = (count-offs);
                        if (len > 0) {
                                dest = garmin_data_p->inbuffer
-                                       +garmin_data_p->insize;
+                                               + garmin_data_p->insize;
                                memcpy(dest, buf+offs, len);
                                garmin_data_p->insize += len;
                                offs += len;
@@ -816,17 +812,19 @@ static int nat_receive(struct garmin_data * garmin_data_p,
                        len = GARMIN_PKTHDR_LENGTH+
                           getDataLength(garmin_data_p->inbuffer);
                        if (garmin_data_p->insize >= len) {
-                               garmin_write_bulk (garmin_data_p->port,
-                                                  garmin_data_p->inbuffer,
-                                                  len, 0);
+                               garmin_write_bulk(garmin_data_p->port,
+                                                  garmin_data_p->inbuffer,
+                                                  len, 0);
                                garmin_data_p->insize = 0;
 
                                /* if this was an abort-transfer command,
                                   flush all queued data. */
                                if (isAbortTrfCmnd(garmin_data_p->inbuffer)) {
-                                       spin_lock_irqsave(&garmin_data_p->lock, flags);
+                                       spin_lock_irqsave(&garmin_data_p->lock,
+                                                                       flags);
                                        garmin_data_p->flags |= FLAGS_DROP_DATA;
-                                       spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+                                       spin_unlock_irqrestore(
+                                               &garmin_data_p->lock, flags);
                                        pkt_clear(garmin_data_p);
                                }
                        }
@@ -842,7 +840,7 @@ static int nat_receive(struct garmin_data * garmin_data_p,
 
 static void priv_status_resp(struct usb_serial_port *port)
 {
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+       struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
        __le32 *pkt = (__le32 *)garmin_data_p->privpkt;
 
        pkt[0] = __cpu_to_le32(GARMIN_LAYERID_PRIVATE);
@@ -852,7 +850,7 @@ static void priv_status_resp(struct usb_serial_port *port)
        pkt[4] = __cpu_to_le32(garmin_data_p->mode);
        pkt[5] = __cpu_to_le32(garmin_data_p->serial_num);
 
-       send_to_tty(port, (__u8*)pkt, 6*4);
+       send_to_tty(port, (__u8 *)pkt, 6 * 4);
 }
 
 
@@ -864,7 +862,7 @@ static int process_resetdev_request(struct usb_serial_port *port)
 {
        unsigned long flags;
        int status;
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+       struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
 
        spin_lock_irqsave(&garmin_data_p->lock, flags);
        garmin_data_p->flags &= ~(CLEAR_HALT_REQUIRED);
@@ -872,8 +870,8 @@ static int process_resetdev_request(struct usb_serial_port *port)
        garmin_data_p->serial_num = 0;
        spin_unlock_irqrestore(&garmin_data_p->lock, flags);
 
-       usb_kill_urb (port->interrupt_in_urb);
-       dbg("%s - usb_reset_device", __func__ );
+       usb_kill_urb(port->interrupt_in_urb);
+       dbg("%s - usb_reset_device", __func__);
        status = usb_reset_device(port->serial->dev);
        if (status)
                dbg("%s - usb_reset_device failed: %d",
@@ -886,7 +884,7 @@ static int process_resetdev_request(struct usb_serial_port *port)
 /*
  * clear all cached data
  */
-static int garmin_clear(struct garmin_data * garmin_data_p)
+static int garmin_clear(struct garmin_data *garmin_data_p)
 {
        unsigned long flags;
        int status = 0;
@@ -896,8 +894,7 @@ static int garmin_clear(struct garmin_data * garmin_data_p)
        if (port != NULL && atomic_read(&garmin_data_p->resp_count)) {
                /* send a terminate command */
                status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ,
-                                          sizeof(GARMIN_STOP_TRANSFER_REQ),
-                                          1);
+                                       sizeof(GARMIN_STOP_TRANSFER_REQ), 1);
        }
 
        /* flush all queued data */
@@ -920,28 +917,26 @@ static int garmin_init_session(struct usb_serial_port *port)
 {
        unsigned long flags;
        struct usb_serial *serial = port->serial;
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+       struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
        int status = 0;
 
        if (status == 0) {
-               usb_kill_urb (port->interrupt_in_urb);
+               usb_kill_urb(port->interrupt_in_urb);
 
                dbg("%s - adding interrupt input", __func__);
                port->interrupt_in_urb->dev = serial->dev;
                status = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
                if (status)
                        dev_err(&serial->dev->dev,
-                               "%s - failed submitting interrupt urb,"
-                               " error %d\n",
-                               __func__, status);
+                         "%s - failed submitting interrupt urb, error %d\n",
+                                                       __func__, status);
        }
 
        if (status == 0) {
                dbg("%s - starting session ...", __func__);
                garmin_data_p->state = STATE_ACTIVE;
                status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ,
-                                          sizeof(GARMIN_START_SESSION_REQ),
-                                          0);
+                                       sizeof(GARMIN_START_SESSION_REQ), 0);
 
                if (status >= 0) {
 
@@ -951,14 +946,14 @@ static int garmin_init_session(struct usb_serial_port *port)
 
                        /* not needed, but the win32 driver does it too ... */
                        status = garmin_write_bulk(port,
-                                                  GARMIN_START_SESSION_REQ2,
-                                                  sizeof(GARMIN_START_SESSION_REQ2),
-                                                  0);
+                                       GARMIN_START_SESSION_REQ2,
+                                       sizeof(GARMIN_START_SESSION_REQ2), 0);
                        if (status >= 0) {
                                status = 0;
                                spin_lock_irqsave(&garmin_data_p->lock, flags);
                                garmin_data_p->ignorePkts++;
-                               spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+                               spin_unlock_irqrestore(&garmin_data_p->lock,
+                                                                       flags);
                        }
                }
        }
@@ -970,11 +965,12 @@ static int garmin_init_session(struct usb_serial_port *port)
 
 
 
-static int garmin_open (struct usb_serial_port *port, struct file *filp)
+static int garmin_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        unsigned long flags;
        int status = 0;
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+       struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
 
        dbg("%s - port %d", __func__, port->number);
 
@@ -983,8 +979,8 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp)
         * through, otherwise it is scheduled, and with high data rates (like
         * with OHCI) data can get lost.
         */
-       if (port->tty)
-               port->tty->low_latency = 1;
+       if (tty)
+               tty->low_latency = 1;
 
        spin_lock_irqsave(&garmin_data_p->lock, flags);
        garmin_data_p->mode  = initial_mode;
@@ -995,23 +991,22 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp)
        spin_unlock_irqrestore(&garmin_data_p->lock, flags);
 
        /* shutdown any bulk reads that might be going on */
-       usb_kill_urb (port->write_urb);
-       usb_kill_urb (port->read_urb);
+       usb_kill_urb(port->write_urb);
+       usb_kill_urb(port->read_urb);
 
-       if (garmin_data_p->state == STATE_RESET) {
+       if (garmin_data_p->state == STATE_RESET)
                status = garmin_init_session(port);
-       }
 
        garmin_data_p->state = STATE_ACTIVE;
-
        return status;
 }
 
 
-static void garmin_close (struct usb_serial_port *port, struct file * filp)
+static void garmin_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial = port->serial;
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+       struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
 
        dbg("%s - port %d - mode=%d state=%d flags=0x%X", __func__,
                port->number, garmin_data_p->mode,
@@ -1025,8 +1020,8 @@ static void garmin_close (struct usb_serial_port *port, struct file * filp)
                garmin_clear(garmin_data_p);
 
        /* shutdown our urbs */
-       usb_kill_urb (port->read_urb);
-       usb_kill_urb (port->write_urb);
+       usb_kill_urb(port->read_urb);
+       usb_kill_urb(port->write_urb);
 
        if (!port->serial->disconnected) {
                if (noResponseFromAppLayer(garmin_data_p) ||
@@ -1042,21 +1037,22 @@ static void garmin_close (struct usb_serial_port *port, struct file * filp)
        mutex_unlock(&port->serial->disc_mutex);
 }
 
-
-static void garmin_write_bulk_callback (struct urb *urb)
+static void garmin_write_bulk_callback(struct urb *urb)
 {
        unsigned long flags;
        struct usb_serial_port *port = urb->context;
        int status = urb->status;
 
        if (port) {
-               struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+               struct garmin_data *garmin_data_p =
+                                       usb_get_serial_port_data(port);
 
                dbg("%s - port %d", __func__, port->number);
 
                if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer)
                    && (garmin_data_p->mode == MODE_GARMIN_SERIAL))  {
-                       gsp_send_ack(garmin_data_p, ((__u8 *)urb->transfer_buffer)[4]);
+                       gsp_send_ack(garmin_data_p,
+                                       ((__u8 *)urb->transfer_buffer)[4]);
                }
 
                if (status) {
@@ -1070,20 +1066,21 @@ static void garmin_write_bulk_callback (struct urb *urb)
                usb_serial_port_softint(port);
        }
 
-       /* Ignore errors that resulted from garmin_write_bulk with dismiss_ack=1 */
+       /* Ignore errors that resulted from garmin_write_bulk with
+          dismiss_ack = 1 */
 
        /* free up the transfer buffer, as usb_free_urb() does not do this */
-       kfree (urb->transfer_buffer);
+       kfree(urb->transfer_buffer);
 }
 
 
-static int garmin_write_bulk (struct usb_serial_port *port,
+static int garmin_write_bulk(struct usb_serial_port *port,
                              const unsigned char *buf, int count,
                              int dismiss_ack)
 {
        unsigned long flags;
        struct usb_serial *serial = port->serial;
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+       struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
        struct urb *urb;
        unsigned char *buffer;
        int status;
@@ -1095,7 +1092,7 @@ static int garmin_write_bulk (struct usb_serial_port *port,
        garmin_data_p->flags &= ~FLAGS_DROP_DATA;
        spin_unlock_irqrestore(&garmin_data_p->lock, flags);
 
-       buffer = kmalloc (count, GFP_ATOMIC);
+       buffer = kmalloc(count, GFP_ATOMIC);
        if (!buffer) {
                dev_err(&port->dev, "out of memory\n");
                return -ENOMEM;
@@ -1104,17 +1101,17 @@ static int garmin_write_bulk (struct usb_serial_port *port,
        urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!urb) {
                dev_err(&port->dev, "no more free urbs\n");
-               kfree (buffer);
+               kfree(buffer);
                return -ENOMEM;
        }
 
-       memcpy (buffer, buf, count);
+       memcpy(buffer, buf, count);
 
        usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);
 
-       usb_fill_bulk_urb (urb, serial->dev,
-                               usb_sndbulkpipe (serial->dev,
-                               port->bulk_out_endpointAddress),
+       usb_fill_bulk_urb(urb, serial->dev,
+                               usb_sndbulkpipe(serial->dev,
+                                       port->bulk_out_endpointAddress),
                                buffer, count,
                                garmin_write_bulk_callback,
                                dismiss_ack ? NULL : port);
@@ -1132,33 +1129,29 @@ static int garmin_write_bulk (struct usb_serial_port *port,
        status = usb_submit_urb(urb, GFP_ATOMIC);
        if (status) {
                dev_err(&port->dev,
-                       "%s - usb_submit_urb(write bulk) "
-                       "failed with status = %d\n",
+                  "%s - usb_submit_urb(write bulk) failed with status = %d\n",
                                __func__, status);
                count = status;
        }
 
        /* we are done with this urb, so let the host driver
         * really free it when it is finished with it */
-       usb_free_urb (urb);
+       usb_free_urb(urb);
 
        return count;
 }
 
-
-
-static int garmin_write (struct usb_serial_port *port,
-                        const unsigned char *buf, int count)
+static int garmin_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                        const unsigned char *buf, int count)
 {
        int pktid, pktsiz, len;
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+       struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
        __le32 *privpkt = (__le32 *)garmin_data_p->privpkt;
 
        usb_serial_debug_data(debug, &port->dev, __func__, count, buf);
 
        /* check for our private packets */
        if (count >= GARMIN_PKTHDR_LENGTH) {
-
                len = PRIVPKTSIZ;
                if (count < len)
                        len = count;
@@ -1169,15 +1162,16 @@ static int garmin_write (struct usb_serial_port *port,
                pktid  = getPacketId(garmin_data_p->privpkt);
 
                if (count == (GARMIN_PKTHDR_LENGTH+pktsiz)
-                   && GARMIN_LAYERID_PRIVATE == getLayerId(garmin_data_p->privpkt)) {
+                   && GARMIN_LAYERID_PRIVATE ==
+                               getLayerId(garmin_data_p->privpkt)) {
 
                        dbg("%s - processing private request %d",
                                __func__, pktid);
 
-                       // drop all unfinished transfers
+                       /* drop all unfinished transfers */
                        garmin_clear(garmin_data_p);
 
-                       switch(pktid) {
+                       switch (pktid) {
 
                        case PRIV_PKTID_SET_DEBUG:
                                if (pktsiz != 4)
@@ -1226,44 +1220,31 @@ static int garmin_write (struct usb_serial_port *port,
 }
 
 
-static int garmin_write_room (struct usb_serial_port *port)
+static int garmin_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        /*
         * Report back the bytes currently available in the output buffer.
         */
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+       struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
        return GPS_OUT_BUFSIZ-garmin_data_p->outsize;
 }
 
 
-static int garmin_chars_in_buffer (struct usb_serial_port *port)
-{
-       /*
-        * Report back the number of bytes currently in our input buffer.
-        * Will this lock up the driver - the buffer contains an incomplete
-        * package which will not be written to the device until it
-        * has been completed ?
-        */
-       //struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
-       //return garmin_data_p->insize;
-       return 0;
-}
-
-
-static void garmin_read_process(struct garmin_data * garmin_data_p,
+static void garmin_read_process(struct garmin_data *garmin_data_p,
                                 unsigned char *data, unsigned data_length)
 {
        if (garmin_data_p->flags & FLAGS_DROP_DATA) {
                /* abort-transfer cmd is actice */
                dbg("%s - pkt dropped", __func__);
        } else if (garmin_data_p->state != STATE_DISCONNECTED &&
-                  garmin_data_p->state != STATE_RESET ) {
+               garmin_data_p->state != STATE_RESET) {
 
                /* remember any appl.layer packets, so we know
                   if a reset is required or not when closing
                   the device */
                if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY,
-                               sizeof(GARMIN_APP_LAYER_REPLY))) {
+                               sizeof(GARMIN_APP_LAYER_REPLY))) {
                        atomic_inc(&garmin_data_p->resp_count);
                }
 
@@ -1273,9 +1254,8 @@ static void garmin_read_process(struct garmin_data * garmin_data_p,
                if (garmin_data_p->flags & FLAGS_QUEUING) {
                        pkt_add(garmin_data_p, data, data_length);
                } else if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
-                       if (getLayerId(data) == GARMIN_LAYERID_APPL) {
+                       if (getLayerId(data) == GARMIN_LAYERID_APPL)
                                pkt_add(garmin_data_p, data, data_length);
-                       }
                } else {
                        send_to_tty(garmin_data_p->port, data, data_length);
                }
@@ -1283,12 +1263,12 @@ static void garmin_read_process(struct garmin_data * garmin_data_p,
 }
 
 
-static void garmin_read_bulk_callback (struct urb *urb)
+static void garmin_read_bulk_callback(struct urb *urb)
 {
        unsigned long flags;
        struct usb_serial_port *port = urb->context;
        struct usb_serial *serial =  port->serial;
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+       struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
        unsigned char *data = urb->transfer_buffer;
        int status = urb->status;
        int retval;
@@ -1306,7 +1286,7 @@ static void garmin_read_bulk_callback (struct urb *urb)
                return;
        }
 
-       usb_serial_debug_data(debug, &port->dev, 
+       usb_serial_debug_data(debug, &port->dev,
                                __func__, urb->actual_length, data);
 
        garmin_read_process(garmin_data_p, data, urb->actual_length);
@@ -1340,13 +1320,13 @@ static void garmin_read_bulk_callback (struct urb *urb)
 }
 
 
-static void garmin_read_int_callback (struct urb *urb)
+static void garmin_read_int_callback(struct urb *urb)
 {
        unsigned long flags;
        int retval;
        struct usb_serial_port *port = urb->context;
        struct usb_serial *serial = port->serial;
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+       struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
        unsigned char *data = urb->transfer_buffer;
        int status = urb->status;
 
@@ -1372,30 +1352,31 @@ static void garmin_read_int_callback (struct urb *urb)
 
        if (urb->actual_length == sizeof(GARMIN_BULK_IN_AVAIL_REPLY) &&
            0 == memcmp(data, GARMIN_BULK_IN_AVAIL_REPLY,
-                       sizeof(GARMIN_BULK_IN_AVAIL_REPLY))) {
+                               sizeof(GARMIN_BULK_IN_AVAIL_REPLY))) {
 
                dbg("%s - bulk data available.", __func__);
 
                if (0 == (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) {
 
                        /* bulk data available */
-                       usb_fill_bulk_urb (port->read_urb, serial->dev,
-                                       usb_rcvbulkpipe (serial->dev,
-                                       port->bulk_in_endpointAddress),
+                       usb_fill_bulk_urb(port->read_urb, serial->dev,
+                                       usb_rcvbulkpipe(serial->dev,
+                                               port->bulk_in_endpointAddress),
                                        port->read_urb->transfer_buffer,
                                        port->read_urb->transfer_buffer_length,
                                        garmin_read_bulk_callback, port);
                        retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);
                        if (retval) {
                                dev_err(&port->dev,
-                                       "%s - failed submitting read urb, error %d\n",
-                               __func__, retval);
+                                "%s - failed submitting read urb, error %d\n",
+                                                       __func__, retval);
                        } else {
                                spin_lock_irqsave(&garmin_data_p->lock, flags);
                                garmin_data_p->flags |= FLAGS_BULK_IN_ACTIVE;
                                /* do not send this packet to the user */
                                garmin_data_p->ignorePkts = 1;
-                               spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+                               spin_unlock_irqrestore(&garmin_data_p->lock,
+                                                                       flags);
                        }
                } else {
                        /* bulk-in transfer still active */
@@ -1406,15 +1387,15 @@ static void garmin_read_int_callback (struct urb *urb)
 
        } else if (urb->actual_length == (4+sizeof(GARMIN_START_SESSION_REPLY))
                         && 0 == memcmp(data, GARMIN_START_SESSION_REPLY,
-                                       sizeof(GARMIN_START_SESSION_REPLY))) {
+                                       sizeof(GARMIN_START_SESSION_REPLY))) {
 
                spin_lock_irqsave(&garmin_data_p->lock, flags);
                garmin_data_p->flags |= FLAGS_SESSION_REPLY1_SEEN;
                spin_unlock_irqrestore(&garmin_data_p->lock, flags);
 
                /* save the serial number */
-               garmin_data_p->serial_num 
-                       = __le32_to_cpup((__le32*)(data+GARMIN_PKTHDR_LENGTH));
+               garmin_data_p->serial_num = __le32_to_cpup(
+                                       (__le32 *)(data+GARMIN_PKTHDR_LENGTH));
 
                dbg("%s - start-of-session reply seen - serial %u.",
                        __func__, garmin_data_p->serial_num);
@@ -1433,7 +1414,7 @@ static void garmin_read_int_callback (struct urb *urb)
        }
 
        port->interrupt_in_urb->dev = port->serial->dev;
-       retval = usb_submit_urb (urb, GFP_ATOMIC);
+       retval = usb_submit_urb(urb, GFP_ATOMIC);
        if (retval)
                dev_err(&urb->dev->dev,
                        "%s - Error %d submitting interrupt urb\n",
@@ -1446,7 +1427,7 @@ static void garmin_read_int_callback (struct urb *urb)
  * and then sets a timer to call itself again until all queued data
  * is sent.
  */
-static int garmin_flush_queue(struct garmin_data * garmin_data_p)
+static int garmin_flush_queue(struct garmin_data *garmin_data_p)
 {
        unsigned long flags;
        struct garmin_packet *pkt;
@@ -1468,10 +1449,11 @@ static int garmin_flush_queue(struct garmin_data * garmin_data_p)
 }
 
 
-static void garmin_throttle (struct usb_serial_port *port)
+static void garmin_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
+       struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
        unsigned long flags;
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
 
        dbg("%s - port %d", __func__, port->number);
        /* set flag, data received will be put into a queue
@@ -1482,10 +1464,11 @@ static void garmin_throttle (struct usb_serial_port *port)
 }
 
 
-static void garmin_unthrottle (struct usb_serial_port *port)
+static void garmin_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
+       struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
        unsigned long flags;
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
        int status;
 
        dbg("%s - port %d", __func__, port->number);
@@ -1507,8 +1490,6 @@ static void garmin_unthrottle (struct usb_serial_port *port)
        }
 }
 
-
-
 /*
  * The timer is currently only used to send queued packets to
  * the tty in cases where the protocol provides no own handshaking
@@ -1526,11 +1507,11 @@ static void timeout_handler(unsigned long data)
 
 
 
-static int garmin_attach (struct usb_serial *serial)
+static int garmin_attach(struct usb_serial *serial)
 {
        int status = 0;
        struct usb_serial_port *port = serial->port[0];
-       struct garmin_data * garmin_data_p = NULL;
+       struct garmin_data *garmin_data_p = NULL;
 
        dbg("%s", __func__);
 
@@ -1542,7 +1523,7 @@ static int garmin_attach (struct usb_serial *serial)
        init_timer(&garmin_data_p->timer);
        spin_lock_init(&garmin_data_p->lock);
        INIT_LIST_HEAD(&garmin_data_p->pktlist);
-       //garmin_data_p->timer.expires = jiffies + session_timeout;
+       /* garmin_data_p->timer.expires = jiffies + session_timeout; */
        garmin_data_p->timer.data = (unsigned long)garmin_data_p;
        garmin_data_p->timer.function = timeout_handler;
        garmin_data_p->port = port;
@@ -1556,16 +1537,16 @@ static int garmin_attach (struct usb_serial *serial)
 }
 
 
-static void garmin_shutdown (struct usb_serial *serial)
+static void garmin_shutdown(struct usb_serial *serial)
 {
        struct usb_serial_port *port = serial->port[0];
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+       struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
 
        dbg("%s", __func__);
 
-       usb_kill_urb (port->interrupt_in_urb);
+       usb_kill_urb(port->interrupt_in_urb);
        del_timer_sync(&garmin_data_p->timer);
-       kfree (garmin_data_p);
+       kfree(garmin_data_p);
        usb_set_serial_port_data(port, NULL);
 }
 
@@ -1588,7 +1569,6 @@ static struct usb_serial_driver garmin_device = {
        .shutdown            = garmin_shutdown,
        .write               = garmin_write,
        .write_room          = garmin_write_room,
-       .chars_in_buffer     = garmin_chars_in_buffer,
        .write_bulk_callback = garmin_write_bulk_callback,
        .read_bulk_callback  = garmin_read_bulk_callback,
        .read_int_callback   = garmin_read_int_callback,
@@ -1596,7 +1576,7 @@ static struct usb_serial_driver garmin_device = {
 
 
 
-static int __init garmin_init (void)
+static int __init garmin_init(void)
 {
        int retval;
 
@@ -1616,10 +1596,10 @@ failed_garmin_register:
 }
 
 
-static void __exit garmin_exit (void)
+static void __exit garmin_exit(void)
 {
-       usb_deregister (&garmin_driver);
-       usb_serial_deregister (&garmin_device);
+       usb_deregister(&garmin_driver);
+       usb_serial_deregister(&garmin_device);
 }
 
 
@@ -1628,8 +1608,8 @@ static void __exit garmin_exit (void)
 module_init(garmin_init);
 module_exit(garmin_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IWUSR | S_IRUGO);
index 537f12a027c224e2a2253224ae020e515714416d..fe84c88ec20cae94b9d1990b1e48be0ef87cb364 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/moduleparam.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 
 static int debug;
@@ -81,7 +81,7 @@ static int generic_probe(struct usb_interface *interface,
 }
 #endif
 
-int usb_serial_generic_register (int _debug)
+int usb_serial_generic_register(int _debug)
 {
        int retval = 0;
 
@@ -89,10 +89,11 @@ int usb_serial_generic_register (int _debug)
 #ifdef CONFIG_USB_SERIAL_GENERIC
        generic_device_ids[0].idVendor = vendor;
        generic_device_ids[0].idProduct = product;
-       generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT;
+       generic_device_ids[0].match_flags =
+               USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT;
 
        /* register our generic driver with ourselves */
-       retval = usb_serial_register (&usb_serial_generic_device);
+       retval = usb_serial_register(&usb_serial_generic_device);
        if (retval)
                goto exit;
        retval = usb_register(&generic_driver);
@@ -103,16 +104,17 @@ exit:
        return retval;
 }
 
-void usb_serial_generic_deregister (void)
+void usb_serial_generic_deregister(void)
 {
 #ifdef CONFIG_USB_SERIAL_GENERIC
        /* remove our generic driver */
        usb_deregister(&generic_driver);
-       usb_serial_deregister (&usb_serial_generic_device);
+       usb_serial_deregister(&usb_serial_generic_device);
 #endif
 }
 
-int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
+int usb_serial_generic_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial = port->serial;
        int result = 0;
@@ -120,11 +122,11 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
 
        dbg("%s - port %d", __func__, port->number);
 
-       /* force low_latency on so that our tty_push actually forces the data through, 
-          otherwise it is scheduled, and with high data rates (like with OHCI) data
-          can get lost. */
-       if (port->tty)
-               port->tty->low_latency = 1;
+       /* force low_latency on so that our tty_push actually forces the data
+          through, otherwise it is scheduled, and with high data rates (like
+          with OHCI) data can get lost. */
+       if (tty)
+               tty->low_latency = 1;
 
        /* clear the throttle flags */
        spin_lock_irqsave(&port->lock, flags);
@@ -135,8 +137,9 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
        /* if we have a bulk endpoint, start reading from it */
        if (serial->num_bulk_in) {
                /* Start reading from the device */
-               usb_fill_bulk_urb (port->read_urb, serial->dev,
-                                  usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
+               usb_fill_bulk_urb(port->read_urb, serial->dev,
+                                  usb_rcvbulkpipe(serial->dev,
+                                               port->bulk_in_endpointAddress),
                                   port->read_urb->transfer_buffer,
                                   port->read_urb->transfer_buffer_length,
                                   ((serial->type->read_bulk_callback) ?
@@ -145,14 +148,16 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
                                   port);
                result = usb_submit_urb(port->read_urb, GFP_KERNEL);
                if (result)
-                       dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result);
+                       dev_err(&port->dev,
+                           "%s - failed resubmitting read urb, error %d\n",
+                                                       __func__, result);
        }
 
        return result;
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_open);
 
-static void generic_cleanup (struct usb_serial_port *port)
+static void generic_cleanup(struct usb_serial_port *port)
 {
        struct usb_serial *serial = port->serial;
 
@@ -182,7 +187,7 @@ int usb_serial_generic_resume(struct usb_serial *serial)
 #endif
        for (i = 0; i < serial->num_ports; i++) {
                port = serial->port[i];
-               if (port->open_count && port->read_urb) {
+               if (port->port.count && port->read_urb) {
                        r = usb_submit_urb(port->read_urb, GFP_NOIO);
                        if (r < 0)
                                c++;
@@ -192,13 +197,15 @@ int usb_serial_generic_resume(struct usb_serial *serial)
        return c ? -EIO : 0;
 }
 
-void usb_serial_generic_close (struct usb_serial_port *port, struct file * filp)
+void usb_serial_generic_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        dbg("%s - port %d", __func__, port->number);
-       generic_cleanup (port);
+       generic_cleanup(port);
 }
 
-int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *buf, int count)
+int usb_serial_generic_write(struct tty_struct *tty,
+       struct usb_serial_port *port, const unsigned char *buf, int count)
 {
        struct usb_serial *serial = port->serial;
        int result;
@@ -208,7 +215,7 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *
 
        if (count == 0) {
                dbg("%s - write request of 0 bytes", __func__);
-               return (0);
+               return 0;
        }
 
        /* only do something if we have a bulk out endpoint */
@@ -223,27 +230,32 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *
                port->write_urb_busy = 1;
                spin_unlock_irqrestore(&port->lock, flags);
 
-               count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
+               count = (count > port->bulk_out_size) ?
+                                       port->bulk_out_size : count;
 
-               memcpy (port->write_urb->transfer_buffer, buf, count);
+               memcpy(port->write_urb->transfer_buffer, buf, count);
                data = port->write_urb->transfer_buffer;
                usb_serial_debug_data(debug, &port->dev, __func__, count, data);
 
                /* set up our urb */
-               usb_fill_bulk_urb (port->write_urb, serial->dev,
-                                  usb_sndbulkpipe (serial->dev,
-                                                   port->bulk_out_endpointAddress),
+               usb_fill_bulk_urb(port->write_urb, serial->dev,
+                                  usb_sndbulkpipe(serial->dev,
+                                       port->bulk_out_endpointAddress),
                                   port->write_urb->transfer_buffer, count,
-                                  ((serial->type->write_bulk_callback) ? 
+                                  ((serial->type->write_bulk_callback) ?
                                     serial->type->write_bulk_callback :
-                                    usb_serial_generic_write_bulk_callback), port);
+                                    usb_serial_generic_write_bulk_callback),
+                                  port);
 
                /* send the data out the bulk port */
                port->write_urb_busy = 1;
                result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
                if (result) {
-                       dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result);
-                       /* don't have to grab the lock here, as we will retry if != 0 */
+                       dev_err(&port->dev,
+                               "%s - failed submitting write urb, error %d\n",
+                                                       __func__, result);
+                       /* don't have to grab the lock here, as we will
+                          retry if != 0 */
                        port->write_urb_busy = 0;
                } else
                        result = count;
@@ -255,8 +267,9 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *
        return 0;
 }
 
-int usb_serial_generic_write_room (struct usb_serial_port *port)
+int usb_serial_generic_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
        int room = 0;
 
@@ -272,8 +285,9 @@ int usb_serial_generic_write_room (struct usb_serial_port *port)
        return room;
 }
 
-int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
+int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
        int chars = 0;
 
@@ -286,7 +300,7 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
        }
 
        dbg("%s - returns %d", __func__, chars);
-       return (chars);
+       return chars;
 }
 
 
@@ -297,24 +311,26 @@ static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags)
        int result;
 
        /* Continue reading from device */
-       usb_fill_bulk_urb (urb, serial->dev,
-                          usb_rcvbulkpipe (serial->dev,
-                                           port->bulk_in_endpointAddress),
+       usb_fill_bulk_urb(urb, serial->dev,
+                          usb_rcvbulkpipe(serial->dev,
+                                       port->bulk_in_endpointAddress),
                           urb->transfer_buffer,
                           urb->transfer_buffer_length,
-                          ((serial->type->read_bulk_callback) ? 
-                            serial->type->read_bulk_callback : 
+                          ((serial->type->read_bulk_callback) ?
+                            serial->type->read_bulk_callback :
                             usb_serial_generic_read_bulk_callback), port);
        result = usb_submit_urb(urb, mem_flags);
        if (result)
-               dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result);
+               dev_err(&port->dev,
+                       "%s - failed resubmitting read urb, error %d\n",
+                                                       __func__, result);
 }
 
 /* Push data to tty layer and resubmit the bulk read URB */
-static void flush_and_resubmit_read_urb (struct usb_serial_port *port)
+static void flush_and_resubmit_read_urb(struct usb_serial_port *port)
 {
        struct urb *urb = port->read_urb;
-       struct tty_struct *tty = port->tty;
+       struct tty_struct *tty = port->port.tty;
        int room;
 
        /* Push data to tty */
@@ -329,7 +345,7 @@ static void flush_and_resubmit_read_urb (struct usb_serial_port *port)
        resubmit_read_urb(port, GFP_ATOMIC);
 }
 
-void usb_serial_generic_read_bulk_callback (struct urb *urb)
+void usb_serial_generic_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        unsigned char *data = urb->transfer_buffer;
@@ -344,20 +360,21 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb)
                return;
        }
 
-       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                                               urb->actual_length, data);
 
        /* Throttle the device if requested by tty */
        spin_lock_irqsave(&port->lock, flags);
-       if (!(port->throttled = port->throttle_req)) {
+       port->throttled = port->throttle_req;
+       if (!port->throttled) {
                spin_unlock_irqrestore(&port->lock, flags);
                flush_and_resubmit_read_urb(port);
-       } else {
+       } else
                spin_unlock_irqrestore(&port->lock, flags);
-       }
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
 
-void usb_serial_generic_write_bulk_callback (struct urb *urb)
+void usb_serial_generic_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        int status = urb->status;
@@ -374,8 +391,9 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb)
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
 
-void usb_serial_generic_throttle (struct usb_serial_port *port)
+void usb_serial_generic_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        unsigned long flags;
 
        dbg("%s - port %d", __func__, port->number);
@@ -387,8 +405,9 @@ void usb_serial_generic_throttle (struct usb_serial_port *port)
        spin_unlock_irqrestore(&port->lock, flags);
 }
 
-void usb_serial_generic_unthrottle (struct usb_serial_port *port)
+void usb_serial_generic_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        int was_throttled;
        unsigned long flags;
 
@@ -406,15 +425,14 @@ void usb_serial_generic_unthrottle (struct usb_serial_port *port)
        }
 }
 
-void usb_serial_generic_shutdown (struct usb_serial *serial)
+void usb_serial_generic_shutdown(struct usb_serial *serial)
 {
        int i;
 
        dbg("%s", __func__);
 
        /* stop reads and writes on all ports */
-       for (i=0; i < serial->num_ports; ++i) {
+       for (i = 0; i < serial->num_ports; ++i)
                generic_cleanup(serial->port[i]);
-       }
 }
 
index 75b88b356ebca4408f8f6e28c94d677856aeee4c..ab905869e959e377cb0b55cfec5b7323220c67de 100644 (file)
@@ -9,7 +9,8 @@
  *     the Free Software Foundation; either version 2 of the License, or
  *     (at your option) any later version.
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
  */
 
 #include <linux/kernel.h>
index 2fd449bcfa35cd2c59fcb112ae0bb84a77be7988..bfa508ddb0fed3f97062bf66e16326b765dbcbe1 100644 (file)
@@ -44,7 +44,7 @@
 #include <linux/wait.h>
 #include <linux/firmware.h>
 #include <linux/ihex.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include "io_edgeport.h"
 
 /* receive port state */
 enum RXSTATE {
-       EXPECT_HDR1 = 0,        /* Expect header byte 1 */
-       EXPECT_HDR2 = 1,        /* Expect header byte 2 */
-       EXPECT_DATA = 2,        /* Expect 'RxBytesRemaining' data */
-       EXPECT_HDR3 = 3,        /* Expect header byte 3 (for status hdrs only) */
+       EXPECT_HDR1 = 0,    /* Expect header byte 1 */
+       EXPECT_HDR2 = 1,    /* Expect header byte 2 */
+       EXPECT_DATA = 2,    /* Expect 'RxBytesRemaining' data */
+       EXPECT_HDR3 = 3,    /* Expect header byte 3 (for status hdrs only) */
 };
 
 
-/* Transmit Fifo 
- * This Transmit queue is an extension of the edgeport Rx buffer. 
- * The maximum amount of data buffered in both the edgeport 
+/* Transmit Fifo
+ * This Transmit queue is an extension of the edgeport Rx buffer.
+ * The maximum amount of data buffered in both the edgeport
  * Rx buffer (maxTxCredits) and this buffer will never exceed maxTxCredits.
  */
 struct TxFifo {
@@ -132,12 +132,12 @@ struct edgeport_serial {
        int                     is_epic;                        /* flag if EPiC device or not */
 
        __u8                    interrupt_in_endpoint;          /* the interrupt endpoint handle */
-       unsigned char *         interrupt_in_buffer;            /* the buffer we use for the interrupt endpoint */
-       struct urb *            interrupt_read_urb;             /* our interrupt urb */
+       unsigned char           *interrupt_in_buffer;           /* the buffer we use for the interrupt endpoint */
+       struct urb              *interrupt_read_urb;            /* our interrupt urb */
 
        __u8                    bulk_in_endpoint;               /* the bulk in endpoint handle */
-       unsigned char *         bulk_in_buffer;                 /* the buffer we use for the bulk in endpoint */
-       struct urb *            read_urb;                       /* our bulk read urb */
+       unsigned char           *bulk_in_buffer;                /* the buffer we use for the bulk in endpoint */
+       struct urb              *read_urb;                      /* our bulk read urb */
        bool                    read_in_progress;
        spinlock_t              es_lock;
 
@@ -162,16 +162,17 @@ struct divisor_table_entry {
        __u16  Divisor;
 };
 
-//
-// Define table of divisors for Rev A EdgePort/4 hardware
-// These assume a 3.6864MHz crystal, the standard /16, and
-// MCR.7 = 0.
-//
+/*
+ * Define table of divisors for Rev A EdgePort/4 hardware
+ * These assume a 3.6864MHz crystal, the standard /16, and
+ * MCR.7 = 0.
+ */
+
 static const struct divisor_table_entry divisor_table[] = {
-       {   50,         4608},  
-       {   75,         3072},  
-       {   110,        2095},          /* 2094.545455 => 230450   => .0217 % over */
-       {   134,        1713},          /* 1713.011152 => 230398.5 => .00065% under */
+       {   50,         4608},
+       {   75,         3072},
+       {   110,        2095},  /* 2094.545455 => 230450   => .0217 % over */
+       {   134,        1713},  /* 1713.011152 => 230398.5 => .00065% under */
        {   150,        1536},
        {   300,        768},
        {   600,        384},
@@ -194,64 +195,86 @@ static int debug;
 
 static int low_latency = 1;    /* tty low latency flag, on by default */
 
-static atomic_t CmdUrbs;               /* Number of outstanding Command Write Urbs */
+static atomic_t CmdUrbs;       /* Number of outstanding Command Write Urbs */
 
 
 /* local function prototypes */
 
 /* function prototypes for all URB callbacks */
-static void edge_interrupt_callback    (struct urb *urb);
-static void edge_bulk_in_callback      (struct urb *urb);
-static void edge_bulk_out_data_callback        (struct urb *urb);
-static void edge_bulk_out_cmd_callback (struct urb *urb);
+static void edge_interrupt_callback(struct urb *urb);
+static void edge_bulk_in_callback(struct urb *urb);
+static void edge_bulk_out_data_callback(struct urb *urb);
+static void edge_bulk_out_cmd_callback(struct urb *urb);
 
 /* function prototypes for the usbserial callbacks */
-static int  edge_open                  (struct usb_serial_port *port, struct file *filp);
-static void edge_close                 (struct usb_serial_port *port, struct file *filp);
-static int  edge_write                 (struct usb_serial_port *port, const unsigned char *buf, int count);
-static int  edge_write_room            (struct usb_serial_port *port);
-static int  edge_chars_in_buffer       (struct usb_serial_port *port);
-static void edge_throttle              (struct usb_serial_port *port);
-static void edge_unthrottle            (struct usb_serial_port *port);
-static void edge_set_termios           (struct usb_serial_port *port, struct ktermios *old_termios);
-static int  edge_ioctl                 (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg);
-static void edge_break                 (struct usb_serial_port *port, int break_state);
-static int  edge_tiocmget              (struct usb_serial_port *port, struct file *file);
-static int  edge_tiocmset              (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
-static int  edge_startup               (struct usb_serial *serial);
-static void edge_shutdown              (struct usb_serial *serial);
-
+static int edge_open(struct tty_struct *tty, struct usb_serial_port *port,
+                                       struct file *filp);
+static void edge_close(struct tty_struct *tty, struct usb_serial_port *port,
+                                       struct file *filp);
+static int edge_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                       const unsigned char *buf, int count);
+static int edge_write_room(struct tty_struct *tty);
+static int edge_chars_in_buffer(struct tty_struct *tty);
+static void edge_throttle(struct tty_struct *tty);
+static void edge_unthrottle(struct tty_struct *tty);
+static void edge_set_termios(struct tty_struct *tty,
+                                       struct usb_serial_port *port,
+                                       struct ktermios *old_termios);
+static int  edge_ioctl(struct tty_struct *tty, struct file *file,
+                                       unsigned int cmd, unsigned long arg);
+static void edge_break(struct tty_struct *tty, int break_state);
+static int  edge_tiocmget(struct tty_struct *tty, struct file *file);
+static int  edge_tiocmset(struct tty_struct *tty, struct file *file,
+                                       unsigned int set, unsigned int clear);
+static int  edge_startup(struct usb_serial *serial);
+static void edge_shutdown(struct usb_serial *serial);
 
 #include "io_tables.h" /* all of the devices that this driver supports */
 
 /* function prototypes for all of our local functions */
-static void  process_rcvd_data         (struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength);
-static void process_rcvd_status                (struct edgeport_serial *edge_serial, __u8 byte2, __u8 byte3);
-static void edge_tty_recv                      (struct device *dev, struct tty_struct *tty, unsigned char *data, int length);
-static void handle_new_msr             (struct edgeport_port *edge_port, __u8 newMsr);
-static void handle_new_lsr             (struct edgeport_port *edge_port, __u8 lsrData, __u8 lsr, __u8 data);
-static int  send_iosp_ext_cmd          (struct edgeport_port *edge_port, __u8 command, __u8 param);
-static int  calc_baud_rate_divisor     (int baud_rate, int *divisor);
-static int  send_cmd_write_baud_rate   (struct edgeport_port *edge_port, int baudRate);
-static void change_port_settings       (struct edgeport_port *edge_port, struct ktermios *old_termios);
-static int  send_cmd_write_uart_register       (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue);
-static int  write_cmd_usb              (struct edgeport_port *edge_port, unsigned char *buffer, int writeLength);
-static void send_more_port_data                (struct edgeport_serial *edge_serial, struct edgeport_port *edge_port);
-
-static int  sram_write                 (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __u8 *data);
-static int  rom_read                   (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data);
-static int  rom_write                  (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __u8 *data);
-static void get_manufacturing_desc     (struct edgeport_serial *edge_serial);
-static void get_boot_desc              (struct edgeport_serial *edge_serial);
-static void load_application_firmware  (struct edgeport_serial *edge_serial);
-
-static void unicode_to_ascii(char *string, int buflen, __le16 *unicode, int unicode_size);
-
-
-// ************************************************************************
-// ************************************************************************
-// ************************************************************************
-// ************************************************************************
+
+static void  process_rcvd_data(struct edgeport_serial *edge_serial,
+                               unsigned char *buffer, __u16 bufferLength);
+static void process_rcvd_status(struct edgeport_serial *edge_serial,
+                               __u8 byte2, __u8 byte3);
+static void edge_tty_recv(struct device *dev, struct tty_struct *tty,
+                               unsigned char *data, int length);
+static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr);
+static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData,
+                               __u8 lsr, __u8 data);
+static int  send_iosp_ext_cmd(struct edgeport_port *edge_port, __u8 command,
+                               __u8 param);
+static int  calc_baud_rate_divisor(int baud_rate, int *divisor);
+static int  send_cmd_write_baud_rate(struct edgeport_port *edge_port,
+                               int baudRate);
+static void change_port_settings(struct tty_struct *tty,
+                               struct edgeport_port *edge_port,
+                               struct ktermios *old_termios);
+static int  send_cmd_write_uart_register(struct edgeport_port *edge_port,
+                               __u8 regNum, __u8 regValue);
+static int  write_cmd_usb(struct edgeport_port *edge_port,
+                               unsigned char *buffer, int writeLength);
+static void send_more_port_data(struct edgeport_serial *edge_serial,
+                               struct edgeport_port *edge_port);
+
+static int sram_write(struct usb_serial *serial, __u16 extAddr, __u16 addr,
+                                       __u16 length, const __u8 *data);
+static int rom_read(struct usb_serial *serial, __u16 extAddr, __u16 addr,
+                                               __u16 length, __u8 *data);
+static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr,
+                                       __u16 length, const __u8 *data);
+static void get_manufacturing_desc(struct edgeport_serial *edge_serial);
+static void get_boot_desc(struct edgeport_serial *edge_serial);
+static void load_application_firmware(struct edgeport_serial *edge_serial);
+
+static void unicode_to_ascii(char *string, int buflen,
+                               __le16 *unicode, int unicode_size);
+
+
+/* ************************************************************************ */
+/* ************************************************************************ */
+/* ************************************************************************ */
+/* ************************************************************************ */
 
 /************************************************************************
  *                                                                     *
@@ -261,7 +284,7 @@ static void unicode_to_ascii(char *string, int buflen, __le16 *unicode, int unic
  *                             embedded in this driver                 *
  *                                                                     *
  ************************************************************************/
-static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial)
+static void update_edgeport_E2PROM(struct edgeport_serial *edge_serial)
 {
        __u32 BootCurVer;
        __u32 BootNewVer;
@@ -275,16 +298,14 @@ static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial)
        int response;
 
        switch (edge_serial->product_info.iDownloadFile) {
-               case EDGE_DOWNLOAD_FILE_I930:
-                       fw_name = "edgeport/boot.fw";
-                       break;
-
-               case EDGE_DOWNLOAD_FILE_80251:
-                       fw_name = "edgeport/boot2.fw";
-                       break;
-
-               default:
-                       return;
+       case EDGE_DOWNLOAD_FILE_I930:
+               fw_name = "edgeport/boot.fw";
+               break;
+       case EDGE_DOWNLOAD_FILE_80251:
+               fw_name = "edgeport/boot2.fw";
+               break;
+       default:
+               return;
        }
 
        response = request_ihex_firmware(&fw, fw_name,
@@ -300,7 +321,7 @@ static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial)
        BootMinorVersion = rec->data[1];
        BootBuildNumber = (rec->data[2] << 8) | rec->data[3];
 
-       // Check Boot Image Version
+       /* Check Boot Image Version */
        BootCurVer = (edge_serial->boot_descriptor.MajorVersion << 24) +
                     (edge_serial->boot_descriptor.MinorVersion << 16) +
                      le16_to_cpu(edge_serial->boot_descriptor.BuildNumber);
@@ -352,29 +373,29 @@ static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial)
  *  Get string descriptor from device                                  *
  *                                                                     *
  ************************************************************************/
-static int get_string (struct usb_device *dev, int Id, char *string, int buflen)
+static int get_string(struct usb_device *dev, int Id, char *string, int buflen)
 {
        struct usb_string_descriptor StringDesc;
        struct usb_string_descriptor *pStringDesc;
 
-       dbg("%s - USB String ID = %d", __func__, Id );
+       dbg("%s - USB String ID = %d", __func__, Id);
 
-       if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc, sizeof(StringDesc))) {
+       if (!usb_get_descriptor(dev, USB_DT_STRING, Id,
+                                       &StringDesc, sizeof(StringDesc)))
                return 0;
-       }
 
-       pStringDesc = kmalloc (StringDesc.bLength, GFP_KERNEL);
-
-       if (!pStringDesc) {
+       pStringDesc = kmalloc(StringDesc.bLength, GFP_KERNEL);
+       if (!pStringDesc)
                return 0;
-       }
 
-       if (!usb_get_descriptor(dev, USB_DT_STRING, Id, pStringDesc, StringDesc.bLength )) {
+       if (!usb_get_descriptor(dev, USB_DT_STRING, Id,
+                                       pStringDesc, StringDesc.bLength)) {
                kfree(pStringDesc);
                return 0;
        }
 
-       unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2);
+       unicode_to_ascii(string, buflen,
+                               pStringDesc->wData, pStringDesc->bLength/2);
 
        kfree(pStringDesc);
        dbg("%s - USB String %s", __func__, string);
@@ -388,24 +409,24 @@ static int get_string (struct usb_device *dev, int Id, char *string, int buflen)
  *  Get string descriptor from device
  *
  ************************************************************************/
-static int get_string_desc (struct usb_device *dev, int Id, struct usb_string_descriptor **pRetDesc)
+static int get_string_desc(struct usb_device *dev, int Id,
+                               struct usb_string_descriptor **pRetDesc)
 {
        struct usb_string_descriptor StringDesc;
        struct usb_string_descriptor *pStringDesc;
 
-       dbg("%s - USB String ID = %d", __func__, Id );
+       dbg("%s - USB String ID = %d", __func__, Id);
 
-       if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc, sizeof(StringDesc))) {
+       if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc,
+                                               sizeof(StringDesc)))
                return 0;
-       }
 
-       pStringDesc = kmalloc (StringDesc.bLength, GFP_KERNEL);
-
-       if (!pStringDesc) {
+       pStringDesc = kmalloc(StringDesc.bLength, GFP_KERNEL);
+       if (!pStringDesc)
                return -1;
-       }
 
-       if (!usb_get_descriptor(dev, USB_DT_STRING, Id, pStringDesc, StringDesc.bLength )) {
+       if (!usb_get_descriptor(dev, USB_DT_STRING, Id, pStringDesc,
+                                                       StringDesc.bLength)) {
                kfree(pStringDesc);
                return -1;
        }
@@ -417,25 +438,30 @@ static int get_string_desc (struct usb_device *dev, int Id, struct usb_string_de
 
 static void dump_product_info(struct edgeport_product_info *product_info)
 {
-       // Dump Product Info structure
+       /* Dump Product Info structure */
        dbg("**Product Information:");
-       dbg("  ProductId             %x", product_info->ProductId );
-       dbg("  NumPorts              %d", product_info->NumPorts );
-       dbg("  ProdInfoVer           %d", product_info->ProdInfoVer );
+       dbg("  ProductId             %x", product_info->ProductId);
+       dbg("  NumPorts              %d", product_info->NumPorts);
+       dbg("  ProdInfoVer           %d", product_info->ProdInfoVer);
        dbg("  IsServer              %d", product_info->IsServer);
-       dbg("  IsRS232               %d", product_info->IsRS232 );
-       dbg("  IsRS422               %d", product_info->IsRS422 );
-       dbg("  IsRS485               %d", product_info->IsRS485 );
-       dbg("  RomSize               %d", product_info->RomSize );
-       dbg("  RamSize               %d", product_info->RamSize );
-       dbg("  CpuRev                %x", product_info->CpuRev  );
+       dbg("  IsRS232               %d", product_info->IsRS232);
+       dbg("  IsRS422               %d", product_info->IsRS422);
+       dbg("  IsRS485               %d", product_info->IsRS485);
+       dbg("  RomSize               %d", product_info->RomSize);
+       dbg("  RamSize               %d", product_info->RamSize);
+       dbg("  CpuRev                %x", product_info->CpuRev);
        dbg("  BoardRev              %x", product_info->BoardRev);
        dbg("  BootMajorVersion      %d.%d.%d", product_info->BootMajorVersion,
            product_info->BootMinorVersion,
            le16_to_cpu(product_info->BootBuildNumber));
-       dbg("  ManufactureDescDate   %d/%d/%d", product_info->ManufactureDescDate[0],
-           product_info->ManufactureDescDate[1],
-           product_info->ManufactureDescDate[2]+1900);
+       dbg("  FirmwareMajorVersion  %d.%d.%d",
+                       product_info->FirmwareMajorVersion,
+                       product_info->FirmwareMinorVersion,
+                       le16_to_cpu(product_info->FirmwareBuildNumber));
+       dbg("  ManufactureDescDate   %d/%d/%d",
+                       product_info->ManufactureDescDate[0],
+                       product_info->ManufactureDescDate[1],
+                       product_info->ManufactureDescDate[2]+1900);
        dbg("  iDownloadFile         0x%x", product_info->iDownloadFile);
        dbg("  EpicVer               %d", product_info->EpicVer);
 }
@@ -444,55 +470,60 @@ static void get_product_info(struct edgeport_serial *edge_serial)
 {
        struct edgeport_product_info *product_info = &edge_serial->product_info;
 
-       memset (product_info, 0, sizeof(struct edgeport_product_info));
-
-       product_info->ProductId         = (__u16)(le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ~ION_DEVICE_ID_80251_NETCHIP);
-       product_info->NumPorts          = edge_serial->manuf_descriptor.NumPorts;
-       product_info->ProdInfoVer       = 0;
-
-       product_info->RomSize           = edge_serial->manuf_descriptor.RomSize;
-       product_info->RamSize           = edge_serial->manuf_descriptor.RamSize;
-       product_info->CpuRev            = edge_serial->manuf_descriptor.CpuRev;
-       product_info->BoardRev          = edge_serial->manuf_descriptor.BoardRev;
-
-       product_info->BootMajorVersion  = edge_serial->boot_descriptor.MajorVersion;
-       product_info->BootMinorVersion  = edge_serial->boot_descriptor.MinorVersion;
-       product_info->BootBuildNumber   = edge_serial->boot_descriptor.BuildNumber;
-
-       memcpy(product_info->ManufactureDescDate, edge_serial->manuf_descriptor.DescDate, sizeof(edge_serial->manuf_descriptor.DescDate));
-
-       // check if this is 2nd generation hardware
-       if (le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ION_DEVICE_ID_80251_NETCHIP) {
-               product_info->iDownloadFile             = EDGE_DOWNLOAD_FILE_80251;
-       } else {
-               product_info->iDownloadFile             = EDGE_DOWNLOAD_FILE_I930;
-       }
-
-       // Determine Product type and set appropriate flags
+       memset(product_info, 0, sizeof(struct edgeport_product_info));
+
+       product_info->ProductId = (__u16)(le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ~ION_DEVICE_ID_80251_NETCHIP);
+       product_info->NumPorts = edge_serial->manuf_descriptor.NumPorts;
+       product_info->ProdInfoVer = 0;
+
+       product_info->RomSize = edge_serial->manuf_descriptor.RomSize;
+       product_info->RamSize = edge_serial->manuf_descriptor.RamSize;
+       product_info->CpuRev = edge_serial->manuf_descriptor.CpuRev;
+       product_info->BoardRev = edge_serial->manuf_descriptor.BoardRev;
+
+       product_info->BootMajorVersion =
+                               edge_serial->boot_descriptor.MajorVersion;
+       product_info->BootMinorVersion =
+                               edge_serial->boot_descriptor.MinorVersion;
+       product_info->BootBuildNumber =
+                               edge_serial->boot_descriptor.BuildNumber;
+
+       memcpy(product_info->ManufactureDescDate,
+                       edge_serial->manuf_descriptor.DescDate,
+                       sizeof(edge_serial->manuf_descriptor.DescDate));
+
+       /* check if this is 2nd generation hardware */
+       if (le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct)
+                                           & ION_DEVICE_ID_80251_NETCHIP)
+               product_info->iDownloadFile = EDGE_DOWNLOAD_FILE_80251;
+       else
+               product_info->iDownloadFile = EDGE_DOWNLOAD_FILE_I930;
+       /* Determine Product type and set appropriate flags */
        switch (DEVICE_ID_FROM_USB_PRODUCT_ID(product_info->ProductId)) {
-               case ION_DEVICE_ID_EDGEPORT_COMPATIBLE:
-               case ION_DEVICE_ID_EDGEPORT_4T:
-               case ION_DEVICE_ID_EDGEPORT_4:
-               case ION_DEVICE_ID_EDGEPORT_2:
-               case ION_DEVICE_ID_EDGEPORT_8_DUAL_CPU:
-               case ION_DEVICE_ID_EDGEPORT_8:
-               case ION_DEVICE_ID_EDGEPORT_421:
-               case ION_DEVICE_ID_EDGEPORT_21:
-               case ION_DEVICE_ID_EDGEPORT_2_DIN:
-               case ION_DEVICE_ID_EDGEPORT_4_DIN:
-               case ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU:
-                       product_info->IsRS232 = 1;
-                       break;
+       case ION_DEVICE_ID_EDGEPORT_COMPATIBLE:
+       case ION_DEVICE_ID_EDGEPORT_4T:
+       case ION_DEVICE_ID_EDGEPORT_4:
+       case ION_DEVICE_ID_EDGEPORT_2:
+       case ION_DEVICE_ID_EDGEPORT_8_DUAL_CPU:
+       case ION_DEVICE_ID_EDGEPORT_8:
+       case ION_DEVICE_ID_EDGEPORT_421:
+       case ION_DEVICE_ID_EDGEPORT_21:
+       case ION_DEVICE_ID_EDGEPORT_2_DIN:
+       case ION_DEVICE_ID_EDGEPORT_4_DIN:
+       case ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU:
+               product_info->IsRS232 = 1;
+               break;
 
-               case ION_DEVICE_ID_EDGEPORT_2I:                            // Edgeport/2 RS422/RS485
-                       product_info->IsRS422 = 1;
-                       product_info->IsRS485 = 1;
-                       break;
+       case ION_DEVICE_ID_EDGEPORT_2I: /* Edgeport/2 RS422/RS485 */
+               product_info->IsRS422 = 1;
+               product_info->IsRS485 = 1;
+               break;
 
-               case ION_DEVICE_ID_EDGEPORT_8I:                            // Edgeport/4 RS422
-               case ION_DEVICE_ID_EDGEPORT_4I:                            // Edgeport/4 RS422
-                       product_info->IsRS422 = 1;
-                       break;
+       case ION_DEVICE_ID_EDGEPORT_8I: /* Edgeport/4 RS422 */
+       case ION_DEVICE_ID_EDGEPORT_4I: /* Edgeport/4 RS422 */
+               product_info->IsRS422 = 1;
+               break;
        }
 
        dump_product_info(product_info);
@@ -520,32 +551,32 @@ static int get_epic_descriptor(struct edgeport_serial *ep)
                ep->is_epic = 1;
                memset(product_info, 0, sizeof(struct edgeport_product_info));
 
-               product_info->NumPorts                  = epic->NumPorts;
-               product_info->ProdInfoVer               = 0;
-               product_info->FirmwareMajorVersion      = epic->MajorVersion;
-               product_info->FirmwareMinorVersion      = epic->MinorVersion;
-               product_info->FirmwareBuildNumber       = epic->BuildNumber;
-               product_info->iDownloadFile             = epic->iDownloadFile;
-               product_info->EpicVer                   = epic->EpicVer;
-               product_info->Epic                      = epic->Supports;
-               product_info->ProductId                 = ION_DEVICE_ID_EDGEPORT_COMPATIBLE;
+               product_info->NumPorts = epic->NumPorts;
+               product_info->ProdInfoVer = 0;
+               product_info->FirmwareMajorVersion = epic->MajorVersion;
+               product_info->FirmwareMinorVersion = epic->MinorVersion;
+               product_info->FirmwareBuildNumber = epic->BuildNumber;
+               product_info->iDownloadFile = epic->iDownloadFile;
+               product_info->EpicVer = epic->EpicVer;
+               product_info->Epic = epic->Supports;
+               product_info->ProductId = ION_DEVICE_ID_EDGEPORT_COMPATIBLE;
                dump_product_info(product_info);
 
                bits = &ep->epic_descriptor.Supports;
                dbg("**EPIC descriptor:");
                dbg("  VendEnableSuspend: %s", bits->VendEnableSuspend  ? "TRUE": "FALSE");
-               dbg("  IOSPOpen         : %s", bits->IOSPOpen           ? "TRUE": "FALSE" );
-               dbg("  IOSPClose        : %s", bits->IOSPClose          ? "TRUE": "FALSE" );
-               dbg("  IOSPChase        : %s", bits->IOSPChase          ? "TRUE": "FALSE" );
-               dbg("  IOSPSetRxFlow    : %s", bits->IOSPSetRxFlow      ? "TRUE": "FALSE" );
-               dbg("  IOSPSetTxFlow    : %s", bits->IOSPSetTxFlow      ? "TRUE": "FALSE" );
-               dbg("  IOSPSetXChar     : %s", bits->IOSPSetXChar       ? "TRUE": "FALSE" );
-               dbg("  IOSPRxCheck      : %s", bits->IOSPRxCheck        ? "TRUE": "FALSE" );
-               dbg("  IOSPSetClrBreak  : %s", bits->IOSPSetClrBreak    ? "TRUE": "FALSE" );
-               dbg("  IOSPWriteMCR     : %s", bits->IOSPWriteMCR       ? "TRUE": "FALSE" );
-               dbg("  IOSPWriteLCR     : %s", bits->IOSPWriteLCR       ? "TRUE": "FALSE" );
-               dbg("  IOSPSetBaudRate  : %s", bits->IOSPSetBaudRate    ? "TRUE": "FALSE" );
-               dbg("  TrueEdgeport     : %s", bits->TrueEdgeport       ? "TRUE": "FALSE" );
+               dbg("  IOSPOpen         : %s", bits->IOSPOpen           ? "TRUE": "FALSE");
+               dbg("  IOSPClose        : %s", bits->IOSPClose          ? "TRUE": "FALSE");
+               dbg("  IOSPChase        : %s", bits->IOSPChase          ? "TRUE": "FALSE");
+               dbg("  IOSPSetRxFlow    : %s", bits->IOSPSetRxFlow      ? "TRUE": "FALSE");
+               dbg("  IOSPSetTxFlow    : %s", bits->IOSPSetTxFlow      ? "TRUE": "FALSE");
+               dbg("  IOSPSetXChar     : %s", bits->IOSPSetXChar       ? "TRUE": "FALSE");
+               dbg("  IOSPRxCheck      : %s", bits->IOSPRxCheck        ? "TRUE": "FALSE");
+               dbg("  IOSPSetClrBreak  : %s", bits->IOSPSetClrBreak    ? "TRUE": "FALSE");
+               dbg("  IOSPWriteMCR     : %s", bits->IOSPWriteMCR       ? "TRUE": "FALSE");
+               dbg("  IOSPWriteLCR     : %s", bits->IOSPWriteLCR       ? "TRUE": "FALSE");
+               dbg("  IOSPSetBaudRate  : %s", bits->IOSPSetBaudRate    ? "TRUE": "FALSE");
+               dbg("  TrueEdgeport     : %s", bits->TrueEdgeport       ? "TRUE": "FALSE");
        }
 
        return result;
@@ -561,10 +592,10 @@ static int get_epic_descriptor(struct edgeport_serial *ep)
 
 /*****************************************************************************
  * edge_interrupt_callback
- *     this is the callback function for when we have received data on the 
+ *     this is the callback function for when we have received data on the
  *     interrupt endpoint.
  *****************************************************************************/
-static void edge_interrupt_callback (struct urb *urb)
+static void edge_interrupt_callback(struct urb *urb)
 {
        struct edgeport_serial  *edge_serial = urb->context;
        struct edgeport_port *edge_port;
@@ -589,17 +620,17 @@ static void edge_interrupt_callback (struct urb *urb)
        case -ESHUTDOWN:
                /* this urb is terminated, clean up */
                dbg("%s - urb shutting down with status: %d",
-                   __func__, status);
+                                               __func__, status);
                return;
        default:
-               dbg("%s - nonzero urb status received: %d",
-                   __func__, status);
+               dbg("%s - nonzero urb status received: %d", __func__, status);
                goto exit;
        }
 
-       // process this interrupt-read even if there are no ports open
+       /* process this interrupt-read even if there are no ports open */
        if (length) {
-               usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __func__, length, data);
+               usb_serial_debug_data(debug, &edge_serial->serial->dev->dev,
+                                               __func__, length, data);
 
                if (length > 1) {
                        bytes_avail = data[0] | (data[1] << 8);
@@ -613,7 +644,8 @@ static void edge_interrupt_callback (struct urb *urb)
                                        dbg("%s - posting a read", __func__);
                                        edge_serial->read_in_progress = true;
 
-                                       /* we have pending bytes on the bulk in pipe, send a request */
+                                       /* we have pending bytes on the
+                                          bulk in pipe, send a request */
                                        edge_serial->read_urb->dev = edge_serial->serial->dev;
                                        result = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC);
                                        if (result) {
@@ -627,7 +659,8 @@ static void edge_interrupt_callback (struct urb *urb)
                /* grab the txcredits for the ports if available */
                position = 2;
                portNumber = 0;
-               while ((position < length) && (portNumber < edge_serial->serial->num_ports)) {
+               while ((position < length) &&
+                               (portNumber < edge_serial->serial->num_ports)) {
                        txCredits = data[position] | (data[position+1] << 8);
                        if (txCredits) {
                                port = edge_serial->serial->port[portNumber];
@@ -636,14 +669,19 @@ static void edge_interrupt_callback (struct urb *urb)
                                        spin_lock(&edge_port->ep_lock);
                                        edge_port->txCredits += txCredits;
                                        spin_unlock(&edge_port->ep_lock);
-                                       dbg("%s - txcredits for port%d = %d", __func__, portNumber, edge_port->txCredits);
-
-                                       /* tell the tty driver that something has changed */
-                                       if (edge_port->port->tty)
-                                               tty_wakeup(edge_port->port->tty);
-
-                                       // Since we have more credit, check if more data can be sent
-                                       send_more_port_data(edge_serial, edge_port);
+                                       dbg("%s - txcredits for port%d = %d",
+                                                       __func__, portNumber,
+                                                       edge_port->txCredits);
+
+                                       /* tell the tty driver that something
+                                          has changed */
+                                       if (edge_port->port->port.tty)
+                                               tty_wakeup(edge_port->port->port.tty);
+
+                                       /* Since we have more credit, check
+                                          if more data can be sent */
+                                       send_more_port_data(edge_serial,
+                                                               edge_port);
                                }
                        }
                        position += 2;
@@ -652,19 +690,20 @@ static void edge_interrupt_callback (struct urb *urb)
        }
 
 exit:
-       result = usb_submit_urb (urb, GFP_ATOMIC);
-       if (result) {
-               dev_err(&urb->dev->dev, "%s - Error %d submitting control urb\n", __func__, result);
-       }
+       result = usb_submit_urb(urb, GFP_ATOMIC);
+       if (result)
+               dev_err(&urb->dev->dev,
+                       "%s - Error %d submitting control urb\n",
+                                               __func__, result);
 }
 
 
 /*****************************************************************************
  * edge_bulk_in_callback
- *     this is the callback function for when we have received data on the 
+ *     this is the callback function for when we have received data on the
  *     bulk in endpoint.
  *****************************************************************************/
-static void edge_bulk_in_callback (struct urb *urb)
+static void edge_bulk_in_callback(struct urb *urb)
 {
        struct edgeport_serial  *edge_serial = urb->context;
        unsigned char           *data = urb->transfer_buffer;
@@ -689,16 +728,18 @@ static void edge_bulk_in_callback (struct urb *urb)
 
        raw_data_length = urb->actual_length;
 
-       usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __func__, raw_data_length, data);
+       usb_serial_debug_data(debug, &edge_serial->serial->dev->dev,
+                                       __func__, raw_data_length, data);
 
        spin_lock(&edge_serial->es_lock);
 
        /* decrement our rxBytes available by the number that we just got */
        edge_serial->rxBytesAvail -= raw_data_length;
 
-       dbg("%s - Received = %d, rxBytesAvail %d", __func__, raw_data_length, edge_serial->rxBytesAvail);
+       dbg("%s - Received = %d, rxBytesAvail %d", __func__,
+                               raw_data_length, edge_serial->rxBytesAvail);
 
-       process_rcvd_data (edge_serial, data, urb->actual_length);
+       process_rcvd_data(edge_serial, data, urb->actual_length);
 
        /* check to see if there's any more data for us to read */
        if (edge_serial->rxBytesAvail > 0) {
@@ -721,10 +762,10 @@ static void edge_bulk_in_callback (struct urb *urb)
 
 /*****************************************************************************
  * edge_bulk_out_data_callback
- *     this is the callback function for when we have finished sending serial data
- *     on the bulk out endpoint.
+ *     this is the callback function for when we have finished sending
+ *     serial data on the bulk out endpoint.
  *****************************************************************************/
-static void edge_bulk_out_data_callback (struct urb *urb)
+static void edge_bulk_out_data_callback(struct urb *urb)
 {
        struct edgeport_port *edge_port = urb->context;
        struct tty_struct *tty;
@@ -737,27 +778,29 @@ static void edge_bulk_out_data_callback (struct urb *urb)
                    __func__, status);
        }
 
-       tty = edge_port->port->tty;
+       tty = edge_port->port->port.tty;
 
        if (tty && edge_port->open) {
-               /* let the tty driver wakeup if it has a special write_wakeup function */
+               /* let the tty driver wakeup if it has a special
+                  write_wakeup function */
                tty_wakeup(tty);
        }
 
-       // Release the Write URB
+       /* Release the Write URB */
        edge_port->write_in_progress = false;
 
-       // Check if more data needs to be sent
-       send_more_port_data((struct edgeport_serial *)(usb_get_serial_data(edge_port->port->serial)), edge_port);
+       /* Check if more data needs to be sent */
+       send_more_port_data((struct edgeport_serial *)
+               (usb_get_serial_data(edge_port->port->serial)), edge_port);
 }
 
 
 /*****************************************************************************
  * BulkOutCmdCallback
- *     this is the callback function for when we have finished sending a command
- *     on the bulk out endpoint.
+ *     this is the callback function for when we have finished sending a
+ *     command on the bulk out endpoint.
  *****************************************************************************/
-static void edge_bulk_out_cmd_callback (struct urb *urb)
+static void edge_bulk_out_cmd_callback(struct urb *urb)
 {
        struct edgeport_port *edge_port = urb->context;
        struct tty_struct *tty;
@@ -766,22 +809,24 @@ static void edge_bulk_out_cmd_callback (struct urb *urb)
        dbg("%s", __func__);
 
        atomic_dec(&CmdUrbs);
-       dbg("%s - FREE URB %p (outstanding %d)", __func__, urb, atomic_read(&CmdUrbs));
+       dbg("%s - FREE URB %p (outstanding %d)", __func__,
+                                       urb, atomic_read(&CmdUrbs));
 
 
        /* clean up the transfer buffer */
        kfree(urb->transfer_buffer);
 
        /* Free the command urb */
-       usb_free_urb (urb);
+       usb_free_urb(urb);
 
        if (status) {
-               dbg("%s - nonzero write bulk status received: %d", __func__, status);
+               dbg("%s - nonzero write bulk status received: %d",
+                                                       __func__, status);
                return;
        }
 
        /* Get pointer to tty */
-       tty = edge_port->port->tty;
+       tty = edge_port->port->port.tty;
 
        /* tell the tty driver that something has changed */
        if (tty && edge_port->open)
@@ -803,7 +848,8 @@ static void edge_bulk_out_cmd_callback (struct urb *urb)
  *     If successful, we return 0
  *     Otherwise we return a negative error number.
  *****************************************************************************/
-static int edge_open (struct usb_serial_port *port, struct file * filp)
+static int edge_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        struct usb_serial *serial;
@@ -815,55 +861,62 @@ static int edge_open (struct usb_serial_port *port, struct file * filp)
        if (edge_port == NULL)
                return -ENODEV;
 
-       if (port->tty)
-               port->tty->low_latency = low_latency;
+       if (tty)
+               tty->low_latency = low_latency;
 
-       /* see if we've set up our endpoint info yet (can't set it up in edge_startup
-          as the structures were not set up at that time.) */
+       /* see if we've set up our endpoint info yet (can't set it up
+          in edge_startup as the structures were not set up at that time.) */
        serial = port->serial;
        edge_serial = usb_get_serial_data(serial);
-       if (edge_serial == NULL) {
+       if (edge_serial == NULL)
                return -ENODEV;
-       }
        if (edge_serial->interrupt_in_buffer == NULL) {
                struct usb_serial_port *port0 = serial->port[0];
-               
+
                /* not set up yet, so do it now */
-               edge_serial->interrupt_in_buffer = port0->interrupt_in_buffer;
-               edge_serial->interrupt_in_endpoint = port0->interrupt_in_endpointAddress;
+               edge_serial->interrupt_in_buffer =
+                                       port0->interrupt_in_buffer;
+               edge_serial->interrupt_in_endpoint =
+                                       port0->interrupt_in_endpointAddress;
                edge_serial->interrupt_read_urb = port0->interrupt_in_urb;
                edge_serial->bulk_in_buffer = port0->bulk_in_buffer;
-               edge_serial->bulk_in_endpoint = port0->bulk_in_endpointAddress;
+               edge_serial->bulk_in_endpoint =
+                                       port0->bulk_in_endpointAddress;
                edge_serial->read_urb = port0->read_urb;
-               edge_serial->bulk_out_endpoint = port0->bulk_out_endpointAddress;
-       
+               edge_serial->bulk_out_endpoint =
+                                       port0->bulk_out_endpointAddress;
+
                /* set up our interrupt urb */
                usb_fill_int_urb(edge_serial->interrupt_read_urb,
-                                serial->dev,
-                                usb_rcvintpipe(serial->dev,
-                                               port0->interrupt_in_endpointAddress),
-                                port0->interrupt_in_buffer,
-                                edge_serial->interrupt_read_urb->transfer_buffer_length,
-                                edge_interrupt_callback, edge_serial,
-                                edge_serial->interrupt_read_urb->interval);
-               
+                     serial->dev,
+                     usb_rcvintpipe(serial->dev,
+                               port0->interrupt_in_endpointAddress),
+                     port0->interrupt_in_buffer,
+                     edge_serial->interrupt_read_urb->transfer_buffer_length,
+                     edge_interrupt_callback, edge_serial,
+                     edge_serial->interrupt_read_urb->interval);
+
                /* set up our bulk in urb */
                usb_fill_bulk_urb(edge_serial->read_urb, serial->dev,
-                                 usb_rcvbulkpipe(serial->dev,
-                                                 port0->bulk_in_endpointAddress),
-                                 port0->bulk_in_buffer,
-                                 edge_serial->read_urb->transfer_buffer_length,
-                                 edge_bulk_in_callback, edge_serial);
+                       usb_rcvbulkpipe(serial->dev,
+                               port0->bulk_in_endpointAddress),
+                       port0->bulk_in_buffer,
+                       edge_serial->read_urb->transfer_buffer_length,
+                       edge_bulk_in_callback, edge_serial);
                edge_serial->read_in_progress = false;
 
                /* start interrupt read for this edgeport
-                * this interrupt will continue as long as the edgeport is connected */
-               response = usb_submit_urb (edge_serial->interrupt_read_urb, GFP_KERNEL);
+                * this interrupt will continue as long
+                * as the edgeport is connected */
+               response = usb_submit_urb(edge_serial->interrupt_read_urb,
+                                                               GFP_KERNEL);
                if (response) {
-                       dev_err(&port->dev, "%s - Error %d submitting control urb\n", __func__, response);
+                       dev_err(&port->dev,
+                               "%s - Error %d submitting control urb\n",
+                                                       __func__, response);
                }
        }
-       
+
        /* initialize our wait queues */
        init_waitqueue_head(&edge_port->wait_open);
        init_waitqueue_head(&edge_port->wait_chase);
@@ -871,26 +924,29 @@ static int edge_open (struct usb_serial_port *port, struct file * filp)
        init_waitqueue_head(&edge_port->wait_command);
 
        /* initialize our icount structure */
-       memset (&(edge_port->icount), 0x00, sizeof(edge_port->icount));
+       memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount));
 
        /* initialize our port settings */
-       edge_port->txCredits            = 0;                    /* Can't send any data yet */
-       edge_port->shadowMCR            = MCR_MASTER_IE;        /* Must always set this bit to enable ints! */
+       edge_port->txCredits = 0;       /* Can't send any data yet */
+       /* Must always set this bit to enable ints! */
+       edge_port->shadowMCR = MCR_MASTER_IE;
        edge_port->chaseResponsePending = false;
 
        /* send a open port command */
        edge_port->openPending = true;
        edge_port->open        = false;
-       response = send_iosp_ext_cmd (edge_port, IOSP_CMD_OPEN_PORT, 0);
+       response = send_iosp_ext_cmd(edge_port, IOSP_CMD_OPEN_PORT, 0);
 
        if (response < 0) {
-               dev_err(&port->dev, "%s - error sending open port command\n", __func__);
+               dev_err(&port->dev, "%s - error sending open port command\n",
+                                                               __func__);
                edge_port->openPending = false;
                return -ENODEV;
        }
 
        /* now wait for the port to be completely opened */
-       wait_event_timeout(edge_port->wait_open, !edge_port->openPending, OPEN_TIMEOUT);
+       wait_event_timeout(edge_port->wait_open, !edge_port->openPending,
+                                                               OPEN_TIMEOUT);
 
        if (!edge_port->open) {
                /* open timed out */
@@ -904,25 +960,26 @@ static int edge_open (struct usb_serial_port *port, struct file * filp)
        edge_port->txfifo.tail  = 0;
        edge_port->txfifo.count = 0;
        edge_port->txfifo.size  = edge_port->maxTxCredits;
-       edge_port->txfifo.fifo  = kmalloc (edge_port->maxTxCredits, GFP_KERNEL);
+       edge_port->txfifo.fifo  = kmalloc(edge_port->maxTxCredits, GFP_KERNEL);
 
        if (!edge_port->txfifo.fifo) {
                dbg("%s - no memory", __func__);
-               edge_close (port, filp);
+               edge_close(tty, port, filp);
                return -ENOMEM;
        }
 
        /* Allocate a URB for the write */
-       edge_port->write_urb = usb_alloc_urb (0, GFP_KERNEL);
+       edge_port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
        edge_port->write_in_progress = false;
 
        if (!edge_port->write_urb) {
                dbg("%s - no memory", __func__);
-               edge_close (port, filp);
+               edge_close(tty, port, filp);
                return -ENOMEM;
        }
 
-       dbg("%s(%d) - Initialize TX fifo to %d bytes", __func__, port->number, edge_port->maxTxCredits);
+       dbg("%s(%d) - Initialize TX fifo to %d bytes",
+                       __func__, port->number, edge_port->maxTxCredits);
 
        dbg("%s exited", __func__);
 
@@ -948,27 +1005,28 @@ static void block_until_chase_response(struct edgeport_port *edge_port)
        int loop = 10;
 
        while (1) {
-               // Save Last credits
+               /* Save Last credits */
                lastCredits = edge_port->txCredits;
 
-               // Did we get our Chase response
+               /* Did we get our Chase response */
                if (!edge_port->chaseResponsePending) {
                        dbg("%s - Got Chase Response", __func__);
 
-                       // did we get all of our credit back?
-                       if (edge_port->txCredits == edge_port->maxTxCredits ) {
+                       /* did we get all of our credit back? */
+                       if (edge_port->txCredits == edge_port->maxTxCredits) {
                                dbg("%s - Got all credits", __func__);
                                return;
                        }
                }
 
-               // Block the thread for a while
-               prepare_to_wait(&edge_port->wait_chase, &wait, TASK_UNINTERRUPTIBLE);
+               /* Block the thread for a while */
+               prepare_to_wait(&edge_port->wait_chase, &wait,
+                                               TASK_UNINTERRUPTIBLE);
                schedule_timeout(timeout);
                finish_wait(&edge_port->wait_chase, &wait);
 
                if (lastCredits == edge_port->txCredits) {
-                       // No activity.. count down.
+                       /* No activity.. count down. */
                        loop--;
                        if (loop == 0) {
                                edge_port->chaseResponsePending = false;
@@ -976,8 +1034,9 @@ static void block_until_chase_response(struct edgeport_port *edge_port)
                                return;
                        }
                } else {
-                       // Reset timeout value back to 10 seconds
-                       dbg("%s - Last %d, Current %d", __func__, lastCredits, edge_port->txCredits);
+                       /* Reset timeout value back to 10 seconds */
+                       dbg("%s - Last %d, Current %d", __func__,
+                                       lastCredits, edge_port->txCredits);
                        loop = 10;
                }
        }
@@ -994,7 +1053,7 @@ static void block_until_chase_response(struct edgeport_port *edge_port)
  *             3. A timeout of 3 seconds without activity has expired
  *
  ************************************************************************/
-static void block_until_tx_empty (struct edgeport_port *edge_port)
+static void block_until_tx_empty(struct edgeport_port *edge_port)
 {
        DEFINE_WAIT(wait);
        struct TxFifo *fifo = &edge_port->txfifo;
@@ -1003,31 +1062,32 @@ static void block_until_tx_empty (struct edgeport_port *edge_port)
        int loop = 30;
 
        while (1) {
-               // Save Last count
+               /* Save Last count */
                lastCount = fifo->count;
 
-               // Is the Edgeport Buffer empty?
+               /* Is the Edgeport Buffer empty? */
                if (lastCount == 0) {
                        dbg("%s - TX Buffer Empty", __func__);
                        return;
                }
 
-               // Block the thread for a while
-               prepare_to_wait (&edge_port->wait_chase, &wait, TASK_UNINTERRUPTIBLE);
+               /* Block the thread for a while */
+               prepare_to_wait(&edge_port->wait_chase, &wait,
+                                               TASK_UNINTERRUPTIBLE);
                schedule_timeout(timeout);
                finish_wait(&edge_port->wait_chase, &wait);
 
                dbg("%s wait", __func__);
 
                if (lastCount == fifo->count) {
-                       // No activity.. count down.
+                       /* No activity.. count down. */
                        loop--;
                        if (loop == 0) {
                                dbg("%s - TIMEOUT", __func__);
                                return;
                        }
                } else {
-                       // Reset timeout value back to seconds
+                       /* Reset timeout value back to seconds */
                        loop = 30;
                }
        }
@@ -1038,20 +1098,21 @@ static void block_until_tx_empty (struct edgeport_port *edge_port)
  * edge_close
  *     this function is called by the tty driver when a port is closed
  *****************************************************************************/
-static void edge_close (struct usb_serial_port *port, struct file * filp)
+static void edge_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct edgeport_serial *edge_serial;
        struct edgeport_port *edge_port;
        int status;
 
        dbg("%s - port %d", __func__, port->number);
-                        
+
        edge_serial = usb_get_serial_data(port->serial);
        edge_port = usb_get_serial_port_data(port);
-       if ((edge_serial == NULL) || (edge_port == NULL))
+       if (edge_serial == NULL || edge_port == NULL)
                return;
-       
-       // block until tx is empty
+
+       /* block until tx is empty */
        block_until_tx_empty(edge_port);
 
        edge_port->closePending = true;
@@ -1063,13 +1124,12 @@ static void edge_close (struct usb_serial_port *port, struct file * filp)
                edge_port->chaseResponsePending = true;
 
                dbg("%s - Sending IOSP_CMD_CHASE_PORT", __func__);
-               status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0);
-               if (status == 0) {
-                       // block until chase finished
+               status = send_iosp_ext_cmd(edge_port, IOSP_CMD_CHASE_PORT, 0);
+               if (status == 0)
+                       /* block until chase finished */
                        block_until_chase_response(edge_port);
-               } else {
+               else
                        edge_port->chaseResponsePending = false;
-               }
        }
 
        if ((!edge_serial->is_epic) ||
@@ -1077,10 +1137,10 @@ static void edge_close (struct usb_serial_port *port, struct file * filp)
             (edge_serial->epic_descriptor.Supports.IOSPClose))) {
               /* close the port */
                dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __func__);
-               send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0);
+               send_iosp_ext_cmd(edge_port, IOSP_CMD_CLOSE_PORT, 0);
        }
 
-       //port->close = true;
+       /* port->close = true; */
        edge_port->closePending = false;
        edge_port->open = false;
        edge_port->openPending = false;
@@ -1088,7 +1148,8 @@ static void edge_close (struct usb_serial_port *port, struct file * filp)
        usb_kill_urb(edge_port->write_urb);
 
        if (edge_port->write_urb) {
-               /* if this urb had a transfer buffer already (old transfer) free it */
+               /* if this urb had a transfer buffer already
+                               (old transfer) free it */
                kfree(edge_port->write_urb->transfer_buffer);
                usb_free_urb(edge_port->write_urb);
                edge_port->write_urb = NULL;
@@ -1097,16 +1158,17 @@ static void edge_close (struct usb_serial_port *port, struct file * filp)
        edge_port->txfifo.fifo = NULL;
 
        dbg("%s exited", __func__);
-}   
+}
 
 /*****************************************************************************
  * SerialWrite
- *     this function is called by the tty driver when data should be written to
- *     the port.
- *     If successful, we return the number of bytes written, otherwise we return
- *     a negative error number.
+ *     this function is called by the tty driver when data should be written
+ *     to the port.
+ *     If successful, we return the number of bytes written, otherwise we
+ *     return a negative error number.
  *****************************************************************************/
-static int edge_write (struct usb_serial_port *port, const unsigned char *data, int count)
+static int edge_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                       const unsigned char *data, int count)
 {
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        struct TxFifo *fifo;
@@ -1121,66 +1183,76 @@ static int edge_write (struct usb_serial_port *port, const unsigned char *data,
        if (edge_port == NULL)
                return -ENODEV;
 
-       // get a pointer to the Tx fifo
+       /* get a pointer to the Tx fifo */
        fifo = &edge_port->txfifo;
 
        spin_lock_irqsave(&edge_port->ep_lock, flags);
 
-       // calculate number of bytes to put in fifo
-       copySize = min ((unsigned int)count, (edge_port->txCredits - fifo->count));
+       /* calculate number of bytes to put in fifo */
+       copySize = min((unsigned int)count,
+                               (edge_port->txCredits - fifo->count));
 
-       dbg("%s(%d) of %d byte(s) Fifo room  %d -- will copy %d bytes", __func__,
-           port->number, count, edge_port->txCredits - fifo->count, copySize);
+       dbg("%s(%d) of %d byte(s) Fifo room  %d -- will copy %d bytes",
+                       __func__, port->number, count,
+                       edge_port->txCredits - fifo->count, copySize);
 
-       /* catch writes of 0 bytes which the tty driver likes to give us, and when txCredits is empty */
+       /* catch writes of 0 bytes which the tty driver likes to give us,
+          and when txCredits is empty */
        if (copySize == 0) {
                dbg("%s - copySize = Zero", __func__);
                goto finish_write;
        }
 
-       // queue the data       
-       // since we can never overflow the buffer we do not have to check for full condition
-
-       // the copy is done is two parts -- first fill to the end of the buffer
-       // then copy the reset from the start of the buffer 
-
+       /* queue the data
+        * since we can never overflow the buffer we do not have to check for a
+        * full condition
+        *
+        * the copy is done is two parts -- first fill to the end of the buffer
+        * then copy the reset from the start of the buffer
+        */
        bytesleft = fifo->size - fifo->head;
-       firsthalf = min (bytesleft, copySize);
-       dbg("%s - copy %d bytes of %d into fifo ", __func__, firsthalf, bytesleft);
+       firsthalf = min(bytesleft, copySize);
+       dbg("%s - copy %d bytes of %d into fifo ", __func__,
+                                       firsthalf, bytesleft);
 
        /* now copy our data */
        memcpy(&fifo->fifo[fifo->head], data, firsthalf);
-       usb_serial_debug_data(debug, &port->dev, __func__, firsthalf, &fifo->fifo[fifo->head]);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                                       firsthalf, &fifo->fifo[fifo->head]);
 
-       // update the index and size
+       /* update the index and size */
        fifo->head  += firsthalf;
        fifo->count += firsthalf;
 
-       // wrap the index
-       if (fifo->head == fifo->size) {
+       /* wrap the index */
+       if (fifo->head == fifo->size)
                fifo->head = 0;
-       }
 
        secondhalf = copySize-firsthalf;
 
        if (secondhalf) {
                dbg("%s - copy rest of data %d", __func__, secondhalf);
                memcpy(&fifo->fifo[fifo->head], &data[firsthalf], secondhalf);
-               usb_serial_debug_data(debug, &port->dev, __func__, secondhalf, &fifo->fifo[fifo->head]);
-               // update the index and size
+               usb_serial_debug_data(debug, &port->dev, __func__,
+                                       secondhalf, &fifo->fifo[fifo->head]);
+               /* update the index and size */
                fifo->count += secondhalf;
                fifo->head  += secondhalf;
-               // No need to check for wrap since we can not get to end of fifo in this part
+               /* No need to check for wrap since we can not get to end of
+                * the fifo in this part
+                */
        }
 
 finish_write:
        spin_unlock_irqrestore(&edge_port->ep_lock, flags);
 
-       send_more_port_data((struct edgeport_serial *)usb_get_serial_data(port->serial), edge_port);
+       send_more_port_data((struct edgeport_serial *)
+                       usb_get_serial_data(port->serial), edge_port);
 
-       dbg("%s wrote %d byte(s) TxCredits %d, Fifo %d", __func__, copySize, edge_port->txCredits, fifo->count);
+       dbg("%s wrote %d byte(s) TxCredits %d, Fifo %d", __func__,
+                               copySize, edge_port->txCredits, fifo->count);
 
-       return copySize;   
+       return copySize;
 }
 
 
@@ -1197,7 +1269,8 @@ finish_write:
  *     can transmit more.
  *
  ************************************************************************/
-static void send_more_port_data(struct edgeport_serial *edge_serial, struct edgeport_port *edge_port)
+static void send_more_port_data(struct edgeport_serial *edge_serial,
+                                       struct edgeport_port *edge_port)
 {
        struct TxFifo   *fifo = &edge_port->txfifo;
        struct urb      *urb;
@@ -1216,67 +1289,78 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge
        if (edge_port->write_in_progress ||
            !edge_port->open             ||
            (fifo->count == 0)) {
-               dbg("%s(%d) EXIT - fifo %d, PendingWrite = %d", __func__, edge_port->port->number, fifo->count, edge_port->write_in_progress);
+               dbg("%s(%d) EXIT - fifo %d, PendingWrite = %d",
+                               __func__, edge_port->port->number,
+                               fifo->count, edge_port->write_in_progress);
                goto exit_send;
        }
 
-       // since the amount of data in the fifo will always fit into the
-       // edgeport buffer we do not need to check the write length
-
-       //      Do we have enough credits for this port to make it worthwhile
-       //      to bother queueing a write. If it's too small, say a few bytes,
-       //      it's better to wait for more credits so we can do a larger
-       //      write.
-       if (edge_port->txCredits < EDGE_FW_GET_TX_CREDITS_SEND_THRESHOLD(edge_port->maxTxCredits,EDGE_FW_BULK_MAX_PACKET_SIZE)) {
-               dbg("%s(%d) Not enough credit - fifo %d TxCredit %d", __func__, edge_port->port->number, fifo->count, edge_port->txCredits );
+       /* since the amount of data in the fifo will always fit into the
+        * edgeport buffer we do not need to check the write length
+        *
+        * Do we have enough credits for this port to make it worthwhile
+        * to bother queueing a write. If it's too small, say a few bytes,
+        * it's better to wait for more credits so we can do a larger write.
+        */
+       if (edge_port->txCredits < EDGE_FW_GET_TX_CREDITS_SEND_THRESHOLD(edge_port->maxTxCredits, EDGE_FW_BULK_MAX_PACKET_SIZE)) {
+               dbg("%s(%d) Not enough credit - fifo %d TxCredit %d",
+                       __func__, edge_port->port->number, fifo->count,
+                       edge_port->txCredits);
                goto exit_send;
        }
 
-       // lock this write
+       /* lock this write */
        edge_port->write_in_progress = true;
 
-       // get a pointer to the write_urb
+       /* get a pointer to the write_urb */
        urb = edge_port->write_urb;
 
        /* make sure transfer buffer is freed */
        kfree(urb->transfer_buffer);
        urb->transfer_buffer = NULL;
 
-       /* build the data header for the buffer and port that we are about to send out */
+       /* build the data header for the buffer and port that we are about
+          to send out */
        count = fifo->count;
-       buffer = kmalloc (count+2, GFP_ATOMIC);
+       buffer = kmalloc(count+2, GFP_ATOMIC);
        if (buffer == NULL) {
-               dev_err(&edge_port->port->dev, "%s - no more kernel memory...\n", __func__);
+               dev_err(&edge_port->port->dev,
+                               "%s - no more kernel memory...\n", __func__);
                edge_port->write_in_progress = false;
                goto exit_send;
        }
-       buffer[0] = IOSP_BUILD_DATA_HDR1 (edge_port->port->number - edge_port->port->serial->minor, count);
-       buffer[1] = IOSP_BUILD_DATA_HDR2 (edge_port->port->number - edge_port->port->serial->minor, count);
+       buffer[0] = IOSP_BUILD_DATA_HDR1(edge_port->port->number
+                               - edge_port->port->serial->minor, count);
+       buffer[1] = IOSP_BUILD_DATA_HDR2(edge_port->port->number
+                               - edge_port->port->serial->minor, count);
 
        /* now copy our data */
        bytesleft =  fifo->size - fifo->tail;
-       firsthalf = min (bytesleft, count);
+       firsthalf = min(bytesleft, count);
        memcpy(&buffer[2], &fifo->fifo[fifo->tail], firsthalf);
        fifo->tail  += firsthalf;
        fifo->count -= firsthalf;
-       if (fifo->tail == fifo->size) {
+       if (fifo->tail == fifo->size)
                fifo->tail = 0;
-       }
 
        secondhalf = count-firsthalf;
        if (secondhalf) {
-               memcpy(&buffer[2+firsthalf], &fifo->fifo[fifo->tail], secondhalf);
+               memcpy(&buffer[2+firsthalf], &fifo->fifo[fifo->tail],
+                                                               secondhalf);
                fifo->tail  += secondhalf;
                fifo->count -= secondhalf;
        }
 
        if (count)
-               usb_serial_debug_data(debug, &edge_port->port->dev, __func__, count, &buffer[2]);
+               usb_serial_debug_data(debug, &edge_port->port->dev,
+                                               __func__, count, &buffer[2]);
 
        /* fill up the urb with all of our data and submit it */
-       usb_fill_bulk_urb (urb, edge_serial->serial->dev, 
-                      usb_sndbulkpipe(edge_serial->serial->dev, edge_serial->bulk_out_endpoint),
-                      buffer, count+2, edge_bulk_out_data_callback, edge_port);
+       usb_fill_bulk_urb(urb, edge_serial->serial->dev,
+                       usb_sndbulkpipe(edge_serial->serial->dev,
+                                       edge_serial->bulk_out_endpoint),
+                       buffer, count+2,
+                       edge_bulk_out_data_callback, edge_port);
 
        /* decrement the number of credits we have by the number we just sent */
        edge_port->txCredits -= count;
@@ -1286,14 +1370,17 @@ static void send_more_port_data(struct edgeport_serial *edge_serial, struct edge
        status = usb_submit_urb(urb, GFP_ATOMIC);
        if (status) {
                /* something went wrong */
-               dev_err(&edge_port->port->dev, "%s - usb_submit_urb(write bulk) failed, status = %d, data lost\n", __func__, status);
+               dev_err(&edge_port->port->dev,
+                       "%s - usb_submit_urb(write bulk) failed, status = %d, data lost\n",
+                               __func__, status);
                edge_port->write_in_progress = false;
 
                /* revert the credits as something bad happened. */
                edge_port->txCredits += count;
                edge_port->icount.tx -= count;
        }
-       dbg("%s wrote %d byte(s) TxCredit %d, Fifo %d", __func__, count, edge_port->txCredits, fifo->count);
+       dbg("%s wrote %d byte(s) TxCredit %d, Fifo %d",
+                       __func__, count, edge_port->txCredits, fifo->count);
 
 exit_send:
        spin_unlock_irqrestore(&edge_port->ep_lock, flags);
@@ -1302,14 +1389,14 @@ exit_send:
 
 /*****************************************************************************
  * edge_write_room
- *     this function is called by the tty driver when it wants to know how many
- *     bytes of data we can accept for a specific port.
- *     If successful, we return the amount of room that we have for this port
- *     (the txCredits), 
- *     Otherwise we return a negative error number.
+ *     this function is called by the tty driver when it wants to know how
+ *     many bytes of data we can accept for a specific port. If successful,
+ *     we return the amount of room that we have for this port (the txCredits)
+ *     otherwise we return a negative error number.
  *****************************************************************************/
-static int edge_write_room (struct usb_serial_port *port)
+static int edge_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        int room;
        unsigned long flags;
@@ -1317,18 +1404,18 @@ static int edge_write_room (struct usb_serial_port *port)
        dbg("%s", __func__);
 
        if (edge_port == NULL)
-               return -ENODEV;
+               return 0;
        if (edge_port->closePending)
-               return -ENODEV;
+               return 0;
 
        dbg("%s - port %d", __func__, port->number);
 
        if (!edge_port->open) {
                dbg("%s - port not opened", __func__);
-               return -EINVAL;
+               return 0;
        }
 
-       // total of both buffers is still txCredit
+       /* total of both buffers is still txCredit */
        spin_lock_irqsave(&edge_port->ep_lock, flags);
        room = edge_port->txCredits - edge_port->txfifo.count;
        spin_unlock_irqrestore(&edge_port->ep_lock, flags);
@@ -1340,15 +1427,16 @@ static int edge_write_room (struct usb_serial_port *port)
 
 /*****************************************************************************
  * edge_chars_in_buffer
- *     this function is called by the tty driver when it wants to know how many
- *     bytes of data we currently have outstanding in the port (data that has
- *     been written, but hasn't made it out the port yet)
- *     If successful, we return the number of bytes left to be written in the 
- *     system, 
+ *     this function is called by the tty driver when it wants to know how
+ *     many bytes of data we currently have outstanding in the port (data that
+ *     has been written, but hasn't made it out the port yet)
+ *     If successful, we return the number of bytes left to be written in the
+ *     system,
  *     Otherwise we return a negative error number.
  *****************************************************************************/
-static int edge_chars_in_buffer (struct usb_serial_port *port)
+static int edge_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        int num_chars;
        unsigned long flags;
@@ -1356,20 +1444,22 @@ static int edge_chars_in_buffer (struct usb_serial_port *port)
        dbg("%s", __func__);
 
        if (edge_port == NULL)
-               return -ENODEV;
+               return 0;
        if (edge_port->closePending)
-               return -ENODEV;
+               return 0;
 
        if (!edge_port->open) {
                dbg("%s - port not opened", __func__);
-               return -EINVAL;
+               return 0;
        }
 
        spin_lock_irqsave(&edge_port->ep_lock, flags);
-       num_chars = edge_port->maxTxCredits - edge_port->txCredits + edge_port->txfifo.count;
+       num_chars = edge_port->maxTxCredits - edge_port->txCredits +
+                                               edge_port->txfifo.count;
        spin_unlock_irqrestore(&edge_port->ep_lock, flags);
        if (num_chars) {
-               dbg("%s(port %d) - returns %d", __func__, port->number, num_chars);
+               dbg("%s(port %d) - returns %d", __func__,
+                                               port->number, num_chars);
        }
 
        return num_chars;
@@ -1381,10 +1471,10 @@ static int edge_chars_in_buffer (struct usb_serial_port *port)
  *     this function is called by the tty driver when it wants to stop the data
  *     being read from the port.
  *****************************************************************************/
-static void edge_throttle (struct usb_serial_port *port)
+static void edge_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
-       struct tty_struct *tty;
        int status;
 
        dbg("%s - port %d", __func__, port->number);
@@ -1397,28 +1487,21 @@ static void edge_throttle (struct usb_serial_port *port)
                return;
        }
 
-       tty = port->tty;
-       if (!tty) {
-               dbg ("%s - no tty available", __func__);
-               return;
-       }
-
        /* if we are implementing XON/XOFF, send the stop character */
        if (I_IXOFF(tty)) {
                unsigned char stop_char = STOP_CHAR(tty);
-               status = edge_write (port, &stop_char, 1);
-               if (status <= 0) {
+               status = edge_write(tty, port, &stop_char, 1);
+               if (status <= 0)
                        return;
-               }
        }
 
        /* if we are implementing RTS/CTS, toggle that line */
        if (tty->termios->c_cflag & CRTSCTS) {
                edge_port->shadowMCR &= ~MCR_RTS;
-               status = send_cmd_write_uart_register(edge_port, MCR, edge_port->shadowMCR);
-               if (status != 0) {
+               status = send_cmd_write_uart_register(edge_port, MCR,
+                                                       edge_port->shadowMCR);
+               if (status != 0)
                        return;
-               }
        }
 
        return;
@@ -1427,13 +1510,13 @@ static void edge_throttle (struct usb_serial_port *port)
 
 /*****************************************************************************
  * edge_unthrottle
- *     this function is called by the tty driver when it wants to resume the data
- *     being read from the port (called after SerialThrottle is called)
+ *     this function is called by the tty driver when it wants to resume the
+ *     data being read from the port (called after SerialThrottle is called)
  *****************************************************************************/
-static void edge_unthrottle (struct usb_serial_port *port)
+static void edge_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
-       struct tty_struct *tty;
        int status;
 
        dbg("%s - port %d", __func__, port->number);
@@ -1446,43 +1529,31 @@ static void edge_unthrottle (struct usb_serial_port *port)
                return;
        }
 
-       tty = port->tty;
-       if (!tty) {
-               dbg ("%s - no tty available", __func__);
-               return;
-       }
-
        /* if we are implementing XON/XOFF, send the start character */
        if (I_IXOFF(tty)) {
                unsigned char start_char = START_CHAR(tty);
-               status = edge_write (port, &start_char, 1);
-               if (status <= 0) {
+               status = edge_write(tty, port, &start_char, 1);
+               if (status <= 0)
                        return;
-               }
        }
-
        /* if we are implementing RTS/CTS, toggle that line */
        if (tty->termios->c_cflag & CRTSCTS) {
                edge_port->shadowMCR |= MCR_RTS;
-               status = send_cmd_write_uart_register(edge_port, MCR, edge_port->shadowMCR);
-               if (status != 0) {
-                       return;
-               }
+               send_cmd_write_uart_register(edge_port, MCR,
+                                               edge_port->shadowMCR);
        }
-
-       return;
 }
 
 
 /*****************************************************************************
  * SerialSetTermios
- *     this function is called by the tty driver when it wants to change the termios structure
+ *     this function is called by the tty driver when it wants to change
+ * the termios structure
  *****************************************************************************/
-static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
+static void edge_set_termios(struct tty_struct *tty,
+       struct usb_serial_port *port, struct ktermios *old_termios)
 {
-       /* FIXME: This function appears unused ?? */
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
-       struct tty_struct *tty = port->tty;
        unsigned int cflag;
 
        cflag = tty->termios->c_cflag;
@@ -1502,9 +1573,7 @@ static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old
        }
 
        /* change the port settings to the new ones specified */
-       change_port_settings (edge_port, old_termios);
-
-       return;
+       change_port_settings(tty, edge_port, old_termios);
 }
 
 
@@ -1516,9 +1585,10 @@ static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old
  *         release the bus after transmitting. This must be done when
  *         the transmit shift register is empty, not be done when the
  *         transmit holding register is empty.  This functionality
- *         allows an RS485 driver to be written in user space. 
+ *         allows an RS485 driver to be written in user space.
  *****************************************************************************/
-static int get_lsr_info(struct edgeport_port *edge_port, unsigned int __user *value)
+static int get_lsr_info(struct edgeport_port *edge_port,
+                                               unsigned int __user *value)
 {
        unsigned int result = 0;
        unsigned long flags;
@@ -1536,25 +1606,10 @@ static int get_lsr_info(struct edgeport_port *edge_port, unsigned int __user *va
        return 0;
 }
 
-static int get_number_bytes_avail(struct edgeport_port *edge_port, unsigned int __user *value)
-{
-       unsigned int result = 0;
-       struct tty_struct *tty = edge_port->port->tty;
-
-       if (!tty)
-               return -ENOIOCTLCMD;
-
-       result = tty->read_cnt;
-
-       dbg("%s(%d) = %d", __func__,  edge_port->port->number, result);
-       if (copy_to_user(value, &result, sizeof(int)))
-               return -EFAULT;
-       //return 0;
-       return -ENOIOCTLCMD;
-}
-
-static int edge_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear)
+static int edge_tiocmset(struct tty_struct *tty, struct file *file,
+                                       unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        unsigned int mcr;
 
@@ -1582,8 +1637,9 @@ static int edge_tiocmset (struct usb_serial_port *port, struct file *file, unsig
        return 0;
 }
 
-static int edge_tiocmget(struct usb_serial_port *port, struct file *file)
+static int edge_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        unsigned int result = 0;
        unsigned int msr;
@@ -1606,7 +1662,8 @@ static int edge_tiocmget(struct usb_serial_port *port, struct file *file)
        return result;
 }
 
-static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct __user *retinfo)
+static int get_serial_info(struct edgeport_port *edge_port,
+                               struct serial_struct __user *retinfo)
 {
        struct serial_struct tmp;
 
@@ -1624,9 +1681,6 @@ static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct
        tmp.baud_base           = 9600;
        tmp.close_delay         = 5*HZ;
        tmp.closing_wait        = 30*HZ;
-//     tmp.custom_divisor      = state->custom_divisor;
-//     tmp.hub6                = state->hub6;
-//     tmp.io_type             = state->io_type;
 
        if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
                return -EFAULT;
@@ -1639,8 +1693,10 @@ static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct
  * SerialIoctl
  *     this function handles any ioctl calls to the driver
  *****************************************************************************/
-static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg)
+static int edge_ioctl(struct tty_struct *tty, struct file *file,
+                                       unsigned int cmd, unsigned long arg)
 {
+       struct usb_serial_port *port = tty->driver_data;
        DEFINE_WAIT(wait);
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        struct async_icount cnow;
@@ -1650,71 +1706,61 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned
        dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
 
        switch (cmd) {
-               // return number of bytes available
-               case TIOCINQ:
-                       dbg("%s (%d) TIOCINQ", __func__,  port->number);
-                       return get_number_bytes_avail(edge_port, (unsigned int __user *) arg);
-                       break;
-
-               case TIOCSERGETLSR:
-                       dbg("%s (%d) TIOCSERGETLSR", __func__,  port->number);
-                       return get_lsr_info(edge_port, (unsigned int __user *) arg);
-                       return 0;
-
-               case TIOCGSERIAL:
-                       dbg("%s (%d) TIOCGSERIAL", __func__,  port->number);
-                       return get_serial_info(edge_port, (struct serial_struct __user *) arg);
-
-               case TIOCSSERIAL:
-                       dbg("%s (%d) TIOCSSERIAL", __func__,  port->number);
-                       break;
-
-               case TIOCMIWAIT:
-                       dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
-                       cprev = edge_port->icount;
-                       while (1) {
-                               prepare_to_wait(&edge_port->delta_msr_wait, &wait, TASK_INTERRUPTIBLE);
-                               schedule();
-                               finish_wait(&edge_port->delta_msr_wait, &wait);
-                               /* see if a signal did it */
-                               if (signal_pending(current))
-                                       return -ERESTARTSYS;
-                               cnow = edge_port->icount;
-                               if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
-                                   cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
-                                       return -EIO; /* no change => error */
-                               if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
-                                   ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
-                                   ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
-                                   ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
-                                       return 0;
-                               }
-                               cprev = cnow;
+       case TIOCSERGETLSR:
+               dbg("%s (%d) TIOCSERGETLSR", __func__,  port->number);
+               return get_lsr_info(edge_port, (unsigned int __user *) arg);
+
+       case TIOCGSERIAL:
+               dbg("%s (%d) TIOCGSERIAL", __func__,  port->number);
+               return get_serial_info(edge_port, (struct serial_struct __user *) arg);
+
+       case TIOCMIWAIT:
+               dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
+               cprev = edge_port->icount;
+               while (1) {
+                       prepare_to_wait(&edge_port->delta_msr_wait,
+                                               &wait, TASK_INTERRUPTIBLE);
+                       schedule();
+                       finish_wait(&edge_port->delta_msr_wait, &wait);
+                       /* see if a signal did it */
+                       if (signal_pending(current))
+                               return -ERESTARTSYS;
+                       cnow = edge_port->icount;
+                       if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+                           cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+                               return -EIO; /* no change => error */
+                       if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+                           ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+                           ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+                           ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
+                               return 0;
                        }
-                       /* NOTREACHED */
-                       break;
+                       cprev = cnow;
+               }
+               /* NOTREACHED */
+               break;
 
-               case TIOCGICOUNT:
-                       cnow = edge_port->icount;
-                       memset(&icount, 0, sizeof(icount));
-                       icount.cts = cnow.cts;
-                       icount.dsr = cnow.dsr;
-                       icount.rng = cnow.rng;
-                       icount.dcd = cnow.dcd;
-                       icount.rx = cnow.rx;
-                       icount.tx = cnow.tx;
-                       icount.frame = cnow.frame;
-                       icount.overrun = cnow.overrun;
-                       icount.parity = cnow.parity;
-                       icount.brk = cnow.brk;
-                       icount.buf_overrun = cnow.buf_overrun;
-
-                       dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,  port->number, icount.rx, icount.tx );
-                       if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
-                               return -EFAULT;
-                       return 0;
+       case TIOCGICOUNT:
+               cnow = edge_port->icount;
+               memset(&icount, 0, sizeof(icount));
+               icount.cts = cnow.cts;
+               icount.dsr = cnow.dsr;
+               icount.rng = cnow.rng;
+               icount.dcd = cnow.dcd;
+               icount.rx = cnow.rx;
+               icount.tx = cnow.tx;
+               icount.frame = cnow.frame;
+               icount.overrun = cnow.overrun;
+               icount.parity = cnow.parity;
+               icount.brk = cnow.brk;
+               icount.buf_overrun = cnow.buf_overrun;
+
+               dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d",
+                               __func__,  port->number, icount.rx, icount.tx);
+               if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
+                       return -EFAULT;
+               return 0;
        }
-
        return -ENOIOCTLCMD;
 }
 
@@ -1723,8 +1769,9 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned
  * SerialBreak
  *     this function sends a break to the port
  *****************************************************************************/
-static void edge_break (struct usb_serial_port *port, int break_state)
+static void edge_break(struct tty_struct *tty, int break_state)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        struct edgeport_serial *edge_serial = usb_get_serial_data(port->serial);
        int status;
@@ -1736,9 +1783,9 @@ static void edge_break (struct usb_serial_port *port, int break_state)
                edge_port->chaseResponsePending = true;
 
                dbg("%s - Sending IOSP_CMD_CHASE_PORT", __func__);
-               status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0);
+               status = send_iosp_ext_cmd(edge_port, IOSP_CMD_CHASE_PORT, 0);
                if (status == 0) {
-                       // block until chase finished
+                       /* block until chase finished */
                        block_until_chase_response(edge_port);
                } else {
                        edge_port->chaseResponsePending = false;
@@ -1750,14 +1797,16 @@ static void edge_break (struct usb_serial_port *port, int break_state)
             (edge_serial->epic_descriptor.Supports.IOSPSetClrBreak))) {
                if (break_state == -1) {
                        dbg("%s - Sending IOSP_CMD_SET_BREAK", __func__);
-                       status = send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_BREAK, 0);
+                       status = send_iosp_ext_cmd(edge_port,
+                                               IOSP_CMD_SET_BREAK, 0);
                } else {
                        dbg("%s - Sending IOSP_CMD_CLEAR_BREAK", __func__);
-                       status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CLEAR_BREAK, 0);
-               }
-               if (status) {
-                       dbg("%s - error sending break set/clear command.", __func__);
+                       status = send_iosp_ext_cmd(edge_port,
+                                               IOSP_CMD_CLEAR_BREAK, 0);
                }
+               if (status)
+                       dbg("%s - error sending break set/clear command.",
+                               __func__);
        }
 
        return;
@@ -1768,7 +1817,8 @@ static void edge_break (struct usb_serial_port *port, int break_state)
  * process_rcvd_data
  *     this function handles the data received on the bulk in pipe.
  *****************************************************************************/
-static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned char * buffer, __u16 bufferLength)
+static void process_rcvd_data(struct edgeport_serial *edge_serial,
+                               unsigned char *buffer, __u16 bufferLength)
 {
        struct usb_serial_port *port;
        struct edgeport_port *edge_port;
@@ -1789,105 +1839,123 @@ static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned cha
                lastBufferLength = bufferLength;
 
                switch (edge_serial->rxState) {
-                       case EXPECT_HDR1:
-                               edge_serial->rxHeader1 = *buffer;
-                               ++buffer;
-                               --bufferLength;
+               case EXPECT_HDR1:
+                       edge_serial->rxHeader1 = *buffer;
+                       ++buffer;
+                       --bufferLength;
 
-                               if (bufferLength == 0) {
-                                       edge_serial->rxState = EXPECT_HDR2;
+                       if (bufferLength == 0) {
+                               edge_serial->rxState = EXPECT_HDR2;
+                               break;
+                       }
+                       /* otherwise, drop on through */
+               case EXPECT_HDR2:
+                       edge_serial->rxHeader2 = *buffer;
+                       ++buffer;
+                       --bufferLength;
+
+                       dbg("%s - Hdr1=%02X Hdr2=%02X", __func__,
+                           edge_serial->rxHeader1, edge_serial->rxHeader2);
+                       /* Process depending on whether this header is
+                        * data or status */
+
+                       if (IS_CMD_STAT_HDR(edge_serial->rxHeader1)) {
+                               /* Decode this status header and go to
+                                * EXPECT_HDR1 (if we can process the status
+                                * with only 2 bytes), or go to EXPECT_HDR3 to
+                                * get the third byte. */
+                               edge_serial->rxPort =
+                                   IOSP_GET_HDR_PORT(edge_serial->rxHeader1);
+                               edge_serial->rxStatusCode =
+                                   IOSP_GET_STATUS_CODE(
+                                               edge_serial->rxHeader1);
+
+                               if (!IOSP_STATUS_IS_2BYTE(
+                                               edge_serial->rxStatusCode)) {
+                                       /* This status needs additional bytes.
+                                        * Save what we have and then wait for
+                                        * more data.
+                                        */
+                                       edge_serial->rxStatusParam
+                                               = edge_serial->rxHeader2;
+                                       edge_serial->rxState = EXPECT_HDR3;
                                        break;
                                }
-                               /* otherwise, drop on through */
-
-                       case EXPECT_HDR2:
-                               edge_serial->rxHeader2 = *buffer;
-                               ++buffer;
-                               --bufferLength;
-
-                               dbg("%s - Hdr1=%02X Hdr2=%02X", __func__, edge_serial->rxHeader1, edge_serial->rxHeader2);
-
-                               // Process depending on whether this header is
-                               // data or status
-
-                               if (IS_CMD_STAT_HDR(edge_serial->rxHeader1)) {
-                                       // Decode this status header and goto EXPECT_HDR1 (if we
-                                       // can process the status with only 2 bytes), or goto
-                                       // EXPECT_HDR3 to get the third byte.
-
-                                       edge_serial->rxPort       = IOSP_GET_HDR_PORT(edge_serial->rxHeader1);
-                                       edge_serial->rxStatusCode = IOSP_GET_STATUS_CODE(edge_serial->rxHeader1);
-
-                                       if (!IOSP_STATUS_IS_2BYTE(edge_serial->rxStatusCode)) {
-                                               // This status needs additional bytes. Save what we have
-                                               // and then wait for more data.
-                                               edge_serial->rxStatusParam = edge_serial->rxHeader2;
-
-                                               edge_serial->rxState = EXPECT_HDR3;
-                                               break;
-                                       }
+                               /* We have all the header bytes, process the
+                                  status now */
+                               process_rcvd_status(edge_serial,
+                                               edge_serial->rxHeader2, 0);
+                               edge_serial->rxState = EXPECT_HDR1;
+                               break;
+                       } else {
+                               edge_serial->rxPort =
+                                   IOSP_GET_HDR_PORT(edge_serial->rxHeader1);
+                               edge_serial->rxBytesRemaining =
+                                   IOSP_GET_HDR_DATA_LEN(
+                                               edge_serial->rxHeader1,
+                                               edge_serial->rxHeader2);
+                               dbg("%s - Data for Port %u Len %u",
+                                               __func__,
+                                               edge_serial->rxPort,
+                                               edge_serial->rxBytesRemaining);
+
+                               /* ASSERT(DevExt->RxPort < DevExt->NumPorts);
+                                * ASSERT(DevExt->RxBytesRemaining <
+                                *              IOSP_MAX_DATA_LENGTH);
+                                */
 
-                                       // We have all the header bytes, process the status now
-                                       process_rcvd_status (edge_serial, edge_serial->rxHeader2, 0);
-                                       edge_serial->rxState = EXPECT_HDR1;
+                               if (bufferLength == 0) {
+                                       edge_serial->rxState = EXPECT_DATA;
                                        break;
-                               } else {
-                                       edge_serial->rxPort = IOSP_GET_HDR_PORT(edge_serial->rxHeader1);
-                                       edge_serial->rxBytesRemaining = IOSP_GET_HDR_DATA_LEN(edge_serial->rxHeader1, edge_serial->rxHeader2);
-
-                                       dbg("%s - Data for Port %u Len %u", __func__, edge_serial->rxPort, edge_serial->rxBytesRemaining);
-
-                                       //ASSERT( DevExt->RxPort < DevExt->NumPorts );
-                                       //ASSERT( DevExt->RxBytesRemaining < IOSP_MAX_DATA_LENGTH );
-
-                                       if (bufferLength == 0 ) {
-                                               edge_serial->rxState = EXPECT_DATA;
-                                               break;
-                                       }
-                                       // Else, drop through
                                }
+                               /* Else, drop through */
+                       }
+               case EXPECT_DATA: /* Expect data */
+                       if (bufferLength < edge_serial->rxBytesRemaining) {
+                               rxLen = bufferLength;
+                               /* Expect data to start next buffer */
+                               edge_serial->rxState = EXPECT_DATA;
+                       } else {
+                               /* BufLen >= RxBytesRemaining */
+                               rxLen = edge_serial->rxBytesRemaining;
+                               /* Start another header next time */
+                               edge_serial->rxState = EXPECT_HDR1;
+                       }
 
-                       case EXPECT_DATA:       // Expect data
-
-                               if (bufferLength < edge_serial->rxBytesRemaining) {
-                                       rxLen = bufferLength;
-                                       edge_serial->rxState = EXPECT_DATA;     // Expect data to start next buffer
-                               } else {
-                                       // BufLen >= RxBytesRemaining
-                                       rxLen = edge_serial->rxBytesRemaining;
-                                       edge_serial->rxState = EXPECT_HDR1;     // Start another header next time
-                               }
+                       bufferLength -= rxLen;
+                       edge_serial->rxBytesRemaining -= rxLen;
 
-                               bufferLength -= rxLen;
-                               edge_serial->rxBytesRemaining -= rxLen;
-
-                               /* spit this data back into the tty driver if this port is open */
-                               if (rxLen) {
-                                       port = edge_serial->serial->port[edge_serial->rxPort];
-                                       edge_port = usb_get_serial_port_data(port);
-                                       if (edge_port->open) {
-                                               tty = edge_port->port->tty;
-                                               if (tty) {
-                                                       dbg("%s - Sending %d bytes to TTY for port %d", __func__, rxLen, edge_serial->rxPort);
-                                                       edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen);
-                                               }
-                                               edge_port->icount.rx += rxLen;
+                       /* spit this data back into the tty driver if this
+                          port is open */
+                       if (rxLen) {
+                               port = edge_serial->serial->port[
+                                                       edge_serial->rxPort];
+                               edge_port = usb_get_serial_port_data(port);
+                               if (edge_port->open) {
+                                       tty = edge_port->port->port.tty;
+                                       if (tty) {
+                                               dbg("%s - Sending %d bytes to TTY for port %d",
+                                                       __func__, rxLen, edge_serial->rxPort);
+                                               edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen);
                                        }
-                                       buffer += rxLen;
+                                       edge_port->icount.rx += rxLen;
                                }
+                               buffer += rxLen;
+                       }
+                       break;
 
-                               break;
-
-                       case EXPECT_HDR3:                       // Expect 3rd byte of status header
-                               edge_serial->rxHeader3 = *buffer;
-                               ++buffer;
-                               --bufferLength;
-
-                               // We have all the header bytes, process the status now
-                               process_rcvd_status (edge_serial, edge_serial->rxStatusParam, edge_serial->rxHeader3);
-                               edge_serial->rxState = EXPECT_HDR1;
-                               break;
-
+               case EXPECT_HDR3:       /* Expect 3rd byte of status header */
+                       edge_serial->rxHeader3 = *buffer;
+                       ++buffer;
+                       --bufferLength;
+
+                       /* We have all the header bytes, process the
+                          status now */
+                       process_rcvd_status(edge_serial,
+                               edge_serial->rxStatusParam,
+                               edge_serial->rxHeader3);
+                       edge_serial->rxState = EXPECT_HDR1;
+                       break;
                }
        }
 }
@@ -1895,9 +1963,11 @@ static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned cha
 
 /*****************************************************************************
  * process_rcvd_status
- *     this function handles the any status messages received on the bulk in pipe.
+ *     this function handles the any status messages received on the
+ *     bulk in pipe.
  *****************************************************************************/
-static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2, __u8 byte3)
+static void process_rcvd_status(struct edgeport_serial *edge_serial,
+                                               __u8 byte2, __u8 byte3)
 {
        struct usb_serial_port *port;
        struct edgeport_port *edge_port;
@@ -1907,7 +1977,9 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2
        port = edge_serial->serial->port[edge_serial->rxPort];
        edge_port = usb_get_serial_port_data(port);
        if (edge_port == NULL) {
-               dev_err(&edge_serial->serial->dev->dev, "%s - edge_port == NULL for port %d\n", __func__, edge_serial->rxPort);
+               dev_err(&edge_serial->serial->dev->dev,
+                       "%s - edge_port == NULL for port %d\n",
+                                       __func__, edge_serial->rxPort);
                return;
        }
 
@@ -1915,22 +1987,28 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2
 
        if (code == IOSP_EXT_STATUS) {
                switch (byte2) {
-                       case IOSP_EXT_STATUS_CHASE_RSP:
-                               // we want to do EXT status regardless of port open/closed 
-                               dbg("%s - Port %u EXT CHASE_RSP Data = %02x", __func__, edge_serial->rxPort, byte3 );
-                               // Currently, the only EXT_STATUS is Chase, so process here instead of one more call
-                               // to one more subroutine. If/when more EXT_STATUS, there'll be more work to do.
-                               // Also, we currently clear flag and close the port regardless of content of above's Byte3.
-                               // We could choose to do something else when Byte3 says Timeout on Chase from Edgeport,
-                               // like wait longer in block_until_chase_response, but for now we don't. 
-                               edge_port->chaseResponsePending = false;
-                               wake_up (&edge_port->wait_chase);
-                               return;
+               case IOSP_EXT_STATUS_CHASE_RSP:
+                       /* we want to do EXT status regardless of port
+                        * open/closed */
+                       dbg("%s - Port %u EXT CHASE_RSP Data = %02x",
+                                       __func__, edge_serial->rxPort, byte3);
+                       /* Currently, the only EXT_STATUS is Chase, so process
+                        * here instead of one more call to one more subroutine
+                        * If/when more EXT_STATUS, there'll be more work to do
+                        * Also, we currently clear flag and close the port
+                        * regardless of content of above's Byte3.
+                        * We could choose to do something else when Byte3 says
+                        * Timeout on Chase from Edgeport, like wait longer in
+                        * block_until_chase_response, but for now we don't.
+                        */
+                       edge_port->chaseResponsePending = false;
+                       wake_up(&edge_port->wait_chase);
+                       return;
 
-                       case IOSP_EXT_STATUS_RX_CHECK_RSP:
-                               dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============\n", __func__, edge_serial->rxPort, byte3 );
-                               //Port->RxCheckRsp = true;
-                               return;
+               case IOSP_EXT_STATUS_RX_CHECK_RSP:
+                       dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============\n", __func__, edge_serial->rxPort, byte3);
+                       /* Port->RxCheckRsp = true; */
+                       return;
                }
        }
 
@@ -1938,11 +2016,14 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2
                edge_port->txCredits = GET_TX_BUFFER_SIZE(byte3);
                edge_port->maxTxCredits = edge_port->txCredits;
                dbg("%s - Port %u Open Response Inital MSR = %02x TxBufferSize = %d", __func__, edge_serial->rxPort, byte2, edge_port->txCredits);
-               handle_new_msr (edge_port, byte2);
+               handle_new_msr(edge_port, byte2);
 
-               /* send the current line settings to the port so we are in sync with any further termios calls */
-               if (edge_port->port->tty)
-                       change_port_settings (edge_port, edge_port->port->tty->termios);
+               /* send the current line settings to the port so we are
+                  in sync with any further termios calls */
+               /* FIXME: locking on tty */
+               if (edge_port->port->port.tty)
+                       change_port_settings(edge_port->port->port.tty,
+                               edge_port, edge_port->port->port.tty->termios);
 
                /* we have completed the open */
                edge_port->openPending = false;
@@ -1951,45 +2032,49 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2
                return;
        }
 
-       // If port is closed, silently discard all rcvd status. We can
-       // have cases where buffered status is received AFTER the close
-       // port command is sent to the Edgeport.
-       if (!edge_port->open || edge_port->closePending) {
+       /* If port is closed, silently discard all rcvd status. We can
+        * have cases where buffered status is received AFTER the close
+        * port command is sent to the Edgeport.
+        */
+       if (!edge_port->open || edge_port->closePending)
                return;
-       }
 
        switch (code) {
-               // Not currently sent by Edgeport
-               case IOSP_STATUS_LSR:
-                       dbg("%s - Port %u LSR Status = %02x", __func__, edge_serial->rxPort, byte2);
-                       handle_new_lsr(edge_port, false, byte2, 0);
-                       break;
+       /* Not currently sent by Edgeport */
+       case IOSP_STATUS_LSR:
+               dbg("%s - Port %u LSR Status = %02x",
+                                       __func__, edge_serial->rxPort, byte2);
+               handle_new_lsr(edge_port, false, byte2, 0);
+               break;
 
-               case IOSP_STATUS_LSR_DATA:
-                       dbg("%s - Port %u LSR Status = %02x, Data = %02x", __func__, edge_serial->rxPort, byte2, byte3);
-                       // byte2 is LSR Register
-                       // byte3 is broken data byte
-                       handle_new_lsr(edge_port, true, byte2, byte3);
-                       break;
-                       //
-                       //      case IOSP_EXT_4_STATUS:
-                       //              dbg("%s - Port %u LSR Status = %02x Data = %02x", __func__, edge_serial->rxPort, byte2, byte3);
-                       //              break;
-                       //
-               case IOSP_STATUS_MSR:
-                       dbg("%s - Port %u MSR Status = %02x", __func__, edge_serial->rxPort, byte2);
-
-                       // Process this new modem status and generate appropriate
-                       // events, etc, based on the new status. This routine
-                       // also saves the MSR in Port->ShadowMsr.
-                       handle_new_msr(edge_port, byte2);
-                       break;
+       case IOSP_STATUS_LSR_DATA:
+               dbg("%s - Port %u LSR Status = %02x, Data = %02x",
+                               __func__, edge_serial->rxPort, byte2, byte3);
+               /* byte2 is LSR Register */
+               /* byte3 is broken data byte */
+               handle_new_lsr(edge_port, true, byte2, byte3);
+               break;
+       /*
+        *      case IOSP_EXT_4_STATUS:
+        *              dbg("%s - Port %u LSR Status = %02x Data = %02x",
+        *                      __func__, edge_serial->rxPort, byte2, byte3);
+        *              break;
+        */
+       case IOSP_STATUS_MSR:
+               dbg("%s - Port %u MSR Status = %02x",
+                                       __func__, edge_serial->rxPort, byte2);
+               /*
+                * Process this new modem status and generate appropriate
+                * events, etc, based on the new status. This routine
+                * also saves the MSR in Port->ShadowMsr.
+                */
+               handle_new_msr(edge_port, byte2);
+               break;
 
-               default:
-                       dbg("%s - Unrecognized IOSP status code %u\n", __func__, code);
-                       break;
+       default:
+               dbg("%s - Unrecognized IOSP status code %u\n", __func__, code);
+               break;
        }
-
        return;
 }
 
@@ -1998,7 +2083,8 @@ static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2
  * edge_tty_recv
  *     this function passes data on to the tty flip buffer
  *****************************************************************************/
-static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length)
+static void edge_tty_recv(struct device *dev, struct tty_struct *tty,
+                                       unsigned char *data, int length)
 {
        int cnt;
 
@@ -2007,7 +2093,7 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c
                if (cnt < length) {
                        dev_err(dev, "%s - dropping data, %d bytes lost\n",
                                        __func__, length - cnt);
-                       if(cnt == 0)
+                       if (cnt == 0)
                                break;
                }
                tty_insert_flip_string(tty, data, cnt);
@@ -2029,22 +2115,19 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr)
 
        dbg("%s %02x", __func__, newMsr);
 
-       if (newMsr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR | EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) {
+       if (newMsr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR |
+                       EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) {
                icount = &edge_port->icount;
 
                /* update input line counters */
-               if (newMsr & EDGEPORT_MSR_DELTA_CTS) {
+               if (newMsr & EDGEPORT_MSR_DELTA_CTS)
                        icount->cts++;
-               }
-               if (newMsr & EDGEPORT_MSR_DELTA_DSR) {
+               if (newMsr & EDGEPORT_MSR_DELTA_DSR)
                        icount->dsr++;
-               }
-               if (newMsr & EDGEPORT_MSR_DELTA_CD) {
+               if (newMsr & EDGEPORT_MSR_DELTA_CD)
                        icount->dcd++;
-               }
-               if (newMsr & EDGEPORT_MSR_DELTA_RI) {
+               if (newMsr & EDGEPORT_MSR_DELTA_RI)
                        icount->rng++;
-               }
                wake_up_interruptible(&edge_port->delta_msr_wait);
        }
 
@@ -2059,42 +2142,41 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr)
  * handle_new_lsr
  *     this function handles any change to the lsr register for a port.
  *****************************************************************************/
-static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, __u8 lsr, __u8 data)
+static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData,
+                                                       __u8 lsr, __u8 data)
 {
-       __u8    newLsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK));
-       struct  async_icount *icount;
+       __u8 newLsr = (__u8) (lsr & (__u8)
+               (LSR_OVER_ERR | LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK));
+       struct async_icount *icount;
 
        dbg("%s - %02x", __func__, newLsr);
 
        edge_port->shadowLSR = lsr;
 
        if (newLsr & LSR_BREAK) {
-               //
-               // Parity and Framing errors only count if they
-               // occur exclusive of a break being
-               // received.
-               //
+               /*
+                * Parity and Framing errors only count if they
+                * occur exclusive of a break being
+                * received.
+                */
                newLsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK);
        }
 
        /* Place LSR data byte into Rx buffer */
-       if (lsrData && edge_port->port->tty)
-               edge_tty_recv(&edge_port->port->dev, edge_port->port->tty, &data, 1);
+       if (lsrData && edge_port->port->port.tty)
+               edge_tty_recv(&edge_port->port->dev,
+                                       edge_port->port->port.tty, &data, 1);
 
        /* update input line counters */
        icount = &edge_port->icount;
-       if (newLsr & LSR_BREAK) {
+       if (newLsr & LSR_BREAK)
                icount->brk++;
-       }
-       if (newLsr & LSR_OVER_ERR) {
+       if (newLsr & LSR_OVER_ERR)
                icount->overrun++;
-       }
-       if (newLsr & LSR_PAR_ERR) {
+       if (newLsr & LSR_PAR_ERR)
                icount->parity++;
-       }
-       if (newLsr & LSR_FRM_ERR) {
+       if (newLsr & LSR_FRM_ERR)
                icount->frame++;
-       }
 
        return;
 }
@@ -2102,12 +2184,13 @@ static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, __u8 l
 
 /****************************************************************************
  * sram_write
- *     writes a number of bytes to the Edgeport device's sram starting at the 
+ *     writes a number of bytes to the Edgeport device's sram starting at the
  *     given address.
  *     If successful returns the number of bytes written, otherwise it returns
  *     a negative error number of the problem.
  ****************************************************************************/
-static int sram_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __u8 *data)
+static int sram_write(struct usb_serial *serial, __u16 extAddr, __u16 addr,
+                                       __u16 length, const __u8 *data)
 {
        int result;
        __u16 current_length;
@@ -2115,32 +2198,37 @@ static int sram_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u1
 
        dbg("%s - %x, %x, %d", __func__, extAddr, addr, length);
 
-       transfer_buffer =  kmalloc (64, GFP_KERNEL);
+       transfer_buffer =  kmalloc(64, GFP_KERNEL);
        if (!transfer_buffer) {
-               dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __func__, 64);
+               dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n",
+                                                       __func__, 64);
                return -ENOMEM;
        }
 
        /* need to split these writes up into 64 byte chunks */
        result = 0;
        while (length > 0) {
-               if (length > 64) {
+               if (length > 64)
                        current_length = 64;
-               } else {
+               else
                        current_length = length;
-               }
-//             dbg("%s - writing %x, %x, %d", __func__, extAddr, addr, current_length);
-               memcpy (transfer_buffer, data, current_length);
-               result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), USB_REQUEST_ION_WRITE_RAM, 
-                                         0x40, addr, extAddr, transfer_buffer, current_length, 300);
+
+/*             dbg("%s - writing %x, %x, %d", __func__,
+                                       extAddr, addr, current_length); */
+               memcpy(transfer_buffer, data, current_length);
+               result = usb_control_msg(serial->dev,
+                                       usb_sndctrlpipe(serial->dev, 0),
+                                       USB_REQUEST_ION_WRITE_RAM,
+                                       0x40, addr, extAddr, transfer_buffer,
+                                       current_length, 300);
                if (result < 0)
                        break;
                length -= current_length;
                addr += current_length;
                data += current_length;
-       }       
+       }
 
-       kfree (transfer_buffer);
+       kfree(transfer_buffer);
        return result;
 }
 
@@ -2152,40 +2240,45 @@ static int sram_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u1
  *     If successful returns the number of bytes written, otherwise it returns
  *     a negative error number of the problem.
  ****************************************************************************/
-static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __u8 *data)
+static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr,
+                                       __u16 length, const __u8 *data)
 {
        int result;
        __u16 current_length;
        unsigned char *transfer_buffer;
 
-//     dbg("%s - %x, %x, %d", __func__, extAddr, addr, length);
+/*     dbg("%s - %x, %x, %d", __func__, extAddr, addr, length); */
 
-       transfer_buffer =  kmalloc (64, GFP_KERNEL);
+       transfer_buffer =  kmalloc(64, GFP_KERNEL);
        if (!transfer_buffer) {
-               dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __func__, 64);
+               dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n",
+                                                               __func__, 64);
                return -ENOMEM;
        }
 
        /* need to split these writes up into 64 byte chunks */
        result = 0;
        while (length > 0) {
-               if (length > 64) {
+               if (length > 64)
                        current_length = 64;
-               } else {
+               else
                        current_length = length;
-               }
-//             dbg("%s - writing %x, %x, %d", __func__, extAddr, addr, current_length);
-               memcpy (transfer_buffer, data, current_length);
-               result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), USB_REQUEST_ION_WRITE_ROM, 
-                                         0x40, addr, extAddr, transfer_buffer, current_length, 300);
+/*             dbg("%s - writing %x, %x, %d", __func__,
+                                       extAddr, addr, current_length); */
+               memcpy(transfer_buffer, data, current_length);
+               result = usb_control_msg(serial->dev,
+                                       usb_sndctrlpipe(serial->dev, 0),
+                                       USB_REQUEST_ION_WRITE_ROM, 0x40,
+                                       addr, extAddr,
+                                       transfer_buffer, current_length, 300);
                if (result < 0)
                        break;
                length -= current_length;
                addr += current_length;
                data += current_length;
-       }       
+       }
 
-       kfree (transfer_buffer);
+       kfree(transfer_buffer);
        return result;
 }
 
@@ -2197,7 +2290,8 @@ static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16
  *     If successful returns the number of bytes read, otherwise it returns
  *     a negative error number of the problem.
  ****************************************************************************/
-static int rom_read (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data)
+static int rom_read(struct usb_serial *serial, __u16 extAddr,
+                                       __u16 addr, __u16 length, __u8 *data)
 {
        int result;
        __u16 current_length;
@@ -2205,32 +2299,36 @@ static int rom_read (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16
 
        dbg("%s - %x, %x, %d", __func__, extAddr, addr, length);
 
-       transfer_buffer =  kmalloc (64, GFP_KERNEL);
+       transfer_buffer =  kmalloc(64, GFP_KERNEL);
        if (!transfer_buffer) {
-               dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __func__, 64);
+               dev_err(&serial->dev->dev,
+                       "%s - kmalloc(%d) failed.\n", __func__, 64);
                return -ENOMEM;
        }
 
        /* need to split these reads up into 64 byte chunks */
        result = 0;
        while (length > 0) {
-               if (length > 64) {
+               if (length > 64)
                        current_length = 64;
-               } else {
+               else
                        current_length = length;
-               }
-//             dbg("%s - %x, %x, %d", __func__, extAddr, addr, current_length);
-               result = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), USB_REQUEST_ION_READ_ROM, 
-                                         0xC0, addr, extAddr, transfer_buffer, current_length, 300);
+/*             dbg("%s - %x, %x, %d", __func__,
+                               extAddr, addr, current_length); */
+               result = usb_control_msg(serial->dev,
+                                       usb_rcvctrlpipe(serial->dev, 0),
+                                       USB_REQUEST_ION_READ_ROM,
+                                       0xC0, addr, extAddr, transfer_buffer,
+                                       current_length, 300);
                if (result < 0)
                        break;
-               memcpy (data, transfer_buffer, current_length);
+               memcpy(data, transfer_buffer, current_length);
                length -= current_length;
                addr += current_length;
                data += current_length;
-       }       
+       }
 
-       kfree (transfer_buffer);
+       kfree(transfer_buffer);
        return result;
 }
 
@@ -2239,7 +2337,8 @@ static int rom_read (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16
  * send_iosp_ext_cmd
  *     Is used to send a IOSP message to the Edgeport device
  ****************************************************************************/
-static int send_iosp_ext_cmd (struct edgeport_port *edge_port, __u8 command, __u8 param)
+static int send_iosp_ext_cmd(struct edgeport_port *edge_port,
+                                               __u8 command, __u8 param)
 {
        unsigned char   *buffer;
        unsigned char   *currentCommand;
@@ -2248,19 +2347,20 @@ static int send_iosp_ext_cmd (struct edgeport_port *edge_port, __u8 command, __u
 
        dbg("%s - %d, %d", __func__, command, param);
 
-       buffer =  kmalloc (10, GFP_ATOMIC);
+       buffer = kmalloc(10, GFP_ATOMIC);
        if (!buffer) {
-               dev_err(&edge_port->port->dev, "%s - kmalloc(%d) failed.\n", __func__, 10);
+               dev_err(&edge_port->port->dev,
+                               "%s - kmalloc(%d) failed.\n", __func__, 10);
                return -ENOMEM;
        }
 
        currentCommand = buffer;
 
-       MAKE_CMD_EXT_CMD (&currentCommand, &length,
-                         edge_port->port->number - edge_port->port->serial->minor,
-                         command, param);
+       MAKE_CMD_EXT_CMD(&currentCommand, &length,
+               edge_port->port->number - edge_port->port->serial->minor,
+               command, param);
 
-       status = write_cmd_usb (edge_port, buffer, length);
+       status = write_cmd_usb(edge_port, buffer, length);
        if (status) {
                /* something bad happened, let's free up the memory */
                kfree(buffer);
@@ -2274,43 +2374,50 @@ static int send_iosp_ext_cmd (struct edgeport_port *edge_port, __u8 command, __u
  * write_cmd_usb
  *     this function writes the given buffer out to the bulk write endpoint.
  *****************************************************************************/
-static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer, int length)
+static int write_cmd_usb(struct edgeport_port *edge_port,
+                                       unsigned char *buffer, int length)
 {
-       struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial);
+       struct edgeport_serial *edge_serial =
+                               usb_get_serial_data(edge_port->port->serial);
        int status = 0;
        struct urb *urb;
        int timeout;
 
-       usb_serial_debug_data(debug, &edge_port->port->dev, __func__, length, buffer);
+       usb_serial_debug_data(debug, &edge_port->port->dev,
+                                               __func__, length, buffer);
 
        /* Allocate our next urb */
-       urb = usb_alloc_urb (0, GFP_ATOMIC);
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!urb)
                return -ENOMEM;
 
        atomic_inc(&CmdUrbs);
-       dbg("%s - ALLOCATE URB %p (outstanding %d)", __func__, urb, atomic_read(&CmdUrbs));
+       dbg("%s - ALLOCATE URB %p (outstanding %d)",
+                               __func__, urb, atomic_read(&CmdUrbs));
 
-       usb_fill_bulk_urb (urb, edge_serial->serial->dev, 
-                      usb_sndbulkpipe(edge_serial->serial->dev, edge_serial->bulk_out_endpoint),
-                      buffer, length, edge_bulk_out_cmd_callback, edge_port);
+       usb_fill_bulk_urb(urb, edge_serial->serial->dev,
+                       usb_sndbulkpipe(edge_serial->serial->dev,
+                                       edge_serial->bulk_out_endpoint),
+                       buffer, length, edge_bulk_out_cmd_callback, edge_port);
 
        edge_port->commandPending = true;
        status = usb_submit_urb(urb, GFP_ATOMIC);
 
        if (status) {
                /* something went wrong */
-               dev_err(&edge_port->port->dev, "%s - usb_submit_urb(write command) failed, status = %d\n", __func__, status);
+               dev_err(&edge_port->port->dev,
+                   "%s - usb_submit_urb(write command) failed, status = %d\n",
+                                                       __func__, status);
                usb_kill_urb(urb);
                usb_free_urb(urb);
                atomic_dec(&CmdUrbs);
                return status;
        }
 
-       // wait for command to finish
+       /* wait for command to finish */
        timeout = COMMAND_TIMEOUT;
 #if 0
-       wait_event (&edge_port->wait_command, !edge_port->commandPending);
+       wait_event(&edge_port->wait_command, !edge_port->commandPending);
 
        if (edge_port->commandPending) {
                /* command timed out */
@@ -2327,15 +2434,18 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer
  *     this function sends the proper command to change the baud rate of the
  *     specified port.
  *****************************************************************************/
-static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRate)
+static int send_cmd_write_baud_rate(struct edgeport_port *edge_port,
+                                                               int baudRate)
 {
-       struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial);
+       struct edgeport_serial *edge_serial =
+                               usb_get_serial_data(edge_port->port->serial);
        unsigned char *cmdBuffer;
        unsigned char *currCmd;
        int cmdLen = 0;
        int divisor;
        int status;
-       unsigned char number = edge_port->port->number - edge_port->port->serial->minor;
+       unsigned char number =
+               edge_port->port->number - edge_port->port->serial->minor;
 
        if (edge_serial->is_epic &&
            !edge_serial->epic_descriptor.Supports.IOSPSetBaudRate) {
@@ -2344,36 +2454,40 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa
                return 0;
        }
 
-       dbg("%s - port = %d, baud = %d", __func__, edge_port->port->number, baudRate);
+       dbg("%s - port = %d, baud = %d", __func__,
+                                       edge_port->port->number, baudRate);
 
-       status = calc_baud_rate_divisor (baudRate, &divisor);
+       status = calc_baud_rate_divisor(baudRate, &divisor);
        if (status) {
-               dev_err(&edge_port->port->dev, "%s - bad baud rate\n", __func__);
+               dev_err(&edge_port->port->dev, "%s - bad baud rate\n",
+                                                               __func__);
                return status;
        }
 
-       // Alloc memory for the string of commands.
-       cmdBuffer =  kmalloc (0x100, GFP_ATOMIC);
+       /* Alloc memory for the string of commands. */
+       cmdBuffer =  kmalloc(0x100, GFP_ATOMIC);
        if (!cmdBuffer) {
-               dev_err(&edge_port->port->dev, "%s - kmalloc(%d) failed.\n", __func__, 0x100);
+               dev_err(&edge_port->port->dev,
+                       "%s - kmalloc(%d) failed.\n", __func__, 0x100);
                return -ENOMEM;
        }
        currCmd = cmdBuffer;
 
-       // Enable access to divisor latch
-       MAKE_CMD_WRITE_REG( &currCmd, &cmdLen, number, LCR, LCR_DL_ENABLE );
+       /* Enable access to divisor latch */
+       MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, number, LCR, LCR_DL_ENABLE);
 
-       // Write the divisor itself
-       MAKE_CMD_WRITE_REG( &currCmd, &cmdLen, number, DLL, LOW8 (divisor) );
-       MAKE_CMD_WRITE_REG( &currCmd, &cmdLen, number, DLM, HIGH8(divisor) );
+       /* Write the divisor itself */
+       MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, number, DLL, LOW8(divisor));
+       MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, number, DLM, HIGH8(divisor));
 
-       // Restore original value to disable access to divisor latch
-       MAKE_CMD_WRITE_REG( &currCmd, &cmdLen, number, LCR, edge_port->shadowLCR);
+       /* Restore original value to disable access to divisor latch */
+       MAKE_CMD_WRITE_REG(&currCmd, &cmdLen, number, LCR,
+                                               edge_port->shadowLCR);
 
-       status = write_cmd_usb(edge_port, cmdBuffer, cmdLen );
+       status = write_cmd_usb(edge_port, cmdBuffer, cmdLen);
        if (status) {
                /* something bad happened, let's free up the memory */
-               kfree (cmdBuffer);
+               kfree(cmdBuffer);
        }
 
        return status;
@@ -2385,7 +2499,7 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa
  *     this function calculates the proper baud rate divisor for the specified
  *     baud rate.
  *****************************************************************************/
-static int calc_baud_rate_divisor (int baudrate, int *divisor)
+static int calc_baud_rate_divisor(int baudrate, int *divisor)
 {
        int i;
        __u16 custom;
@@ -2394,17 +2508,17 @@ static int calc_baud_rate_divisor (int baudrate, int *divisor)
        dbg("%s - %d", __func__, baudrate);
 
        for (i = 0; i < ARRAY_SIZE(divisor_table); i++) {
-               if ( divisor_table[i].BaudRate == baudrate ) {
+               if (divisor_table[i].BaudRate == baudrate) {
                        *divisor = divisor_table[i].Divisor;
                        return 0;
                }
        }
 
-       // We have tried all of the standard baud rates
-       // lets try to calculate the divisor for this baud rate
-       // Make sure the baud rate is reasonable
+       /* We have tried all of the standard baud rates
+        * lets try to calculate the divisor for this baud rate
+        * Make sure the baud rate is reasonable */
        if (baudrate > 50 && baudrate < 230400) {
-               // get divisor
+               /* get divisor */
                custom = (__u16)((230400L + baudrate/2) / baudrate);
 
                *divisor = custom;
@@ -2419,17 +2533,20 @@ static int calc_baud_rate_divisor (int baudrate, int *divisor)
 
 /*****************************************************************************
  * send_cmd_write_uart_register
- *     this function builds up a uart register message and sends to to the device.
+ *  this function builds up a uart register message and sends to to the device.
  *****************************************************************************/
-static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue)
+static int send_cmd_write_uart_register(struct edgeport_port *edge_port,
+                                               __u8 regNum, __u8 regValue)
 {
-       struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial);
+       struct edgeport_serial *edge_serial =
+                               usb_get_serial_data(edge_port->port->serial);
        unsigned char *cmdBuffer;
        unsigned char *currCmd;
        unsigned long cmdLen = 0;
        int status;
 
-       dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __func__, regValue);
+       dbg("%s - write to %s register 0x%02x",
+                       (regNum == MCR) ? "MCR" : "LCR", __func__, regValue);
 
        if (edge_serial->is_epic &&
            !edge_serial->epic_descriptor.Supports.IOSPWriteMCR &&
@@ -2441,27 +2558,26 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r
        if (edge_serial->is_epic &&
            !edge_serial->epic_descriptor.Supports.IOSPWriteLCR &&
            regNum == LCR) {
-               dbg ("SendCmdWriteUartReg - Not writing to LCR Register");
+               dbg("SendCmdWriteUartReg - Not writing to LCR Register");
                return 0;
        }
 
-       // Alloc memory for the string of commands.
-       cmdBuffer = kmalloc (0x10, GFP_ATOMIC);
-       if (cmdBuffer == NULL ) {
+       /* Alloc memory for the string of commands. */
+       cmdBuffer = kmalloc(0x10, GFP_ATOMIC);
+       if (cmdBuffer == NULL)
                return -ENOMEM;
-       }
 
        currCmd = cmdBuffer;
 
-       // Build a cmd in the buffer to write the given register
-       MAKE_CMD_WRITE_REG (&currCmd, &cmdLen,
-                           edge_port->port->number - edge_port->port->serial->minor,
-                           regNum, regValue);
+       /* Build a cmd in the buffer to write the given register */
+       MAKE_CMD_WRITE_REG(&currCmd, &cmdLen,
+               edge_port->port->number - edge_port->port->serial->minor,
+               regNum, regValue);
 
        status = write_cmd_usb(edge_port, cmdBuffer, cmdLen);
        if (status) {
                /* something bad happened, let's free up the memory */
-               kfree (cmdBuffer);
+               kfree(cmdBuffer);
        }
 
        return status;
@@ -2470,16 +2586,15 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r
 
 /*****************************************************************************
  * change_port_settings
- *     This routine is called to set the UART on the device to match the specified
- *     new settings.
+ *     This routine is called to set the UART on the device to match the
+ *     specified new settings.
  *****************************************************************************/
-#ifndef CMSPAR
-#define CMSPAR 0
-#endif
-static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios)
+
+static void change_port_settings(struct tty_struct *tty,
+       struct edgeport_port *edge_port, struct ktermios *old_termios)
 {
-       struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial);
-       struct tty_struct *tty;
+       struct edgeport_serial *edge_serial =
+                       usb_get_serial_data(edge_port->port->serial);
        int baud;
        unsigned cflag;
        __u8 mask = 0xff;
@@ -2498,21 +2613,26 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
                return;
        }
 
-       tty = edge_port->port->tty;
-       if ((!tty) ||
-           (!tty->termios)) {
-               dbg("%s - no tty structures", __func__);
-               return;
-       }
-
        cflag = tty->termios->c_cflag;
 
        switch (cflag & CSIZE) {
-               case CS5:   lData = LCR_BITS_5; mask = 0x1f;    dbg("%s - data bits = 5", __func__);   break;
-               case CS6:   lData = LCR_BITS_6; mask = 0x3f;    dbg("%s - data bits = 6", __func__);   break;
-               case CS7:   lData = LCR_BITS_7; mask = 0x7f;    dbg("%s - data bits = 7", __func__);   break;
-               default:
-               case CS8:   lData = LCR_BITS_8;                 dbg("%s - data bits = 8", __func__);   break;
+       case CS5:
+               lData = LCR_BITS_5; mask = 0x1f;
+               dbg("%s - data bits = 5", __func__);
+               break;
+       case CS6:
+               lData = LCR_BITS_6; mask = 0x3f;
+               dbg("%s - data bits = 6", __func__);
+               break;
+       case CS7:
+               lData = LCR_BITS_7; mask = 0x7f;
+               dbg("%s - data bits = 7", __func__);
+               break;
+       default:
+       case CS8:
+               lData = LCR_BITS_8;
+               dbg("%s - data bits = 8", __func__);
+               break;
        }
 
        lParity = LCR_PAR_NONE;
@@ -2554,7 +2674,8 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
                dbg("%s - RTS/CTS is disabled", __func__);
        }
 
-       /* if we are implementing XON/XOFF, set the start and stop character in the device */
+       /* if we are implementing XON/XOFF, set the start and stop character
+          in the device */
        if (I_IXOFF(tty) || I_IXON(tty)) {
                unsigned char stop_char  = STOP_CHAR(tty);
                unsigned char start_char = START_CHAR(tty);
@@ -2562,14 +2683,17 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
                if ((!edge_serial->is_epic) ||
                    ((edge_serial->is_epic) &&
                     (edge_serial->epic_descriptor.Supports.IOSPSetXChar))) {
-                       send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XON_CHAR, start_char);
-                       send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XOFF_CHAR, stop_char);
+                       send_iosp_ext_cmd(edge_port,
+                                       IOSP_CMD_SET_XON_CHAR, start_char);
+                       send_iosp_ext_cmd(edge_port,
+                                       IOSP_CMD_SET_XOFF_CHAR, stop_char);
                }
 
                /* if we are implementing INBOUND XON/XOFF */
                if (I_IXOFF(tty)) {
                        rxFlow |= IOSP_RX_FLOW_XON_XOFF;
-                       dbg("%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", __func__, start_char, stop_char);
+                       dbg("%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x",
+                                       __func__, start_char, stop_char);
                } else {
                        dbg("%s - INBOUND XON/XOFF is disabled", __func__);
                }
@@ -2577,7 +2701,8 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
                /* if we are implementing OUTBOUND XON/XOFF */
                if (I_IXON(tty)) {
                        txFlow |= IOSP_TX_FLOW_XON_XOFF;
-                       dbg("%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", __func__, start_char, stop_char);
+                       dbg("%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x",
+                                       __func__, start_char, stop_char);
                } else {
                        dbg("%s - OUTBOUND XON/XOFF is disabled", __func__);
                }
@@ -2600,20 +2725,20 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
        edge_port->validDataMask = mask;
 
        /* Send the updated LCR value to the EdgePort */
-       status = send_cmd_write_uart_register(edge_port, LCR, edge_port->shadowLCR);
-       if (status != 0) {
+       status = send_cmd_write_uart_register(edge_port, LCR,
+                                                       edge_port->shadowLCR);
+       if (status != 0)
                return;
-       }
 
        /* set up the MCR register and send it to the EdgePort */
        edge_port->shadowMCR = MCR_MASTER_IE;
-       if (cflag & CBAUD) {
+       if (cflag & CBAUD)
                edge_port->shadowMCR |= (MCR_DTR | MCR_RTS);
-       }
-       status = send_cmd_write_uart_register(edge_port, MCR, edge_port->shadowMCR);
-       if (status != 0) {
+
+       status = send_cmd_write_uart_register(edge_port, MCR,
+                                               edge_port->shadowMCR);
+       if (status != 0)
                return;
-       }
 
        /* Determine divisor based on baud rate */
        baud = tty_get_baud_rate(tty);
@@ -2623,7 +2748,7 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
        }
 
        dbg("%s - baud rate = %d", __func__, baud);
-       status = send_cmd_write_baud_rate (edge_port, baud);
+       status = send_cmd_write_baud_rate(edge_port, baud);
        if (status == -1) {
                /* Speed change was not possible - put back the old speed */
                baud = tty_termios_baud_rate(old_termios);
@@ -2640,7 +2765,8 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
  *     ASCII range, but it's only for debugging...
  *     NOTE: expects the unicode in LE format
  ****************************************************************************/
-static void unicode_to_ascii(char *string, int buflen, __le16 *unicode, int unicode_size)
+static void unicode_to_ascii(char *string, int buflen,
+                                       __le16 *unicode, int unicode_size)
 {
        int i;
 
@@ -2659,75 +2785,99 @@ static void unicode_to_ascii(char *string, int buflen, __le16 *unicode, int unic
 
 /****************************************************************************
  * get_manufacturing_desc
- *     reads in the manufacturing descriptor and stores it into the serial 
+ *     reads in the manufacturing descriptor and stores it into the serial
  *     structure.
  ****************************************************************************/
-static void get_manufacturing_desc (struct edgeport_serial *edge_serial)
+static void get_manufacturing_desc(struct edgeport_serial *edge_serial)
 {
        int response;
 
        dbg("getting manufacturer descriptor");
 
-       response = rom_read (edge_serial->serial, (EDGE_MANUF_DESC_ADDR & 0xffff0000) >> 16, 
-                           (__u16)(EDGE_MANUF_DESC_ADDR & 0x0000ffff), EDGE_MANUF_DESC_LEN,
-                           (__u8 *)(&edge_serial->manuf_descriptor));
+       response = rom_read(edge_serial->serial,
+                               (EDGE_MANUF_DESC_ADDR & 0xffff0000) >> 16,
+                               (__u16)(EDGE_MANUF_DESC_ADDR & 0x0000ffff),
+                               EDGE_MANUF_DESC_LEN,
+                               (__u8 *)(&edge_serial->manuf_descriptor));
 
-       if (response < 1) {
-               dev_err(&edge_serial->serial->dev->dev, "error in getting manufacturer descriptor\n");
-       } else {
+       if (response < 1)
+               dev_err(&edge_serial->serial->dev->dev,
+                       "error in getting manufacturer descriptor\n");
+       else {
                char string[30];
                dbg("**Manufacturer Descriptor");
-               dbg("  RomSize:        %dK", edge_serial->manuf_descriptor.RomSize);
-               dbg("  RamSize:        %dK", edge_serial->manuf_descriptor.RamSize);
-               dbg("  CpuRev:         %d", edge_serial->manuf_descriptor.CpuRev);
-               dbg("  BoardRev:       %d", edge_serial->manuf_descriptor.BoardRev);
-               dbg("  NumPorts:       %d", edge_serial->manuf_descriptor.NumPorts);
-               dbg("  DescDate:       %d/%d/%d", edge_serial->manuf_descriptor.DescDate[0], edge_serial->manuf_descriptor.DescDate[1], edge_serial->manuf_descriptor.DescDate[2]+1900);
+               dbg("  RomSize:        %dK",
+                       edge_serial->manuf_descriptor.RomSize);
+               dbg("  RamSize:        %dK",
+                       edge_serial->manuf_descriptor.RamSize);
+               dbg("  CpuRev:         %d",
+                       edge_serial->manuf_descriptor.CpuRev);
+               dbg("  BoardRev:       %d",
+                       edge_serial->manuf_descriptor.BoardRev);
+               dbg("  NumPorts:       %d",
+                       edge_serial->manuf_descriptor.NumPorts);
+               dbg("  DescDate:       %d/%d/%d",
+                       edge_serial->manuf_descriptor.DescDate[0],
+                       edge_serial->manuf_descriptor.DescDate[1],
+                       edge_serial->manuf_descriptor.DescDate[2]+1900);
                unicode_to_ascii(string, sizeof(string),
-                   edge_serial->manuf_descriptor.SerialNumber,
-                   edge_serial->manuf_descriptor.SerNumLength/2);
+                       edge_serial->manuf_descriptor.SerialNumber,
+                       edge_serial->manuf_descriptor.SerNumLength/2);
                dbg("  SerialNumber: %s", string);
                unicode_to_ascii(string, sizeof(string),
-                   edge_serial->manuf_descriptor.AssemblyNumber,
-                   edge_serial->manuf_descriptor.AssemblyNumLength/2);
+                       edge_serial->manuf_descriptor.AssemblyNumber,
+                       edge_serial->manuf_descriptor.AssemblyNumLength/2);
                dbg("  AssemblyNumber: %s", string);
                unicode_to_ascii(string, sizeof(string),
                    edge_serial->manuf_descriptor.OemAssyNumber,
                    edge_serial->manuf_descriptor.OemAssyNumLength/2);
                dbg("  OemAssyNumber:  %s", string);
-               dbg("  UartType:       %d", edge_serial->manuf_descriptor.UartType);
-               dbg("  IonPid:         %d", edge_serial->manuf_descriptor.IonPid);
-               dbg("  IonConfig:      %d", edge_serial->manuf_descriptor.IonConfig);
+               dbg("  UartType:       %d",
+                       edge_serial->manuf_descriptor.UartType);
+               dbg("  IonPid:         %d",
+                       edge_serial->manuf_descriptor.IonPid);
+               dbg("  IonConfig:      %d",
+                       edge_serial->manuf_descriptor.IonConfig);
        }
 }
 
 
 /****************************************************************************
  * get_boot_desc
- *     reads in the bootloader descriptor and stores it into the serial 
+ *     reads in the bootloader descriptor and stores it into the serial
  *     structure.
  ****************************************************************************/
-static void get_boot_desc (struct edgeport_serial *edge_serial)
+static void get_boot_desc(struct edgeport_serial *edge_serial)
 {
        int response;
 
        dbg("getting boot descriptor");
 
-       response = rom_read (edge_serial->serial, (EDGE_BOOT_DESC_ADDR & 0xffff0000) >> 16, 
-                           (__u16)(EDGE_BOOT_DESC_ADDR & 0x0000ffff), EDGE_BOOT_DESC_LEN,
-                           (__u8 *)(&edge_serial->boot_descriptor));
+       response = rom_read(edge_serial->serial,
+                               (EDGE_BOOT_DESC_ADDR & 0xffff0000) >> 16,
+                               (__u16)(EDGE_BOOT_DESC_ADDR & 0x0000ffff),
+                               EDGE_BOOT_DESC_LEN,
+                               (__u8 *)(&edge_serial->boot_descriptor));
 
-       if (response < 1) {
-               dev_err(&edge_serial->serial->dev->dev, "error in getting boot descriptor\n");
-       } else {
+       if (response < 1)
+               dev_err(&edge_serial->serial->dev->dev,
+                               "error in getting boot descriptor\n");
+       else {
                dbg("**Boot Descriptor:");
-               dbg("  BootCodeLength: %d", le16_to_cpu(edge_serial->boot_descriptor.BootCodeLength));
-               dbg("  MajorVersion:   %d", edge_serial->boot_descriptor.MajorVersion);
-               dbg("  MinorVersion:   %d", edge_serial->boot_descriptor.MinorVersion);
-               dbg("  BuildNumber:    %d", le16_to_cpu(edge_serial->boot_descriptor.BuildNumber));
-               dbg("  Capabilities:   0x%x", le16_to_cpu(edge_serial->boot_descriptor.Capabilities));
-               dbg("  UConfig0:       %d", edge_serial->boot_descriptor.UConfig0);
-               dbg("  UConfig1:       %d", edge_serial->boot_descriptor.UConfig1);
+               dbg("  BootCodeLength: %d",
+                   le16_to_cpu(edge_serial->boot_descriptor.BootCodeLength));
+               dbg("  MajorVersion:   %d",
+                       edge_serial->boot_descriptor.MajorVersion);
+               dbg("  MinorVersion:   %d",
+                       edge_serial->boot_descriptor.MinorVersion);
+               dbg("  BuildNumber:    %d",
+                       le16_to_cpu(edge_serial->boot_descriptor.BuildNumber));
+               dbg("  Capabilities:   0x%x",
+                     le16_to_cpu(edge_serial->boot_descriptor.Capabilities));
+               dbg("  UConfig0:       %d",
+                       edge_serial->boot_descriptor.UConfig0);
+               dbg("  UConfig1:       %d",
+                       edge_serial->boot_descriptor.UConfig1);
        }
 }
 
@@ -2736,7 +2886,7 @@ static void get_boot_desc (struct edgeport_serial *edge_serial)
  * load_application_firmware
  *     This is called to load the application firmware to the device
  ****************************************************************************/
-static void load_application_firmware (struct edgeport_serial *edge_serial)
+static void load_application_firmware(struct edgeport_serial *edge_serial)
 {
        const struct ihex_binrec *rec;
        const struct firmware *fw;
@@ -2813,7 +2963,7 @@ static void load_application_firmware (struct edgeport_serial *edge_serial)
 /****************************************************************************
  * edge_startup
  ****************************************************************************/
-static int edge_startup (struct usb_serial *serial)
+static int edge_startup(struct usb_serial *serial)
 {
        struct edgeport_serial *edge_serial;
        struct edgeport_port *edge_port;
@@ -2855,10 +3005,10 @@ static int edge_startup (struct usb_serial *serial)
                       sizeof(struct edge_compatibility_bits));
 
                /* get the manufacturing descriptor for this device */
-               get_manufacturing_desc (edge_serial);
+               get_manufacturing_desc(edge_serial);
 
                /* get the boot descriptor */
-               get_boot_desc (edge_serial);
+               get_boot_desc(edge_serial);
 
                get_product_info(edge_serial);
        }
@@ -2879,41 +3029,43 @@ static int edge_startup (struct usb_serial *serial)
        /* If not an EPiC device */
        if (!edge_serial->is_epic) {
                /* now load the application firmware into this device */
-               load_application_firmware (edge_serial);
+               load_application_firmware(edge_serial);
 
                dbg("%s - time 2 %ld", __func__, jiffies);
 
                /* Check current Edgeport EEPROM and update if necessary */
-               update_edgeport_E2PROM (edge_serial);
+               update_edgeport_E2PROM(edge_serial);
 
                dbg("%s - time 3 %ld", __func__, jiffies);
 
                /* set the configuration to use #1 */
-//             dbg("set_configuration 1");
-//             usb_set_configuration (dev, 1);
+/*             dbg("set_configuration 1"); */
+/*             usb_set_configuration (dev, 1); */
        }
        dbg("  FirmwareMajorVersion  %d.%d.%d",
            edge_serial->product_info.FirmwareMajorVersion,
            edge_serial->product_info.FirmwareMinorVersion,
            le16_to_cpu(edge_serial->product_info.FirmwareBuildNumber));
 
-       /* we set up the pointers to the endpoints in the edge_open function, 
+       /* we set up the pointers to the endpoints in the edge_open function,
         * as the structures aren't created yet. */
 
        /* set up our port private structures */
        for (i = 0; i < serial->num_ports; ++i) {
-               edge_port = kmalloc (sizeof(struct edgeport_port), GFP_KERNEL);
+               edge_port = kmalloc(sizeof(struct edgeport_port), GFP_KERNEL);
                if (edge_port == NULL) {
-                       dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__);
+                       dev_err(&serial->dev->dev, "%s - Out of memory\n",
+                                                                  __func__);
                        for (j = 0; j < i; ++j) {
-                               kfree (usb_get_serial_port_data(serial->port[j]));
-                               usb_set_serial_port_data(serial->port[j],  NULL);
+                               kfree(usb_get_serial_port_data(serial->port[j]));
+                               usb_set_serial_port_data(serial->port[j],
+                                                                       NULL);
                        }
                        usb_set_serial_data(serial, NULL);
                        kfree(edge_serial);
                        return -ENOMEM;
                }
-               memset (edge_port, 0, sizeof(struct edgeport_port));
+               memset(edge_port, 0, sizeof(struct edgeport_port));
                spin_lock_init(&edge_port->ep_lock);
                edge_port->port = serial->port[i];
                usb_set_serial_port_data(serial->port[i], edge_port);
@@ -2922,14 +3074,16 @@ static int edge_startup (struct usb_serial *serial)
        response = 0;
 
        if (edge_serial->is_epic) {
-               /* EPIC thing, set up our interrupt polling now and our read urb, so
-                * that the device knows it really is connected. */
+               /* EPIC thing, set up our interrupt polling now and our read
+                * urb, so that the device knows it really is connected. */
                interrupt_in_found = bulk_in_found = bulk_out_found = false;
-               for (i = 0; i < serial->interface->altsetting[0].desc.bNumEndpoints; ++i) {
+               for (i = 0; i < serial->interface->altsetting[0]
+                                               .desc.bNumEndpoints; ++i) {
                        struct usb_endpoint_descriptor *endpoint;
                        int buffer_size;
 
-                       endpoint = &serial->interface->altsetting[0].endpoint[i].desc;
+                       endpoint = &serial->interface->altsetting[0].
+                                                       endpoint[i].desc;
                        buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
                        if (!interrupt_in_found &&
                            (usb_endpoint_is_int_in(endpoint))) {
@@ -2937,58 +3091,67 @@ static int edge_startup (struct usb_serial *serial)
                                dbg("found interrupt in");
 
                                /* not set up yet, so do it now */
-                               edge_serial->interrupt_read_urb = usb_alloc_urb(0, GFP_KERNEL);
+                               edge_serial->interrupt_read_urb =
+                                               usb_alloc_urb(0, GFP_KERNEL);
                                if (!edge_serial->interrupt_read_urb) {
                                        err("out of memory");
                                        return -ENOMEM;
                                }
-                               edge_serial->interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
+                               edge_serial->interrupt_in_buffer =
+                                       kmalloc(buffer_size, GFP_KERNEL);
                                if (!edge_serial->interrupt_in_buffer) {
                                        err("out of memory");
                                        usb_free_urb(edge_serial->interrupt_read_urb);
                                        return -ENOMEM;
                                }
-                               edge_serial->interrupt_in_endpoint = endpoint->bEndpointAddress;
+                               edge_serial->interrupt_in_endpoint =
+                                               endpoint->bEndpointAddress;
 
                                /* set up our interrupt urb */
-                               usb_fill_int_urb(edge_serial->interrupt_read_urb,
-                                                dev,
-                                                usb_rcvintpipe(dev, endpoint->bEndpointAddress),
-                                                edge_serial->interrupt_in_buffer,
-                                                buffer_size,
-                                                edge_interrupt_callback,
-                                                edge_serial,
-                                                endpoint->bInterval);
+                               usb_fill_int_urb(
+                                       edge_serial->interrupt_read_urb,
+                                       dev,
+                                       usb_rcvintpipe(dev,
+                                               endpoint->bEndpointAddress),
+                                       edge_serial->interrupt_in_buffer,
+                                       buffer_size,
+                                       edge_interrupt_callback,
+                                       edge_serial,
+                                       endpoint->bInterval);
 
                                interrupt_in_found = true;
                        }
 
                        if (!bulk_in_found &&
-                           (usb_endpoint_is_bulk_in(endpoint))) {
+                               (usb_endpoint_is_bulk_in(endpoint))) {
                                /* we found a bulk in endpoint */
                                dbg("found bulk in");
 
                                /* not set up yet, so do it now */
-                               edge_serial->read_urb = usb_alloc_urb(0, GFP_KERNEL);
+                               edge_serial->read_urb =
+                                               usb_alloc_urb(0, GFP_KERNEL);
                                if (!edge_serial->read_urb) {
                                        err("out of memory");
                                        return -ENOMEM;
                                }
-                               edge_serial->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
+                               edge_serial->bulk_in_buffer =
+                                       kmalloc(buffer_size, GFP_KERNEL);
                                if (!edge_serial->bulk_in_buffer) {
-                                       err ("out of memory");
+                                       err("out of memory");
                                        usb_free_urb(edge_serial->read_urb);
                                        return -ENOMEM;
                                }
-                               edge_serial->bulk_in_endpoint = endpoint->bEndpointAddress;
+                               edge_serial->bulk_in_endpoint =
+                                               endpoint->bEndpointAddress;
 
                                /* set up our bulk in urb */
                                usb_fill_bulk_urb(edge_serial->read_urb, dev,
-                                                 usb_rcvbulkpipe(dev, endpoint->bEndpointAddress),
-                                                 edge_serial->bulk_in_buffer,
-                                                 le16_to_cpu(endpoint->wMaxPacketSize),
-                                                 edge_bulk_in_callback,
-                                                 edge_serial);
+                                       usb_rcvbulkpipe(dev,
+                                               endpoint->bEndpointAddress),
+                                       edge_serial->bulk_in_buffer,
+                                       le16_to_cpu(endpoint->wMaxPacketSize),
+                                       edge_bulk_in_callback,
+                                       edge_serial);
                                bulk_in_found = true;
                        }
 
@@ -2996,21 +3159,24 @@ static int edge_startup (struct usb_serial *serial)
                            (usb_endpoint_is_bulk_out(endpoint))) {
                                /* we found a bulk out endpoint */
                                dbg("found bulk out");
-                               edge_serial->bulk_out_endpoint = endpoint->bEndpointAddress;
+                               edge_serial->bulk_out_endpoint =
+                                               endpoint->bEndpointAddress;
                                bulk_out_found = true;
                        }
                }
 
                if (!interrupt_in_found || !bulk_in_found || !bulk_out_found) {
-                       err ("Error - the proper endpoints were not found!");
+                       err("Error - the proper endpoints were not found!");
                        return -ENODEV;
                }
 
                /* start interrupt read for this edgeport this interrupt will
                 * continue as long as the edgeport is connected */
-               response = usb_submit_urb(edge_serial->interrupt_read_urb, GFP_KERNEL);
+               response = usb_submit_urb(edge_serial->interrupt_read_urb,
+                                                               GFP_KERNEL);
                if (response)
-                       err("%s - Error %d submitting control urb", __func__, response);
+                       err("%s - Error %d submitting control urb",
+                                                       __func__, response);
        }
        return response;
 }
@@ -3020,7 +3186,7 @@ static int edge_startup (struct usb_serial *serial)
  * edge_shutdown
  *     This function is called whenever the device is removed from the usb bus.
  ****************************************************************************/
-static void edge_shutdown (struct usb_serial *serial)
+static void edge_shutdown(struct usb_serial *serial)
 {
        struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
        int i;
@@ -3028,8 +3194,8 @@ static void edge_shutdown (struct usb_serial *serial)
        dbg("%s", __func__);
 
        /* stop reads and writes on all ports */
-       for (i=0; i < serial->num_ports; ++i) {
-               kfree (usb_get_serial_port_data(serial->port[i]));
+       for (i = 0; i < serial->num_ports; ++i) {
+               kfree(usb_get_serial_port_data(serial->port[i]));
                usb_set_serial_port_data(serial->port[i],  NULL);
        }
        /* free up our endpoint stuff */
@@ -3069,7 +3235,7 @@ static int __init edgeport_init(void)
        if (retval)
                goto failed_epic_device_register;
        retval = usb_register(&io_driver);
-       if (retval) 
+       if (retval)
                goto failed_usb_register;
        atomic_set(&CmdUrbs, 0);
        info(DRIVER_DESC " " DRIVER_VERSION);
@@ -3094,19 +3260,19 @@ failed_2port_device_register:
  ****************************************************************************/
 static void __exit edgeport_exit (void)
 {
-       usb_deregister (&io_driver);
-       usb_serial_deregister (&edgeport_2port_device);
-       usb_serial_deregister (&edgeport_4port_device);
-       usb_serial_deregister (&edgeport_8port_device);
-       usb_serial_deregister (&epic_device);
+       usb_deregister(&io_driver);
+       usb_serial_deregister(&edgeport_2port_device);
+       usb_serial_deregister(&edgeport_4port_device);
+       usb_serial_deregister(&edgeport_8port_device);
+       usb_serial_deregister(&epic_device);
 }
 
 module_init(edgeport_init);
 module_exit(edgeport_exit);
 
 /* Module information */
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE("edgeport/boot.fw");
 MODULE_FIRMWARE("edgeport/boot2.fw");
index 2ec85893f27abc8f8877d0fcfe23aad58db17dbd..7eb9d67b81b632a20ead2479933c4e86cead3dfe 100644 (file)
@@ -8,7 +8,7 @@
  *     it under the terms of the 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 IO_TABLES_H
@@ -90,10 +90,10 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A758) },
        { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A794) },
        { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A225) },
-       { }                                                     /* Terminating entry */
+       { } /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
 
 static struct usb_driver io_driver = {
        .name =         "io_edgeport",
index 61daea3f7b2d5c40014c50681378aa47ff40bba1..cb4c54316cf56a935691ceba62971c3fcd5963c9 100644 (file)
@@ -18,8 +18,8 @@
  *
  * Version history:
  *
- *     July 11, 2002   Removed 4 port device structure since all TI UMP 
- *                     chips have only 2 ports 
+ *     July 11, 2002   Removed 4 port device structure since all TI UMP
+ *                     chips have only 2 ports
  *                     David Iacovelli (davidi@ionetworks.com)
  *
  */
@@ -38,7 +38,7 @@
 #include <linux/serial.h>
 #include <linux/ioctl.h>
 #include <linux/firmware.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
 
 
 struct edgeport_uart_buf_desc {
-       __u32 count;            // Number of bytes currently in buffer
+       __u32 count;            /* Number of bytes currently in buffer */
 };
 
 /* different hardware types */
 #define HARDWARE_TYPE_930      0
 #define HARDWARE_TYPE_TIUMP    1
 
-// IOCTL_PRIVATE_TI_GET_MODE Definitions
-#define        TI_MODE_CONFIGURING     0   // Device has not entered start device 
-#define        TI_MODE_BOOT            1   // Staying in boot mode
-#define TI_MODE_DOWNLOAD       2   // Made it to download mode
-#define TI_MODE_TRANSITIONING  3   // Currently in boot mode but transitioning to download mode
+/* IOCTL_PRIVATE_TI_GET_MODE Definitions */
+#define        TI_MODE_CONFIGURING     0   /* Device has not entered start device */
+#define        TI_MODE_BOOT            1   /* Staying in boot mode                */
+#define TI_MODE_DOWNLOAD       2   /* Made it to download mode            */
+#define TI_MODE_TRANSITIONING  3   /* Currently in boot mode but
+                                      transitioning to download mode      */
 
 /* read urb state */
 #define EDGE_READ_URB_RUNNING  0
@@ -82,10 +83,9 @@ struct edgeport_uart_buf_desc {
 
 
 /* Product information read from the Edgeport */
-struct product_info
-{
-       int     TiMode;                 // Current TI Mode
-       __u8    hardware_type;          // Type of hardware
+struct product_info {
+       int     TiMode;                 /* Current TI Mode  */
+       __u8    hardware_type;          /* Type of hardware */
 } __attribute__((packed));
 
 /* circular buffer */
@@ -116,7 +116,7 @@ struct edgeport_port {
                                                   happen */
        struct edgeport_serial  *edge_serial;
        struct usb_serial_port  *port;
-       __u8 bUartMode;         /* Port type, 0: RS232, etc. */ 
+       __u8 bUartMode;         /* Port type, 0: RS232, etc. */
        spinlock_t ep_lock;
        int ep_read_urb_state;
        int ep_write_urb_in_use;
@@ -125,8 +125,9 @@ struct edgeport_port {
 
 struct edgeport_serial {
        struct product_info product_info;
-       u8 TI_I2C_Type;                 // Type of I2C in UMP
-       u8 TiReadI2C;                   // Set to TRUE if we have read the I2c in Boot Mode
+       u8 TI_I2C_Type;                 /* Type of I2C in UMP */
+       u8 TiReadI2C;                   /* Set to TRUE if we have read the
+                                          I2c in Boot Mode */
        struct mutex es_lock;
        int num_ports_open;
        struct usb_serial *serial;
@@ -214,7 +215,7 @@ static struct usb_device_id id_table_combined [] = {
        { }
 };
 
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
 
 static struct usb_driver io_driver = {
        .name =         "io_ti",
@@ -231,20 +232,20 @@ static unsigned short OperationalBuildNumber;
 
 static int debug;
 
-static int TIStayInBootMode = 0;
 static int low_latency = EDGE_LOW_LATENCY;
 static int closing_wait = EDGE_CLOSING_WAIT;
-static int ignore_cpu_rev = 0;
-static int default_uart_mode = 0;      /* RS232 */
-
+static int ignore_cpu_rev;
+static int default_uart_mode;          /* RS232 */
 
-static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length);
+static void edge_tty_recv(struct device *dev, struct tty_struct *tty,
+                         unsigned char *data, int length);
 
 static void stop_read(struct edgeport_port *edge_port);
 static int restart_read(struct edgeport_port *edge_port);
 
-static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
-static void edge_send(struct usb_serial_port *port);
+static void edge_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios);
+static void edge_send(struct tty_struct *tty);
 
 /* sysfs attributes */
 static int edge_create_sysfs_attrs(struct usb_serial_port *port);
@@ -262,87 +263,57 @@ static unsigned int edge_buf_get(struct edge_buf *eb, char *buf,
        unsigned int count);
 
 
-static int TIReadVendorRequestSync (struct usb_device *dev,
-                               __u8            request,
-                               __u16           value,
-                               __u16           index,
-                               u8              *data,
-                               int             size)
+static int ti_vread_sync(struct usb_device *dev, __u8 request,
+                               __u16 value, __u16 index, u8 *data, int size)
 {
        int status;
 
-       status = usb_control_msg (dev,
-                               usb_rcvctrlpipe(dev, 0),
-                               request,
-                               (USB_TYPE_VENDOR | 
-                                USB_RECIP_DEVICE | 
-                                USB_DIR_IN),
-                               value,
-                               index,
-                               data,
-                               size,
-                               1000);
+       status = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request,
+                       (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN),
+                       value, index, data, size, 1000);
        if (status < 0)
                return status;
        if (status != size) {
-               dbg ("%s - wanted to write %d, but only wrote %d",
-                    __func__, size, status);
+               dbg("%s - wanted to write %d, but only wrote %d",
+                                            __func__, size, status);
                return -ECOMM;
        }
        return 0;
 }
 
-static int TISendVendorRequestSync (struct usb_device *dev,
-                               __u8            request,
-                               __u16           value,
-                               __u16           index,
-                               u8              *data,
-                               int             size)
+static int ti_vsend_sync(struct usb_device *dev, __u8 request,
+                               __u16 value, __u16 index, u8 *data, int size)
 {
        int status;
 
-       status = usb_control_msg (dev,
-                               usb_sndctrlpipe(dev, 0),
-                               request,
-                               (USB_TYPE_VENDOR | 
-                                USB_RECIP_DEVICE | 
-                                USB_DIR_OUT),
-                               value,
-                               index,
-                               data,
-                               size,
-                               1000);
+       status = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request,
+                       (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT),
+                       value, index, data, size, 1000);
        if (status < 0)
                return status;
        if (status != size) {
-               dbg ("%s - wanted to write %d, but only wrote %d",
+               dbg("%s - wanted to write %d, but only wrote %d",
                     __func__, size, status);
                return -ECOMM;
        }
        return 0;
 }
 
-static int TIWriteCommandSync (struct usb_device *dev, __u8 command,
+static int send_cmd(struct usb_device *dev, __u8 command,
                                __u8 moduleid, __u16 value, u8 *data,
                                int size)
 {
-       return TISendVendorRequestSync (dev,
-                                         command,                      // Request
-                                         value,                        // wValue 
-                                         moduleid,                     // wIndex
-                                         data,                         // TransferBuffer
-                                         size);                        // TransferBufferLength
-
+       return ti_vsend_sync(dev, command, value, moduleid, data, size);
 }
 
 /* clear tx/rx buffers and fifo in TI UMP */
-static int TIPurgeDataSync (struct usb_serial_port *port, __u16 mask)
+static int purge_port(struct usb_serial_port *port, __u16 mask)
 {
        int port_number = port->number - port->serial->minor;
 
-       dbg ("%s - port %d, mask %x", __func__, port_number, mask);
+       dbg("%s - port %d, mask %x", __func__, port_number, mask);
 
-       return TIWriteCommandSync (port->serial->dev,
+       return send_cmd(port->serial->dev,
                                        UMPC_PURGE_PORT,
                                        (__u8)(UMPM_UART1_PORT + port_number),
                                        mask,
@@ -351,92 +322,87 @@ static int TIPurgeDataSync (struct usb_serial_port *port, __u16 mask)
 }
 
 /**
- * TIReadDownloadMemory - Read edgeport memory from TI chip
+ * read_download_mem - Read edgeport memory from TI chip
  * @dev: usb device pointer
  * @start_address: Device CPU address at which to read
  * @length: Length of above data
  * @address_type: Can read both XDATA and I2C
  * @buffer: pointer to input data buffer
  */
-static int TIReadDownloadMemory(struct usb_device *dev, int start_address,
+static int read_download_mem(struct usb_device *dev, int start_address,
                                int length, __u8 address_type, __u8 *buffer)
 {
        int status = 0;
        __u8 read_length;
        __be16 be_start_address;
-       
-       dbg ("%s - @ %x for %d", __func__, start_address, length);
+
+       dbg("%s - @ %x for %d", __func__, start_address, length);
 
        /* Read in blocks of 64 bytes
         * (TI firmware can't handle more than 64 byte reads)
         */
        while (length) {
                if (length > 64)
-                       read_length= 64;
+                       read_length = 64;
                else
                        read_length = (__u8)length;
 
                if (read_length > 1) {
-                       dbg ("%s - @ %x for %d", __func__,
+                       dbg("%s - @ %x for %d", __func__,
                             start_address, read_length);
                }
-               be_start_address = cpu_to_be16 (start_address);
-               status = TIReadVendorRequestSync (dev,
-                                                 UMPC_MEMORY_READ,     // Request
-                                                 (__u16)address_type,  // wValue (Address type)
-                                                 (__force __u16)be_start_address,      // wIndex (Address to read)
-                                                 buffer,               // TransferBuffer
-                                                 read_length); // TransferBufferLength
+               be_start_address = cpu_to_be16(start_address);
+               status = ti_vread_sync(dev, UMPC_MEMORY_READ,
+                                       (__u16)address_type,
+                                       (__force __u16)be_start_address,
+                                       buffer, read_length);
 
                if (status) {
-                       dbg ("%s - ERROR %x", __func__, status);
+                       dbg("%s - ERROR %x", __func__, status);
                        return status;
                }
 
-               if (read_length > 1) {
+               if (read_length > 1)
                        usb_serial_debug_data(debug, &dev->dev, __func__,
                                              read_length, buffer);
-               }
 
                /* Update pointers/length */
                start_address += read_length;
                buffer += read_length;
                length -= read_length;
        }
-       
+
        return status;
 }
 
-static int TIReadRam (struct usb_device *dev, int start_address, int length, __u8 *buffer)
+static int read_ram(struct usb_device *dev, int start_address,
+                                               int length, __u8 *buffer)
 {
-       return TIReadDownloadMemory (dev,
-                                    start_address,
-                                    length,
-                                    DTK_ADDR_SPACE_XDATA,
-                                    buffer);
+       return read_download_mem(dev, start_address, length,
+                                       DTK_ADDR_SPACE_XDATA, buffer);
 }
 
 /* Read edgeport memory to a given block */
-static int TIReadBootMemory (struct edgeport_serial *serial, int start_address, int length, __u8 * buffer)
+static int read_boot_mem(struct edgeport_serial *serial,
+                               int start_address, int length, __u8 *buffer)
 {
        int status = 0;
        int i;
 
-       for (i=0; i< length; i++) {
-               status = TIReadVendorRequestSync (serial->serial->dev,
-                                       UMPC_MEMORY_READ,               // Request
-                                       serial->TI_I2C_Type,            // wValue (Address type)
-                                       (__u16)(start_address+i),       // wIndex
-                                       &buffer[i],                     // TransferBuffer
-                                       0x01);                          // TransferBufferLength
+       for (i = 0; i < length; i++) {
+               status = ti_vread_sync(serial->serial->dev,
+                               UMPC_MEMORY_READ, serial->TI_I2C_Type,
+                               (__u16)(start_address+i), &buffer[i], 0x01);
                if (status) {
-                       dbg ("%s - ERROR %x", __func__, status);
+                       dbg("%s - ERROR %x", __func__, status);
                        return status;
                }
        }
 
-       dbg ("%s - start_address = %x, length = %d", __func__, start_address, length);
-       usb_serial_debug_data(debug, &serial->serial->dev->dev, __func__, length, buffer);
+       dbg("%s - start_address = %x, length = %d",
+                                       __func__, start_address, length);
+       usb_serial_debug_data(debug, &serial->serial->dev->dev,
+                                       __func__, length, buffer);
 
        serial->TiReadI2C = 1;
 
@@ -444,7 +410,8 @@ static int TIReadBootMemory (struct edgeport_serial *serial, int start_address,
 }
 
 /* Write given block to TI EPROM memory */
-static int TIWriteBootMemory (struct edgeport_serial *serial, int start_address, int length, __u8 *buffer)
+static int write_boot_mem(struct edgeport_serial *serial,
+                               int start_address, int length, __u8 *buffer)
 {
        int status = 0;
        int i;
@@ -452,57 +419,58 @@ static int TIWriteBootMemory (struct edgeport_serial *serial, int start_address,
 
        /* Must do a read before write */
        if (!serial->TiReadI2C) {
-               status = TIReadBootMemory(serial, 0, 1, &temp);
+               status = read_boot_mem(serial, 0, 1, &temp);
                if (status)
                        return status;
        }
 
-       for (i=0; i < length; ++i) {
-               status = TISendVendorRequestSync (serial->serial->dev,
-                                               UMPC_MEMORY_WRITE,              // Request
-                                               buffer[i],                      // wValue
-                                               (__u16)(i+start_address),       // wIndex
-                                               NULL,                           // TransferBuffer
-                                               0);                             // TransferBufferLength
+       for (i = 0; i < length; ++i) {
+               status = ti_vsend_sync(serial->serial->dev,
+                               UMPC_MEMORY_WRITE, buffer[i],
+                               (__u16)(i + start_address), NULL, 0);
                if (status)
                        return status;
        }
 
-       dbg ("%s - start_sddr = %x, length = %d", __func__, start_address, length);
-       usb_serial_debug_data(debug, &serial->serial->dev->dev, __func__, length, buffer);
+       dbg("%s - start_sddr = %x, length = %d",
+                                       __func__, start_address, length);
+       usb_serial_debug_data(debug, &serial->serial->dev->dev,
+                                       __func__, length, buffer);
 
        return status;
 }
 
 
 /* Write edgeport I2C memory to TI chip        */
-static int TIWriteDownloadI2C (struct edgeport_serial *serial, int start_address, int length, __u8 address_type, __u8 *buffer)
+static int write_i2c_mem(struct edgeport_serial *serial,
+               int start_address, int length, __u8 address_type, __u8 *buffer)
 {
        int status = 0;
        int write_length;
        __be16 be_start_address;
 
        /* We can only send a maximum of 1 aligned byte page at a time */
-       
+
        /* calulate the number of bytes left in the first page */
-       write_length = EPROM_PAGE_SIZE - (start_address & (EPROM_PAGE_SIZE - 1));
+       write_length = EPROM_PAGE_SIZE -
+                               (start_address & (EPROM_PAGE_SIZE - 1));
 
        if (write_length > length)
                write_length = length;
 
-       dbg ("%s - BytesInFirstPage Addr = %x, length = %d", __func__, start_address, write_length);
-       usb_serial_debug_data(debug, &serial->serial->dev->dev, __func__, write_length, buffer);
+       dbg("%s - BytesInFirstPage Addr = %x, length = %d",
+                                       __func__, start_address, write_length);
+       usb_serial_debug_data(debug, &serial->serial->dev->dev,
+                                               __func__, write_length, buffer);
 
        /* Write first page */
-       be_start_address = cpu_to_be16 (start_address);
-       status = TISendVendorRequestSync (serial->serial->dev,
-                                       UMPC_MEMORY_WRITE,      // Request
-                                       (__u16)address_type,    // wValue
-                                       (__force __u16)be_start_address,        // wIndex
-                                       buffer,                 // TransferBuffer
-                                       write_length);
+       be_start_address = cpu_to_be16(start_address);
+       status = ti_vsend_sync(serial->serial->dev,
+                               UMPC_MEMORY_WRITE, (__u16)address_type,
+                               (__force __u16)be_start_address,
+                               buffer, write_length);
        if (status) {
-               dbg ("%s - ERROR %d", __func__, status);
+               dbg("%s - ERROR %d", __func__, status);
                return status;
        }
 
@@ -510,29 +478,31 @@ static int TIWriteDownloadI2C (struct edgeport_serial *serial, int start_address
        start_address   += write_length;
        buffer          += write_length;
 
-       /* We should be aligned now -- can write max page size bytes at a time */
+       /* We should be aligned now -- can write
+          max page size bytes at a time */
        while (length) {
                if (length > EPROM_PAGE_SIZE)
                        write_length = EPROM_PAGE_SIZE;
                else
                        write_length = length;
 
-               dbg ("%s - Page Write Addr = %x, length = %d", __func__, start_address, write_length);
-               usb_serial_debug_data(debug, &serial->serial->dev->dev, __func__, write_length, buffer);
+               dbg("%s - Page Write Addr = %x, length = %d",
+                                       __func__, start_address, write_length);
+               usb_serial_debug_data(debug, &serial->serial->dev->dev,
+                                       __func__, write_length, buffer);
 
                /* Write next page */
-               be_start_address = cpu_to_be16 (start_address);
-               status = TISendVendorRequestSync (serial->serial->dev,
-                                               UMPC_MEMORY_WRITE,      // Request
-                                               (__u16)address_type,    // wValue
-                                               (__force __u16)be_start_address,        // wIndex
-                                               buffer,                 // TransferBuffer
-                                               write_length);          // TransferBufferLength
+               be_start_address = cpu_to_be16(start_address);
+               status = ti_vsend_sync(serial->serial->dev, UMPC_MEMORY_WRITE,
+                               (__u16)address_type,
+                               (__force __u16)be_start_address,
+                               buffer, write_length);
                if (status) {
-                       dev_err (&serial->serial->dev->dev, "%s - ERROR %d\n", __func__, status);
+                       dev_err(&serial->serial->dev->dev, "%s - ERROR %d\n",
+                                       __func__, status);
                        return status;
                }
-               
+
                length          -= write_length;
                start_address   += write_length;
                buffer          += write_length;
@@ -541,25 +511,25 @@ static int TIWriteDownloadI2C (struct edgeport_serial *serial, int start_address
 }
 
 /* Examine the UMP DMA registers and LSR
- * 
+ *
  * Check the MSBit of the X and Y DMA byte count registers.
  * A zero in this bit indicates that the TX DMA buffers are empty
  * then check the TX Empty bit in the UART.
  */
-static int TIIsTxActive (struct edgeport_port *port)
+static int tx_active(struct edgeport_port *port)
 {
        int status;
        struct out_endpoint_desc_block *oedb;
        __u8 *lsr;
        int bytes_left = 0;
 
-       oedb = kmalloc (sizeof (* oedb), GFP_KERNEL);
+       oedb = kmalloc(sizeof(*oedb), GFP_KERNEL);
        if (!oedb) {
-               dev_err (&port->port->dev, "%s - out of memory\n", __func__);
+               dev_err(&port->port->dev, "%s - out of memory\n", __func__);
                return -ENOMEM;
        }
 
-       lsr = kmalloc (1, GFP_KERNEL);  /* Sigh, that's right, just one byte,
+       lsr = kmalloc(1, GFP_KERNEL);   /* Sigh, that's right, just one byte,
                                           as not all platforms can do DMA
                                           from stack */
        if (!lsr) {
@@ -567,51 +537,47 @@ static int TIIsTxActive (struct edgeport_port *port)
                return -ENOMEM;
        }
        /* Read the DMA Count Registers */
-       status = TIReadRam (port->port->serial->dev,
-                           port->dma_address,
-                           sizeof( *oedb),
-                           (void *)oedb);
-
+       status = read_ram(port->port->serial->dev, port->dma_address,
+                                               sizeof(*oedb), (void *)oedb);
        if (status)
                goto exit_is_tx_active;
 
-       dbg ("%s - XByteCount    0x%X", __func__, oedb->XByteCount);
+       dbg("%s - XByteCount    0x%X", __func__, oedb->XByteCount);
 
        /* and the LSR */
-       status = TIReadRam (port->port->serial->dev, 
-                           port->uart_base + UMPMEM_OFFS_UART_LSR,
-                           1,
-                           lsr);
+       status = read_ram(port->port->serial->dev,
+                       port->uart_base + UMPMEM_OFFS_UART_LSR, 1, lsr);
 
        if (status)
                goto exit_is_tx_active;
-       dbg ("%s - LSR = 0x%X", __func__, *lsr);
-       
+       dbg("%s - LSR = 0x%X", __func__, *lsr);
+
        /* If either buffer has data or we are transmitting then return TRUE */
-       if ((oedb->XByteCount & 0x80 ) != 0 )
+       if ((oedb->XByteCount & 0x80) != 0)
                bytes_left += 64;
 
-       if ((*lsr & UMP_UART_LSR_TX_MASK ) == 0 )
+       if ((*lsr & UMP_UART_LSR_TX_MASK) == 0)
                bytes_left += 1;
 
        /* We return Not Active if we get any kind of error */
 exit_is_tx_active:
-       dbg ("%s - return %d", __func__, bytes_left );
+       dbg("%s - return %d", __func__, bytes_left);
 
        kfree(lsr);
        kfree(oedb);
        return bytes_left;
 }
 
-static void TIChasePort(struct edgeport_port *port, unsigned long timeout, int flush)
+static void chase_port(struct edgeport_port *port, unsigned long timeout,
+                                                               int flush)
 {
        int baud_rate;
-       struct tty_struct *tty = port->port->tty;
+       struct tty_struct *tty = port->port->port.tty;
        wait_queue_t wait;
        unsigned long flags;
 
        if (!timeout)
-               timeout = (HZ*EDGE_CLOSING_WAIT)/100;
+               timeout = (HZ * EDGE_CLOSING_WAIT)/100;
 
        /* wait for data to drain from the buffer */
        spin_lock_irqsave(&port->ep_lock, flags);
@@ -621,7 +587,8 @@ static void TIChasePort(struct edgeport_port *port, unsigned long timeout, int f
                set_current_state(TASK_INTERRUPTIBLE);
                if (edge_buf_data_avail(port->ep_out_buf) == 0
                || timeout == 0 || signal_pending(current)
-               || !usb_get_intfdata(port->port->serial->interface))  /* disconnect */
+               || !usb_get_intfdata(port->port->serial->interface))
+                       /* disconnect */
                        break;
                spin_unlock_irqrestore(&port->ep_lock, flags);
                timeout = schedule_timeout(timeout);
@@ -636,8 +603,9 @@ static void TIChasePort(struct edgeport_port *port, unsigned long timeout, int f
        /* wait for data to drain from the device */
        timeout += jiffies;
        while ((long)(jiffies - timeout) < 0 && !signal_pending(current)
-       && usb_get_intfdata(port->port->serial->interface)) {  /* not disconnected */
-               if (!TIIsTxActive(port))
+       && usb_get_intfdata(port->port->serial->interface)) {
+               /* not disconnected */
+               if (!tx_active(port))
                        break;
                msleep(10);
        }
@@ -647,72 +615,72 @@ static void TIChasePort(struct edgeport_port *port, unsigned long timeout, int f
                return;
 
        /* wait one more character time, based on baud rate */
-       /* (TIIsTxActive doesn't seem to wait for the last byte) */
-       if ((baud_rate=port->baud_rate) == 0)
+       /* (tx_active doesn't seem to wait for the last byte) */
+       baud_rate = port->baud_rate;
+       if (baud_rate == 0)
                baud_rate = 50;
        msleep(max(1, DIV_ROUND_UP(10000, baud_rate)));
 }
 
-static int TIChooseConfiguration (struct usb_device *dev)
+static int choose_config(struct usb_device *dev)
 {
-       // There may be multiple configurations on this device, in which case
-       // we would need to read and parse all of them to find out which one
-       // we want. However, we just support one config at this point,
-       // configuration # 1, which is Config Descriptor 0.
+       /*
+        * There may be multiple configurations on this device, in which case
+        * we would need to read and parse all of them to find out which one
+        * we want. However, we just support one config at this point,
+        * configuration # 1, which is Config Descriptor 0.
+        */
 
-       dbg ("%s - Number of Interfaces = %d", __func__, dev->config->desc.bNumInterfaces);
-       dbg ("%s - MAX Power            = %d", __func__, dev->config->desc.bMaxPower*2);
+       dbg("%s - Number of Interfaces = %d",
+                               __func__, dev->config->desc.bNumInterfaces);
+       dbg("%s - MAX Power            = %d",
+                               __func__, dev->config->desc.bMaxPower * 2);
 
        if (dev->config->desc.bNumInterfaces != 1) {
-               dev_err (&dev->dev, "%s - bNumInterfaces is not 1, ERROR!\n", __func__);
+               dev_err(&dev->dev, "%s - bNumInterfaces is not 1, ERROR!\n",
+                                                               __func__);
                return -ENODEV;
        }
 
        return 0;
 }
 
-static int TIReadRom (struct edgeport_serial *serial, int start_address, int length, __u8 *buffer)
+static int read_rom(struct edgeport_serial *serial,
+                               int start_address, int length, __u8 *buffer)
 {
        int status;
 
        if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) {
-               status = TIReadDownloadMemory (serial->serial->dev,
+               status = read_download_mem(serial->serial->dev,
                                               start_address,
                                               length,
                                               serial->TI_I2C_Type,
                                               buffer);
        } else {
-               status = TIReadBootMemory (serial,
-                                          start_address,
-                                          length,
-                                          buffer);
+               status = read_boot_mem(serial, start_address, length,
+                                                               buffer);
        }
-
        return status;
 }
 
-static int TIWriteRom (struct edgeport_serial *serial, int start_address, int length, __u8 *buffer)
+static int write_rom(struct edgeport_serial *serial, int start_address,
+                                               int length, __u8 *buffer)
 {
        if (serial->product_info.TiMode == TI_MODE_BOOT)
-               return TIWriteBootMemory (serial,
-                                         start_address,
-                                         length,
-                                         buffer);
+               return write_boot_mem(serial, start_address, length,
+                                                               buffer);
 
        if (serial->product_info.TiMode == TI_MODE_DOWNLOAD)
-               return TIWriteDownloadI2C (serial,
-                                          start_address,
-                                          length,
-                                          serial->TI_I2C_Type,
-                                          buffer);
-
+               return write_i2c_mem(serial, start_address, length,
+                                               serial->TI_I2C_Type, buffer);
        return -EINVAL;
 }
 
 
 
 /* Read a descriptor header from I2C based on type */
-static int TIGetDescriptorAddress (struct edgeport_serial *serial, int desc_type, struct ti_i2c_desc *rom_desc)
+static int get_descriptor_addr(struct edgeport_serial *serial,
+                               int desc_type, struct ti_i2c_desc *rom_desc)
 {
        int start_address;
        int status;
@@ -720,41 +688,42 @@ static int TIGetDescriptorAddress (struct edgeport_serial *serial, int desc_type
        /* Search for requested descriptor in I2C */
        start_address = 2;
        do {
-               status = TIReadRom (serial,
+               status = read_rom(serial,
                                   start_address,
                                   sizeof(struct ti_i2c_desc),
-                                  (__u8 *)rom_desc );
+                                  (__u8 *)rom_desc);
                if (status)
                        return 0;
 
                if (rom_desc->Type == desc_type)
                        return start_address;
 
-               start_address = start_address + sizeof(struct ti_i2c_desc) +  rom_desc->Size;
+               start_address = start_address + sizeof(struct ti_i2c_desc)
+                                                       + rom_desc->Size;
 
        } while ((start_address < TI_MAX_I2C_SIZE) && rom_desc->Type);
-       
+
        return 0;
 }
 
 /* Validate descriptor checksum */
-static int ValidChecksum(struct ti_i2c_desc *rom_desc, __u8 *buffer)
+static int valid_csum(struct ti_i2c_desc *rom_desc, __u8 *buffer)
 {
        __u16 i;
        __u8 cs = 0;
 
-       for (i=0; i < rom_desc->Size; i++) {
+       for (i = 0; i < rom_desc->Size; i++)
                cs = (__u8)(cs + buffer[i]);
-       }
+
        if (cs != rom_desc->CheckSum) {
-               dbg ("%s - Mismatch %x - %x", __func__, rom_desc->CheckSum, cs);
+               dbg("%s - Mismatch %x - %x", __func__, rom_desc->CheckSum, cs);
                return -EINVAL;
        }
        return 0;
 }
 
 /* Make sure that the I2C image is good */
-static int TiValidateI2cImage (struct edgeport_serial *serial)
+static int check_i2c_image(struct edgeport_serial *serial)
 {
        struct device *dev = &serial->serial->dev->dev;
        int status = 0;
@@ -763,120 +732,124 @@ static int TiValidateI2cImage (struct edgeport_serial *serial)
        __u8 *buffer;
        __u16 ttype;
 
-       rom_desc = kmalloc (sizeof (*rom_desc), GFP_KERNEL);
+       rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL);
        if (!rom_desc) {
-               dev_err (dev, "%s - out of memory\n", __func__);
+               dev_err(dev, "%s - out of memory\n", __func__);
                return -ENOMEM;
        }
-       buffer = kmalloc (TI_MAX_I2C_SIZE, GFP_KERNEL);
+       buffer = kmalloc(TI_MAX_I2C_SIZE, GFP_KERNEL);
        if (!buffer) {
-               dev_err (dev, "%s - out of memory when allocating buffer\n", __func__);
-               kfree (rom_desc);
+               dev_err(dev, "%s - out of memory when allocating buffer\n",
+                                                               __func__);
+               kfree(rom_desc);
                return -ENOMEM;
        }
 
-       // Read the first byte (Signature0) must be 0x52 or 0x10
-       status = TIReadRom (serial, 0, 1, buffer);
+       /* Read the first byte (Signature0) must be 0x52 or 0x10 */
+       status = read_rom(serial, 0, 1, buffer);
        if (status)
-               goto ExitTiValidateI2cImage; 
+               goto out;
 
        if (*buffer != UMP5152 && *buffer != UMP3410) {
-               dev_err (dev, "%s - invalid buffer signature\n", __func__);
+               dev_err(dev, "%s - invalid buffer signature\n", __func__);
                status = -ENODEV;
-               goto ExitTiValidateI2cImage;
+               goto out;
        }
 
        do {
-               // Validate the I2C
-               status = TIReadRom (serial,
+               /* Validate the I2C */
+               status = read_rom(serial,
                                start_address,
                                sizeof(struct ti_i2c_desc),
                                (__u8 *)rom_desc);
                if (status)
                        break;
 
-               if ((start_address + sizeof(struct ti_i2c_desc) + rom_desc->Size) > TI_MAX_I2C_SIZE) {
+               if ((start_address + sizeof(struct ti_i2c_desc) +
+                                       rom_desc->Size) > TI_MAX_I2C_SIZE) {
                        status = -ENODEV;
-                       dbg ("%s - structure too big, erroring out.", __func__);
+                       dbg("%s - structure too big, erroring out.", __func__);
                        break;
                }
 
-               dbg ("%s Type = 0x%x", __func__, rom_desc->Type);
+               dbg("%s Type = 0x%x", __func__, rom_desc->Type);
 
-               // Skip type 2 record
+               /* Skip type 2 record */
                ttype = rom_desc->Type & 0x0f;
-               if ( ttype != I2C_DESC_TYPE_FIRMWARE_BASIC
-                       && ttype != I2C_DESC_TYPE_FIRMWARE_AUTO ) {
-                       // Read the descriptor data
-                       status = TIReadRom(serial,
-                                               start_address+sizeof(struct ti_i2c_desc),
-                                               rom_desc->Size,
-                                               buffer);
+               if (ttype != I2C_DESC_TYPE_FIRMWARE_BASIC
+                       && ttype != I2C_DESC_TYPE_FIRMWARE_AUTO) {
+                       /* Read the descriptor data */
+                       status = read_rom(serial, start_address +
+                                               sizeof(struct ti_i2c_desc),
+                                               rom_desc->Size, buffer);
                        if (status)
                                break;
 
-                       status = ValidChecksum(rom_desc, buffer);
+                       status = valid_csum(rom_desc, buffer);
                        if (status)
                                break;
                }
-               start_address = start_address + sizeof(struct ti_i2c_desc) + rom_desc->Size;
+               start_address = start_address + sizeof(struct ti_i2c_desc) +
+                                                               rom_desc->Size;
 
-       } while ((rom_desc->Type != I2C_DESC_TYPE_ION) && (start_address < TI_MAX_I2C_SIZE));
+       } while ((rom_desc->Type != I2C_DESC_TYPE_ION) &&
+                               (start_address < TI_MAX_I2C_SIZE));
 
-       if ((rom_desc->Type != I2C_DESC_TYPE_ION) || (start_address > TI_MAX_I2C_SIZE))
+       if ((rom_desc->Type != I2C_DESC_TYPE_ION) ||
+                               (start_address > TI_MAX_I2C_SIZE))
                status = -ENODEV;
 
-ExitTiValidateI2cImage:        
-       kfree (buffer);
-       kfree (rom_desc);
+out:
+       kfree(buffer);
+       kfree(rom_desc);
        return status;
 }
 
-static int TIReadManufDescriptor (struct edgeport_serial *serial, __u8 *buffer)
+static int get_manuf_info(struct edgeport_serial *serial, __u8 *buffer)
 {
        int status;
        int start_address;
        struct ti_i2c_desc *rom_desc;
        struct edge_ti_manuf_descriptor *desc;
 
-       rom_desc = kmalloc (sizeof (*rom_desc), GFP_KERNEL);
+       rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL);
        if (!rom_desc) {
-               dev_err (&serial->serial->dev->dev, "%s - out of memory\n", __func__);
+               dev_err(&serial->serial->dev->dev, "%s - out of memory\n",
+                                                               __func__);
                return -ENOMEM;
        }
-       start_address = TIGetDescriptorAddress (serial, I2C_DESC_TYPE_ION, rom_desc);
+       start_address = get_descriptor_addr(serial, I2C_DESC_TYPE_ION,
+                                                               rom_desc);
 
        if (!start_address) {
-               dbg ("%s - Edge Descriptor not found in I2C", __func__);
+               dbg("%s - Edge Descriptor not found in I2C", __func__);
                status = -ENODEV;
                goto exit;
        }
 
-       // Read the descriptor data
-       status = TIReadRom (serial,
-                               start_address+sizeof(struct ti_i2c_desc),
-                               rom_desc->Size,
-                               buffer);
+       /* Read the descriptor data */
+       status = read_rom(serial, start_address+sizeof(struct ti_i2c_desc),
+                                               rom_desc->Size, buffer);
        if (status)
                goto exit;
-       
-       status = ValidChecksum(rom_desc, buffer);
-       
+
+       status = valid_csum(rom_desc, buffer);
+
        desc = (struct edge_ti_manuf_descriptor *)buffer;
-       dbg ( "%s - IonConfig      0x%x", __func__, desc->IonConfig     );
-       dbg ( "%s - Version          %d", __func__, desc->Version               );
-       dbg ( "%s - Cpu/Board      0x%x", __func__, desc->CpuRev_BoardRev       );
-       dbg ( "%s - NumPorts         %d", __func__, desc->NumPorts      );
-       dbg ( "%s - NumVirtualPorts  %d", __func__, desc->NumVirtualPorts       );
-       dbg ( "%s - TotalPorts       %d", __func__, desc->TotalPorts    );
+       dbg("%s - IonConfig      0x%x", __func__, desc->IonConfig);
+       dbg("%s - Version          %d", __func__, desc->Version);
+       dbg("%s - Cpu/Board      0x%x", __func__, desc->CpuRev_BoardRev);
+       dbg("%s - NumPorts         %d", __func__, desc->NumPorts);
+       dbg("%s - NumVirtualPorts  %d", __func__, desc->NumVirtualPorts);
+       dbg("%s - TotalPorts       %d", __func__, desc->TotalPorts);
 
 exit:
-       kfree (rom_desc);
+       kfree(rom_desc);
        return status;
 }
 
 /* Build firmware header used for firmware update */
-static int BuildI2CFirmwareHeader (__u8 *header, struct device *dev)
+static int build_i2c_fw_hdr(__u8 *header, struct device *dev)
 {
        __u8 *buffer;
        int buffer_size;
@@ -889,24 +862,28 @@ static int BuildI2CFirmwareHeader (__u8 *header, struct device *dev)
        const struct firmware *fw;
        const char *fw_name = "edgeport/down3.bin";
 
-       // In order to update the I2C firmware we must change the type 2 record to type 0xF2.
-       // This will force the UMP to come up in Boot Mode.  Then while in boot mode, the driver 
-       // will download the latest firmware (padded to 15.5k) into the UMP ram. 
-       // And finally when the device comes back up in download mode the driver will cause 
-       // the new firmware to be copied from the UMP Ram to I2C and the firmware will update
-       // the record type from 0xf2 to 0x02.
-       
-       // Allocate a 15.5k buffer + 2 bytes for version number (Firmware Record)
-       buffer_size = (((1024 * 16) - 512 )+ sizeof(struct ti_i2c_firmware_rec));
-
-       buffer = kmalloc (buffer_size, GFP_KERNEL);
+       /* In order to update the I2C firmware we must change the type 2 record
+        * to type 0xF2.  This will force the UMP to come up in Boot Mode.
+        * Then while in boot mode, the driver will download the latest
+        * firmware (padded to 15.5k) into the UMP ram.  And finally when the
+        * device comes back up in download mode the driver will cause the new
+        * firmware to be copied from the UMP Ram to I2C and the firmware will
+        * update the record type from 0xf2 to 0x02.
+        */
+
+       /* Allocate a 15.5k buffer + 2 bytes for version number
+        * (Firmware Record) */
+       buffer_size = (((1024 * 16) - 512 ) +
+                       sizeof(struct ti_i2c_firmware_rec));
+
+       buffer = kmalloc(buffer_size, GFP_KERNEL);
        if (!buffer) {
-               dev_err (dev, "%s - out of memory\n", __func__);
+               dev_err(dev, "%s - out of memory\n", __func__);
                return -ENOMEM;
        }
-       
+
        // Set entire image of 0xffs
-       memset (buffer, 0xff, buffer_size);
+       memset(buffer, 0xff, buffer_size);
 
        err = request_firmware(&fw, fw_name, dev);
        if (err) {
@@ -921,16 +898,16 @@ static int BuildI2CFirmwareHeader (__u8 *header, struct device *dev)
        OperationalMinorVersion = fw->data[1];
        OperationalBuildNumber = fw->data[2] | (fw->data[3] << 8);
 
-       // Copy version number into firmware record
+       /* Copy version number into firmware record */
        firmware_rec = (struct ti_i2c_firmware_rec *)buffer;
 
        firmware_rec->Ver_Major = OperationalMajorVersion;
        firmware_rec->Ver_Minor = OperationalMinorVersion;
 
-       // Pointer to fw_down memory image
+       /* Pointer to fw_down memory image */
        img_header = (struct ti_i2c_image_header *)&fw->data[4];
 
-       memcpy (buffer + sizeof(struct ti_i2c_firmware_rec),
+       memcpy(buffer + sizeof(struct ti_i2c_firmware_rec),
                &fw->data[4 + sizeof(struct ti_i2c_image_header)],
                le16_to_cpu(img_header->Length));
 
@@ -940,12 +917,12 @@ static int BuildI2CFirmwareHeader (__u8 *header, struct device *dev)
                cs = (__u8)(cs + buffer[i]);
        }
 
-       kfree (buffer);
+       kfree(buffer);
 
-       // Build new header
+       /* Build new header */
        i2c_header =  (struct ti_i2c_desc *)header;
        firmware_rec =  (struct ti_i2c_firmware_rec*)i2c_header->Data;
-       
+
        i2c_header->Type        = I2C_DESC_TYPE_FIRMWARE_BLANK;
        i2c_header->Size        = (__u16)buffer_size;
        i2c_header->CheckSum    = cs;
@@ -956,103 +933,100 @@ static int BuildI2CFirmwareHeader (__u8 *header, struct device *dev)
 }
 
 /* Try to figure out what type of I2c we have */
-static int TIGetI2cTypeInBootMode (struct edgeport_serial *serial)
+static int i2c_type_bootmode(struct edgeport_serial *serial)
 {
        int status;
        __u8 data;
-               
-       // Try to read type 2
-       status = TIReadVendorRequestSync (serial->serial->dev,
-                                       UMPC_MEMORY_READ,               // Request
-                                       DTK_ADDR_SPACE_I2C_TYPE_II,     // wValue (Address type)
-                                       0,                              // wIndex
-                                       &data,                          // TransferBuffer
-                                       0x01);                          // TransferBufferLength
+
+       /* Try to read type 2 */
+       status = ti_vread_sync(serial->serial->dev, UMPC_MEMORY_READ,
+                               DTK_ADDR_SPACE_I2C_TYPE_II, 0, &data, 0x01);
        if (status)
-               dbg ("%s - read 2 status error = %d", __func__, status);
+               dbg("%s - read 2 status error = %d", __func__, status);
        else
-               dbg ("%s - read 2 data = 0x%x", __func__, data);
+               dbg("%s - read 2 data = 0x%x", __func__, data);
        if ((!status) && (data == UMP5152 || data == UMP3410)) {
-               dbg ("%s - ROM_TYPE_II", __func__);
+               dbg("%s - ROM_TYPE_II", __func__);
                serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II;
                return 0;
        }
 
-       // Try to read type 3
-       status = TIReadVendorRequestSync (serial->serial->dev,
-                                       UMPC_MEMORY_READ,               // Request
-                                       DTK_ADDR_SPACE_I2C_TYPE_III,    // wValue (Address type)
-                                       0,                              // wIndex
-                                       &data,                          // TransferBuffer
-                                       0x01);                          // TransferBufferLength
+       /* Try to read type 3 */
+       status = ti_vread_sync(serial->serial->dev, UMPC_MEMORY_READ,
+                               DTK_ADDR_SPACE_I2C_TYPE_III, 0, &data, 0x01);
        if (status)
-               dbg ("%s - read 3 status error = %d", __func__, status);
+               dbg("%s - read 3 status error = %d", __func__, status);
        else
-               dbg ("%s - read 2 data = 0x%x", __func__, data);
+               dbg("%s - read 2 data = 0x%x", __func__, data);
        if ((!status) && (data == UMP5152 || data == UMP3410)) {
-               dbg ("%s - ROM_TYPE_III", __func__);
+               dbg("%s - ROM_TYPE_III", __func__);
                serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_III;
                return 0;
        }
 
-       dbg ("%s - Unknown", __func__);
+       dbg("%s - Unknown", __func__);
        serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II;
        return -ENODEV;
 }
 
-static int TISendBulkTransferSync (struct usb_serial *serial, void *buffer, int length, int *num_sent)
+static int bulk_xfer(struct usb_serial *serial, void *buffer,
+                                               int length, int *num_sent)
 {
        int status;
 
-       status = usb_bulk_msg (serial->dev,
-                               usb_sndbulkpipe(serial->dev,
-                                               serial->port[0]->bulk_out_endpointAddress),
-                               buffer,
-                               length,
-                               num_sent,
-                               1000);
+       status = usb_bulk_msg(serial->dev,
+                       usb_sndbulkpipe(serial->dev,
+                               serial->port[0]->bulk_out_endpointAddress),
+                       buffer, length, num_sent, 1000);
        return status;
 }
 
 /* Download given firmware image to the device (IN BOOT MODE) */
-static int TIDownloadCodeImage (struct edgeport_serial *serial, __u8 *image, int image_length)
+static int download_code(struct edgeport_serial *serial, __u8 *image,
+                                                       int image_length)
 {
        int status = 0;
        int pos;
        int transfer;
        int done;
 
-       // Transfer firmware image
+       /* Transfer firmware image */
        for (pos = 0; pos < image_length; ) {
-               // Read the next buffer from file
+               /* Read the next buffer from file */
                transfer = image_length - pos;
                if (transfer > EDGE_FW_BULK_MAX_PACKET_SIZE)
                        transfer = EDGE_FW_BULK_MAX_PACKET_SIZE;
 
-               // Transfer data
-               status = TISendBulkTransferSync (serial->serial, &image[pos], transfer, &done);
+               /* Transfer data */
+               status = bulk_xfer(serial->serial, &image[pos],
+                                                       transfer, &done);
                if (status)
                        break;
-               // Advance buffer pointer
+               /* Advance buffer pointer */
                pos += done;
        }
 
        return status;
 }
 
-// FIXME!!!
-static int TIConfigureBootDevice (struct usb_device *dev)
+/* FIXME!!! */
+static int config_boot_dev(struct usb_device *dev)
 {
        return 0;
 }
 
+static int ti_cpu_rev(struct edge_ti_manuf_descriptor *desc)
+{
+       return TI_GET_CPU_REVISION(desc->CpuRev_BoardRev);
+}
+
 /**
  * DownloadTIFirmware - Download run-time operating firmware to the TI5052
- * 
+ *
  * This routine downloads the main operating code into the TI5052, using the
  * boot code already burned into E2PROM or ROM.
  */
-static int TIDownloadFirmware (struct edgeport_serial *serial)
+static int download_fw(struct edgeport_serial *serial)
 {
        struct device *dev = &serial->serial->dev->dev;
        int status = 0;
@@ -1071,22 +1045,25 @@ static int TIDownloadFirmware (struct edgeport_serial *serial)
        /* Default to type 2 i2c */
        serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II;
 
-       status = TIChooseConfiguration (serial->serial->dev);
+       status = choose_config(serial->serial->dev);
        if (status)
                return status;
 
        interface = &serial->serial->interface->cur_altsetting->desc;
        if (!interface) {
-               dev_err (dev, "%s - no interface set, error!\n", __func__);
+               dev_err(dev, "%s - no interface set, error!\n", __func__);
                return -ENODEV;
        }
 
-       // Setup initial mode -- the default mode 0 is TI_MODE_CONFIGURING
-       // if we have more than one endpoint we are definitely in download mode
+       /*
+        * Setup initial mode -- the default mode 0 is TI_MODE_CONFIGURING
+        * if we have more than one endpoint we are definitely in download
+        * mode
+        */
        if (interface->bNumEndpoints > 1)
                serial->product_info.TiMode = TI_MODE_DOWNLOAD;
        else
-               // Otherwise we will remain in configuring mode
+               /* Otherwise we will remain in configuring mode */
                serial->product_info.TiMode = TI_MODE_CONFIGURING;
 
        /********************************************************************/
@@ -1097,256 +1074,273 @@ static int TIDownloadFirmware (struct edgeport_serial *serial)
 
                dbg("%s - RUNNING IN DOWNLOAD MODE", __func__);
 
-               status = TiValidateI2cImage (serial);
+               status = check_i2c_image(serial);
                if (status) {
                        dbg("%s - DOWNLOAD MODE -- BAD I2C", __func__);
                        return status;
                }
-               
+
                /* Validate Hardware version number
                 * Read Manufacturing Descriptor from TI Based Edgeport
                 */
-               ti_manuf_desc = kmalloc (sizeof (*ti_manuf_desc), GFP_KERNEL);
+               ti_manuf_desc = kmalloc(sizeof(*ti_manuf_desc), GFP_KERNEL);
                if (!ti_manuf_desc) {
-                       dev_err (dev, "%s - out of memory.\n", __func__);
+                       dev_err(dev, "%s - out of memory.\n", __func__);
                        return -ENOMEM;
                }
-               status = TIReadManufDescriptor (serial, (__u8 *)ti_manuf_desc);
+               status = get_manuf_info(serial, (__u8 *)ti_manuf_desc);
                if (status) {
-                       kfree (ti_manuf_desc);
+                       kfree(ti_manuf_desc);
                        return status;
                }
 
-               // Check version number of ION descriptor
-               if (!ignore_cpu_rev && TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev) < 2) {
-                       dbg ( "%s - Wrong CPU Rev %d (Must be 2)", __func__,
-                            TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev));
-                       kfree (ti_manuf_desc);
-                       return -EINVAL;
-               }
+               /* Check version number of ION descriptor */
+               if (!ignore_cpu_rev && ti_cpu_rev(ti_manuf_desc) < 2) {
+                       dbg("%s - Wrong CPU Rev %d (Must be 2)",
+                               __func__, ti_cpu_rev(ti_manuf_desc));
+                       kfree(ti_manuf_desc);
+                       return -EINVAL;
+               }
 
-               rom_desc = kmalloc (sizeof (*rom_desc), GFP_KERNEL);
+               rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL);
                if (!rom_desc) {
-                       dev_err (dev, "%s - out of memory.\n", __func__);
-                       kfree (ti_manuf_desc);
+                       dev_err(dev, "%s - out of memory.\n", __func__);
+                       kfree(ti_manuf_desc);
                        return -ENOMEM;
                }
 
-               // Search for type 2 record (firmware record)
-               if ((start_address = TIGetDescriptorAddress (serial, I2C_DESC_TYPE_FIRMWARE_BASIC, rom_desc)) != 0) {
+               /* Search for type 2 record (firmware record) */
+               start_address = get_descriptor_addr(serial,
+                               I2C_DESC_TYPE_FIRMWARE_BASIC, rom_desc);
+               if (start_address != 0) {
                        struct ti_i2c_firmware_rec *firmware_version;
                        __u8 record;
 
-                       dbg ("%s - Found Type FIRMWARE (Type 2) record", __func__);
+                       dbg("%s - Found Type FIRMWARE (Type 2) record",
+                                                               __func__);
 
-                       firmware_version = kmalloc (sizeof (*firmware_version), GFP_KERNEL);
+                       firmware_version = kmalloc(sizeof(*firmware_version),
+                                                               GFP_KERNEL);
                        if (!firmware_version) {
-                               dev_err (dev, "%s - out of memory.\n", __func__);
-                               kfree (rom_desc);
-                               kfree (ti_manuf_desc);
+                               dev_err(dev, "%s - out of memory.\n", __func__);
+                               kfree(rom_desc);
+                               kfree(ti_manuf_desc);
                                return -ENOMEM;
                        }
 
-                       // Validate version number                              
-                       // Read the descriptor data
-                       status = TIReadRom (serial,
-                                       start_address+sizeof(struct ti_i2c_desc),
+                       /* Validate version number
+                        * Read the descriptor data
+                        */
+                       status = read_rom(serial, start_address +
+                                       sizeof(struct ti_i2c_desc),
                                        sizeof(struct ti_i2c_firmware_rec),
                                        (__u8 *)firmware_version);
                        if (status) {
-                               kfree (firmware_version);
-                               kfree (rom_desc);
-                               kfree (ti_manuf_desc);
+                               kfree(firmware_version);
+                               kfree(rom_desc);
+                               kfree(ti_manuf_desc);
                                return status;
                        }
 
-                       // Check version number of download with current version in I2c
-                       download_cur_ver = (firmware_version->Ver_Major << 8) + 
+                       /* Check version number of download with current
+                          version in I2c */
+                       download_cur_ver = (firmware_version->Ver_Major << 8) +
                                           (firmware_version->Ver_Minor);
                        download_new_ver = (OperationalMajorVersion << 8) +
                                           (OperationalMinorVersion);
 
-                       dbg ("%s - >>>Firmware Versions Device %d.%d  Driver %d.%d",
-                            __func__,
-                            firmware_version->Ver_Major,
-                            firmware_version->Ver_Minor,
-                            OperationalMajorVersion,
-                            OperationalMinorVersion);
+                       dbg("%s - >> FW Versions Device %d.%d  Driver %d.%d",
+                           __func__,
+                           firmware_version->Ver_Major,
+                           firmware_version->Ver_Minor,
+                           OperationalMajorVersion,
+                           OperationalMinorVersion);
 
-                       // Check if we have an old version in the I2C and update if necessary
+                       /* Check if we have an old version in the I2C and
+                          update if necessary */
                        if (download_cur_ver != download_new_ver) {
-                               dbg ("%s - Update I2C Download from %d.%d to %d.%d",
-                                    __func__,
-                                    firmware_version->Ver_Major,
-                                    firmware_version->Ver_Minor,
-                                    OperationalMajorVersion,
-                                    OperationalMinorVersion);
-
-                               // In order to update the I2C firmware we must change the type 2 record to type 0xF2.
-                               // This will force the UMP to come up in Boot Mode.  Then while in boot mode, the driver 
-                               // will download the latest firmware (padded to 15.5k) into the UMP ram. 
-                               // And finally when the device comes back up in download mode the driver will cause 
-                               // the new firmware to be copied from the UMP Ram to I2C and the firmware will update
-                               // the record type from 0xf2 to 0x02.
-
+                               dbg("%s - Update I2C dld from %d.%d to %d.%d",
+                                   __func__,
+                                   firmware_version->Ver_Major,
+                                   firmware_version->Ver_Minor,
+                                   OperationalMajorVersion,
+                                   OperationalMinorVersion);
+
+                               /* In order to update the I2C firmware we must
+                                * change the type 2 record to type 0xF2. This
+                                * will force the UMP to come up in Boot Mode.
+                                * Then while in boot mode, the driver will
+                                * download the latest firmware (padded to
+                                * 15.5k) into the UMP ram. Finally when the
+                                * device comes back up in download mode the
+                                * driver will cause the new firmware to be
+                                * copied from the UMP Ram to I2C and the
+                                * firmware will update the record type from
+                                * 0xf2 to 0x02.
+                                */
                                record = I2C_DESC_TYPE_FIRMWARE_BLANK;
 
-                               // Change the I2C Firmware record type to 0xf2 to trigger an update
-                               status = TIWriteRom (serial,
-                                                       start_address,
-                                                       sizeof(record),
-                                                       &record);
+                               /* Change the I2C Firmware record type to
+                                  0xf2 to trigger an update */
+                               status = write_rom(serial, start_address,
+                                               sizeof(record), &record);
                                if (status) {
-                                       kfree (firmware_version);
-                                       kfree (rom_desc);
-                                       kfree (ti_manuf_desc);
+                                       kfree(firmware_version);
+                                       kfree(rom_desc);
+                                       kfree(ti_manuf_desc);
                                        return status;
                                }
 
-                               // verify the write -- must do this in order for write to 
-                               // complete before we do the hardware reset
-                               status = TIReadRom (serial,
+                               /* verify the write -- must do this in order
+                                * for write to complete before we do the
+                                * hardware reset
+                                */
+                               status = read_rom(serial,
                                                        start_address,
                                                        sizeof(record),
                                                        &record);
-
                                if (status) {
-                                       kfree (firmware_version);
-                                       kfree (rom_desc);
-                                       kfree (ti_manuf_desc);
+                                       kfree(firmware_version);
+                                       kfree(rom_desc);
+                                       kfree(ti_manuf_desc);
                                        return status;
                                }
 
                                if (record != I2C_DESC_TYPE_FIRMWARE_BLANK) {
-                                       dev_err (dev, "%s - error resetting device\n", __func__);
-                                       kfree (firmware_version);
-                                       kfree (rom_desc);
-                                       kfree (ti_manuf_desc);
+                                       dev_err(dev,
+                                               "%s - error resetting device\n",
+                                               __func__);
+                                       kfree(firmware_version);
+                                       kfree(rom_desc);
+                                       kfree(ti_manuf_desc);
                                        return -ENODEV;
                                }
 
-                               dbg ("%s - HARDWARE RESET", __func__);
+                               dbg("%s - HARDWARE RESET", __func__);
 
-                               // Reset UMP -- Back to BOOT MODE
-                               status = TISendVendorRequestSync (serial->serial->dev,
-                                                               UMPC_HARDWARE_RESET,    // Request
-                                                               0,                      // wValue
-                                                               0,                      // wIndex
-                                                               NULL,                   // TransferBuffer
-                                                               0);                     // TransferBufferLength
+                               /* Reset UMP -- Back to BOOT MODE */
+                               status = ti_vsend_sync(serial->serial->dev,
+                                               UMPC_HARDWARE_RESET,
+                                               0, 0, NULL, 0);
 
-                               dbg ( "%s - HARDWARE RESET return %d", __func__, status);
+                               dbg("%s - HARDWARE RESET return %d",
+                                               __func__, status);
 
                                /* return an error on purpose. */
-                               kfree (firmware_version);
-                               kfree (rom_desc);
-                               kfree (ti_manuf_desc);
+                               kfree(firmware_version);
+                               kfree(rom_desc);
+                               kfree(ti_manuf_desc);
                                return -ENODEV;
                        }
-                       kfree (firmware_version);
+                       kfree(firmware_version);
                }
-               // Search for type 0xF2 record (firmware blank record)
-               else if ((start_address = TIGetDescriptorAddress (serial, I2C_DESC_TYPE_FIRMWARE_BLANK, rom_desc)) != 0) {
-                       #define HEADER_SIZE     (sizeof(struct ti_i2c_desc) + sizeof(struct ti_i2c_firmware_rec))
+               /* Search for type 0xF2 record (firmware blank record) */
+               else if ((start_address = get_descriptor_addr(serial, I2C_DESC_TYPE_FIRMWARE_BLANK, rom_desc)) != 0) {
+#define HEADER_SIZE    (sizeof(struct ti_i2c_desc) + \
+                                       sizeof(struct ti_i2c_firmware_rec))
                        __u8 *header;
                        __u8 *vheader;
 
-                       header  = kmalloc (HEADER_SIZE, GFP_KERNEL);
+                       header = kmalloc(HEADER_SIZE, GFP_KERNEL);
                        if (!header) {
-                               dev_err (dev, "%s - out of memory.\n", __func__);
-                               kfree (rom_desc);
-                               kfree (ti_manuf_desc);
+                               dev_err(dev, "%s - out of memory.\n", __func__);
+                               kfree(rom_desc);
+                               kfree(ti_manuf_desc);
                                return -ENOMEM;
                        }
-                               
-                       vheader = kmalloc (HEADER_SIZE, GFP_KERNEL);
+
+                       vheader = kmalloc(HEADER_SIZE, GFP_KERNEL);
                        if (!vheader) {
-                               dev_err (dev, "%s - out of memory.\n", __func__);
-                               kfree (header);
-                               kfree (rom_desc);
-                               kfree (ti_manuf_desc);
+                               dev_err(dev, "%s - out of memory.\n", __func__);
+                               kfree(header);
+                               kfree(rom_desc);
+                               kfree(ti_manuf_desc);
                                return -ENOMEM;
                        }
-                       
-                       dbg ("%s - Found Type BLANK FIRMWARE (Type F2) record", __func__);
-
-                       // In order to update the I2C firmware we must change the type 2 record to type 0xF2.
-                       // This will force the UMP to come up in Boot Mode.  Then while in boot mode, the driver 
-                       // will download the latest firmware (padded to 15.5k) into the UMP ram. 
-                       // And finally when the device comes back up in download mode the driver will cause 
-                       // the new firmware to be copied from the UMP Ram to I2C and the firmware will update
-                       // the record type from 0xf2 to 0x02.
-                       status = BuildI2CFirmwareHeader(header, dev);
+
+                       dbg("%s - Found Type BLANK FIRMWARE (Type F2) record",
+                                                               __func__);
+
+                       /*
+                        * In order to update the I2C firmware we must change
+                        * the type 2 record to type 0xF2. This will force the
+                        * UMP to come up in Boot Mode.  Then while in boot
+                        * mode, the driver will download the latest firmware
+                        * (padded to 15.5k) into the UMP ram. Finally when the
+                        * device comes back up in download mode the driver
+                        * will cause the new firmware to be copied from the
+                        * UMP Ram to I2C and the firmware will update the
+                        * record type from 0xf2 to 0x02.
+                        */
+                       status = build_i2c_fw_hdr(header, dev);
                        if (status) {
-                               kfree (vheader);
-                               kfree (header);
-                               kfree (rom_desc);
-                               kfree (ti_manuf_desc);
+                               kfree(vheader);
+                               kfree(header);
+                               kfree(rom_desc);
+                               kfree(ti_manuf_desc);
                                return status;
                        }
 
-                       // Update I2C with type 0xf2 record with correct size and checksum
-                       status = TIWriteRom (serial,
+                       /* Update I2C with type 0xf2 record with correct
+                          size and checksum */
+                       status = write_rom(serial,
                                                start_address,
                                                HEADER_SIZE,
                                                header);
                        if (status) {
-                               kfree (vheader);
-                               kfree (header);
-                               kfree (rom_desc);
-                               kfree (ti_manuf_desc);
+                               kfree(vheader);
+                               kfree(header);
+                               kfree(rom_desc);
+                               kfree(ti_manuf_desc);
                                return status;
                        }
 
-                       // verify the write -- must do this in order for write to 
-                       // complete before we do the hardware reset
-                       status = TIReadRom (serial,
-                                               start_address,
-                                               HEADER_SIZE,
-                                               vheader);
+                       /* verify the write -- must do this in order for
+                          write to complete before we do the hardware reset */
+                       status = read_rom(serial, start_address,
+                                                       HEADER_SIZE, vheader);
 
                        if (status) {
-                               dbg ("%s - can't read header back", __func__);
-                               kfree (vheader);
-                               kfree (header);
-                               kfree (rom_desc);
-                               kfree (ti_manuf_desc);
+                               dbg("%s - can't read header back", __func__);
+                               kfree(vheader);
+                               kfree(header);
+                               kfree(rom_desc);
+                               kfree(ti_manuf_desc);
                                return status;
                        }
                        if (memcmp(vheader, header, HEADER_SIZE)) {
-                               dbg ("%s - write download record failed", __func__);
-                               kfree (vheader);
-                               kfree (header);
-                               kfree (rom_desc);
-                               kfree (ti_manuf_desc);
+                               dbg("%s - write download record failed",
+                                       __func__);
+                               kfree(vheader);
+                               kfree(header);
+                               kfree(rom_desc);
+                               kfree(ti_manuf_desc);
                                return status;
                        }
 
-                       kfree (vheader);
-                       kfree (header);
+                       kfree(vheader);
+                       kfree(header);
 
-                       dbg ("%s - Start firmware update", __func__);
+                       dbg("%s - Start firmware update", __func__);
 
-                       // Tell firmware to copy download image into I2C 
-                       status = TISendVendorRequestSync (serial->serial->dev,
-                                               UMPC_COPY_DNLD_TO_I2C,  // Request
-                                               0,                      // wValue 
-                                               0,                      // wIndex
-                                               NULL,                   // TransferBuffer
-                                               0);                     // TransferBufferLength
+                       /* Tell firmware to copy download image into I2C */
+                       status = ti_vsend_sync(serial->serial->dev,
+                                       UMPC_COPY_DNLD_TO_I2C, 0, 0, NULL, 0);
 
-                       dbg ("%s - Update complete 0x%x", __func__, status);
+                       dbg("%s - Update complete 0x%x", __func__, status);
                        if (status) {
-                               dev_err (dev, "%s - UMPC_COPY_DNLD_TO_I2C failed\n", __func__);
-                               kfree (rom_desc);
-                               kfree (ti_manuf_desc);
+                               dev_err(dev,
+                                       "%s - UMPC_COPY_DNLD_TO_I2C failed\n",
+                                                               __func__);
+                               kfree(rom_desc);
+                               kfree(ti_manuf_desc);
                                return status;
                        }
                }
 
                // The device is running the download code
-               kfree (rom_desc);
-               kfree (ti_manuf_desc);
+               kfree(rom_desc);
+               kfree(ti_manuf_desc);
                return 0;
        }
 
@@ -1355,32 +1349,26 @@ static int TIDownloadFirmware (struct edgeport_serial *serial)
        /********************************************************************/
        dbg("%s - RUNNING IN BOOT MODE", __func__);
 
-       // Configure the TI device so we can use the BULK pipes for download
-       status = TIConfigureBootDevice (serial->serial->dev);
+       /* Configure the TI device so we can use the BULK pipes for download */
+       status = config_boot_dev(serial->serial->dev);
        if (status)
                return status;
 
-       if (le16_to_cpu(serial->serial->dev->descriptor.idVendor) != USB_VENDOR_ID_ION) {
-               dbg ("%s - VID = 0x%x", __func__,
+       if (le16_to_cpu(serial->serial->dev->descriptor.idVendor)
+                                                       != USB_VENDOR_ID_ION) {
+               dbg("%s - VID = 0x%x", __func__,
                     le16_to_cpu(serial->serial->dev->descriptor.idVendor));
                serial->TI_I2C_Type = DTK_ADDR_SPACE_I2C_TYPE_II;
-               goto StayInBootMode;
+               goto stayinbootmode;
        }
 
-       // We have an ION device (I2c Must be programmed)
-       // Determine I2C image type
-       if (TIGetI2cTypeInBootMode(serial)) {
-               goto StayInBootMode;
-       }
+       /* We have an ION device (I2c Must be programmed)
+          Determine I2C image type */
+       if (i2c_type_bootmode(serial))
+               goto stayinbootmode;
 
-       // Registry variable set?
-       if (TIStayInBootMode) {
-               dbg ("%s - TIStayInBootMode", __func__);
-               goto StayInBootMode;
-       }
-
-       // Check for ION Vendor ID and that the I2C is valid
-       if (!TiValidateI2cImage(serial)) {
+       /* Check for ION Vendor ID and that the I2C is valid */
+       if (!check_i2c_image(serial)) {
                struct ti_i2c_image_header *header;
                int i;
                __u8 cs = 0;
@@ -1393,49 +1381,52 @@ static int TIDownloadFirmware (struct edgeport_serial *serial)
                /* Validate Hardware version number
                 * Read Manufacturing Descriptor from TI Based Edgeport
                 */
-               ti_manuf_desc = kmalloc (sizeof (*ti_manuf_desc), GFP_KERNEL);
+               ti_manuf_desc = kmalloc(sizeof(*ti_manuf_desc), GFP_KERNEL);
                if (!ti_manuf_desc) {
-                       dev_err (dev, "%s - out of memory.\n", __func__);
+                       dev_err(dev, "%s - out of memory.\n", __func__);
                        return -ENOMEM;
                }
-               status = TIReadManufDescriptor (serial, (__u8 *)ti_manuf_desc);
+               status = get_manuf_info(serial, (__u8 *)ti_manuf_desc);
                if (status) {
-                       kfree (ti_manuf_desc);
-                       goto StayInBootMode;
+                       kfree(ti_manuf_desc);
+                       goto stayinbootmode;
                }
 
-               // Check for version 2
-               if (!ignore_cpu_rev && TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev) < 2) {
-                       dbg ("%s - Wrong CPU Rev %d (Must be 2)", __func__,
-                            TI_GET_CPU_REVISION(ti_manuf_desc->CpuRev_BoardRev));
-                       kfree (ti_manuf_desc);
-                       goto StayInBootMode;
+               /* Check for version 2 */
+               if (!ignore_cpu_rev && ti_cpu_rev(ti_manuf_desc) < 2) {
+                       dbg("%s - Wrong CPU Rev %d (Must be 2)",
+                                       __func__, ti_cpu_rev(ti_manuf_desc));
+                       kfree(ti_manuf_desc);
+                       goto stayinbootmode;
                }
 
-               kfree (ti_manuf_desc);
+               kfree(ti_manuf_desc);
 
-               // In order to update the I2C firmware we must change the type 2 record to type 0xF2.
-               // This will force the UMP to come up in Boot Mode.  Then while in boot mode, the driver 
-               // will download the latest firmware (padded to 15.5k) into the UMP ram. 
-               // And finally when the device comes back up in download mode the driver will cause 
-               // the new firmware to be copied from the UMP Ram to I2C and the firmware will update
-               // the record type from 0xf2 to 0x02.
-               
                /*
+                * In order to update the I2C firmware we must change the type
+                * 2 record to type 0xF2. This will force the UMP to come up
+                * in Boot Mode.  Then while in boot mode, the driver will
+                * download the latest firmware (padded to 15.5k) into the
+                * UMP ram. Finally when the device comes back up in download
+                * mode the driver will cause the new firmware to be copied
+                * from the UMP Ram to I2C and the firmware will update the
+                * record type from 0xf2 to 0x02.
+                *
                 * Do we really have to copy the whole firmware image,
                 * or could we do this in place!
                 */
 
-               // Allocate a 15.5k buffer + 3 byte header
-               buffer_size = (((1024 * 16) - 512) + sizeof(struct ti_i2c_image_header));
-               buffer = kmalloc (buffer_size, GFP_KERNEL);
+               /* Allocate a 15.5k buffer + 3 byte header */
+               buffer_size = (((1024 * 16) - 512) +
+                                       sizeof(struct ti_i2c_image_header));
+               buffer = kmalloc(buffer_size, GFP_KERNEL);
                if (!buffer) {
-                       dev_err (dev, "%s - out of memory\n", __func__);
+                       dev_err(dev, "%s - out of memory\n", __func__);
                        return -ENOMEM;
                }
-               
-               // Initialize the buffer to 0xff (pad the buffer)
-               memset (buffer, 0xff, buffer_size);
+
+               /* Initialize the buffer to 0xff (pad the buffer) */
+               memset(buffer, 0xff, buffer_size);
 
                err = request_firmware(&fw, fw_name, dev);
                if (err) {
@@ -1447,38 +1438,43 @@ static int TIDownloadFirmware (struct edgeport_serial *serial)
                memcpy(buffer, &fw->data[4], fw->size - 4);
                release_firmware(fw);
 
-               for(i = sizeof(struct ti_i2c_image_header); i < buffer_size; i++) {
+               for (i = sizeof(struct ti_i2c_image_header);
+                               i < buffer_size; i++) {
                        cs = (__u8)(cs + buffer[i]);
                }
-               
+
                header = (struct ti_i2c_image_header *)buffer;
-               
-               // update length and checksum after padding
-               header->Length   = cpu_to_le16((__u16)(buffer_size - sizeof(struct ti_i2c_image_header)));
+
+               /* update length and checksum after padding */
+               header->Length   = cpu_to_le16((__u16)(buffer_size -
+                                       sizeof(struct ti_i2c_image_header)));
                header->CheckSum = cs;
 
-               // Download the operational code 
-               dbg ("%s - Downloading operational code image (TI UMP)", __func__);
-               status = TIDownloadCodeImage (serial, buffer, buffer_size);
+               /* Download the operational code  */
+               dbg("%s - Downloading operational code image (TI UMP)",
+                                                               __func__);
+               status = download_code(serial, buffer, buffer_size);
 
-               kfree (buffer);
+               kfree(buffer);
 
                if (status) {
-                       dbg ("%s - Error downloading operational code image", __func__);
+                       dbg("%s - Error downloading operational code image",
+                                                               __func__);
                        return status;
                }
 
-               // Device will reboot
+               /* Device will reboot */
                serial->product_info.TiMode = TI_MODE_TRANSITIONING;
 
-               dbg ("%s - Download successful -- Device rebooting...", __func__);
+               dbg("%s - Download successful -- Device rebooting...",
+                                                               __func__);
 
                /* return an error on purpose */
                return -ENODEV;
        }
 
-StayInBootMode:
-       // Eprom is invalid or blank stay in boot mode
+stayinbootmode:
+       /* Eprom is invalid or blank stay in boot mode */
        dbg("%s - STAYING IN BOOT MODE", __func__);
        serial->product_info.TiMode = TI_MODE_BOOT;
 
@@ -1486,156 +1482,33 @@ StayInBootMode:
 }
 
 
-static int TISetDtr (struct edgeport_port *port)
-{
-       int port_number = port->port->number - port->port->serial->minor;
-
-       dbg ("%s", __func__);
-       port->shadow_mcr |= MCR_DTR;
-
-       return TIWriteCommandSync (port->port->serial->dev,
-                               UMPC_SET_CLR_DTR,
-                               (__u8)(UMPM_UART1_PORT + port_number),
-                               1,      /* set */
-                               NULL,
-                               0);
-}
-
-static int TIClearDtr (struct edgeport_port *port)
-{
-       int port_number = port->port->number - port->port->serial->minor;
-
-       dbg ("%s", __func__);
-       port->shadow_mcr &= ~MCR_DTR;
-
-       return TIWriteCommandSync (port->port->serial->dev,
-                               UMPC_SET_CLR_DTR,
-                               (__u8)(UMPM_UART1_PORT + port_number),
-                               0,      /* clear */
-                               NULL,
-                               0);
-}
-
-static int TISetRts (struct edgeport_port *port)
-{
-       int port_number = port->port->number - port->port->serial->minor;
-
-       dbg ("%s", __func__);
-       port->shadow_mcr |= MCR_RTS;
-
-       return TIWriteCommandSync (port->port->serial->dev,
-                               UMPC_SET_CLR_RTS,
-                               (__u8)(UMPM_UART1_PORT + port_number),
-                               1,      /* set */
-                               NULL,
-                               0);
-}
-
-static int TIClearRts (struct edgeport_port *port)
-{
-       int port_number = port->port->number - port->port->serial->minor;
-
-       dbg ("%s", __func__);
-       port->shadow_mcr &= ~MCR_RTS;
-
-       return TIWriteCommandSync (port->port->serial->dev,
-                               UMPC_SET_CLR_RTS,
-                               (__u8)(UMPM_UART1_PORT + port_number),
-                               0,      /* clear */
-                               NULL,
-                               0);
-}
-
-static int TISetLoopBack (struct edgeport_port *port)
-{
-       int port_number = port->port->number - port->port->serial->minor;
-
-       dbg ("%s", __func__);
-
-       return TIWriteCommandSync (port->port->serial->dev,
-                               UMPC_SET_CLR_LOOPBACK,
-                               (__u8)(UMPM_UART1_PORT + port_number),
-                               1,      /* set */
-                               NULL,
-                               0);
-}
-
-static int TIClearLoopBack (struct edgeport_port *port)
-{
-       int port_number = port->port->number - port->port->serial->minor;
-
-       dbg ("%s", __func__);
-
-       return TIWriteCommandSync (port->port->serial->dev,
-                               UMPC_SET_CLR_LOOPBACK,
-                               (__u8)(UMPM_UART1_PORT + port_number),
-                               0,      /* clear */
-                               NULL,
-                               0);
-}
-
-static int TISetBreak (struct edgeport_port *port)
+static int ti_do_config(struct edgeport_port *port, int feature, int on)
 {
        int port_number = port->port->number - port->port->serial->minor;
-
-       dbg ("%s", __func__);
-
-       return TIWriteCommandSync (port->port->serial->dev,
-                               UMPC_SET_CLR_BREAK,
-                               (__u8)(UMPM_UART1_PORT + port_number),
-                               1,      /* set */
-                               NULL,
-                               0);
+       on = !!on;      /* 1 or 0 not bitmask */
+       return send_cmd(port->port->serial->dev,
+                       feature, (__u8)(UMPM_UART1_PORT + port_number),
+                       on, NULL, 0);
 }
 
-static int TIClearBreak (struct edgeport_port *port)
-{
-       int port_number = port->port->number - port->port->serial->minor;
-
-       dbg ("%s", __func__);
 
-       return TIWriteCommandSync (port->port->serial->dev,
-                               UMPC_SET_CLR_BREAK,
-                               (__u8)(UMPM_UART1_PORT + port_number),
-                               0,      /* clear */
-                               NULL,
-                               0);
-}
-
-static int TIRestoreMCR (struct edgeport_port *port, __u8 mcr)
+static int restore_mcr(struct edgeport_port *port, __u8 mcr)
 {
        int status = 0;
 
-       dbg ("%s - %x", __func__, mcr);
-
-       if (mcr & MCR_DTR)
-               status = TISetDtr (port);
-       else
-               status = TIClearDtr (port);
+       dbg("%s - %x", __func__, mcr);
 
+       status = ti_do_config(port, UMPC_SET_CLR_DTR, mcr & MCR_DTR);
        if (status)
                return status;
-
-       if (mcr & MCR_RTS)
-               status = TISetRts (port);
-       else
-               status = TIClearRts (port);
-
+       status = ti_do_config(port, UMPC_SET_CLR_RTS, mcr & MCR_RTS);
        if (status)
                return status;
-
-       if (mcr & MCR_LOOPBACK)
-               status = TISetLoopBack (port);
-       else
-               status = TIClearLoopBack (port);
-
-       return status;
+       return ti_do_config(port, UMPC_SET_CLR_LOOPBACK, mcr & MCR_LOOPBACK);
 }
 
-
-
 /* Convert TI LSR to standard UART flags */
-static __u8 MapLineStatus (__u8 ti_lsr)
+static __u8 map_line_status(__u8 ti_lsr)
 {
        __u8 lsr = 0;
 
@@ -1647,22 +1520,23 @@ static __u8 MapLineStatus (__u8 ti_lsr)
        MAP_FLAG(UMP_UART_LSR_PE_MASK, LSR_PAR_ERR)     /* parity error */
        MAP_FLAG(UMP_UART_LSR_FE_MASK, LSR_FRM_ERR)     /* framing error */
        MAP_FLAG(UMP_UART_LSR_BR_MASK, LSR_BREAK)       /* break detected */
-       MAP_FLAG(UMP_UART_LSR_RX_MASK, LSR_RX_AVAIL)    /* receive data available */
-       MAP_FLAG(UMP_UART_LSR_TX_MASK, LSR_TX_EMPTY)    /* transmit holding register empty */
+       MAP_FLAG(UMP_UART_LSR_RX_MASK, LSR_RX_AVAIL)    /* rx data available */
+       MAP_FLAG(UMP_UART_LSR_TX_MASK, LSR_TX_EMPTY)    /* tx hold reg empty */
 
 #undef MAP_FLAG
 
        return lsr;
 }
 
-static void handle_new_msr (struct edgeport_port *edge_port, __u8 msr)
+static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr)
 {
        struct async_icount *icount;
        struct tty_struct *tty;
 
-       dbg ("%s - %02x", __func__, msr);
+       dbg("%s - %02x", __func__, msr);
 
-       if (msr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR | EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) {
+       if (msr & (EDGEPORT_MSR_DELTA_CTS | EDGEPORT_MSR_DELTA_DSR |
+                       EDGEPORT_MSR_DELTA_RI | EDGEPORT_MSR_DELTA_CD)) {
                icount = &edge_port->icount;
 
                /* update input line counters */
@@ -1674,13 +1548,13 @@ static void handle_new_msr (struct edgeport_port *edge_port, __u8 msr)
                        icount->dcd++;
                if (msr & EDGEPORT_MSR_DELTA_RI)
                        icount->rng++;
-               wake_up_interruptible (&edge_port->delta_msr_wait);
+               wake_up_interruptible(&edge_port->delta_msr_wait);
        }
 
        /* Save the new modem status */
        edge_port->shadow_msr = msr & 0xf0;
 
-       tty = edge_port->port->tty;
+       tty = edge_port->port->port.tty;
        /* handle CTS flow control */
        if (tty && C_CRTSCTS(tty)) {
                if (msr & EDGEPORT_MSR_CTS) {
@@ -1694,26 +1568,27 @@ static void handle_new_msr (struct edgeport_port *edge_port, __u8 msr)
        return;
 }
 
-static void handle_new_lsr (struct edgeport_port *edge_port, int lsr_data, __u8 lsr, __u8 data)
+static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data,
+                                                       __u8 lsr, __u8 data)
 {
        struct async_icount *icount;
-       __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | LSR_FRM_ERR | LSR_BREAK));
+       __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR |
+                                               LSR_FRM_ERR | LSR_BREAK));
 
-       dbg ("%s - %02x", __func__, new_lsr);
+       dbg("%s - %02x", __func__, new_lsr);
 
        edge_port->shadow_lsr = lsr;
 
-       if (new_lsr & LSR_BREAK) {
+       if (new_lsr & LSR_BREAK)
                /*
                 * Parity and Framing errors only count if they
                 * occur exclusive of a break being received.
                 */
                new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK);
-       }
 
        /* Place LSR data byte into Rx buffer */
-       if (lsr_data && edge_port->port->tty)
-               edge_tty_recv(&edge_port->port->dev, edge_port->port->tty, &data, 1);
+       if (lsr_data && edge_port->port->port.tty)
+               edge_tty_recv(&edge_port->port->dev, edge_port->port->port.tty, &data, 1);
 
        /* update input line counters */
        icount = &edge_port->icount;
@@ -1728,7 +1603,7 @@ static void handle_new_lsr (struct edgeport_port *edge_port, int lsr_data, __u8
 }
 
 
-static void edge_interrupt_callback (struct urb *urb)
+static void edge_interrupt_callback(struct urb *urb)
 {
        struct edgeport_serial *edge_serial = urb->context;
        struct usb_serial_port *port;
@@ -1762,66 +1637,71 @@ static void edge_interrupt_callback (struct urb *urb)
        }
 
        if (!length) {
-               dbg ("%s - no data in urb", __func__);
+               dbg("%s - no data in urb", __func__);
                goto exit;
        }
-               
-       usb_serial_debug_data(debug, &edge_serial->serial->dev->dev, __func__, length, data);
-               
+
+       usb_serial_debug_data(debug, &edge_serial->serial->dev->dev,
+                                               __func__, length, data);
+
        if (length != 2) {
-               dbg ("%s - expecting packet of size 2, got %d", __func__, length);
+               dbg("%s - expecting packet of size 2, got %d",
+                                                       __func__, length);
                goto exit;
        }
 
-       port_number = TIUMP_GET_PORT_FROM_CODE (data[0]);
-       function    = TIUMP_GET_FUNC_FROM_CODE (data[0]);
-       dbg ("%s - port_number %d, function %d, info 0x%x",
+       port_number = TIUMP_GET_PORT_FROM_CODE(data[0]);
+       function    = TIUMP_GET_FUNC_FROM_CODE(data[0]);
+       dbg("%s - port_number %d, function %d, info 0x%x",
             __func__, port_number, function, data[1]);
        port = edge_serial->serial->port[port_number];
        edge_port = usb_get_serial_port_data(port);
        if (!edge_port) {
-               dbg ("%s - edge_port not found", __func__);
+               dbg("%s - edge_port not found", __func__);
                return;
        }
        switch (function) {
        case TIUMP_INTERRUPT_CODE_LSR:
-               lsr = MapLineStatus(data[1]);
+               lsr = map_line_status(data[1]);
                if (lsr & UMP_UART_LSR_DATA_MASK) {
-                       /* Save the LSR event for bulk read completion routine */
-                       dbg ("%s - LSR Event Port %u LSR Status = %02x",
+                       /* Save the LSR event for bulk read
+                          completion routine */
+                       dbg("%s - LSR Event Port %u LSR Status = %02x",
                             __func__, port_number, lsr);
                        edge_port->lsr_event = 1;
                        edge_port->lsr_mask = lsr;
                } else {
-                       dbg ("%s - ===== Port %d LSR Status = %02x ======",
+                       dbg("%s - ===== Port %d LSR Status = %02x ======",
                             __func__, port_number, lsr);
-                       handle_new_lsr (edge_port, 0, lsr, 0);
+                       handle_new_lsr(edge_port, 0, lsr, 0);
                }
                break;
 
-       case TIUMP_INTERRUPT_CODE_MSR:  // MSR
+       case TIUMP_INTERRUPT_CODE_MSR:  /* MSR */
                /* Copy MSR from UMP */
                msr = data[1];
-               dbg ("%s - ===== Port %u MSR Status = %02x ======\n",
+               dbg("%s - ===== Port %u MSR Status = %02x ======\n",
                     __func__, port_number, msr);
-               handle_new_msr (edge_port, msr);
+               handle_new_msr(edge_port, msr);
                break;
 
        default:
-               dev_err (&urb->dev->dev, "%s - Unknown Interrupt code from UMP %x\n",
-                        __func__, data[1]);
+               dev_err(&urb->dev->dev,
+                       "%s - Unknown Interrupt code from UMP %x\n",
+                       __func__, data[1]);
                break;
-               
+
        }
 
 exit:
-       retval = usb_submit_urb (urb, GFP_ATOMIC);
+       retval = usb_submit_urb(urb, GFP_ATOMIC);
        if (retval)
-               dev_err (&urb->dev->dev, "%s - usb_submit_urb failed with result %d\n",
+               dev_err(&urb->dev->dev,
+                       "%s - usb_submit_urb failed with result %d\n",
                         __func__, retval);
 }
 
-static void edge_bulk_in_callback (struct urb *urb)
+static void edge_bulk_in_callback(struct urb *urb)
 {
        struct edgeport_port *edge_port = urb->context;
        unsigned char *data = urb->transfer_buffer;
@@ -1844,15 +1724,16 @@ static void edge_bulk_in_callback (struct urb *urb)
                    __func__, status);
                return;
        default:
-               dev_err (&urb->dev->dev,"%s - nonzero read bulk status received: %d\n",
-                    __func__, status);
+               dev_err(&urb->dev->dev,
+                       "%s - nonzero read bulk status received: %d\n",
+                            __func__, status);
        }
 
        if (status == -EPIPE)
                goto exit;
 
        if (status) {
-               dev_err(&urb->dev->dev,"%s - stopping read!\n", __func__);
+               dev_err(&urb->dev->dev, "%s - stopping read!\n", __func__);
                return;
        }
 
@@ -1860,23 +1741,24 @@ static void edge_bulk_in_callback (struct urb *urb)
 
        if (edge_port->lsr_event) {
                edge_port->lsr_event = 0;
-               dbg ("%s ===== Port %u LSR Status = %02x, Data = %02x ======",
+               dbg("%s ===== Port %u LSR Status = %02x, Data = %02x ======",
                     __func__, port_number, edge_port->lsr_mask, *data);
-               handle_new_lsr (edge_port, 1, edge_port->lsr_mask, *data);
+               handle_new_lsr(edge_port, 1, edge_port->lsr_mask, *data);
                /* Adjust buffer length/pointer */
                --urb->actual_length;
                ++data;
        }
 
-       tty = edge_port->port->tty;
+       tty = edge_port->port->port.tty;
        if (tty && urb->actual_length) {
-               usb_serial_debug_data(debug, &edge_port->port->dev, __func__, urb->actual_length, data);
-
-               if (edge_port->close_pending) {
-                       dbg ("%s - close is pending, dropping data on the floor.", __func__);
-               } else {
-                       edge_tty_recv(&edge_port->port->dev, tty, data, urb->actual_length);
-               }
+               usb_serial_debug_data(debug, &edge_port->port->dev,
+                                       __func__, urb->actual_length, data);
+               if (edge_port->close_pending)
+                       dbg("%s - close pending, dropping data on the floor",
+                                                               __func__);
+               else
+                       edge_tty_recv(&edge_port->port->dev, tty, data,
+                                                       urb->actual_length);
                edge_port->icount.rx += urb->actual_length;
        }
 
@@ -1891,37 +1773,31 @@ exit:
        }
        spin_unlock(&edge_port->ep_lock);
        if (retval)
-               dev_err (&urb->dev->dev, "%s - usb_submit_urb failed with result %d\n",
+               dev_err(&urb->dev->dev,
+                       "%s - usb_submit_urb failed with result %d\n",
                         __func__, retval);
 }
 
-static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned char *data, int length)
+static void edge_tty_recv(struct device *dev, struct tty_struct *tty,
+                                       unsigned char *data, int length)
 {
-       int cnt;
-
-       do {
-               cnt = tty_buffer_request_room(tty, length);
-               if (cnt < length) {
-                       dev_err(dev, "%s - dropping data, %d bytes lost\n",
-                               __func__, length - cnt);
-                       if(cnt == 0)
-                               break;
-               }
-               tty_insert_flip_string(tty, data, cnt);
-               data += cnt;
-               length -= cnt;
-       } while (length > 0);
+       int queued;
 
+       tty_buffer_request_room(tty, length);
+       queued = tty_insert_flip_string(tty, data, length);
+       if (queued < length)
+               dev_err(dev, "%s - dropping data, %d bytes lost\n",
+                       __func__, length - queued);
        tty_flip_buffer_push(tty);
 }
 
-static void edge_bulk_out_callback (struct urb *urb)
+static void edge_bulk_out_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        int status = urb->status;
 
-       dbg ("%s - port %d", __func__, port->number);
+       dbg("%s - port %d", __func__, port->number);
 
        edge_port->ep_write_urb_in_use = 0;
 
@@ -1942,10 +1818,11 @@ static void edge_bulk_out_callback (struct urb *urb)
        }
 
        /* send any buffered data */
-       edge_send(port);
+       edge_send(port->port.tty);
 }
 
-static int edge_open (struct usb_serial_port *port, struct file * filp)
+static int edge_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        struct edgeport_serial *edge_serial;
@@ -1961,122 +1838,125 @@ static int edge_open (struct usb_serial_port *port, struct file * filp)
        if (edge_port == NULL)
                return -ENODEV;
 
-       port->tty->low_latency = low_latency;
+       if (tty)
+               tty->low_latency = low_latency;
 
        port_number = port->number - port->serial->minor;
        switch (port_number) {
-               case 0:
-                       edge_port->uart_base = UMPMEM_BASE_UART1;
-                       edge_port->dma_address = UMPD_OEDB1_ADDRESS;
-                       break;
-               case 1:
-                       edge_port->uart_base = UMPMEM_BASE_UART2;
-                       edge_port->dma_address = UMPD_OEDB2_ADDRESS;
-                       break;
-               default:
-                       dev_err (&port->dev, "Unknown port number!!!\n");
-                       return -ENODEV;
+       case 0:
+               edge_port->uart_base = UMPMEM_BASE_UART1;
+               edge_port->dma_address = UMPD_OEDB1_ADDRESS;
+               break;
+       case 1:
+               edge_port->uart_base = UMPMEM_BASE_UART2;
+               edge_port->dma_address = UMPD_OEDB2_ADDRESS;
+               break;
+       default:
+               dev_err(&port->dev, "Unknown port number!!!\n");
+               return -ENODEV;
        }
 
-       dbg ("%s - port_number = %d, uart_base = %04x, dma_address = %04x",
-            __func__, port_number, edge_port->uart_base, edge_port->dma_address);
+       dbg("%s - port_number = %d, uart_base = %04x, dma_address = %04x",
+                               __func__, port_number, edge_port->uart_base,
+                               edge_port->dma_address);
 
        dev = port->serial->dev;
 
-       memset (&(edge_port->icount), 0x00, sizeof(edge_port->icount));
-       init_waitqueue_head (&edge_port->delta_msr_wait);
+       memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount));
+       init_waitqueue_head(&edge_port->delta_msr_wait);
 
        /* turn off loopback */
-       status = TIClearLoopBack (edge_port);
+       status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0);
        if (status) {
-               dev_err(&port->dev,"%s - cannot send clear loopback command, %d\n",
+               dev_err(&port->dev,
+                               "%s - cannot send clear loopback command, %d\n",
                        __func__, status);
                return status;
        }
-       
+
        /* set up the port settings */
-       edge_set_termios (port, port->tty->termios);
+       if (tty)
+               edge_set_termios(tty, port, port->port.tty->termios);
 
        /* open up the port */
 
        /* milliseconds to timeout for DMA transfer */
        transaction_timeout = 2;
 
-       edge_port->ump_read_timeout = max (20, ((transaction_timeout * 3) / 2) );
+       edge_port->ump_read_timeout =
+                               max(20, ((transaction_timeout * 3) / 2));
 
-       // milliseconds to timeout for DMA transfer
-       open_settings = (u8)(UMP_DMA_MODE_CONTINOUS | 
-                            UMP_PIPE_TRANS_TIMEOUT_ENA | 
+       /* milliseconds to timeout for DMA transfer */
+       open_settings = (u8)(UMP_DMA_MODE_CONTINOUS |
+                            UMP_PIPE_TRANS_TIMEOUT_ENA |
                             (transaction_timeout << 2));
 
-       dbg ("%s - Sending UMPC_OPEN_PORT", __func__);
+       dbg("%s - Sending UMPC_OPEN_PORT", __func__);
 
        /* Tell TI to open and start the port */
-       status = TIWriteCommandSync (dev,
-                                       UMPC_OPEN_PORT,
-                                       (u8)(UMPM_UART1_PORT + port_number),
-                                       open_settings,
-                                       NULL,
-                                       0);
+       status = send_cmd(dev, UMPC_OPEN_PORT,
+               (u8)(UMPM_UART1_PORT + port_number), open_settings, NULL, 0);
        if (status) {
-               dev_err(&port->dev,"%s - cannot send open command, %d\n", __func__, status);
+               dev_err(&port->dev, "%s - cannot send open command, %d\n",
+                                                       __func__, status);
                return status;
        }
 
        /* Start the DMA? */
-       status = TIWriteCommandSync (dev,
-                                       UMPC_START_PORT,
-                                       (u8)(UMPM_UART1_PORT + port_number),
-                                       0,
-                                       NULL,
-                                       0);
+       status = send_cmd(dev, UMPC_START_PORT,
+               (u8)(UMPM_UART1_PORT + port_number), 0, NULL, 0);
        if (status) {
-               dev_err(&port->dev,"%s - cannot send start DMA command, %d\n", __func__, status);
+               dev_err(&port->dev, "%s - cannot send start DMA command, %d\n",
+                                                       __func__, status);
                return status;
        }
 
        /* Clear TX and RX buffers in UMP */
-       status = TIPurgeDataSync (port, UMP_PORT_DIR_OUT | UMP_PORT_DIR_IN);
+       status = purge_port(port, UMP_PORT_DIR_OUT | UMP_PORT_DIR_IN);
        if (status) {
-               dev_err(&port->dev,"%s - cannot send clear buffers command, %d\n", __func__, status);
+               dev_err(&port->dev,
+                       "%s - cannot send clear buffers command, %d\n",
+                       __func__, status);
                return status;
        }
 
        /* Read Initial MSR */
-       status = TIReadVendorRequestSync (dev,
-                                       UMPC_READ_MSR,  // Request
-                                       0,              // wValue
-                                       (__u16)(UMPM_UART1_PORT + port_number), // wIndex (Address)
-                                       &edge_port->shadow_msr,                 // TransferBuffer
-                                       1);                                     // TransferBufferLength
+       status = ti_vread_sync(dev, UMPC_READ_MSR, 0,
+                               (__u16)(UMPM_UART1_PORT + port_number),
+                               &edge_port->shadow_msr, 1);
        if (status) {
-               dev_err(&port->dev,"%s - cannot send read MSR command, %d\n", __func__, status);
+               dev_err(&port->dev, "%s - cannot send read MSR command, %d\n",
+                                                       __func__, status);
                return status;
        }
 
-       dbg ("ShadowMSR 0x%X", edge_port->shadow_msr);
+       dbg("ShadowMSR 0x%X", edge_port->shadow_msr);
+
        /* Set Initial MCR */
        edge_port->shadow_mcr = MCR_RTS | MCR_DTR;
-       dbg ("ShadowMCR 0x%X", edge_port->shadow_mcr);
+       dbg("ShadowMCR 0x%X", edge_port->shadow_mcr);
 
        edge_serial = edge_port->edge_serial;
        if (mutex_lock_interruptible(&edge_serial->es_lock))
                return -ERESTARTSYS;
        if (edge_serial->num_ports_open == 0) {
-               /* we are the first port to be opened, let's post the interrupt urb */
+               /* we are the first port to open, post the interrupt urb */
                urb = edge_serial->serial->port[0]->interrupt_in_urb;
                if (!urb) {
-                       dev_err (&port->dev, "%s - no interrupt urb present, exiting\n", __func__);
+                       dev_err(&port->dev,
+                               "%s - no interrupt urb present, exiting\n",
+                               __func__);
                        status = -EINVAL;
                        goto release_es_lock;
                }
                urb->complete = edge_interrupt_callback;
                urb->context = edge_serial;
                urb->dev = dev;
-               status = usb_submit_urb (urb, GFP_KERNEL);
+               status = usb_submit_urb(urb, GFP_KERNEL);
                if (status) {
-                       dev_err (&port->dev, "%s - usb_submit_urb failed with value %d\n", __func__, status);
+                       dev_err(&port->dev,
+                               "%s - usb_submit_urb failed with value %d\n",
+                                       __func__, status);
                        goto release_es_lock;
                }
        }
@@ -2085,13 +1965,14 @@ static int edge_open (struct usb_serial_port *port, struct file * filp)
         * reset the data toggle on the bulk endpoints to work around bug in
         * host controllers where things get out of sync some times
         */
-       usb_clear_halt (dev, port->write_urb->pipe);
-       usb_clear_halt (dev, port->read_urb->pipe);
+       usb_clear_halt(dev, port->write_urb->pipe);
+       usb_clear_halt(dev, port->read_urb->pipe);
 
        /* start up our bulk read urb */
        urb = port->read_urb;
        if (!urb) {
-               dev_err (&port->dev, "%s - no read urb present, exiting\n", __func__);
+               dev_err(&port->dev, "%s - no read urb present, exiting\n",
+                                                               __func__);
                status = -EINVAL;
                goto unlink_int_urb;
        }
@@ -2099,9 +1980,11 @@ static int edge_open (struct usb_serial_port *port, struct file * filp)
        urb->complete = edge_bulk_in_callback;
        urb->context = edge_port;
        urb->dev = dev;
-       status = usb_submit_urb (urb, GFP_KERNEL);
+       status = usb_submit_urb(urb, GFP_KERNEL);
        if (status) {
-               dev_err (&port->dev, "%s - read bulk usb_submit_urb failed with value %d\n", __func__, status);
+               dev_err(&port->dev,
+                       "%s - read bulk usb_submit_urb failed with value %d\n",
+                               __func__, status);
                goto unlink_int_urb;
        }
 
@@ -2119,7 +2002,8 @@ release_es_lock:
        return status;
 }
 
-static void edge_close (struct usb_serial_port *port, struct file *filp)
+static void edge_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct edgeport_serial *edge_serial;
        struct edgeport_port *edge_port;
@@ -2127,18 +2011,18 @@ static void edge_close (struct usb_serial_port *port, struct file *filp)
        int status;
 
        dbg("%s - port %d", __func__, port->number);
-                        
+
        edge_serial = usb_get_serial_data(port->serial);
        edge_port = usb_get_serial_port_data(port);
-       if ((edge_serial == NULL) || (edge_port == NULL))
+       if (edge_serial == NULL || edge_port == NULL)
                return;
-       
-       /* The bulkreadcompletion routine will check 
+
+       /* The bulkreadcompletion routine will check
         * this flag and dump add read data */
        edge_port->close_pending = 1;
 
        /* chase the port close and flush */
-       TIChasePort (edge_port, (HZ*closing_wait)/100, 1);
+       chase_port(edge_port, (HZ * closing_wait) / 100, 1);
 
        usb_kill_urb(port->read_urb);
        usb_kill_urb(port->write_urb);
@@ -2148,7 +2032,7 @@ static void edge_close (struct usb_serial_port *port, struct file *filp)
         * send a close port command to it */
        dbg("%s - send umpc_close_port", __func__);
        port_number = port->number - port->serial->minor;
-       status = TIWriteCommandSync (port->serial->dev,
+       status = send_cmd(port->serial->dev,
                                     UMPC_CLOSE_PORT,
                                     (__u8)(UMPM_UART1_PORT + port_number),
                                     0,
@@ -2167,7 +2051,8 @@ static void edge_close (struct usb_serial_port *port, struct file *filp)
        dbg("%s - exited", __func__);
 }
 
-static int edge_write (struct usb_serial_port *port, const unsigned char *data, int count)
+static int edge_write(struct tty_struct *tty, struct usb_serial_port *port,
+                               const unsigned char *data, int count)
 {
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        unsigned long flags;
@@ -2188,16 +2073,16 @@ static int edge_write (struct usb_serial_port *port, const unsigned char *data,
        count = edge_buf_put(edge_port->ep_out_buf, data, count);
        spin_unlock_irqrestore(&edge_port->ep_lock, flags);
 
-       edge_send(port);
+       edge_send(tty);
 
        return count;
 }
 
-static void edge_send(struct usb_serial_port *port)
+static void edge_send(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        int count, result;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
-       struct tty_struct *tty = port->tty;
        unsigned long flags;
 
 
@@ -2223,11 +2108,12 @@ static void edge_send(struct usb_serial_port *port)
 
        spin_unlock_irqrestore(&edge_port->ep_lock, flags);
 
-       usb_serial_debug_data(debug, &port->dev, __func__, count, port->write_urb->transfer_buffer);
+       usb_serial_debug_data(debug, &port->dev, __func__, count,
+                               port->write_urb->transfer_buffer);
 
        /* set up our urb */
-       usb_fill_bulk_urb (port->write_urb, port->serial->dev,
-                          usb_sndbulkpipe (port->serial->dev,
+       usb_fill_bulk_urb(port->write_urb, port->serial->dev,
+                          usb_sndbulkpipe(port->serial->dev,
                                            port->bulk_out_endpointAddress),
                           port->write_urb->transfer_buffer, count,
                           edge_bulk_out_callback,
@@ -2236,23 +2122,23 @@ static void edge_send(struct usb_serial_port *port)
        /* send the data out the bulk port */
        result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
        if (result) {
-               dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result);
+               dev_err(&port->dev,
+                       "%s - failed submitting write urb, error %d\n",
+                               __func__, result);
                edge_port->ep_write_urb_in_use = 0;
-               // TODO: reschedule edge_send
-       } else {
+               /* TODO: reschedule edge_send */
+       } else
                edge_port->icount.tx += count;
-       }
 
        /* wakeup any process waiting for writes to complete */
        /* there is now more room in the buffer for new writes */
-       if (tty) {
-               /* let the tty driver wakeup if it has a special write_wakeup function */
+       if (tty)
                tty_wakeup(tty);
-       }
 }
 
-static int edge_write_room (struct usb_serial_port *port)
+static int edge_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        int room = 0;
        unsigned long flags;
@@ -2260,9 +2146,9 @@ static int edge_write_room (struct usb_serial_port *port)
        dbg("%s - port %d", __func__, port->number);
 
        if (edge_port == NULL)
-               return -ENODEV;
+               return 0;
        if (edge_port->close_pending == 1)
-               return -ENODEV;
+               return 0;
 
        spin_lock_irqsave(&edge_port->ep_lock, flags);
        room = edge_buf_space_avail(edge_port->ep_out_buf);
@@ -2272,8 +2158,9 @@ static int edge_write_room (struct usb_serial_port *port)
        return room;
 }
 
-static int edge_chars_in_buffer (struct usb_serial_port *port)
+static int edge_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        int chars = 0;
        unsigned long flags;
@@ -2281,22 +2168,22 @@ static int edge_chars_in_buffer (struct usb_serial_port *port)
        dbg("%s - port %d", __func__, port->number);
 
        if (edge_port == NULL)
-               return -ENODEV;
+               return 0;
        if (edge_port->close_pending == 1)
-               return -ENODEV;
+               return 0;
 
        spin_lock_irqsave(&edge_port->ep_lock, flags);
        chars = edge_buf_data_avail(edge_port->ep_out_buf);
        spin_unlock_irqrestore(&edge_port->ep_lock, flags);
 
-       dbg ("%s - returns %d", __func__, chars);
+       dbg("%s - returns %d", __func__, chars);
        return chars;
 }
 
-static void edge_throttle (struct usb_serial_port *port)
+static void edge_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
-       struct tty_struct *tty;
        int status;
 
        dbg("%s - port %d", __func__, port->number);
@@ -2304,16 +2191,10 @@ static void edge_throttle (struct usb_serial_port *port)
        if (edge_port == NULL)
                return;
 
-       tty = port->tty;
-       if (!tty) {
-               dbg ("%s - no tty available", __func__);
-               return;
-       }
-
        /* if we are implementing XON/XOFF, send the stop character */
        if (I_IXOFF(tty)) {
                unsigned char stop_char = STOP_CHAR(tty);
-               status = edge_write (port, &stop_char, 1);
+               status = edge_write(tty, port, &stop_char, 1);
                if (status <= 0) {
                        dev_err(&port->dev, "%s - failed to write stop character, %d\n", __func__, status);
                }
@@ -2326,10 +2207,10 @@ static void edge_throttle (struct usb_serial_port *port)
 
 }
 
-static void edge_unthrottle (struct usb_serial_port *port)
+static void edge_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
-       struct tty_struct *tty;
        int status;
 
        dbg("%s - port %d", __func__, port->number);
@@ -2337,27 +2218,22 @@ static void edge_unthrottle (struct usb_serial_port *port)
        if (edge_port == NULL)
                return;
 
-       tty = port->tty;
-       if (!tty) {
-               dbg ("%s - no tty available", __func__);
-               return;
-       }
-
        /* if we are implementing XON/XOFF, send the start character */
        if (I_IXOFF(tty)) {
                unsigned char start_char = START_CHAR(tty);
-               status = edge_write (port, &start_char, 1);
+               status = edge_write(tty, port, &start_char, 1);
                if (status <= 0) {
                        dev_err(&port->dev, "%s - failed to write start character, %d\n", __func__, status);
                }
        }
-
        /* if we are implementing RTS/CTS, restart reads */
        /* are the Edgeport will assert the RTS line */
        if (C_CRTSCTS(tty)) {
                status = restart_read(edge_port);
                if (status)
-                       dev_err(&port->dev, "%s - read bulk usb_submit_urb failed with value %d\n", __func__, status);
+                       dev_err(&port->dev,
+                               "%s - read bulk usb_submit_urb failed: %d\n",
+                                                       __func__, status);
        }
 
 }
@@ -2398,22 +2274,23 @@ static int restart_read(struct edgeport_port *edge_port)
        return status;
 }
 
-static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios)
+static void change_port_settings(struct tty_struct *tty,
+               struct edgeport_port *edge_port, struct ktermios *old_termios)
 {
        struct ump_uart_config *config;
-       struct tty_struct *tty;
        int baud;
        unsigned cflag;
        int status;
-       int port_number = edge_port->port->number - edge_port->port->serial->minor;
+       int port_number = edge_port->port->number -
+                                       edge_port->port->serial->minor;
 
        dbg("%s - port %d", __func__, edge_port->port->number);
 
-       tty = edge_port->port->tty;
-
        config = kmalloc (sizeof (*config), GFP_KERNEL);
        if (!config) {
-               dev_err (&edge_port->port->dev, "%s - out of memory\n", __func__);
+               *tty->termios = *old_termios;
+               dev_err(&edge_port->port->dev, "%s - out of memory\n",
+                                                               __func__);
                return;
        }
 
@@ -2427,22 +2304,22 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
        config->bUartMode = (__u8)(edge_port->bUartMode);
 
        switch (cflag & CSIZE) {
-               case CS5:
-                           config->bDataBits = UMP_UART_CHAR5BITS;
-                           dbg ("%s - data bits = 5", __func__);
-                           break;
-               case CS6:
-                           config->bDataBits = UMP_UART_CHAR6BITS;
-                           dbg ("%s - data bits = 6", __func__);
-                           break;
-               case CS7:
-                           config->bDataBits = UMP_UART_CHAR7BITS;
-                           dbg ("%s - data bits = 7", __func__);
-                           break;
-               default:
-               case CS8:
-                           config->bDataBits = UMP_UART_CHAR8BITS;
-                           dbg ("%s - data bits = 8", __func__);
+       case CS5:
+                   config->bDataBits = UMP_UART_CHAR5BITS;
+                   dbg("%s - data bits = 5", __func__);
+                   break;
+       case CS6:
+                   config->bDataBits = UMP_UART_CHAR6BITS;
+                   dbg("%s - data bits = 6", __func__);
+                   break;
+       case CS7:
+                   config->bDataBits = UMP_UART_CHAR7BITS;
+                   dbg("%s - data bits = 7", __func__);
+                   break;
+       default:
+       case CS8:
+                   config->bDataBits = UMP_UART_CHAR8BITS;
+                   dbg("%s - data bits = 8", __func__);
                            break;
        }
 
@@ -2457,7 +2334,7 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
                        dbg("%s - parity = even", __func__);
                }
        } else {
-               config->bParity = UMP_UART_NOPARITY;    
+               config->bParity = UMP_UART_NOPARITY;
                dbg("%s - parity = none", __func__);
        }
 
@@ -2480,29 +2357,26 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
                restart_read(edge_port);
        }
 
-       /* if we are implementing XON/XOFF, set the start and stop character in the device */
-       if (I_IXOFF(tty) || I_IXON(tty)) {
-               config->cXon  = START_CHAR(tty);
-               config->cXoff = STOP_CHAR(tty);
+       /* if we are implementing XON/XOFF, set the start and stop
+          character in the device */
+       config->cXon  = START_CHAR(tty);
+       config->cXoff = STOP_CHAR(tty);
 
-               /* if we are implementing INBOUND XON/XOFF */
-               if (I_IXOFF(tty)) {
-                       config->wFlags |= UMP_MASK_UART_FLAGS_IN_X;
-                       dbg ("%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x",
-                            __func__, config->cXon, config->cXoff);
-               } else {
-                       dbg ("%s - INBOUND XON/XOFF is disabled", __func__);
-               }
+       /* if we are implementing INBOUND XON/XOFF */
+       if (I_IXOFF(tty)) {
+               config->wFlags |= UMP_MASK_UART_FLAGS_IN_X;
+               dbg("%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x",
+                    __func__, config->cXon, config->cXoff);
+       } else
+               dbg("%s - INBOUND XON/XOFF is disabled", __func__);
 
-               /* if we are implementing OUTBOUND XON/XOFF */
-               if (I_IXON(tty)) {
-                       config->wFlags |= UMP_MASK_UART_FLAGS_OUT_X;
-                       dbg ("%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x",
-                            __func__, config->cXon, config->cXoff);
-               } else {
-                       dbg ("%s - OUTBOUND XON/XOFF is disabled", __func__);
-               }
-       }
+       /* if we are implementing OUTBOUND XON/XOFF */
+       if (I_IXON(tty)) {
+               config->wFlags |= UMP_MASK_UART_FLAGS_OUT_X;
+               dbg("%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x",
+                    __func__, config->cXon, config->cXoff);
+       } else
+               dbg("%s - OUTBOUND XON/XOFF is disabled", __func__);
 
        tty->termios->c_cflag &= ~CMSPAR;
 
@@ -2519,41 +2393,36 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
 
        /* FIXME: Recompute actual baud from divisor here */
 
-       dbg ("%s - baud rate = %d, wBaudRate = %d", __func__, baud, config->wBaudRate);
+       dbg("%s - baud rate = %d, wBaudRate = %d", __func__, baud,
+                                                       config->wBaudRate);
 
-       dbg ("wBaudRate:   %d", (int)(461550L / config->wBaudRate));
-       dbg ("wFlags:    0x%x", config->wFlags);
-       dbg ("bDataBits:   %d", config->bDataBits);
-       dbg ("bParity:     %d", config->bParity);
-       dbg ("bStopBits:   %d", config->bStopBits);
-       dbg ("cXon:        %d", config->cXon);
-       dbg ("cXoff:       %d", config->cXoff);
-       dbg ("bUartMode:   %d", config->bUartMode);
+       dbg("wBaudRate:   %d", (int)(461550L / config->wBaudRate));
+       dbg("wFlags:    0x%x", config->wFlags);
+       dbg("bDataBits:   %d", config->bDataBits);
+       dbg("bParity:     %d", config->bParity);
+       dbg("bStopBits:   %d", config->bStopBits);
+       dbg("cXon:        %d", config->cXon);
+       dbg("cXoff:       %d", config->cXoff);
+       dbg("bUartMode:   %d", config->bUartMode);
 
        /* move the word values into big endian mode */
-       cpu_to_be16s (&config->wFlags);
-       cpu_to_be16s (&config->wBaudRate);
+       cpu_to_be16s(&config->wFlags);
+       cpu_to_be16s(&config->wBaudRate);
 
-       status = TIWriteCommandSync (edge_port->port->serial->dev,
-                               UMPC_SET_CONFIG,
+       status = send_cmd(edge_port->port->serial->dev, UMPC_SET_CONFIG,
                                (__u8)(UMPM_UART1_PORT + port_number),
-                               0,
-                               (__u8 *)config,
-                               sizeof(*config));
-       if (status) {
-               dbg ("%s - error %d when trying to write config to device",
+                               0, (__u8 *)config, sizeof(*config));
+       if (status)
+               dbg("%s - error %d when trying to write config to device",
                     __func__, status);
-       }
-
-       kfree (config);
-       
+       kfree(config);
        return;
 }
 
-static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
+static void edge_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
-       struct tty_struct *tty = port->tty;
        unsigned int cflag;
 
        cflag = tty->termios->c_cflag;
@@ -2562,20 +2431,19 @@ static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old
            tty->termios->c_cflag, tty->termios->c_iflag);
        dbg("%s - old clfag %08x old iflag %08x", __func__,
            old_termios->c_cflag, old_termios->c_iflag);
-
        dbg("%s - port %d", __func__, port->number);
 
        if (edge_port == NULL)
                return;
-
        /* change the port settings to the new ones specified */
-       change_port_settings (edge_port, old_termios);
-
+       change_port_settings(tty, edge_port, old_termios);
        return;
 }
 
-static int edge_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear)
+static int edge_tiocmset(struct tty_struct *tty, struct file *file,
+                                       unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        unsigned int mcr;
        unsigned long flags;
@@ -2601,13 +2469,13 @@ static int edge_tiocmset (struct usb_serial_port *port, struct file *file, unsig
        edge_port->shadow_mcr = mcr;
        spin_unlock_irqrestore(&edge_port->ep_lock, flags);
 
-       TIRestoreMCR (edge_port, mcr);
-
+       restore_mcr(edge_port, mcr);
        return 0;
 }
 
-static int edge_tiocmget(struct usb_serial_port *port, struct file *file)
+static int edge_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        unsigned int result = 0;
        unsigned int msr;
@@ -2634,7 +2502,8 @@ static int edge_tiocmget(struct usb_serial_port *port, struct file *file)
        return result;
 }
 
-static int get_serial_info (struct edgeport_port *edge_port, struct serial_struct __user *retinfo)
+static int get_serial_info(struct edgeport_port *edge_port,
+                               struct serial_struct __user *retinfo)
 {
        struct serial_struct tmp;
 
@@ -2652,18 +2521,16 @@ static int get_serial_info (struct edgeport_port *edge_port, struct serial_struc
        tmp.baud_base           = 9600;
        tmp.close_delay         = 5*HZ;
        tmp.closing_wait        = closing_wait;
-//     tmp.custom_divisor      = state->custom_divisor;
-//     tmp.hub6                = state->hub6;
-//     tmp.io_type             = state->io_type;
-
 
        if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
                return -EFAULT;
        return 0;
 }
 
-static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg)
+static int edge_ioctl(struct tty_struct *tty, struct file *file,
+                                       unsigned int cmd, unsigned long arg)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        struct async_icount cnow;
        struct async_icount cprev;
@@ -2671,81 +2538,64 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned
        dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
 
        switch (cmd) {
-               case TIOCINQ:
-                       dbg("%s - (%d) TIOCINQ", __func__, port->number);
-//                     return get_number_bytes_avail(edge_port, (unsigned int *) arg);
-                       break;
-
-               case TIOCSERGETLSR:
-                       dbg("%s - (%d) TIOCSERGETLSR", __func__, port->number);
-//                     return get_lsr_info(edge_port, (unsigned int *) arg);
-                       break;
-
-               case TIOCGSERIAL:
-                       dbg("%s - (%d) TIOCGSERIAL", __func__, port->number);
-                       return get_serial_info(edge_port, (struct serial_struct __user *) arg);
-                       break;
-
-               case TIOCSSERIAL:
-                       dbg("%s - (%d) TIOCSSERIAL", __func__, port->number);
-                       break;
-
-               case TIOCMIWAIT:
-                       dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
-                       cprev = edge_port->icount;
-                       while (1) {
-                               interruptible_sleep_on(&edge_port->delta_msr_wait);
-                               /* see if a signal did it */
-                               if (signal_pending(current))
-                                       return -ERESTARTSYS;
-                               cnow = edge_port->icount;
-                               if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
-                                   cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
-                                       return -EIO; /* no change => error */
-                               if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
-                                   ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
-                                   ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
-                                   ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
-                                       return 0;
-                               }
-                               cprev = cnow;
+       case TIOCGSERIAL:
+               dbg("%s - (%d) TIOCGSERIAL", __func__, port->number);
+               return get_serial_info(edge_port,
+                               (struct serial_struct __user *) arg);
+       case TIOCMIWAIT:
+               dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
+               cprev = edge_port->icount;
+               while (1) {
+                       interruptible_sleep_on(&edge_port->delta_msr_wait);
+                       /* see if a signal did it */
+                       if (signal_pending(current))
+                               return -ERESTARTSYS;
+                       cnow = edge_port->icount;
+                       if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+                           cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+                               return -EIO; /* no change => error */
+                       if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+                           ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+                           ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+                           ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
+                               return 0;
                        }
-                       /* not reached */
-                       break;
-
-               case TIOCGICOUNT:
-                       dbg ("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
-                            port->number, edge_port->icount.rx, edge_port->icount.tx);
-                       if (copy_to_user((void __user *)arg, &edge_port->icount, sizeof(edge_port->icount)))
-                               return -EFAULT;
-                       return 0;
+                       cprev = cnow;
+               }
+               /* not reached */
+               break;
+       case TIOCGICOUNT:
+               dbg("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
+                    port->number, edge_port->icount.rx, edge_port->icount.tx);
+               if (copy_to_user((void __user *)arg, &edge_port->icount,
+                               sizeof(edge_port->icount)))
+                       return -EFAULT;
+               return 0;
        }
-
        return -ENOIOCTLCMD;
 }
 
-static void edge_break (struct usb_serial_port *port, int break_state)
+static void edge_break(struct tty_struct *tty, int break_state)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        int status;
+       int bv = 0;     /* Off */
 
-       dbg ("%s - state = %d", __func__, break_state);
+       dbg("%s - state = %d", __func__, break_state);
 
        /* chase the port close */
-       TIChasePort (edge_port, 0, 0);
+       chase_port(edge_port, 0, 0);
 
-       if (break_state == -1) {
-               status = TISetBreak (edge_port);
-       } else {
-               status = TIClearBreak (edge_port);
-       }
-       if (status) {
-               dbg ("%s - error %d sending break set/clear command.",
+       if (break_state == -1)
+               bv = 1; /* On */
+       status = ti_do_config(edge_port, UMPC_SET_CLR_BREAK, bv);
+       if (status)
+               dbg("%s - error %d sending break set/clear command.",
                     __func__, status);
-       }
 }
 
-static int edge_startup (struct usb_serial *serial)
+static int edge_startup(struct usb_serial *serial)
 {
        struct edgeport_serial *edge_serial;
        struct edgeport_port *edge_port;
@@ -2765,9 +2615,9 @@ static int edge_startup (struct usb_serial *serial)
        edge_serial->serial = serial;
        usb_set_serial_data(serial, edge_serial);
 
-       status = TIDownloadFirmware (edge_serial);
+       status = download_fw(edge_serial);
        if (status) {
-               kfree (edge_serial);
+               kfree(edge_serial);
                return status;
        }
 
@@ -2775,13 +2625,15 @@ static int edge_startup (struct usb_serial *serial)
        for (i = 0; i < serial->num_ports; ++i) {
                edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL);
                if (edge_port == NULL) {
-                       dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__);
+                       dev_err(&serial->dev->dev, "%s - Out of memory\n",
+                                                               __func__);
                        goto cleanup;
                }
                spin_lock_init(&edge_port->ep_lock);
                edge_port->ep_out_buf = edge_buf_alloc(EDGE_OUT_BUF_SIZE);
                if (edge_port->ep_out_buf == NULL) {
-                       dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__);
+                       dev_err(&serial->dev->dev, "%s - Out of memory\n",
+                                                               __func__);
                        kfree(edge_port);
                        goto cleanup;
                }
@@ -2790,27 +2642,27 @@ static int edge_startup (struct usb_serial *serial)
                usb_set_serial_port_data(serial->port[i], edge_port);
                edge_port->bUartMode = default_uart_mode;
        }
-       
+
        return 0;
 
 cleanup:
-       for (--i; i>=0; --i) {
+       for (--i; i >= 0; --i) {
                edge_port = usb_get_serial_port_data(serial->port[i]);
                edge_buf_free(edge_port->ep_out_buf);
                kfree(edge_port);
                usb_set_serial_port_data(serial->port[i], NULL);
        }
-       kfree (edge_serial);
+       kfree(edge_serial);
        usb_set_serial_data(serial, NULL);
        return -ENOMEM;
 }
 
-static void edge_shutdown (struct usb_serial *serial)
+static void edge_shutdown(struct usb_serial *serial)
 {
        int i;
        struct edgeport_port *edge_port;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        for (i = 0; i < serial->num_ports; ++i) {
                edge_port = usb_get_serial_port_data(serial->port[i]);
@@ -2852,7 +2704,8 @@ static ssize_t store_uart_mode(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(uart_mode, S_IWUSR | S_IRUGO, show_uart_mode, store_uart_mode);
+static DEVICE_ATTR(uart_mode, S_IWUSR | S_IRUGO, show_uart_mode,
+                                                       store_uart_mode);
 
 static int edge_create_sysfs_attrs(struct usb_serial_port *port)
 {
@@ -2922,9 +2775,9 @@ static void edge_buf_free(struct edge_buf *eb)
 
 static void edge_buf_clear(struct edge_buf *eb)
 {
-        if (eb != NULL)
-                eb->buf_get = eb->buf_put;
-                /* equivalent to a get of all data available */
+       if (eb != NULL)
+               eb->buf_get = eb->buf_put;
+       /* equivalent to a get of all data available */
 }
 
 
@@ -2937,10 +2790,9 @@ static void edge_buf_clear(struct edge_buf *eb)
 
 static unsigned int edge_buf_data_avail(struct edge_buf *eb)
 {
-       if (eb != NULL)
-               return ((eb->buf_size + eb->buf_put - eb->buf_get) % eb->buf_size);
-       else
+       if (eb == NULL)
                return 0;
+       return ((eb->buf_size + eb->buf_put - eb->buf_get) % eb->buf_size);
 }
 
 
@@ -2953,10 +2805,9 @@ static unsigned int edge_buf_data_avail(struct edge_buf *eb)
 
 static unsigned int edge_buf_space_avail(struct edge_buf *eb)
 {
-       if (eb != NULL)
-               return ((eb->buf_size + eb->buf_get - eb->buf_put - 1) % eb->buf_size);
-       else
+       if (eb == NULL)
                return 0;
+       return ((eb->buf_size + eb->buf_get - eb->buf_put - 1) % eb->buf_size);
 }
 
 
@@ -3113,7 +2964,7 @@ static int __init edgeport_init(void)
        if (retval)
                goto failed_2port_device_register;
        retval = usb_register(&io_driver);
-       if (retval) 
+       if (retval)
                goto failed_usb_register;
        info(DRIVER_DESC " " DRIVER_VERSION);
        return 0;
@@ -3125,11 +2976,11 @@ failed_1port_device_register:
        return retval;
 }
 
-static void __exit edgeport_exit (void)
+static void __exit edgeport_exit(void)
 {
-       usb_deregister (&io_driver);
-       usb_serial_deregister (&edgeport_1port_device);
-       usb_serial_deregister (&edgeport_2port_device);
+       usb_deregister(&io_driver);
+       usb_serial_deregister(&edgeport_1port_device);
+       usb_serial_deregister(&edgeport_2port_device);
 }
 
 module_init(edgeport_init);
@@ -3151,8 +3002,8 @@ module_param(closing_wait, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain, in .01 secs");
 
 module_param(ignore_cpu_rev, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(ignore_cpu_rev, "Ignore the cpu revision when connecting to a device");
+MODULE_PARM_DESC(ignore_cpu_rev,
+                       "Ignore the cpu revision when connecting to a device");
 
 module_param(default_uart_mode, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(default_uart_mode, "Default uart_mode, 0=RS232, ...");
-
index d9fb3768a2d7b1ba869e4275bcc6ec9d29d1ed2c..832a5a4f3cb3ca9ab3394b9795b7685c8f80d7b1 100644 (file)
@@ -53,7 +53,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include "ipaq.h"
@@ -74,19 +74,21 @@ static int connect_retries = KP_RETRIES;
 static int initial_wait;
 
 /* Function prototypes for an ipaq */
-static int  ipaq_open (struct usb_serial_port *port, struct file *filp);
-static void ipaq_close (struct usb_serial_port *port, struct file *filp);
-static int  ipaq_startup (struct usb_serial *serial);
-static void ipaq_shutdown (struct usb_serial *serial);
-static int ipaq_write(struct usb_serial_port *port, const unsigned char *buf,
-                      int count);
-static int ipaq_write_bulk(struct usb_serial_port *port, const unsigned char *buf,
-                          int count);
+static int  ipaq_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static void ipaq_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static int  ipaq_startup(struct usb_serial *serial);
+static void ipaq_shutdown(struct usb_serial *serial);
+static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port,
+                       const unsigned char *buf, int count);
+static int ipaq_write_bulk(struct usb_serial_port *port,
+                               const unsigned char *buf, int count);
 static void ipaq_write_gather(struct usb_serial_port *port);
-static void ipaq_read_bulk_callback (struct urb *urb);
+static void ipaq_read_bulk_callback(struct urb *urb);
 static void ipaq_write_bulk_callback(struct urb *urb);
-static int ipaq_write_room(struct usb_serial_port *port);
-static int ipaq_chars_in_buffer(struct usb_serial_port *port);
+static int ipaq_write_room(struct tty_struct *tty);
+static int ipaq_chars_in_buffer(struct tty_struct *tty);
 static void ipaq_destroy_lists(struct usb_serial_port *port);
 
 
@@ -550,7 +552,7 @@ static struct usb_device_id ipaq_id_table [] = {
        { }                             /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, ipaq_id_table);
+MODULE_DEVICE_TABLE(usb, ipaq_id_table);
 
 static struct usb_driver ipaq_driver = {
        .name =         "ipaq",
@@ -591,7 +593,8 @@ static spinlock_t   write_list_lock;
 static int             bytes_in;
 static int             bytes_out;
 
-static int ipaq_open(struct usb_serial_port *port, struct file *filp)
+static int ipaq_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial       *serial = port->serial;
        struct ipaq_private     *priv;
@@ -617,9 +620,9 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
 
        for (i = 0; i < URBDATA_QUEUE_MAX / PACKET_SIZE; i++) {
                pkt = kmalloc(sizeof(struct ipaq_packet), GFP_KERNEL);
-               if (pkt == NULL) {
+               if (pkt == NULL)
                        goto enomem;
-               }
+
                pkt->data = kmalloc(PACKET_SIZE, GFP_KERNEL);
                if (pkt->data == NULL) {
                        kfree(pkt);
@@ -637,21 +640,24 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
         * discipline instead of queueing.
         */
 
-       port->tty->low_latency = 1;
-       port->tty->raw = 1;
-       port->tty->real_raw = 1;
-
+       if (tty) {
+               tty->low_latency = 1;
+               /* FIXME: These two are bogus */
+               tty->raw = 1;
+               tty->real_raw = 1;
+       }
        /*
         * Lose the small buffers usbserial provides. Make larger ones.
         */
 
        kfree(port->bulk_in_buffer);
-       kfree(port->bulk_out_buffer);
        port->bulk_in_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL);
        if (port->bulk_in_buffer == NULL) {
                port->bulk_out_buffer = NULL; /* prevent double free */
                goto enomem;
        }
+
+       kfree(port->bulk_out_buffer);
        port->bulk_out_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL);
        if (port->bulk_out_buffer == NULL) {
                kfree(port->bulk_in_buffer);
@@ -661,8 +667,9 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
        port->read_urb->transfer_buffer = port->bulk_in_buffer;
        port->write_urb->transfer_buffer = port->bulk_out_buffer;
        port->read_urb->transfer_buffer_length = URBDATA_SIZE;
-       port->bulk_out_size = port->write_urb->transfer_buffer_length = URBDATA_SIZE;
-       
+       port->bulk_out_size = port->write_urb->transfer_buffer_length
+                                                       = URBDATA_SIZE;
+
        msleep(1000*initial_wait);
 
        /*
@@ -691,13 +698,15 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
 
        /* Start reading from the device */
        usb_fill_bulk_urb(port->read_urb, serial->dev,
-                     usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
-                     port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
-                     ipaq_read_bulk_callback, port);
+               usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
+               port->read_urb->transfer_buffer,
+               port->read_urb->transfer_buffer_length,
+               ipaq_read_bulk_callback, port);
 
        result = usb_submit_urb(port->read_urb, GFP_KERNEL);
        if (result) {
-               err("%s - failed submitting read urb, error %d", __func__, result);
+               err("%s - failed submitting read urb, error %d",
+                                               __func__, result);
                goto error;
        }
 
@@ -713,12 +722,13 @@ error:
 }
 
 
-static void ipaq_close(struct usb_serial_port *port, struct file *filp)
+static void ipaq_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct ipaq_private     *priv = usb_get_serial_port_data(port);
 
        dbg("%s - port %d", __func__, port->number);
-                        
+
        /*
         * shut down bulk read and write
         */
@@ -728,7 +738,8 @@ static void ipaq_close(struct usb_serial_port *port, struct file *filp)
        kfree(priv);
        usb_set_serial_port_data(port, NULL);
 
-       /* Uncomment the following line if you want to see some statistics in your syslog */
+       /* Uncomment the following line if you want to see some statistics
+        * in your syslog */
        /* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */
 }
 
@@ -748,9 +759,10 @@ static void ipaq_read_bulk_callback(struct urb *urb)
                return;
        }
 
-       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                                               urb->actual_length, data);
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (tty && urb->actual_length) {
                tty_buffer_request_room(tty, urb->actual_length);
                tty_insert_flip_string(tty, data, urb->actual_length);
@@ -759,18 +771,20 @@ static void ipaq_read_bulk_callback(struct urb *urb)
        }
 
        /* Continue trying to always read  */
-       usb_fill_bulk_urb(port->read_urb, port->serial->dev, 
-                     usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress),
-                     port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
-                     ipaq_read_bulk_callback, port);
+       usb_fill_bulk_urb(port->read_urb, port->serial->dev,
+           usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress),
+           port->read_urb->transfer_buffer,
+           port->read_urb->transfer_buffer_length,
+           ipaq_read_bulk_callback, port);
        result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
        if (result)
-               err("%s - failed resubmitting read urb, error %d", __func__, result);
+               err("%s - failed resubmitting read urb, error %d",
+                                                       __func__, result);
        return;
 }
 
-static int ipaq_write(struct usb_serial_port *port, const unsigned char *buf,
-                      int count)
+static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port,
+                       const unsigned char *buf, int count)
 {
        const unsigned char     *current_position = buf;
        int                     bytes_sent = 0;
@@ -780,9 +794,8 @@ static int ipaq_write(struct usb_serial_port *port, const unsigned char *buf,
 
        while (count > 0) {
                transfer_size = min(count, PACKET_SIZE);
-               if (ipaq_write_bulk(port, current_position, transfer_size)) {
+               if (ipaq_write_bulk(port, current_position, transfer_size))
                        break;
-               }
                current_position += transfer_size;
                bytes_sent += transfer_size;
                count -= transfer_size;
@@ -790,10 +803,10 @@ static int ipaq_write(struct usb_serial_port *port, const unsigned char *buf,
        }
 
        return bytes_sent;
-} 
+}
 
-static int ipaq_write_bulk(struct usb_serial_port *port, const unsigned char *buf,
-                          int count)
+static int ipaq_write_bulk(struct usb_serial_port *port,
+                                       const unsigned char *buf, int count)
 {
        struct ipaq_private     *priv = usb_get_serial_port_data(port);
        struct ipaq_packet      *pkt = NULL;
@@ -830,9 +843,9 @@ static int ipaq_write_bulk(struct usb_serial_port *port, const unsigned char *bu
                ipaq_write_gather(port);
                spin_unlock_irqrestore(&write_list_lock, flags);
                result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
-               if (result) {
-                       err("%s - failed submitting write urb, error %d", __func__, result);
-               }
+               if (result)
+                       err("%s - failed submitting write urb, error %d",
+                               __func__, result);
        } else {
                spin_unlock_irqrestore(&write_list_lock, flags);
        }
@@ -859,16 +872,15 @@ static void ipaq_write_gather(struct usb_serial_port *port)
                        list_move(&pkt->list, &priv->freelist);
                        priv->free_len += PACKET_SIZE;
                }
-               if (room == 0) {
+               if (room == 0)
                        break;
-               }
        }
 
        count = URBDATA_SIZE - room;
-       usb_fill_bulk_urb(port->write_urb, serial->dev, 
-                     usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
-                     port->write_urb->transfer_buffer, count, ipaq_write_bulk_callback,
-                     port);
+       usb_fill_bulk_urb(port->write_urb, serial->dev,
+               usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
+               port->write_urb->transfer_buffer, count,
+               ipaq_write_bulk_callback, port);
        return;
 }
 
@@ -893,9 +905,9 @@ static void ipaq_write_bulk_callback(struct urb *urb)
                ipaq_write_gather(port);
                spin_unlock_irqrestore(&write_list_lock, flags);
                result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
-               if (result) {
-                       err("%s - failed submitting write urb, error %d", __func__, result);
-               }
+               if (result)
+                       err("%s - failed submitting write urb, error %d",
+                                       __func__, result);
        } else {
                priv->active = 0;
                spin_unlock_irqrestore(&write_list_lock, flags);
@@ -904,16 +916,18 @@ static void ipaq_write_bulk_callback(struct urb *urb)
        usb_serial_port_softint(port);
 }
 
-static int ipaq_write_room(struct usb_serial_port *port)
+static int ipaq_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ipaq_private     *priv = usb_get_serial_port_data(port);
 
        dbg("%s - freelen %d", __func__, priv->free_len);
        return priv->free_len;
 }
 
-static int ipaq_chars_in_buffer(struct usb_serial_port *port)
+static int ipaq_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ipaq_private     *priv = usb_get_serial_port_data(port);
 
        dbg("%s - queuelen %d", __func__, priv->queue_len);
@@ -944,7 +958,7 @@ static int ipaq_startup(struct usb_serial *serial)
                        serial->dev->actconfig->desc.bConfigurationValue);
                return -ENODEV;
        }
-       return usb_reset_configuration (serial->dev);
+       return usb_reset_configuration(serial->dev);
 }
 
 static void ipaq_shutdown(struct usb_serial *serial)
@@ -957,7 +971,7 @@ static int __init ipaq_init(void)
        int retval;
        spin_lock_init(&write_list_lock);
        retval = usb_serial_register(&ipaq_device);
-       if (retval) 
+       if (retval)
                goto failed_usb_serial_register;
        info(DRIVER_DESC " " DRIVER_VERSION);
        if (vendor) {
@@ -967,7 +981,7 @@ static int __init ipaq_init(void)
        retval = usb_register(&ipaq_driver);
        if (retval)
                goto failed_usb_register;
-                 
+
        return 0;
 failed_usb_register:
        usb_serial_deregister(&ipaq_device);
@@ -986,8 +1000,8 @@ static void __exit ipaq_exit(void)
 module_init(ipaq_init);
 module_exit(ipaq_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
@@ -1000,7 +1014,9 @@ module_param(product, ushort, 0);
 MODULE_PARM_DESC(product, "User specified USB idProduct");
 
 module_param(connect_retries, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(connect_retries, "Maximum number of connect retries (one second each)");
+MODULE_PARM_DESC(connect_retries,
+               "Maximum number of connect retries (one second each)");
 
 module_param(initial_wait, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(initial_wait, "Time to wait before attempting a connection (in seconds)");
+MODULE_PARM_DESC(initial_wait,
+               "Time to wait before attempting a connection (in seconds)");
index bc85ca5c1c375d556d0b18c6d30ba201e2f8459f..a842025b9b576d4f3e8e678cf386713a9c7baf61 100644 (file)
  *   (at your option) any later version.
  *
  * All information about the device was acquired using SnoopyPro
- * on MSFT's O/S, and examing the MSFT drivers' debug output 
+ * on MSFT's O/S, and examing the MSFT drivers' debug output
  * (insanely left _on_ in the enduser version)
  *
  * It was written out of frustration with the IPWireless USB modem
  * supplied by Axity3G/Sentech South Africa not supporting
  * Linux whatsoever.
  *
- * Nobody provided any proprietary information that was not already 
+ * Nobody provided any proprietary information that was not already
  * available for this device.
- * 
- * The modem adheres to the "3GPP TS  27.007 AT command set for 3G 
- * User Equipment (UE)" standard, available from 
+ *
+ * The modem adheres to the "3GPP TS  27.007 AT command set for 3G
+ * User Equipment (UE)" standard, available from
  * http://www.3gpp.org/ftp/Specs/html-info/27007.htm
  *
  * The code was only tested the IPWireless handheld modem distributed
  * in South Africa by Sentech.
- * 
+ *
  * It may work for Woosh Inc in .nz too, as it appears they use the
  * same kit.
  *
- * There is still some work to be done in terms of handling 
+ * There is still some work to be done in terms of handling
  * DCD, DTR, RTS, CTS which are currently faked.
  * It's good enough for PPP at this point. It's based off all kinds of
  * code found in usb/serial and usb/class
@@ -47,7 +47,7 @@
 #include <linux/spinlock.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 /*
  * Version Information
@@ -64,7 +64,7 @@
 
 /* Message sizes */
 #define EVENT_BUFFER_SIZE      0xFF
-#define CHAR2INT16(c1,c0)      (((u32)((c1) & 0xff) << 8) + (u32)((c0) & 0xff))
+#define CHAR2INT16(c1, c0)     (((u32)((c1) & 0xff) << 8) + (u32)((c0) & 0xff))
 #define NUM_BULK_URBS          24
 #define NUM_CONTROL_URBS       16
 
@@ -94,33 +94,34 @@ enum {
 
 /* data bits */
 #define ipw_dtb_7              0x700
-#define ipw_dtb_8              0x810   // ok so the define is misleading, I know, but forces 8,n,1
-                                       // I mean, is there a point to any other setting these days? :) 
+#define ipw_dtb_8              0x810   /* ok so the define is misleading, I know, but forces 8,n,1 */
+                                       /* I mean, is there a point to any other setting these days? :) */
 
 /* usb control request types : */
-#define IPW_SIO_RXCTL          0x00    // control bulk rx channel transmissions, value=1/0 (on/off)
-#define IPW_SIO_SET_BAUD       0x01    // set baud, value=requested ipw_sio_bxxxx
-#define IPW_SIO_SET_LINE       0x03    // set databits, parity. value=ipw_dtb_x
-#define IPW_SIO_SET_PIN                0x03    // set/clear dtr/rts value=ipw_pin_xxx
-#define IPW_SIO_POLL           0x08    // get serial port status byte, call with value=0
-#define IPW_SIO_INIT           0x11    // initializes ? value=0 (appears as first thing todo on open)
-#define IPW_SIO_PURGE          0x12    // purge all transmissions?, call with value=numchar_to_purge
-#define IPW_SIO_HANDFLOW       0x13    // set xon/xoff limits value=0, and a buffer of 0x10 bytes
-#define IPW_SIO_SETCHARS       0x13    // set the flowcontrol special chars, value=0, buf=6 bytes, 
-                                       // last 2 bytes contain flowcontrol chars e.g. 00 00 00 00 11 13
+#define IPW_SIO_RXCTL          0x00    /* control bulk rx channel transmissions, value=1/0 (on/off) */
+#define IPW_SIO_SET_BAUD       0x01    /* set baud, value=requested ipw_sio_bxxxx */
+#define IPW_SIO_SET_LINE       0x03    /* set databits, parity. value=ipw_dtb_x */
+#define IPW_SIO_SET_PIN                0x03    /* set/clear dtr/rts value=ipw_pin_xxx */
+#define IPW_SIO_POLL           0x08    /* get serial port status byte, call with value=0 */
+#define IPW_SIO_INIT           0x11    /* initializes ? value=0 (appears as first thing todo on open) */
+#define IPW_SIO_PURGE          0x12    /* purge all transmissions?, call with value=numchar_to_purge */
+#define IPW_SIO_HANDFLOW       0x13    /* set xon/xoff limits value=0, and a buffer of 0x10 bytes */
+#define IPW_SIO_SETCHARS       0x13    /* set the flowcontrol special chars, value=0, buf=6 bytes, */
+                                       /* last 2 bytes contain flowcontrol chars e.g. 00 00 00 00 11 13 */
 
 /* values used for request IPW_SIO_SET_PIN */
 #define IPW_PIN_SETDTR         0x101
 #define IPW_PIN_SETRTS         0x202
 #define IPW_PIN_CLRDTR         0x100
-#define IPW_PIN_CLRRTS         0x200 // unconfirmed
+#define IPW_PIN_CLRRTS         0x200 /* unconfirmed */
 
 /* values used for request IPW_SIO_RXCTL */
 #define IPW_RXBULK_ON          1
 #define IPW_RXBULK_OFF         0
 
 /* various 16 byte hardcoded transferbuffers used by flow control */
-#define IPW_BYTES_FLOWINIT     { 0x01, 0, 0, 0, 0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+#define IPW_BYTES_FLOWINIT     { 0x01, 0, 0, 0, 0x40, 0, 0, 0, \
+                                       0, 0, 0, 0, 0, 0, 0, 0 }
 
 /* Interpretation of modem status lines */
 /* These need sorting out by individually connecting pins and checking
@@ -132,17 +133,6 @@ enum {
 #define IPW_CTS                        ((1<<5) | (1<<4))
 
 #define IPW_WANTS_TO_SEND      0x30
-//#define IPW_DTR                      /* Data Terminal Ready */
-//#define IPW_CTS                      /* Clear To Send */
-//#define IPW_CD                       /* Carrier Detect */
-//#define IPW_DSR                      /* Data Set Ready */
-//#define IPW_RxD                      /* Receive pin */
-
-//#define IPW_LE
-//#define IPW_RTS              
-//#define IPW_ST               
-//#define IPW_SR               
-//#define IPW_RI                       /* Ring Indicator */
 
 static struct usb_device_id usb_ipw_ids[] = {
        { USB_DEVICE(IPW_VID, IPW_PID) },
@@ -177,9 +167,10 @@ static void ipw_read_bulk_callback(struct urb *urb)
                return;
        }
 
-       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                                       urb->actual_length, data);
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (tty && urb->actual_length) {
                tty_buffer_request_room(tty, urb->actual_length);
                tty_insert_flip_string(tty, data, urb->actual_length);
@@ -187,19 +178,22 @@ static void ipw_read_bulk_callback(struct urb *urb)
        }
 
        /* Continue trying to always read  */
-       usb_fill_bulk_urb (port->read_urb, port->serial->dev,
-                          usb_rcvbulkpipe(port->serial->dev,
+       usb_fill_bulk_urb(port->read_urb, port->serial->dev,
+                         usb_rcvbulkpipe(port->serial->dev,
                                           port->bulk_in_endpointAddress),
-                          port->read_urb->transfer_buffer,
-                          port->read_urb->transfer_buffer_length,
-                          ipw_read_bulk_callback, port);
+                         port->read_urb->transfer_buffer,
+                         port->read_urb->transfer_buffer_length,
+                         ipw_read_bulk_callback, port);
        result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
        if (result)
-               dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result);
+               dev_err(&port->dev,
+                       "%s - failed resubmitting read urb, error %d\n",
+                                                       __func__, result);
        return;
 }
 
-static int ipw_open(struct usb_serial_port *port, struct file *filp)
+static int ipw_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct usb_device *dev = port->serial->dev;
        u8 buf_flow_static[16] = IPW_BYTES_FLOWINIT;
@@ -212,29 +206,33 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp)
        if (!buf_flow_init)
                return -ENOMEM;
 
-       if (port->tty)
-               port->tty->low_latency = 1;
-
-       /* --1: Tell the modem to initialize (we think) From sniffs this is always the
-        * first thing that gets sent to the modem during opening of the device */
-       dbg("%s: Sending SIO_INIT (we guess)",__func__);
-       result = usb_control_msg(dev, usb_sndctrlpipe(dev,0),
-                                IPW_SIO_INIT,
-                                USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
-                                0,
-                                0, /* index */
-                                NULL,
-                                0,
-                                100000);
+       if (tty)
+               tty->low_latency = 1;
+
+       /* --1: Tell the modem to initialize (we think) From sniffs this is
+        *      always the first thing that gets sent to the modem during
+        *      opening of the device */
+       dbg("%s: Sending SIO_INIT (we guess)", __func__);
+       result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+                        IPW_SIO_INIT,
+                        USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+                        0,
+                        0, /* index */
+                        NULL,
+                        0,
+                        100000);
        if (result < 0)
-               dev_err(&port->dev, "Init of modem failed (error = %d)\n", result);
+               dev_err(&port->dev,
+                       "Init of modem failed (error = %d)\n", result);
 
        /* reset the bulk pipes */
-       usb_clear_halt(dev, usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress));
-       usb_clear_halt(dev, usb_sndbulkpipe(dev, port->bulk_out_endpointAddress));
+       usb_clear_halt(dev,
+                       usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress));
+       usb_clear_halt(dev,
+                       usb_sndbulkpipe(dev, port->bulk_out_endpointAddress));
 
-       /*--2: Start reading from the device */ 
-       dbg("%s: setting up bulk read callback",__func__);
+       /*--2: Start reading from the device */
+       dbg("%s: setting up bulk read callback", __func__);
        usb_fill_bulk_urb(port->read_urb, dev,
                          usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress),
                          port->bulk_in_buffer,
@@ -242,66 +240,72 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp)
                          ipw_read_bulk_callback, port);
        result = usb_submit_urb(port->read_urb, GFP_KERNEL);
        if (result < 0)
-               dbg("%s - usb_submit_urb(read bulk) failed with status %d", __func__, result);
+               dbg("%s - usb_submit_urb(read bulk) failed with status %d",
+                                                       __func__, result);
 
        /*--3: Tell the modem to open the floodgates on the rx bulk channel */
-       dbg("%s:asking modem for RxRead (RXBULK_ON)",__func__);
+       dbg("%s:asking modem for RxRead (RXBULK_ON)", __func__);
        result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                                IPW_SIO_RXCTL,
-                                USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
-                                IPW_RXBULK_ON,
-                                0, /* index */
-                                NULL,
-                                0,
-                                100000);
-       if (result < 0) 
-               dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)\n", result);
+                        IPW_SIO_RXCTL,
+                        USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+                        IPW_RXBULK_ON,
+                        0, /* index */
+                        NULL,
+                        0,
+                        100000);
+       if (result < 0)
+               dev_err(&port->dev,
+                       "Enabling bulk RxRead failed (error = %d)\n", result);
 
        /*--4: setup the initial flowcontrol */
-       dbg("%s:setting init flowcontrol (%s)",__func__,buf_flow_init);
+       dbg("%s:setting init flowcontrol (%s)", __func__, buf_flow_init);
        result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                                IPW_SIO_HANDFLOW,
-                                USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
-                                0,
-                                0,
-                                buf_flow_init,
-                                0x10,
-                                200000);
+                        IPW_SIO_HANDFLOW,
+                        USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+                        0,
+                        0,
+                        buf_flow_init,
+                        0x10,
+                        200000);
        if (result < 0)
-               dev_err(&port->dev, "initial flowcontrol failed (error = %d)\n", result);
+               dev_err(&port->dev,
+                       "initial flowcontrol failed (error = %d)\n", result);
 
 
        /*--5: raise the dtr */
-       dbg("%s:raising dtr",__func__);
+       dbg("%s:raising dtr", __func__);
        result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                                IPW_SIO_SET_PIN,
-                                USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
-                                IPW_PIN_SETDTR,
-                                0,
-                                NULL,
-                                0,
-                                200000);
+                        IPW_SIO_SET_PIN,
+                        USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+                        IPW_PIN_SETDTR,
+                        0,
+                        NULL,
+                        0,
+                        200000);
        if (result < 0)
-               dev_err(&port->dev, "setting dtr failed (error = %d)\n", result);
+               dev_err(&port->dev,
+                               "setting dtr failed (error = %d)\n", result);
 
        /*--6: raise the rts */
-       dbg("%s:raising rts",__func__);
+       dbg("%s:raising rts", __func__);
        result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                                IPW_SIO_SET_PIN,
-                                USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
-                                IPW_PIN_SETRTS,
-                                0,
-                                NULL,
-                                0,
-                                200000);
+                        IPW_SIO_SET_PIN,
+                        USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+                        IPW_PIN_SETRTS,
+                        0,
+                        NULL,
+                        0,
+                        200000);
        if (result < 0)
-               dev_err(&port->dev, "setting dtr failed (error = %d)\n", result);
-       
+               dev_err(&port->dev,
+                               "setting dtr failed (error = %d)\n", result);
+
        kfree(buf_flow_init);
        return 0;
 }
 
-static void ipw_close(struct usb_serial_port *port, struct file * filp)
+static void ipw_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct usb_device *dev = port->serial->dev;
        int result;
@@ -312,56 +316,62 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp)
        }
 
        /*--1: drop the dtr */
-       dbg("%s:dropping dtr",__func__);
+       dbg("%s:dropping dtr", __func__);
        result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                                IPW_SIO_SET_PIN,
-                                USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
-                                IPW_PIN_CLRDTR,
-                                0,
-                                NULL,
-                                0,
-                                200000);
+                        IPW_SIO_SET_PIN,
+                        USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+                        IPW_PIN_CLRDTR,
+                        0,
+                        NULL,
+                        0,
+                        200000);
        if (result < 0)
-               dev_err(&port->dev, "dropping dtr failed (error = %d)\n", result);
+               dev_err(&port->dev, "dropping dtr failed (error = %d)\n",
+                                                               result);
 
        /*--2: drop the rts */
-       dbg("%s:dropping rts",__func__);
+       dbg("%s:dropping rts", __func__);
        result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                                IPW_SIO_SET_PIN, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
-                                IPW_PIN_CLRRTS,
-                                0,
-                                NULL,
-                                0,
-                                200000);
+                        IPW_SIO_SET_PIN, USB_TYPE_VENDOR |
+                                       USB_RECIP_INTERFACE | USB_DIR_OUT,
+                        IPW_PIN_CLRRTS,
+                        0,
+                        NULL,
+                        0,
+                        200000);
        if (result < 0)
-               dev_err(&port->dev, "dropping rts failed (error = %d)\n", result);
+               dev_err(&port->dev,
+                               "dropping rts failed (error = %d)\n", result);
 
 
        /*--3: purge */
-       dbg("%s:sending purge",__func__);
+       dbg("%s:sending purge", __func__);
        result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                                IPW_SIO_PURGE, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
-                                0x03,
-                                0,
-                                NULL,
-                                0,
-                                200000);
+                        IPW_SIO_PURGE, USB_TYPE_VENDOR |
+                                       USB_RECIP_INTERFACE | USB_DIR_OUT,
+                        0x03,
+                        0,
+                        NULL,
+                        0,
+                        200000);
        if (result < 0)
                dev_err(&port->dev, "purge failed (error = %d)\n", result);
 
 
-       /* send RXBULK_off (tell modem to stop transmitting bulk data on rx chan) */
+       /* send RXBULK_off (tell modem to stop transmitting bulk data on
+          rx chan) */
        result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                                IPW_SIO_RXCTL,
-                                USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
-                                IPW_RXBULK_OFF,
-                                0, /* index */
-                                NULL,
-                                0,
-                                100000);
+                        IPW_SIO_RXCTL,
+                        USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+                        IPW_RXBULK_OFF,
+                        0, /* index */
+                        NULL,
+                        0,
+                        100000);
 
        if (result < 0)
-               dev_err(&port->dev, "Disabling bulk RxRead failed (error = %d)\n", result);
+               dev_err(&port->dev,
+                       "Disabling bulk RxRead failed (error = %d)\n", result);
 
        /* shutdown any in-flight urbs that we know about */
        usb_kill_urb(port->read_urb);
@@ -384,13 +394,14 @@ static void ipw_write_bulk_callback(struct urb *urb)
        usb_serial_port_softint(port);
 }
 
-static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int count)
+static int ipw_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                       const unsigned char *buf, int count)
 {
        struct usb_device *dev = port->serial->dev;
        int ret;
 
        dbg("%s: TOP: count=%d, in_interrupt=%ld", __func__,
-               count, in_interrupt() );
+               count, in_interrupt());
 
        if (count == 0) {
                dbg("%s - write request of 0 bytes", __func__);
@@ -421,13 +432,14 @@ static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int
        ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
        if (ret != 0) {
                port->write_urb_busy = 0;
-               dbg("%s - usb_submit_urb(write bulk) failed with error = %d", __func__, ret);
+               dbg("%s - usb_submit_urb(write bulk) failed with error = %d",
+                                                               __func__, ret);
                return ret;
        }
 
        dbg("%s returning %d", __func__, count);
        return count;
-} 
+}
 
 static int ipw_probe(struct usb_serial_port *port)
 {
@@ -486,8 +498,8 @@ module_init(usb_ipw_init);
 module_exit(usb_ipw_exit);
 
 /* Module information */
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
index 004d57385a757fac1064311efdb4d53b3355f009..e59155c6607da7c58dabe8b7d5b83b7957816358 100644 (file)
  * was written by Roman Weissgaerber <weissg@vienna.at>, Dag Brattli
  * <dag@brattli.net>, and Jean Tourrilhes <jt@hpl.hp.com>
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
+ *
+ * 2008_Jun_02  Felipe Balbi <me@felipebalbi.com>
+ *     Introduced common header to be used also in USB Gadget Framework.
+ *     Still needs some other style fixes.
  *
  * 2007_Jun_21  Alan Cox <alan@redhat.com>
  *     Minimal cleanups for some of the driver problens and tty layer abuse.
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
+#include <linux/usb/irda.h>
 
 /*
  * Version Information
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
 #define DRIVER_DESC "USB IR Dongle driver"
 
-/* USB IrDA class spec information */
-#define USB_CLASS_IRDA         0x02
-#define USB_DT_IRDA            0x21
-#define IU_REQ_GET_CLASS_DESC  0x06
-#define SPEED_2400             0x01
-#define SPEED_9600             0x02
-#define SPEED_19200            0x03
-#define SPEED_38400            0x04
-#define SPEED_57600            0x05
-#define SPEED_115200           0x06
-#define SPEED_576000           0x07
-#define SPEED_1152000          0x08
-#define SPEED_4000000          0x09
-
-struct irda_class_desc {
-       u8      bLength;
-       u8      bDescriptorType;
-       u16     bcdSpecRevision;
-       u8      bmDataSize;
-       u8      bmWindowSize;
-       u8      bmMinTurnaroundTime;
-       u16     wBaudRate;
-       u8      bmAdditionalBOFs;
-       u8      bIrdaRateSniff;
-       u8      bMaxUnicastList;
-} __attribute__ ((packed));
-
 static int debug;
 
 /* if overridden by the user, then use their value for the size of the read and
  * write urbs */
 static int buffer_size;
+
 /* if overridden by the user, then use the specified number of XBOFs */
 static int xbof = -1;
 
 static int  ir_startup (struct usb_serial *serial);
-static int  ir_open (struct usb_serial_port *port, struct file *filep);
-static void ir_close (struct usb_serial_port *port, struct file *filep);
-static int  ir_write (struct usb_serial_port *port, const unsigned char *buf, int count);
+static int  ir_open(struct tty_struct *tty, struct usb_serial_port *port,
+                                       struct file *filep);
+static void ir_close(struct tty_struct *tty, struct usb_serial_port *port,
+                                       struct file *filep);
+static int  ir_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                       const unsigned char *buf, int count);
 static void ir_write_bulk_callback (struct urb *urb);
 static void ir_read_bulk_callback (struct urb *urb);
-static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
+static void ir_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios);
 
 /* Not that this lot means you can only have one per system */
-static u8 ir_baud = 0;
-static u8 ir_xbof = 0;
-static u8 ir_add_bof = 0;
+static u8 ir_baud;
+static u8 ir_xbof;
+static u8 ir_add_bof;
 
-static struct usb_device_id id_table [] = {
+static struct usb_device_id ir_id_table[] = {
        { USB_DEVICE(0x050f, 0x0180) },         /* KC Technology, KC-180 */
        { USB_DEVICE(0x08e9, 0x0100) },         /* XTNDAccess */
        { USB_DEVICE(0x09c4, 0x0011) },         /* ACTiSys ACT-IR2000U */
-       { USB_INTERFACE_INFO (USB_CLASS_APP_SPEC, USB_CLASS_IRDA, 0) },
+       { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, USB_SUBCLASS_IRDA, 0) },
        { }                                     /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, ir_id_table);
 
 static struct usb_driver ir_driver = {
-       .name =         "ir-usb",
-       .probe =        usb_serial_probe,
-       .disconnect =   usb_serial_disconnect,
-       .id_table =     id_table,
-       .no_dynamic_id =        1,
+       .name           = "ir-usb",
+       .probe          = usb_serial_probe,
+       .disconnect     = usb_serial_disconnect,
+       .id_table       = ir_id_table,
+       .no_dynamic_id  = 1,
 };
 
-
 static struct usb_serial_driver ir_device = {
-       .driver = {
-               .owner =        THIS_MODULE,
-               .name =         "ir-usb",
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = "ir-usb",
        },
-       .description =          "IR Dongle",
-       .usb_driver =           &ir_driver,
-       .id_table =             id_table,
-       .num_ports =            1,
-       .set_termios =          ir_set_termios,
-       .attach =               ir_startup,
-       .open =                 ir_open,
-       .close =                ir_close,
-       .write =                ir_write,
-       .write_bulk_callback  ir_write_bulk_callback,
-       .read_bulk_callback =   ir_read_bulk_callback,
+       .description            = "IR Dongle",
+       .usb_driver             = &ir_driver,
+       .id_table               = ir_id_table,
+       .num_ports              = 1,
+       .set_termios            = ir_set_termios,
+       .attach                 = ir_startup,
+       .open                   = ir_open,
+       .close                  = ir_close,
+       .write                  = ir_write,
+       .write_bulk_callback    = ir_write_bulk_callback,
+       .read_bulk_callback     = ir_read_bulk_callback,
 };
 
-static inline void irda_usb_dump_class_desc(struct irda_class_desc *desc)
+static inline void irda_usb_dump_class_desc(struct usb_irda_cs_descriptor *desc)
 {
        dbg("bLength=%x", desc->bLength);
        dbg("bDescriptorType=%x", desc->bDescriptorType);
-       dbg("bcdSpecRevision=%x", desc->bcdSpecRevision); 
+       dbg("bcdSpecRevision=%x", __le16_to_cpu(desc->bcdSpecRevision));
        dbg("bmDataSize=%x", desc->bmDataSize);
        dbg("bmWindowSize=%x", desc->bmWindowSize);
        dbg("bmMinTurnaroundTime=%d", desc->bmMinTurnaroundTime);
-       dbg("wBaudRate=%x", desc->wBaudRate);
+       dbg("wBaudRate=%x", __le16_to_cpu(desc->wBaudRate));
        dbg("bmAdditionalBOFs=%x", desc->bmAdditionalBOFs);
        dbg("bIrdaRateSniff=%x", desc->bIrdaRateSniff);
        dbg("bMaxUnicastList=%x", desc->bMaxUnicastList);
@@ -181,35 +164,37 @@ static inline void irda_usb_dump_class_desc(struct irda_class_desc *desc)
  *
  * Based on the same function in drivers/net/irda/irda-usb.c
  */
-static struct irda_class_desc *irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum)
+static struct usb_irda_cs_descriptor *
+irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum)
 {
-       struct irda_class_desc *desc;
+       struct usb_irda_cs_descriptor *desc;
        int ret;
-               
-       desc = kzalloc(sizeof (struct irda_class_desc), GFP_KERNEL);
-       if (desc == NULL) 
+
+       desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+       if (!desc)
                return NULL;
-       
-       ret = usb_control_msg(dev, usb_rcvctrlpipe(dev,0),
-                       IU_REQ_GET_CLASS_DESC,
+
+       ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+                       USB_REQ_CS_IRDA_GET_CLASS_DESC,
                        USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                        0, ifnum, desc, sizeof(*desc), 1000);
-       
+
        dbg("%s -  ret=%d", __func__, ret);
        if (ret < sizeof(*desc)) {
                dbg("%s - class descriptor read %s (%d)",
                                __func__,
-                               (ret<0) ? "failed" : "too short",
+                               (ret < 0) ? "failed" : "too short",
                                ret);
                goto error;
        }
-       if (desc->bDescriptorType != USB_DT_IRDA) {
+       if (desc->bDescriptorType != USB_DT_CS_IRDA) {
                dbg("%s - bad class descriptor type", __func__);
                goto error;
        }
-       
+
        irda_usb_dump_class_desc(desc);
        return desc;
+
 error:
        kfree(desc);
        return NULL;
@@ -219,64 +204,101 @@ error:
 static u8 ir_xbof_change(u8 xbof)
 {
        u8 result;
+
        /* reference irda-usb.c */
-       switch(xbof) {
-               case 48: result = 0x10; break;
-               case 28:
-               case 24: result = 0x20; break;
-               default:
-               case 12: result = 0x30; break;
-               case  5:
-               case  6: result = 0x40; break;
-               case  3: result = 0x50; break;
-               case  2: result = 0x60; break;
-               case  1: result = 0x70; break;
-               case  0: result = 0x80; break;
+       switch (xbof) {
+       case 48:
+               result = 0x10;
+               break;
+       case 28:
+       case 24:
+               result = 0x20;
+               break;
+       default:
+       case 12:
+               result = 0x30;
+               break;
+       case  5:
+       case  6:
+               result = 0x40;
+               break;
+       case  3:
+               result = 0x50;
+               break;
+       case  2:
+               result = 0x60;
+               break;
+       case  1:
+               result = 0x70;
+               break;
+       case  0:
+               result = 0x80;
+               break;
        }
+
        return(result);
 }
 
 
-static int ir_startup (struct usb_serial *serial)
+static int ir_startup(struct usb_serial *serial)
 {
-       struct irda_class_desc *irda_desc;
+       struct usb_irda_cs_descriptor *irda_desc;
 
-       irda_desc = irda_usb_find_class_desc (serial->dev, 0);
-       if (irda_desc == NULL) {
-               dev_err (&serial->dev->dev, "IRDA class descriptor not found, device not bound\n");
+       irda_desc = irda_usb_find_class_desc(serial->dev, 0);
+       if (!irda_desc) {
+               dev_err(&serial->dev->dev,
+                       "IRDA class descriptor not found, device not bound\n");
                return -ENODEV;
        }
 
-       dbg ("%s - Baud rates supported:%s%s%s%s%s%s%s%s%s",
+       dbg("%s - Baud rates supported:%s%s%s%s%s%s%s%s%s",
                __func__,
-               (irda_desc->wBaudRate & 0x0001) ? " 2400"    : "",
-               (irda_desc->wBaudRate & 0x0002) ? " 9600"    : "",
-               (irda_desc->wBaudRate & 0x0004) ? " 19200"   : "",
-               (irda_desc->wBaudRate & 0x0008) ? " 38400"   : "",
-               (irda_desc->wBaudRate & 0x0010) ? " 57600"   : "",
-               (irda_desc->wBaudRate & 0x0020) ? " 115200"  : "",
-               (irda_desc->wBaudRate & 0x0040) ? " 576000"  : "",
-               (irda_desc->wBaudRate & 0x0080) ? " 1152000" : "",
-               (irda_desc->wBaudRate & 0x0100) ? " 4000000" : "");
-
-       switch( irda_desc->bmAdditionalBOFs ) {
-               case 0x01: ir_add_bof = 48; break;
-               case 0x02: ir_add_bof = 24; break;
-               case 0x04: ir_add_bof = 12; break;
-               case 0x08: ir_add_bof =  6; break;
-               case 0x10: ir_add_bof =  3; break;
-               case 0x20: ir_add_bof =  2; break;
-               case 0x40: ir_add_bof =  1; break;
-               case 0x80: ir_add_bof =  0; break;
-               default:;
+               (irda_desc->wBaudRate & USB_IRDA_BR_2400) ? " 2400" : "",
+               (irda_desc->wBaudRate & USB_IRDA_BR_9600) ? " 9600" : "",
+               (irda_desc->wBaudRate & USB_IRDA_BR_19200) ? " 19200" : "",
+               (irda_desc->wBaudRate & USB_IRDA_BR_38400) ? " 38400" : "",
+               (irda_desc->wBaudRate & USB_IRDA_BR_57600) ? " 57600" : "",
+               (irda_desc->wBaudRate & USB_IRDA_BR_115200) ? " 115200" : "",
+               (irda_desc->wBaudRate & USB_IRDA_BR_576000) ? " 576000" : "",
+               (irda_desc->wBaudRate & USB_IRDA_BR_1152000) ? " 1152000" : "",
+               (irda_desc->wBaudRate & USB_IRDA_BR_4000000) ? " 4000000" : "");
+
+       switch (irda_desc->bmAdditionalBOFs) {
+       case USB_IRDA_AB_48:
+               ir_add_bof = 48;
+               break;
+       case USB_IRDA_AB_24:
+               ir_add_bof = 24;
+               break;
+       case USB_IRDA_AB_12:
+               ir_add_bof = 12;
+               break;
+       case USB_IRDA_AB_6:
+               ir_add_bof = 6;
+               break;
+       case USB_IRDA_AB_3:
+               ir_add_bof = 3;
+               break;
+       case USB_IRDA_AB_2:
+               ir_add_bof = 2;
+               break;
+       case USB_IRDA_AB_1:
+               ir_add_bof = 1;
+               break;
+       case USB_IRDA_AB_0:
+               ir_add_bof = 0;
+               break;
+       default:
+               break;
        }
 
-       kfree (irda_desc);
+       kfree(irda_desc);
 
-       return 0;               
+       return 0;
 }
 
-static int ir_open (struct usb_serial_port *port, struct file *filp)
+static int ir_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        char *buffer;
        int result = 0;
@@ -285,51 +307,56 @@ static int ir_open (struct usb_serial_port *port, struct file *filp)
 
        if (buffer_size) {
                /* override the default buffer sizes */
-               buffer = kmalloc (buffer_size, GFP_KERNEL);
+               buffer = kmalloc(buffer_size, GFP_KERNEL);
                if (!buffer) {
-                       dev_err (&port->dev, "%s - out of memory.\n", __func__);
+                       dev_err(&port->dev, "%s - out of memory.\n", __func__);
                        return -ENOMEM;
                }
-               kfree (port->read_urb->transfer_buffer);
+               kfree(port->read_urb->transfer_buffer);
                port->read_urb->transfer_buffer = buffer;
                port->read_urb->transfer_buffer_length = buffer_size;
 
-               buffer = kmalloc (buffer_size, GFP_KERNEL);
+               buffer = kmalloc(buffer_size, GFP_KERNEL);
                if (!buffer) {
-                       dev_err (&port->dev, "%s - out of memory.\n", __func__);
+                       dev_err(&port->dev, "%s - out of memory.\n", __func__);
                        return -ENOMEM;
                }
-               kfree (port->write_urb->transfer_buffer);
+               kfree(port->write_urb->transfer_buffer);
                port->write_urb->transfer_buffer = buffer;
                port->write_urb->transfer_buffer_length = buffer_size;
                port->bulk_out_size = buffer_size;
        }
 
        /* Start reading from the device */
-       usb_fill_bulk_urb (
+       usb_fill_bulk_urb(
                port->read_urb,
-               port->serial->dev, 
-               usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress),
+               port->serial->dev,
+               usb_rcvbulkpipe(port->serial->dev,
+                       port->bulk_in_endpointAddress),
                port->read_urb->transfer_buffer,
                port->read_urb->transfer_buffer_length,
                ir_read_bulk_callback,
                port);
        result = usb_submit_urb(port->read_urb, GFP_KERNEL);
        if (result)
-               dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result);
+               dev_err(&port->dev,
+                       "%s - failed submitting read urb, error %d\n",
+                       __func__, result);
 
        return result;
 }
 
-static void ir_close (struct usb_serial_port *port, struct file * filp)
+static void ir_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file * filp)
 {
        dbg("%s - port %d", __func__, port->number);
-                        
+
        /* shutdown our bulk read */
        usb_kill_urb(port->read_urb);
 }
 
-static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int count)
+static int ir_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                       const unsigned char *buf, int count)
 {
        unsigned char *transfer_buffer;
        int result;
@@ -337,11 +364,6 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
 
        dbg("%s - port = %d, count = %d", __func__, port->number, count);
 
-       if (!port->tty) {
-               dev_err (&port->dev, "%s - no tty???\n", __func__);
-               return 0;
-       }
-
        if (count == 0)
                return 0;
 
@@ -359,7 +381,7 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
 
        /*
         * The first byte of the packet we send to the device contains an
-        * inband header which indicates an additional number of BOFs and
+        * inbound header which indicates an additional number of BOFs and
         * a baud rate change.
         *
         * See section 5.4.2.2 of the USB IrDA spec.
@@ -367,9 +389,9 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
        *transfer_buffer = ir_xbof | ir_baud;
        ++transfer_buffer;
 
-       memcpy (transfer_buffer, buf, transfer_size);
+       memcpy(transfer_buffer, buf, transfer_size);
 
-       usb_fill_bulk_urb (
+       usb_fill_bulk_urb(
                port->write_urb,
                port->serial->dev,
                usb_sndbulkpipe(port->serial->dev,
@@ -381,17 +403,19 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
 
        port->write_urb->transfer_flags = URB_ZERO_PACKET;
 
-       result = usb_submit_urb (port->write_urb, GFP_ATOMIC);
+       result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
        if (result) {
                port->write_urb_busy = 0;
-               dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result);
+               dev_err(&port->dev,
+                       "%s - failed submitting write urb, error %d\n",
+                       __func__, result);
        } else
                result = transfer_size;
 
        return result;
 }
 
-static void ir_write_bulk_callback (struct urb *urb)
+static void ir_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        int status = urb->status;
@@ -405,7 +429,7 @@ static void ir_write_bulk_callback (struct urb *urb)
                return;
        }
 
-       usb_serial_debug_data (
+       usb_serial_debug_data(
                debug,
                &port->dev,
                __func__,
@@ -415,7 +439,7 @@ static void ir_write_bulk_callback (struct urb *urb)
        usb_serial_port_softint(port);
 }
 
-static void ir_read_bulk_callback (struct urb *urb)
+static void ir_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct tty_struct *tty;
@@ -425,74 +449,61 @@ static void ir_read_bulk_callback (struct urb *urb)
 
        dbg("%s - port %d", __func__, port->number);
 
-       if (!port->open_count) {
+       if (!port->port.count) {
                dbg("%s - port closed.", __func__);
                return;
        }
 
        switch (status) {
-               case 0: /* Successful */
-
-                       /*
-                        * The first byte of the packet we get from the device
-                        * contains a busy indicator and baud rate change.
-                        * See section 5.4.1.2 of the USB IrDA spec.
-                        */
-                       if ((*data & 0x0f) > 0)
-                               ir_baud = *data & 0x0f;
-
-                       usb_serial_debug_data (
-                               debug,
-                               &port->dev,
-                               __func__,
-                               urb->actual_length,
-                               data);
-
-                       tty = port->tty;
-
-                       if (tty_buffer_request_room(tty, urb->actual_length - 1)) {
-                               tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
-                               tty_flip_buffer_push(tty);
-                       }
-
-                       /*
-                        * No break here.
-                        * We want to resubmit the urb so we can read
-                        * again.
-                        */
+       case 0: /* Successful */
+               /*
+                * The first byte of the packet we get from the device
+                * contains a busy indicator and baud rate change.
+                * See section 5.4.1.2 of the USB IrDA spec.
+                */
+               if ((*data & 0x0f) > 0)
+                       ir_baud = *data & 0x0f;
+               usb_serial_debug_data(debug, &port->dev, __func__,
+                                               urb->actual_length, data);
+               tty = port->port.tty;
+               if (tty_buffer_request_room(tty, urb->actual_length - 1)) {
+                       tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
+                       tty_flip_buffer_push(tty);
+               }
 
-               case -EPROTO: /* taking inspiration from pl2303.c */
+               /*
+                * No break here.
+                * We want to resubmit the urb so we can read
+                * again.
+                */
 
+       case -EPROTO: /* taking inspiration from pl2303.c */
                        /* Continue trying to always read */
-                       usb_fill_bulk_urb (
-                               port->read_urb,
-                               port->serial->dev, 
-                               usb_rcvbulkpipe(port->serial->dev,
-                                       port->bulk_in_endpointAddress),
-                               port->read_urb->transfer_buffer,
-                               port->read_urb->transfer_buffer_length,
-                               ir_read_bulk_callback,
-                               port);
-
-                       result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
-                       if (result)
-                               dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n",
-                                       __func__, result);
-
-                       break ;
-
-               default:
-                       dbg("%s - nonzero read bulk status received: %d",
-                               __func__,
-                               status);
+               usb_fill_bulk_urb(
+                       port->read_urb,
+                       port->serial->dev, 
+                       usb_rcvbulkpipe(port->serial->dev,
+                               port->bulk_in_endpointAddress),
+                       port->read_urb->transfer_buffer,
+                       port->read_urb->transfer_buffer_length,
+                       ir_read_bulk_callback,
+                       port);
+
+               result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+               if (result)
+                       dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n",
+                               __func__, result);
                        break ;
-
+       default:
+               dbg("%s - nonzero read bulk status received: %d",
+                       __func__, status);
+               break ;
        }
-
        return;
 }
 
-static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
+static void ir_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        unsigned char *transfer_buffer;
        int result;
@@ -501,7 +512,7 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
 
        dbg("%s - port %d", __func__, port->number);
 
-       baud = tty_get_baud_rate(port->tty);
+       baud = tty_get_baud_rate(tty);
 
        /*
         * FIXME, we should compare the baud request against the
@@ -510,19 +521,36 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
         */
 
        switch (baud) {
-               case 2400:      ir_baud = SPEED_2400; break;
-               case 9600:      ir_baud = SPEED_9600; break;
-               case 19200:     ir_baud = SPEED_19200; break;
-               case 38400:     ir_baud = SPEED_38400; break;
-               case 57600:     ir_baud = SPEED_57600; break;
-               case 115200:    ir_baud = SPEED_115200; break;
-               case 576000:    ir_baud = SPEED_576000; break;
-               case 1152000:   ir_baud = SPEED_1152000; break;
-               case 4000000:   ir_baud = SPEED_4000000; break;
-                       break;
-               default:
-                       ir_baud = SPEED_9600;
-                       baud = 9600;
+       case 2400:
+               ir_baud = USB_IRDA_BR_2400;
+               break;
+       case 9600:
+               ir_baud = USB_IRDA_BR_9600;
+               break;
+       case 19200:
+               ir_baud = USB_IRDA_BR_19200;
+               break;
+       case 38400:
+               ir_baud = USB_IRDA_BR_38400;
+               break;
+       case 57600:
+               ir_baud = USB_IRDA_BR_57600;
+               break;
+       case 115200:
+               ir_baud = USB_IRDA_BR_115200;
+               break;
+       case 576000:
+               ir_baud = USB_IRDA_BR_576000;
+               break;
+       case 1152000:
+               ir_baud = USB_IRDA_BR_1152000;
+               break;
+       case 4000000:
+               ir_baud = USB_IRDA_BR_4000000;
+               break;
+       default:
+               ir_baud = USB_IRDA_BR_9600;
+               baud = 9600;
        }
 
        if (xbof == -1)
@@ -538,10 +566,11 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
        transfer_buffer = port->write_urb->transfer_buffer;
        *transfer_buffer = ir_xbof | ir_baud;
 
-       usb_fill_bulk_urb (
+       usb_fill_bulk_urb(
                port->write_urb,
                port->serial->dev,
-               usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress),
+               usb_sndbulkpipe(port->serial->dev,
+                       port->bulk_out_endpointAddress),
                port->write_urb->transfer_buffer,
                1,
                ir_write_bulk_callback,
@@ -549,38 +578,44 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
 
        port->write_urb->transfer_flags = URB_ZERO_PACKET;
 
-       result = usb_submit_urb (port->write_urb, GFP_KERNEL);
+       result = usb_submit_urb(port->write_urb, GFP_KERNEL);
        if (result)
-               dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __func__, result);
+               dev_err(&port->dev,
+                               "%s - failed submitting write urb, error %d\n",
+                               __func__, result);
 
        /* Only speed changes are supported */
-       tty_termios_copy_hw(port->tty->termios, old_termios);
-       tty_encode_baud_rate(port->tty, baud, baud);
+       tty_termios_copy_hw(tty->termios, old_termios);
+       tty_encode_baud_rate(tty, baud, baud);
 }
 
-
-static int __init ir_init (void)
+static int __init ir_init(void)
 {
        int retval;
+
        retval = usb_serial_register(&ir_device);
        if (retval)
                goto failed_usb_serial_register;
+
        retval = usb_register(&ir_driver);
-       if (retval) 
+       if (retval)
                goto failed_usb_register;
+
        info(DRIVER_DESC " " DRIVER_VERSION);
+
        return 0;
+
 failed_usb_register:
        usb_serial_deregister(&ir_device);
+
 failed_usb_serial_register:
        return retval;
 }
 
-
-static void __exit ir_exit (void)
+static void __exit ir_exit(void)
 {
-       usb_deregister (&ir_driver);
-       usb_serial_deregister (&ir_device);
+       usb_deregister(&ir_driver);
+       usb_serial_deregister(&ir_device);
 }
 
 
index a01e987c7d32e274d8d060ef15276fae913a1ca0..ddff37fa633904b28cb7a8ffe41c2a4804491c5f 100644 (file)
@@ -144,9 +144,10 @@ static void iuu_shutdown(struct usb_serial *serial)
        }
 }
 
-static int iuu_tiocmset(struct usb_serial_port *port, struct file *file,
+static int iuu_tiocmset(struct tty_struct *tty, struct file *file,
                        unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct iuu_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
 
@@ -171,8 +172,9 @@ static int iuu_tiocmset(struct usb_serial_port *port, struct file *file,
  * When no card , the reader respond with TIOCM_CD
  * This is known as CD autodetect mechanism
  */
-static int iuu_tiocmget(struct usb_serial_port *port, struct file *file)
+static int iuu_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct iuu_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        int rc;
@@ -316,11 +318,10 @@ static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
                                         port->bulk_out_endpointAddress), buf,
                         count, &actual, HZ * 1);
 
-       if (status != IUU_OPERATION_OK) {
+       if (status != IUU_OPERATION_OK)
                dbg("%s - error = %2x", __func__, status);
-       } else {
+       else
                dbg("%s - write OK !", __func__);
-       }
        return status;
 }
 
@@ -340,12 +341,10 @@ static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
                                         port->bulk_in_endpointAddress), buf,
                         count, &actual, HZ * 1);
 
-       if (status != IUU_OPERATION_OK) {
+       if (status != IUU_OPERATION_OK)
                dbg("%s - error = %2x", __func__, status);
-       } else {
+       else
                dbg("%s - read OK !", __func__);
-       }
-
        return status;
 }
 
@@ -630,7 +629,7 @@ static void read_buf_callback(struct urb *urb)
        }
 
        dbg("%s - %i chars to write", __func__, urb->actual_length);
-       tty = port->tty;
+       tty = port->port.tty;
        if (data == NULL)
                dbg("%s - data is NULL !!!", __func__);
        if (tty && urb->actual_length && data) {
@@ -752,11 +751,10 @@ static void iuu_uart_read_callback(struct urb *urb)
        /* if nothing to write call again rxcmd */
        dbg("%s - rxcmd recall", __func__);
        iuu_led_activity_off(urb);
-       return;
 }
 
-static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf,
-                         int count)
+static int iuu_uart_write(struct tty_struct *tty, struct usb_serial_port *port,
+                         const u8 *buf, int count)
 {
        struct iuu_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
@@ -769,14 +767,14 @@ static int iuu_uart_write(struct usb_serial_port *port, const u8 *buf,
        if (priv->writelen > 0) {
                /* buffer already filled but not commited */
                spin_unlock_irqrestore(&priv->lock, flags);
-               return (0);
+               return 0;
        }
        /* fill the buffer */
        memcpy(priv->writebuf, buf, count);
        priv->writelen = count;
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       return (count);
+       return count;
 }
 
 static void read_rxcmd_callback(struct urb *urb)
@@ -948,7 +946,8 @@ static int set_control_lines(struct usb_device *dev, u8 value)
        return 0;
 }
 
-static void iuu_close(struct usb_serial_port *port, struct file *filp)
+static void iuu_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        /* iuu_led (port,255,0,0,0); */
        struct usb_serial *serial;
@@ -964,8 +963,8 @@ static void iuu_close(struct usb_serial_port *port, struct file *filp)
 
        iuu_uart_off(port);
        if (serial->dev) {
-               if (port->tty) {
-                       c_cflag = port->tty->termios->c_cflag;
+               if (tty) {
+                       c_cflag = tty->termios->c_cflag;
                        if (c_cflag & HUPCL) {
                                /* drop DTR and RTS */
                                priv = usb_get_serial_port_data(port);
@@ -989,7 +988,8 @@ static void iuu_close(struct usb_serial_port *port, struct file *filp)
        }
 }
 
-static int iuu_open(struct usb_serial_port *port, struct file *filp)
+static int iuu_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial = port->serial;
        u8 *buf;
@@ -1036,15 +1036,17 @@ static int iuu_open(struct usb_serial_port *port, struct file *filp)
 
        /* set the termios structure */
        spin_lock_irqsave(&priv->lock, flags);
-       if (!priv->termios_initialized) {
-               *(port->tty->termios) = tty_std_termios;
-               port->tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
-                                               | TIOCM_CTS | CSTOPB | PARENB;
-               port->tty->termios->c_lflag = 0;
-               port->tty->termios->c_oflag = 0;
-               port->tty->termios->c_iflag = 0;
+       if (tty && !priv->termios_initialized) {
+               *(tty->termios) = tty_std_termios;
+               tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
+                                       | TIOCM_CTS | CSTOPB | PARENB;
+               tty->termios->c_ispeed = 9600;
+               tty->termios->c_ospeed = 9600;
+               tty->termios->c_lflag = 0;
+               tty->termios->c_oflag = 0;
+               tty->termios->c_iflag = 0;
                priv->termios_initialized = 1;
-               port->tty->low_latency = 1;
+               tty->low_latency = 1;
                priv->poll = 0;
         }
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -1148,7 +1150,7 @@ static int iuu_open(struct usb_serial_port *port, struct file *filp)
        if (result) {
                dev_err(&port->dev, "%s - failed submitting read urb,"
                        " error %d\n", __func__, result);
-               iuu_close(port, NULL);
+               iuu_close(tty, port, NULL);
                return -EPROTO;
        } else {
                dbg("%s - rxcmd OK", __func__);
index 11e439b90eacd88a2a89e1a48ee6759e7982ccc0..704716f6f6d378c825920c213f3cedd7585b0ab5 100644 (file)
@@ -1,29 +1,29 @@
 /*
   Keyspan USB to Serial Converter driver
+
   (C) Copyright (C) 2000-2001  Hugh Blemings <hugh@blemings.org>
   (C) Copyright (C) 2002       Greg Kroah-Hartman <greg@kroah.com>
-   
+
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
 
   See http://misc.nu/hugh/keyspan.html for more information.
-  
+
   Code in this driver inspired by and in a number of places taken
   from Brian Warner's original Keyspan-PDA driver.
 
   This driver has been put together with the support of Innosys, Inc.
   and Keyspan, Inc the manufacturers of the Keyspan USB-serial products.
   Thanks Guys :)
-  
+
   Thanks to Paulus for miscellaneous tidy ups, some largish chunks
   of much nicer and/or completely new code and (perhaps most uniquely)
   having the patience to sit down and explain why and where he'd changed
-  stuff. 
-  
-  Tip 'o the hat to IBM (and previously Linuxcare :) for supporting 
+  stuff.
+
+  Tip 'o the hat to IBM (and previously Linuxcare :) for supporting
   staff in their work on open source projects.
 
   Change History
 
     Thu May 31 11:56:42 PDT 2001 gkh
       switched from using spinlock to a semaphore
-   
+
     (04/08/2001) gb
        Identify version on module load.
-   
+
     (11/01/2000) Adam J. Richter
        usb_device_id table support.
-   
+
     Tue Oct 10 23:15:33 EST 2000 Hugh
       Merged Paul's changes with my USA-49W mods.  Work in progress
       still...
-  
+
     Wed Jul 19 14:00:42 EST 2000 gkh
       Added module_init and module_exit functions to handle the fact that
       this driver is a loadable module now.
+
     Tue Jul 18 16:14:52 EST 2000 Hugh
       Basic character input/output for USA-19 now mostly works,
       fixed at 9600 baud for the moment.
 #include <linux/spinlock.h>
 #include <linux/firmware.h>
 #include <linux/ihex.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include "keyspan.h"
@@ -132,15 +132,15 @@ struct keyspan_serial_private {
        struct urb      *instat_urb;
        char            instat_buf[INSTAT_BUFLEN];
 
-       /* added to support 49wg, where data from all 4 ports comes in on 1 EP */
-       /* and high-speed supported */
+       /* added to support 49wg, where data from all 4 ports comes in
+          on 1 EP and high-speed supported */
        struct urb      *indat_urb;
        char            indat_buf[INDAT49W_BUFLEN];
 
        /* XXX this one probably will need a lock */
        struct urb      *glocont_urb;
        char            glocont_buf[GLOCONT_BUFLEN];
-       char            ctrl_buf[8];                    // for EP0 control message
+       char            ctrl_buf[8];    /* for EP0 control message */
 };
 
 struct keyspan_port_private {
@@ -186,19 +186,19 @@ struct keyspan_port_private {
        int             resend_cont;    /* need to resend control packet */
 };
 
-       
 /* Include Keyspan message headers.  All current Keyspan Adapters
    make use of one of five message formats which are referred
-   to as USA-26, USA-28, USA-49, USA-90, USA-67 by Keyspan and within this driver. */
+   to as USA-26, USA-28, USA-49, USA-90, USA-67 by Keyspan and
+   within this driver. */
 #include "keyspan_usa26msg.h"
 #include "keyspan_usa28msg.h"
 #include "keyspan_usa49msg.h"
 #include "keyspan_usa90msg.h"
 #include "keyspan_usa67msg.h"
-       
+
 
 /* Functions used by new usb-serial code. */
-static int __init keyspan_init (void)
+static int __init keyspan_init(void)
 {
        int retval;
        retval = usb_serial_register(&keyspan_pre_device);
@@ -214,7 +214,7 @@ static int __init keyspan_init (void)
        if (retval)
                goto failed_4port_device_register;
        retval = usb_register(&keyspan_driver);
-       if (retval) 
+       if (retval)
                goto failed_usb_register;
 
        info(DRIVER_VERSION ":" DRIVER_DESC);
@@ -232,35 +232,24 @@ failed_pre_device_register:
        return retval;
 }
 
-static void __exit keyspan_exit (void)
+static void __exit keyspan_exit(void)
 {
-       usb_deregister (&keyspan_driver);
-       usb_serial_deregister (&keyspan_pre_device);
-       usb_serial_deregister (&keyspan_1port_device);
-       usb_serial_deregister (&keyspan_2port_device);
-       usb_serial_deregister (&keyspan_4port_device);
+       usb_deregister(&keyspan_driver);
+       usb_serial_deregister(&keyspan_pre_device);
+       usb_serial_deregister(&keyspan_1port_device);
+       usb_serial_deregister(&keyspan_2port_device);
+       usb_serial_deregister(&keyspan_4port_device);
 }
 
 module_init(keyspan_init);
 module_exit(keyspan_exit);
 
-static void keyspan_rx_throttle (struct usb_serial_port *port)
-{
-       dbg("%s - port %d", __func__, port->number);
-}
-
-
-static void keyspan_rx_unthrottle (struct usb_serial_port *port)
-{
-       dbg("%s - port %d", __func__, port->number);
-}
-
-
-static void keyspan_break_ctl (struct usb_serial_port *port, int break_state)
+static void keyspan_break_ctl(struct tty_struct *tty, int break_state)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct keyspan_port_private     *p_priv;
 
-       dbg("%s", __func__);
+       dbg("%s", __func__);
 
        p_priv = usb_get_serial_port_data(port);
 
@@ -273,14 +262,13 @@ static void keyspan_break_ctl (struct usb_serial_port *port, int break_state)
 }
 
 
-static void keyspan_set_termios (struct usb_serial_port *port, 
-                                    struct ktermios *old_termios)
+static void keyspan_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        int                             baud_rate, device_port;
        struct keyspan_port_private     *p_priv;
        const struct keyspan_device_details     *d_details;
        unsigned int                    cflag;
-       struct tty_struct               *tty = port->tty;
 
        dbg("%s", __func__);
 
@@ -292,7 +280,7 @@ static void keyspan_set_termios (struct usb_serial_port *port,
        /* Baud rate calculation takes baud rate as an integer
           so other rates can be generated if desired. */
        baud_rate = tty_get_baud_rate(tty);
-       /* If no match or invalid, don't change */              
+       /* If no match or invalid, don't change */
        if (d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
                                NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
                /* FIXME - more to do here to ensure rate changes cleanly */
@@ -312,35 +300,32 @@ static void keyspan_set_termios (struct usb_serial_port *port,
        keyspan_send_setup(port, 0);
 }
 
-static int keyspan_tiocmget(struct usb_serial_port *port, struct file *file)
+static int keyspan_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
+       struct keyspan_port_private *p_priv = usb_get_serial_port_data(port);
        unsigned int                    value;
-       struct keyspan_port_private     *p_priv;
 
-       p_priv = usb_get_serial_port_data(port);
-       
        value = ((p_priv->rts_state) ? TIOCM_RTS : 0) |
                ((p_priv->dtr_state) ? TIOCM_DTR : 0) |
                ((p_priv->cts_state) ? TIOCM_CTS : 0) |
                ((p_priv->dsr_state) ? TIOCM_DSR : 0) |
                ((p_priv->dcd_state) ? TIOCM_CAR : 0) |
-               ((p_priv->ri_state) ? TIOCM_RNG : 0); 
+               ((p_priv->ri_state) ? TIOCM_RNG : 0);
 
        return value;
 }
 
-static int keyspan_tiocmset(struct usb_serial_port *port, struct file *file,
+static int keyspan_tiocmset(struct tty_struct *tty, struct file *file,
                            unsigned int set, unsigned int clear)
 {
-       struct keyspan_port_private     *p_priv;
+       struct usb_serial_port *port = tty->driver_data;
+       struct keyspan_port_private *p_priv = usb_get_serial_port_data(port);
 
-       p_priv = usb_get_serial_port_data(port);
-       
        if (set & TIOCM_RTS)
                p_priv->rts_state = 1;
        if (set & TIOCM_DTR)
                p_priv->dtr_state = 1;
-
        if (clear & TIOCM_RTS)
                p_priv->rts_state = 0;
        if (clear & TIOCM_DTR)
@@ -349,35 +334,29 @@ static int keyspan_tiocmset(struct usb_serial_port *port, struct file *file,
        return 0;
 }
 
-static int keyspan_ioctl(struct usb_serial_port *port, struct file *file,
-                            unsigned int cmd, unsigned long arg)
-{
-       return -ENOIOCTLCMD;
-}
-
-       /* Write function is similar for the four protocols used
-          with only a minor change for usa90 (usa19hs) required */
-static int keyspan_write(struct usb_serial_port *port, 
-                        const unsigned char *buf, int count)
+/* Write function is similar for the four protocols used
+   with only a minor change for usa90 (usa19hs) required */
+static int keyspan_write(struct tty_struct *tty,
+       struct usb_serial_port *port, const unsigned char *buf, int count)
 {
        struct keyspan_port_private     *p_priv;
        const struct keyspan_device_details     *d_details;
        int                             flip;
        int                             left, todo;
        struct urb                      *this_urb;
-       int                             err, maxDataLen, dataOffset;
+       int                             err, maxDataLen, dataOffset;
 
        p_priv = usb_get_serial_port_data(port);
        d_details = p_priv->device_details;
 
        if (d_details->msg_format == msg_usa90) {
-               maxDataLen = 64;
+               maxDataLen = 64;
                dataOffset = 0;
        } else {
                maxDataLen = 63;
                dataOffset = 1;
        }
-       
+
        dbg("%s - for port %d (%d chars), flip=%d",
            __func__, port->number, count, p_priv->out_flip);
 
@@ -387,37 +366,40 @@ static int keyspan_write(struct usb_serial_port *port,
                        todo = maxDataLen;
 
                flip = p_priv->out_flip;
-       
+
                /* Check we have a valid urb/endpoint before we use it... */
-               if ((this_urb = p_priv->out_urbs[flip]) == NULL) {
+               this_urb = p_priv->out_urbs[flip];
+               if (this_urb == NULL) {
                        /* no bulk out, so return 0 bytes written */
                        dbg("%s - no output urb :(", __func__);
                        return count;
                }
 
-               dbg("%s - endpoint %d flip %d", __func__, usb_pipeendpoint(this_urb->pipe), flip);
+               dbg("%s - endpoint %d flip %d",
+                       __func__, usb_pipeendpoint(this_urb->pipe), flip);
 
                if (this_urb->status == -EINPROGRESS) {
-                       if (time_before(jiffies, p_priv->tx_start_time[flip] + 10 * HZ))
+                       if (time_before(jiffies,
+                                       p_priv->tx_start_time[flip] + 10 * HZ))
                                break;
                        usb_unlink_urb(this_urb);
                        break;
                }
 
-               /* First byte in buffer is "last flag" (except for usa19hx) - unused so
-                  for now so set to zero */
+               /* First byte in buffer is "last flag" (except for usa19hx)
+                  - unused so for now so set to zero */
                ((char *)this_urb->transfer_buffer)[0] = 0;
 
-               memcpy (this_urb->transfer_buffer + dataOffset, buf, todo);
+               memcpy(this_urb->transfer_buffer + dataOffset, buf, todo);
                buf += todo;
 
                /* send the data out the bulk port */
                this_urb->transfer_buffer_length = todo + dataOffset;
 
                this_urb->dev = port->serial->dev;
-               if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
+               err = usb_submit_urb(this_urb, GFP_ATOMIC);
+               if (err != 0)
                        dbg("usb_submit_urb(write bulk) failed (%d)", err);
-               }
                p_priv->tx_start_time[flip] = jiffies;
 
                /* Flip for next time if usa26 or usa28 interface
@@ -437,7 +419,7 @@ static void usa26_indat_callback(struct urb *urb)
        unsigned char           *data = urb->transfer_buffer;
        int status = urb->status;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        endpoint = usb_pipeendpoint(urb->pipe);
 
@@ -448,17 +430,18 @@ static void       usa26_indat_callback(struct urb *urb)
        }
 
        port =  urb->context;
-       tty = port->tty;
+       tty = port->port.tty;
        if (tty && urb->actual_length) {
                /* 0x80 bit is error flag */
                if ((data[0] & 0x80) == 0) {
-                       /* no errors on individual bytes, only possible overrun err*/
+                       /* no errors on individual bytes, only
+                          possible overrun err */
                        if (data[0] & RXERROR_OVERRUN)
-                                       err = TTY_OVERRUN;
-                       else err = 0;
-                       for (i = 1; i < urb->actual_length ; ++i) {
+                               err = TTY_OVERRUN;
+                       else
+                               err = 0;
+                       for (i = 1; i < urb->actual_length ; ++i)
                                tty_insert_flip_char(tty, data[i], err);
-                       }
                } else {
                        /* some bytes had errors, every byte has status */
                        dbg("%s - RX error!!!!", __func__);
@@ -476,17 +459,19 @@ static void       usa26_indat_callback(struct urb *urb)
                }
                tty_flip_buffer_push(tty);
        }
-                               
-               /* Resubmit urb so we continue receiving */
+
+       /* Resubmit urb so we continue receiving */
        urb->dev = port->serial->dev;
-       if (port->open_count)
-               if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
-                       dbg("%s - resubmit read urb failed. (%d)", __func__, err);
-               }
+       if (port->port.count) {
+               err = usb_submit_urb(urb, GFP_ATOMIC);
+               if (err != 0)
+                       dbg("%s - resubmit read urb failed. (%d)",
+                                       __func__, err);
+       }
        return;
 }
 
-       /* Outdat handling is common for all devices */
+/* Outdat handling is common for all devices */
 static void    usa2x_outdat_callback(struct urb *urb)
 {
        struct usb_serial_port *port;
@@ -494,16 +479,16 @@ static void       usa2x_outdat_callback(struct urb *urb)
 
        port =  urb->context;
        p_priv = usb_get_serial_port_data(port);
-       dbg ("%s - urb %d", __func__, urb == p_priv->out_urbs[1]);
+       dbg("%s - urb %d", __func__, urb == p_priv->out_urbs[1]);
 
-       if (port->open_count)
+       if (port->port.count)
                usb_serial_port_softint(port);
 }
 
 static void    usa26_inack_callback(struct urb *urb)
 {
-       dbg ("%s", __func__);
-       
+       dbg("%s", __func__);
+
 }
 
 static void    usa26_outcont_callback(struct urb *urb)
@@ -515,8 +500,9 @@ static void usa26_outcont_callback(struct urb *urb)
        p_priv = usb_get_serial_port_data(port);
 
        if (p_priv->resend_cont) {
-               dbg ("%s - sending setup", __func__);
-               keyspan_usa26_send_setup(port->serial, port, p_priv->resend_cont - 1);
+               dbg("%s - sending setup", __func__);
+               keyspan_usa26_send_setup(port->serial, port,
+                                               p_priv->resend_cont - 1);
        }
 }
 
@@ -552,14 +538,14 @@ static void       usa26_instat_callback(struct urb *urb)
        /* Now do something useful with the data */
 
 
-       /* Check port number from message and retrieve private data */  
+       /* Check port number from message and retrieve private data */
        if (msg->port >= serial->num_ports) {
-               dbg ("%s - Unexpected port number %d", __func__, msg->port);
+               dbg("%s - Unexpected port number %d", __func__, msg->port);
                goto exit;
        }
        port = serial->port[msg->port];
        p_priv = usb_get_serial_port_data(port);
-       
+
        /* Update handshaking pin state information */
        old_dcd_state = p_priv->dcd_state;
        p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
@@ -567,39 +553,38 @@ static void       usa26_instat_callback(struct urb *urb)
        p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
        p_priv->ri_state = ((msg->ri) ? 1 : 0);
 
-       if (port->tty && !C_CLOCAL(port->tty)
+       if (port->port.tty && !C_CLOCAL(port->port.tty)
            && old_dcd_state != p_priv->dcd_state) {
                if (old_dcd_state)
-                       tty_hangup(port->tty);
+                       tty_hangup(port->port.tty);
                /*  else */
                /*      wake_up_interruptible(&p_priv->open_wait); */
        }
-       
+
        /* Resubmit urb so we continue receiving */
        urb->dev = serial->dev;
-       if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err != 0)
                dbg("%s - resubmit read urb failed. (%d)", __func__, err);
-       }
 exit: ;
 }
 
 static void    usa26_glocont_callback(struct urb *urb)
 {
-       dbg ("%s", __func__);
-       
+       dbg("%s", __func__);
 }
 
 
 static void usa28_indat_callback(struct urb *urb)
 {
-       int                     i, err;
+       int                     err;
        struct usb_serial_port  *port;
        struct tty_struct       *tty;
        unsigned char           *data;
        struct keyspan_port_private             *p_priv;
        int status = urb->status;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        port =  urb->context;
        p_priv = usb_get_serial_port_data(port);
@@ -619,20 +604,20 @@ static void usa28_indat_callback(struct urb *urb)
                p_priv = usb_get_serial_port_data(port);
                data = urb->transfer_buffer;
 
-               tty = port->tty;
+               tty = port->port.tty;
                if (urb->actual_length) {
-                       for (i = 0; i < urb->actual_length ; ++i) {
-                               tty_insert_flip_char(tty, data[i], 0);
-                       }
+                       tty_insert_flip_string(tty, data, urb->actual_length);
                        tty_flip_buffer_push(tty);
                }
 
                /* Resubmit urb so we continue receiving */
                urb->dev = port->serial->dev;
-               if (port->open_count)
-                       if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
-                               dbg("%s - resubmit read urb failed. (%d)", __func__, err);
-                       }
+               if (port->port.count) {
+                       err = usb_submit_urb(urb, GFP_ATOMIC);
+                       if (err != 0)
+                               dbg("%s - resubmit read urb failed. (%d)",
+                                                               __func__, err);
+               }
                p_priv->in_flip ^= 1;
 
                urb = p_priv->in_urbs[p_priv->in_flip];
@@ -641,7 +626,7 @@ static void usa28_indat_callback(struct urb *urb)
 
 static void    usa28_inack_callback(struct urb *urb)
 {
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 }
 
 static void    usa28_outcont_callback(struct urb *urb)
@@ -653,8 +638,9 @@ static void usa28_outcont_callback(struct urb *urb)
        p_priv = usb_get_serial_port_data(port);
 
        if (p_priv->resend_cont) {
-               dbg ("%s - sending setup", __func__);
-               keyspan_usa28_send_setup(port->serial, port, p_priv->resend_cont - 1);
+               dbg("%s - sending setup", __func__);
+               keyspan_usa28_send_setup(port->serial, port,
+                                               p_priv->resend_cont - 1);
        }
 }
 
@@ -684,19 +670,18 @@ static void       usa28_instat_callback(struct urb *urb)
        /*dbg("%s %x %x %x %x %x %x %x %x %x %x %x %x", __func__
            data[0], data[1], data[2], data[3], data[4], data[5],
            data[6], data[7], data[8], data[9], data[10], data[11]);*/
-       
-               /* Now do something useful with the data */
-       msg = (struct keyspan_usa28_portStatusMessage *)data;
 
+       /* Now do something useful with the data */
+       msg = (struct keyspan_usa28_portStatusMessage *)data;
 
-               /* Check port number from message and retrieve private data */  
+       /* Check port number from message and retrieve private data */
        if (msg->port >= serial->num_ports) {
-               dbg ("%s - Unexpected port number %d", __func__, msg->port);
+               dbg("%s - Unexpected port number %d", __func__, msg->port);
                goto exit;
        }
        port = serial->port[msg->port];
        p_priv = usb_get_serial_port_data(port);
-       
+
        /* Update handshaking pin state information */
        old_dcd_state = p_priv->dcd_state;
        p_priv->cts_state = ((msg->cts) ? 1 : 0);
@@ -704,25 +689,25 @@ static void       usa28_instat_callback(struct urb *urb)
        p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
        p_priv->ri_state = ((msg->ri) ? 1 : 0);
 
-       if (port->tty && !C_CLOCAL(port->tty)
+       if (port->port.tty && !C_CLOCAL(port->port.tty)
            && old_dcd_state != p_priv->dcd_state) {
                if (old_dcd_state)
-                       tty_hangup(port->tty);
+                       tty_hangup(port->port.tty);
                /*  else */
                /*      wake_up_interruptible(&p_priv->open_wait); */
        }
 
                /* Resubmit urb so we continue receiving */
        urb->dev = serial->dev;
-       if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err != 0)
                dbg("%s - resubmit read urb failed. (%d)", __func__, err);
-       }
 exit: ;
 }
 
 static void    usa28_glocont_callback(struct urb *urb)
 {
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 }
 
 
@@ -733,7 +718,7 @@ static void usa49_glocont_callback(struct urb *urb)
        struct keyspan_port_private *p_priv;
        int i;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        serial =  urb->context;
        for (i = 0; i < serial->num_ports; ++i) {
@@ -741,8 +726,9 @@ static void usa49_glocont_callback(struct urb *urb)
                p_priv = usb_get_serial_port_data(port);
 
                if (p_priv->resend_cont) {
-                       dbg ("%s - sending setup", __func__);
-                       keyspan_usa49_send_setup(serial, port, p_priv->resend_cont - 1);
+                       dbg("%s - sending setup", __func__);
+                       keyspan_usa49_send_setup(serial, port,
+                                               p_priv->resend_cont - 1);
                        break;
                }
        }
@@ -761,7 +747,7 @@ static void usa49_instat_callback(struct urb *urb)
        int old_dcd_state;
        int status = urb->status;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        serial =  urb->context;
 
@@ -770,7 +756,8 @@ static void usa49_instat_callback(struct urb *urb)
                return;
        }
 
-       if (urb->actual_length != sizeof(struct keyspan_usa49_portStatusMessage)) {
+       if (urb->actual_length !=
+                       sizeof(struct keyspan_usa49_portStatusMessage)) {
                dbg("%s - bad length %d", __func__, urb->actual_length);
                goto exit;
        }
@@ -778,18 +765,19 @@ static void       usa49_instat_callback(struct urb *urb)
        /*dbg(" %x %x %x %x %x %x %x %x %x %x %x", __func__,
            data[0], data[1], data[2], data[3], data[4], data[5],
            data[6], data[7], data[8], data[9], data[10]);*/
-       
-               /* Now do something useful with the data */
+
+       /* Now do something useful with the data */
        msg = (struct keyspan_usa49_portStatusMessage *)data;
 
-               /* Check port number from message and retrieve private data */  
+       /* Check port number from message and retrieve private data */
        if (msg->portNumber >= serial->num_ports) {
-               dbg ("%s - Unexpected port number %d", __func__, msg->portNumber);
+               dbg("%s - Unexpected port number %d",
+                                       __func__, msg->portNumber);
                goto exit;
        }
        port = serial->port[msg->portNumber];
        p_priv = usb_get_serial_port_data(port);
-       
+
        /* Update handshaking pin state information */
        old_dcd_state = p_priv->dcd_state;
        p_priv->cts_state = ((msg->cts) ? 1 : 0);
@@ -797,26 +785,26 @@ static void       usa49_instat_callback(struct urb *urb)
        p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
        p_priv->ri_state = ((msg->ri) ? 1 : 0);
 
-       if (port->tty && !C_CLOCAL(port->tty)
+       if (port->port.tty && !C_CLOCAL(port->port.tty)
            && old_dcd_state != p_priv->dcd_state) {
                if (old_dcd_state)
-                       tty_hangup(port->tty);
+                       tty_hangup(port->port.tty);
                /*  else */
                /*      wake_up_interruptible(&p_priv->open_wait); */
        }
 
-               /* Resubmit urb so we continue receiving */
+       /* Resubmit urb so we continue receiving */
        urb->dev = serial->dev;
 
-       if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err != 0)
                dbg("%s - resubmit read urb failed. (%d)", __func__, err);
-       }
 exit:  ;
 }
 
 static void    usa49_inack_callback(struct urb *urb)
 {
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 }
 
 static void    usa49_indat_callback(struct urb *urb)
@@ -828,7 +816,7 @@ static void usa49_indat_callback(struct urb *urb)
        unsigned char           *data = urb->transfer_buffer;
        int status = urb->status;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        endpoint = usb_pipeendpoint(urb->pipe);
 
@@ -839,14 +827,13 @@ static void       usa49_indat_callback(struct urb *urb)
        }
 
        port =  urb->context;
-       tty = port->tty;
+       tty = port->port.tty;
        if (tty && urb->actual_length) {
                /* 0x80 bit is error flag */
                if ((data[0] & 0x80) == 0) {
                        /* no error on any byte */
-                       for (i = 1; i < urb->actual_length ; ++i) {
-                               tty_insert_flip_char(tty, data[i], 0);
-                       }
+                       tty_insert_flip_string(tty, data + 1,
+                                               urb->actual_length - 1);
                } else {
                        /* some bytes had errors, every byte has status */
                        for (i = 0; i + 1 < urb->actual_length; i += 2) {
@@ -863,13 +850,15 @@ static void       usa49_indat_callback(struct urb *urb)
                }
                tty_flip_buffer_push(tty);
        }
-                               
-               /* Resubmit urb so we continue receiving */
+
+       /* Resubmit urb so we continue receiving */
        urb->dev = port->serial->dev;
-       if (port->open_count)
-               if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
-                       dbg("%s - resubmit read urb failed. (%d)", __func__, err);
-               }
+       if (port->port.count) {
+               err = usb_submit_urb(urb, GFP_ATOMIC);
+               if (err != 0)
+                       dbg("%s - resubmit read urb failed. (%d)",
+                                                       __func__, err);
+       }
 }
 
 static void usa49wg_indat_callback(struct urb *urb)
@@ -881,7 +870,7 @@ static void usa49wg_indat_callback(struct urb *urb)
        unsigned char           *data = urb->transfer_buffer;
        int status = urb->status;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        serial = urb->context;
 
@@ -899,12 +888,12 @@ static void usa49wg_indat_callback(struct urb *urb)
 
                        /* Check port number from message*/
                        if (data[i] >= serial->num_ports) {
-                               dbg ("%s - Unexpected port number %d",
+                               dbg("%s - Unexpected port number %d",
                                        __func__, data[i]);
                                return;
                        }
                        port = serial->port[data[i++]];
-                       tty = port->tty;
+                       tty = port->port.tty;
                        len = data[i++];
 
                        /* 0x80 bit is error flag */
@@ -912,7 +901,7 @@ static void usa49wg_indat_callback(struct urb *urb)
                                /* no error on any byte */
                                i++;
                                for (x = 1; x < len ; ++x)
-                                       if (port->open_count)
+                                       if (port->port.count)
                                                tty_insert_flip_char(tty,
                                                                data[i++], 0);
                                        else
@@ -930,13 +919,13 @@ static void usa49wg_indat_callback(struct urb *urb)
                                        if (stat & RXERROR_PARITY)
                                                flag |= TTY_PARITY;
                                        /* XXX should handle break (0x10) */
-                                       if (port->open_count)
+                                       if (port->port.count)
                                                tty_insert_flip_char(tty,
                                                        data[i+1], flag);
                                        i += 2;
                                }
                        }
-                       if (port->open_count)
+                       if (port->port.count)
                                tty_flip_buffer_push(tty);
                }
        }
@@ -952,7 +941,7 @@ static void usa49wg_indat_callback(struct urb *urb)
 /* not used, usa-49 doesn't have per-port control endpoints */
 static void usa49_outcont_callback(struct urb *urb)
 {
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 }
 
 static void usa90_indat_callback(struct urb *urb)
@@ -965,7 +954,7 @@ static void usa90_indat_callback(struct urb *urb)
        unsigned char           *data = urb->transfer_buffer;
        int status = urb->status;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        endpoint = usb_pipeendpoint(urb->pipe);
 
@@ -978,29 +967,26 @@ static void usa90_indat_callback(struct urb *urb)
        port =  urb->context;
        p_priv = usb_get_serial_port_data(port);
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (urb->actual_length) {
-       
                /* if current mode is DMA, looks like usa28 format
-                       otherwise looks like usa26 data format */
+                  otherwise looks like usa26 data format */
 
-               if (p_priv->baud > 57600) {
-                       for (i = 0; i < urb->actual_length ; ++i) 
-                               tty_insert_flip_char(tty, data[i], 0);
-               }
+               if (p_priv->baud > 57600)
+                       tty_insert_flip_string(tty, data, urb->actual_length);
                else {
-                       
                        /* 0x80 bit is error flag */
                        if ((data[0] & 0x80) == 0) {
-                               /* no errors on individual bytes, only possible overrun err*/
+                               /* no errors on individual bytes, only
+                                  possible overrun err*/
                                if (data[0] & RXERROR_OVERRUN)
-                                               err = TTY_OVERRUN;
-                               else err = 0;
-                               for (i = 1; i < urb->actual_length ; ++i) 
-                                       tty_insert_flip_char(tty, data[i], err);
-                       
-                       } 
-                       else {
+                                       err = TTY_OVERRUN;
+                               else
+                                       err = 0;
+                               for (i = 1; i < urb->actual_length ; ++i)
+                                       tty_insert_flip_char(tty, data[i],
+                                                                       err);
+                       }  else {
                        /* some bytes had errors, every byte has status */
                                dbg("%s - RX error!!!!", __func__);
                                for (i = 0; i + 1 < urb->actual_length; i += 2) {
@@ -1012,19 +998,22 @@ static void usa90_indat_callback(struct urb *urb)
                                        if (stat & RXERROR_PARITY)
                                                flag |= TTY_PARITY;
                                        /* XXX should handle break (0x10) */
-                                       tty_insert_flip_char(tty, data[i+1], flag);
+                                       tty_insert_flip_char(tty, data[i+1],
+                                                                       flag);
                                }
                        }
                }
                tty_flip_buffer_push(tty);
        }
-                               
+
        /* Resubmit urb so we continue receiving */
        urb->dev = port->serial->dev;
-       if (port->open_count)
-               if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
-                       dbg("%s - resubmit read urb failed. (%d)", __func__, err);
-               }
+       if (port->port.count) {
+               err = usb_submit_urb(urb, GFP_ATOMIC);
+               if (err != 0)
+                       dbg("%s - resubmit read urb failed. (%d)",
+                                                       __func__, err);
+       }
        return;
 }
 
@@ -1056,7 +1045,7 @@ static void       usa90_instat_callback(struct urb *urb)
 
        port = serial->port[0];
        p_priv = usb_get_serial_port_data(port);
-       
+
        /* Update handshaking pin state information */
        old_dcd_state = p_priv->dcd_state;
        p_priv->cts_state = ((msg->cts) ? 1 : 0);
@@ -1064,19 +1053,19 @@ static void     usa90_instat_callback(struct urb *urb)
        p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
        p_priv->ri_state = ((msg->ri) ? 1 : 0);
 
-       if (port->tty && !C_CLOCAL(port->tty)
+       if (port->port.tty && !C_CLOCAL(port->port.tty)
            && old_dcd_state != p_priv->dcd_state) {
                if (old_dcd_state)
-                       tty_hangup(port->tty);
+                       tty_hangup(port->port.tty);
                /*  else */
                /*      wake_up_interruptible(&p_priv->open_wait); */
        }
-       
+
        /* Resubmit urb so we continue receiving */
        urb->dev = serial->dev;
-       if ((err = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err != 0)
                dbg("%s - resubmit read urb failed. (%d)", __func__, err);
-       }
 exit:
        ;
 }
@@ -1090,8 +1079,9 @@ static void       usa90_outcont_callback(struct urb *urb)
        p_priv = usb_get_serial_port_data(port);
 
        if (p_priv->resend_cont) {
-               dbg ("%s - sending setup", __func__);
-               keyspan_usa90_send_setup(port->serial, port, p_priv->resend_cont - 1);
+               dbg("%s - sending setup", __func__);
+               keyspan_usa90_send_setup(port->serial, port,
+                                               p_priv->resend_cont - 1);
        }
 }
 
@@ -1107,7 +1097,7 @@ static void       usa67_instat_callback(struct urb *urb)
        int old_dcd_state;
        int status = urb->status;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        serial = urb->context;
 
@@ -1116,7 +1106,8 @@ static void       usa67_instat_callback(struct urb *urb)
                return;
        }
 
-       if (urb->actual_length != sizeof(struct keyspan_usa67_portStatusMessage)) {
+       if (urb->actual_length !=
+                       sizeof(struct keyspan_usa67_portStatusMessage)) {
                dbg("%s - bad length %d", __func__, urb->actual_length);
                return;
        }
@@ -1127,7 +1118,7 @@ static void       usa67_instat_callback(struct urb *urb)
 
        /* Check port number from message and retrieve private data */
        if (msg->port >= serial->num_ports) {
-               dbg ("%s - Unexpected port number %d", __func__, msg->port);
+               dbg("%s - Unexpected port number %d", __func__, msg->port);
                return;
        }
 
@@ -1139,10 +1130,10 @@ static void     usa67_instat_callback(struct urb *urb)
        p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
        p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
 
-       if (port->tty && !C_CLOCAL(port->tty)
+       if (port->port.tty && !C_CLOCAL(port->port.tty)
            && old_dcd_state != p_priv->dcd_state) {
                if (old_dcd_state)
-                       tty_hangup(port->tty);
+                       tty_hangup(port->port.tty);
                /*  else */
                /*      wake_up_interruptible(&p_priv->open_wait); */
        }
@@ -1161,7 +1152,7 @@ static void usa67_glocont_callback(struct urb *urb)
        struct keyspan_port_private *p_priv;
        int i;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        serial = urb->context;
        for (i = 0; i < serial->num_ports; ++i) {
@@ -1169,7 +1160,7 @@ static void usa67_glocont_callback(struct urb *urb)
                p_priv = usb_get_serial_port_data(port);
 
                if (p_priv->resend_cont) {
-                       dbg ("%s - sending setup", __func__);
+                       dbg("%s - sending setup", __func__);
                        keyspan_usa67_send_setup(serial, port,
                                                p_priv->resend_cont - 1);
                        break;
@@ -1177,8 +1168,9 @@ static void usa67_glocont_callback(struct urb *urb)
        }
 }
 
-static int keyspan_write_room (struct usb_serial_port *port)
+static int keyspan_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct keyspan_port_private     *p_priv;
        const struct keyspan_device_details     *d_details;
        int                             flip;
@@ -1191,32 +1183,30 @@ static int keyspan_write_room (struct usb_serial_port *port)
 
        /* FIXME: locking */
        if (d_details->msg_format == msg_usa90)
-               data_len = 64;
+               data_len = 64;
        else
                data_len = 63;
 
        flip = p_priv->out_flip;
 
        /* Check both endpoints to see if any are available. */
-       if ((this_urb = p_priv->out_urbs[flip]) != NULL) {
+       this_urb = p_priv->out_urbs[flip];
+       if (this_urb != NULL) {
                if (this_urb->status != -EINPROGRESS)
-                       return (data_len);
-               flip = (flip + 1) & d_details->outdat_endp_flip;        
-               if ((this_urb = p_priv->out_urbs[flip]) != NULL) 
+                       return data_len;
+               flip = (flip + 1) & d_details->outdat_endp_flip;
+               this_urb = p_priv->out_urbs[flip];
+               if (this_urb != NULL) {
                        if (this_urb->status != -EINPROGRESS)
-                               return (data_len);
+                               return data_len;
+               }
        }
        return 0;
 }
 
 
-static int keyspan_chars_in_buffer (struct usb_serial_port *port)
-{
-       return 0;
-}
-
-
-static int keyspan_open (struct usb_serial_port *port, struct file *filp)
+static int keyspan_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct keyspan_port_private     *p_priv;
        struct keyspan_serial_private   *s_priv;
@@ -1225,7 +1215,7 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
        int                             i, err;
        int                             baud_rate, device_port;
        struct urb                      *urb;
-       unsigned int                    cflag;
+       unsigned int                    cflag = 0;
 
        s_priv = usb_get_serial_data(serial);
        p_priv = usb_get_serial_port_data(port);
@@ -1247,50 +1237,53 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
 
        /* Reset low level data toggle and start reading from endpoints */
        for (i = 0; i < 2; i++) {
-               if ((urb = p_priv->in_urbs[i]) == NULL)
+               urb = p_priv->in_urbs[i];
+               if (urb == NULL)
                        continue;
                urb->dev = serial->dev;
 
-               /* make sure endpoint data toggle is synchronized with the device */
-
+               /* make sure endpoint data toggle is synchronized
+                  with the device */
                usb_clear_halt(urb->dev, urb->pipe);
-
-               if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) {
-                       dbg("%s - submit urb %d failed (%d)", __func__, i, err);
-               }
+               err = usb_submit_urb(urb, GFP_KERNEL);
+               if (err != 0)
+                       dbg("%s - submit urb %d failed (%d)",
+                                                       __func__, i, err);
        }
 
        /* Reset low level data toggle on out endpoints */
        for (i = 0; i < 2; i++) {
-               if ((urb = p_priv->out_urbs[i]) == NULL)
+               urb = p_priv->out_urbs[i];
+               if (urb == NULL)
                        continue;
                urb->dev = serial->dev;
-               /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */
+               /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+                                               usb_pipeout(urb->pipe), 0); */
        }
 
        /* get the terminal config for the setup message now so we don't
         * need to send 2 of them */
 
-       cflag = port->tty->termios->c_cflag;
        device_port = port->number - port->serial->minor;
-
-       /* Baud rate calculation takes baud rate as an integer
-          so other rates can be generated if desired. */
-       baud_rate = tty_get_baud_rate(port->tty);
-       /* If no match or invalid, leave as default */
-       if (baud_rate >= 0
-           && d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
-                               NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
-               p_priv->baud = baud_rate;
+       if (tty) {
+               cflag = tty->termios->c_cflag;
+               /* Baud rate calculation takes baud rate as an integer
+                  so other rates can be generated if desired. */
+               baud_rate = tty_get_baud_rate(tty);
+               /* If no match or invalid, leave as default */
+               if (baud_rate >= 0
+                   && d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
+                                       NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
+                       p_priv->baud = baud_rate;
+               }
        }
-
        /* set CTS/RTS handshake etc. */
        p_priv->cflag = cflag;
        p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
 
        keyspan_send_setup(port, 1);
-       //mdelay(100);
-       //keyspan_set_termios(port, NULL);
+       /* mdelay(100); */
+       /* keyspan_set_termios(port, NULL); */
 
        return 0;
 }
@@ -1301,7 +1294,8 @@ static inline void stop_urb(struct urb *urb)
                usb_kill_urb(urb);
 }
 
-static void keyspan_close(struct usb_serial_port *port, struct file *filp)
+static void keyspan_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        int                     i;
        struct usb_serial       *serial = port->serial;
@@ -1311,15 +1305,15 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp)
        dbg("%s", __func__);
        s_priv = usb_get_serial_data(serial);
        p_priv = usb_get_serial_port_data(port);
-       
+
        p_priv->rts_state = 0;
        p_priv->dtr_state = 0;
-       
+
        if (serial->dev) {
                keyspan_send_setup(port, 2);
                /* pilot-xfer seems to work best with this delay */
                mdelay(100);
-               // keyspan_set_termios(port, NULL);
+               /* keyspan_set_termios(port, NULL); */
        }
 
        /*while (p_priv->outcont_urb->status == -EINPROGRESS) {
@@ -1338,11 +1332,11 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp)
                        stop_urb(p_priv->out_urbs[i]);
                }
        }
-       port->tty = NULL;
+       port->port.tty = NULL;
 }
 
-       /* download the firmware to a pre-renumeration device */
-static int keyspan_fake_startup (struct usb_serial *serial)
+/* download the firmware to a pre-renumeration device */
+static int keyspan_fake_startup(struct usb_serial *serial)
 {
        int                             response;
        const struct ihex_binrec        *record;
@@ -1352,10 +1346,11 @@ static int keyspan_fake_startup (struct usb_serial *serial)
        dbg("Keyspan startup version %04x product %04x",
            le16_to_cpu(serial->dev->descriptor.bcdDevice),
            le16_to_cpu(serial->dev->descriptor.idProduct));
-       
-       if ((le16_to_cpu(serial->dev->descriptor.bcdDevice) & 0x8000) != 0x8000) {
+
+       if ((le16_to_cpu(serial->dev->descriptor.bcdDevice) & 0x8000)
+                                                               != 0x8000) {
                dbg("Firmware already loaded.  Quitting.");
-               return(1);
+               return 1;
        }
 
                /* Select firmware image on the basis of idProduct */
@@ -1379,11 +1374,11 @@ static int keyspan_fake_startup (struct usb_serial *serial)
        case keyspan_usa19_pre_product_id:
                fw_name = "keyspan/usa19.fw";
                break;
-                            
+
        case keyspan_usa19qi_pre_product_id:
                fw_name = "keyspan/usa19qi.fw";
                break;
-                            
+
        case keyspan_mpr_pre_product_id:
                fw_name = "keyspan/mpr.fw";
                break;
@@ -1391,15 +1386,15 @@ static int keyspan_fake_startup (struct usb_serial *serial)
        case keyspan_usa19qw_pre_product_id:
                fw_name = "keyspan/usa19qw.fw";
                break;
-                            
+
        case keyspan_usa18x_pre_product_id:
                fw_name = "keyspan/usa18x.fw";
                break;
-                            
+
        case keyspan_usa19w_pre_product_id:
                fw_name = "keyspan/usa19w.fw";
                break;
-               
+
        case keyspan_usa49w_pre_product_id:
                fw_name = "keyspan/usa49w.fw";
                break;
@@ -1431,8 +1426,7 @@ static int keyspan_fake_startup (struct usb_serial *serial)
                                             (unsigned char *)record->data,
                                             be16_to_cpu(record->len), 0xa0);
                if (response < 0) {
-                       dev_err(&serial->dev->dev, "ezusb_writememory failed for Keyspan"
-                               "firmware (%d %04X %p %d)\n",
+                       dev_err(&serial->dev->dev, "ezusb_writememory failed for Keyspan firmware (%d %04X %p %d)\n",
                                response, be32_to_cpu(record->addr),
                                record->data, be16_to_cpu(record->len));
                        break;
@@ -1445,7 +1439,7 @@ static int keyspan_fake_startup (struct usb_serial *serial)
        response = ezusb_set_reset(serial, 0);
 
        /* we don't want this device to have a driver assigned to it. */
-       return (1);
+       return 1;
 }
 
 /* Helper functions used by keyspan_setup_urbs */
@@ -1467,7 +1461,7 @@ static struct usb_endpoint_descriptor const *find_ep(struct usb_serial const *se
        return NULL;
 }
 
-static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint,
+static struct urb *keyspan_setup_urb(struct usb_serial *serial, int endpoint,
                                      int dir, void *ctx, char *buf, int len,
                                      void (*callback)(struct urb *))
 {
@@ -1478,10 +1472,10 @@ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint,
        if (endpoint == -1)
                return NULL;            /* endpoint not needed */
 
-       dbg ("%s - alloc for endpoint %d.", __func__, endpoint);
+       dbg("%s - alloc for endpoint %d.", __func__, endpoint);
        urb = usb_alloc_urb(0, GFP_KERNEL);             /* No ISO */
        if (urb == NULL) {
-               dbg ("%s - alloc for endpoint %d failed.", __func__, endpoint);
+               dbg("%s - alloc for endpoint %d failed.", __func__, endpoint);
                return NULL;
        }
 
@@ -1554,7 +1548,7 @@ static struct callbacks {
        }, {
                /* msg_usa90 callbacks */
                .instat_callback =      usa90_instat_callback,
-               .glocont_callback =     usa28_glocont_callback,         
+               .glocont_callback =     usa28_glocont_callback,
                .indat_callback =       usa90_indat_callback,
                .outdat_callback =      usa2x_outdat_callback,
                .inack_callback =       usa28_inack_callback,
@@ -1582,16 +1576,16 @@ static void keyspan_setup_urbs(struct usb_serial *serial)
        struct callbacks                *cback;
        int                             endp;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        s_priv = usb_get_serial_data(serial);
        d_details = s_priv->device_details;
 
-               /* Setup values for the various callback routines */
+       /* Setup values for the various callback routines */
        cback = &keyspan_callbacks[d_details->msg_format];
 
-               /* Allocate and set up urbs for each one that is in use, 
-                  starting with instat endpoints */
+       /* Allocate and set up urbs for each one that is in use,
+          starting with instat endpoints */
        s_priv->instat_urb = keyspan_setup_urb
                (serial, d_details->instat_endpoint, USB_DIR_IN,
                 serial, s_priv->instat_buf, INSTAT_BUFLEN,
@@ -1607,8 +1601,8 @@ static void keyspan_setup_urbs(struct usb_serial *serial)
                 serial, s_priv->glocont_buf, GLOCONT_BUFLEN,
                 cback->glocont_callback);
 
-               /* Setup endpoints for each port specific thing */
-       for (i = 0; i < d_details->num_ports; i ++) {
+       /* Setup endpoints for each port specific thing */
+       for (i = 0; i < d_details->num_ports; i++) {
                port = serial->port[i];
                p_priv = usb_get_serial_port_data(port);
 
@@ -1644,8 +1638,7 @@ static void keyspan_setup_urbs(struct usb_serial *serial)
                        (serial, d_details->outcont_endpoints[i], USB_DIR_OUT,
                         port, p_priv->outcont_buffer, 64,
                         cback->outcont_callback);
-       }       
-
+       }
 }
 
 /* usa19 function doesn't require prescaler */
@@ -1653,46 +1646,39 @@ static int keyspan_usa19_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi,
                                   u8 *rate_low, u8 *prescaler, int portnum)
 {
        u32     b16,    /* baud rate times 16 (actual rate used internally) */
-               div,    /* divisor */   
+               div,    /* divisor */
                cnt;    /* inverse of divisor (programmed into 8051) */
-               
-       dbg ("%s - %d.", __func__, baud_rate);
-
-               /* prevent divide by zero...  */
-       if( (b16 = (baud_rate * 16L)) == 0) {
-               return (KEYSPAN_INVALID_BAUD_RATE);
-       }
 
-               /* Any "standard" rate over 57k6 is marginal on the USA-19
-                  as we run out of divisor resolution. */
-       if (baud_rate > 57600) {
-               return (KEYSPAN_INVALID_BAUD_RATE);
-       }
-
-               /* calculate the divisor and the counter (its inverse) */
-       if( (div = (baudclk / b16)) == 0) {
-               return (KEYSPAN_INVALID_BAUD_RATE);
-       }
-       else {
+       dbg("%s - %d.", __func__, baud_rate);
+
+       /* prevent divide by zero...  */
+       b16 = baud_rate * 16L;
+       if (b16 == 0)
+               return KEYSPAN_INVALID_BAUD_RATE;
+       /* Any "standard" rate over 57k6 is marginal on the USA-19
+          as we run out of divisor resolution. */
+       if (baud_rate > 57600)
+               return KEYSPAN_INVALID_BAUD_RATE;
+
+       /* calculate the divisor and the counter (its inverse) */
+       div = baudclk / b16;
+       if (div == 0)
+               return KEYSPAN_INVALID_BAUD_RATE;
+       else
                cnt = 0 - div;
-       }
 
-       if(div > 0xffff) {
-               return (KEYSPAN_INVALID_BAUD_RATE);
-       }
+       if (div > 0xffff)
+               return KEYSPAN_INVALID_BAUD_RATE;
 
-               /* return the counter values if non-null */
-       if (rate_low) {
+       /* return the counter values if non-null */
+       if (rate_low)
                *rate_low = (u8) (cnt & 0xff);
-       }
-       if (rate_hi) {
+       if (rate_hi)
                *rate_hi = (u8) ((cnt >> 8) & 0xff);
-       }
-       if (rate_low && rate_hi) {
-               dbg ("%s - %d %02x %02x.", __func__, baud_rate, *rate_hi, *rate_low);
-       }
-       
-       return (KEYSPAN_BAUD_RATE_OK);
+       if (rate_low && rate_hi)
+               dbg("%s - %d %02x %02x.",
+                               __func__, baud_rate, *rate_hi, *rate_low);
+       return KEYSPAN_BAUD_RATE_OK;
 }
 
 /* usa19hs function doesn't require prescaler */
@@ -1700,34 +1686,35 @@ static int keyspan_usa19hs_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi,
                                   u8 *rate_low, u8 *prescaler, int portnum)
 {
        u32     b16,    /* baud rate times 16 (actual rate used internally) */
-                       div;    /* divisor */   
-               
-       dbg ("%s - %d.", __func__, baud_rate);
+                       div;    /* divisor */
 
-               /* prevent divide by zero...  */
-       if( (b16 = (baud_rate * 16L)) == 0) 
-               return (KEYSPAN_INVALID_BAUD_RATE);
-       
+       dbg("%s - %d.", __func__, baud_rate);
 
+       /* prevent divide by zero...  */
+       b16 = baud_rate * 16L;
+       if (b16 == 0)
+               return KEYSPAN_INVALID_BAUD_RATE;
 
-               /* calculate the divisor */
-       if( (div = (baudclk / b16)) == 0) 
-               return (KEYSPAN_INVALID_BAUD_RATE);
+       /* calculate the divisor */
+       div = baudclk / b16;
+       if (div == 0)
+               return KEYSPAN_INVALID_BAUD_RATE;
 
-       if(div > 0xffff) 
-               return (KEYSPAN_INVALID_BAUD_RATE);
+       if (div > 0xffff)
+               return KEYSPAN_INVALID_BAUD_RATE;
 
-               /* return the counter values if non-null */
-       if (rate_low) 
+       /* return the counter values if non-null */
+       if (rate_low)
                *rate_low = (u8) (div & 0xff);
-       
-       if (rate_hi) 
+
+       if (rate_hi)
                *rate_hi = (u8) ((div >> 8) & 0xff);
-       
-       if (rate_low && rate_hi) 
-               dbg ("%s - %d %02x %02x.", __func__, baud_rate, *rate_hi, *rate_low);
-       
-       return (KEYSPAN_BAUD_RATE_OK);
+
+       if (rate_low && rate_hi)
+               dbg("%s - %d %02x %02x.",
+                       __func__, baud_rate, *rate_hi, *rate_low);
+
+       return KEYSPAN_BAUD_RATE_OK;
 }
 
 static int keyspan_usa19w_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi,
@@ -1735,64 +1722,61 @@ static int keyspan_usa19w_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi,
 {
        u32     b16,    /* baud rate times 16 (actual rate used internally) */
                clk,    /* clock with 13/8 prescaler */
-               div,    /* divisor using 13/8 prescaler */      
+               div,    /* divisor using 13/8 prescaler */
                res,    /* resulting baud rate using 13/8 prescaler */
                diff,   /* error using 13/8 prescaler */
                smallest_diff;
        u8      best_prescaler;
        int     i;
 
-       dbg ("%s - %d.", __func__, baud_rate);
+       dbg("%s - %d.", __func__, baud_rate);
 
-               /* prevent divide by zero */
-       if( (b16 = baud_rate * 16L) == 0) {
-               return (KEYSPAN_INVALID_BAUD_RATE);
-       }
+       /* prevent divide by zero */
+       b16 = baud_rate * 16L;
+       if (b16 == 0)
+               return KEYSPAN_INVALID_BAUD_RATE;
 
-               /* Calculate prescaler by trying them all and looking
-                  for best fit */
-               
-               /* start with largest possible difference */
+       /* Calculate prescaler by trying them all and looking
+          for best fit */
+
+       /* start with largest possible difference */
        smallest_diff = 0xffffffff;
 
                /* 0 is an invalid prescaler, used as a flag */
        best_prescaler = 0;
 
-       for(i = 8; i <= 0xff; ++i) {
+       for (i = 8; i <= 0xff; ++i) {
                clk = (baudclk * 8) / (u32) i;
-               
-               if( (div = clk / b16) == 0) {
+
+               div = clk / b16;
+               if (div == 0)
                        continue;
-               }
 
                res = clk / div;
-               diff= (res > b16) ? (res-b16) : (b16-res);
+               diff = (res > b16) ? (res-b16) : (b16-res);
 
-               if(diff < smallest_diff) {
+               if (diff < smallest_diff) {
                        best_prescaler = i;
                        smallest_diff = diff;
                }
        }
 
-       if(best_prescaler == 0) {
-               return (KEYSPAN_INVALID_BAUD_RATE);
-       }
+       if (best_prescaler == 0)
+               return KEYSPAN_INVALID_BAUD_RATE;
 
        clk = (baudclk * 8) / (u32) best_prescaler;
        div = clk / b16;
 
-               /* return the divisor and prescaler if non-null */
-       if (rate_low) {
+       /* return the divisor and prescaler if non-null */
+       if (rate_low)
                *rate_low = (u8) (div & 0xff);
-       }
-       if (rate_hi) {
+       if (rate_hi)
                *rate_hi = (u8) ((div >> 8) & 0xff);
-       }
        if (prescaler) {
                *prescaler = best_prescaler;
                /*  dbg("%s - %d %d", __func__, *prescaler, div); */
        }
-       return (KEYSPAN_BAUD_RATE_OK);
+       return KEYSPAN_BAUD_RATE_OK;
 }
 
        /* USA-28 supports different maximum baud rates on each port */
@@ -1800,57 +1784,51 @@ static int keyspan_usa28_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi,
                                    u8 *rate_low, u8 *prescaler, int portnum)
 {
        u32     b16,    /* baud rate times 16 (actual rate used internally) */
-               div,    /* divisor */   
+               div,    /* divisor */
                cnt;    /* inverse of divisor (programmed into 8051) */
 
-       dbg ("%s - %d.", __func__, baud_rate);
+       dbg("%s - %d.", __func__, baud_rate);
 
                /* prevent divide by zero */
-       if ((b16 = baud_rate * 16L) == 0)
-               return (KEYSPAN_INVALID_BAUD_RATE);
-
-               /* calculate the divisor and the counter (its inverse) */
-       if ((div = (KEYSPAN_USA28_BAUDCLK / b16)) == 0) {
-               return (KEYSPAN_INVALID_BAUD_RATE);
-       }
-       else {
+       b16 = baud_rate * 16L;
+       if (b16 == 0)
+               return KEYSPAN_INVALID_BAUD_RATE;
+
+       /* calculate the divisor and the counter (its inverse) */
+       div = KEYSPAN_USA28_BAUDCLK / b16;
+       if (div == 0)
+               return KEYSPAN_INVALID_BAUD_RATE;
+       else
                cnt = 0 - div;
-       }
 
-               /* check for out of range, based on portnum, 
-                  and return result */
-       if(portnum == 0) {
-               if(div > 0xffff)
-                       return (KEYSPAN_INVALID_BAUD_RATE);
-       }
-       else {
-               if(portnum == 1) {
-                       if(div > 0xff) {
-                               return (KEYSPAN_INVALID_BAUD_RATE);
-                       }
-               }
-               else {
-                       return (KEYSPAN_INVALID_BAUD_RATE);
-               }
+       /* check for out of range, based on portnum,
+          and return result */
+       if (portnum == 0) {
+               if (div > 0xffff)
+                       return KEYSPAN_INVALID_BAUD_RATE;
+       } else {
+               if (portnum == 1) {
+                       if (div > 0xff)
+                               return KEYSPAN_INVALID_BAUD_RATE;
+               } else
+                       return KEYSPAN_INVALID_BAUD_RATE;
        }
 
                /* return the counter values if not NULL
                   (port 1 will ignore retHi) */
-       if (rate_low) {
+       if (rate_low)
                *rate_low = (u8) (cnt & 0xff);
-       }
-       if (rate_hi) {
+       if (rate_hi)
                *rate_hi = (u8) ((cnt >> 8) & 0xff);
-       }
-       dbg ("%s - %d OK.", __func__, baud_rate);
-       return (KEYSPAN_BAUD_RATE_OK);
+       dbg("%s - %d OK.", __func__, baud_rate);
+       return KEYSPAN_BAUD_RATE_OK;
 }
 
 static int keyspan_usa26_send_setup(struct usb_serial *serial,
                                    struct usb_serial_port *port,
                                    int reset_port)
 {
-       struct keyspan_usa26_portControlMessage msg;            
+       struct keyspan_usa26_portControlMessage msg;
        struct keyspan_serial_private           *s_priv;
        struct keyspan_port_private             *p_priv;
        const struct keyspan_device_details     *d_details;
@@ -1858,7 +1836,7 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
        struct urb                              *this_urb;
        int                                     device_port, err;
 
-       dbg ("%s reset=%d", __func__, reset_port);
+       dbg("%s reset=%d", __func__, reset_port);
 
        s_priv = usb_get_serial_data(serial);
        p_priv = usb_get_serial_port_data(port);
@@ -1881,22 +1859,22 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
        if ((reset_port + 1) > p_priv->resend_cont)
                p_priv->resend_cont = reset_port + 1;
        if (this_urb->status == -EINPROGRESS) {
-               /*  dbg ("%s - already writing", __func__); */
+               /*  dbg("%s - already writing", __func__); */
                mdelay(5);
-               return(-1);
+               return -1;
        }
 
-       memset(&msg, 0, sizeof (struct keyspan_usa26_portControlMessage));
-       
-               /* Only set baud rate if it's changed */        
+       memset(&msg, 0, sizeof(struct keyspan_usa26_portControlMessage));
+
+       /* Only set baud rate if it's changed */
        if (p_priv->old_baud != p_priv->baud) {
                p_priv->old_baud = p_priv->baud;
                msg.setClocking = 0xff;
                if (d_details->calculate_baud_rate
                    (p_priv->baud, d_details->baudclk, &msg.baudHi,
-                    &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE ) {
-                       dbg("%s - Invalid baud rate %d requested, using 9600.", __func__,
-                           p_priv->baud);
+                    &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE) {
+                       dbg("%s - Invalid baud rate %d requested, using 9600.",
+                                               __func__, p_priv->baud);
                        msg.baudLo = 0;
                        msg.baudHi = 125;       /* Values for 9600 baud */
                        msg.prescaler = 10;
@@ -1922,7 +1900,7 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
        if (p_priv->cflag & PARENB) {
                /* note USA_PARITY_NONE == 0 */
                msg.lcr |= (p_priv->cflag & PARODD)?
-                       USA_PARITY_ODD: USA_PARITY_EVEN;
+                       USA_PARITY_ODD : USA_PARITY_EVEN;
        }
        msg.setLcr = 0xff;
 
@@ -1963,7 +1941,7 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
 
        /* Sending intermediate configs */
        else {
-               msg._txOn = (! p_priv->break_on);
+               msg._txOn = (!p_priv->break_on);
                msg._txOff = 0;
                msg.txFlush = 0;
                msg.txBreak = (p_priv->break_on);
@@ -1975,23 +1953,23 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,
                msg.resetDataToggle = 0x0;
        }
 
-               /* Do handshaking outputs */    
+       /* Do handshaking outputs */
        msg.setTxTriState_setRts = 0xff;
        msg.txTriState_rts = p_priv->rts_state;
 
        msg.setHskoa_setDtr = 0xff;
        msg.hskoa_dtr = p_priv->dtr_state;
-               
+
        p_priv->resend_cont = 0;
-       memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));
-       
+       memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
+
        /* send the data out the device on control endpoint */
        this_urb->transfer_buffer_length = sizeof(msg);
 
        this_urb->dev = serial->dev;
-       if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
+       err = usb_submit_urb(this_urb, GFP_ATOMIC);
+       if (err != 0)
                dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err);
-       }
 #if 0
        else {
                dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __func__
@@ -2007,14 +1985,14 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
                                    struct usb_serial_port *port,
                                    int reset_port)
 {
-       struct keyspan_usa28_portControlMessage msg;            
+       struct keyspan_usa28_portControlMessage msg;
        struct keyspan_serial_private           *s_priv;
        struct keyspan_port_private             *p_priv;
        const struct keyspan_device_details     *d_details;
        struct urb                              *this_urb;
        int                                     device_port, err;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        s_priv = usb_get_serial_data(serial);
        p_priv = usb_get_serial_port_data(port);
@@ -2022,7 +2000,8 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
        device_port = port->number - port->serial->minor;
 
        /* only do something if we have a bulk out endpoint */
-       if ((this_urb = p_priv->outcont_urb) == NULL) {
+       this_urb = p_priv->outcont_urb;
+       if (this_urb == NULL) {
                dbg("%s - oops no urb.", __func__);
                return -1;
        }
@@ -2032,17 +2011,18 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
        if ((reset_port + 1) > p_priv->resend_cont)
                p_priv->resend_cont = reset_port + 1;
        if (this_urb->status == -EINPROGRESS) {
-               dbg ("%s already writing", __func__);
+               dbg("%s already writing", __func__);
                mdelay(5);
-               return(-1);
+               return -1;
        }
 
-       memset(&msg, 0, sizeof (struct keyspan_usa28_portControlMessage));
+       memset(&msg, 0, sizeof(struct keyspan_usa28_portControlMessage));
 
        msg.setBaudRate = 1;
        if (d_details->calculate_baud_rate(p_priv->baud, d_details->baudclk,
-               &msg.baudHi, &msg.baudLo, NULL, device_port) == KEYSPAN_INVALID_BAUD_RATE ) {
-               dbg("%s - Invalid baud rate requested %d.", __func__, p_priv->baud);
+               &msg.baudHi, &msg.baudLo, NULL, device_port) == KEYSPAN_INVALID_BAUD_RATE) {
+               dbg("%s - Invalid baud rate requested %d.",
+                                               __func__, p_priv->baud);
                msg.baudLo = 0xff;
                msg.baudHi = 0xb2;      /* Values for 9600 baud */
        }
@@ -2053,7 +2033,7 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
        msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
        msg.xonFlowControl = 0;
 
-       /* Do handshaking outputs, DTR is inverted relative to RTS */   
+       /* Do handshaking outputs, DTR is inverted relative to RTS */
        msg.rts = p_priv->rts_state;
        msg.dtr = p_priv->dtr_state;
 
@@ -2095,7 +2075,7 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
        }
        /* Sending intermediate configs */
        else {
-               msg._txOn = (! p_priv->break_on);
+               msg._txOn = (!p_priv->break_on);
                msg._txOff = 0;
                msg.txFlush = 0;
                msg.txForceXoff = 0;
@@ -2109,15 +2089,15 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,
        }
 
        p_priv->resend_cont = 0;
-       memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));
+       memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
 
        /* send the data out the device on control endpoint */
        this_urb->transfer_buffer_length = sizeof(msg);
 
        this_urb->dev = serial->dev;
-       if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
+       err = usb_submit_urb(this_urb, GFP_ATOMIC);
+       if (err != 0)
                dbg("%s - usb_submit_urb(setup) failed", __func__);
-       }
 #if 0
        else {
                dbg("%s - usb_submit_urb(setup) OK %d bytes", __func__,
@@ -2140,7 +2120,7 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
        struct urb                              *this_urb;
        int                                     err, device_port;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        s_priv = usb_get_serial_data(serial);
        p_priv = usb_get_serial_port_data(port);
@@ -2151,7 +2131,9 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
        /* Work out which port within the device is being setup */
        device_port = port->number - port->serial->minor;
 
-       dbg("%s - endpoint %d port %d (%d)",__func__, usb_pipeendpoint(this_urb->pipe), port->number, device_port);
+       dbg("%s - endpoint %d port %d (%d)",
+                       __func__, usb_pipeendpoint(this_urb->pipe),
+                       port->number, device_port);
 
                /* Make sure we have an urb then send the message */
        if (this_urb == NULL) {
@@ -2165,30 +2147,30 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
                p_priv->resend_cont = reset_port + 1;
 
        if (this_urb->status == -EINPROGRESS) {
-               /*  dbg ("%s - already writing", __func__); */
+               /*  dbg("%s - already writing", __func__); */
                mdelay(5);
-               return(-1);
+               return -1;
        }
 
-       memset(&msg, 0, sizeof (struct keyspan_usa49_portControlMessage));
+       memset(&msg, 0, sizeof(struct keyspan_usa49_portControlMessage));
 
        /*msg.portNumber = port->number;*/
        msg.portNumber = device_port;
-       
-               /* Only set baud rate if it's changed */        
+
+       /* Only set baud rate if it's changed */
        if (p_priv->old_baud != p_priv->baud) {
                p_priv->old_baud = p_priv->baud;
                msg.setClocking = 0xff;
                if (d_details->calculate_baud_rate
                    (p_priv->baud, d_details->baudclk, &msg.baudHi,
-                    &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE ) {
-                       dbg("%s - Invalid baud rate %d requested, using 9600.", __func__,
-                           p_priv->baud);
+                    &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE) {
+                       dbg("%s - Invalid baud rate %d requested, using 9600.",
+                                               __func__, p_priv->baud);
                        msg.baudLo = 0;
                        msg.baudHi = 125;       /* Values for 9600 baud */
                        msg.prescaler = 10;
                }
-               //msg.setPrescaler = 0xff;
+               /* msg.setPrescaler = 0xff; */
        }
 
        msg.lcr = (p_priv->cflag & CSTOPB)? STOPBITS_678_2: STOPBITS_5678_1;
@@ -2209,19 +2191,19 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
        if (p_priv->cflag & PARENB) {
                /* note USA_PARITY_NONE == 0 */
                msg.lcr |= (p_priv->cflag & PARODD)?
-                       USA_PARITY_ODD: USA_PARITY_EVEN;
+                       USA_PARITY_ODD : USA_PARITY_EVEN;
        }
        msg.setLcr = 0xff;
 
        msg.ctsFlowControl = (p_priv->flow_control == flow_cts);
        msg.xonFlowControl = 0;
        msg.setFlowControl = 0xff;
-       
+
        msg.forwardingLength = 16;
        msg.xonChar = 17;
        msg.xoffChar = 19;
 
-       /* Opening port */ 
+       /* Opening port */
        if (reset_port == 1) {
                msg._txOn = 1;
                msg._txOff = 0;
@@ -2253,7 +2235,7 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
        }
        /* Sending intermediate configs */
        else {
-               msg._txOn = (! p_priv->break_on);
+               msg._txOn = (!p_priv->break_on);
                msg._txOff = 0;
                msg.txFlush = 0;
                msg.txBreak = (p_priv->break_on);
@@ -2267,16 +2249,17 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
                msg.disablePort = 0;
        }
 
-               /* Do handshaking outputs */    
+       /* Do handshaking outputs */
        msg.setRts = 0xff;
        msg.rts = p_priv->rts_state;
 
        msg.setDtr = 0xff;
        msg.dtr = p_priv->dtr_state;
-               
+
        p_priv->resend_cont = 0;
 
-       /* if the device is a 49wg, we send control message on usb control EP 0 */
+       /* if the device is a 49wg, we send control message on usb
+          control EP 0 */
 
        if (d_details->product_id == keyspan_usa49wg_product_id) {
                dr = (void *)(s_priv->ctrl_buf);
@@ -2286,23 +2269,24 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,
                dr->wIndex = 0;
                dr->wLength = cpu_to_le16(sizeof(msg));
 
-               memcpy (s_priv->glocont_buf, &msg, sizeof(msg));
+               memcpy(s_priv->glocont_buf, &msg, sizeof(msg));
 
-               usb_fill_control_urb(this_urb, serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                            (unsigned char *)dr, s_priv->glocont_buf, sizeof(msg),
-                            usa49_glocont_callback, serial);
+               usb_fill_control_urb(this_urb, serial->dev,
+                               usb_sndctrlpipe(serial->dev, 0),
+                               (unsigned char *)dr, s_priv->glocont_buf,
+                               sizeof(msg), usa49_glocont_callback, serial);
 
        } else {
                memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
-       
+
                /* send the data out the device on control endpoint */
                this_urb->transfer_buffer_length = sizeof(msg);
 
                this_urb->dev = serial->dev;
        }
-       if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
+       err = usb_submit_urb(this_urb, GFP_ATOMIC);
+       if (err != 0)
                dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err);
-       }
 #if 0
        else {
                dbg("%s - usb_submit_urb(%d) OK %d bytes (end %d)", __func__,
@@ -2318,7 +2302,7 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial,
                                    struct usb_serial_port *port,
                                    int reset_port)
 {
-       struct keyspan_usa90_portControlMessage msg;            
+       struct keyspan_usa90_portControlMessage msg;
        struct keyspan_serial_private           *s_priv;
        struct keyspan_port_private             *p_priv;
        const struct keyspan_device_details     *d_details;
@@ -2326,14 +2310,15 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial,
        int                                     err;
        u8                                              prescaler;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        s_priv = usb_get_serial_data(serial);
        p_priv = usb_get_serial_port_data(port);
        d_details = s_priv->device_details;
 
        /* only do something if we have a bulk out endpoint */
-       if ((this_urb = p_priv->outcont_urb) == NULL) {
+       this_urb = p_priv->outcont_urb;
+       if (this_urb == NULL) {
                dbg("%s - oops no urb.", __func__);
                return -1;
        }
@@ -2343,24 +2328,24 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial,
        if ((reset_port + 1) > p_priv->resend_cont)
                p_priv->resend_cont = reset_port + 1;
        if (this_urb->status == -EINPROGRESS) {
-               dbg ("%s already writing", __func__);
+               dbg("%s already writing", __func__);
                mdelay(5);
-               return(-1);
+               return -1;
        }
 
-       memset(&msg, 0, sizeof (struct keyspan_usa90_portControlMessage));
+       memset(&msg, 0, sizeof(struct keyspan_usa90_portControlMessage));
 
-       /* Only set baud rate if it's changed */        
+       /* Only set baud rate if it's changed */
        if (p_priv->old_baud != p_priv->baud) {
                p_priv->old_baud = p_priv->baud;
                msg.setClocking = 0x01;
                if (d_details->calculate_baud_rate
                    (p_priv->baud, d_details->baudclk, &msg.baudHi,
-                    &msg.baudLo, &prescaler, 0) == KEYSPAN_INVALID_BAUD_RATE ) {
-                       dbg("%s - Invalid baud rate %d requested, using 9600.", __func__,
-                           p_priv->baud);
+                    &msg.baudLo, &prescaler, 0) == KEYSPAN_INVALID_BAUD_RATE) {
+                       dbg("%s - Invalid baud rate %d requested, using 9600.",
+                                               __func__, p_priv->baud);
                        p_priv->baud = 9600;
-                       d_details->calculate_baud_rate (p_priv->baud, d_details->baudclk, 
+                       d_details->calculate_baud_rate(p_priv->baud, d_details->baudclk,
                                &msg.baudHi, &msg.baudLo, &prescaler, 0);
                }
                msg.setRxMode = 1;
@@ -2368,13 +2353,10 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial,
        }
 
        /* modes must always be correctly specified */
-       if (p_priv->baud > 57600)
-       {
+       if (p_priv->baud > 57600) {
                msg.rxMode = RXMODE_DMA;
                msg.txMode = TXMODE_DMA;
-       }
-       else
-       {
+       } else {
                msg.rxMode = RXMODE_BYHAND;
                msg.txMode = TXMODE_BYHAND;
        }
@@ -2397,7 +2379,7 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial,
        if (p_priv->cflag & PARENB) {
                /* note USA_PARITY_NONE == 0 */
                msg.lcr |= (p_priv->cflag & PARODD)?
-                       USA_PARITY_ODD: USA_PARITY_EVEN;
+                       USA_PARITY_ODD : USA_PARITY_EVEN;
        }
        if (p_priv->old_cflag != p_priv->cflag) {
                p_priv->old_cflag = p_priv->cflag;
@@ -2408,47 +2390,46 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial,
                msg.txFlowControl = TXFLOW_CTS;
        msg.setTxFlowControl = 0x01;
        msg.setRxFlowControl = 0x01;
-       
+
        msg.rxForwardingLength = 16;
-       msg.rxForwardingTimeout = 16;   
+       msg.rxForwardingTimeout = 16;
        msg.txAckSetting = 0;
        msg.xonChar = 17;
        msg.xoffChar = 19;
 
-       /* Opening port */ 
+       /* Opening port */
        if (reset_port == 1) {
                msg.portEnabled = 1;
                msg.rxFlush = 1;
                msg.txBreak = (p_priv->break_on);
        }
        /* Closing port */
-       else if (reset_port == 2) {
+       else if (reset_port == 2)
                msg.portEnabled = 0;
-       }
        /* Sending intermediate configs */
        else {
-               if (port->open_count)
+               if (port->port.count)
                        msg.portEnabled = 1;
                msg.txBreak = (p_priv->break_on);
        }
 
-       /* Do handshaking outputs */    
+       /* Do handshaking outputs */
        msg.setRts = 0x01;
        msg.rts = p_priv->rts_state;
 
        msg.setDtr = 0x01;
        msg.dtr = p_priv->dtr_state;
-               
+
        p_priv->resend_cont = 0;
-       memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));
-       
+       memcpy(this_urb->transfer_buffer, &msg, sizeof(msg));
+
        /* send the data out the device on control endpoint */
        this_urb->transfer_buffer_length = sizeof(msg);
 
        this_urb->dev = serial->dev;
-       if ((err = usb_submit_urb(this_urb, GFP_ATOMIC)) != 0) {
+       err = usb_submit_urb(this_urb, GFP_ATOMIC);
+       if (err != 0)
                dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err);
-       }
        return 0;
 }
 
@@ -2463,7 +2444,7 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial,
        struct urb                              *this_urb;
        int                                     err, device_port;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        s_priv = usb_get_serial_data(serial);
        p_priv = usb_get_serial_port_data(port);
@@ -2486,9 +2467,9 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial,
        if ((reset_port + 1) > p_priv->resend_cont)
                p_priv->resend_cont = reset_port + 1;
        if (this_urb->status == -EINPROGRESS) {
-               /*  dbg ("%s - already writing", __func__); */
+               /*  dbg("%s - already writing", __func__); */
                mdelay(5);
-               return(-1);
+               return -1;
        }
 
        memset(&msg, 0, sizeof(struct keyspan_usa67_portControlMessage));
@@ -2501,9 +2482,9 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial,
                msg.setClocking = 0xff;
                if (d_details->calculate_baud_rate
                    (p_priv->baud, d_details->baudclk, &msg.baudHi,
-                    &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE ) {
-                       dbg("%s - Invalid baud rate %d requested, using 9600.", __func__,
-                           p_priv->baud);
+                    &msg.baudLo, &msg.prescaler, device_port) == KEYSPAN_INVALID_BAUD_RATE) {
+                       dbg("%s - Invalid baud rate %d requested, using 9600.",
+                                               __func__, p_priv->baud);
                        msg.baudLo = 0;
                        msg.baudHi = 125;       /* Values for 9600 baud */
                        msg.prescaler = 10;
@@ -2529,7 +2510,7 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial,
        if (p_priv->cflag & PARENB) {
                /* note USA_PARITY_NONE == 0 */
                msg.lcr |= (p_priv->cflag & PARODD)?
-                       USA_PARITY_ODD: USA_PARITY_EVEN;
+                                       USA_PARITY_ODD : USA_PARITY_EVEN;
        }
        msg.setLcr = 0xff;
 
@@ -2566,7 +2547,7 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial,
                msg.resetDataToggle = 0;
        } else {
                /* Sending intermediate configs */
-               msg._txOn = (! p_priv->break_on);
+               msg._txOn = (!p_priv->break_on);
                msg._txOff = 0;
                msg.txFlush = 0;
                msg.txBreak = (p_priv->break_on);
@@ -2606,7 +2587,7 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
        struct keyspan_serial_private *s_priv;
        const struct keyspan_device_details *d_details;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        s_priv = usb_get_serial_data(serial);
        d_details = s_priv->device_details;
@@ -2633,7 +2614,7 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
 
 /* Gets called by the "real" driver (ie once firmware is loaded
    and renumeration has taken place. */
-static int keyspan_startup (struct usb_serial *serial)
+static int keyspan_startup(struct usb_serial *serial)
 {
        int                             i, err;
        struct usb_serial_port          *port;
@@ -2644,17 +2625,20 @@ static int keyspan_startup (struct usb_serial *serial)
        dbg("%s", __func__);
 
        for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)
-               if (d_details->product_id == le16_to_cpu(serial->dev->descriptor.idProduct))
+               if (d_details->product_id ==
+                               le16_to_cpu(serial->dev->descriptor.idProduct))
                        break;
        if (d_details == NULL) {
-               dev_err(&serial->dev->dev, "%s - unknown product id %x\n", __func__, le16_to_cpu(serial->dev->descriptor.idProduct));
+               dev_err(&serial->dev->dev, "%s - unknown product id %x\n",
+                   __func__, le16_to_cpu(serial->dev->descriptor.idProduct));
                return 1;
        }
 
        /* Setup private data for serial driver */
        s_priv = kzalloc(sizeof(struct keyspan_serial_private), GFP_KERNEL);
        if (!s_priv) {
-               dbg("%s - kmalloc for keyspan_serial_private failed.", __func__);
+               dbg("%s - kmalloc for keyspan_serial_private failed.",
+                                                               __func__);
                return -ENOMEM;
        }
 
@@ -2664,10 +2648,11 @@ static int keyspan_startup (struct usb_serial *serial)
        /* Now setup per port private data */
        for (i = 0; i < serial->num_ports; i++) {
                port = serial->port[i];
-               p_priv = kzalloc(sizeof(struct keyspan_port_private), GFP_KERNEL);
+               p_priv = kzalloc(sizeof(struct keyspan_port_private),
+                                                               GFP_KERNEL);
                if (!p_priv) {
                        dbg("%s - kmalloc for keyspan_port_private (%d) failed!.", __func__, i);
-                       return (1);
+                       return 1;
                }
                p_priv->device_details = d_details;
                usb_set_serial_port_data(port, p_priv);
@@ -2689,11 +2674,11 @@ static int keyspan_startup (struct usb_serial *serial)
                        dbg("%s - submit indat urb failed %d", __func__,
                                err);
        }
-                       
+
        return 0;
 }
 
-static void keyspan_shutdown (struct usb_serial *serial)
+static void keyspan_shutdown(struct usb_serial *serial)
 {
        int                             i, j;
        struct usb_serial_port          *port;
@@ -2745,8 +2730,8 @@ static void keyspan_shutdown (struct usb_serial *serial)
        }
 }
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 MODULE_FIRMWARE("keyspan/usa28.fw");
index b52fb657a24410887e7925c874c36b48c3c3c771..38b4582e073446ad6513b7ed11145ccc6a26e61c 100644 (file)
 
 
 /* Function prototypes for Keyspan serial converter */
-static int  keyspan_open               (struct usb_serial_port *port,
+static int  keyspan_open               (struct tty_struct *tty,
+                                        struct usb_serial_port *port,
                                         struct file *filp);
-static void keyspan_close              (struct usb_serial_port *port,
+static void keyspan_close              (struct tty_struct *tty,
+                                        struct usb_serial_port *port,
                                         struct file *filp);
 static int  keyspan_startup            (struct usb_serial *serial);
 static void keyspan_shutdown           (struct usb_serial *serial);
-static void keyspan_rx_throttle                (struct usb_serial_port *port);
-static void keyspan_rx_unthrottle      (struct usb_serial_port *port);
-static int  keyspan_write_room         (struct usb_serial_port *port);
+static int  keyspan_write_room         (struct tty_struct *tty);
 
-static int  keyspan_write              (struct usb_serial_port *port,
+static int  keyspan_write              (struct tty_struct *tty,
+                                        struct usb_serial_port *port,
                                         const unsigned char *buf,
                                         int count);
 
@@ -53,18 +54,14 @@ static void keyspan_send_setup              (struct usb_serial_port *port,
                                         int reset_port);
 
 
-static int  keyspan_chars_in_buffer    (struct usb_serial_port *port);
-static int  keyspan_ioctl              (struct usb_serial_port *port,
-                                        struct file *file,
-                                        unsigned int cmd,
-                                        unsigned long arg);
-static void keyspan_set_termios                (struct usb_serial_port *port,
+static void keyspan_set_termios                (struct tty_struct *tty,
+                                        struct usb_serial_port *port,
                                         struct ktermios *old);
-static void keyspan_break_ctl          (struct usb_serial_port *port,
+static void keyspan_break_ctl          (struct tty_struct *tty,
                                         int break_state);
-static int  keyspan_tiocmget           (struct usb_serial_port *port,
+static int  keyspan_tiocmget           (struct tty_struct *tty,
                                         struct file *file);
-static int  keyspan_tiocmset           (struct usb_serial_port *port,
+static int  keyspan_tiocmset           (struct tty_struct *tty,
                                         struct file *file, unsigned int set,
                                         unsigned int clear);
 static int  keyspan_fake_startup       (struct usb_serial *serial);
@@ -138,7 +135,8 @@ static int  keyspan_usa67_send_setup        (struct usb_serial *serial,
 
 /* Product IDs post-renumeration.  Note that the 28x and 28xb
    have the same id's post-renumeration but behave identically
-   so it's not an issue. */
+   so it's not an issue. As such, the 28xb is not listed in any
+   of the device tables. */
 #define        keyspan_usa18x_product_id               0x0112
 #define        keyspan_usa19_product_id                0x0107
 #define        keyspan_usa19qi_product_id              0x010c
@@ -482,7 +480,6 @@ static struct usb_device_id keyspan_ids_combined[] = {
        { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) },
        { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) },
        { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) },
-       { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) },
        { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xg_product_id) },
        { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id)},
        { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)},
@@ -532,7 +529,6 @@ static struct usb_device_id keyspan_2port_ids[] = {
        { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) },
        { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) },
        { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) },
-       { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) },
        { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xg_product_id) },
        { } /* Terminating entry */
 };
@@ -568,10 +564,6 @@ static struct usb_serial_driver keyspan_1port_device = {
        .close                  = keyspan_close,
        .write                  = keyspan_write,
        .write_room             = keyspan_write_room,
-       .chars_in_buffer        = keyspan_chars_in_buffer,
-       .throttle               = keyspan_rx_throttle,
-       .unthrottle             = keyspan_rx_unthrottle,
-       .ioctl                  = keyspan_ioctl,
        .set_termios            = keyspan_set_termios,
        .break_ctl              = keyspan_break_ctl,
        .tiocmget               = keyspan_tiocmget,
@@ -592,10 +584,6 @@ static struct usb_serial_driver keyspan_2port_device = {
        .close                  = keyspan_close,
        .write                  = keyspan_write,
        .write_room             = keyspan_write_room,
-       .chars_in_buffer        = keyspan_chars_in_buffer,
-       .throttle               = keyspan_rx_throttle,
-       .unthrottle             = keyspan_rx_unthrottle,
-       .ioctl                  = keyspan_ioctl,
        .set_termios            = keyspan_set_termios,
        .break_ctl              = keyspan_break_ctl,
        .tiocmget               = keyspan_tiocmget,
@@ -616,10 +604,6 @@ static struct usb_serial_driver keyspan_4port_device = {
        .close                  = keyspan_close,
        .write                  = keyspan_write,
        .write_room             = keyspan_write_room,
-       .chars_in_buffer        = keyspan_chars_in_buffer,
-       .throttle               = keyspan_rx_throttle,
-       .unthrottle             = keyspan_rx_unthrottle,
-       .ioctl                  = keyspan_ioctl,
        .set_termios            = keyspan_set_termios,
        .break_ctl              = keyspan_break_ctl,
        .tiocmget               = keyspan_tiocmget,
index 644a1eaaa376686adc4c147dcf3e80cf373fdccd..040040a267d970ff0fe97b057fb1eb7cb8f6df33 100644 (file)
@@ -10,8 +10,9 @@
  *     the Free Software Foundation; either version 2 of the License, or
  *     (at your option) any later version.
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
- * 
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
+ *
  * (09/07/2001) gkh
  *     cleaned up the Xircom support.  Added ids for Entregra device which is
  *     the same as the Xircom device.  Enabled the code to be compiled for
  *     support for Xircom PGSDB9
  *
  * (05/31/2001) gkh
- *     switched from using spinlock to a semaphore, which fixes lots of problems.
+ *     switched from using spinlock to a semaphore, which fixes lots of
+ *     problems.
  *
  * (04/08/2001) gb
  *     Identify version on module load.
- * 
+ *
  * (11/01/2000) Adam J. Richter
  *     usb_device_id table support
- * 
+ *
  * (10/05/2000) gkh
  *     Fixed bug with urb->dev not being set properly, now that the usb
  *     core needs it.
- * 
+ *
  * (08/28/2000) gkh
  *     Added locks for SMP safeness.
- *     Fixed MOD_INC and MOD_DEC logic and the ability to open a port more 
+ *     Fixed MOD_INC and MOD_DEC logic and the ability to open a port more
  *     than once.
- * 
+ *
  * (07/20/2000) borchers
  *     - keyspan_pda_write no longer sleeps if it is called on interrupt time;
  *       PPP and the line discipline with stty echo on can call write on
  *       than done directly from the callback to avoid the race in write_chan
  *     - keyspan_pda_chars_in_buffer also indicates its buffer is full if the
  *       urb status is -EINPROGRESS, meaning it cannot write at the moment
- *      
+ *
  * (07/19/2000) gkh
  *     Added module_init and module_exit functions to handle the fact that this
  *     driver is a loadable module now.
  *
  * (03/26/2000) gkh
  *     Split driver up into device specific pieces.
- * 
+ *
  */
 
 
@@ -78,7 +80,7 @@
 #include <linux/workqueue.h>
 #include <linux/firmware.h>
 #include <linux/ihex.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
@@ -135,7 +137,7 @@ static struct usb_device_id id_table_combined [] = {
        { }                                             /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
 
 static struct usb_driver keyspan_pda_driver = {
        .name =         "keyspan_pda",
@@ -159,9 +161,9 @@ static struct usb_device_id id_table_fake [] = {
 
 #ifdef XIRCOM
 static struct usb_device_id id_table_fake_xircom [] = {
-        { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
-        { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
-        { }                                             
+       { USB_DEVICE(XIRCOM_VENDOR_ID, XIRCOM_FAKE_ID) },
+       { USB_DEVICE(ENTREGRA_VENDOR_ID, ENTREGRA_FAKE_ID) },
+       { }
 };
 #endif
 
@@ -171,7 +173,7 @@ static void keyspan_pda_wakeup_write(struct work_struct *work)
                container_of(work, struct keyspan_pda_private, wakeup_work);
        struct usb_serial_port *port = priv->port;
 
-       tty_wakeup(port->tty);
+       tty_wakeup(port->port.tty);
 }
 
 static void keyspan_pda_request_unthrottle(struct work_struct *work)
@@ -184,7 +186,7 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work)
        dbg(" request_unthrottle");
        /* ask the device to tell us when the tx buffer becomes
           sufficiently empty */
-       result = usb_control_msg(serial->dev, 
+       result = usb_control_msg(serial->dev,
                                 usb_sndctrlpipe(serial->dev, 0),
                                 7, /* request_unthrottle */
                                 USB_TYPE_VENDOR | USB_RECIP_INTERFACE
@@ -195,17 +197,16 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work)
                                 0,
                                 2000);
        if (result < 0)
-               dbg("%s - error %d from usb_control_msg", 
+               dbg("%s - error %d from usb_control_msg",
                    __func__, result);
 }
 
 
-static void keyspan_pda_rx_interrupt (struct urb *urb)
+static void keyspan_pda_rx_interrupt(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
-               struct tty_struct *tty = port->tty;
+       struct tty_struct *tty = port->port.tty;
        unsigned char *data = urb->transfer_buffer;
-       int i;
        int retval;
        int status = urb->status;
        struct keyspan_pda_private *priv;
@@ -228,14 +229,13 @@ static void keyspan_pda_rx_interrupt (struct urb *urb)
                goto exit;
        }
 
-       /* see if the message is data or a status interrupt */
+       /* see if the message is data or a status interrupt */
        switch (data[0]) {
        case 0:
                /* rest of message is rx data */
                if (urb->actual_length) {
-                       for (i = 1; i < urb->actual_length ; ++i) {
-                               tty_insert_flip_char(tty, data[i], 0);
-                       }
+                       tty_insert_flip_string(tty, data + 1,
+                                               urb->actual_length - 1);
                        tty_flip_buffer_push(tty);
                }
                break;
@@ -259,14 +259,14 @@ static void keyspan_pda_rx_interrupt (struct urb *urb)
        }
 
 exit:
-       retval = usb_submit_urb (urb, GFP_ATOMIC);
+       retval = usb_submit_urb(urb, GFP_ATOMIC);
        if (retval)
-               err ("%s - usb_submit_urb failed with result %d",
+               err("%s - usb_submit_urb failed with result %d",
                     __func__, retval);
 }
 
 
-static void keyspan_pda_rx_throttle (struct usb_serial_port *port)
+static void keyspan_pda_rx_throttle(struct tty_struct *tty)
 {
        /* stop receiving characters. We just turn off the URB request, and
           let chars pile up in the device. If we're doing hardware
@@ -274,14 +274,15 @@ static void keyspan_pda_rx_throttle (struct usb_serial_port *port)
           fills up. If we're doing XON/XOFF, this would be a good time to
           send an XOFF, although it might make sense to foist that off
           upon the device too. */
-
+       struct usb_serial_port *port = tty->driver_data;
        dbg("keyspan_pda_rx_throttle port %d", port->number);
        usb_kill_urb(port->interrupt_in_urb);
 }
 
 
-static void keyspan_pda_rx_unthrottle (struct usb_serial_port *port)
+static void keyspan_pda_rx_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        /* just restart the receive interrupt URB */
        dbg("keyspan_pda_rx_unthrottle port %d", port->number);
        port->interrupt_in_urb->dev = port->serial->dev;
@@ -291,32 +292,52 @@ static void keyspan_pda_rx_unthrottle (struct usb_serial_port *port)
 }
 
 
-static speed_t keyspan_pda_setbaud (struct usb_serial *serial, speed_t baud)
+static speed_t keyspan_pda_setbaud(struct usb_serial *serial, speed_t baud)
 {
        int rc;
        int bindex;
 
-       switch(baud) {
-               case 110: bindex = 0; break;
-               case 300: bindex = 1; break;
-               case 1200: bindex = 2; break;
-               case 2400: bindex = 3; break;
-               case 4800: bindex = 4; break;
-               case 9600: bindex = 5; break;
-               case 19200: bindex = 6; break;
-               case 38400: bindex = 7; break;
-               case 57600: bindex = 8; break;
-               case 115200: bindex = 9; break;
-               default:
-                       bindex = 5;     /* Default to 9600 */
-                       baud = 9600;
+       switch (baud) {
+       case 110:
+               bindex = 0;
+               break;
+       case 300:
+               bindex = 1;
+               break;
+       case 1200:
+               bindex = 2;
+               break;
+       case 2400:
+               bindex = 3;
+               break;
+       case 4800:
+               bindex = 4;
+               break;
+       case 9600:
+               bindex = 5;
+               break;
+       case 19200:
+               bindex = 6;
+               break;
+       case 38400:
+               bindex = 7;
+               break;
+       case 57600:
+               bindex = 8;
+               break;
+       case 115200:
+               bindex = 9;
+               break;
+       default:
+               bindex = 5;     /* Default to 9600 */
+               baud = 9600;
        }
 
        /* rather than figure out how to sleep while waiting for this
           to complete, I just use the "legacy" API. */
        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                             0, /* set baud */
-                            USB_TYPE_VENDOR 
+                            USB_TYPE_VENDOR
                             | USB_RECIP_INTERFACE
                             | USB_DIR_OUT, /* type */
                             bindex, /* value */
@@ -330,8 +351,9 @@ static speed_t keyspan_pda_setbaud (struct usb_serial *serial, speed_t baud)
 }
 
 
-static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state)
+static void keyspan_pda_break_ctl(struct tty_struct *tty, int break_state)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
        int value;
        int result;
@@ -341,11 +363,11 @@ static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state
        else
                value = 0; /* clear break */
        result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                               4, /* set break */
-                               USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
-                               value, 0, NULL, 0, 2000);
+                       4, /* set break */
+                       USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT,
+                       value, 0, NULL, 0, 2000);
        if (result < 0)
-               dbg("%s - error %d from usb_control_msg", 
+               dbg("%s - error %d from usb_control_msg",
                    __func__, result);
        /* there is something funky about this.. the TCSBRK that 'cu' performs
           ought to translate into a break_ctl(-1),break_ctl(0) pair HZ/4
@@ -354,8 +376,8 @@ static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state
 }
 
 
-static void keyspan_pda_set_termios (struct usb_serial_port *port, 
-                                    struct ktermios *old_termios)
+static void keyspan_pda_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        struct usb_serial *serial = port->serial;
        speed_t speed;
@@ -380,7 +402,7 @@ static void keyspan_pda_set_termios (struct usb_serial_port *port,
 
           For now, just do baud. */
 
-       speed = tty_get_baud_rate(port->tty);
+       speed = tty_get_baud_rate(tty);
        speed = keyspan_pda_setbaud(serial, speed);
 
        if (speed == 0) {
@@ -390,8 +412,8 @@ static void keyspan_pda_set_termios (struct usb_serial_port *port,
        }
        /* Only speed can change so copy the old h/w parameters
           then encode the new speed */
-       tty_termios_copy_hw(port->tty->termios, old_termios);
-       tty_encode_baud_rate(port->tty, speed, speed);
+       tty_termios_copy_hw(tty->termios, old_termios);
+       tty_encode_baud_rate(tty, speed, speed);
 }
 
 
@@ -408,7 +430,7 @@ static int keyspan_pda_get_modem_info(struct usb_serial *serial,
                             3, /* get pins */
                             USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN,
                             0, 0, &data, 1, 2000);
-       if (rc > 0)
+       if (rc >= 0)
                *value = data;
        return rc;
 }
@@ -425,8 +447,9 @@ static int keyspan_pda_set_modem_info(struct usb_serial *serial,
        return rc;
 }
 
-static int keyspan_pda_tiocmget(struct usb_serial_port *port, struct file *file)
+static int keyspan_pda_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
        int rc;
        unsigned char status;
@@ -445,9 +468,10 @@ static int keyspan_pda_tiocmget(struct usb_serial_port *port, struct file *file)
        return value;
 }
 
-static int keyspan_pda_tiocmset(struct usb_serial_port *port, struct file *file,
+static int keyspan_pda_tiocmset(struct tty_struct *tty, struct file *file,
                                unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
        int rc;
        unsigned char status;
@@ -469,23 +493,8 @@ static int keyspan_pda_tiocmset(struct usb_serial_port *port, struct file *file,
        return rc;
 }
 
-static int keyspan_pda_ioctl(struct usb_serial_port *port, struct file *file,
-                            unsigned int cmd, unsigned long arg)
-{
-       switch (cmd) {
-       case TIOCMIWAIT:
-               /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
-               /* TODO */
-       case TIOCGICOUNT:
-               /* return count of modemline transitions */
-               return 0; /* TODO */
-       }
-       
-       return -ENOIOCTLCMD;
-}
-
-static int keyspan_pda_write(struct usb_serial_port *port, 
-                            const unsigned char *buf, int count)
+static int keyspan_pda_write(struct tty_struct *tty,
+       struct usb_serial_port *port, const unsigned char *buf, int count)
 {
        struct usb_serial *serial = port->serial;
        int request_unthrottle = 0;
@@ -501,10 +510,10 @@ static int keyspan_pda_write(struct usb_serial_port *port,
           select() or poll() too) until we receive that unthrottle interrupt.
           Block if we can't write anything at all, otherwise write as much as
           we can. */
-       dbg("keyspan_pda_write(%d)",count);
+       dbg("keyspan_pda_write(%d)", count);
        if (count == 0) {
                dbg(" write request of 0 bytes");
-               return (0);
+               return 0;
        }
 
        /* we might block because of:
@@ -531,7 +540,7 @@ static int keyspan_pda_write(struct usb_serial_port *port,
           scheduler time, since usb_control_msg() sleeps. */
        if (count > priv->tx_room && !in_interrupt()) {
                unsigned char room;
-               rc = usb_control_msg(serial->dev, 
+               rc = usb_control_msg(serial->dev,
                                     usb_rcvctrlpipe(serial->dev, 0),
                                     6, /* write_room */
                                     USB_TYPE_VENDOR | USB_RECIP_INTERFACE
@@ -562,7 +571,7 @@ static int keyspan_pda_write(struct usb_serial_port *port,
 
        if (count) {
                /* now transfer data */
-               memcpy (port->write_urb->transfer_buffer, buf, count);
+               memcpy(port->write_urb->transfer_buffer, buf, count);
                /* send the data out the bulk port */
                port->write_urb->transfer_buffer_length = count;
 
@@ -574,8 +583,7 @@ static int keyspan_pda_write(struct usb_serial_port *port,
                        dbg(" usb_submit_urb(write bulk) failed");
                        goto exit;
                }
-       }
-       else {
+       } else {
                /* There wasn't any room left, so we are throttled until
                   the buffer empties a bit */
                request_unthrottle = 1;
@@ -594,7 +602,7 @@ exit:
 }
 
 
-static void keyspan_pda_write_bulk_callback (struct urb *urb)
+static void keyspan_pda_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct keyspan_pda_private *priv;
@@ -607,22 +615,21 @@ static void keyspan_pda_write_bulk_callback (struct urb *urb)
 }
 
 
-static int keyspan_pda_write_room (struct usb_serial_port *port)
+static int keyspan_pda_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct keyspan_pda_private *priv;
-
        priv = usb_get_serial_port_data(port);
-
        /* used by n_tty.c for processing of tabs and such. Giving it our
           conservative guess is probably good enough, but needs testing by
           running a console through the device. */
-
-       return (priv->tx_room);
+       return priv->tx_room;
 }
 
 
-static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port)
+static int keyspan_pda_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct keyspan_pda_private *priv;
        unsigned long flags;
        int ret = 0;
@@ -640,7 +647,8 @@ static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port)
 }
 
 
-static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp)
+static int keyspan_pda_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial = port->serial;
        unsigned char room;
@@ -672,8 +680,8 @@ static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp)
 
        /* the normal serial device seems to always turn on DTR and RTS here,
           so do the same */
-       if (port->tty->termios->c_cflag & CBAUD)
-               keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2) );
+       if (tty && (tty->termios->c_cflag & CBAUD))
+               keyspan_pda_set_modem_info(serial, (1<<7) | (1<<2));
        else
                keyspan_pda_set_modem_info(serial, 0);
 
@@ -690,13 +698,15 @@ error:
 }
 
 
-static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
+static void keyspan_pda_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial = port->serial;
 
        if (serial->dev) {
-               /* the normal serial device seems to always shut off DTR and RTS now */
-               if (port->tty->termios->c_cflag & HUPCL)
+               /* the normal serial device seems to always shut
+                  off DTR and RTS now */
+               if (tty->termios->c_cflag & HUPCL)
                        keyspan_pda_set_modem_info(serial, 0);
 
                /* shutdown our bulk reads and writes */
@@ -707,7 +717,7 @@ static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
 
 
 /* download the firmware to a "fake" device (pre-renumeration) */
-static int keyspan_pda_fake_startup (struct usb_serial *serial)
+static int keyspan_pda_fake_startup(struct usb_serial *serial)
 {
        int response;
        const char *fw_name;
@@ -756,10 +766,10 @@ static int keyspan_pda_fake_startup (struct usb_serial *serial)
        response = ezusb_set_reset(serial, 0);
 
        /* we want this device to fail to have a driver assigned to it. */
-       return (1);
+       return 1;
 }
 
-static int keyspan_pda_startup (struct usb_serial *serial)
+static int keyspan_pda_startup(struct usb_serial *serial)
 {
 
        struct keyspan_pda_private *priv;
@@ -769,20 +779,20 @@ static int keyspan_pda_startup (struct usb_serial *serial)
 
        priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL);
        if (!priv)
-               return (1); /* error */
+               return 1; /* error */
        usb_set_serial_port_data(serial->port[0], priv);
        init_waitqueue_head(&serial->port[0]->write_wait);
        INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write);
        INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle);
        priv->serial = serial;
        priv->port = serial->port[0];
-       return (0);
+       return 0;
 }
 
-static void keyspan_pda_shutdown (struct usb_serial *serial)
+static void keyspan_pda_shutdown(struct usb_serial *serial)
 {
        dbg("%s", __func__);
-       
+
        kfree(usb_get_serial_port_data(serial->port[0]));
 }
 
@@ -832,7 +842,6 @@ static struct usb_serial_driver keyspan_pda_device = {
        .chars_in_buffer =      keyspan_pda_chars_in_buffer,
        .throttle =             keyspan_pda_rx_throttle,
        .unthrottle =           keyspan_pda_rx_unthrottle,
-       .ioctl =                keyspan_pda_ioctl,
        .set_termios =          keyspan_pda_set_termios,
        .break_ctl =            keyspan_pda_break_ctl,
        .tiocmget =             keyspan_pda_tiocmget,
@@ -842,7 +851,7 @@ static struct usb_serial_driver keyspan_pda_device = {
 };
 
 
-static int __init keyspan_pda_init (void)
+static int __init keyspan_pda_init(void)
 {
        int retval;
        retval = usb_serial_register(&keyspan_pda_device);
@@ -863,7 +872,7 @@ static int __init keyspan_pda_init (void)
                goto failed_usb_register;
        info(DRIVER_DESC " " DRIVER_VERSION);
        return 0;
-failed_usb_register:   
+failed_usb_register:
 #ifdef XIRCOM
        usb_serial_deregister(&xircom_pgs_fake_device);
 failed_xircom_register:
@@ -880,15 +889,15 @@ failed_pda_register:
 }
 
 
-static void __exit keyspan_pda_exit (void)
+static void __exit keyspan_pda_exit(void)
 {
-       usb_deregister (&keyspan_pda_driver);
-       usb_serial_deregister (&keyspan_pda_device);
+       usb_deregister(&keyspan_pda_driver);
+       usb_serial_deregister(&keyspan_pda_device);
 #ifdef KEYSPAN
-       usb_serial_deregister (&keyspan_pda_fake_device);
+       usb_serial_deregister(&keyspan_pda_fake_device);
 #endif
 #ifdef XIRCOM
-       usb_serial_deregister (&xircom_pgs_fake_device);
+       usb_serial_deregister(&xircom_pgs_fake_device);
 #endif
 }
 
@@ -896,8 +905,8 @@ static void __exit keyspan_pda_exit (void)
 module_init(keyspan_pda_init);
 module_exit(keyspan_pda_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
index f328948d74e3dfc9cf21439333ef48140eff1af9..b84dddc71124546ec0fd968ae03748975dae6f1a 100644 (file)
  * Neither Palm, nor their contractor (MCCI) or their supplier (KLSI) provided
  * information that was not already available.
  *
- * It seems that KLSI bought some silicon-design information from ScanLogic, 
+ * It seems that KLSI bought some silicon-design information from ScanLogic,
  * whose SL11R processor is at the core of the KL5KUSB chipset from KLSI.
  * KLSI has firmware available for their devices; it is probable that the
  * firmware differs from that used by KLSI in their products. If you have an
- * original KLSI device and can provide some information on it, I would be 
- * most interested in adding support for it here. If you have any information 
+ * original KLSI device and can provide some information on it, I would be
+ * most interested in adding support for it here. If you have any information
  * on the protocol used (or find errors in my reverse-engineered stuff), please
  * let me know.
  *
@@ -40,7 +40,7 @@
  *   0.2  - TIOCMGET works, so autopilot(1) can be used!
  *   0.1  - can be used to to pilot-xfer -p /dev/ttyUSB0 -l
  *
- *   The driver skeleton is mainly based on mct_u232.c and various other 
+ *   The driver skeleton is mainly based on mct_u232.c and various other
  *   pieces of code shamelessly copied from the drivers/usb/serial/ directory.
  */
 
@@ -53,7 +53,7 @@
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
 #include <linux/module.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <asm/unaligned.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
@@ -72,33 +72,25 @@ static int debug;
 /*
  * Function prototypes
  */
-static int  klsi_105_startup            (struct usb_serial *serial);
-static void klsi_105_shutdown           (struct usb_serial *serial);
-static int  klsi_105_open               (struct usb_serial_port *port,
-                                         struct file *filp);
-static void klsi_105_close              (struct usb_serial_port *port,
-                                         struct file *filp);
-static int  klsi_105_write              (struct usb_serial_port *port,
-                                         const unsigned char *buf,
-                                         int count);
-static void klsi_105_write_bulk_callback (struct urb *urb);
-static int  klsi_105_chars_in_buffer     (struct usb_serial_port *port);
-static int  klsi_105_write_room          (struct usb_serial_port *port);
-
-static void klsi_105_read_bulk_callback  (struct urb *urb);
-static void klsi_105_set_termios         (struct usb_serial_port *port,
-                                         struct ktermios *old);
-static void klsi_105_throttle           (struct usb_serial_port *port);
-static void klsi_105_unthrottle                 (struct usb_serial_port *port);
-/*
-static void klsi_105_break_ctl          (struct usb_serial_port *port,
-                                         int break_state );
- */
-static int  klsi_105_tiocmget           (struct usb_serial_port *port,
-                                         struct file *file);
-static int  klsi_105_tiocmset           (struct usb_serial_port *port,
-                                         struct file *file, unsigned int set,
-                                         unsigned int clear);
+static int  klsi_105_startup(struct usb_serial *serial);
+static void klsi_105_shutdown(struct usb_serial *serial);
+static int  klsi_105_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static void klsi_105_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static int  klsi_105_write(struct tty_struct *tty,
+       struct usb_serial_port *port, const unsigned char *buf, int count);
+static void klsi_105_write_bulk_callback(struct urb *urb);
+static int  klsi_105_chars_in_buffer(struct tty_struct *tty);
+static int  klsi_105_write_room(struct tty_struct *tty);
+static void klsi_105_read_bulk_callback(struct urb *urb);
+static void klsi_105_set_termios(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct ktermios *old);
+static void klsi_105_throttle(struct tty_struct *tty);
+static void klsi_105_unthrottle(struct tty_struct *tty);
+static int  klsi_105_tiocmget(struct tty_struct *tty, struct file *file);
+static int  klsi_105_tiocmset(struct tty_struct *tty, struct file *file,
+                       unsigned int set, unsigned int clear);
 
 /*
  * All of the device info needed for the KLSI converters.
@@ -109,7 +101,7 @@ static struct usb_device_id id_table [] = {
        { }             /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver kl5kusb105d_driver = {
        .name =         "kl5kusb105d",
@@ -134,7 +126,7 @@ static struct usb_serial_driver kl5kusb105d_device = {
        .write_bulk_callback = klsi_105_write_bulk_callback,
        .chars_in_buffer =   klsi_105_chars_in_buffer,
        .write_room =        klsi_105_write_room,
-       .read_bulk_callback =klsi_105_read_bulk_callback,
+       .read_bulk_callback = klsi_105_read_bulk_callback,
        .set_termios =       klsi_105_set_termios,
        /*.break_ctl =       klsi_105_break_ctl,*/
        .tiocmget =          klsi_105_tiocmget,
@@ -161,7 +153,7 @@ struct klsi_105_private {
        struct ktermios                 termios;
        unsigned long                   line_state; /* modem line settings */
        /* write pool */
-       struct urb *                    write_urb_pool[NUM_URBS];
+       struct urb                      *write_urb_pool[NUM_URBS];
        spinlock_t                      lock;
        unsigned long                   bytes_in;
        unsigned long                   bytes_out;
@@ -180,15 +172,15 @@ static int klsi_105_chg_port_settings(struct usb_serial_port *port,
 {
        int rc;
 
-        rc = usb_control_msg(port->serial->dev,
-                            usb_sndctrlpipe(port->serial->dev, 0),
-                            KL5KUSB105A_SIO_SET_DATA,
-                             USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_INTERFACE,
-                            0, /* value */
-                            0, /* index */
-                            settings,
-                            sizeof(struct klsi_105_port_settings),
-                            KLSI_TIMEOUT);
+       rc = usb_control_msg(port->serial->dev,
+                       usb_sndctrlpipe(port->serial->dev, 0),
+                       KL5KUSB105A_SIO_SET_DATA,
+                       USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_INTERFACE,
+                       0, /* value */
+                       0, /* index */
+                       settings,
+                       sizeof(struct klsi_105_port_settings),
+                       KLSI_TIMEOUT);
        if (rc < 0)
                err("Change port settings failed (error = %d)", rc);
        info("%s - %d byte block, baudrate %x, databits %d, u1 %d, u2 %d",
@@ -196,7 +188,7 @@ static int klsi_105_chg_port_settings(struct usb_serial_port *port,
            settings->pktlen,
            settings->baudrate, settings->databits,
            settings->unknown1, settings->unknown2);
-        return rc;
+       return rc;
 } /* klsi_105_chg_port_settings */
 
 /* translate a 16-bit status value from the device to linux's TIO bits */
@@ -210,9 +202,9 @@ static unsigned long klsi_105_status2linestate(const __u16 status)
 
        return res;
 }
-/* 
+/*
  * Read line control via vendor command and return result through
- * *line_state_p 
+ * *line_state_p
  */
 /* It seems that the status buffer has always only 2 bytes length */
 #define KLSI_STATUSBUF_LEN     2
@@ -220,14 +212,14 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
                                   unsigned long *line_state_p)
 {
        int rc;
-       __u8 status_buf[KLSI_STATUSBUF_LEN] = { -1,-1};
+       __u8 status_buf[KLSI_STATUSBUF_LEN] = { -1, -1};
        __u16 status;
 
        info("%s - sending SIO Poll request", __func__);
-        rc = usb_control_msg(port->serial->dev,
+       rc = usb_control_msg(port->serial->dev,
                             usb_rcvctrlpipe(port->serial->dev, 0),
                             KL5KUSB105A_SIO_POLL,
-                             USB_TYPE_VENDOR | USB_DIR_IN,
+                            USB_TYPE_VENDOR | USB_DIR_IN,
                             0, /* value */
                             0, /* index */
                             status_buf, KLSI_STATUSBUF_LEN,
@@ -236,15 +228,14 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
        if (rc < 0)
                err("Reading line status failed (error = %d)", rc);
        else {
-               status = le16_to_cpu(get_unaligned((__le16 *)status_buf));
+               status = get_unaligned_le16(status_buf);
 
                info("%s - read status %x %x", __func__,
                     status_buf[0], status_buf[1]);
 
                *line_state_p = klsi_105_status2linestate(status);
        }
-
-        return rc;
+       return rc;
 }
 
 
@@ -252,7 +243,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
  * Driver's tty interface functions
  */
 
-static int klsi_105_startup (struct usb_serial *serial)
+static int klsi_105_startup(struct usb_serial *serial)
 {
        struct klsi_105_private *priv;
        int i, j;
@@ -262,7 +253,7 @@ static int klsi_105_startup (struct usb_serial *serial)
         */
 
        /* allocate the private data structure */
-       for (i=0; i<serial->num_ports; i++) {
+       for (i = 0; i < serial->num_ports; i++) {
                priv = kmalloc(sizeof(struct klsi_105_private),
                                                   GFP_KERNEL);
                if (!priv) {
@@ -283,9 +274,9 @@ static int klsi_105_startup (struct usb_serial *serial)
                priv->bytes_out     = 0;
                usb_set_serial_port_data(serial->port[i], priv);
 
-               spin_lock_init (&priv->lock);
-               for (j=0; j<NUM_URBS; j++) {
-                       struct urburb = usb_alloc_urb(0, GFP_KERNEL);
+               spin_lock_init(&priv->lock);
+               for (j = 0; j < NUM_URBS; j++) {
+                       struct urb *urb = usb_alloc_urb(0, GFP_KERNEL);
 
                        priv->write_urb_pool[j] = urb;
                        if (urb == NULL) {
@@ -293,10 +284,11 @@ static int klsi_105_startup (struct usb_serial *serial)
                                goto err_cleanup;
                        }
 
-                       urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE,
-                                                       GFP_KERNEL);
+                       urb->transfer_buffer =
+                               kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
                        if (!urb->transfer_buffer) {
-                               err("%s - out of memory for urb buffers.", __func__);
+                               err("%s - out of memory for urb buffers.",
+                                                               __func__);
                                goto err_cleanup;
                        }
                }
@@ -304,13 +296,13 @@ static int klsi_105_startup (struct usb_serial *serial)
                /* priv->termios is left uninitalized until port opening */
                init_waitqueue_head(&serial->port[i]->write_wait);
        }
-       
+
        return 0;
 
 err_cleanup:
        for (; i >= 0; i--) {
                priv = usb_get_serial_port_data(serial->port[i]);
-               for (j=0; j < NUM_URBS; j++) {
+               for (j = 0; j < NUM_URBS; j++) {
                        if (priv->write_urb_pool[j]) {
                                kfree(priv->write_urb_pool[j]->transfer_buffer);
                                usb_free_urb(priv->write_urb_pool[j]);
@@ -322,22 +314,23 @@ err_cleanup:
 } /* klsi_105_startup */
 
 
-static void klsi_105_shutdown (struct usb_serial *serial)
+static void klsi_105_shutdown(struct usb_serial *serial)
 {
        int i;
-       
+
        dbg("%s", __func__);
 
        /* stop reads and writes on all ports */
-       for (i=0; i < serial->num_ports; ++i) {
-               struct klsi_105_private *priv = usb_get_serial_port_data(serial->port[i]);
+       for (i = 0; i < serial->num_ports; ++i) {
+               struct klsi_105_private *priv =
+                               usb_get_serial_port_data(serial->port[i]);
                unsigned long flags;
 
                if (priv) {
                        /* kill our write urb pool */
                        int j;
                        struct urb **write_urbs = priv->write_urb_pool;
-                       spin_lock_irqsave(&priv->lock,flags);
+                       spin_lock_irqsave(&priv->lock, flags);
 
                        for (j = 0; j < NUM_URBS; j++) {
                                if (write_urbs[j]) {
@@ -349,19 +342,18 @@ static void klsi_105_shutdown (struct usb_serial *serial)
                                         * oopses. */
                                        /* usb_kill_urb(write_urbs[j]); */
                                        kfree(write_urbs[j]->transfer_buffer);
-                                       usb_free_urb (write_urbs[j]);
+                                       usb_free_urb(write_urbs[j]);
                                }
                        }
-
-                       spin_unlock_irqrestore (&priv->lock, flags);
-
+                       spin_unlock_irqrestore(&priv->lock, flags);
                        kfree(priv);
                        usb_set_serial_port_data(serial->port[i], NULL);
                }
        }
 } /* klsi_105_shutdown */
 
-static int  klsi_105_open (struct usb_serial_port *port, struct file *filp)
+static int  klsi_105_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct klsi_105_private *priv = usb_get_serial_port_data(port);
        int retval = 0;
@@ -375,11 +367,11 @@ static int  klsi_105_open (struct usb_serial_port *port, struct file *filp)
 
        /* force low_latency on so that our tty_push actually forces
         * the data through
-        * port->tty->low_latency = 1; */
+        * tty->low_latency = 1; */
 
        /* Do a defined restart:
         * Set up sane default baud rate and send the 'READ_ON'
-        * vendor command. 
+        * vendor command.
         * FIXME: set modem line control (how?)
         * Then read the modem line control and store values in
         * priv->line_state.
@@ -390,24 +382,24 @@ static int  klsi_105_open (struct usb_serial_port *port, struct file *filp)
        cfg.unknown1 = 0;
        cfg.unknown2 = 1;
        klsi_105_chg_port_settings(port, &cfg);
-       
+
        /* set up termios structure */
-       spin_lock_irqsave (&priv->lock, flags);
-       priv->termios.c_iflag = port->tty->termios->c_iflag;
-       priv->termios.c_oflag = port->tty->termios->c_oflag;
-       priv->termios.c_cflag = port->tty->termios->c_cflag;
-       priv->termios.c_lflag = port->tty->termios->c_lflag;
-       for (i=0; i<NCCS; i++)
-               priv->termios.c_cc[i] = port->tty->termios->c_cc[i];
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->termios.c_iflag = tty->termios->c_iflag;
+       priv->termios.c_oflag = tty->termios->c_oflag;
+       priv->termios.c_cflag = tty->termios->c_cflag;
+       priv->termios.c_lflag = tty->termios->c_lflag;
+       for (i = 0; i < NCCS; i++)
+               priv->termios.c_cc[i] = tty->termios->c_cc[i];
        priv->cfg.pktlen   = cfg.pktlen;
        priv->cfg.baudrate = cfg.baudrate;
        priv->cfg.databits = cfg.databits;
        priv->cfg.unknown1 = cfg.unknown1;
        priv->cfg.unknown2 = cfg.unknown2;
-       spin_unlock_irqrestore (&priv->lock, flags);
+       spin_unlock_irqrestore(&priv->lock, flags);
 
        /* READ_ON and urb submission */
-       usb_fill_bulk_urb(port->read_urb, port->serial->dev, 
+       usb_fill_bulk_urb(port->read_urb, port->serial->dev,
                      usb_rcvbulkpipe(port->serial->dev,
                                      port->bulk_in_endpointAddress),
                      port->read_urb->transfer_buffer,
@@ -423,7 +415,7 @@ static int  klsi_105_open (struct usb_serial_port *port, struct file *filp)
        }
 
        rc = usb_control_msg(port->serial->dev,
-                            usb_sndctrlpipe(port->serial->dev,0),
+                            usb_sndctrlpipe(port->serial->dev, 0),
                             KL5KUSB105A_SIO_CONFIGURE,
                             USB_TYPE_VENDOR|USB_DIR_OUT|USB_RECIP_INTERFACE,
                             KL5KUSB105A_SIO_CONFIGURE_READ_ON,
@@ -434,14 +426,14 @@ static int  klsi_105_open (struct usb_serial_port *port, struct file *filp)
        if (rc < 0) {
                err("Enabling read failed (error = %d)", rc);
                retval = rc;
-       } else 
+       } else
                dbg("%s - enabled reading", __func__);
 
        rc = klsi_105_get_line_state(port, &line_state);
        if (rc >= 0) {
-               spin_lock_irqsave (&priv->lock, flags);
+               spin_lock_irqsave(&priv->lock, flags);
                priv->line_state = line_state;
-               spin_unlock_irqrestore (&priv->lock, flags);
+               spin_unlock_irqrestore(&priv->lock, flags);
                dbg("%s - read line state 0x%lx", __func__, line_state);
                retval = 0;
        } else
@@ -452,7 +444,8 @@ exit:
 } /* klsi_105_open */
 
 
-static void klsi_105_close (struct usb_serial_port *port, struct file *filp)
+static void klsi_105_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct klsi_105_private *priv = usb_get_serial_port_data(port);
        int rc;
@@ -462,14 +455,14 @@ static void klsi_105_close (struct usb_serial_port *port, struct file *filp)
        mutex_lock(&port->serial->disc_mutex);
        if (!port->serial->disconnected) {
                /* send READ_OFF */
-               rc = usb_control_msg (port->serial->dev,
-                                     usb_sndctrlpipe(port->serial->dev, 0),
-                                     KL5KUSB105A_SIO_CONFIGURE,
-                                     USB_TYPE_VENDOR | USB_DIR_OUT,
-                                     KL5KUSB105A_SIO_CONFIGURE_READ_OFF,
-                                     0, /* index */
-                                     NULL, 0,
-                                     KLSI_TIMEOUT);
+               rc = usb_control_msg(port->serial->dev,
+                                    usb_sndctrlpipe(port->serial->dev, 0),
+                                    KL5KUSB105A_SIO_CONFIGURE,
+                                    USB_TYPE_VENDOR | USB_DIR_OUT,
+                                    KL5KUSB105A_SIO_CONFIGURE_READ_OFF,
+                                    0, /* index */
+                                    NULL, 0,
+                                    KLSI_TIMEOUT);
                if (rc < 0)
                        err("Disabling read failed (error = %d)", rc);
        }
@@ -482,23 +475,24 @@ static void klsi_105_close (struct usb_serial_port *port, struct file *filp)
        /* FIXME */
        /* wgg - do I need this? I think so. */
        usb_kill_urb(port->interrupt_in_urb);
-       info("kl5kusb105 port stats: %ld bytes in, %ld bytes out", priv->bytes_in, priv->bytes_out);
+       info("kl5kusb105 port stats: %ld bytes in, %ld bytes out",
+                                       priv->bytes_in, priv->bytes_out);
 } /* klsi_105_close */
 
 
 /* We need to write a complete 64-byte data block and encode the
- * number actually sent in the first double-byte, LSB-order. That 
+ * number actually sent in the first double-byte, LSB-order. That
  * leaves at most 62 bytes of payload.
  */
 #define KLSI_105_DATA_OFFSET   2   /* in the bulk urb data block */
 
 
-static int klsi_105_write (struct usb_serial_port *port,
-                          const unsigned char *buf, int count)
+static int klsi_105_write(struct tty_struct *tty,
+       struct usb_serial_port *port, const unsigned char *buf, int count)
 {
        struct klsi_105_private *priv = usb_get_serial_port_data(port);
        int result, size;
-       int bytes_sent=0;
+       int bytes_sent = 0;
 
        dbg("%s - port %d", __func__, port->number);
 
@@ -507,34 +501,37 @@ static int klsi_105_write (struct usb_serial_port *port,
                struct urb *urb = NULL;
                unsigned long flags;
                int i;
-               /* since the pool is per-port we might not need the spin lock !? */
-               spin_lock_irqsave (&priv->lock, flags);
-               for (i=0; i<NUM_URBS; i++) {
+               /* since the pool is per-port we might not need
+                  the spin lock !? */
+               spin_lock_irqsave(&priv->lock, flags);
+               for (i = 0; i < NUM_URBS; i++) {
                        if (priv->write_urb_pool[i]->status != -EINPROGRESS) {
                                urb = priv->write_urb_pool[i];
                                dbg("%s - using pool URB %d", __func__, i);
                                break;
                        }
                }
-               spin_unlock_irqrestore (&priv->lock, flags);
+               spin_unlock_irqrestore(&priv->lock, flags);
 
-               if (urb==NULL) {
+               if (urb == NULL) {
                        dbg("%s - no more free urbs", __func__);
                        goto exit;
                }
 
                if (urb->transfer_buffer == NULL) {
-                       urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC);
+                       urb->transfer_buffer =
+                               kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC);
                        if (urb->transfer_buffer == NULL) {
                                err("%s - no more kernel memory...", __func__);
                                goto exit;
                        }
                }
 
-               size = min (count, port->bulk_out_size - KLSI_105_DATA_OFFSET);
-               size = min (size, URB_TRANSFER_BUFFER_SIZE - KLSI_105_DATA_OFFSET);
+               size = min(count, port->bulk_out_size - KLSI_105_DATA_OFFSET);
+               size = min(size, URB_TRANSFER_BUFFER_SIZE -
+                                                       KLSI_105_DATA_OFFSET);
 
-               memcpy (urb->transfer_buffer + KLSI_105_DATA_OFFSET, buf, size);
+               memcpy(urb->transfer_buffer + KLSI_105_DATA_OFFSET, buf, size);
 
                /* write payload size into transfer buffer */
                ((__u8 *)urb->transfer_buffer)[0] = (__u8) (size & 0xFF);
@@ -552,7 +549,8 @@ static int klsi_105_write (struct usb_serial_port *port,
                /* send the data out the bulk port */
                result = usb_submit_urb(urb, GFP_ATOMIC);
                if (result) {
-                       err("%s - failed submitting write urb, error %d", __func__, result);
+                       err("%s - failed submitting write urb, error %d",
+                                                       __func__, result);
                        goto exit;
                }
                buf += size;
@@ -561,12 +559,12 @@ static int klsi_105_write (struct usb_serial_port *port,
        }
 exit:
        /* lockless, but it's for debug info only... */
-       priv->bytes_out+=bytes_sent;
+       priv->bytes_out += bytes_sent;
 
        return bytes_sent;      /* that's how much we wrote */
 } /* klsi_105_write */
 
-static void klsi_105_write_bulk_callback ( struct urb *urb)
+static void klsi_105_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        int status = urb->status;
@@ -584,50 +582,50 @@ static void klsi_105_write_bulk_callback ( struct urb *urb)
 
 
 /* return number of characters currently in the writing process */
-static int klsi_105_chars_in_buffer (struct usb_serial_port *port)
+static int klsi_105_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        int chars = 0;
        int i;
        unsigned long flags;
        struct klsi_105_private *priv = usb_get_serial_port_data(port);
 
-       spin_lock_irqsave (&priv->lock, flags);
+       spin_lock_irqsave(&priv->lock, flags);
 
        for (i = 0; i < NUM_URBS; ++i) {
-               if (priv->write_urb_pool[i]->status == -EINPROGRESS) {
+               if (priv->write_urb_pool[i]->status == -EINPROGRESS)
                        chars += URB_TRANSFER_BUFFER_SIZE;
-               }
        }
 
-       spin_unlock_irqrestore (&priv->lock, flags);
+       spin_unlock_irqrestore(&priv->lock, flags);
 
        dbg("%s - returns %d", __func__, chars);
-       return (chars);
+       return chars;
 }
 
-static int klsi_105_write_room (struct usb_serial_port *port)
+static int klsi_105_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        unsigned long flags;
        int i;
        int room = 0;
        struct klsi_105_private *priv = usb_get_serial_port_data(port);
 
-       spin_lock_irqsave (&priv->lock, flags);
+       spin_lock_irqsave(&priv->lock, flags);
        for (i = 0; i < NUM_URBS; ++i) {
-               if (priv->write_urb_pool[i]->status != -EINPROGRESS) {
+               if (priv->write_urb_pool[i]->status != -EINPROGRESS)
                        room += URB_TRANSFER_BUFFER_SIZE;
-               }
        }
 
-       spin_unlock_irqrestore (&priv->lock, flags);
+       spin_unlock_irqrestore(&priv->lock, flags);
 
        dbg("%s - returns %d", __func__, room);
-       return (room);
+       return room;
 }
 
 
 
-static void klsi_105_read_bulk_callback (struct urb *urb)
+static void klsi_105_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct klsi_105_private *priv = usb_get_serial_port_data(port);
@@ -660,13 +658,13 @@ static void klsi_105_read_bulk_callback (struct urb *urb)
        } else {
                int bytes_sent = ((__u8 *) data)[0] +
                                 ((unsigned int) ((__u8 *) data)[1] << 8);
-               tty = port->tty;
+               tty = port->port.tty;
                /* we should immediately resubmit the URB, before attempting
                 * to pass the data on to the tty layer. But that needs locking
                 * against re-entry an then mixed-up data because of
                 * intermixed tty_flip_buffer_push()s
                 * FIXME
-                */ 
+                */
                usb_serial_debug_data(debug, &port->dev, __func__,
                                      urb->actual_length, data);
 
@@ -686,7 +684,7 @@ static void klsi_105_read_bulk_callback (struct urb *urb)
                priv->bytes_in += bytes_sent;
        }
        /* Continue trying to always read  */
-       usb_fill_bulk_urb(port->read_urb, port->serial->dev, 
+       usb_fill_bulk_urb(port->read_urb, port->serial->dev,
                      usb_rcvbulkpipe(port->serial->dev,
                                      port->bulk_in_endpointAddress),
                      port->read_urb->transfer_buffer,
@@ -695,15 +693,16 @@ static void klsi_105_read_bulk_callback (struct urb *urb)
                      port);
        rc = usb_submit_urb(port->read_urb, GFP_ATOMIC);
        if (rc)
-               err("%s - failed resubmitting read urb, error %d", __func__, rc);
+               err("%s - failed resubmitting read urb, error %d",
+                                                       __func__, rc);
 } /* klsi_105_read_bulk_callback */
 
 
-static void klsi_105_set_termios (struct usb_serial_port *port,
-                                 struct ktermios *old_termios)
+static void klsi_105_set_termios(struct tty_struct *tty,
+                                struct usb_serial_port *port,
+                                struct ktermios *old_termios)
 {
        struct klsi_105_private *priv = usb_get_serial_port_data(port);
-       struct tty_struct *tty = port->tty;
        unsigned int iflag = tty->termios->c_iflag;
        unsigned int old_iflag = old_termios->c_iflag;
        unsigned int cflag = tty->termios->c_cflag;
@@ -711,65 +710,63 @@ static void klsi_105_set_termios (struct usb_serial_port *port,
        struct klsi_105_port_settings cfg;
        unsigned long flags;
        speed_t baud;
-       
+
        /* lock while we are modifying the settings */
-       spin_lock_irqsave (&priv->lock, flags);
-       
+       spin_lock_irqsave(&priv->lock, flags);
+
        /*
         * Update baud rate
         */
        baud = tty_get_baud_rate(tty);
 
-       if( (cflag & CBAUD) != (old_cflag & CBAUD) ) {
-               /* reassert DTR and (maybe) RTS on transition from B0 */
-               if( (old_cflag & CBAUD) == B0 ) {
+       if ((cflag & CBAUD) != (old_cflag & CBAUD)) {
+               /* reassert DTR and (maybe) RTS on transition from B0 */
+               if ((old_cflag & CBAUD) == B0) {
                        dbg("%s: baud was B0", __func__);
 #if 0
                        priv->control_state |= TIOCM_DTR;
                        /* don't set RTS if using hardware flow control */
-                       if (!(old_cflag & CRTSCTS)) {
+                       if (!(old_cflag & CRTSCTS))
                                priv->control_state |= TIOCM_RTS;
-                       }
                        mct_u232_set_modem_ctrl(serial, priv->control_state);
 #endif
                }
        }
-       switch(baud) {
-               case 0: /* handled below */
-                       break;
-               case 1200:
-                       priv->cfg.baudrate = kl5kusb105a_sio_b1200;
-                       break;
-               case 2400:
-                       priv->cfg.baudrate = kl5kusb105a_sio_b2400;
-                       break;
-               case 4800:
-                       priv->cfg.baudrate = kl5kusb105a_sio_b4800;
-                       break;
-               case 9600:
-                       priv->cfg.baudrate = kl5kusb105a_sio_b9600;
-                       break;
-               case 19200:
-                       priv->cfg.baudrate = kl5kusb105a_sio_b19200;
-                       break;
-               case 38400:
-                       priv->cfg.baudrate = kl5kusb105a_sio_b38400;
-                       break;
-               case 57600:
-                       priv->cfg.baudrate = kl5kusb105a_sio_b57600;
-                       break;
-               case 115200:
-                       priv->cfg.baudrate = kl5kusb105a_sio_b115200;
-                       break;
-               default:
-                       dbg("KLSI USB->Serial converter:"
-                           " unsupported baudrate request, using default"
-                           " of 9600");
+       switch (baud) {
+       case 0: /* handled below */
+               break;
+       case 1200:
+               priv->cfg.baudrate = kl5kusb105a_sio_b1200;
+               break;
+       case 2400:
+               priv->cfg.baudrate = kl5kusb105a_sio_b2400;
+               break;
+       case 4800:
+               priv->cfg.baudrate = kl5kusb105a_sio_b4800;
+               break;
+       case 9600:
+               priv->cfg.baudrate = kl5kusb105a_sio_b9600;
+               break;
+       case 19200:
+               priv->cfg.baudrate = kl5kusb105a_sio_b19200;
+               break;
+       case 38400:
+               priv->cfg.baudrate = kl5kusb105a_sio_b38400;
+               break;
+       case 57600:
+               priv->cfg.baudrate = kl5kusb105a_sio_b57600;
+               break;
+       case 115200:
+               priv->cfg.baudrate = kl5kusb105a_sio_b115200;
+               break;
+       default:
+               dbg("KLSI USB->Serial converter:"
+                   " unsupported baudrate request, using default of 9600");
                        priv->cfg.baudrate = kl5kusb105a_sio_b9600;
-                       baud = 9600;
-                       break;
+               baud = 9600;
+               break;
        }
-       if ((cflag & CBAUD) == B0 ) {
+       if ((cflag & CBAUD) == B0) {
                dbg("%s: baud is B0", __func__);
                /* Drop RTS and DTR */
                /* maybe this should be simulated by sending read
@@ -778,7 +775,7 @@ static void klsi_105_set_termios (struct usb_serial_port *port,
                ;
 #if 0
                priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
-                       mct_u232_set_modem_ctrl(serial, priv->control_state);
+               mct_u232_set_modem_ctrl(serial, priv->control_state);
 #endif
        }
        tty_encode_baud_rate(tty, baud, baud);
@@ -788,11 +785,11 @@ static void klsi_105_set_termios (struct usb_serial_port *port,
                switch (cflag & CSIZE) {
                case CS5:
                        dbg("%s - 5 bits/byte not supported", __func__);
-                       spin_unlock_irqrestore (&priv->lock, flags);
+                       spin_unlock_irqrestore(&priv->lock, flags);
                        return ;
                case CS6:
                        dbg("%s - 6 bits/byte not supported", __func__);
-                       spin_unlock_irqrestore (&priv->lock, flags);
+                       spin_unlock_irqrestore(&priv->lock, flags);
                        return ;
                case CS7:
                        priv->cfg.databits = kl5kusb105a_dtb_7;
@@ -811,8 +808,7 @@ static void klsi_105_set_termios (struct usb_serial_port *port,
         * Update line control register (LCR)
         */
        if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))
-           || (cflag & CSTOPB) != (old_cflag & CSTOPB) ) {
-               
+           || (cflag & CSTOPB) != (old_cflag & CSTOPB)) {
                /* Not currently supported */
                tty->termios->c_cflag &= ~(PARENB|PARODD|CSTOPB);
 #if 0
@@ -833,20 +829,18 @@ static void klsi_105_set_termios (struct usb_serial_port *port,
 #endif
                ;
        }
-       
        /*
         * Set flow control: well, I do not really now how to handle DTR/RTS.
         * Just do what we have seen with SniffUSB on Win98.
         */
-       if(iflag & IXOFF) != (old_iflag & IXOFF)
+       if ((iflag & IXOFF) != (old_iflag & IXOFF)
            || (iflag & IXON) != (old_iflag & IXON)
-           ||  (cflag & CRTSCTS) != (old_cflag & CRTSCTS) ) {
-               
+           ||  (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
                /* Not currently supported */
                tty->termios->c_cflag &= ~CRTSCTS;
                /* Drop DTR/RTS if no flow control otherwise assert */
 #if 0
-               if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS) )
+               if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS))
                        priv->control_state |= TIOCM_DTR | TIOCM_RTS;
                else
                        priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
@@ -854,19 +848,21 @@ static void klsi_105_set_termios (struct usb_serial_port *port,
 #endif
                ;
        }
-       memcpy (&cfg, &priv->cfg, sizeof(cfg));
-       spin_unlock_irqrestore (&priv->lock, flags);
-       
+       memcpy(&cfg, &priv->cfg, sizeof(cfg));
+       spin_unlock_irqrestore(&priv->lock, flags);
+
        /* now commit changes to device */
        klsi_105_chg_port_settings(port, &cfg);
 } /* klsi_105_set_termios */
 
 
 #if 0
-static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state )
+static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
-       struct mct_u232_private *priv = (struct mct_u232_private *)port->private;
+       struct mct_u232_private *priv =
+                               (struct mct_u232_private *)port->private;
        unsigned char lcr = priv->last_lcr;
 
        dbg("%sstate=%d", __func__, break_state);
@@ -878,8 +874,9 @@ static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state )
 } /* mct_u232_break_ctl */
 #endif
 
-static int klsi_105_tiocmget (struct usb_serial_port *port, struct file *file)
+static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct klsi_105_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        int rc;
@@ -893,18 +890,18 @@ static int klsi_105_tiocmget (struct usb_serial_port *port, struct file *file)
                return rc;
        }
 
-       spin_lock_irqsave (&priv->lock, flags);
+       spin_lock_irqsave(&priv->lock, flags);
        priv->line_state = line_state;
-       spin_unlock_irqrestore (&priv->lock, flags);
+       spin_unlock_irqrestore(&priv->lock, flags);
        dbg("%s - read line state 0x%lx", __func__, line_state);
        return (int)line_state;
 }
 
-static int klsi_105_tiocmset (struct usb_serial_port *port, struct file *file,
-                             unsigned int set, unsigned int clear)
+static int klsi_105_tiocmset(struct tty_struct *tty, struct file *file,
+                            unsigned int set, unsigned int clear)
 {
        int retval = -EINVAL;
-       
+
        dbg("%s", __func__);
 
 /* if this ever gets implemented, it should be done something like this:
@@ -929,14 +926,16 @@ static int klsi_105_tiocmset (struct usb_serial_port *port, struct file *file,
        return retval;
 }
 
-static void klsi_105_throttle (struct usb_serial_port *port)
+static void klsi_105_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        dbg("%s - port %d", __func__, port->number);
        usb_kill_urb(port->read_urb);
 }
 
-static void klsi_105_unthrottle (struct usb_serial_port *port)
+static void klsi_105_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        int result;
 
        dbg("%s - port %d", __func__, port->number);
@@ -950,7 +949,7 @@ static void klsi_105_unthrottle (struct usb_serial_port *port)
 
 
 
-static int __init klsi_105_init (void)
+static int __init klsi_105_init(void)
 {
        int retval;
        retval = usb_serial_register(&kl5kusb105d_device);
@@ -969,19 +968,19 @@ failed_usb_serial_register:
 }
 
 
-static void __exit klsi_105_exit (void)
+static void __exit klsi_105_exit(void)
 {
-       usb_deregister (&kl5kusb105d_driver);
-       usb_serial_deregister (&kl5kusb105d_device);
+       usb_deregister(&kl5kusb105d_driver);
+       usb_serial_deregister(&kl5kusb105d_device);
 }
 
 
-module_init (klsi_105_init);
-module_exit (klsi_105_exit);
+module_init(klsi_105_init);
+module_exit(klsi_105_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_LICENSE("GPL"); 
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
index 693f00da7c038b0072d360b031479c0f1a30bea5..deba28ec77e8e43cab07691bf17ed68624b9d517 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  KOBIL USB Smart Card Terminal Driver
  *
- *  Copyright (C) 2002  KOBIL Systems GmbH 
+ *  Copyright (C) 2002  KOBIL Systems GmbH
  *  Author: Thomas Wahrenbruch
  *
  *  Contact: linuxusb@kobil.de
@@ -20,7 +20,7 @@
  *
  * Supported readers: USB TWIN, KAAN Standard Plus and SecOVID Reader Plus
  * (Adapter K), B1 Professional and KAAN Professional (Adapter B)
- * 
+ *
  * (21/05/2004) tw
  *      Fix bug with P'n'P readers
  *
@@ -44,7 +44,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include <linux/ioctl.h>
@@ -68,21 +68,24 @@ static int debug;
 
 
 /* Function prototypes */
-static int  kobil_startup (struct usb_serial *serial);
-static void kobil_shutdown (struct usb_serial *serial);
-static int  kobil_open (struct usb_serial_port *port, struct file *filp);
-static void kobil_close (struct usb_serial_port *port, struct file *filp);
-static int  kobil_write (struct usb_serial_port *port, 
+static int  kobil_startup(struct usb_serial *serial);
+static void kobil_shutdown(struct usb_serial *serial);
+static int  kobil_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static void kobil_close(struct tty_struct *tty, struct usb_serial_port *port,
+                       struct file *filp);
+static int  kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
                         const unsigned char *buf, int count);
-static int  kobil_write_room(struct usb_serial_port *port);
-static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,
+static int  kobil_write_room(struct tty_struct *tty);
+static int  kobil_ioctl(struct tty_struct *tty, struct file *file,
                        unsigned int cmd, unsigned long arg);
-static int  kobil_tiocmget(struct usb_serial_port *port, struct file *file);
-static int  kobil_tiocmset(struct usb_serial_port *port, struct file *file,
+static int  kobil_tiocmget(struct tty_struct *tty, struct file *file);
+static int  kobil_tiocmset(struct tty_struct *tty, struct file *file,
                           unsigned int set, unsigned int clear);
-static void kobil_read_int_callback( struct urb *urb );
-static void kobil_write_callback( struct urb *purb );
-static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old);
+static void kobil_read_int_callback(struct urb *urb);
+static void kobil_write_callback(struct urb *purb);
+static void kobil_set_termios(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct ktermios *old);
 
 
 static struct usb_device_id id_table [] = {
@@ -94,7 +97,7 @@ static struct usb_device_id id_table [] = {
 };
 
 
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver kobil_driver = {
        .name =         "kobil",
@@ -131,14 +134,14 @@ static struct usb_serial_driver kobil_device = {
 struct kobil_private {
        int write_int_endpoint_address;
        int read_int_endpoint_address;
-       unsigned char buf[KOBIL_BUF_LENGTH]; // buffer for the APDU to send
-       int filled;  // index of the last char in buf
-       int cur_pos; // index of the next char to send in buf
+       unsigned char buf[KOBIL_BUF_LENGTH]; /* buffer for the APDU to send */
+       int filled;  /* index of the last char in buf */
+       int cur_pos; /* index of the next char to send in buf */
        __u16 device_type;
 };
 
 
-static int kobil_startup (struct usb_serial *serial)
+static int kobil_startup(struct usb_serial *serial)
 {
        int i;
        struct kobil_private *priv;
@@ -149,20 +152,20 @@ static int kobil_startup (struct usb_serial *serial)
        struct usb_host_endpoint *endpoint;
 
        priv = kmalloc(sizeof(struct kobil_private), GFP_KERNEL);
-       if (!priv){
+       if (!priv)
                return -ENOMEM;
-       }
 
        priv->filled = 0;
        priv->cur_pos = 0;
        priv->device_type = le16_to_cpu(serial->dev->descriptor.idProduct);
 
-       switch (priv->device_type){
+       switch (priv->device_type) {
        case KOBIL_ADAPTER_B_PRODUCT_ID:
                printk(KERN_DEBUG "KOBIL B1 PRO / KAAN PRO detected\n");
                break;
        case KOBIL_ADAPTER_K_PRODUCT_ID:
-               printk(KERN_DEBUG "KOBIL KAAN Standard Plus / SecOVID Reader Plus detected\n");
+               printk(KERN_DEBUG
+                 "KOBIL KAAN Standard Plus / SecOVID Reader Plus detected\n");
                break;
        case KOBIL_USBTWIN_PRODUCT_ID:
                printk(KERN_DEBUG "KOBIL USBTWIN detected\n");
@@ -173,44 +176,48 @@ static int kobil_startup (struct usb_serial *serial)
        }
        usb_set_serial_port_data(serial->port[0], priv);
 
-       // search for the necessary endpoints
+       /* search for the necessary endpoints */
        pdev = serial->dev;
-       actconfig = pdev->actconfig;
-       interface = actconfig->interface[0];
+       actconfig = pdev->actconfig;
+       interface = actconfig->interface[0];
        altsetting = interface->cur_altsetting;
-       endpoint = altsetting->endpoint;
-  
-       for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
+       endpoint = altsetting->endpoint;
+
+       for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
                endpoint = &altsetting->endpoint[i];
                if (usb_endpoint_is_int_out(&endpoint->desc)) {
-                       dbg("%s Found interrupt out endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress);
-                       priv->write_int_endpoint_address = endpoint->desc.bEndpointAddress;
-               }
+                       dbg("%s Found interrupt out endpoint. Address: %d",
+                               __func__, endpoint->desc.bEndpointAddress);
+                       priv->write_int_endpoint_address =
+                               endpoint->desc.bEndpointAddress;
+               }
                if (usb_endpoint_is_int_in(&endpoint->desc)) {
-                       dbg("%s Found interrupt in  endpoint. Address: %d", __func__, endpoint->desc.bEndpointAddress);
-                       priv->read_int_endpoint_address = endpoint->desc.bEndpointAddress;
-               }
+                       dbg("%s Found interrupt in  endpoint. Address: %d",
+                               __func__, endpoint->desc.bEndpointAddress);
+                       priv->read_int_endpoint_address =
+                               endpoint->desc.bEndpointAddress;
+               }
        }
        return 0;
 }
 
 
-static void kobil_shutdown (struct usb_serial *serial)
+static void kobil_shutdown(struct usb_serial *serial)
 {
        int i;
        dbg("%s - port %d", __func__, serial->port[0]->number);
 
-       for (i=0; i < serial->num_ports; ++i) {
-               while (serial->port[i]->open_count > 0) {
-                       kobil_close (serial->port[i], NULL);
-               }
+       for (i = 0; i < serial->num_ports; ++i) {
+               while (serial->port[i]->port.count > 0)
+                       kobil_close(NULL, serial->port[i], NULL);
                kfree(usb_get_serial_port_data(serial->port[i]));
                usb_set_serial_port_data(serial->port[i], NULL);
        }
 }
 
 
-static int kobil_open (struct usb_serial_port *port, struct file *filp)
+static int kobil_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        int result = 0;
        struct kobil_private *priv;
@@ -221,7 +228,7 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp)
        dbg("%s - port %d", __func__, port->number);
        priv = usb_get_serial_port_data(port);
 
-       // someone sets the dev to 0 if the close method has been called
+       /* someone sets the dev to 0 if the close method has been called */
        port->interrupt_in_urb->dev = port->serial->dev;
 
 
@@ -229,100 +236,115 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp)
         * the data through, otherwise it is scheduled, and with high
         * data rates (like with OHCI) data can get lost.
         */
-       port->tty->low_latency = 1;
-
-       // without this, every push_tty_char is echoed :-(  
-       port->tty->termios->c_lflag = 0;
-       port->tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
-       port->tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
-       port->tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D)
-       
-       // allocate memory for transfer buffer
+       if (tty) {
+               tty->low_latency = 1;
+
+               /* Default to echo off and other sane device settings */
+               tty->termios->c_lflag = 0;
+               tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN |
+                                                                XCASE);
+               tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
+               /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
+               tty->termios->c_oflag &= ~ONLCR;
+       }
+       /* allocate memory for transfer buffer */
        transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
-       if (! transfer_buffer) {
+       if (!transfer_buffer)
                return -ENOMEM;
-       }
-       
-       // allocate write_urb
-       if (!port->write_urb) { 
-               dbg("%s - port %d  Allocating port->write_urb", __func__, port->number);
-               port->write_urb = usb_alloc_urb(0, GFP_KERNEL);  
+
+       /* allocate write_urb */
+       if (!port->write_urb) {
+               dbg("%s - port %d  Allocating port->write_urb",
+                                               __func__, port->number);
+               port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
                if (!port->write_urb) {
-                       dbg("%s - port %d usb_alloc_urb failed", __func__, port->number);
+                       dbg("%s - port %d usb_alloc_urb failed",
+                                               __func__, port->number);
                        kfree(transfer_buffer);
                        return -ENOMEM;
                }
        }
 
-       // allocate memory for write_urb transfer buffer
-       port->write_urb->transfer_buffer = kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
-       if (! port->write_urb->transfer_buffer) {
+       /* allocate memory for write_urb transfer buffer */
+       port->write_urb->transfer_buffer =
+                       kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
+       if (!port->write_urb->transfer_buffer) {
                kfree(transfer_buffer);
                usb_free_urb(port->write_urb);
                port->write_urb = NULL;
                return -ENOMEM;
-       } 
-
-       // get hardware version
-       result = usb_control_msg( port->serial->dev, 
-                                 usb_rcvctrlpipe(port->serial->dev, 0 ), 
-                                 SUSBCRequest_GetMisc,
-                                 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
-                                 SUSBCR_MSC_GetHWVersion,
-                                 0,
-                                 transfer_buffer,
-                                 transfer_buffer_length,
-                                 KOBIL_TIMEOUT
+       }
+
+       /* get hardware version */
+       result = usb_control_msg(port->serial->dev,
+                         usb_rcvctrlpipe(port->serial->dev, 0),
+                         SUSBCRequest_GetMisc,
+                         USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
+                         SUSBCR_MSC_GetHWVersion,
+                         0,
+                         transfer_buffer,
+                         transfer_buffer_length,
+                         KOBIL_TIMEOUT
+       );
+       dbg("%s - port %d Send get_HW_version URB returns: %i",
+               __func__, port->number, result);
+       dbg("Harware version: %i.%i.%i",
+               transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]);
+
+       /* get firmware version */
+       result = usb_control_msg(port->serial->dev,
+                         usb_rcvctrlpipe(port->serial->dev, 0),
+                         SUSBCRequest_GetMisc,
+                         USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
+                         SUSBCR_MSC_GetFWVersion,
+                         0,
+                         transfer_buffer,
+                         transfer_buffer_length,
+                         KOBIL_TIMEOUT
+       );
+       dbg("%s - port %d Send get_FW_version URB returns: %i",
+                                       __func__, port->number, result);
+       dbg("Firmware version: %i.%i.%i",
+               transfer_buffer[0], transfer_buffer[1], transfer_buffer[2]);
+
+       if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
+                       priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
+               /* Setting Baudrate, Parity and Stopbits */
+               result = usb_control_msg(port->serial->dev,
+                         usb_rcvctrlpipe(port->serial->dev, 0),
+                         SUSBCRequest_SetBaudRateParityAndStopBits,
+                         USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+                         SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity |
+                                                       SUSBCR_SPASB_1StopBit,
+                         0,
+                         transfer_buffer,
+                         0,
+                         KOBIL_TIMEOUT
                );
-       dbg("%s - port %d Send get_HW_version URB returns: %i", __func__, port->number, result);
-       dbg("Harware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] );
-       
-       // get firmware version
-       result = usb_control_msg( port->serial->dev, 
-                                 usb_rcvctrlpipe(port->serial->dev, 0 ), 
-                                 SUSBCRequest_GetMisc,
-                                 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
-                                 SUSBCR_MSC_GetFWVersion,
-                                 0,
-                                 transfer_buffer,
-                                 transfer_buffer_length,
-                                 KOBIL_TIMEOUT
+               dbg("%s - port %d Send set_baudrate URB returns: %i",
+                                       __func__, port->number, result);
+
+               /* reset all queues */
+               result = usb_control_msg(port->serial->dev,
+                         usb_rcvctrlpipe(port->serial->dev, 0),
+                         SUSBCRequest_Misc,
+                         USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+                         SUSBCR_MSC_ResetAllQueues,
+                         0,
+                         transfer_buffer,
+                         0,
+                         KOBIL_TIMEOUT
                );
-       dbg("%s - port %d Send get_FW_version URB returns: %i", __func__, port->number, result);
-       dbg("Firmware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] );
-
-       if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
-               // Setting Baudrate, Parity and Stopbits
-               result = usb_control_msg( port->serial->dev, 
-                                         usb_rcvctrlpipe(port->serial->dev, 0 ), 
-                                         SUSBCRequest_SetBaudRateParityAndStopBits,
-                                         USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
-                                         SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity | SUSBCR_SPASB_1StopBit,
-                                         0,
-                                         transfer_buffer,
-                                         0,
-                                         KOBIL_TIMEOUT
-                       );
-               dbg("%s - port %d Send set_baudrate URB returns: %i", __func__, port->number, result);
-               
-               // reset all queues
-               result = usb_control_msg( port->serial->dev, 
-                                         usb_rcvctrlpipe(port->serial->dev, 0 ), 
-                                         SUSBCRequest_Misc,
-                                         USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
-                                         SUSBCR_MSC_ResetAllQueues,
-                                         0,
-                                         transfer_buffer,
-                                         0,
-                                         KOBIL_TIMEOUT
-                       );
-               dbg("%s - port %d Send reset_all_queues URB returns: %i", __func__, port->number, result);
+               dbg("%s - port %d Send reset_all_queues URB returns: %i",
+                                       __func__, port->number, result);
        }
-       if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
+       if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
+           priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
            priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
-               // start reading (Adapter B 'cause PNP string)
-               result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC  ); 
-               dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result);
+               /* start reading (Adapter B 'cause PNP string) */
+               result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
+               dbg("%s - port %d Send read URB returns: %i",
+                                       __func__, port->number, result);
        }
 
        kfree(transfer_buffer);
@@ -330,13 +352,14 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp)
 }
 
 
-static void kobil_close (struct usb_serial_port *port, struct file *filp)
+static void kobil_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        dbg("%s - port %d", __func__, port->number);
 
        if (port->write_urb) {
                usb_kill_urb(port->write_urb);
-               usb_free_urb( port->write_urb );
+               usb_free_urb(port->write_urb);
                port->write_urb = NULL;
        }
        usb_kill_urb(port->interrupt_in_urb);
@@ -350,7 +373,7 @@ static void kobil_read_int_callback(struct urb *urb)
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
        int status = urb->status;
-//     char *dbg_data;
+/*     char *dbg_data; */
 
        dbg("%s - port %d", __func__, port->number);
 
@@ -360,51 +383,53 @@ static void kobil_read_int_callback(struct urb *urb)
                return;
        }
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (urb->actual_length) {
 
-               // BEGIN DEBUG
+               /* BEGIN DEBUG */
                /*
-                 dbg_data = kzalloc((3 *  purb->actual_length + 10) * sizeof(char), GFP_KERNEL);
+                 dbg_data = kzalloc((3 *  purb->actual_length + 10)
+                                               * sizeof(char), GFP_KERNEL);
                  if (! dbg_data) {
-                 return;
+                         return;
                  }
-                 for (i = 0; i < purb->actual_length; i++) { 
-                 sprintf(dbg_data +3*i, "%02X ", data[i]); 
+                 for (i = 0; i < purb->actual_length; i++) {
+                         sprintf(dbg_data +3*i, "%02X ", data[i]);
                  }
-                 dbg(" <-- %s", dbg_data );
+                 dbg(" <-- %s", dbg_data);
                  kfree(dbg_data);
                */
-               // END DEBUG
+               /* END DEBUG */
 
                tty_buffer_request_room(tty, urb->actual_length);
                tty_insert_flip_string(tty, data, urb->actual_length);
                tty_flip_buffer_push(tty);
        }
-
-       // someone sets the dev to 0 if the close method has been called
+       /* someone sets the dev to 0 if the close method has been called */
        port->interrupt_in_urb->dev = port->serial->dev;
 
        result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
-       dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result);
+       dbg("%s - port %d Send read URB returns: %i",
+                       __func__, port->number, result);
 }
 
 
-static void kobil_write_callback( struct urb *purb )
+static void kobil_write_callback(struct urb *purb)
 {
 }
 
 
-static int kobil_write (struct usb_serial_port *port, 
+static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
                        const unsigned char *buf, int count)
 {
        int length = 0;
        int result = 0;
        int todo = 0;
-       struct kobil_private * priv;
+       struct kobil_private *priv;
 
        if (count == 0) {
-               dbg("%s - port %d write request of 0 bytes", __func__, port->number);
+               dbg("%s - port %d write request of 0 bytes",
+                                               __func__, port->number);
                return 0;
        }
 
@@ -415,106 +440,113 @@ static int kobil_write (struct usb_serial_port *port,
                return -ENOMEM;
        }
 
-       // Copy data to buffer
-       memcpy (priv->buf + priv->filled, buf, count);
-
-       usb_serial_debug_data(debug, &port->dev, __func__, count, priv->buf + priv->filled);
-
+       /* Copy data to buffer */
+       memcpy(priv->buf + priv->filled, buf, count);
+       usb_serial_debug_data(debug, &port->dev, __func__, count,
+                                               priv->buf + priv->filled);
        priv->filled = priv->filled + count;
 
-
-       // only send complete block. TWIN, KAAN SIM and adapter K use the same protocol.
-       if ( ((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) || 
-            ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4))) ) {
-               
-               // stop reading (except TWIN and KAAN SIM)
-               if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) )
+       /* only send complete block. TWIN, KAAN SIM and adapter K
+          use the same protocol. */
+       if (((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) ||
+            ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4)))) {
+               /* stop reading (except TWIN and KAAN SIM) */
+               if ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID)
+                       || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID))
                        usb_kill_urb(port->interrupt_in_urb);
 
                todo = priv->filled - priv->cur_pos;
 
-               while(todo > 0) {
-                       // max 8 byte in one urb (endpoint size)
+               while (todo > 0) {
+                       /* max 8 byte in one urb (endpoint size) */
                        length = (todo < 8) ? todo : 8;
-                       // copy data to transfer buffer
-                       memcpy(port->write_urb->transfer_buffer, priv->buf + priv->cur_pos, length );
-                       usb_fill_int_urb( port->write_urb,
-                                         port->serial->dev,
-                                         usb_sndintpipe(port->serial->dev, priv->write_int_endpoint_address),
-                                         port->write_urb->transfer_buffer,
-                                         length,
-                                         kobil_write_callback,
-                                         port,
-                                         8
-                               );
+                       /* copy data to transfer buffer */
+                       memcpy(port->write_urb->transfer_buffer,
+                                       priv->buf + priv->cur_pos, length);
+                       usb_fill_int_urb(port->write_urb,
+                                 port->serial->dev,
+                                 usb_sndintpipe(port->serial->dev,
+                                       priv->write_int_endpoint_address),
+                                 port->write_urb->transfer_buffer,
+                                 length,
+                                 kobil_write_callback,
+                                 port,
+                                 8
+                       );
 
                        priv->cur_pos = priv->cur_pos + length;
-                       result = usb_submit_urb( port->write_urb, GFP_NOIO );
-                       dbg("%s - port %d Send write URB returns: %i", __func__, port->number, result);
+                       result = usb_submit_urb(port->write_urb, GFP_NOIO);
+                       dbg("%s - port %d Send write URB returns: %i",
+                                       __func__, port->number, result);
                        todo = priv->filled - priv->cur_pos;
 
-                       if (todo > 0) {
+                       if (todo > 0)
                                msleep(24);
-                       }
+               }
 
-               } // end while
-               
                priv->filled = 0;
                priv->cur_pos = 0;
 
-               // someone sets the dev to 0 if the close method has been called
+               /* someone sets the dev to 0 if the close method
+                  has been called */
                port->interrupt_in_urb->dev = port->serial->dev;
-               
-               // start reading (except TWIN and KAAN SIM)
-               if ( (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) || (priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) ) {
-                       // someone sets the dev to 0 if the close method has been called
+
+               /* start reading (except TWIN and KAAN SIM) */
+               if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
+                       priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
+                       /* someone sets the dev to 0 if the close method has
+                          been called */
                        port->interrupt_in_urb->dev = port->serial->dev;
-                       
-                       result = usb_submit_urb( port->interrupt_in_urb, GFP_NOIO ); 
-                       dbg("%s - port %d Send read URB returns: %i", __func__, port->number, result);
+
+                       result = usb_submit_urb(port->interrupt_in_urb,
+                                                               GFP_NOIO);
+                       dbg("%s - port %d Send read URB returns: %i",
+                                       __func__, port->number, result);
                }
        }
        return count;
 }
 
 
-static int kobil_write_room (struct usb_serial_port *port)
+static int kobil_write_room(struct tty_struct *tty)
 {
-       //dbg("%s - port %d", __func__, port->number);
+       /* dbg("%s - port %d", __func__, port->number); */
+       /* FIXME */
        return 8;
 }
 
 
-static int kobil_tiocmget(struct usb_serial_port *port, struct file *file)
+static int kobil_tiocmget(struct tty_struct *tty, struct file *file)
 {
-       struct kobil_private * priv;
+       struct usb_serial_port *port = tty->driver_data;
+       struct kobil_private *priv;
        int result;
        unsigned char *transfer_buffer;
        int transfer_buffer_length = 8;
 
        priv = usb_get_serial_port_data(port);
-       if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
-               // This device doesn't support ioctl calls
+       if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID
+                       || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
+               /* This device doesn't support ioctl calls */
                return -EINVAL;
        }
 
-       // allocate memory for transfer buffer
+       /* allocate memory for transfer buffer */
        transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
-       if (!transfer_buffer) {
+       if (!transfer_buffer)
                return -ENOMEM;
-       }
 
-       result = usb_control_msg( port->serial->dev, 
-                                 usb_rcvctrlpipe(port->serial->dev, 0 ), 
-                                 SUSBCRequest_GetStatusLineState,
-                                 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
-                                 0,
-                                 0,
-                                 transfer_buffer,
-                                 transfer_buffer_length,
-                                 KOBIL_TIMEOUT);
-
-       dbg("%s - port %d Send get_status_line_state URB returns: %i. Statusline: %02x", 
+       result = usb_control_msg(port->serial->dev,
+                         usb_rcvctrlpipe(port->serial->dev, 0),
+                         SUSBCRequest_GetStatusLineState,
+                         USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
+                         0,
+                         0,
+                         transfer_buffer,
+                         transfer_buffer_length,
+                         KOBIL_TIMEOUT);
+
+       dbg("%s - port %d Send get_status_line_state URB returns: %i. Statusline: %02x",
            __func__, port->number, result, transfer_buffer[0]);
 
        result = 0;
@@ -524,10 +556,11 @@ static int kobil_tiocmget(struct usb_serial_port *port, struct file *file)
        return result;
 }
 
-static int  kobil_tiocmset(struct usb_serial_port *port, struct file *file,
+static int kobil_tiocmset(struct tty_struct *tty, struct file *file,
                           unsigned int set, unsigned int clear)
 {
-       struct kobil_private * priv;
+       struct usb_serial_port *port = tty->driver_data;
+       struct kobil_private *priv;
        int result;
        int dtr = 0;
        int rts = 0;
@@ -536,16 +569,16 @@ static int  kobil_tiocmset(struct usb_serial_port *port, struct file *file,
 
        /* FIXME: locking ? */
        priv = usb_get_serial_port_data(port);
-       if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
-               // This device doesn't support ioctl calls
+       if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID
+               || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
+               /* This device doesn't support ioctl calls */
                return -EINVAL;
        }
 
-       // allocate memory for transfer buffer
+       /* allocate memory for transfer buffer */
        transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
-       if (! transfer_buffer) {
+       if (!transfer_buffer)
                return -ENOMEM;
-       }
 
        if (set & TIOCM_RTS)
                rts = 1;
@@ -558,66 +591,77 @@ static int  kobil_tiocmset(struct usb_serial_port *port, struct file *file,
 
        if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) {
                if (dtr != 0)
-                       dbg("%s - port %d Setting DTR", __func__, port->number);
+                       dbg("%s - port %d Setting DTR",
+                                               __func__, port->number);
                else
-                       dbg("%s - port %d Clearing DTR", __func__, port->number);
-               result = usb_control_msg( port->serial->dev, 
-                                         usb_rcvctrlpipe(port->serial->dev, 0 ), 
-                                         SUSBCRequest_SetStatusLinesOrQueues,
-                                         USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
-                                         ((dtr != 0) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR),
-                                         0,
-                                         transfer_buffer,
-                                         0,
-                                         KOBIL_TIMEOUT);
+                       dbg("%s - port %d Clearing DTR",
+                                               __func__, port->number);
+               result = usb_control_msg(port->serial->dev,
+                         usb_rcvctrlpipe(port->serial->dev, 0),
+                         SUSBCRequest_SetStatusLinesOrQueues,
+                         USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+                         ((dtr != 0) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR),
+                         0,
+                         transfer_buffer,
+                         0,
+                         KOBIL_TIMEOUT);
        } else {
                if (rts != 0)
-                       dbg("%s - port %d Setting RTS", __func__, port->number);
+                       dbg("%s - port %d Setting RTS",
+                                               __func__, port->number);
                else
-                       dbg("%s - port %d Clearing RTS", __func__, port->number);
-               result = usb_control_msg( port->serial->dev, 
-                                         usb_rcvctrlpipe(port->serial->dev, 0 ), 
-                                         SUSBCRequest_SetStatusLinesOrQueues,
-                                         USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
-                                         ((rts != 0) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS),
-                                         0,
-                                         transfer_buffer,
-                                         0,
-                                         KOBIL_TIMEOUT);
+                       dbg("%s - port %d Clearing RTS",
+                                               __func__, port->number);
+               result = usb_control_msg(port->serial->dev,
+                       usb_rcvctrlpipe(port->serial->dev, 0),
+                       SUSBCRequest_SetStatusLinesOrQueues,
+                       USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+                       ((rts != 0) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS),
+                       0,
+                       transfer_buffer,
+                       0,
+                       KOBIL_TIMEOUT);
        }
-       dbg("%s - port %d Send set_status_line URB returns: %i", __func__, port->number, result);
+       dbg("%s - port %d Send set_status_line URB returns: %i",
+                                       __func__, port->number, result);
        kfree(transfer_buffer);
        return (result < 0) ? result : 0;
 }
 
-static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old)
+static void kobil_set_termios(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct ktermios *old)
 {
-       struct kobil_private * priv;
+       struct kobil_private *priv;
        int result;
        unsigned short urb_val = 0;
-       int c_cflag = port->tty->termios->c_cflag;
+       int c_cflag = tty->termios->c_cflag;
        speed_t speed;
-       void * settings;
+       void *settings;
 
        priv = usb_get_serial_port_data(port);
-       if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
-               // This device doesn't support ioctl calls
+       if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
+                       priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
+               /* This device doesn't support ioctl calls */
+               *tty->termios = *old;
                return;
+       }
 
-       switch (speed = tty_get_baud_rate(port->tty)) {
-               case 1200:
-                       urb_val = SUSBCR_SBR_1200;
-                       break;
-               default:
-                       speed = 9600;
-               case 9600:
-                       urb_val = SUSBCR_SBR_9600;
-                       break;
+       speed = tty_get_baud_rate(tty);
+       switch (speed) {
+       case 1200:
+               urb_val = SUSBCR_SBR_1200;
+               break;
+       default:
+               speed = 9600;
+       case 9600:
+               urb_val = SUSBCR_SBR_9600;
+               break;
        }
-       urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit;
+       urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits :
+                                                       SUSBCR_SPASB_1StopBit;
 
        settings = kzalloc(50, GFP_KERNEL);
-       if (! settings)
+       if (!settings)
                return;
 
        sprintf(settings, "%d ", speed);
@@ -634,66 +678,69 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old
                urb_val |= SUSBCR_SPASB_NoParity;
                strcat(settings, "No Parity");
        }
-       port->tty->termios->c_cflag &= ~CMSPAR;
-       tty_encode_baud_rate(port->tty, speed, speed);
-
-       result = usb_control_msg( port->serial->dev,
-                                 usb_rcvctrlpipe(port->serial->dev, 0 ),
-                                 SUSBCRequest_SetBaudRateParityAndStopBits,
-                                 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
-                                 urb_val,
-                                 0,
-                                 settings,
-                                 0,
-                                 KOBIL_TIMEOUT
+       tty->termios->c_cflag &= ~CMSPAR;
+       tty_encode_baud_rate(tty, speed, speed);
+
+       result = usb_control_msg(port->serial->dev,
+                 usb_rcvctrlpipe(port->serial->dev, 0),
+                 SUSBCRequest_SetBaudRateParityAndStopBits,
+                 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+                 urb_val,
+                 0,
+                 settings,
+                 0,
+                 KOBIL_TIMEOUT
                );
        kfree(settings);
 }
 
-static int kobil_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
+static int kobil_ioctl(struct tty_struct *tty, struct file *file,
+                                       unsigned int cmd, unsigned long arg)
 {
-       struct kobil_private * priv = usb_get_serial_port_data(port);
+       struct usb_serial_port *port = tty->driver_data;
+       struct kobil_private *priv = usb_get_serial_port_data(port);
        unsigned char *transfer_buffer;
        int transfer_buffer_length = 8;
        int result;
 
-       if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
-               // This device doesn't support ioctl calls
-               return 0;
+       if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
+                       priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
+               /* This device doesn't support ioctl calls */
+               return -ENOIOCTLCMD;
 
        switch (cmd) {
-       case TCFLSH:   // 0x540B
+       case TCFLSH:
                transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL);
-               if (! transfer_buffer)
-                       return -ENOBUFS;
-
-               result = usb_control_msg( port->serial->dev, 
-                                         usb_rcvctrlpipe(port->serial->dev, 0 ), 
-                                         SUSBCRequest_Misc,
-                                         USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
-                                         SUSBCR_MSC_ResetAllQueues,
-                                         0,
-                                         NULL,//transfer_buffer,
-                                         0,
-                                         KOBIL_TIMEOUT
+               if (!transfer_buffer)
+                       return -ENOBUFS;
+
+               result = usb_control_msg(port->serial->dev,
+                         usb_rcvctrlpipe(port->serial->dev, 0),
+                         SUSBCRequest_Misc,
+                         USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+                         SUSBCR_MSC_ResetAllQueues,
+                         0,
+                         NULL, /* transfer_buffer, */
+                         0,
+                         KOBIL_TIMEOUT
                        );
-               
+
                dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __func__, port->number, result);
                kfree(transfer_buffer);
-               return (result < 0) ? -EFAULT : 0;
+               return (result < 0) ? -EIO: 0;
        default:
                return -ENOIOCTLCMD;
        }
 }
 
-static int __init kobil_init (void)
+static int __init kobil_init(void)
 {
        int retval;
        retval = usb_serial_register(&kobil_device);
        if (retval)
                goto failed_usb_serial_register;
        retval = usb_register(&kobil_driver);
-       if (retval) 
+       if (retval)
                goto failed_usb_register;
 
        info(DRIVER_VERSION " " DRIVER_AUTHOR);
@@ -707,18 +754,18 @@ failed_usb_serial_register:
 }
 
 
-static void __exit kobil_exit (void)
+static void __exit kobil_exit(void)
 {
-       usb_deregister (&kobil_driver);
-       usb_serial_deregister (&kobil_device);
+       usb_deregister(&kobil_driver);
+       usb_serial_deregister(&kobil_device);
 }
 
 module_init(kobil_init);
 module_exit(kobil_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_LICENSE( "GPL" );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
index 5fc2cef30e39f76603421616b3e4a06c9cebd586..0ded8bd6ec8546a9ff694b2e002ab4b2b6f3758e 100644 (file)
  *   - Fixed an endianess problem with the baudrate selection for PowerPC.
  *
  * 06-Dec-2001 Martin Hamilton <martinh@gnu.org>
- *     Added support for the Belkin F5U109 DB9 adaptor
+ *   - Added support for the Belkin F5U109 DB9 adaptor
  *
  * 30-May-2001 Greg Kroah-Hartman
- *     switched from using spinlock to a semaphore, which fixes lots of problems.
+ *   - switched from using spinlock to a semaphore, which fixes lots of
+ *     problems.
  *
  * 04-May-2001 Stelian Pop
  *   - Set the maximum bulk output size for Sitecom U232-P25 model to 16 bytes
@@ -49,7 +50,7 @@
  * 08-Apr-2001 gb
  *   - Identify version on module load.
  *
- * 06-Jan-2001 Cornel Ciocirlan 
+ * 06-Jan-2001 Cornel Ciocirlan
  *   - Added support for Sitecom U232-P25 model (Product Id 0x0230)
  *   - Added support for D-Link DU-H3SP USB BAY (Product Id 0x0200)
  *
@@ -59,8 +60,8 @@
  *     (lots of things will change if/when the usb-serial core changes to
  *     handle these issues.
  *
- * 27-Nov-2000 Wolfgang Grandegger
- *   A version for kernel 2.4.0-test10 released to the Linux community 
+ * 27-Nov-2000 Wolfgang Grandegge
+ *   A version for kernel 2.4.0-test10 released to the Linux community
  *   (via linux-usb-devel).
  */
 
@@ -73,7 +74,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include "mct_u232.h"
@@ -90,28 +91,21 @@ static int debug;
 /*
  * Function prototypes
  */
-static int  mct_u232_startup            (struct usb_serial *serial);
-static void mct_u232_shutdown           (struct usb_serial *serial);
-static int  mct_u232_open               (struct usb_serial_port *port,
-                                         struct file *filp);
-static void mct_u232_close              (struct usb_serial_port *port,
-                                         struct file *filp);
-static void mct_u232_read_int_callback   (struct urb *urb);
-static void mct_u232_set_termios         (struct usb_serial_port *port,
-                                         struct ktermios * old);
-static int  mct_u232_ioctl              (struct usb_serial_port *port,
-                                         struct file * file,
-                                         unsigned int cmd,
-                                         unsigned long arg);
-static void mct_u232_break_ctl          (struct usb_serial_port *port,
-                                         int break_state );
-static int  mct_u232_tiocmget           (struct usb_serial_port *port,
-                                         struct file *file);
-static int  mct_u232_tiocmset           (struct usb_serial_port *port,
-                                         struct file *file, unsigned int set,
-                                         unsigned int clear);
-static void mct_u232_throttle           (struct usb_serial_port *port);
-static void mct_u232_unthrottle                 (struct usb_serial_port *port);
+static int  mct_u232_startup(struct usb_serial *serial);
+static void mct_u232_shutdown(struct usb_serial *serial);
+static int  mct_u232_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static void mct_u232_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static void mct_u232_read_int_callback(struct urb *urb);
+static void mct_u232_set_termios(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct ktermios *old);
+static void mct_u232_break_ctl(struct tty_struct *tty, int break_state);
+static int  mct_u232_tiocmget(struct tty_struct *tty, struct file *file);
+static int  mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
+                       unsigned int set, unsigned int clear);
+static void mct_u232_throttle(struct tty_struct *tty);
+static void mct_u232_unthrottle(struct tty_struct *tty);
 
 
 /*
@@ -125,7 +119,7 @@ static struct usb_device_id id_table_combined [] = {
        { }             /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
 
 static struct usb_driver mct_u232_driver = {
        .name =         "mct_u232",
@@ -149,7 +143,6 @@ static struct usb_serial_driver mct_u232_device = {
        .throttle =          mct_u232_throttle,
        .unthrottle =        mct_u232_unthrottle,
        .read_int_callback = mct_u232_read_int_callback,
-       .ioctl =             mct_u232_ioctl,
        .set_termios =       mct_u232_set_termios,
        .break_ctl =         mct_u232_break_ctl,
        .tiocmget =          mct_u232_tiocmget,
@@ -180,23 +173,34 @@ struct mct_u232_private {
  * Later day 2.6.0-test kernels have new baud rates like B230400 which
  * we do not know how to support. We ignore them for the moment.
  */
-static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value, speed_t *result)
+static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
+                                       speed_t value, speed_t *result)
 {
        *result = value;
 
        if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID
-         || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
+               || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) {
                switch (value) {
-               case    300: return 0x01;
-               case    600: return 0x02; /* this one not tested */
-               case   1200: return 0x03;
-               case   2400: return 0x04;
-               case   4800: return 0x06;
-               case   9600: return 0x08;
-               case  19200: return 0x09;
-               case  38400: return 0x0a;
-               case  57600: return 0x0b;
-               case 115200: return 0x0c;
+               case 300:
+                       return 0x01;
+               case 600:
+                       return 0x02; /* this one not tested */
+               case 1200:
+                       return 0x03;
+               case 2400:
+                       return 0x04;
+               case 4800:
+                       return 0x06;
+               case 9600:
+                       return 0x08;
+               case 19200:
+                       return 0x09;
+               case 38400:
+                       return 0x0a;
+               case 57600:
+                       return 0x0b;
+               case 115200:
+                       return 0x0c;
                default:
                        *result = 9600;
                        return 0x08;
@@ -224,26 +228,27 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value
        }
 }
 
-static int mct_u232_set_baud_rate(struct usb_serial *serial, struct usb_serial_port *port,
-                                 speed_t value)
+static int mct_u232_set_baud_rate(struct tty_struct *tty,
+       struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
 {
        __le32 divisor;
-        int rc;
-        unsigned char zero_byte = 0;
-        unsigned char cts_enable_byte = 0;
-        speed_t speed;
-
-       divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value, &speed));
-
-        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                             MCT_U232_SET_BAUD_RATE_REQUEST,
-                            MCT_U232_SET_REQUEST_TYPE,
-                             0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE,
-                            WDR_TIMEOUT);
+       int rc;
+       unsigned char zero_byte = 0;
+       unsigned char cts_enable_byte = 0;
+       speed_t speed;
+
+       divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value,
+                                                               &speed));
+
+       rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+                               MCT_U232_SET_BAUD_RATE_REQUEST,
+                               MCT_U232_SET_REQUEST_TYPE,
+                               0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE,
+                               WDR_TIMEOUT);
        if (rc < 0)     /*FIXME: What value speed results */
                err("Set BAUD RATE %d failed (error = %d)", value, rc);
        else
-               tty_encode_baud_rate(port->tty, speed, speed);
+               tty_encode_baud_rate(tty, speed, speed);
        dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor);
 
        /* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
@@ -258,55 +263,55 @@ static int mct_u232_set_baud_rate(struct usb_serial *serial, struct usb_serial_p
           whether data will be transmitted to a device which is not asserting
           the 'CTS' signal.  If the second message's data byte is zero, data
           will be transmitted even if 'CTS' is not asserted (i.e. no hardware
-          flow control).  if the second message's data byte is nonzero (a value
-          of 1 is used by this driver), data will not be transmitted to a device
-          which is not asserting 'CTS'.
+          flow control).  if the second message's data byte is nonzero (a
+          value of 1 is used by this driver), data will not be transmitted to
+          a device which is not asserting 'CTS'.
        */
 
        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                            MCT_U232_SET_UNKNOWN1_REQUEST, 
-                            MCT_U232_SET_REQUEST_TYPE,
-                            0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE, 
-                            WDR_TIMEOUT);
+                               MCT_U232_SET_UNKNOWN1_REQUEST,
+                               MCT_U232_SET_REQUEST_TYPE,
+                               0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE,
+                               WDR_TIMEOUT);
        if (rc < 0)
-               err("Sending USB device request code %d failed (error = %d)", 
+               err("Sending USB device request code %d failed (error = %d)",
                    MCT_U232_SET_UNKNOWN1_REQUEST, rc);
 
-       if (port && C_CRTSCTS(port->tty)) {
+       if (port && C_CRTSCTS(tty))
           cts_enable_byte = 1;
-       }
 
-        dbg("set_baud_rate: send second control message, data = %02X", cts_enable_byte);
+       dbg("set_baud_rate: send second control message, data = %02X",
+                                                       cts_enable_byte);
        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                            MCT_U232_SET_CTS_REQUEST,
-                            MCT_U232_SET_REQUEST_TYPE,
-                            0, 0, &cts_enable_byte, MCT_U232_SET_CTS_SIZE,
-                            WDR_TIMEOUT);
+                       MCT_U232_SET_CTS_REQUEST,
+                       MCT_U232_SET_REQUEST_TYPE,
+                       0, 0, &cts_enable_byte, MCT_U232_SET_CTS_SIZE,
+                       WDR_TIMEOUT);
        if (rc < 0)
-         err("Sending USB device request code %d failed (error = %d)",
-             MCT_U232_SET_CTS_REQUEST, rc);
+               err("Sending USB device request code %d failed (error = %d)",
+                                       MCT_U232_SET_CTS_REQUEST, rc);
 
-        return rc;
+       return rc;
 } /* mct_u232_set_baud_rate */
 
 static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr)
 {
-        int rc;
-        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                             MCT_U232_SET_LINE_CTRL_REQUEST,
-                            MCT_U232_SET_REQUEST_TYPE,
-                             0, 0, &lcr, MCT_U232_SET_LINE_CTRL_SIZE,
-                            WDR_TIMEOUT);
+       int rc;
+       rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+                       MCT_U232_SET_LINE_CTRL_REQUEST,
+                       MCT_U232_SET_REQUEST_TYPE,
+                       0, 0, &lcr, MCT_U232_SET_LINE_CTRL_SIZE,
+                       WDR_TIMEOUT);
        if (rc < 0)
                err("Set LINE CTRL 0x%x failed (error = %d)", lcr, rc);
        dbg("set_line_ctrl: 0x%x", lcr);
-        return rc;
+       return rc;
 } /* mct_u232_set_line_ctrl */
 
 static int mct_u232_set_modem_ctrl(struct usb_serial *serial,
                                   unsigned int control_state)
 {
-        int rc;
+       int rc;
        unsigned char mcr = MCT_U232_MCR_NONE;
 
        if (control_state & TIOCM_DTR)
@@ -314,37 +319,39 @@ static int mct_u232_set_modem_ctrl(struct usb_serial *serial,
        if (control_state & TIOCM_RTS)
                mcr |= MCT_U232_MCR_RTS;
 
-        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                             MCT_U232_SET_MODEM_CTRL_REQUEST,
-                            MCT_U232_SET_REQUEST_TYPE,
-                             0, 0, &mcr, MCT_U232_SET_MODEM_CTRL_SIZE,
-                            WDR_TIMEOUT);
+       rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+                       MCT_U232_SET_MODEM_CTRL_REQUEST,
+                       MCT_U232_SET_REQUEST_TYPE,
+                       0, 0, &mcr, MCT_U232_SET_MODEM_CTRL_SIZE,
+                       WDR_TIMEOUT);
        if (rc < 0)
                err("Set MODEM CTRL 0x%x failed (error = %d)", mcr, rc);
        dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr);
 
-        return rc;
+       return rc;
 } /* mct_u232_set_modem_ctrl */
 
-static int mct_u232_get_modem_stat(struct usb_serial *serial, unsigned char *msr)
+static int mct_u232_get_modem_stat(struct usb_serial *serial,
+                                               unsigned char *msr)
 {
-        int rc;
-        rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-                             MCT_U232_GET_MODEM_STAT_REQUEST,
-                            MCT_U232_GET_REQUEST_TYPE,
-                             0, 0, msr, MCT_U232_GET_MODEM_STAT_SIZE,
-                            WDR_TIMEOUT);
+       int rc;
+       rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                       MCT_U232_GET_MODEM_STAT_REQUEST,
+                       MCT_U232_GET_REQUEST_TYPE,
+                       0, 0, msr, MCT_U232_GET_MODEM_STAT_SIZE,
+                       WDR_TIMEOUT);
        if (rc < 0) {
                err("Get MODEM STATus failed (error = %d)", rc);
                *msr = 0;
        }
        dbg("get_modem_stat: 0x%x", *msr);
-        return rc;
+       return rc;
 } /* mct_u232_get_modem_stat */
 
-static void mct_u232_msr_to_state(unsigned int *control_state, unsigned char msr)
+static void mct_u232_msr_to_state(unsigned int *control_state,
+                                               unsigned char msr)
 {
-       /* Translate Control Line states */
+       /* Translate Control Line states */
        if (msr & MCT_U232_MSR_DSR)
                *control_state |=  TIOCM_DSR;
        else
@@ -361,14 +368,14 @@ static void mct_u232_msr_to_state(unsigned int *control_state, unsigned char msr
                *control_state |=  TIOCM_CD;
        else
                *control_state &= ~TIOCM_CD;
-       dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state);
+       dbg("msr_to_state: msr=0x%x ==> state=0x%x", msr, *control_state);
 } /* mct_u232_msr_to_state */
 
 /*
  * Driver's tty interface functions
  */
 
-static int mct_u232_startup (struct usb_serial *serial)
+static int mct_u232_startup(struct usb_serial *serial)
 {
        struct mct_u232_private *priv;
        struct usb_serial_port *port, *rport;
@@ -390,18 +397,18 @@ static int mct_u232_startup (struct usb_serial *serial)
        rport->interrupt_in_urb = NULL;
        port->read_urb->context = port;
 
-       return (0);
+       return 0;
 } /* mct_u232_startup */
 
 
-static void mct_u232_shutdown (struct usb_serial *serial)
+static void mct_u232_shutdown(struct usb_serial *serial)
 {
        struct mct_u232_private *priv;
        int i;
-       
+
        dbg("%s", __func__);
 
-       for (i=0; i < serial->num_ports; ++i) {
+       for (i = 0; i < serial->num_ports; ++i) {
                /* My special items, the standard routines free my urbs */
                priv = usb_get_serial_port_data(serial->port[i]);
                if (priv) {
@@ -411,7 +418,8 @@ static void mct_u232_shutdown (struct usb_serial *serial)
        }
 } /* mct_u232_shutdown */
 
-static int  mct_u232_open (struct usb_serial_port *port, struct file *filp)
+static int  mct_u232_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial = port->serial;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
@@ -428,21 +436,22 @@ static int  mct_u232_open (struct usb_serial_port *port, struct file *filp)
         * it seems to be able to accept only 16 bytes (and that's what
         * SniffUSB says too...)
         */
-       if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID)
+       if (le16_to_cpu(serial->dev->descriptor.idProduct)
+                                               == MCT_U232_SITECOM_PID)
                port->bulk_out_size = 16;
 
-       /* Do a defined restart: the normal serial device seems to 
+       /* Do a defined restart: the normal serial device seems to
         * always turn on DTR and RTS here, so do the same. I'm not
         * sure if this is really necessary. But it should not harm
         * either.
         */
        spin_lock_irqsave(&priv->lock, flags);
-       if (port->tty->termios->c_cflag & CBAUD)
+       if (tty && (tty->termios->c_cflag & CBAUD))
                priv->control_state = TIOCM_DTR | TIOCM_RTS;
        else
                priv->control_state = 0;
-       
-       priv->last_lcr = (MCT_U232_DATA_BITS_8 | 
+
+       priv->last_lcr = (MCT_U232_DATA_BITS_8 |
                          MCT_U232_PARITY_NONE |
                          MCT_U232_STOP_BITS_1);
        control_state = priv->control_state;
@@ -481,15 +490,16 @@ error:
 } /* mct_u232_open */
 
 
-static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
+static void mct_u232_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        unsigned int c_cflag;
        unsigned int control_state;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
        dbg("%s port %d", __func__, port->number);
 
-       if (port->tty) {
-               c_cflag = port->tty->termios->c_cflag;
+       if (tty) {
+               c_cflag = tty->termios->c_cflag;
                mutex_lock(&port->serial->disc_mutex);
                if (c_cflag & HUPCL && !port->serial->disconnected) {
                        /* drop DTR and RTS */
@@ -512,7 +522,7 @@ static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
 } /* mct_u232_close */
 
 
-static void mct_u232_read_int_callback (struct urb *urb)
+static void mct_u232_read_int_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
@@ -545,36 +555,34 @@ static void mct_u232_read_int_callback (struct urb *urb)
                return;
        }
 
-        dbg("%s - port %d", __func__, port->number);
-       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+       dbg("%s - port %d", __func__, port->number);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                                       urb->actual_length, data);
 
        /*
         * Work-a-round: handle the 'usual' bulk-in pipe here
         */
        if (urb->transfer_buffer_length > 2) {
-               int i;
-               tty = port->tty;
+               tty = port->port.tty;
                if (urb->actual_length) {
-                       for (i = 0; i < urb->actual_length ; ++i) {
-                               tty_insert_flip_char(tty, data[i], 0);
-                       }
+                       tty_insert_flip_string(tty, data, urb->actual_length);
                        tty_flip_buffer_push(tty);
                }
                goto exit;
        }
-       
+
        /*
         * The interrupt-in pipe signals exceptional conditions (modem line
         * signal changes and errors). data[0] holds MSR, data[1] holds LSR.
         */
        spin_lock_irqsave(&priv->lock, flags);
        priv->last_msr = data[MCT_U232_MSR_INDEX];
-       
+
        /* Record Control Line states */
        mct_u232_msr_to_state(&priv->control_state, priv->last_msr);
 
 #if 0
-       /* Not yet handled. See belin_sa.c for further information */
+       /* Not yet handled. See belkin_sa.c for further information */
        /* Now to report any errors */
        priv->last_lsr = data[MCT_U232_LSR_INDEX];
        /*
@@ -583,7 +591,7 @@ static void mct_u232_read_int_callback (struct urb *urb)
         * to look in to this before committing any code.
         */
        if (priv->last_lsr & MCT_U232_LSR_ERR) {
-               tty = port->tty;
+               tty = port->port.tty;
                /* Overrun Error */
                if (priv->last_lsr & MCT_U232_LSR_OE) {
                }
@@ -600,18 +608,19 @@ static void mct_u232_read_int_callback (struct urb *urb)
 #endif
        spin_unlock_irqrestore(&priv->lock, flags);
 exit:
-       retval = usb_submit_urb (urb, GFP_ATOMIC);
+       retval = usb_submit_urb(urb, GFP_ATOMIC);
        if (retval)
-               err ("%s - usb_submit_urb failed with result %d",
+               err("%s - usb_submit_urb failed with result %d",
                     __func__, retval);
 } /* mct_u232_read_int_callback */
 
-static void mct_u232_set_termios (struct usb_serial_port *port,
-                                 struct ktermios *old_termios)
+static void mct_u232_set_termios(struct tty_struct *tty,
+                                struct usb_serial_port *port,
+                                struct ktermios *old_termios)
 {
        struct usb_serial *serial = port->serial;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
-       struct ktermios *termios = port->tty->termios;
+       struct ktermios *termios = tty->termios;
        unsigned int cflag = termios->c_cflag;
        unsigned int old_cflag = old_termios->c_cflag;
        unsigned long flags;
@@ -631,20 +640,20 @@ static void mct_u232_set_termios (struct usb_serial_port *port,
         * Premature optimization is the root of all evil.
         */
 
-        /* reassert DTR and RTS on transition from B0 */
+       /* reassert DTR and RTS on transition from B0 */
        if ((old_cflag & CBAUD) == B0) {
                dbg("%s: baud was B0", __func__);
                control_state |= TIOCM_DTR | TIOCM_RTS;
                mct_u232_set_modem_ctrl(serial, control_state);
        }
 
-       mct_u232_set_baud_rate(serial, port, tty_get_baud_rate(port->tty));
+       mct_u232_set_baud_rate(tty, serial, port, tty_get_baud_rate(tty));
 
-       if ((cflag & CBAUD) == B0 ) {
+       if ((cflag & CBAUD) == B0) {
                dbg("%s: baud is B0", __func__);
                /* Drop RTS and DTR */
                control_state &= ~(TIOCM_DTR | TIOCM_RTS);
-                       mct_u232_set_modem_ctrl(serial, control_state);
+               mct_u232_set_modem_ctrl(serial, control_state);
        }
 
        /*
@@ -689,8 +698,9 @@ static void mct_u232_set_termios (struct usb_serial_port *port,
        spin_unlock_irqrestore(&priv->lock, flags);
 } /* mct_u232_set_termios */
 
-static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state )
+static void mct_u232_break_ctl(struct tty_struct *tty, int break_state)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
        unsigned char lcr;
@@ -709,12 +719,13 @@ static void mct_u232_break_ctl( struct usb_serial_port *port, int break_state )
 } /* mct_u232_break_ctl */
 
 
-static int mct_u232_tiocmget (struct usb_serial_port *port, struct file *file)
+static int mct_u232_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
        unsigned int control_state;
        unsigned long flags;
-       
+
        dbg("%s", __func__);
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -724,14 +735,15 @@ static int mct_u232_tiocmget (struct usb_serial_port *port, struct file *file)
        return control_state;
 }
 
-static int mct_u232_tiocmset (struct usb_serial_port *port, struct file *file,
+static int mct_u232_tiocmset(struct tty_struct *tty, struct file *file,
                              unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
        unsigned int control_state;
        unsigned long flags;
-       
+
        dbg("%s", __func__);
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -751,77 +763,50 @@ static int mct_u232_tiocmset (struct usb_serial_port *port, struct file *file,
        return mct_u232_set_modem_ctrl(serial, control_state);
 }
 
-static int mct_u232_ioctl (struct usb_serial_port *port, struct file * file,
-                          unsigned int cmd, unsigned long arg)
-{
-       dbg("%scmd=0x%x", __func__, cmd);
-
-       /* Based on code from acm.c and others */
-       switch (cmd) {
-       case TIOCMIWAIT:
-               /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
-               /* TODO */
-               return( 0 );
-
-       case TIOCGICOUNT:
-               /* return count of modemline transitions */
-               /* TODO */
-               return 0;
-
-       default:
-               dbg("%s: arg not supported - 0x%04x", __func__,cmd);
-               return(-ENOIOCTLCMD);
-               break;
-       }
-       return 0;
-} /* mct_u232_ioctl */
-
-static void mct_u232_throttle (struct usb_serial_port *port)
+static void mct_u232_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        unsigned int control_state;
-       struct tty_struct *tty;
 
-       tty = port->tty;
        dbg("%s - port %d", __func__, port->number);
 
        spin_lock_irqsave(&priv->lock, flags);
        priv->rx_flags |= THROTTLED;
        if (C_CRTSCTS(tty)) {
-         priv->control_state &= ~TIOCM_RTS;
-         control_state = priv->control_state;
-         spin_unlock_irqrestore(&priv->lock, flags);
-         (void) mct_u232_set_modem_ctrl(port->serial, control_state);
+               priv->control_state &= ~TIOCM_RTS;
+               control_state = priv->control_state;
+               spin_unlock_irqrestore(&priv->lock, flags);
+               (void) mct_u232_set_modem_ctrl(port->serial, control_state);
        } else {
-         spin_unlock_irqrestore(&priv->lock, flags);
+               spin_unlock_irqrestore(&priv->lock, flags);
        }
 }
 
 
-static void mct_u232_unthrottle (struct usb_serial_port *port)
+static void mct_u232_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        unsigned int control_state;
-       struct tty_struct *tty;
 
        dbg("%s - port %d", __func__, port->number);
 
-       tty = port->tty;
        spin_lock_irqsave(&priv->lock, flags);
        if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
-         priv->rx_flags &= ~THROTTLED;
-         priv->control_state |= TIOCM_RTS;
-         control_state = priv->control_state;
-         spin_unlock_irqrestore(&priv->lock, flags);
-         (void) mct_u232_set_modem_ctrl(port->serial, control_state);
+               priv->rx_flags &= ~THROTTLED;
+               priv->control_state |= TIOCM_RTS;
+               control_state = priv->control_state;
+               spin_unlock_irqrestore(&priv->lock, flags);
+               (void) mct_u232_set_modem_ctrl(port->serial, control_state);
        } else {
-         spin_unlock_irqrestore(&priv->lock, flags);
+               spin_unlock_irqrestore(&priv->lock, flags);
        }
 }
 
-static int __init mct_u232_init (void)
+static int __init mct_u232_init(void)
 {
        int retval;
        retval = usb_serial_register(&mct_u232_device);
@@ -839,18 +824,17 @@ failed_usb_serial_register:
 }
 
 
-static void __exit mct_u232_exit (void)
+static void __exit mct_u232_exit(void)
 {
-       usb_deregister (&mct_u232_driver);
-       usb_serial_deregister (&mct_u232_device);
+       usb_deregister(&mct_u232_driver);
+       usb_serial_deregister(&mct_u232_device);
 }
 
-
-module_init (mct_u232_init);
+module_init(mct_u232_init);
 module_exit(mct_u232_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
index 50f1fe263338dc5fb736a4c8024ddd1afb4fb765..7c4917d77c0a4bf5583ddb53806dae79cb308f9b 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/serial_reg.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 
 /*
@@ -64,8 +64,7 @@
 #define URB_TRANSFER_BUFFER_SIZE       32      /* URB Size */
 
 /* This structure holds all of the local port information */
-struct moschip_port
-{
+struct moschip_port {
        __u8    shadowLCR;              /* last LCR value received */
        __u8    shadowMCR;              /* last MCR value received */
        __u8    shadowMSR;              /* last MSR value received */
@@ -76,8 +75,7 @@ struct moschip_port
 };
 
 /* This structure holds all of the individual serial device information */
-struct moschip_serial
-{
+struct moschip_serial {
        int interrupt_started;
 };
 
@@ -88,7 +86,7 @@ static int debug;
 #define MOSCHIP_DEVICE_ID_7715         0x7715
 
 static struct usb_device_id moschip_port_id_table [] = {
-       { USB_DEVICE(USB_VENDOR_ID_MOSCHIP,MOSCHIP_DEVICE_ID_7720) },
+       { USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7720) },
        { } /* terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, moschip_port_id_table);
@@ -108,7 +106,7 @@ static void mos7720_interrupt_callback(struct urb *urb)
        __u8 sp1;
        __u8 sp2;
 
-       dbg("%s"," : Entering\n");
+       dbg("%s", " : Entering\n");
 
        switch (status) {
        case 0:
@@ -208,7 +206,7 @@ static void mos7720_bulk_in_callback(struct urb *urb)
 
        mos7720_port = urb->context;
        if (!mos7720_port) {
-               dbg("%s","NULL mos7720_port pointer \n");
+               dbg("%s", "NULL mos7720_port pointer \n");
                return ;
        }
 
@@ -218,7 +216,7 @@ static void mos7720_bulk_in_callback(struct urb *urb)
 
        data = urb->transfer_buffer;
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (tty && urb->actual_length) {
                tty_buffer_request_room(tty, urb->actual_length);
                tty_insert_flip_string(tty, data, urb->actual_length);
@@ -264,7 +262,7 @@ static void mos7720_bulk_out_data_callback(struct urb *urb)
 
        dbg("Entering .........");
 
-       tty = mos7720_port->port->tty;
+       tty = mos7720_port->port->port.tty;
 
        if (tty && mos7720_port->open)
                tty_wakeup(tty);
@@ -284,17 +282,16 @@ static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value,
        __u16 size = 0x0000;
 
        if (value < MOS_MAX_PORT) {
-               if (product == MOSCHIP_DEVICE_ID_7715) {
+               if (product == MOSCHIP_DEVICE_ID_7715)
                        value = value*0x100+0x100;
-               } else {
+               else
                        value = value*0x100+0x200;
-               }
        } else {
                value = 0x0000;
                if ((product == MOSCHIP_DEVICE_ID_7715) &&
                    (index != 0x08)) {
                        dbg("serial->product== MOSCHIP_DEVICE_ID_7715");
-                       //index = 0x01 ;
+                       /* index = 0x01 ; */
                }
        }
 
@@ -308,19 +305,20 @@ static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value,
                request = (__u8)MOS_READ;
                requesttype = (__u8)0xC0;
                size = 0x01;
-               pipe = usb_rcvctrlpipe(serial->dev,0);
+               pipe = usb_rcvctrlpipe(serial->dev, 0);
        }
 
        status = usb_control_msg(serial->dev, pipe, request, requesttype,
                                 value, index, data, size, MOS_WDR_TIMEOUT);
 
        if (status < 0)
-               dbg("Command Write failed Value %x index %x\n",value,index);
+               dbg("Command Write failed Value %x index %x\n", value, index);
 
        return status;
 }
 
-static int mos7720_open(struct usb_serial_port *port, struct file * filp)
+static int mos7720_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial;
        struct usb_serial_port *port0;
@@ -351,7 +349,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
 
        /* Initialising the write urb pool */
        for (j = 0; j < NUM_URBS; ++j) {
-               urb = usb_alloc_urb(0,GFP_KERNEL);
+               urb = usb_alloc_urb(0, GFP_KERNEL);
                mos7720_port->write_urb_pool[j] = urb;
 
                if (urb == NULL) {
@@ -385,7 +383,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
          */
        port_number = port->number - port->serial->minor;
        send_mos_cmd(port->serial, MOS_READ, port_number, UART_LSR, &data);
-       dbg("SS::%p LSR:%x\n",mos7720_port, data);
+       dbg("SS::%p LSR:%x\n", mos7720_port, data);
 
        dbg("Check:Sending Command ..........");
 
@@ -402,10 +400,10 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
        data = 0xCF;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data);
        data = 0x03;
-        mos7720_port->shadowLCR  = data;
+       mos7720_port->shadowLCR  = data;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
        data = 0x0b;
-        mos7720_port->shadowMCR  = data;
+       mos7720_port->shadowMCR  = data;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
        data = 0x0b;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
@@ -420,7 +418,8 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
        data = 0x03;
        send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
        data = 0x00;
-       send_mos_cmd(port->serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
+       send_mos_cmd(port->serial, MOS_WRITE, MOS_MAX_PORT,
+                                               port_number + 1, &data);
 */
        data = 0x00;
        send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
@@ -429,28 +428,26 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
        send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
 
        data = 0x83;
-        mos7720_port->shadowLCR  = data;
+       mos7720_port->shadowLCR  = data;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
        data = 0x0c;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data);
        data = 0x00;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
        data = 0x03;
-        mos7720_port->shadowLCR  = data;
+       mos7720_port->shadowLCR  = data;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
        data = 0x0c;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
        data = 0x0c;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
 
-//Matrix
-
        /* force low_latency on so that our tty_push actually forces *
         * the data through,otherwise it is scheduled, and with      *
         * high data rates (like with OHCI) data can get lost.       */
 
-       if (port->tty)
-               port->tty->low_latency = 1;
+       if (tty)
+               tty->low_latency = 1;
 
        /* see if we've set up our endpoint info yet   *
         * (can't set it up in mos7720_startup as the  *
@@ -465,15 +462,15 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
 
                /* set up our interrupt urb */
                usb_fill_int_urb(port0->interrupt_in_urb, serial->dev,
-                                usb_rcvintpipe(serial->dev,
-                                               port->interrupt_in_endpointAddress),
-                                port0->interrupt_in_buffer,
-                                port0->interrupt_in_urb->transfer_buffer_length,
-                                mos7720_interrupt_callback, mos7720_port,
-                                port0->interrupt_in_urb->interval);
+                        usb_rcvintpipe(serial->dev,
+                               port->interrupt_in_endpointAddress),
+                        port0->interrupt_in_buffer,
+                        port0->interrupt_in_urb->transfer_buffer_length,
+                        mos7720_interrupt_callback, mos7720_port,
+                        port0->interrupt_in_urb->interval);
 
                /* start interrupt read for this mos7720 this interrupt *
-                * will continue as long as the mos7720 is connected    */
+                * will continue as long as the mos7720 is connected    */
                dbg("Submit URB over !!!");
                response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL);
                if (response)
@@ -485,14 +482,14 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
        /* set up our bulk in urb */
        usb_fill_bulk_urb(port->read_urb, serial->dev,
                          usb_rcvbulkpipe(serial->dev,
-                                         port->bulk_in_endpointAddress),
+                               port->bulk_in_endpointAddress),
                          port->bulk_in_buffer,
                          port->read_urb->transfer_buffer_length,
                          mos7720_bulk_in_callback, mos7720_port);
        response = usb_submit_urb(port->read_urb, GFP_KERNEL);
        if (response)
-               dev_err(&port->dev,
-                       "%s - Error %d submitting read urb\n", __func__, response);
+               dev_err(&port->dev, "%s - Error %d submitting read urb\n",
+                                                       __func__, response);
 
        /* initialize our icount structure */
        memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount));
@@ -515,8 +512,9 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
  *     system,
  *     Otherwise we return a negative error number.
  */
-static int mos7720_chars_in_buffer(struct usb_serial_port *port)
+static int mos7720_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        int i;
        int chars = 0;
        struct moschip_port *mos7720_port;
@@ -530,14 +528,16 @@ static int mos7720_chars_in_buffer(struct usb_serial_port *port)
        }
 
        for (i = 0; i < NUM_URBS; ++i) {
-               if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status == -EINPROGRESS)
+               if (mos7720_port->write_urb_pool[i] &&
+                   mos7720_port->write_urb_pool[i]->status == -EINPROGRESS)
                        chars += URB_TRANSFER_BUFFER_SIZE;
        }
        dbg("%s - returns %d", __func__, chars);
        return chars;
 }
 
-static void mos7720_close(struct usb_serial_port *port, struct file *filp)
+static void mos7720_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial;
        struct moschip_port *mos7720_port;
@@ -575,12 +575,12 @@ static void mos7720_close(struct usb_serial_port *port, struct file *filp)
         * been disconnected */
        if (!serial->disconnected) {
                data = 0x00;
-               send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
-                            0x04, &data);
+               send_mos_cmd(serial, MOS_WRITE,
+                       port->number - port->serial->minor, 0x04, &data);
 
                data = 0x00;
-               send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
-                            0x01, &data);
+               send_mos_cmd(serial, MOS_WRITE,
+                       port->number - port->serial->minor, 0x01, &data);
        }
        mutex_unlock(&serial->disc_mutex);
        mos7720_port->open = 0;
@@ -588,9 +588,10 @@ static void mos7720_close(struct usb_serial_port *port, struct file *filp)
        dbg("Leaving %s", __func__);
 }
 
-static void mos7720_break(struct usb_serial_port *port, int break_state)
+static void mos7720_break(struct tty_struct *tty, int break_state)
 {
-        unsigned char data;
+       struct usb_serial_port *port = tty->driver_data;
+       unsigned char data;
        struct usb_serial *serial;
        struct moschip_port *mos7720_port;
 
@@ -621,8 +622,9 @@ static void mos7720_break(struct usb_serial_port *port, int break_state)
  *     If successful, we return the amount of room that we have for this port
  *     Otherwise we return a negative error number.
  */
-static int mos7720_write_room(struct usb_serial_port *port)
+static int mos7720_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct moschip_port *mos7720_port;
        int room = 0;
        int i;
@@ -637,7 +639,8 @@ static int mos7720_write_room(struct usb_serial_port *port)
 
        /* FIXME: Locking */
        for (i = 0; i < NUM_URBS; ++i) {
-               if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status != -EINPROGRESS)
+               if (mos7720_port->write_urb_pool[i] &&
+                   mos7720_port->write_urb_pool[i]->status != -EINPROGRESS)
                        room += URB_TRANSFER_BUFFER_SIZE;
        }
 
@@ -645,8 +648,8 @@ static int mos7720_write_room(struct usb_serial_port *port)
        return room;
 }
 
-static int mos7720_write(struct usb_serial_port *port,
-                        const unsigned char *data, int count)
+static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                const unsigned char *data, int count)
 {
        int status;
        int i;
@@ -672,9 +675,10 @@ static int mos7720_write(struct usb_serial_port *port,
        urb = NULL;
 
        for (i = 0; i < NUM_URBS; ++i) {
-               if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) {
+               if (mos7720_port->write_urb_pool[i] &&
+                   mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) {
                        urb = mos7720_port->write_urb_pool[i];
-                       dbg("URB:%d",i);
+                       dbg("URB:%d", i);
                        break;
                }
        }
@@ -692,7 +696,7 @@ static int mos7720_write(struct usb_serial_port *port,
                        goto exit;
                }
        }
-       transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE);
+       transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
 
        memcpy(urb->transfer_buffer, current_position, transfer_size);
        usb_serial_debug_data(debug, &port->dev, __func__, transfer_size,
@@ -701,12 +705,12 @@ static int mos7720_write(struct usb_serial_port *port,
        /* fill urb with data and submit  */
        usb_fill_bulk_urb(urb, serial->dev,
                          usb_sndbulkpipe(serial->dev,
-                                         port->bulk_out_endpointAddress),
+                                       port->bulk_out_endpointAddress),
                          urb->transfer_buffer, transfer_size,
                          mos7720_bulk_out_data_callback, mos7720_port);
 
        /* send it down the pipe */
-       status = usb_submit_urb(urb,GFP_ATOMIC);
+       status = usb_submit_urb(urb, GFP_ATOMIC);
        if (status) {
                err("%s - usb_submit_urb(write bulk) failed with status = %d",
                    __func__, status);
@@ -719,10 +723,10 @@ exit:
        return bytes_sent;
 }
 
-static void mos7720_throttle(struct usb_serial_port *port)
+static void mos7720_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct moschip_port *mos7720_port;
-       struct tty_struct *tty;
        int status;
 
        dbg("%s- port %d\n", __func__, port->number);
@@ -739,16 +743,10 @@ static void mos7720_throttle(struct usb_serial_port *port)
 
        dbg("%s: Entering ..........", __func__);
 
-       tty = port->tty;
-       if (!tty) {
-               dbg("%s - no tty available", __func__);
-               return;
-       }
-
        /* if we are implementing XON/XOFF, send the stop character */
        if (I_IXOFF(tty)) {
                unsigned char stop_char = STOP_CHAR(tty);
-               status = mos7720_write(port, &stop_char, 1);
+               status = mos7720_write(tty, port, &stop_char, 1);
                if (status <= 0)
                        return;
        }
@@ -764,11 +762,11 @@ static void mos7720_throttle(struct usb_serial_port *port)
        }
 }
 
-static void mos7720_unthrottle(struct usb_serial_port *port)
+static void mos7720_unthrottle(struct tty_struct *tty)
 {
-       struct tty_struct *tty;
-       int status;
+       struct usb_serial_port *port = tty->driver_data;
        struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
+       int status;
 
        if (mos7720_port == NULL)
                return;
@@ -780,16 +778,10 @@ static void mos7720_unthrottle(struct usb_serial_port *port)
 
        dbg("%s: Entering ..........", __func__);
 
-       tty = port->tty;
-       if (!tty) {
-               dbg("%s - no tty available", __func__);
-               return;
-       }
-
        /* if we are implementing XON/XOFF, send the start character */
        if (I_IXOFF(tty)) {
                unsigned char start_char = START_CHAR(tty);
-               status = mos7720_write(port, &start_char, 1);
+               status = mos7720_write(tty, port, &start_char, 1);
                if (status <= 0)
                        return;
        }
@@ -819,9 +811,9 @@ static int set_higher_rates(struct moschip_port *mos7720_port,
        port = mos7720_port->port;
        serial = port->serial;
 
-        /***********************************************
-         *      Init Sequence for higher rates
-         ***********************************************/
+        /***********************************************
+        *      Init Sequence for higher rates
+        ***********************************************/
        dbg("Sending Setting Commands ..........");
        port_number = port->number - port->serial->minor;
 
@@ -832,7 +824,7 @@ static int set_higher_rates(struct moschip_port *mos7720_port,
        data = 0x0CF;
        send_mos_cmd(serial, MOS_WRITE, port->number, 0x02, &data);
        data = 0x00b;
-        mos7720_port->shadowMCR  = data;
+       mos7720_port->shadowMCR  = data;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
        data = 0x00b;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
@@ -843,12 +835,12 @@ static int set_higher_rates(struct moschip_port *mos7720_port,
        send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
 
 
-        /***********************************************
-         *              Set for higher rates           *
-         ***********************************************/
+       /***********************************************
+        *              Set for higher rates           *
+        ***********************************************/
 
        data = baud * 0x10;
-       send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1,&data);
+       send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
 
        data = 0x003;
        send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
@@ -856,34 +848,33 @@ static int set_higher_rates(struct moschip_port *mos7720_port,
        send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
 
        data = 0x02b;
-        mos7720_port->shadowMCR  = data;
+       mos7720_port->shadowMCR  = data;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
        data = 0x02b;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
 
-        /***********************************************
-         *              Set DLL/DLM
-         ***********************************************/
+       /***********************************************
+        *              Set DLL/DLM
+        ***********************************************/
 
        data = mos7720_port->shadowLCR | UART_LCR_DLAB;
-        mos7720_port->shadowLCR  = data;
+       mos7720_port->shadowLCR  = data;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
 
        data =  0x001; /* DLL */
-        send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data);
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data);
        data =  0x000; /* DLM */
-        send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
 
        data = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
-        mos7720_port->shadowLCR  = data;
+       mos7720_port->shadowLCR  = data;
        send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
 
        return 0;
 }
 
 /* baud rate information */
-struct divisor_table_entry
-{
+struct divisor_table_entry {
        __u32  baudrate;
        __u16  divisor;
 };
@@ -932,8 +923,8 @@ static int calc_baud_rate_divisor(int baudrate, int *divisor)
                }
        }
 
-        /* After trying for all the standard baud rates    *
-         * Try calculating the divisor for this baud rate  */
+       /* After trying for all the standard baud rates    *
+        * Try calculating the divisor for this baud rate  */
        if (baudrate > 75 &&  baudrate < 230400) {
                /* get the divisor */
                custom = (__u16)(230400L  / baudrate);
@@ -945,7 +936,7 @@ static int calc_baud_rate_divisor(int baudrate, int *divisor)
                        custom++;
                *divisor = custom;
 
-               dbg("Baud %d = %d",baudrate, custom);
+               dbg("Baud %d = %d", baudrate, custom);
                return 0;
        }
 
@@ -979,29 +970,29 @@ static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port,
        number = port->number - port->serial->minor;
        dbg("%s - port = %d, baud = %d", __func__, port->number, baudrate);
 
-        /* Calculate the Divisor */
+       /* Calculate the Divisor */
        status = calc_baud_rate_divisor(baudrate, &divisor);
        if (status) {
                err("%s - bad baud rate", __func__);
                return status;
        }
 
-        /* Enable access to divisor latch */
-        data = mos7720_port->shadowLCR | UART_LCR_DLAB;
-        mos7720_port->shadowLCR  = data;
-        send_mos_cmd(serial, MOS_WRITE, number, UART_LCR, &data);
+       /* Enable access to divisor latch */
+       data = mos7720_port->shadowLCR | UART_LCR_DLAB;
+       mos7720_port->shadowLCR  = data;
+       send_mos_cmd(serial, MOS_WRITE, number, UART_LCR, &data);
 
        /* Write the divisor */
        data = ((unsigned char)(divisor & 0xff));
-        send_mos_cmd(serial, MOS_WRITE, number, 0x00, &data);
+       send_mos_cmd(serial, MOS_WRITE, number, 0x00, &data);
 
        data = ((unsigned char)((divisor & 0xff00) >> 8));
-        send_mos_cmd(serial, MOS_WRITE, number, 0x01, &data);
+       send_mos_cmd(serial, MOS_WRITE, number, 0x01, &data);
 
-        /* Disable access to divisor latch */
-        data = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
-        mos7720_port->shadowLCR = data;
-        send_mos_cmd(serial, MOS_WRITE, number, 0x03, &data);
+       /* Disable access to divisor latch */
+       data = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
+       mos7720_port->shadowLCR = data;
+       send_mos_cmd(serial, MOS_WRITE, number, 0x03, &data);
 
        return status;
 }
@@ -1011,12 +1002,12 @@ static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port,
  *     This routine is called to set the UART on the device to match
  *      the specified new settings.
  */
-static void change_port_settings(struct moschip_port *mos7720_port,
+static void change_port_settings(struct tty_struct *tty,
+                                struct moschip_port *mos7720_port,
                                 struct ktermios *old_termios)
 {
        struct usb_serial_port *port;
        struct usb_serial *serial;
-       struct tty_struct *tty;
        int baud;
        unsigned cflag;
        unsigned iflag;
@@ -1042,8 +1033,6 @@ static void change_port_settings(struct moschip_port *mos7720_port,
                return;
        }
 
-       tty = mos7720_port->port->tty;
-
        dbg("%s: Entering ..........", __func__);
 
        lData = UART_LCR_WLEN8;
@@ -1106,29 +1095,31 @@ static void change_port_settings(struct moschip_port *mos7720_port,
 #define LCR_PAR_MASK           0x38    /* Mask for parity field */
 
        /* Update the LCR with the correct value */
-       mos7720_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
+       mos7720_port->shadowLCR &=
+                       ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
        mos7720_port->shadowLCR |= (lData | lParity | lStop);
 
 
        /* Disable Interrupts */
        data = 0x00;
-        send_mos_cmd(serial,MOS_WRITE,port->number - port->serial->minor, UART_IER, &data);
+       send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
+                                                       UART_IER, &data);
 
        data = 0x00;
-        send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
+       send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
 
        data = 0xcf;
-        send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
+       send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
 
        /* Send the updated LCR value to the mos7720 */
        data = mos7720_port->shadowLCR;
-        send_mos_cmd(serial, MOS_WRITE, port_number, UART_LCR, &data);
+       send_mos_cmd(serial, MOS_WRITE, port_number, UART_LCR, &data);
 
-        data = 0x00b;
-        mos7720_port->shadowMCR = data;
-        send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
-        data = 0x00b;
-        send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+       data = 0x00b;
+       mos7720_port->shadowMCR = data;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+       data = 0x00b;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
 
        /* set up the MCR register and send it to the mos7720 */
        mos7720_port->shadowMCR = UART_MCR_OUT2;
@@ -1137,9 +1128,8 @@ static void change_port_settings(struct moschip_port *mos7720_port,
 
        if (cflag & CRTSCTS) {
                mos7720_port->shadowMCR |= (UART_MCR_XONANY);
-
-                /* To set hardware flow control to the specified *
-                 * serial port, in SP1/2_CONTROL_REG             */
+               /* To set hardware flow control to the specified *
+                * serial port, in SP1/2_CONTROL_REG             */
                if (port->number) {
                        data = 0x001;
                        send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT,
@@ -1198,14 +1188,13 @@ static void change_port_settings(struct moschip_port *mos7720_port,
  *     this function is called by the tty driver when it wants to change the
  *     termios structure.
  */
-static void mos7720_set_termios(struct usb_serial_port *port,
-                               struct ktermios *old_termios)
+static void mos7720_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        int status;
        unsigned int cflag;
        struct usb_serial *serial;
        struct moschip_port *mos7720_port;
-       struct tty_struct *tty;
 
        serial = port->serial;
 
@@ -1214,15 +1203,12 @@ static void mos7720_set_termios(struct usb_serial_port *port,
        if (mos7720_port == NULL)
                return;
 
-       tty = port->tty;
-
-
        if (!mos7720_port->open) {
                dbg("%s - port not opened", __func__);
                return;
        }
 
-       dbg("%s\n","setting termios - ASPIRE");
+       dbg("%s\n", "setting termios - ASPIRE");
 
        cflag = tty->termios->c_cflag;
 
@@ -1237,14 +1223,14 @@ static void mos7720_set_termios(struct usb_serial_port *port,
        dbg("%s - port %d", __func__, port->number);
 
        /* change the port settings to the new ones specified */
-       change_port_settings(mos7720_port, old_termios);
+       change_port_settings(tty, mos7720_port, old_termios);
 
-       if(!port->read_urb) {
-               dbg("%s","URB KILLED !!!!!\n");
+       if (!port->read_urb) {
+               dbg("%s", "URB KILLED !!!!!\n");
                return;
        }
 
-       if(port->read_urb->status != -EINPROGRESS) {
+       if (port->read_urb->status != -EINPROGRESS) {
                port->read_urb->dev = serial->dev;
                status = usb_submit_urb(port->read_urb, GFP_ATOMIC);
                if (status)
@@ -1264,13 +1250,13 @@ static void mos7720_set_termios(struct usb_serial_port *port,
  *         transmit holding register is empty.  This functionality
  *         allows an RS485 driver to be written in user space.
  */
-static int get_lsr_info(struct moschip_port *mos7720_port,
-                       unsigned int __user *value)
+static int get_lsr_info(struct tty_struct *tty,
+               struct moschip_port *mos7720_port, unsigned int __user *value)
 {
        int count;
        unsigned int result = 0;
 
-       count = mos7720_chars_in_buffer(mos7720_port->port);
+       count = mos7720_chars_in_buffer(tty);
        if (count == 0) {
                dbg("%s -- Empty", __func__);
                result = TIOCSER_TEMT;
@@ -1290,7 +1276,7 @@ static int get_number_bytes_avail(struct moschip_port *mos7720_port,
                                  unsigned int __user *value)
 {
        unsigned int result = 0;
-       struct tty_struct *tty = mos7720_port->port->tty;
+       struct tty_struct *tty = mos7720_port->port->port.tty;
 
        if (!tty)
                return -ENOIOCTLCMD;
@@ -1316,7 +1302,7 @@ static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd,
        if (mos7720_port == NULL)
                return -1;
 
-       port = (struct usb_serial_port*)mos7720_port->port;
+       port = (struct usb_serial_port *)mos7720_port->port;
        mcr = mos7720_port->shadowMCR;
 
        if (copy_from_user(&arg, value, sizeof(int)))
@@ -1397,7 +1383,7 @@ static int get_serial_info(struct moschip_port *mos7720_port,
        tmp.port                = mos7720_port->port->number;
        tmp.irq                 = 0;
        tmp.flags               = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
-        tmp.xmit_fifo_size     = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
+       tmp.xmit_fifo_size      = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
        tmp.baud_base           = 9600;
        tmp.close_delay         = 5*HZ;
        tmp.closing_wait        = 30*HZ;
@@ -1407,9 +1393,10 @@ static int get_serial_info(struct moschip_port *mos7720_port,
        return 0;
 }
 
-static int mos7720_ioctl(struct usb_serial_port *port, struct file *file,
+static int mos7720_ioctl(struct tty_struct *tty, struct file *file,
                         unsigned int cmd, unsigned long arg)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct moschip_port *mos7720_port;
        struct async_icount cnow;
        struct async_icount cprev;
@@ -1431,14 +1418,16 @@ static int mos7720_ioctl(struct usb_serial_port *port, struct file *file,
 
        case TIOCSERGETLSR:
                dbg("%s (%d) TIOCSERGETLSR", __func__,  port->number);
-               return get_lsr_info(mos7720_port, (unsigned int __user *)arg);
+               return get_lsr_info(tty, mos7720_port,
+                                       (unsigned int __user *)arg);
                return 0;
 
+       /* FIXME: These should be using the mode methods */
        case TIOCMBIS:
        case TIOCMBIC:
        case TIOCMSET:
-               dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __func__,
-                   port->number);
+               dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET",
+                                       __func__, port->number);
                return set_modem_info(mos7720_port, cmd,
                                      (unsigned int __user *)arg);
 
@@ -1452,10 +1441,6 @@ static int mos7720_ioctl(struct usb_serial_port *port, struct file *file,
                return get_serial_info(mos7720_port,
                                       (struct serial_struct __user *)arg);
 
-       case TIOCSSERIAL:
-               dbg("%s (%d) TIOCSSERIAL", __func__,  port->number);
-               break;
-
        case TIOCMIWAIT:
                dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
                cprev = mos7720_port->icount;
@@ -1469,7 +1454,7 @@ static int mos7720_ioctl(struct usb_serial_port *port, struct file *file,
                        if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
                            ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
                            ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
-                           ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+                           ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
                                return 0;
                        }
                        cprev = cnow;
@@ -1492,7 +1477,7 @@ static int mos7720_ioctl(struct usb_serial_port *port, struct file *file,
                icount.buf_overrun = cnow.buf_overrun;
 
                dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
-                   port->number, icount.rx, icount.tx );
+                   port->number, icount.rx, icount.tx);
                if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
                        return -EFAULT;
                return 0;
@@ -1543,7 +1528,8 @@ static int mos7720_startup(struct usb_serial *serial)
                /* Initialize all port interrupt end point to port 0 int
                 * endpoint.  Our device has only one interrupt endpoint
                 * comman to all ports */
-               serial->port[i]->interrupt_in_endpointAddress = serial->port[0]->interrupt_in_endpointAddress;
+               serial->port[i]->interrupt_in_endpointAddress =
+                               serial->port[0]->interrupt_in_endpointAddress;
 
                mos7720_port->port = serial->port[i];
                usb_set_serial_port_data(serial->port[i], mos7720_port);
@@ -1555,13 +1541,15 @@ static int mos7720_startup(struct usb_serial *serial)
 
        /* setting configuration feature to one */
        usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                       (__u8)0x03, 0x00,0x01,0x00, NULL, 0x00, 5*HZ);
+                       (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ);
 
-       send_mos_cmd(serial,MOS_READ,0x00, UART_LSR, &data);  // LSR For Port 1
-       dbg("LSR:%x",data);
+       /* LSR For Port 1 */
+       send_mos_cmd(serial, MOS_READ, 0x00, UART_LSR, &data);
+       dbg("LSR:%x", data);
 
-       send_mos_cmd(serial,MOS_READ,0x01, UART_LSR, &data);  // LSR For Port 2
-       dbg("LSR:%x",data);
+       /* LSR For Port 2 */
+       send_mos_cmd(serial, MOS_READ, 0x01, UART_LSR, &data);
+       dbg("LSR:%x", data);
 
        return 0;
 }
@@ -1571,7 +1559,7 @@ static void mos7720_shutdown(struct usb_serial *serial)
        int i;
 
        /* free private structure allocated for serial port */
-       for (i=0; i < serial->num_ports; ++i) {
+       for (i = 0; i < serial->num_ports; ++i) {
                kfree(usb_get_serial_port_data(serial->port[i]));
                usb_set_serial_port_data(serial->port[i], NULL);
        }
@@ -1651,8 +1639,8 @@ module_init(moschip7720_init);
 module_exit(moschip7720_exit);
 
 /* Module information */
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
index 78f2f6db494d790fb4d00d75c0ef9c1229ef89ef..09d82062b97384f2402feda9f7401d75a76fb407 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/serial.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 /*
  * Version Information
@@ -82,8 +82,8 @@
  * Defines used for sending commands to port
  */
 
-#define WAIT_FOR_EVER   (HZ * 0 )      /* timeout urb is wait for ever */
-#define MOS_WDR_TIMEOUT (HZ * 5 )      /* default urb timeout */
+#define WAIT_FOR_EVER   (HZ * 0      /* timeout urb is wait for ever */
+#define MOS_WDR_TIMEOUT (HZ * 5      /* default urb timeout */
 
 #define MOS_PORT1       0x0200
 #define MOS_PORT2       0x0300
 
 #define MAX_NAME_LEN    64
 
-#define ZLP_REG1  0x3A         //Zero_Flag_Reg1    58
-#define ZLP_REG5  0x3E         //Zero_Flag_Reg5    62
+#define ZLP_REG1  0x3A         /* Zero_Flag_Reg1    58 */
+#define ZLP_REG5  0x3E         /* Zero_Flag_Reg5    62 */
 
 /* For higher baud Rates use TIOCEXBAUD */
 #define TIOCEXBAUD     0x5462
 #define MOS_MSR_DELTA_RI    0x40
 #define MOS_MSR_DELTA_CD    0x80
 
-// Serial Port register Address
+/* Serial Port register Address */
 #define INTERRUPT_ENABLE_REGISTER  ((__u16)(0x01))
 #define FIFO_CONTROL_REGISTER      ((__u16)(0x02))
 #define LINE_CONTROL_REGISTER      ((__u16)(0x03))
@@ -201,11 +201,11 @@ struct moschip_port {
        struct async_icount icount;
        struct usb_serial_port *port;   /* loop back to the owner of this object */
 
-       /*Offsets */
+       /* Offsets */
        __u8 SpRegOffset;
        __u8 ControlRegOffset;
        __u8 DcrRegOffset;
-       //for processing control URBS in interrupt context
+       /* for processing control URBS in interrupt context */
        struct urb *control_urb;
        struct usb_ctrlrequest *dr;
        char *ctrl_buf;
@@ -244,7 +244,7 @@ static int mos7840_set_reg_sync(struct usb_serial_port *port, __u16 reg,
  */
 
 static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg,
-                               __u16 * val)
+                               __u16 *val)
 {
        struct usb_device *dev = port->serial->dev;
        int ret = 0;
@@ -269,16 +269,15 @@ static int mos7840_set_uart_reg(struct usb_serial_port *port, __u16 reg,
 
        struct usb_device *dev = port->serial->dev;
        val = val & 0x00ff;
-       // For the UART control registers, the application number need to be Or'ed
+       /* For the UART control registers, the application number need
+          to be Or'ed */
        if (port->serial->num_ports == 4) {
-               val |=
-                   (((__u16) port->number - (__u16) (port->serial->minor)) +
-                    1) << 8;
+               val |= (((__u16) port->number -
+                               (__u16) (port->serial->minor)) + 1) << 8;
                dbg("mos7840_set_uart_reg application number is %x\n", val);
        } else {
                if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) {
-                       val |=
-                           (((__u16) port->number -
+                       val |= (((__u16) port->number -
                              (__u16) (port->serial->minor)) + 1) << 8;
                        dbg("mos7840_set_uart_reg application number is %x\n",
                            val);
@@ -302,14 +301,15 @@ static int mos7840_set_uart_reg(struct usb_serial_port *port, __u16 reg,
  *     by passing usb_rcvctrlpipe function as parameter.
  */
 static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg,
-                               __u16 * val)
+                               __u16 *val)
 {
        struct usb_device *dev = port->serial->dev;
        int ret = 0;
        __u16 Wval;
 
-       //dbg("application number is %4x \n",(((__u16)port->number - (__u16)(port->serial->minor))+1)<<8);
-       /*Wval  is same as application number */
+       /* dbg("application number is %4x \n",
+           (((__u16)port->number - (__u16)(port->serial->minor))+1)<<8); */
+       /* Wval  is same as application number */
        if (port->serial->num_ports == 4) {
                Wval =
                    (((__u16) port->number - (__u16) (port->serial->minor)) +
@@ -317,14 +317,12 @@ static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg,
                dbg("mos7840_get_uart_reg application number is %x\n", Wval);
        } else {
                if (((__u16) port->number - (__u16) (port->serial->minor)) == 0) {
-                       Wval =
-                           (((__u16) port->number -
+                       Wval = (((__u16) port->number -
                              (__u16) (port->serial->minor)) + 1) << 8;
                        dbg("mos7840_get_uart_reg application number is %x\n",
                            Wval);
                } else {
-                       Wval =
-                           (((__u16) port->number -
+                       Wval = (((__u16) port->number -
                              (__u16) (port->serial->minor)) + 2) << 8;
                        dbg("mos7840_get_uart_reg application number is %x\n",
                            Wval);
@@ -406,11 +404,11 @@ static void mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr)
        dbg("%s - %02x", __func__, new_lsr);
 
        if (new_lsr & SERIAL_LSR_BI) {
-               //
-               // Parity and Framing errors only count if they
-               // occur exclusive of a break being
-               // received.
-               //
+               /*
+                * Parity and Framing errors only count if they
+                * occur exclusive of a break being
+                * received.
+                */
                new_lsr &= (__u8) (SERIAL_LSR_OE | SERIAL_LSR_BI);
        }
 
@@ -492,7 +490,7 @@ exit:
 }
 
 static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
-                          __u16 * val)
+                          __u16 *val)
 {
        struct usb_device *dev = mcs->port->serial->dev;
        struct usb_ctrlrequest *dr = mcs->dr;
@@ -501,7 +499,7 @@ static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
 
        dr->bRequestType = MCS_RD_RTYPE;
        dr->bRequest = MCS_RDREQ;
-       dr->wValue = cpu_to_le16(Wval); //0;
+       dr->wValue = cpu_to_le16(Wval); /* 0 */
        dr->wIndex = cpu_to_le16(reg);
        dr->wLength = cpu_to_le16(2);
 
@@ -607,7 +605,8 @@ static void mos7840_interrupt_callback(struct urb *urb)
                        }
                }
        }
-       if (!(rv < 0)) /* the completion handler for the control urb will resubmit */
+       if (!(rv < 0))
+               /* the completion handler for the control urb will resubmit */
                return;
 exit:
        result = usb_submit_urb(urb, GFP_ATOMIC);
@@ -656,8 +655,8 @@ static struct usb_serial *mos7840_get_usb_serial(struct usb_serial_port *port,
        if (!port ||
            mos7840_port_paranoia_check(port, function) ||
            mos7840_serial_paranoia_check(port->serial, function)) {
-               /* then say that we don't have a valid usb_serial thing, which will
-                * end up genrating -ENODEV return values */
+               /* then say that we don't have a valid usb_serial thing,
+                * which will end up genrating -ENODEV return values */
                return NULL;
        }
 
@@ -710,7 +709,7 @@ static void mos7840_bulk_in_callback(struct urb *urb)
        dbg("%s", "Entering ........... \n");
 
        if (urb->actual_length) {
-               tty = mos7840_port->port->tty;
+               tty = mos7840_port->port->port.tty;
                if (tty) {
                        tty_buffer_request_room(tty, urb->actual_length);
                        tty_insert_flip_string(tty, data, urb->actual_length);
@@ -741,8 +740,8 @@ static void mos7840_bulk_in_callback(struct urb *urb)
 
 /*****************************************************************************
  * mos7840_bulk_out_data_callback
- *     this is the callback function for when we have finished sending serial data
- *     on the bulk out endpoint.
+ *     this is the callback function for when we have finished sending
+ *     serial data on the bulk out endpoint.
  *****************************************************************************/
 
 static void mos7840_bulk_out_data_callback(struct urb *urb)
@@ -774,7 +773,7 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
 
        dbg("%s \n", "Entering .........");
 
-       tty = mos7840_port->port->tty;
+       tty = mos7840_port->port->port.tty;
 
        if (tty && mos7840_port->open)
                tty_wakeup(tty);
@@ -804,7 +803,8 @@ static int mos7840_serial_probe(struct usb_serial *serial,
  *     Otherwise we return a negative error number.
  *****************************************************************************/
 
-static int mos7840_open(struct usb_serial_port *port, struct file *filp)
+static int mos7840_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        int response;
        int j;
@@ -847,7 +847,8 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp)
                        continue;
                }
 
-               urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+               urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
+                                                               GFP_KERNEL);
                if (!urb->transfer_buffer) {
                        usb_free_urb(urb);
                        mos7840_port->write_urb_pool[j] = NULL;
@@ -868,9 +869,8 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp)
  * 0x08 : SP1/2 Control Reg
  *****************************************************************************/
 
-//NEED to check the following Block
+       /* NEED to check the following Block */
 
-       status = 0;
        Data = 0x0;
        status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data);
        if (status < 0) {
@@ -890,36 +890,35 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp)
                dbg("writing Spreg failed\n");
                return -1;
        }
-//End of block to be checked
+       /* End of block to be checked */
 
-       status = 0;
        Data = 0x0;
-       status =
-           mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data);
+       status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset,
+                                                                       &Data);
        if (status < 0) {
                dbg("Reading Controlreg failed\n");
                return -1;
        }
-       Data |= 0x08;           //Driver done bit
-       Data |= 0x20;           //rx_disable
-       status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data);
+       Data |= 0x08;           /* Driver done bit */
+       Data |= 0x20;           /* rx_disable */
+       status = mos7840_set_reg_sync(port,
+                               mos7840_port->ControlRegOffset, Data);
        if (status < 0) {
                dbg("writing Controlreg failed\n");
                return -1;
        }
-       //do register settings here
-       // Set all regs to the device default values.
-       ////////////////////////////////////
-       // First Disable all interrupts.
-       ////////////////////////////////////
-
+       /* do register settings here */
+       /* Set all regs to the device default values. */
+       /***********************************
+        * First Disable all interrupts.
+        ***********************************/
        Data = 0x00;
        status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
        if (status < 0) {
                dbg("disableing interrupts failed\n");
                return -1;
        }
-       // Set FIFO_CONTROL_REGISTER to the default value
+       /* Set FIFO_CONTROL_REGISTER to the default value */
        Data = 0x00;
        status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
        if (status < 0) {
@@ -946,90 +945,73 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp)
        status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
        mos7840_port->shadowLCR = Data;
 
-       Data |= SERIAL_LCR_DLAB;        //data latch enable in LCR 0x80
+       Data |= SERIAL_LCR_DLAB;        /* data latch enable in LCR 0x80 */
        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
 
        Data = 0x0c;
-       status = 0;
        status = mos7840_set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
 
        Data = 0x0;
-       status = 0;
        status = mos7840_set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
 
        Data = 0x00;
-       status = 0;
        status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
 
        Data = Data & ~SERIAL_LCR_DLAB;
-       status = 0;
        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
        mos7840_port->shadowLCR = Data;
 
-       //clearing Bulkin and Bulkout Fifo
+       /* clearing Bulkin and Bulkout Fifo */
        Data = 0x0;
-       status = 0;
        status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset, &Data);
 
        Data = Data | 0x0c;
-       status = 0;
        status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
 
        Data = Data & ~0x0c;
-       status = 0;
        status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
-       //Finally enable all interrupts
-       Data = 0x0;
+       /* Finally enable all interrupts */
        Data = 0x0c;
-       status = 0;
        status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
 
-       //clearing rx_disable
+       /* clearing rx_disable */
        Data = 0x0;
-       status = 0;
-       status =
-           mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data);
+       status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset,
+                                                                       &Data);
        Data = Data & ~0x20;
-       status = 0;
-       status =
-           mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data);
+       status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset,
+                                                                       Data);
 
-       // rx_negate
+       /* rx_negate */
        Data = 0x0;
-       status = 0;
-       status =
-           mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset, &Data);
+       status = mos7840_get_reg_sync(port, mos7840_port->ControlRegOffset,
+                                                                       &Data);
        Data = Data | 0x10;
-       status = 0;
-       status =
-           mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data);
+       status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset,
+                                                                       Data);
 
        /* force low_latency on so that our tty_push actually forces *
         * the data through,otherwise it is scheduled, and with      *
         * high data rates (like with OHCI) data can get lost.       */
+       if (tty)
+               tty->low_latency = 1;
 
-       if (port->tty)
-               port->tty->low_latency = 1;
-/* Check to see if we've set up our endpoint info yet    *
-     * (can't set it up in mos7840_startup as the structures *
-     * were not set up at that time.)                        */
+       /* Check to see if we've set up our endpoint info yet    *
+        * (can't set it up in mos7840_startup as the structures *
+        * were not set up at that time.)                        */
        if (port0->open_ports == 1) {
                if (serial->port[0]->interrupt_in_buffer == NULL) {
-
                        /* set up interrupt urb */
-
                        usb_fill_int_urb(serial->port[0]->interrupt_in_urb,
-                                        serial->dev,
-                                        usb_rcvintpipe(serial->dev,
-                                                       serial->port[0]->
-                                                       interrupt_in_endpointAddress),
-                                        serial->port[0]->interrupt_in_buffer,
-                                        serial->port[0]->interrupt_in_urb->
-                                        transfer_buffer_length,
-                                        mos7840_interrupt_callback,
-                                        serial,
-                                        serial->port[0]->interrupt_in_urb->
-                                        interval);
+                               serial->dev,
+                               usb_rcvintpipe(serial->dev,
+                               serial->port[0]->interrupt_in_endpointAddress),
+                               serial->port[0]->interrupt_in_buffer,
+                               serial->port[0]->interrupt_in_urb->
+                               transfer_buffer_length,
+                               mos7840_interrupt_callback,
+                               serial,
+                               serial->port[0]->interrupt_in_urb->interval);
 
                        /* start interrupt read for mos7840               *
                         * will continue as long as mos7840 is connected  */
@@ -1084,14 +1066,16 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp)
        memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount));
 
        /* initialize our port settings */
-       mos7840_port->shadowMCR = MCR_MASTER_IE;        /* Must set to enable ints! */
+       /* Must set to enable ints! */
+       mos7840_port->shadowMCR = MCR_MASTER_IE;
        /* send a open port command */
        mos7840_port->open = 1;
-       //mos7840_change_port_settings(mos7840_port,old_termios);
+       /* mos7840_change_port_settings(mos7840_port,old_termios); */
        mos7840_port->icount.tx = 0;
        mos7840_port->icount.rx = 0;
 
-       dbg("\n\nusb_serial serial:%p       mos7840_port:%p\n      usb_serial_port port:%p\n\n", serial, mos7840_port, port);
+       dbg("\n\nusb_serial serial:%p       mos7840_port:%p\n      usb_serial_port port:%p\n\n",
+                               serial, mos7840_port, port);
 
        return 0;
 
@@ -1104,11 +1088,12 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp)
  *     been written, but hasn't made it out the port yet)
  *     If successful, we return the number of bytes left to be written in the
  *     system,
- *     Otherwise we return a negative error number.
+ *     Otherwise we return zero.
  *****************************************************************************/
 
-static int mos7840_chars_in_buffer(struct usb_serial_port *port)
+static int mos7840_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        int i;
        int chars = 0;
        unsigned long flags;
@@ -1118,22 +1103,20 @@ static int mos7840_chars_in_buffer(struct usb_serial_port *port)
 
        if (mos7840_port_paranoia_check(port, __func__)) {
                dbg("%s", "Invalid port \n");
-               return -1;
+               return 0;
        }
 
        mos7840_port = mos7840_get_port_private(port);
        if (mos7840_port == NULL) {
                dbg("%s \n", "mos7840_break:leaving ...........");
-               return -1;
+               return 0;
        }
 
-       spin_lock_irqsave(&mos7840_port->pool_lock,flags);
-       for (i = 0; i < NUM_URBS; ++i) {
-               if (mos7840_port->busy[i]) {
+       spin_lock_irqsave(&mos7840_port->pool_lock, flags);
+       for (i = 0; i < NUM_URBS; ++i)
+               if (mos7840_port->busy[i])
                        chars += URB_TRANSFER_BUFFER_SIZE;
-               }
-       }
-       spin_unlock_irqrestore(&mos7840_port->pool_lock,flags);
+       spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
        dbg("%s - returns %d", __func__, chars);
        return chars;
 
@@ -1149,7 +1132,8 @@ static int mos7840_chars_in_buffer(struct usb_serial_port *port)
  *             3. A timeout of 3 seconds without activity has expired
  *
  ************************************************************************/
-static void mos7840_block_until_tx_empty(struct moschip_port *mos7840_port)
+static void mos7840_block_until_tx_empty(struct tty_struct *tty,
+                               struct moschip_port *mos7840_port)
 {
        int timeout = HZ / 10;
        int wait = 30;
@@ -1157,12 +1141,11 @@ static void mos7840_block_until_tx_empty(struct moschip_port *mos7840_port)
 
        while (1) {
 
-               count = mos7840_chars_in_buffer(mos7840_port->port);
+               count = mos7840_chars_in_buffer(tty);
 
                /* Check for Buffer status */
-               if (count <= 0) {
+               if (count <= 0)
                        return;
-               }
 
                /* Block the thread for a while */
                interruptible_sleep_on_timeout(&mos7840_port->wait_chase,
@@ -1185,7 +1168,8 @@ static void mos7840_block_until_tx_empty(struct moschip_port *mos7840_port)
  *     this function is called by the tty driver when a port is closed
  *****************************************************************************/
 
-static void mos7840_close(struct usb_serial_port *port, struct file *filp)
+static void mos7840_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial;
        struct moschip_port *mos7840_port;
@@ -1226,32 +1210,28 @@ static void mos7840_close(struct usb_serial_port *port, struct file *filp)
                }
        }
 
-       if (serial->dev) {
+       if (serial->dev)
                /* flush and block until tx is empty */
-               mos7840_block_until_tx_empty(mos7840_port);
-       }
+               mos7840_block_until_tx_empty(tty, mos7840_port);
 
        /* While closing port, shutdown all bulk read, write  *
         * and interrupt read if they exists                  */
        if (serial->dev) {
-
                if (mos7840_port->write_urb) {
                        dbg("%s", "Shutdown bulk write\n");
                        usb_kill_urb(mos7840_port->write_urb);
                }
-
                if (mos7840_port->read_urb) {
                        dbg("%s", "Shutdown bulk read\n");
                        usb_kill_urb(mos7840_port->read_urb);
                }
                if ((&mos7840_port->control_urb)) {
                        dbg("%s", "Shutdown control read\n");
-                       //      usb_kill_urb (mos7840_port->control_urb);
-
+                       /*/      usb_kill_urb (mos7840_port->control_urb); */
                }
        }
-//              if(mos7840_port->ctrl_buf != NULL)
-//                      kfree(mos7840_port->ctrl_buf);
+/*      if(mos7840_port->ctrl_buf != NULL) */
+/*              kfree(mos7840_port->ctrl_buf); */
        port0->open_ports--;
        dbg("mos7840_num_open_ports in close%d:in port%d\n",
            port0->open_ports, port->number);
@@ -1264,10 +1244,8 @@ static void mos7840_close(struct usb_serial_port *port, struct file *filp)
 
        if (mos7840_port->write_urb) {
                /* if this urb had a transfer buffer already (old tx) free it */
-
-               if (mos7840_port->write_urb->transfer_buffer != NULL) {
+               if (mos7840_port->write_urb->transfer_buffer != NULL)
                        kfree(mos7840_port->write_urb->transfer_buffer);
-               }
                usb_free_urb(mos7840_port->write_urb);
        }
 
@@ -1293,20 +1271,19 @@ static void mos7840_close(struct usb_serial_port *port, struct file *filp)
  *
  ************************************************************************/
 
-static void mos7840_block_until_chase_response(struct moschip_port
-                                              *mos7840_port)
+static void mos7840_block_until_chase_response(struct tty_struct *tty,
+                                       struct moschip_port *mos7840_port)
 {
        int timeout = 1 * HZ;
        int wait = 10;
        int count;
 
        while (1) {
-               count = mos7840_chars_in_buffer(mos7840_port->port);
+               count = mos7840_chars_in_buffer(tty);
 
                /* Check for Buffer status */
-               if (count <= 0) {
+               if (count <= 0)
                        return;
-               }
 
                /* Block the thread for a while */
                interruptible_sleep_on_timeout(&mos7840_port->wait_chase,
@@ -1328,8 +1305,9 @@ static void mos7840_block_until_chase_response(struct moschip_port
  * mos7840_break
  *     this function sends a break to the port
  *****************************************************************************/
-static void mos7840_break(struct usb_serial_port *port, int break_state)
+static void mos7840_break(struct tty_struct *tty, int break_state)
 {
+       struct usb_serial_port *port = tty->driver_data;
        unsigned char data;
        struct usb_serial *serial;
        struct moschip_port *mos7840_port;
@@ -1350,21 +1328,17 @@ static void mos7840_break(struct usb_serial_port *port, int break_state)
 
        mos7840_port = mos7840_get_port_private(port);
 
-       if (mos7840_port == NULL) {
+       if (mos7840_port == NULL)
                return;
-       }
-
-       if (serial->dev) {
 
+       if (serial->dev)
                /* flush and block until tx is empty */
-               mos7840_block_until_chase_response(mos7840_port);
-       }
+               mos7840_block_until_chase_response(tty, mos7840_port);
 
-       if (break_state == -1) {
+       if (break_state == -1)
                data = mos7840_port->shadowLCR | LCR_SET_BREAK;
-       } else {
+       else
                data = mos7840_port->shadowLCR & ~LCR_SET_BREAK;
-       }
 
        mos7840_port->shadowLCR = data;
        dbg("mcs7840_break mos7840_port->shadowLCR is %x\n",
@@ -1383,8 +1357,9 @@ static void mos7840_break(struct usb_serial_port *port, int break_state)
  *     Otherwise we return a negative error number.
  *****************************************************************************/
 
-static int mos7840_write_room(struct usb_serial_port *port)
+static int mos7840_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        int i;
        int room = 0;
        unsigned long flags;
@@ -1406,9 +1381,8 @@ static int mos7840_write_room(struct usb_serial_port *port)
 
        spin_lock_irqsave(&mos7840_port->pool_lock, flags);
        for (i = 0; i < NUM_URBS; ++i) {
-               if (!mos7840_port->busy[i]) {
+               if (!mos7840_port->busy[i])
                        room += URB_TRANSFER_BUFFER_SIZE;
-               }
        }
        spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
 
@@ -1426,7 +1400,7 @@ static int mos7840_write_room(struct usb_serial_port *port)
  *      return a negative error number.
  *****************************************************************************/
 
-static int mos7840_write(struct usb_serial_port *port,
+static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
                         const unsigned char *data, int count)
 {
        int status;
@@ -1438,45 +1412,41 @@ static int mos7840_write(struct usb_serial_port *port,
        struct moschip_port *mos7840_port;
        struct usb_serial *serial;
        struct urb *urb;
-       //__u16 Data;
+       /* __u16 Data; */
        const unsigned char *current_position = data;
        unsigned char *data1;
        dbg("%s \n", "entering ...........");
-       //dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",mos7840_port->shadowLCR);
+       /* dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",
+                                       mos7840_port->shadowLCR); */
 
 #ifdef NOTMOS7840
        Data = 0x00;
-       status = 0;
        status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
        mos7840_port->shadowLCR = Data;
        dbg("mos7840_write: LINE_CONTROL_REGISTER is %x\n", Data);
        dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",
            mos7840_port->shadowLCR);
 
-       //Data = 0x03;
-       //status = mos7840_set_uart_reg(port,LINE_CONTROL_REGISTER,Data);
-       //mos7840_port->shadowLCR=Data;//Need to add later
+       /* Data = 0x03; */
+       /* status = mos7840_set_uart_reg(port,LINE_CONTROL_REGISTER,Data); */
+       /* mos7840_port->shadowLCR=Data;//Need to add later */
 
-       Data |= SERIAL_LCR_DLAB;        //data latch enable in LCR 0x80
-       status = 0;
+       Data |= SERIAL_LCR_DLAB;        /* data latch enable in LCR 0x80 */
        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
 
-       //Data = 0x0c;
-       //status = mos7840_set_uart_reg(port,DIVISOR_LATCH_LSB,Data);
+       /* Data = 0x0c; */
+       /* status = mos7840_set_uart_reg(port,DIVISOR_LATCH_LSB,Data); */
        Data = 0x00;
-       status = 0;
        status = mos7840_get_uart_reg(port, DIVISOR_LATCH_LSB, &Data);
        dbg("mos7840_write:DLL value is %x\n", Data);
 
        Data = 0x0;
-       status = 0;
        status = mos7840_get_uart_reg(port, DIVISOR_LATCH_MSB, &Data);
        dbg("mos7840_write:DLM value is %x\n", Data);
 
        Data = Data & ~SERIAL_LCR_DLAB;
        dbg("mos7840_write: mos7840_port->shadowLCR is %x\n",
            mos7840_port->shadowLCR);
-       status = 0;
        status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
 #endif
 
@@ -1555,8 +1525,7 @@ static int mos7840_write(struct usb_serial_port *port,
        mos7840_port->icount.tx += transfer_size;
        smp_wmb();
        dbg("mos7840_port->icount.tx is %d:\n", mos7840_port->icount.tx);
-      exit:
-
+exit:
        return bytes_sent;
 
 }
@@ -1567,10 +1536,10 @@ static int mos7840_write(struct usb_serial_port *port,
  *     being read from the port.
  *****************************************************************************/
 
-static void mos7840_throttle(struct usb_serial_port *port)
+static void mos7840_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct moschip_port *mos7840_port;
-       struct tty_struct *tty;
        int status;
 
        if (mos7840_port_paranoia_check(port, __func__)) {
@@ -1592,32 +1561,20 @@ static void mos7840_throttle(struct usb_serial_port *port)
 
        dbg("%s", "Entering .......... \n");
 
-       tty = port->tty;
-       if (!tty) {
-               dbg("%s - no tty available", __func__);
-               return;
-       }
-
        /* if we are implementing XON/XOFF, send the stop character */
        if (I_IXOFF(tty)) {
                unsigned char stop_char = STOP_CHAR(tty);
-               status = mos7840_write(port, &stop_char, 1);
-               if (status <= 0) {
+               status = mos7840_write(tty, port, &stop_char, 1);
+               if (status <= 0)
                        return;
-               }
        }
-
        /* if we are implementing RTS/CTS, toggle that line */
        if (tty->termios->c_cflag & CRTSCTS) {
                mos7840_port->shadowMCR &= ~MCR_RTS;
-               status = 0;
-               status =
-                   mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
+               status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
                                         mos7840_port->shadowMCR);
-
-               if (status < 0) {
+               if (status < 0)
                        return;
-               }
        }
 
        return;
@@ -1625,12 +1582,13 @@ static void mos7840_throttle(struct usb_serial_port *port)
 
 /*****************************************************************************
  * mos7840_unthrottle
- *     this function is called by the tty driver when it wants to resume the data
- *     being read from the port (called after SerialThrottle is called)
+ *     this function is called by the tty driver when it wants to resume
+ *     the data being read from the port (called after mos7840_throttle is
+ *     called)
  *****************************************************************************/
-static void mos7840_unthrottle(struct usb_serial_port *port)
+static void mos7840_unthrottle(struct tty_struct *tty)
 {
-       struct tty_struct *tty;
+       struct usb_serial_port *port = tty->driver_data;
        int status;
        struct moschip_port *mos7840_port = mos7840_get_port_private(port);
 
@@ -1649,43 +1607,32 @@ static void mos7840_unthrottle(struct usb_serial_port *port)
 
        dbg("%s", "Entering .......... \n");
 
-       tty = port->tty;
-       if (!tty) {
-               dbg("%s - no tty available", __func__);
-               return;
-       }
-
        /* if we are implementing XON/XOFF, send the start character */
        if (I_IXOFF(tty)) {
                unsigned char start_char = START_CHAR(tty);
-               status = mos7840_write(port, &start_char, 1);
-               if (status <= 0) {
+               status = mos7840_write(tty, port, &start_char, 1);
+               if (status <= 0)
                        return;
-               }
        }
 
        /* if we are implementing RTS/CTS, toggle that line */
        if (tty->termios->c_cflag & CRTSCTS) {
                mos7840_port->shadowMCR |= MCR_RTS;
-               status = 0;
-               status =
-                   mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
+               status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
                                         mos7840_port->shadowMCR);
-               if (status < 0) {
+               if (status < 0)
                        return;
-               }
        }
-
-       return;
 }
 
-static int mos7840_tiocmget(struct usb_serial_port *port, struct file *file)
+static int mos7840_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct moschip_port *mos7840_port;
        unsigned int result;
        __u16 msr;
        __u16 mcr;
-       int status = 0;
+       int status;
        mos7840_port = mos7840_get_port_private(port);
 
        dbg("%s - port %d", __func__, port->number);
@@ -1708,9 +1655,10 @@ static int mos7840_tiocmget(struct usb_serial_port *port, struct file *file)
        return result;
 }
 
-static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file,
+static int mos7840_tiocmset(struct tty_struct *tty, struct file *file,
                            unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct moschip_port *mos7840_port;
        unsigned int mcr;
        int status;
@@ -1755,7 +1703,7 @@ static int mos7840_tiocmset(struct usb_serial_port *port, struct file *file,
  *     baud rate.
  *****************************************************************************/
 static int mos7840_calc_baud_rate_divisor(int baudRate, int *divisor,
-                                         __u16 * clk_sel_val)
+                                         __u16 *clk_sel_val)
 {
 
        dbg("%s - %d", __func__, baudRate);
@@ -1807,9 +1755,8 @@ static int mos7840_calc_baud_rate_divisor(int baudRate, int *divisor,
                /* Check for round off */
                round1 = (__u16) (2304000L / baudrate);
                round = (__u16) (round1 - (custom * 10));
-               if (round > 4) {
+               if (round > 4)
                        custom++;
-               }
                *divisor = custom;
 
                dbg(" Baud %d = %d\n", baudrate, custom);
@@ -1857,16 +1804,15 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
 
        dbg("%s - port = %d, baud = %d", __func__,
            mos7840_port->port->number, baudRate);
-       //reset clk_uart_sel in spregOffset
+       /* reset clk_uart_sel in spregOffset */
        if (baudRate > 115200) {
 #ifdef HW_flow_control
-               //NOTE: need to see the pther register to modify
-               //setting h/w flow control bit to 1;
-               status = 0;
+               /* NOTE: need to see the pther register to modify */
+               /* setting h/w flow control bit to 1 */
                Data = 0x2b;
                mos7840_port->shadowMCR = Data;
-               status =
-                   mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+               status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
+                                                                       Data);
                if (status < 0) {
                        dbg("Writing spreg failed in set_serial_baud\n");
                        return -1;
@@ -1875,12 +1821,11 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
 
        } else {
 #ifdef HW_flow_control
-               //setting h/w flow control bit to 0;
-               status = 0;
+               / *setting h/w flow control bit to 0 */
                Data = 0xb;
                mos7840_port->shadowMCR = Data;
-               status =
-                   mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+               status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
+                                                                       Data);
                if (status < 0) {
                        dbg("Writing spreg failed in set_serial_baud\n");
                        return -1;
@@ -1889,25 +1834,20 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
 
        }
 
-       if (1)                  //baudRate <= 115200)
-       {
+       if (1) {                /* baudRate <= 115200) */
                clk_sel_val = 0x0;
                Data = 0x0;
-               status = 0;
-               status =
-                   mos7840_calc_baud_rate_divisor(baudRate, &divisor,
+               status = mos7840_calc_baud_rate_divisor(baudRate, &divisor,
                                                   &clk_sel_val);
-               status =
-                   mos7840_get_reg_sync(port, mos7840_port->SpRegOffset,
-                                        &Data);
+               status = mos7840_get_reg_sync(port, mos7840_port->SpRegOffset,
+                                                                &Data);
                if (status < 0) {
                        dbg("reading spreg failed in set_serial_baud\n");
                        return -1;
                }
                Data = (Data & 0x8f) | clk_sel_val;
-               status = 0;
-               status =
-                   mos7840_set_reg_sync(port, mos7840_port->SpRegOffset, Data);
+               status = mos7840_set_reg_sync(port, mos7840_port->SpRegOffset,
+                                                               Data);
                if (status < 0) {
                        dbg("Writing spreg failed in set_serial_baud\n");
                        return -1;
@@ -1939,7 +1879,6 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
                mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
 
        }
-
        return status;
 }
 
@@ -1949,10 +1888,9 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
  *      the specified new settings.
  *****************************************************************************/
 
-static void mos7840_change_port_settings(struct moschip_port *mos7840_port,
-                                        struct ktermios *old_termios)
+static void mos7840_change_port_settings(struct tty_struct *tty,
+       struct moschip_port *mos7840_port, struct ktermios *old_termios)
 {
-       struct tty_struct *tty;
        int baud;
        unsigned cflag;
        unsigned iflag;
@@ -1988,8 +1926,6 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port,
                return;
        }
 
-       tty = mos7840_port->port->tty;
-
        dbg("%s", "Entering .......... \n");
 
        lData = LCR_BITS_8;
@@ -2033,9 +1969,8 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port,
                dbg("%s - parity = none", __func__);
        }
 
-       if (cflag & CMSPAR) {
+       if (cflag & CMSPAR)
                lParity = lParity | 0x20;
-       }
 
        /* Change the Stop bit */
        if (cflag & CSTOPB) {
@@ -2077,16 +2012,13 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port,
        /* set up the MCR register and send it to the mos7840 */
 
        mos7840_port->shadowMCR = MCR_MASTER_IE;
-       if (cflag & CBAUD) {
+       if (cflag & CBAUD)
                mos7840_port->shadowMCR |= (MCR_DTR | MCR_RTS);
-       }
 
-       if (cflag & CRTSCTS) {
+       if (cflag & CRTSCTS)
                mos7840_port->shadowMCR |= (MCR_XON_ANY);
-
-       } else {
+       else
                mos7840_port->shadowMCR &= ~(MCR_XON_ANY);
-       }
 
        Data = mos7840_port->shadowMCR;
        mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
@@ -2131,14 +2063,14 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port,
  *     the termios structure
  *****************************************************************************/
 
-static void mos7840_set_termios(struct usb_serial_port *port,
+static void mos7840_set_termios(struct tty_struct *tty,
+                               struct usb_serial_port *port,
                                struct ktermios *old_termios)
 {
        int status;
        unsigned int cflag;
        struct usb_serial *serial;
        struct moschip_port *mos7840_port;
-       struct tty_struct *tty;
        dbg("mos7840_set_termios: START\n");
        if (mos7840_port_paranoia_check(port, __func__)) {
                dbg("%s", "Invalid port \n");
@@ -2157,8 +2089,6 @@ static void mos7840_set_termios(struct usb_serial_port *port,
        if (mos7840_port == NULL)
                return;
 
-       tty = port->tty;
-
        if (!mos7840_port->open) {
                dbg("%s - port not opened", __func__);
                return;
@@ -2176,7 +2106,7 @@ static void mos7840_set_termios(struct usb_serial_port *port,
 
        /* change the port settings to the new ones specified */
 
-       mos7840_change_port_settings(mos7840_port, old_termios);
+       mos7840_change_port_settings(tty, mos7840_port, old_termios);
 
        if (!mos7840_port->read_urb) {
                dbg("%s", "URB KILLED !!!!!\n");
@@ -2205,13 +2135,13 @@ static void mos7840_set_termios(struct usb_serial_port *port,
  *         allows an RS485 driver to be written in user space.
  *****************************************************************************/
 
-static int mos7840_get_lsr_info(struct moschip_port *mos7840_port,
+static int mos7840_get_lsr_info(struct tty_struct *tty,
                                unsigned int __user *value)
 {
        int count;
        unsigned int result = 0;
 
-       count = mos7840_chars_in_buffer(mos7840_port->port);
+       count = mos7840_chars_in_buffer(tty);
        if (count == 0) {
                dbg("%s -- Empty", __func__);
                result = TIOCSER_TEMT;
@@ -2227,6 +2157,8 @@ static int mos7840_get_lsr_info(struct moschip_port *mos7840_port,
  *      function to set modem info
  *****************************************************************************/
 
+/* FIXME: Should be using the model control hooks */
+
 static int mos7840_set_modem_info(struct moschip_port *mos7840_port,
                                  unsigned int cmd, unsigned int __user *value)
 {
@@ -2282,7 +2214,6 @@ static int mos7840_set_modem_info(struct moschip_port *mos7840_port,
        mos7840_port->shadowMCR = mcr;
 
        Data = mos7840_port->shadowMCR;
-       status = 0;
        status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
        if (status < 0) {
                dbg("setting MODEM_CONTROL_REGISTER Failed\n");
@@ -2303,10 +2234,8 @@ static int mos7840_get_modem_info(struct moschip_port *mos7840_port,
        unsigned int result = 0;
        __u16 msr;
        unsigned int mcr = mos7840_port->shadowMCR;
-       int status = 0;
-       status =
-           mos7840_get_uart_reg(mos7840_port->port, MODEM_STATUS_REGISTER,
-                                &msr);
+        mos7840_get_uart_reg(mos7840_port->port,
+                                               MODEM_STATUS_REGISTER, &msr);
        result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)      /* 0x002 */
            |((mcr & MCR_RTS) ? TIOCM_RTS : 0)  /* 0x004 */
            |((msr & MOS7840_MSR_CTS) ? TIOCM_CTS : 0)  /* 0x020 */
@@ -2359,12 +2288,12 @@ static int mos7840_get_serial_info(struct moschip_port *mos7840_port,
  *     this function handles any ioctl calls to the driver
  *****************************************************************************/
 
-static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
+static int mos7840_ioctl(struct tty_struct *tty, struct file *file,
                         unsigned int cmd, unsigned long arg)
 {
+       struct usb_serial_port *port = tty->driver_data;
        void __user *argp = (void __user *)arg;
        struct moschip_port *mos7840_port;
-       struct tty_struct *tty;
 
        struct async_icount cnow;
        struct async_icount cprev;
@@ -2381,8 +2310,6 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
        if (mos7840_port == NULL)
                return -1;
 
-       tty = mos7840_port->port->tty;
-
        dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
 
        switch (cmd) {
@@ -2390,9 +2317,10 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
 
        case TIOCSERGETLSR:
                dbg("%s (%d) TIOCSERGETLSR", __func__, port->number);
-               return mos7840_get_lsr_info(mos7840_port, argp);
+               return mos7840_get_lsr_info(tty, argp);
                return 0;
 
+       /* FIXME: use the modem hooks and remove this */
        case TIOCMBIS:
        case TIOCMBIC:
        case TIOCMSET:
@@ -2418,7 +2346,7 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
                dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
                cprev = mos7840_port->icount;
                while (1) {
-                       //interruptible_sleep_on(&mos7840_port->delta_msr_wait);
+                       /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */
                        mos7840_port->delta_msr_cond = 0;
                        wait_event_interruptible(mos7840_port->delta_msr_wait,
                                                 (mos7840_port->
@@ -2463,13 +2391,9 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
                if (copy_to_user(argp, &icount, sizeof(icount)))
                        return -EFAULT;
                return 0;
-
-       case TIOCEXBAUD:
-               return 0;
        default:
                break;
        }
-
        return -ENOIOCTLCMD;
 }
 
@@ -2527,8 +2451,9 @@ static int mos7840_startup(struct usb_serial *serial)
                        goto error;
                }
 
-               /* Initialize all port interrupt end point to port 0 int endpoint *
-                * Our device has only one interrupt end point comman to all port */
+               /* Initialize all port interrupt end point to port 0 int
+                * endpoint. Our device has only one interrupt end point
+                * common to all port */
 
                mos7840_port->port = serial->port[i];
                mos7840_set_port_private(serial->port[i], mos7840_port);
@@ -2564,27 +2489,23 @@ static int mos7840_startup(struct usb_serial *serial)
                        mos7840_port->DcrRegOffset = 0x1c;
                }
                mos7840_dump_serial_port(mos7840_port);
-
                mos7840_set_port_private(serial->port[i], mos7840_port);
 
-               //enable rx_disable bit in control register
-
-               status =
-                   mos7840_get_reg_sync(serial->port[i],
-                                        mos7840_port->ControlRegOffset, &Data);
+               /* enable rx_disable bit in control register */
+               status = mos7840_get_reg_sync(serial->port[i],
+                                mos7840_port->ControlRegOffset, &Data);
                if (status < 0) {
                        dbg("Reading ControlReg failed status-0x%x\n", status);
                        break;
                } else
                        dbg("ControlReg Reading success val is %x, status%d\n",
                            Data, status);
-               Data |= 0x08;   //setting driver done bit
-               Data |= 0x04;   //sp1_bit to have cts change reflect in modem status reg
+               Data |= 0x08;   /* setting driver done bit */
+               Data |= 0x04;   /* sp1_bit to have cts change reflect in
+                                  modem status reg */
 
-               //Data |= 0x20; //rx_disable bit
-               status = 0;
-               status =
-                   mos7840_set_reg_sync(serial->port[i],
+               /* Data |= 0x20; //rx_disable bit */
+               status = mos7840_set_reg_sync(serial->port[i],
                                         mos7840_port->ControlRegOffset, Data);
                if (status < 0) {
                        dbg("Writing ControlReg failed(rx_disable) status-0x%x\n", status);
@@ -2593,13 +2514,11 @@ static int mos7840_startup(struct usb_serial *serial)
                        dbg("ControlReg Writing success(rx_disable) status%d\n",
                            status);
 
-               //Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 and 0x24 in DCR3
+               /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
+                  and 0x24 in DCR3 */
                Data = 0x01;
-               status = 0;
-               status =
-                   mos7840_set_reg_sync(serial->port[i],
-                                        (__u16) (mos7840_port->DcrRegOffset +
-                                                 0), Data);
+               status = mos7840_set_reg_sync(serial->port[i],
+                        (__u16) (mos7840_port->DcrRegOffset + 0), Data);
                if (status < 0) {
                        dbg("Writing DCR0 failed status-0x%x\n", status);
                        break;
@@ -2607,11 +2526,8 @@ static int mos7840_startup(struct usb_serial *serial)
                        dbg("DCR0 Writing success status%d\n", status);
 
                Data = 0x05;
-               status = 0;
-               status =
-                   mos7840_set_reg_sync(serial->port[i],
-                                        (__u16) (mos7840_port->DcrRegOffset +
-                                                 1), Data);
+               status = mos7840_set_reg_sync(serial->port[i],
+                        (__u16) (mos7840_port->DcrRegOffset + 1), Data);
                if (status < 0) {
                        dbg("Writing DCR1 failed status-0x%x\n", status);
                        break;
@@ -2619,22 +2535,17 @@ static int mos7840_startup(struct usb_serial *serial)
                        dbg("DCR1 Writing success status%d\n", status);
 
                Data = 0x24;
-               status = 0;
-               status =
-                   mos7840_set_reg_sync(serial->port[i],
-                                        (__u16) (mos7840_port->DcrRegOffset +
-                                                 2), Data);
+               status = mos7840_set_reg_sync(serial->port[i],
+                        (__u16) (mos7840_port->DcrRegOffset + 2), Data);
                if (status < 0) {
                        dbg("Writing DCR2 failed status-0x%x\n", status);
                        break;
                } else
                        dbg("DCR2 Writing success status%d\n", status);
 
-               // write values in clkstart0x0 and clkmulti 0x20
+               /* write values in clkstart0x0 and clkmulti 0x20 */
                Data = 0x0;
-               status = 0;
-               status =
-                   mos7840_set_reg_sync(serial->port[i],
+               status = mos7840_set_reg_sync(serial->port[i],
                                         CLK_START_VALUE_REGISTER, Data);
                if (status < 0) {
                        dbg("Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status);
@@ -2643,9 +2554,8 @@ static int mos7840_startup(struct usb_serial *serial)
                        dbg("CLK_START_VALUE_REGISTER Writing success status%d\n", status);
 
                Data = 0x20;
-               status =
-                   mos7840_set_reg_sync(serial->port[i], CLK_MULTI_REGISTER,
-                                        Data);
+               status = mos7840_set_reg_sync(serial->port[i],
+                                       CLK_MULTI_REGISTER, Data);
                if (status < 0) {
                        dbg("Writing CLK_MULTI_REGISTER failed status-0x%x\n",
                            status);
@@ -2654,11 +2564,10 @@ static int mos7840_startup(struct usb_serial *serial)
                        dbg("CLK_MULTI_REGISTER Writing success status%d\n",
                            status);
 
-               //write value 0x0 to scratchpad register
+               /* write value 0x0 to scratchpad register */
                Data = 0x00;
-               status =
-                   mos7840_set_uart_reg(serial->port[i], SCRATCH_PAD_REGISTER,
-                                        Data);
+               status = mos7840_set_uart_reg(serial->port[i],
+                                               SCRATCH_PAD_REGISTER, Data);
                if (status < 0) {
                        dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x\n",
                            status);
@@ -2667,21 +2576,17 @@ static int mos7840_startup(struct usb_serial *serial)
                        dbg("SCRATCH_PAD_REGISTER Writing success status%d\n",
                            status);
 
-               //Zero Length flag register
+               /* Zero Length flag register */
                if ((mos7840_port->port_num != 1)
                    && (serial->num_ports == 2)) {
 
                        Data = 0xff;
-                       status = 0;
                        status = mos7840_set_reg_sync(serial->port[i],
-                                                     (__u16) (ZLP_REG1 +
-                                                              ((__u16)
-                                                               mos7840_port->
-                                                               port_num)),
-                                                     Data);
+                                     (__u16) (ZLP_REG1 +
+                                     ((__u16)mos7840_port->port_num)), Data);
                        dbg("ZLIP offset%x\n",
                            (__u16) (ZLP_REG1 +
-                                    ((__u16) mos7840_port->port_num)));
+                                       ((__u16) mos7840_port->port_num)));
                        if (status < 0) {
                                dbg("Writing ZLP_REG%d failed status-0x%x\n",
                                    i + 2, status);
@@ -2691,13 +2596,9 @@ static int mos7840_startup(struct usb_serial *serial)
                                    i + 2, status);
                } else {
                        Data = 0xff;
-                       status = 0;
                        status = mos7840_set_reg_sync(serial->port[i],
-                                                     (__u16) (ZLP_REG1 +
-                                                              ((__u16)
-                                                               mos7840_port->
-                                                               port_num) -
-                                                              0x1), Data);
+                             (__u16) (ZLP_REG1 +
+                             ((__u16)mos7840_port->port_num) - 0x1), Data);
                        dbg("ZLIP offset%x\n",
                            (__u16) (ZLP_REG1 +
                                     ((__u16) mos7840_port->port_num) - 0x1));
@@ -2712,14 +2613,16 @@ static int mos7840_startup(struct usb_serial *serial)
                }
                mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL);
                mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
-               mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
-               if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf || !mos7840_port->dr) {
+               mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest),
+                                                               GFP_KERNEL);
+               if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf ||
+                                                       !mos7840_port->dr) {
                        status = -ENOMEM;
                        goto error;
                }
        }
 
-       //Zero Length flag enable
+       /* Zero Length flag enable */
        Data = 0x0f;
        status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
        if (status < 0) {
@@ -2762,7 +2665,7 @@ static void mos7840_shutdown(struct usb_serial *serial)
                return;
        }
 
-       /*      check for the ports to be closed,close the ports and disconnect         */
+       /* check for the ports to be closed,close the ports and disconnect */
 
        /* free private structure allocated for serial port  *
         * stop reads and writes on all ports                */
@@ -2843,20 +2746,12 @@ static int __init moschip7840_init(void)
 
        /* Register with the usb */
        retval = usb_register(&io_driver);
-
-       if (retval)
-               goto failed_usb_register;
-
        if (retval == 0) {
                dbg("%s\n", "Leaving...");
                return 0;
        }
-
-      failed_usb_register:
        usb_serial_deregister(&moschip7840_4port_device);
-
-      failed_port_device_register:
-
+failed_port_device_register:
        return retval;
 }
 
index 43c8894353bff422fbd93ae9a600efeb750f8bd0..d6736531a0fab1be65f8fe78a01ffb3bc535a207 100644 (file)
@@ -64,7 +64,7 @@ static void navman_read_int_callback(struct urb *urb)
        usb_serial_debug_data(debug, &port->dev, __func__,
                              urb->actual_length, data);
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (tty && urb->actual_length) {
                tty_buffer_request_room(tty, urb->actual_length);
                tty_insert_flip_string(tty, data, urb->actual_length);
@@ -79,7 +79,8 @@ exit:
                        __func__, result);
 }
 
-static int navman_open(struct usb_serial_port *port, struct file *filp)
+static int navman_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        int result = 0;
 
@@ -96,14 +97,15 @@ static int navman_open(struct usb_serial_port *port, struct file *filp)
        return result;
 }
 
-static void navman_close(struct usb_serial_port *port, struct file *filp)
+static void navman_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        dbg("%s - port %d", __func__, port->number);
 
        usb_kill_urb(port->interrupt_in_urb);
 }
 
-static int navman_write(struct usb_serial_port *port,
+static int navman_write(struct tty_struct *tty, struct usb_serial_port *port,
                        const unsigned char *buf, int count)
 {
        dbg("%s - port %d", __func__, port->number);
index 7b7422f4947854008500f13cb3deabd2cde0be45..ae8e227f3db2c940a9cd0fb65b1be4641162ac95 100644 (file)
@@ -5,26 +5,28 @@
  *     modify it under the terms of the GNU General Public License version
  *     2 as published by the Free Software Foundation.
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
  *
  * Please report both successes and troubles to the author at omninet@kroah.com
- * 
+ *
  * (05/30/2001) gkh
- *     switched from using spinlock to a semaphore, which fixes lots of problems.
+ *     switched from using spinlock to a semaphore, which fixes lots of
+ *     problems.
  *
  * (04/08/2001) gb
  *     Identify version on module load.
  *
  * (11/01/2000) Adam J. Richter
  *     usb_device_id table support
- * 
+ *
  * (10/05/2000) gkh
  *     Fixed bug with urb->dev not being set properly, now that the usb
  *     core needs it.
- * 
+ *
  * (08/28/2000) gkh
  *     Added locks for SMP safeness.
- *     Fixed MOD_INC and MOD_DEC logic and the ability to open a port more 
+ *     Fixed MOD_INC and MOD_DEC logic and the ability to open a port more
  *     than once.
  *     Fixed potential race in omninet_write_bulk_callback
  *
@@ -43,7 +45,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
@@ -58,25 +60,29 @@ static int debug;
 
 #define ZYXEL_VENDOR_ID                0x0586
 #define ZYXEL_OMNINET_ID       0x1000
-#define BT_IGNITIONPRO_ID      0x2000  /* This one seems to be a re-branded ZyXEL device */
+/* This one seems to be a re-branded ZyXEL device */
+#define BT_IGNITIONPRO_ID      0x2000
 
 /* function prototypes */
-static int  omninet_open               (struct usb_serial_port *port, struct file *filp);
-static void omninet_close              (struct usb_serial_port *port, struct file *filp);
-static void omninet_read_bulk_callback (struct urb *urb);
-static void omninet_write_bulk_callback        (struct urb *urb);
-static int  omninet_write              (struct usb_serial_port *port, const unsigned char *buf, int count);
-static int  omninet_write_room         (struct usb_serial_port *port);
-static void omninet_shutdown           (struct usb_serial *serial);
-static int omninet_attach              (struct usb_serial *serial);
-
-static struct usb_device_id id_table [] = {
+static int  omninet_open(struct tty_struct *tty, struct usb_serial_port *port,
+                                                       struct file *filp);
+static void omninet_close(struct tty_struct *tty, struct usb_serial_port *port,
+                                                       struct file *filp);
+static void omninet_read_bulk_callback(struct urb *urb);
+static void omninet_write_bulk_callback(struct urb *urb);
+static int  omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
+                               const unsigned char *buf, int count);
+static int  omninet_write_room(struct tty_struct *tty);
+static void omninet_shutdown(struct usb_serial *serial);
+static int omninet_attach(struct usb_serial *serial);
+
+static struct usb_device_id id_table[] = {
        { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) },
        { USB_DEVICE(ZYXEL_VENDOR_ID, BT_IGNITIONPRO_ID) },
        { }                                             /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver omninet_driver = {
        .name =         "omninet",
@@ -130,34 +136,34 @@ static struct usb_serial_driver zyxel_omninet_device = {
  *
  */
 
-struct omninet_header
-{
+struct omninet_header {
        __u8    oh_seq;
        __u8    oh_len;
        __u8    oh_xxx;
        __u8    oh_pad;
 };
 
-struct omninet_data
-{
-       __u8    od_outseq;      // Sequence number for bulk_out URBs
+struct omninet_data {
+       __u8    od_outseq;      /* Sequence number for bulk_out URBs */
 };
 
-static int omninet_attach (struct usb_serial *serial)
+static int omninet_attach(struct usb_serial *serial)
 {
        struct omninet_data *od;
        struct usb_serial_port *port = serial->port[0];
 
-       od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL );
-       if( !od ) {
-               err("%s- kmalloc(%Zd) failed.", __func__, sizeof(struct omninet_data));
+       od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL);
+       if (!od) {
+               err("%s- kmalloc(%Zd) failed.",
+                               __func__, sizeof(struct omninet_data));
                return -ENOMEM;
        }
        usb_set_serial_port_data(port, od);
        return 0;
 }
 
-static int omninet_open (struct usb_serial_port *port, struct file *filp)
+static int omninet_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial       *serial = port->serial;
        struct usb_serial_port  *wport;
@@ -166,22 +172,24 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp)
        dbg("%s - port %d", __func__, port->number);
 
        wport = serial->port[1];
-       wport->tty = port->tty;
+       wport->port.tty = tty;          /* FIXME */
 
        /* Start reading from the device */
-       usb_fill_bulk_urb(port->read_urb, serial->dev, 
-                     usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
-                     port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
-                     omninet_read_bulk_callback, port);
+       usb_fill_bulk_urb(port->read_urb, serial->dev,
+                       usb_rcvbulkpipe(serial->dev,
+                               port->bulk_in_endpointAddress),
+                       port->read_urb->transfer_buffer,
+                       port->read_urb->transfer_buffer_length,
+                       omninet_read_bulk_callback, port);
        result = usb_submit_urb(port->read_urb, GFP_KERNEL);
-       if (result) {
-               err("%s - failed submitting read urb, error %d", __func__, result);
-       }
-
+       if (result)
+               err("%s - failed submitting read urb, error %d",
+                                                       __func__, result);
        return result;
 }
 
-static void omninet_close (struct usb_serial_port *port, struct file * filp)
+static void omninet_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        dbg("%s - port %d", __func__, port->number);
        usb_kill_urb(port->read_urb);
@@ -192,14 +200,14 @@ static void omninet_close (struct usb_serial_port *port, struct file * filp)
 #define OMNINET_HEADERLEN      sizeof(struct omninet_header)
 #define OMNINET_BULKOUTSIZE    (64 - OMNINET_HEADERLEN)
 
-static void omninet_read_bulk_callback (struct urb *urb)
+static void omninet_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port  *port   = urb->context;
        unsigned char           *data   = urb->transfer_buffer;
        struct omninet_header   *header = (struct omninet_header *) &data[0];
        int status = urb->status;
-       int i;
        int result;
+       int i;
 
        dbg("%s - port %d", __func__, port->number);
 
@@ -209,42 +217,46 @@ static void omninet_read_bulk_callback (struct urb *urb)
                return;
        }
 
-       if ((debug) && (header->oh_xxx != 0x30)) {
+       if (debug && header->oh_xxx != 0x30) {
                if (urb->actual_length) {
-                       printk (KERN_DEBUG __FILE__ ": omninet_read %d: ", header->oh_len);
-                       for (i = 0; i < (header->oh_len + OMNINET_HEADERLEN); i++) {
-                               printk ("%.2x ", data[i]);
-                       }
-                       printk ("\n");
+                       printk(KERN_DEBUG __FILE__
+                                       ": omninet_read %d: ", header->oh_len);
+                       for (i = 0; i < (header->oh_len +
+                                               OMNINET_HEADERLEN); i++)
+                               printk("%.2x ", data[i]);
+                       printk("\n");
                }
        }
 
        if (urb->actual_length && header->oh_len) {
-               for (i = 0; i < header->oh_len; i++) {
-                        tty_insert_flip_char(port->tty, data[OMNINET_DATAOFFSET + i], 0);
-               }
-               tty_flip_buffer_push(port->tty);
+               tty_insert_flip_string(port->port.tty,
+                       data + OMNINET_DATAOFFSET, header->oh_len);
+               tty_flip_buffer_push(port->port.tty);
        }
 
        /* Continue trying to always read  */
-       usb_fill_bulk_urb(urb, port->serial->dev, 
-                     usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress),
-                     urb->transfer_buffer, urb->transfer_buffer_length,
-                     omninet_read_bulk_callback, port);
+       usb_fill_bulk_urb(urb, port->serial->dev,
+                       usb_rcvbulkpipe(port->serial->dev,
+                                       port->bulk_in_endpointAddress),
+                       urb->transfer_buffer, urb->transfer_buffer_length,
+                       omninet_read_bulk_callback, port);
        result = usb_submit_urb(urb, GFP_ATOMIC);
        if (result)
-               err("%s - failed resubmitting read urb, error %d", __func__, result);
+               err("%s - failed resubmitting read urb, error %d",
+                                               __func__, result);
 
        return;
 }
 
-static int omninet_write (struct usb_serial_port *port, const unsigned char *buf, int count)
+static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                       const unsigned char *buf, int count)
 {
-       struct usb_serial       *serial = port->serial;
-       struct usb_serial_port  *wport  = serial->port[1];
+       struct usb_serial *serial = port->serial;
+       struct usb_serial_port *wport = serial->port[1];
 
-       struct omninet_data     *od     = usb_get_serial_port_data(port);
-       struct omninet_header   *header = (struct omninet_header *) wport->write_urb->transfer_buffer;
+       struct omninet_data *od = usb_get_serial_port_data(port);
+       struct omninet_header *header = (struct omninet_header *)
+                                       wport->write_urb->transfer_buffer;
 
        int                     result;
 
@@ -252,7 +264,7 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf
 
        if (count == 0) {
                dbg("%s - write request of 0 bytes", __func__);
-               return (0);
+               return 0;
        }
 
        spin_lock_bh(&wport->lock);
@@ -266,9 +278,11 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf
 
        count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count;
 
-       memcpy (wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, buf, count);
+       memcpy(wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET,
+                                                               buf, count);
 
-       usb_serial_debug_data(debug, &port->dev, __func__, count, wport->write_urb->transfer_buffer);
+       usb_serial_debug_data(debug, &port->dev, __func__, count,
+                                       wport->write_urb->transfer_buffer);
 
        header->oh_seq  = od->od_outseq++;
        header->oh_len  = count;
@@ -282,7 +296,8 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf
        result = usb_submit_urb(wport->write_urb, GFP_ATOMIC);
        if (result) {
                wport->write_urb_busy = 0;
-               err("%s - failed submitting write urb, error %d", __func__, result);
+               err("%s - failed submitting write urb, error %d",
+                                                       __func__, result);
        } else
                result = count;
 
@@ -290,8 +305,9 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf
 }
 
 
-static int omninet_write_room (struct usb_serial_port *port)
+static int omninet_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct usb_serial       *serial = port->serial;
        struct usb_serial_port  *wport  = serial->port[1];
 
@@ -303,12 +319,13 @@ static int omninet_write_room (struct usb_serial_port *port)
 
        dbg("%s - returns %d", __func__, room);
 
-       return (room);
+       return room;
 }
 
-static void omninet_write_bulk_callback (struct urb *urb)
+static void omninet_write_bulk_callback(struct urb *urb)
 {
-/*     struct omninet_header   *header = (struct omninet_header  *) urb->transfer_buffer; */
+/*     struct omninet_header   *header = (struct omninet_header  *)
+                                               urb->transfer_buffer; */
        struct usb_serial_port  *port   =  urb->context;
        int status = urb->status;
 
@@ -325,18 +342,18 @@ static void omninet_write_bulk_callback (struct urb *urb)
 }
 
 
-static void omninet_shutdown (struct usb_serial *serial)
+static void omninet_shutdown(struct usb_serial *serial)
 {
        struct usb_serial_port *wport = serial->port[1];
        struct usb_serial_port *port = serial->port[0];
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        usb_kill_urb(wport->write_urb);
        kfree(usb_get_serial_port_data(port));
 }
 
 
-static int __init omninet_init (void)
+static int __init omninet_init(void)
 {
        int retval;
        retval = usb_serial_register(&zyxel_omninet_device);
@@ -354,18 +371,18 @@ failed_usb_serial_register:
 }
 
 
-static void __exit omninet_exit (void)
+static void __exit omninet_exit(void)
 {
-       usb_deregister (&omninet_driver);
-       usb_serial_deregister (&zyxel_omninet_device);
+       usb_deregister(&omninet_driver);
+       usb_serial_deregister(&zyxel_omninet_device);
 }
 
 
 module_init(omninet_init);
 module_exit(omninet_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
index a73420dd052a511846be7466050355380d0b970d..e4eca95f2b0f7aa984cc8194ad0f4c755a908116 100644 (file)
 #include <linux/usb/serial.h>
 
 /* Function prototypes */
-static int  option_open(struct usb_serial_port *port, struct file *filp);
-static void option_close(struct usb_serial_port *port, struct file *filp);
+static int  option_open(struct tty_struct *tty, struct usb_serial_port *port,
+                                                       struct file *filp);
+static void option_close(struct tty_struct *tty, struct usb_serial_port *port,
+                                                       struct file *filp);
 static int  option_startup(struct usb_serial *serial);
 static void option_shutdown(struct usb_serial *serial);
-static void option_rx_throttle(struct usb_serial_port *port);
-static void option_rx_unthrottle(struct usb_serial_port *port);
-static int  option_write_room(struct usb_serial_port *port);
+static int  option_write_room(struct tty_struct *tty);
 
 static void option_instat_callback(struct urb *urb);
 
-static int option_write(struct usb_serial_port *port,
+static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
                        const unsigned char *buf, int count);
-
-static int  option_chars_in_buffer(struct usb_serial_port *port);
-static int  option_ioctl(struct usb_serial_port *port, struct file *file,
-                       unsigned int cmd, unsigned long arg);
-static void option_set_termios(struct usb_serial_port *port,
-                               struct ktermios *old);
-static void option_break_ctl(struct usb_serial_port *port, int break_state);
-static int  option_tiocmget(struct usb_serial_port *port, struct file *file);
-static int  option_tiocmset(struct usb_serial_port *port, struct file *file,
+static int  option_chars_in_buffer(struct tty_struct *tty);
+static void option_set_termios(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct ktermios *old);
+static int  option_tiocmget(struct tty_struct *tty, struct file *file);
+static int  option_tiocmset(struct tty_struct *tty, struct file *file,
                                unsigned int set, unsigned int clear);
-static int  option_send_setup(struct usb_serial_port *port);
+static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *port);
 
 /* Vendor and product IDs */
 #define OPTION_VENDOR_ID                       0x0AF0
@@ -173,6 +169,7 @@ static int  option_send_setup(struct usb_serial_port *port);
 #define DELL_VENDOR_ID                         0x413C
 
 #define KYOCERA_VENDOR_ID                      0x0c88
+#define KYOCERA_PRODUCT_KPC650                 0x17da
 #define KYOCERA_PRODUCT_KPC680                 0x180a
 
 #define ANYDATA_VENDOR_ID                      0x16d5
@@ -305,6 +302,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) },
        { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
        { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
+       { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) },
        { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
@@ -340,11 +338,7 @@ static struct usb_serial_driver option_1port_device = {
        .write             = option_write,
        .write_room        = option_write_room,
        .chars_in_buffer   = option_chars_in_buffer,
-       .throttle          = option_rx_throttle,
-       .unthrottle        = option_rx_unthrottle,
-       .ioctl             = option_ioctl,
        .set_termios       = option_set_termios,
-       .break_ctl         = option_break_ctl,
        .tiocmget          = option_tiocmget,
        .tiocmset          = option_tiocmset,
        .attach            = option_startup,
@@ -401,47 +395,32 @@ static int __init option_init(void)
        return 0;
 
 failed_driver_register:
-       usb_serial_deregister (&option_1port_device);
+       usb_serial_deregister(&option_1port_device);
 failed_1port_device_register:
        return retval;
 }
 
 static void __exit option_exit(void)
 {
-       usb_deregister (&option_driver);
-       usb_serial_deregister (&option_1port_device);
+       usb_deregister(&option_driver);
+       usb_serial_deregister(&option_1port_device);
 }
 
 module_init(option_init);
 module_exit(option_exit);
 
-static void option_rx_throttle(struct usb_serial_port *port)
-{
-       dbg("%s", __func__);
-}
-
-static void option_rx_unthrottle(struct usb_serial_port *port)
-{
-       dbg("%s", __func__);
-}
-
-static void option_break_ctl(struct usb_serial_port *port, int break_state)
-{
-       /* Unfortunately, I don't know how to send a break */
-       dbg("%s", __func__);
-}
-
-static void option_set_termios(struct usb_serial_port *port,
-                       struct ktermios *old_termios)
+static void option_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        dbg("%s", __func__);
        /* Doesn't support option setting */
-       tty_termios_copy_hw(port->tty->termios, old_termios);
-       option_send_setup(port);
+       tty_termios_copy_hw(tty->termios, old_termios);
+       option_send_setup(tty, port);
 }
 
-static int option_tiocmget(struct usb_serial_port *port, struct file *file)
+static int option_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        unsigned int value;
        struct option_port_private *portdata;
 
@@ -457,9 +436,10 @@ static int option_tiocmget(struct usb_serial_port *port, struct file *file)
        return value;
 }
 
-static int option_tiocmset(struct usb_serial_port *port, struct file *file,
+static int option_tiocmset(struct tty_struct *tty, struct file *file,
                        unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct option_port_private *portdata;
 
        portdata = usb_get_serial_port_data(port);
@@ -474,17 +454,11 @@ static int option_tiocmset(struct usb_serial_port *port, struct file *file,
                portdata->rts_state = 0;
        if (clear & TIOCM_DTR)
                portdata->dtr_state = 0;
-       return option_send_setup(port);
-}
-
-static int option_ioctl(struct usb_serial_port *port, struct file *file,
-                       unsigned int cmd, unsigned long arg)
-{
-       return -ENOIOCTLCMD;
+       return option_send_setup(tty, port);
 }
 
 /* Write */
-static int option_write(struct usb_serial_port *port,
+static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
                        const unsigned char *buf, int count)
 {
        struct option_port_private *portdata;
@@ -499,7 +473,7 @@ static int option_write(struct usb_serial_port *port,
 
        i = 0;
        left = count;
-       for (i=0; left > 0 && i < N_OUT_URB; i++) {
+       for (i = 0; left > 0 && i < N_OUT_URB; i++) {
                todo = left;
                if (todo > OUT_BUFLEN)
                        todo = OUT_BUFLEN;
@@ -520,7 +494,7 @@ static int option_write(struct usb_serial_port *port,
                        usb_pipeendpoint(this_urb->pipe), i);
 
                /* send the data */
-               memcpy (this_urb->transfer_buffer, buf, todo);
+               memcpy(this_urb->transfer_buffer, buf, todo);
                this_urb->transfer_buffer_length = todo;
 
                this_urb->dev = port->serial->dev;
@@ -560,7 +534,7 @@ static void option_indat_callback(struct urb *urb)
                dbg("%s: nonzero status: %d on endpoint %02x.",
                    __func__, status, endpoint);
        } else {
-               tty = port->tty;
+               tty = port->port.tty;
                if (urb->actual_length) {
                        tty_buffer_request_room(tty, urb->actual_length);
                        tty_insert_flip_string(tty, data, urb->actual_length);
@@ -570,7 +544,7 @@ static void option_indat_callback(struct urb *urb)
                }
 
                /* Resubmit urb so we continue receiving */
-               if (port->open_count && status != -ESHUTDOWN) {
+               if (port->port.count && status != -ESHUTDOWN) {
                        err = usb_submit_urb(urb, GFP_ATOMIC);
                        if (err)
                                printk(KERN_ERR "%s: resubmit read urb failed. "
@@ -611,7 +585,7 @@ static void option_instat_callback(struct urb *urb)
        struct usb_serial *serial = port->serial;
 
        dbg("%s", __func__);
-       dbg("%s: urb %p port %p has data %p", __func__,urb,port,portdata);
+       dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata);
 
        if (status == 0) {
                struct usb_ctrlrequest *req_pkt =
@@ -636,12 +610,12 @@ static void option_instat_callback(struct urb *urb)
                        portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
                        portdata->ri_state = ((signals & 0x08) ? 1 : 0);
 
-                       if (port->tty && !C_CLOCAL(port->tty) &&
+                       if (port->port.tty && !C_CLOCAL(port->port.tty) &&
                                        old_dcd_state && !portdata->dcd_state)
-                               tty_hangup(port->tty);
+                               tty_hangup(port->port.tty);
                } else {
                        dbg("%s: type %x req %x", __func__,
-                               req_pkt->bRequestType,req_pkt->bRequest);
+                               req_pkt->bRequestType, req_pkt->bRequest);
                }
        } else
                dbg("%s: error %d", __func__, status);
@@ -656,8 +630,9 @@ static void option_instat_callback(struct urb *urb)
        }
 }
 
-static int option_write_room(struct usb_serial_port *port)
+static int option_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct option_port_private *portdata;
        int i;
        int data_len = 0;
@@ -666,7 +641,7 @@ static int option_write_room(struct usb_serial_port *port)
        portdata = usb_get_serial_port_data(port);
 
 
-       for (i=0; i < N_OUT_URB; i++) {
+       for (i = 0; i < N_OUT_URB; i++) {
                this_urb = portdata->out_urbs[i];
                if (this_urb && !test_bit(i, &portdata->out_busy))
                        data_len += OUT_BUFLEN;
@@ -676,8 +651,9 @@ static int option_write_room(struct usb_serial_port *port)
        return data_len;
 }
 
-static int option_chars_in_buffer(struct usb_serial_port *port)
+static int option_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct option_port_private *portdata;
        int i;
        int data_len = 0;
@@ -685,7 +661,7 @@ static int option_chars_in_buffer(struct usb_serial_port *port)
 
        portdata = usb_get_serial_port_data(port);
 
-       for (i=0; i < N_OUT_URB; i++) {
+       for (i = 0; i < N_OUT_URB; i++) {
                this_urb = portdata->out_urbs[i];
                /* FIXME: This locking is insufficient as this_urb may
                   go unused during the test */
@@ -696,7 +672,8 @@ static int option_chars_in_buffer(struct usb_serial_port *port)
        return data_len;
 }
 
-static int option_open(struct usb_serial_port *port, struct file *filp)
+static int option_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct option_port_private *portdata;
        struct usb_serial *serial = port->serial;
@@ -714,7 +691,7 @@ static int option_open(struct usb_serial_port *port, struct file *filp)
        /* Reset low level data toggle and start reading from endpoints */
        for (i = 0; i < N_IN_URB; i++) {
                urb = portdata->in_urbs[i];
-               if (! urb)
+               if (!urb)
                        continue;
                if (urb->dev != serial->dev) {
                        dbg("%s: dev %p != %p", __func__,
@@ -739,21 +716,23 @@ static int option_open(struct usb_serial_port *port, struct file *filp)
        /* Reset low level data toggle on out endpoints */
        for (i = 0; i < N_OUT_URB; i++) {
                urb = portdata->out_urbs[i];
-               if (! urb)
+               if (!urb)
                        continue;
                urb->dev = serial->dev;
                /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
                                usb_pipeout(urb->pipe), 0); */
        }
 
-       port->tty->low_latency = 1;
+       if (tty)
+               tty->low_latency = 1;
 
-       option_send_setup(port);
+       option_send_setup(tty, port);
 
-       return (0);
+       return 0;
 }
 
-static void option_close(struct usb_serial_port *port, struct file *filp)
+static void option_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        int i;
        struct usb_serial *serial = port->serial;
@@ -768,7 +747,7 @@ static void option_close(struct usb_serial_port *port, struct file *filp)
        if (serial->dev) {
                mutex_lock(&serial->disc_mutex);
                if (!serial->disconnected)
-                       option_send_setup(port);
+                       option_send_setup(tty, port);
                mutex_unlock(&serial->disc_mutex);
 
                /* Stop reading/writing urbs */
@@ -777,7 +756,7 @@ static void option_close(struct usb_serial_port *port, struct file *filp)
                for (i = 0; i < N_OUT_URB; i++)
                        usb_kill_urb(portdata->out_urbs[i]);
        }
-       port->tty = NULL;
+       port->port.tty = NULL;  /* FIXME */
 }
 
 /* Helper functions used by option_setup_urbs */
@@ -807,7 +786,7 @@ static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint,
 /* Setup urbs */
 static void option_setup_urbs(struct usb_serial *serial)
 {
-       int i,j;
+       int i, j;
        struct usb_serial_port *port;
        struct option_port_private *portdata;
 
@@ -817,18 +796,22 @@ static void option_setup_urbs(struct usb_serial *serial)
                port = serial->port[i];
                portdata = usb_get_serial_port_data(port);
 
-       /* Do indat endpoints first */
+               /* Do indat endpoints first */
                for (j = 0; j < N_IN_URB; ++j) {
-                       portdata->in_urbs[j] = option_setup_urb (serial,
-                       port->bulk_in_endpointAddress, USB_DIR_IN, port,
-                       portdata->in_buffer[j], IN_BUFLEN, option_indat_callback);
+                       portdata->in_urbs[j] = option_setup_urb(serial,
+                                       port->bulk_in_endpointAddress,
+                                       USB_DIR_IN, port,
+                                       portdata->in_buffer[j],
+                                       IN_BUFLEN, option_indat_callback);
                }
 
                /* outdat endpoints */
                for (j = 0; j < N_OUT_URB; ++j) {
-                       portdata->out_urbs[j] = option_setup_urb (serial,
-                       port->bulk_out_endpointAddress, USB_DIR_OUT, port,
-                       portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback);
+                       portdata->out_urbs[j] = option_setup_urb(serial,
+                                       port->bulk_out_endpointAddress,
+                                       USB_DIR_OUT, port,
+                                       portdata->out_buffer[j],
+                                       OUT_BUFLEN, option_outdat_callback);
                }
        }
 }
@@ -839,7 +822,8 @@ static void option_setup_urbs(struct usb_serial *serial)
  * This is exactly the same as SET_CONTROL_LINE_STATE from the PSTN
  * CDC.
 */
-static int option_send_setup(struct usb_serial_port *port)
+static int option_send_setup(struct tty_struct *tty,
+                                               struct usb_serial_port *port)
 {
        struct usb_serial *serial = port->serial;
        struct option_port_private *portdata;
@@ -848,7 +832,7 @@ static int option_send_setup(struct usb_serial_port *port)
 
        portdata = usb_get_serial_port_data(port);
 
-       if (port->tty) {
+       if (tty) {
                int val = 0;
                if (portdata->dtr_state)
                        val |= 0x01;
@@ -856,10 +840,9 @@ static int option_send_setup(struct usb_serial_port *port)
                        val |= 0x02;
 
                return usb_control_msg(serial->dev,
-                               usb_rcvctrlpipe(serial->dev, 0),
-                               0x22,0x21,val,ifNum,NULL,0,USB_CTRL_SET_TIMEOUT);
+                       usb_rcvctrlpipe(serial->dev, 0),
+                       0x22, 0x21, val, ifNum, NULL, 0, USB_CTRL_SET_TIMEOUT);
        }
-
        return 0;
 }
 
@@ -879,7 +862,7 @@ static int option_startup(struct usb_serial *serial)
                if (!portdata) {
                        dbg("%s: kmalloc for option_port_private (%d) failed!.",
                                        __func__, i);
-                       return (1);
+                       return 1;
                }
 
                for (j = 0; j < N_IN_URB; j++) {
@@ -898,17 +881,15 @@ static int option_startup(struct usb_serial *serial)
 
                usb_set_serial_port_data(port, portdata);
 
-               if (! port->interrupt_in_urb)
+               if (!port->interrupt_in_urb)
                        continue;
                err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
                if (err)
                        dbg("%s: submit irq_in urb failed %d",
                                __func__, err);
        }
-
        option_setup_urbs(serial);
-
-       return (0);
+       return 0;
 
 bail_out_error2:
        for (j = 0; j < N_OUT_URB; j++)
@@ -947,7 +928,8 @@ static void option_shutdown(struct usb_serial *serial)
                for (j = 0; j < N_IN_URB; j++) {
                        if (portdata->in_urbs[j]) {
                                usb_free_urb(portdata->in_urbs[j]);
-                               free_page((unsigned long)portdata->in_buffer[j]);
+                               free_page((unsigned long)
+                                       portdata->in_buffer[j]);
                                portdata->in_urbs[j] = NULL;
                        }
                }
index a9625c180dc3502206d2d967224a1d6ea31d2bf5..81db5715ee25ef5d0769494a11318c4cf866e0ad 100644 (file)
@@ -25,7 +25,8 @@
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License.
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
  *
  * TODO:
  *  - implement correct flushing for ioctls and oti6858_close()
@@ -49,7 +50,7 @@
 #include <linux/spinlock.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include "oti6858.h"
 
 #define OTI6858_DESCRIPTION \
@@ -135,27 +136,28 @@ struct oti6858_control_pkt {
 
 #define OTI6858_CTRL_PKT_SIZE  sizeof(struct oti6858_control_pkt)
 #define OTI6858_CTRL_EQUALS_PENDING(a, priv) \
-       (    ((a)->divisor == (priv)->pending_setup.divisor) \
+       (((a)->divisor == (priv)->pending_setup.divisor) \
          && ((a)->control == (priv)->pending_setup.control) \
-         && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt) )
+         && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt))
 
 /* function prototypes */
-static int oti6858_open(struct usb_serial_port *port, struct file *filp);
-static void oti6858_close(struct usb_serial_port *port, struct file *filp);
-static void oti6858_set_termios(struct usb_serial_port *port,
-                               struct ktermios *old);
-static int oti6858_ioctl(struct usb_serial_port *port, struct file *file,
+static int oti6858_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static void oti6858_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static void oti6858_set_termios(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct ktermios *old);
+static int oti6858_ioctl(struct tty_struct *tty, struct file *file,
                        unsigned int cmd, unsigned long arg);
 static void oti6858_read_int_callback(struct urb *urb);
 static void oti6858_read_bulk_callback(struct urb *urb);
 static void oti6858_write_bulk_callback(struct urb *urb);
-static int oti6858_write(struct usb_serial_port *port,
+static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
                        const unsigned char *buf, int count);
-static int oti6858_write_room(struct usb_serial_port *port);
-static void oti6858_break_ctl(struct usb_serial_port *port, int break_state);
-static int oti6858_chars_in_buffer(struct usb_serial_port *port);
-static int oti6858_tiocmget(struct usb_serial_port *port, struct file *file);
-static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file,
+static int oti6858_write_room(struct tty_struct *tty);
+static int oti6858_chars_in_buffer(struct tty_struct *tty);
+static int oti6858_tiocmget(struct tty_struct *tty, struct file *file);
+static int oti6858_tiocmset(struct tty_struct *tty, struct file *file,
                                unsigned int set, unsigned int clear);
 static int oti6858_startup(struct usb_serial *serial);
 static void oti6858_shutdown(struct usb_serial *serial);
@@ -184,7 +186,6 @@ static struct usb_serial_driver oti6858_device = {
        .close =                oti6858_close,
        .write =                oti6858_write,
        .ioctl =                oti6858_ioctl,
-       .break_ctl =            oti6858_break_ctl,
        .set_termios =          oti6858_set_termios,
        .tiocmget =             oti6858_tiocmget,
        .tiocmset =             oti6858_tiocmset,
@@ -220,7 +221,7 @@ struct oti6858_private {
        struct delayed_work delayed_setup_work;
 
        wait_queue_head_t intr_wait;
-        struct usb_serial_port *port;   /* USB port with which associated */
+       struct usb_serial_port *port;   /* USB port with which associated */
 };
 
 #undef dbg
@@ -229,7 +230,8 @@ struct oti6858_private {
 
 static void setup_line(struct work_struct *work)
 {
-       struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_setup_work.work);
+       struct oti6858_private *priv = container_of(work,
+                       struct oti6858_private, delayed_setup_work.work);
        struct usb_serial_port *port = priv->port;
        struct oti6858_control_pkt *new_setup;
        unsigned long flags;
@@ -237,10 +239,12 @@ static void setup_line(struct work_struct *work)
 
        dbg("%s(port = %d)", __func__, port->number);
 
-       if ((new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) {
+       new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL);
+       if (new_setup == NULL) {
                dev_err(&port->dev, "%s(): out of memory!\n", __func__);
                /* we will try again */
-               schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2));
+               schedule_delayed_work(&priv->delayed_setup_work,
+                                               msecs_to_jiffies(2));
                return;
        }
 
@@ -256,7 +260,8 @@ static void setup_line(struct work_struct *work)
                dev_err(&port->dev, "%s(): error reading status\n", __func__);
                kfree(new_setup);
                /* we will try again */
-               schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2));
+               schedule_delayed_work(&priv->delayed_setup_work,
+                                                       msecs_to_jiffies(2));
                return;
        }
 
@@ -297,7 +302,8 @@ static void setup_line(struct work_struct *work)
 
 void send_data(struct work_struct *work)
 {
-       struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_write_work.work);
+       struct oti6858_private *priv = container_of(work,
+                       struct oti6858_private, delayed_write_work.work);
        struct usb_serial_port *port = priv->port;
        int count = 0, result;
        unsigned long flags;
@@ -308,7 +314,8 @@ void send_data(struct work_struct *work)
        spin_lock_irqsave(&priv->lock, flags);
        if (priv->flags.write_urb_in_use) {
                spin_unlock_irqrestore(&priv->lock, flags);
-               schedule_delayed_work(&priv->delayed_write_work, msecs_to_jiffies(2));
+               schedule_delayed_work(&priv->delayed_write_work,
+                                               msecs_to_jiffies(2));
                return;
        }
        priv->flags.write_urb_in_use = 1;
@@ -359,8 +366,8 @@ void send_data(struct work_struct *work)
 
 static int oti6858_startup(struct usb_serial *serial)
 {
-        struct usb_serial_port *port = serial->port[0];
-        struct oti6858_private *priv;
+       struct usb_serial_port *port = serial->port[0];
+       struct oti6858_private *priv;
        int i;
 
        for (i = 0; i < serial->num_ports; ++i) {
@@ -375,8 +382,8 @@ static int oti6858_startup(struct usb_serial *serial)
 
                spin_lock_init(&priv->lock);
                init_waitqueue_head(&priv->intr_wait);
-//             INIT_WORK(&priv->setup_work, setup_line, serial->port[i]);
-//             INIT_WORK(&priv->write_work, send_data, serial->port[i]);
+/*             INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */
+/*             INIT_WORK(&priv->write_work, send_data, serial->port[i]); */
                priv->port = port;
                INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line);
                INIT_DELAYED_WORK(&priv->delayed_write_work, send_data);
@@ -395,7 +402,7 @@ static int oti6858_startup(struct usb_serial *serial)
        return -ENOMEM;
 }
 
-static int oti6858_write(struct usb_serial_port *port,
+static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
                        const unsigned char *buf, int count)
 {
        struct oti6858_private *priv = usb_get_serial_port_data(port);
@@ -413,8 +420,9 @@ static int oti6858_write(struct usb_serial_port *port,
        return count;
 }
 
-static int oti6858_write_room(struct usb_serial_port *port)
+static int oti6858_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct oti6858_private *priv = usb_get_serial_port_data(port);
        int room = 0;
        unsigned long flags;
@@ -428,8 +436,9 @@ static int oti6858_write_room(struct usb_serial_port *port)
        return room;
 }
 
-static int oti6858_chars_in_buffer(struct usb_serial_port *port)
+static int oti6858_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct oti6858_private *priv = usb_get_serial_port_data(port);
        int chars = 0;
        unsigned long flags;
@@ -443,8 +452,8 @@ static int oti6858_chars_in_buffer(struct usb_serial_port *port)
        return chars;
 }
 
-static void oti6858_set_termios(struct usb_serial_port *port,
-                               struct ktermios *old_termios)
+static void oti6858_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        struct oti6858_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
@@ -455,22 +464,22 @@ static void oti6858_set_termios(struct usb_serial_port *port,
 
        dbg("%s(port = %d)", __func__, port->number);
 
-       if (!port->tty || !port->tty->termios) {
+       if (!tty) {
                dbg("%s(): no tty structures", __func__);
                return;
        }
 
        spin_lock_irqsave(&priv->lock, flags);
        if (!priv->flags.termios_initialized) {
-               *(port->tty->termios) = tty_std_termios;
-               port->tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
+               *(tty->termios) = tty_std_termios;
+               tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
+               tty->termios->c_ispeed = 38400;
+               tty->termios->c_ospeed = 38400;
                priv->flags.termios_initialized = 1;
-               port->tty->termios->c_ispeed = 38400;
-               port->tty->termios->c_ospeed = 38400;
        }
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       cflag = port->tty->termios->c_cflag;
+       cflag = tty->termios->c_cflag;
 
        spin_lock_irqsave(&priv->lock, flags);
        divisor = priv->pending_setup.divisor;
@@ -480,19 +489,19 @@ static void oti6858_set_termios(struct usb_serial_port *port,
 
        frame_fmt &= ~FMT_DATA_BITS_MASK;
        switch (cflag & CSIZE) {
-               case CS5:
-                       frame_fmt |= FMT_DATA_BITS_5;
-                       break;
-               case CS6:
-                       frame_fmt |= FMT_DATA_BITS_6;
-                       break;
-               case CS7:
-                       frame_fmt |= FMT_DATA_BITS_7;
-                       break;
-               default:
-               case CS8:
-                       frame_fmt |= FMT_DATA_BITS_8;
-                       break;
+       case CS5:
+               frame_fmt |= FMT_DATA_BITS_5;
+               break;
+       case CS6:
+               frame_fmt |= FMT_DATA_BITS_6;
+               break;
+       case CS7:
+               frame_fmt |= FMT_DATA_BITS_7;
+               break;
+       default:
+       case CS8:
+               frame_fmt |= FMT_DATA_BITS_8;
+               break;
        }
 
        /* manufacturer claims that this device can work with baud rates
@@ -500,7 +509,7 @@ static void oti6858_set_termios(struct usb_serial_port *port,
         * guarantee that any other baud rate will work (especially
         * the higher ones)
         */
-       br = tty_get_baud_rate(port->tty);
+       br = tty_get_baud_rate(tty);
        if (br == 0) {
                divisor = 0;
        } else {
@@ -511,23 +520,21 @@ static void oti6858_set_termios(struct usb_serial_port *port,
                new_divisor = (96000000 + 8 * br) / (16 * br);
                real_br = 96000000 / (16 * new_divisor);
                divisor = cpu_to_le16(new_divisor);
-               tty_encode_baud_rate(port->tty, real_br, real_br);
+               tty_encode_baud_rate(tty, real_br, real_br);
        }
 
        frame_fmt &= ~FMT_STOP_BITS_MASK;
-       if ((cflag & CSTOPB) != 0) {
+       if ((cflag & CSTOPB) != 0)
                frame_fmt |= FMT_STOP_BITS_2;
-       } else {
+       else
                frame_fmt |= FMT_STOP_BITS_1;
-       }
 
        frame_fmt &= ~FMT_PARITY_MASK;
        if ((cflag & PARENB) != 0) {
-               if ((cflag & PARODD) != 0) {
+               if ((cflag & PARODD) != 0)
                        frame_fmt |= FMT_PARITY_ODD;
-               } else {
+               else
                        frame_fmt |= FMT_PARITY_EVEN;
-               }
        } else {
                frame_fmt |= FMT_PARITY_NONE;
        }
@@ -564,7 +571,8 @@ static void oti6858_set_termios(struct usb_serial_port *port,
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static int oti6858_open(struct usb_serial_port *port, struct file *filp)
+static int oti6858_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct oti6858_private *priv = usb_get_serial_port_data(port);
        struct ktermios tmp_termios;
@@ -578,10 +586,11 @@ static int oti6858_open(struct usb_serial_port *port, struct file *filp)
        usb_clear_halt(serial->dev, port->write_urb->pipe);
        usb_clear_halt(serial->dev, port->read_urb->pipe);
 
-       if (port->open_count != 1)
+       if (port->port.count != 1)
                return 0;
 
-       if ((buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) {
+       buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL);
+       if (buf == NULL) {
                dev_err(&port->dev, "%s(): out of memory!\n", __func__);
                return -ENOMEM;
        }
@@ -617,18 +626,19 @@ static int oti6858_open(struct usb_serial_port *port, struct file *filp)
        if (result != 0) {
                dev_err(&port->dev, "%s(): usb_submit_urb() failed"
                               " with error %d\n", __func__, result);
-               oti6858_close(port, NULL);
+               oti6858_close(tty, port, NULL);
                return -EPROTO;
        }
 
        /* setup termios */
-       if (port->tty)
-               oti6858_set_termios(port, &tmp_termios);
+       if (tty)
+               oti6858_set_termios(tty, port, &tmp_termios);
 
        return 0;
 }
 
-static void oti6858_close(struct usb_serial_port *port, struct file *filp)
+static void oti6858_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct oti6858_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
@@ -641,7 +651,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp)
        spin_lock_irqsave(&priv->lock, flags);
        timeout = 30 * HZ;      /* PL2303_CLOSING_WAIT */
        init_waitqueue_entry(&wait, current);
-       add_wait_queue(&port->tty->write_wait, &wait);
+       add_wait_queue(&tty->write_wait, &wait);
        dbg("%s(): entering wait loop", __func__);
        for (;;) {
                set_current_state(TASK_INTERRUPTIBLE);
@@ -654,7 +664,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp)
                spin_lock_irqsave(&priv->lock, flags);
        }
        set_current_state(TASK_RUNNING);
-       remove_wait_queue(&port->tty->write_wait, &wait);
+       remove_wait_queue(&tty->write_wait, &wait);
        dbg("%s(): after wait loop", __func__);
 
        /* clear out any remaining data in the buffer */
@@ -669,7 +679,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp)
        /* data is in the buffer to compute a delay */
        /* that is not unnecessarily long) */
        /* FIXME
-       bps = tty_get_baud_rate(port->tty);
+       bps = tty_get_baud_rate(tty);
        if (bps > 1200)
                timeout = max((HZ*2560)/bps,HZ/10);
        else
@@ -690,7 +700,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp)
        usb_kill_urb(port->interrupt_in_urb);
 
        /*
-       if (port->tty && (port->tty->termios->c_cflag) & HUPCL) {
+       if (tty && (tty->termios->c_cflag) & HUPCL) {
                // drop DTR and RTS
                spin_lock_irqsave(&priv->lock, flags);
                priv->pending_setup.control &= ~CONTROL_MASK;
@@ -699,9 +709,10 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp)
        */
 }
 
-static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file,
+static int oti6858_tiocmset(struct tty_struct *tty, struct file *file,
                                unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct oti6858_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        u8 control;
@@ -724,16 +735,16 @@ static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file,
        if ((clear & TIOCM_DTR) != 0)
                control &= ~CONTROL_DTR_HIGH;
 
-       if (control != priv->pending_setup.control) {
+       if (control != priv->pending_setup.control)
                priv->pending_setup.control = control;
-       }
-       spin_unlock_irqrestore(&priv->lock, flags);
 
+       spin_unlock_irqrestore(&priv->lock, flags);
        return 0;
 }
 
-static int oti6858_tiocmget(struct usb_serial_port *port, struct file *file)
+static int oti6858_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct oti6858_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        unsigned pin_state;
@@ -779,7 +790,8 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
        spin_unlock_irqrestore(&priv->lock, flags);
 
        while (1) {
-               wait_event_interruptible(priv->intr_wait, priv->status.pin_state != prev);
+               wait_event_interruptible(priv->intr_wait,
+                                       priv->status.pin_state != prev);
                if (signal_pending(current))
                        return -ERESTARTSYS;
 
@@ -789,12 +801,11 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
 
                changed = prev ^ status;
                /* FIXME: check if this is correct (active high/low) */
-               if (    ((arg & TIOCM_RNG) && (changed & PIN_RI)) ||
-                       ((arg & TIOCM_DSR) && (changed & PIN_DSR)) ||
-                       ((arg & TIOCM_CD)  && (changed & PIN_DCD)) ||
-                       ((arg & TIOCM_CTS) && (changed & PIN_CTS))) {
-                               return 0;
-               }
+               if (((arg & TIOCM_RNG) && (changed & PIN_RI)) ||
+                   ((arg & TIOCM_DSR) && (changed & PIN_DSR)) ||
+                   ((arg & TIOCM_CD)  && (changed & PIN_DCD)) ||
+                   ((arg & TIOCM_CTS) && (changed & PIN_CTS)))
+                       return 0;
                prev = status;
        }
 
@@ -802,56 +813,25 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
        return 0;
 }
 
-static int oti6858_ioctl(struct usb_serial_port *port, struct file *file,
+static int oti6858_ioctl(struct tty_struct *tty, struct file *file,
                        unsigned int cmd, unsigned long arg)
 {
-       void __user *user_arg = (void __user *) arg;
-       unsigned int x;
+       struct usb_serial_port *port = tty->driver_data;
 
        dbg("%s(port = %d, cmd = 0x%04x, arg = 0x%08lx)",
                                __func__, port->number, cmd, arg);
 
        switch (cmd) {
-               case TIOCMBIS:
-                       if (copy_from_user(&x, user_arg, sizeof(x)))
-                               return -EFAULT;
-                       return oti6858_tiocmset(port, NULL, x, 0);
-
-               case TIOCMBIC:
-                       if (copy_from_user(&x, user_arg, sizeof(x)))
-                               return -EFAULT;
-                       return oti6858_tiocmset(port, NULL, 0, x);
-
-               case TIOCMIWAIT:
-                       dbg("%s(): TIOCMIWAIT", __func__);
-                       return wait_modem_info(port, arg);
-
-               default:
-                       dbg("%s(): 0x%04x not supported", __func__, cmd);
-                       break;
+       case TIOCMIWAIT:
+               dbg("%s(): TIOCMIWAIT", __func__);
+               return wait_modem_info(port, arg);
+       default:
+               dbg("%s(): 0x%04x not supported", __func__, cmd);
+               break;
        }
-
        return -ENOIOCTLCMD;
 }
 
-static void oti6858_break_ctl(struct usb_serial_port *port, int break_state)
-{
-       int state;
-
-       dbg("%s(port = %d)", __func__, port->number);
-
-       state = (break_state == 0) ? 0 : 1;
-       dbg("%s(): turning break %s", __func__, state ? "on" : "off");
-
-       /* FIXME */
-/*
-       result = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0),
-                                 BREAK_REQUEST, BREAK_REQUEST_TYPE, state,
-                                 0, NULL, 0, 100);
-       if (result != 0)
-               dbg("%s(): error sending break", __func__);
- */
-}
 
 static void oti6858_shutdown(struct usb_serial *serial)
 {
@@ -964,7 +944,7 @@ static void oti6858_read_int_callback(struct urb *urb)
                spin_lock_irqsave(&priv->lock, flags);
                if (priv->flags.write_urb_in_use == 0
                                && oti6858_buf_data_avail(priv->buf) != 0) {
-                       schedule_delayed_work(&priv->delayed_write_work,0);
+                       schedule_delayed_work(&priv->delayed_write_work, 0);
                        resubmit = 0;
                }
                spin_unlock_irqrestore(&priv->lock, flags);
@@ -973,7 +953,7 @@ static void oti6858_read_int_callback(struct urb *urb)
        if (resubmit) {
                int result;
 
-//             dbg("%s(): submitting interrupt urb", __func__);
+/*             dbg("%s(): submitting interrupt urb", __func__); */
                urb->dev = port->serial->dev;
                result = usb_submit_urb(urb, GFP_ATOMIC);
                if (result != 0) {
@@ -1002,14 +982,16 @@ static void oti6858_read_bulk_callback(struct urb *urb)
        spin_unlock_irqrestore(&priv->lock, flags);
 
        if (status != 0) {
-               if (!port->open_count) {
+               if (!port->port.count) {
                        dbg("%s(): port is closed, exiting", __func__);
                        return;
                }
                /*
                if (status == -EPROTO) {
-                       // PL2303 mysteriously fails with -EPROTO reschedule the read
-                       dbg("%s - caught -EPROTO, resubmitting the urb", __func__);
+                       * PL2303 mysteriously fails with -EPROTO reschedule
+                          the read *
+                       dbg("%s - caught -EPROTO, resubmitting the urb",
+                                                               __func__);
                        result = usb_submit_urb(urb, GFP_ATOMIC);
                        if (result)
                                dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result);
@@ -1020,14 +1002,14 @@ static void oti6858_read_bulk_callback(struct urb *urb)
                return;
        }
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (tty != NULL && urb->actual_length > 0) {
                tty_insert_flip_string(tty, data, urb->actual_length);
                tty_flip_buffer_push(tty);
        }
 
-       // schedule the interrupt urb if we are still open */
-       if (port->open_count != 0) {
+       /* schedule the interrupt urb if we are still open */
+       if (port->port.count != 0) {
                port->interrupt_in_urb->dev = port->serial->dev;
                result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
                if (result != 0) {
@@ -1078,7 +1060,7 @@ static void oti6858_write_bulk_callback(struct urb *urb)
 
        priv->flags.write_urb_in_use = 0;
 
-       // schedule the interrupt urb if we are still open */
+       /* schedule the interrupt urb if we are still open */
        port->interrupt_in_urb->dev = port->serial->dev;
        dbg("%s(): submitting interrupt urb", __func__);
        result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
@@ -1153,7 +1135,7 @@ static unsigned int oti6858_buf_data_avail(struct oti6858_buf *pb)
 {
        if (pb == NULL)
                return 0;
-       return ((pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size);
+       return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size;
 }
 
 /*
@@ -1166,7 +1148,7 @@ static unsigned int oti6858_buf_space_avail(struct oti6858_buf *pb)
 {
        if (pb == NULL)
                return 0;
-       return ((pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size);
+       return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size;
 }
 
 /*
@@ -1253,13 +1235,12 @@ static int __init oti6858_init(void)
 {
        int retval;
 
-       if ((retval = usb_serial_register(&oti6858_device)) == 0) {
-               if ((retval = usb_register(&oti6858_driver)) != 0)
+       retval = usb_serial_register(&oti6858_device);
+       if (retval == 0) {
+               retval = usb_register(&oti6858_driver);
+               if (retval)
                        usb_serial_deregister(&oti6858_device);
-               else
-                       return 0;
        }
-
        return retval;
 }
 
index 2a0dd1b50dc43b8dc884f0964c4f6624bfac1921..2c9c446ad625ded55144ad36955abc6bef07ddfa 100644 (file)
@@ -10,7 +10,8 @@
  *     modify it under the terms of the GNU General Public License version
  *     2 as published by the Free Software Foundation.
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
  *
  */
 
@@ -25,7 +26,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include "pl2303.h"
@@ -116,7 +117,7 @@ static struct usb_driver pl2303_driver = {
 #define CONTROL_RTS                    0x02
 
 #define BREAK_REQUEST_TYPE             0x21
-#define BREAK_REQUEST                  0x23    
+#define BREAK_REQUEST                  0x23
 #define BREAK_ON                       0xffff
 #define BREAK_OFF                      0x0000
 
@@ -222,7 +223,7 @@ static unsigned int pl2303_buf_data_avail(struct pl2303_buf *pb)
        if (pb == NULL)
                return 0;
 
-       return ((pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size);
+       return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size;
 }
 
 /*
@@ -236,7 +237,7 @@ static unsigned int pl2303_buf_space_avail(struct pl2303_buf *pb)
        if (pb == NULL)
                return 0;
 
-       return ((pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size);
+       return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size;
 }
 
 /*
@@ -395,7 +396,7 @@ static int pl2303_startup(struct usb_serial *serial)
 
 cleanup:
        kfree(buf);
-       for (--i; i>=0; --i) {
+       for (--i; i >= 0; --i) {
                priv = usb_get_serial_port_data(serial->port[i]);
                pl2303_buf_free(priv->buf);
                kfree(priv);
@@ -407,7 +408,7 @@ cleanup:
 static int set_control_lines(struct usb_device *dev, u8 value)
 {
        int retval;
-       
+
        retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
                                 SET_CONTROL_REQUEST, SET_CONTROL_REQUEST_TYPE,
                                 value, 0, NULL, 0, 100);
@@ -452,14 +453,14 @@ static void pl2303_send(struct usb_serial_port *port)
                dev_err(&port->dev, "%s - failed submitting write urb,"
                        " error %d\n", __func__, result);
                priv->write_urb_in_use = 0;
-               // TODO: reschedule pl2303_send
+               /* TODO: reschedule pl2303_send */
        }
 
        usb_serial_port_softint(port);
 }
 
-static int pl2303_write(struct usb_serial_port *port, const unsigned char *buf,
-                       int count)
+static int pl2303_write(struct tty_struct *tty, struct usb_serial_port *port,
+                               const unsigned char *buf, int count)
 {
        struct pl2303_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
@@ -478,8 +479,9 @@ static int pl2303_write(struct usb_serial_port *port, const unsigned char *buf,
        return count;
 }
 
-static int pl2303_write_room(struct usb_serial_port *port)
+static int pl2303_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct pl2303_private *priv = usb_get_serial_port_data(port);
        int room = 0;
        unsigned long flags;
@@ -494,8 +496,9 @@ static int pl2303_write_room(struct usb_serial_port *port)
        return room;
 }
 
-static int pl2303_chars_in_buffer(struct usb_serial_port *port)
+static int pl2303_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct pl2303_private *priv = usb_get_serial_port_data(port);
        int chars = 0;
        unsigned long flags;
@@ -510,8 +513,8 @@ static int pl2303_chars_in_buffer(struct usb_serial_port *port)
        return chars;
 }
 
-static void pl2303_set_termios(struct usb_serial_port *port,
-                              struct ktermios *old_termios)
+static void pl2303_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        struct usb_serial *serial = port->serial;
        struct pl2303_private *priv = usb_get_serial_port_data(port);
@@ -526,11 +529,10 @@ static void pl2303_set_termios(struct usb_serial_port *port,
 
        spin_lock_irqsave(&priv->lock, flags);
        if (!priv->termios_initialized) {
-               *(port->tty->termios) = tty_std_termios;
-               port->tty->termios->c_cflag = B9600 | CS8 | CREAD |
-                                             HUPCL | CLOCAL;
-               port->tty->termios->c_ispeed = 9600;
-               port->tty->termios->c_ospeed = 9600;
+               *(tty->termios) = tty_std_termios;
+               tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+               tty->termios->c_ispeed = 9600;
+               tty->termios->c_ospeed = 9600;
                priv->termios_initialized = 1;
        }
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -539,16 +541,16 @@ static void pl2303_set_termios(struct usb_serial_port *port,
           serial settings even to the same values as before. Thus
           we actually need to filter in this specific case */
 
-       if (!tty_termios_hw_change(port->tty->termios, old_termios))
+       if (!tty_termios_hw_change(tty->termios, old_termios))
                return;
 
-       cflag = port->tty->termios->c_cflag;
+       cflag = tty->termios->c_cflag;
 
        buf = kzalloc(7, GFP_KERNEL);
        if (!buf) {
                dev_err(&port->dev, "%s - out of memory.\n", __func__);
                /* Report back no change occurred */
-               *port->tty->termios = *old_termios;
+               *tty->termios = *old_termios;
                return;
        }
 
@@ -560,16 +562,24 @@ static void pl2303_set_termios(struct usb_serial_port *port,
 
        if (cflag & CSIZE) {
                switch (cflag & CSIZE) {
-                       case CS5:       buf[6] = 5;     break;
-                       case CS6:       buf[6] = 6;     break;
-                       case CS7:       buf[6] = 7;     break;
-                       default:
-                       case CS8:       buf[6] = 8;     break;
+               case CS5:
+                       buf[6] = 5;
+                       break;
+               case CS6:
+                       buf[6] = 6;
+                       break;
+               case CS7:
+                       buf[6] = 7;
+                       break;
+               default:
+               case CS8:
+                       buf[6] = 8;
+                       break;
                }
                dbg("%s - data bits = %d", __func__, buf[6]);
        }
 
-       baud = tty_get_baud_rate(port->tty);;
+       baud = tty_get_baud_rate(tty);
        dbg("%s - baud = %d", __func__, baud);
        if (baud) {
                buf[0] = baud & 0xff;
@@ -646,12 +656,13 @@ static void pl2303_set_termios(struct usb_serial_port *port,
 
        /* FIXME: Need to read back resulting baud rate */
        if (baud)
-               tty_encode_baud_rate(port->tty, baud, baud);
+               tty_encode_baud_rate(tty, baud, baud);
 
        kfree(buf);
 }
 
-static void pl2303_close(struct usb_serial_port *port, struct file *filp)
+static void pl2303_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct pl2303_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
@@ -666,7 +677,7 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp)
        spin_lock_irqsave(&priv->lock, flags);
        timeout = PL2303_CLOSING_WAIT;
        init_waitqueue_entry(&wait, current);
-       add_wait_queue(&port->tty->write_wait, &wait);
+       add_wait_queue(&tty->write_wait, &wait);
        for (;;) {
                set_current_state(TASK_INTERRUPTIBLE);
                if (pl2303_buf_data_avail(priv->buf) == 0 ||
@@ -678,7 +689,7 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp)
                spin_lock_irqsave(&priv->lock, flags);
        }
        set_current_state(TASK_RUNNING);
-       remove_wait_queue(&port->tty->write_wait, &wait);
+       remove_wait_queue(&tty->write_wait, &wait);
        /* clear out any remaining data in the buffer */
        pl2303_buf_clear(priv->buf);
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -690,9 +701,9 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp)
        /* for lower rates we should really know how much */
        /* data is in the buffer to compute a delay */
        /* that is not unnecessarily long) */
-       bps = tty_get_baud_rate(port->tty);
+       bps = tty_get_baud_rate(tty);
        if (bps > 1200)
-               timeout = max((HZ*2560)/bps,HZ/10);
+               timeout = max((HZ*2560)/bps, HZ/10);
        else
                timeout = 2*HZ;
        schedule_timeout_interruptible(timeout);
@@ -703,8 +714,8 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp)
        usb_kill_urb(port->read_urb);
        usb_kill_urb(port->interrupt_in_urb);
 
-       if (port->tty) {
-               c_cflag = port->tty->termios->c_cflag;
+       if (tty) {
+               c_cflag = tty->termios->c_cflag;
                if (c_cflag & HUPCL) {
                        /* drop DTR and RTS */
                        spin_lock_irqsave(&priv->lock, flags);
@@ -715,7 +726,8 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp)
        }
 }
 
-static int pl2303_open(struct usb_serial_port *port, struct file *filp)
+static int pl2303_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct ktermios tmp_termios;
        struct usb_serial *serial = port->serial;
@@ -734,11 +746,10 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp)
        }
 
        /* Setup termios */
-       if (port->tty) {
-               pl2303_set_termios(port, &tmp_termios);
-       }
+       if (tty)
+               pl2303_set_termios(tty, port, &tmp_termios);
 
-       //FIXME: need to assert RTS and DTR if CRTSCTS off
+       /* FIXME: need to assert RTS and DTR if CRTSCTS off */
 
        dbg("%s - submitting read urb", __func__);
        port->read_urb->dev = serial->dev;
@@ -746,7 +757,7 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp)
        if (result) {
                dev_err(&port->dev, "%s - failed submitting read urb,"
                        " error %d\n", __func__, result);
-               pl2303_close(port, NULL);
+               pl2303_close(tty, port, NULL);
                return -EPROTO;
        }
 
@@ -756,15 +767,16 @@ static int pl2303_open(struct usb_serial_port *port, struct file *filp)
        if (result) {
                dev_err(&port->dev, "%s - failed submitting interrupt urb,"
                        " error %d\n", __func__, result);
-               pl2303_close(port, NULL);
+               pl2303_close(tty, port, NULL);
                return -EPROTO;
        }
        return 0;
 }
 
-static int pl2303_tiocmset(struct usb_serial_port *port, struct file *file,
+static int pl2303_tiocmset(struct tty_struct *tty, struct file *file,
                           unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct pl2303_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        u8 control;
@@ -787,8 +799,9 @@ static int pl2303_tiocmset(struct usb_serial_port *port, struct file *file,
        return set_control_lines(port->serial->dev, control);
 }
 
-static int pl2303_tiocmget(struct usb_serial_port *port, struct file *file)
+static int pl2303_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct pl2303_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        unsigned int mcr;
@@ -839,12 +852,12 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
                status = priv->line_status;
                spin_unlock_irqrestore(&priv->lock, flags);
 
-               changed=prevstatus^status;
+               changed = prevstatus ^ status;
 
                if (((arg & TIOCM_RNG) && (changed & UART_RING)) ||
                    ((arg & TIOCM_DSR) && (changed & UART_DSR)) ||
                    ((arg & TIOCM_CD)  && (changed & UART_DCD)) ||
-                   ((arg & TIOCM_CTS) && (changed & UART_CTS)) ) {
+                   ((arg & TIOCM_CTS) && (changed & UART_CTS))) {
                        return 0;
                }
                prevstatus = status;
@@ -853,26 +866,26 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
        return 0;
 }
 
-static int pl2303_ioctl(struct usb_serial_port *port, struct file *file,
+static int pl2303_ioctl(struct tty_struct *tty, struct file *file,
                        unsigned int cmd, unsigned long arg)
 {
+       struct usb_serial_port *port = tty->driver_data;
        dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd);
 
        switch (cmd) {
-               case TIOCMIWAIT:
-                       dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
-                       return wait_modem_info(port, arg);
-
-               default:
-                       dbg("%s not supported = 0x%04x", __func__, cmd);
-                       break;
+       case TIOCMIWAIT:
+               dbg("%s (%d) TIOCMIWAIT", __func__,  port->number);
+               return wait_modem_info(port, arg);
+       default:
+               dbg("%s not supported = 0x%04x", __func__, cmd);
+               break;
        }
-
        return -ENOIOCTLCMD;
 }
 
-static void pl2303_break_ctl(struct usb_serial_port *port, int break_state)
+static void pl2303_break_ctl(struct tty_struct *tty, int break_state)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct usb_serial *serial = port->serial;
        u16 state;
        int result;
@@ -883,7 +896,8 @@ static void pl2303_break_ctl(struct usb_serial_port *port, int break_state)
                state = BREAK_OFF;
        else
                state = BREAK_ON;
-       dbg("%s - turning break %s", __func__, state==BREAK_OFF ? "off" : "on");
+       dbg("%s - turning break %s", __func__,
+                       state == BREAK_OFF ? "off" : "on");
 
        result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                                 BREAK_REQUEST, BREAK_REQUEST_TYPE, state,
@@ -937,7 +951,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
        if (actual_length < length)
                return;
 
-        /* Save off the uart status for others to look at */
+       /* Save off the uart status for others to look at */
        spin_lock_irqsave(&priv->lock, flags);
        priv->line_status = data[status_idx];
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -1001,7 +1015,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
 
        if (status) {
                dbg("%s - urb status = %d", __func__, status);
-               if (!port->open_count) {
+               if (!port->port.count) {
                        dbg("%s - port is closed, exiting.", __func__);
                        return;
                }
@@ -1036,7 +1050,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
 
        /* break takes precedence over parity, */
        /* which takes precedence over framing errors */
-       if (line_status & UART_BREAK_ERROR )
+       if (line_status & UART_BREAK_ERROR)
                tty_flag = TTY_BREAK;
        else if (line_status & UART_PARITY_ERROR)
                tty_flag = TTY_PARITY;
@@ -1044,7 +1058,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
                tty_flag = TTY_FRAME;
        dbg("%s - tty_flag = %d", __func__, tty_flag);
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (tty && urb->actual_length) {
                tty_buffer_request_room(tty, urb->actual_length + 1);
                /* overrun is special, not associated with a char */
@@ -1056,7 +1070,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
        }
 
        /* Schedule the next read _if_ we are still open */
-       if (port->open_count) {
+       if (port->port.count) {
                urb->dev = port->serial->dev;
                result = usb_submit_urb(urb, GFP_ATOMIC);
                if (result)
index 94bddf06ea4fb8f7d6849b99a5abfd53bb7729b8..def52d07a4ea34f817c03b60ecc827655fd05d3a 100644 (file)
  *      Stuart Lynne <sl@lineo.com>, Tom Rushworth <tbr@lineo.com>
  */
 
-/* 
- * The encapsultaion is designed to overcome difficulties with some USB hardware.
+/*
+ * The encapsultaion is designed to overcome difficulties with some USB
+ * hardware.
  *
  * While the USB protocol has a CRC over the data while in transit, i.e. while
- * being carried over the bus, there is no end to end protection. If the hardware
- * has any problems getting the data into or out of the USB transmit and receive
- * FIFO's then data can be lost. 
+ * being carried over the bus, there is no end to end protection. If the
+ * hardware has any problems getting the data into or out of the USB transmit
+ * and receive FIFO's then data can be lost.
  *
- * This protocol adds a two byte trailer to each USB packet to specify the number
- * of bytes of valid data and a 10 bit CRC that will allow the receiver to verify
- * that the entire USB packet was received without error.
+ * This protocol adds a two byte trailer to each USB packet to specify the
+ * number of bytes of valid data and a 10 bit CRC that will allow the receiver
+ * to verify that the entire USB packet was received without error.
  *
- * Because in this case the sender and receiver are the class and function drivers
- * there is now end to end protection.
+ * Because in this case the sender and receiver are the class and function
+ * drivers there is now end to end protection.
  *
- * There is an additional option that can be used to force all transmitted packets
- * to be padded to the maximum packet size. This provides a work around for some
- * devices which have problems with small USB packets.
+ * There is an additional option that can be used to force all transmitted
+ * packets to be padded to the maximum packet size. This provides a work
+ * around for some devices which have problems with small USB packets.
  *
  * Assuming a packetsize of N:
  *
  *      | Data Length       | 10 bit CRC                                |
  *      + 7 . 6 . 5 . 4 . 3 . 2 . 1 . 0 | 7 . 6 . 5 . 4 . 3 . 2 . 1 . 0 +
  *
- * The 10 bit CRC is computed across the sent data, followed by the trailer with
- * the length set and the CRC set to zero. The CRC is then OR'd into the trailer.
+ * The 10 bit CRC is computed across the sent data, followed by the trailer
+ * with the length set and the CRC set to zero. The CRC is then OR'd into
+ * the trailer.
  *
- * When received a 10 bit CRC is computed over the entire frame including the trailer
- * and should be equal to zero.
+ * When received a 10 bit CRC is computed over the entire frame including
+ * the trailer and should be equal to zero.
  *
  * Two module parameters are used to control the encapsulation, if both are
  * turned of the module works as a simple serial device with NO
@@ -69,7 +71,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
@@ -86,12 +88,12 @@ static int padded = CONFIG_USB_SERIAL_SAFE_PADDED;
 #define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com"
 #define DRIVER_DESC "USB Safe Encapsulated Serial"
 
-MODULE_AUTHOR (DRIVER_AUTHOR);
-MODULE_DESCRIPTION (DRIVER_DESC);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-static __u16 vendor;           // no default
-static __u16 product;          // no default
+static __u16 vendor;           /* no default */
+static __u16 product;          /* no default */
 module_param(vendor, ushort, 0);
 MODULE_PARM_DESC(vendor, "User specified USB idVendor (required)");
 module_param(product, ushort, 0);
@@ -122,30 +124,31 @@ MODULE_PARM_DESC(padded, "Pad to full wMaxPacketSize On/Off");
 #define LINEO_SAFESERIAL_CRC_PADDED             0x02
 
 
-#define MY_USB_DEVICE(vend,prod,dc,ic,isc) \
-        .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS | \
-                USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS, \
-        .idVendor = (vend), \
-        .idProduct = (prod),\
-        .bDeviceClass = (dc),\
-        .bInterfaceClass = (ic), \
-        .bInterfaceSubClass = (isc),
+#define MY_USB_DEVICE(vend, prod, dc, ic, isc) \
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
+                      USB_DEVICE_ID_MATCH_DEV_CLASS | \
+                      USB_DEVICE_ID_MATCH_INT_CLASS | \
+                      USB_DEVICE_ID_MATCH_INT_SUBCLASS, \
+       .idVendor = (vend), \
+       .idProduct = (prod),\
+       .bDeviceClass = (dc),\
+       .bInterfaceClass = (ic), \
+       .bInterfaceSubClass = (isc),
 
 static struct usb_device_id id_table[] = {
-       {MY_USB_DEVICE (0x49f, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},  // Itsy
-       {MY_USB_DEVICE (0x3f0, 0x2101, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},  // Calypso
-       {MY_USB_DEVICE (0x4dd, 0x8001, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},  // Iris 
-       {MY_USB_DEVICE (0x4dd, 0x8002, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},  // Collie 
-       {MY_USB_DEVICE (0x4dd, 0x8003, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},  // Collie 
-       {MY_USB_DEVICE (0x4dd, 0x8004, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},  // Collie 
-       {MY_USB_DEVICE (0x5f9, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},  // Sharp tmp
-       // extra null entry for module 
-       // vendor/produc parameters
-       {MY_USB_DEVICE (0, 0, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},
-       {}                      // terminating entry 
+       {MY_USB_DEVICE(0x49f, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},   /* Itsy */
+       {MY_USB_DEVICE(0x3f0, 0x2101, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},   /* Calypso */
+       {MY_USB_DEVICE(0x4dd, 0x8001, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},   /* Iris */
+       {MY_USB_DEVICE(0x4dd, 0x8002, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},   /* Collie */
+       {MY_USB_DEVICE(0x4dd, 0x8003, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},   /* Collie */
+       {MY_USB_DEVICE(0x4dd, 0x8004, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},   /* Collie */
+       {MY_USB_DEVICE(0x5f9, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},   /* Sharp tmp */
+       /* extra null entry for module vendor/produc parameters */
+       {MY_USB_DEVICE(0, 0, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)},
+       {}                      /* terminating entry  */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver safe_driver = {
        .name =         "safe_serial",
@@ -156,29 +159,45 @@ static struct usb_driver safe_driver = {
 };
 
 static const __u16 crc10_table[256] = {
-       0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe,
-       0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf,
-       0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c,
-       0x053, 0x260, 0x206, 0x035, 0x2ca, 0x0f9, 0x09f, 0x2ac, 0x352, 0x161, 0x107, 0x334, 0x1cb, 0x3f8, 0x39e, 0x1ad,
-       0x0c4, 0x2f7, 0x291, 0x0a2, 0x25d, 0x06e, 0x008, 0x23b, 0x3c5, 0x1f6, 0x190, 0x3a3, 0x15c, 0x36f, 0x309, 0x13a,
-       0x0f5, 0x2c6, 0x2a0, 0x093, 0x26c, 0x05f, 0x039, 0x20a, 0x3f4, 0x1c7, 0x1a1, 0x392, 0x16d, 0x35e, 0x338, 0x10b,
-       0x0a6, 0x295, 0x2f3, 0x0c0, 0x23f, 0x00c, 0x06a, 0x259, 0x3a7, 0x194, 0x1f2, 0x3c1, 0x13e, 0x30d, 0x36b, 0x158,
-       0x097, 0x2a4, 0x2c2, 0x0f1, 0x20e, 0x03d, 0x05b, 0x268, 0x396, 0x1a5, 0x1c3, 0x3f0, 0x10f, 0x33c, 0x35a, 0x169,
-       0x188, 0x3bb, 0x3dd, 0x1ee, 0x311, 0x122, 0x144, 0x377, 0x289, 0x0ba, 0x0dc, 0x2ef, 0x010, 0x223, 0x245, 0x076,
-       0x1b9, 0x38a, 0x3ec, 0x1df, 0x320, 0x113, 0x175, 0x346, 0x2b8, 0x08b, 0x0ed, 0x2de, 0x021, 0x212, 0x274, 0x047,
-       0x1ea, 0x3d9, 0x3bf, 0x18c, 0x373, 0x140, 0x126, 0x315, 0x2eb, 0x0d8, 0x0be, 0x28d, 0x072, 0x241, 0x227, 0x014,
-       0x1db, 0x3e8, 0x38e, 0x1bd, 0x342, 0x171, 0x117, 0x324, 0x2da, 0x0e9, 0x08f, 0x2bc, 0x043, 0x270, 0x216, 0x025,
-       0x14c, 0x37f, 0x319, 0x12a, 0x3d5, 0x1e6, 0x180, 0x3b3, 0x24d, 0x07e, 0x018, 0x22b, 0x0d4, 0x2e7, 0x281, 0x0b2,
-       0x17d, 0x34e, 0x328, 0x11b, 0x3e4, 0x1d7, 0x1b1, 0x382, 0x27c, 0x04f, 0x029, 0x21a, 0x0e5, 0x2d6, 0x2b0, 0x083,
-       0x12e, 0x31d, 0x37b, 0x148, 0x3b7, 0x184, 0x1e2, 0x3d1, 0x22f, 0x01c, 0x07a, 0x249, 0x0b6, 0x285, 0x2e3, 0x0d0,
-       0x11f, 0x32c, 0x34a, 0x179, 0x386, 0x1b5, 0x1d3, 0x3e0, 0x21e, 0x02d, 0x04b, 0x278, 0x087, 0x2b4, 0x2d2, 0x0e1,
+       0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff,
+       0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe,
+       0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce,
+       0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf,
+       0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d,
+       0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c,
+       0x053, 0x260, 0x206, 0x035, 0x2ca, 0x0f9, 0x09f, 0x2ac,
+       0x352, 0x161, 0x107, 0x334, 0x1cb, 0x3f8, 0x39e, 0x1ad,
+       0x0c4, 0x2f7, 0x291, 0x0a2, 0x25d, 0x06e, 0x008, 0x23b,
+       0x3c5, 0x1f6, 0x190, 0x3a3, 0x15c, 0x36f, 0x309, 0x13a,
+       0x0f5, 0x2c6, 0x2a0, 0x093, 0x26c, 0x05f, 0x039, 0x20a,
+       0x3f4, 0x1c7, 0x1a1, 0x392, 0x16d, 0x35e, 0x338, 0x10b,
+       0x0a6, 0x295, 0x2f3, 0x0c0, 0x23f, 0x00c, 0x06a, 0x259,
+       0x3a7, 0x194, 0x1f2, 0x3c1, 0x13e, 0x30d, 0x36b, 0x158,
+       0x097, 0x2a4, 0x2c2, 0x0f1, 0x20e, 0x03d, 0x05b, 0x268,
+       0x396, 0x1a5, 0x1c3, 0x3f0, 0x10f, 0x33c, 0x35a, 0x169,
+       0x188, 0x3bb, 0x3dd, 0x1ee, 0x311, 0x122, 0x144, 0x377,
+       0x289, 0x0ba, 0x0dc, 0x2ef, 0x010, 0x223, 0x245, 0x076,
+       0x1b9, 0x38a, 0x3ec, 0x1df, 0x320, 0x113, 0x175, 0x346,
+       0x2b8, 0x08b, 0x0ed, 0x2de, 0x021, 0x212, 0x274, 0x047,
+       0x1ea, 0x3d9, 0x3bf, 0x18c, 0x373, 0x140, 0x126, 0x315,
+       0x2eb, 0x0d8, 0x0be, 0x28d, 0x072, 0x241, 0x227, 0x014,
+       0x1db, 0x3e8, 0x38e, 0x1bd, 0x342, 0x171, 0x117, 0x324,
+       0x2da, 0x0e9, 0x08f, 0x2bc, 0x043, 0x270, 0x216, 0x025,
+       0x14c, 0x37f, 0x319, 0x12a, 0x3d5, 0x1e6, 0x180, 0x3b3,
+       0x24d, 0x07e, 0x018, 0x22b, 0x0d4, 0x2e7, 0x281, 0x0b2,
+       0x17d, 0x34e, 0x328, 0x11b, 0x3e4, 0x1d7, 0x1b1, 0x382,
+       0x27c, 0x04f, 0x029, 0x21a, 0x0e5, 0x2d6, 0x2b0, 0x083,
+       0x12e, 0x31d, 0x37b, 0x148, 0x3b7, 0x184, 0x1e2, 0x3d1,
+       0x22f, 0x01c, 0x07a, 0x249, 0x0b6, 0x285, 0x2e3, 0x0d0,
+       0x11f, 0x32c, 0x34a, 0x179, 0x386, 0x1b5, 0x1d3, 0x3e0,
+       0x21e, 0x02d, 0x04b, 0x278, 0x087, 0x2b4, 0x2d2, 0x0e1,
 };
 
-#define CRC10_INITFCS     0x000        // Initial FCS value
-#define CRC10_GOODFCS     0x000        // Good final FCS value
-#define CRC10_FCS(fcs, c) ( (((fcs) << 8) & 0x3ff) ^ crc10_table[((fcs) >> 2) & 0xff] ^ (c))
+#define CRC10_INITFCS     0x000        /* Initial FCS value */
+#define CRC10_GOODFCS     0x000        /* Good final FCS value */
+#define CRC10_FCS(fcs, c) ((((fcs) << 8) & 0x3ff) ^ crc10_table[((fcs) >> 2) & 0xff] ^ (c))
 
-/**     
+/**
  * fcs_compute10 - memcpy and calculate 10 bit CRC across buffer
  * @sp: pointer to buffer
  * @len: number of bytes
@@ -187,13 +206,13 @@ static const __u16 crc10_table[256] = {
  * Perform a memcpy and calculate fcs using ppp 10bit CRC algorithm. Return
  * new 10 bit FCS.
  */
-static __u16 __inline__ fcs_compute10 (unsigned char *sp, int len, __u16 fcs)
+static __u16 __inline__ fcs_compute10(unsigned char *sp, int len, __u16 fcs)
 {
-       for (; len-- > 0; fcs = CRC10_FCS (fcs, *sp++));
+       for (; len-- > 0; fcs = CRC10_FCS(fcs, *sp++));
        return fcs;
 }
 
-static void safe_read_bulk_callback (struct urb *urb)
+static void safe_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port =  urb->context;
        unsigned char *data = urb->transfer_buffer;
@@ -201,7 +220,7 @@ static void safe_read_bulk_callback (struct urb *urb)
        int result;
        int status = urb->status;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        if (status) {
                dbg("%s - nonzero read bulk status received: %d",
@@ -209,76 +228,82 @@ static void safe_read_bulk_callback (struct urb *urb)
                return;
        }
 
-       dbg ("safe_read_bulk_callback length: %d", port->read_urb->actual_length);
+       dbg("safe_read_bulk_callback length: %d",
+                                       port->read_urb->actual_length);
 #ifdef ECHO_RCV
        {
                int i;
                unsigned char *cp = port->read_urb->transfer_buffer;
                for (i = 0; i < port->read_urb->actual_length; i++) {
-                       if ((i % 32) == 0) {
-                               printk ("\nru[%02x] ", i);
-                       }
-                       printk ("%02x ", *cp++);
+                       if ((i % 32) == 0)
+                               printk("\nru[%02x] ", i);
+                       printk("%02x ", *cp++);
                }
-               printk ("\n");
+               printk("\n");
        }
 #endif
        if (safe) {
                __u16 fcs;
-               if (!(fcs = fcs_compute10 (data, length, CRC10_INITFCS))) {
+               fcs = fcs_compute10(data, length, CRC10_INITFCS);
+               if (!fcs) {
                        int actual_length = data[length - 2] >> 2;
                        if (actual_length <= (length - 2)) {
-                               info ("%s - actual: %d", __func__, actual_length);
-                               tty_insert_flip_string(port->tty, data, actual_length);
-                               tty_flip_buffer_push (port->tty);
+                               info("%s - actual: %d", __func__,
+                                                       actual_length);
+                               tty_insert_flip_string(port->port.tty,
+                                                       data, actual_length);
+                               tty_flip_buffer_push(port->port.tty);
                        } else {
-                               err ("%s - inconsistent lengths %d:%d", __func__,
-                                    actual_length, length);
+                               err("%s - inconsistent lengths %d:%d",
+                                       __func__, actual_length, length);
                        }
                } else {
-                       err ("%s - bad CRC %x", __func__, fcs);
+                       err("%s - bad CRC %x", __func__, fcs);
                }
        } else {
-               tty_insert_flip_string(port->tty, data, length);
-               tty_flip_buffer_push (port->tty);
+               tty_insert_flip_string(port->port.tty, data, length);
+               tty_flip_buffer_push(port->port.tty);
        }
 
        /* Continue trying to always read  */
-       usb_fill_bulk_urb (urb, port->serial->dev,
-                      usb_rcvbulkpipe (port->serial->dev, port->bulk_in_endpointAddress),
-                      urb->transfer_buffer, urb->transfer_buffer_length,
-                      safe_read_bulk_callback, port);
-
-       if ((result = usb_submit_urb (urb, GFP_ATOMIC))) {
-               err ("%s - failed resubmitting read urb, error %d", __func__, result);
+       usb_fill_bulk_urb(urb, port->serial->dev,
+                       usb_rcvbulkpipe(port->serial->dev,
+                                       port->bulk_in_endpointAddress),
+                       urb->transfer_buffer, urb->transfer_buffer_length,
+                       safe_read_bulk_callback, port);
+
+       result = usb_submit_urb(urb, GFP_ATOMIC);
+       if (result)
+               err("%s - failed resubmitting read urb, error %d",
+                                                       __func__, result);
                /* FIXME: Need a mechanism to retry later if this happens */
-       }
 }
 
-static int safe_write (struct usb_serial_port *port, const unsigned char *buf, int count)
+static int safe_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                       const unsigned char *buf, int count)
 {
        unsigned char *data;
        int result;
        int i;
        int packet_length;
 
-       dbg ("safe_write port: %p %d urb: %p count: %d", port, port->number, port->write_urb,
-            count);
+       dbg("safe_write port: %p %d urb: %p count: %d",
+                               port, port->number, port->write_urb, count);
 
        if (!port->write_urb) {
-               dbg ("%s - write urb NULL", __func__);
+               dbg("%s - write urb NULL", __func__);
                return 0;
        }
 
-       dbg ("safe_write write_urb: %d transfer_buffer_length",
+       dbg("safe_write write_urb: %d transfer_buffer_length",
             port->write_urb->transfer_buffer_length);
 
        if (!port->write_urb->transfer_buffer_length) {
-               dbg ("%s - write urb transfer_buffer_length zero", __func__);
+               dbg("%s - write urb transfer_buffer_length zero", __func__);
                return 0;
        }
        if (count == 0) {
-               dbg ("%s - write request of 0 bytes", __func__);
+               dbg("%s - write request of 0 bytes", __func__);
                return 0;
        }
        spin_lock_bh(&port->lock);
@@ -290,85 +315,85 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i
        port->write_urb_busy = 1;
        spin_unlock_bh(&port->lock);
 
-       packet_length = port->bulk_out_size;    // get max packetsize
+       packet_length = port->bulk_out_size;    /* get max packetsize */
 
-       i = packet_length - (safe ? 2 : 0);     // get bytes to send
+       i = packet_length - (safe ? 2 : 0);     /* get bytes to send */
        count = (count > i) ? i : count;
 
 
-       // get the data into the transfer buffer
+       /* get the data into the transfer buffer */
        data = port->write_urb->transfer_buffer;
-       memset (data, '0', packet_length);
+       memset(data, '0', packet_length);
 
-       memcpy (data, buf, count);
+       memcpy(data, buf, count);
 
        if (safe) {
                __u16 fcs;
 
-               // pad if necessary
-               if (!padded) {
+               /* pad if necessary */
+               if (!padded)
                        packet_length = count + 2;
-               }
-               // set count
+               /* set count */
                data[packet_length - 2] = count << 2;
                data[packet_length - 1] = 0;
 
-               // compute fcs and insert into trailer
-               fcs = fcs_compute10 (data, packet_length, CRC10_INITFCS);
+               /* compute fcs and insert into trailer */
+               fcs = fcs_compute10(data, packet_length, CRC10_INITFCS);
                data[packet_length - 2] |= fcs >> 8;
                data[packet_length - 1] |= fcs & 0xff;
 
-               // set length to send
+               /* set length to send */
                port->write_urb->transfer_buffer_length = packet_length;
        } else {
                port->write_urb->transfer_buffer_length = count;
        }
 
-       usb_serial_debug_data(debug, &port->dev, __func__, count, port->write_urb->transfer_buffer);
+       usb_serial_debug_data(debug, &port->dev, __func__, count,
+                                       port->write_urb->transfer_buffer);
 #ifdef ECHO_TX
        {
                int i;
                unsigned char *cp = port->write_urb->transfer_buffer;
                for (i = 0; i < port->write_urb->transfer_buffer_length; i++) {
-                       if ((i % 32) == 0) {
-                               printk ("\nsu[%02x] ", i);
-                       }
-                       printk ("%02x ", *cp++);
+                       if ((i % 32) == 0)
+                               printk("\nsu[%02x] ", i);
+                       printk("%02x ", *cp++);
                }
-               printk ("\n");
+               printk("\n");
        }
 #endif
        port->write_urb->dev = port->serial->dev;
-       if ((result = usb_submit_urb (port->write_urb, GFP_KERNEL))) {
+       result = usb_submit_urb(port->write_urb, GFP_KERNEL);
+       if (result) {
                port->write_urb_busy = 0;
-               err ("%s - failed submitting write urb, error %d", __func__, result);
+               err("%s - failed submitting write urb, error %d",
+                                                       __func__, result);
                return 0;
        }
-       dbg ("%s urb: %p submitted", __func__, port->write_urb);
+       dbg("%s urb: %p submitted", __func__, port->write_urb);
 
-       return (count);
+       return count;
 }
 
-static int safe_write_room (struct usb_serial_port *port)
+static int safe_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        int room = 0;           /* Default: no room */
        unsigned long flags;
 
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        spin_lock_irqsave(&port->lock, flags);
        if (port->write_urb_busy)
                room = port->bulk_out_size - (safe ? 2 : 0);
        spin_unlock_irqrestore(&port->lock, flags);
 
-       if (room) {
-               dbg ("safe_write_room returns %d", room);
-       }
-
+       if (room)
+               dbg("safe_write_room returns %d", room);
        return room;
 }
 
-static int safe_startup (struct usb_serial *serial)
+static int safe_startup(struct usb_serial *serial)
 {
        switch (serial->interface->cur_altsetting->desc.bInterfaceProtocol) {
        case LINEO_SAFESERIAL_CRC:
@@ -396,17 +421,18 @@ static struct usb_serial_driver safe_device = {
        .attach =               safe_startup,
 };
 
-static int __init safe_init (void)
+static int __init safe_init(void)
 {
        int i, retval;
 
-       info (DRIVER_VERSION " " DRIVER_AUTHOR);
-       info (DRIVER_DESC);
-       info ("vendor: %x product: %x safe: %d padded: %d\n", vendor, product, safe, padded);
+       info(DRIVER_VERSION " " DRIVER_AUTHOR);
+       info(DRIVER_DESC);
+       info("vendor: %x product: %x safe: %d padded: %d\n",
+                                       vendor, product, safe, padded);
 
-       // if we have vendor / product parameters patch them into id list
+       /* if we have vendor / product parameters patch them into id list */
        if (vendor || product) {
-               info ("vendor: %x product: %x\n", vendor, product);
+               info("vendor: %x product: %x\n", vendor, product);
 
                for (i = 0; i < ARRAY_SIZE(id_table); i++) {
                        if (!id_table[i].idVendor && !id_table[i].idProduct) {
@@ -431,11 +457,11 @@ failed_usb_serial_register:
        return retval;
 }
 
-static void __exit safe_exit (void)
+static void __exit safe_exit(void)
 {
-       usb_deregister (&safe_driver);
-       usb_serial_deregister (&safe_device);
+       usb_deregister(&safe_driver);
+       usb_serial_deregister(&safe_device);
 }
 
-module_init (safe_init);
-module_exit (safe_exit);
+module_init(safe_init);
+module_exit(safe_exit);
index 29074c1ba22b6dd504218328e11c177ae4a76ab6..2f6f1523ec56b5462461fbf1a6c1e260513919d9 100644 (file)
@@ -250,7 +250,8 @@ struct sierra_port_private {
        int ri_state;
 };
 
-static int sierra_send_setup(struct usb_serial_port *port)
+static int sierra_send_setup(struct tty_struct *tty,
+                                               struct usb_serial_port *port)
 {
        struct usb_serial *serial = port->serial;
        struct sierra_port_private *portdata;
@@ -260,7 +261,7 @@ static int sierra_send_setup(struct usb_serial_port *port)
 
        portdata = usb_get_serial_port_data(port);
 
-       if (port->tty) {
+       if (tty) {
                int val = 0;
                if (portdata->dtr_state)
                        val |= 0x01;
@@ -284,32 +285,17 @@ static int sierra_send_setup(struct usb_serial_port *port)
        return 0;
 }
 
-static void sierra_rx_throttle(struct usb_serial_port *port)
+static void sierra_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        dbg("%s", __func__);
+       tty_termios_copy_hw(tty->termios, old_termios);
+       sierra_send_setup(tty, port);
 }
 
-static void sierra_rx_unthrottle(struct usb_serial_port *port)
-{
-       dbg("%s", __func__);
-}
-
-static void sierra_break_ctl(struct usb_serial_port *port, int break_state)
-{
-       /* Unfortunately, I don't know how to send a break */
-       dbg("%s", __func__);
-}
-
-static void sierra_set_termios(struct usb_serial_port *port,
-                       struct ktermios *old_termios)
-{
-       dbg("%s", __func__);
-       tty_termios_copy_hw(port->tty->termios, old_termios);
-       sierra_send_setup(port);
-}
-
-static int sierra_tiocmget(struct usb_serial_port *port, struct file *file)
+static int sierra_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        unsigned int value;
        struct sierra_port_private *portdata;
 
@@ -325,9 +311,10 @@ static int sierra_tiocmget(struct usb_serial_port *port, struct file *file)
        return value;
 }
 
-static int sierra_tiocmset(struct usb_serial_port *port, struct file *file,
+static int sierra_tiocmset(struct tty_struct *tty, struct file *file,
                        unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct sierra_port_private *portdata;
 
        portdata = usb_get_serial_port_data(port);
@@ -341,13 +328,7 @@ static int sierra_tiocmset(struct usb_serial_port *port, struct file *file,
                portdata->rts_state = 0;
        if (clear & TIOCM_DTR)
                portdata->dtr_state = 0;
-       return sierra_send_setup(port);
-}
-
-static int sierra_ioctl(struct usb_serial_port *port, struct file *file,
-                       unsigned int cmd, unsigned long arg)
-{
-       return -ENOIOCTLCMD;
+       return sierra_send_setup(tty, port);
 }
 
 static void sierra_outdat_callback(struct urb *urb)
@@ -374,8 +355,8 @@ static void sierra_outdat_callback(struct urb *urb)
 }
 
 /* Write */
-static int sierra_write(struct usb_serial_port *port,
-                       const unsigned char *buf, int count)
+static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                       const unsigned char *buf, int count)
 {
        struct sierra_port_private *portdata = usb_get_serial_port_data(port);
        struct usb_serial *serial = port->serial;
@@ -463,7 +444,7 @@ static void sierra_indat_callback(struct urb *urb)
                dbg("%s: nonzero status: %d on endpoint %02x.",
                    __func__, status, endpoint);
        } else {
-               tty = port->tty;
+               tty = port->port.tty;
                if (urb->actual_length) {
                        tty_buffer_request_room(tty, urb->actual_length);
                        tty_insert_flip_string(tty, data, urb->actual_length);
@@ -473,7 +454,7 @@ static void sierra_indat_callback(struct urb *urb)
                }
 
                /* Resubmit urb so we continue receiving */
-               if (port->open_count && status != -ESHUTDOWN) {
+               if (port->port.count && status != -ESHUTDOWN) {
                        err = usb_submit_urb(urb, GFP_ATOMIC);
                        if (err)
                                dev_err(&port->dev, "resubmit read urb failed."
@@ -517,9 +498,9 @@ static void sierra_instat_callback(struct urb *urb)
                        portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
                        portdata->ri_state = ((signals & 0x08) ? 1 : 0);
 
-                       if (port->tty && !C_CLOCAL(port->tty) &&
+                       if (port->port.tty && !C_CLOCAL(port->port.tty) &&
                                        old_dcd_state && !portdata->dcd_state)
-                               tty_hangup(port->tty);
+                               tty_hangup(port->port.tty);
                } else {
                        dbg("%s: type %x req %x", __func__,
                                req_pkt->bRequestType, req_pkt->bRequest);
@@ -537,8 +518,9 @@ static void sierra_instat_callback(struct urb *urb)
        }
 }
 
-static int sierra_write_room(struct usb_serial_port *port)
+static int sierra_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct sierra_port_private *portdata = usb_get_serial_port_data(port);
        unsigned long flags;
 
@@ -557,22 +539,8 @@ static int sierra_write_room(struct usb_serial_port *port)
        return 2048;
 }
 
-static int sierra_chars_in_buffer(struct usb_serial_port *port)
-{
-       dbg("%s - port %d", __func__, port->number);
-
-       /*
-        * We can't really account for how much data we
-        * have sent out, but hasn't made it through to the
-        * device as we can't see the backend here, so just
-        * tell the tty layer that everything is flushed.
-        *
-        * FIXME: should walk the outstanding urbs info
-        */
-       return 0;
-}
-
-static int sierra_open(struct usb_serial_port *port, struct file *filp)
+static int sierra_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct sierra_port_private *portdata;
        struct usb_serial *serial = port->serial;
@@ -612,9 +580,10 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
                }
        }
 
-       port->tty->low_latency = 1;
+       if (tty)
+               tty->low_latency = 1;
 
-       sierra_send_setup(port);
+       sierra_send_setup(tty, port);
 
        /* start up the interrupt endpoint if we have one */
        if (port->interrupt_in_urb) {
@@ -626,7 +595,8 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
        return 0;
 }
 
-static void sierra_close(struct usb_serial_port *port, struct file *filp)
+static void sierra_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        int i;
        struct usb_serial *serial = port->serial;
@@ -641,7 +611,7 @@ static void sierra_close(struct usb_serial_port *port, struct file *filp)
        if (serial->dev) {
                mutex_lock(&serial->disc_mutex);
                if (!serial->disconnected)
-                       sierra_send_setup(port);
+                       sierra_send_setup(tty, port);
                mutex_unlock(&serial->disc_mutex);
 
                /* Stop reading/writing urbs */
@@ -651,7 +621,7 @@ static void sierra_close(struct usb_serial_port *port, struct file *filp)
 
        usb_kill_urb(port->interrupt_in_urb);
 
-       port->tty = NULL;
+       port->port.tty = NULL;  /* FIXME */
 }
 
 static int sierra_startup(struct usb_serial *serial)
@@ -754,12 +724,7 @@ static struct usb_serial_driver sierra_device = {
        .close             = sierra_close,
        .write             = sierra_write,
        .write_room        = sierra_write_room,
-       .chars_in_buffer   = sierra_chars_in_buffer,
-       .throttle          = sierra_rx_throttle,
-       .unthrottle        = sierra_rx_unthrottle,
-       .ioctl             = sierra_ioctl,
        .set_termios       = sierra_set_termios,
-       .break_ctl         = sierra_break_ctl,
        .tiocmget          = sierra_tiocmget,
        .tiocmset          = sierra_tiocmset,
        .attach            = sierra_startup,
@@ -792,7 +757,7 @@ failed_device_register:
 
 static void __exit sierra_exit(void)
 {
-       usb_deregister (&sierra_driver);
+       usb_deregister(&sierra_driver);
        usb_serial_deregister(&sierra_device);
 }
 
index 55b2570b8b8b568ad0e694ed575d8153ed4333f6..283cf6b36b2c0cca7f77c7ce0409c4420faa6753 100644 (file)
@@ -208,7 +208,7 @@ static inline unsigned int ringbuf_avail_data(struct ringbuf *pb)
 {
        if (pb == NULL)
                return 0;
-       return ((pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size);
+       return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size;
 }
 
 /* get the number of space in the pipo */
@@ -216,7 +216,7 @@ static inline unsigned int ringbuf_avail_space(struct ringbuf *pb)
 {
        if (pb == NULL)
                return 0;
-       return ((pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size);
+       return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size;
 }
 
 /* put count data into pipo */
@@ -448,7 +448,8 @@ static void spcp8x5_set_workMode(struct usb_device *dev, u16 value,
 
 /* close the serial port. We should wait for data sending to device 1st and
  * then kill all urb. */
-static void spcp8x5_close(struct usb_serial_port *port, struct file *filp)
+static void spcp8x5_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct spcp8x5_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
@@ -464,7 +465,7 @@ static void spcp8x5_close(struct usb_serial_port *port, struct file *filp)
        spin_lock_irqsave(&priv->lock, flags);
        timeout = SPCP8x5_CLOSING_WAIT;
        init_waitqueue_entry(&wait, current);
-       add_wait_queue(&port->tty->write_wait, &wait);
+       add_wait_queue(&tty->write_wait, &wait);
        for (;;) {
                set_current_state(TASK_INTERRUPTIBLE);
                if (ringbuf_avail_data(priv->buf) == 0 ||
@@ -475,7 +476,7 @@ static void spcp8x5_close(struct usb_serial_port *port, struct file *filp)
                spin_lock_irqsave(&priv->lock, flags);
        }
        set_current_state(TASK_RUNNING);
-       remove_wait_queue(&port->tty->write_wait, &wait);
+       remove_wait_queue(&tty->write_wait, &wait);
 
        /* clear out any remaining data in the buffer */
        clear_ringbuf(priv->buf);
@@ -486,7 +487,7 @@ static void spcp8x5_close(struct usb_serial_port *port, struct file *filp)
         * flow control for data rates of 1200 bps or more, for lower rates we
         * should really know how much data is in the buffer to compute a delay
         * that is not unnecessarily long) */
-       bps = tty_get_baud_rate(port->tty);
+       bps = tty_get_baud_rate(tty);
        if (bps > 1200)
                timeout = max((HZ*2560) / bps, HZ/10);
        else
@@ -495,8 +496,8 @@ static void spcp8x5_close(struct usb_serial_port *port, struct file *filp)
        schedule_timeout(timeout);
 
        /* clear control lines */
-       if (port->tty) {
-               c_cflag = port->tty->termios->c_cflag;
+       if (tty) {
+               c_cflag = tty->termios->c_cflag;
                if (c_cflag & HUPCL) {
                        spin_lock_irqsave(&priv->lock, flags);
                        priv->line_control = 0;
@@ -518,14 +519,14 @@ static void spcp8x5_close(struct usb_serial_port *port, struct file *filp)
 }
 
 /* set the serial param for transfer. we should check if we really need to
- * transfer. then if be set flow contorl we should do this too. */
-static void spcp8x5_set_termios(struct usb_serial_port *port,
-                               struct ktermios *old_termios)
+ * transfer. if we set flow control we should do this too. */
+static void spcp8x5_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        struct usb_serial *serial = port->serial;
        struct spcp8x5_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
-       unsigned int cflag = port->tty->termios->c_cflag;
+       unsigned int cflag = tty->termios->c_cflag;
        unsigned int old_cflag = old_termios->c_cflag;
        unsigned short uartdata;
        unsigned char buf[2] = {0, 0};
@@ -533,21 +534,19 @@ static void spcp8x5_set_termios(struct usb_serial_port *port,
        int i;
        u8 control;
 
-       if ((!port->tty) || (!port->tty->termios))
-               return;
-
        /* for the 1st time call this function */
        spin_lock_irqsave(&priv->lock, flags);
        if (!priv->termios_initialized) {
-               *(port->tty->termios) = tty_std_termios;
-               port->tty->termios->c_cflag = B115200 | CS8 | CREAD |
-                                             HUPCL | CLOCAL;
+               *(tty->termios) = tty_std_termios;
+               tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+               tty->termios->c_ispeed = 115200;
+               tty->termios->c_ospeed = 115200;
                priv->termios_initialized = 1;
        }
        spin_unlock_irqrestore(&priv->lock, flags);
 
        /* check that they really want us to change something */
-       if (!tty_termios_hw_change(port->tty->termios, old_termios))
+       if (!tty_termios_hw_change(tty->termios, old_termios))
                return;
 
        /* set DTR/RTS active */
@@ -567,7 +566,7 @@ static void spcp8x5_set_termios(struct usb_serial_port *port,
        }
 
        /* Set Baud Rate */
-       baud = tty_get_baud_rate(port->tty);;
+       baud = tty_get_baud_rate(tty);;
        switch (baud) {
        case 300:       buf[0] = 0x00;  break;
        case 600:       buf[0] = 0x01;  break;
@@ -643,7 +642,8 @@ static void spcp8x5_set_termios(struct usb_serial_port *port,
 
 /* open the serial port. do some usb system call. set termios and get the line
  * status of the device. then submit the read urb */
-static int spcp8x5_open(struct usb_serial_port *port, struct file *filp)
+static int spcp8x5_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct ktermios tmp_termios;
        struct usb_serial *serial = port->serial;
@@ -665,7 +665,7 @@ static int spcp8x5_open(struct usb_serial_port *port, struct file *filp)
                return ret;
 
        spin_lock_irqsave(&priv->lock, flags);
-       if (port->tty->termios->c_cflag & CBAUD)
+       if (tty && (tty->termios->c_cflag & CBAUD))
                priv->line_control = MCR_DTR | MCR_RTS;
        else
                priv->line_control = 0;
@@ -674,8 +674,8 @@ static int spcp8x5_open(struct usb_serial_port *port, struct file *filp)
        spcp8x5_set_ctrlLine(serial->dev, priv->line_control , priv->type);
 
        /* Setup termios */
-       if (port->tty)
-               spcp8x5_set_termios(port, &tmp_termios);
+       if (tty)
+               spcp8x5_set_termios(tty, port, &tmp_termios);
 
        spcp8x5_get_msr(serial->dev, &status, priv->type);
 
@@ -690,7 +690,7 @@ static int spcp8x5_open(struct usb_serial_port *port, struct file *filp)
        port->read_urb->dev = serial->dev;
        ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
        if (ret) {
-               spcp8x5_close(port, NULL);
+               spcp8x5_close(tty, port, NULL);
                return -EPROTO;
        }
        return 0;
@@ -717,7 +717,7 @@ static void spcp8x5_read_bulk_callback(struct urb *urb)
 
        /* check the urb status */
        if (urb->status) {
-               if (!port->open_count)
+               if (!port->port.count)
                        return;
                if (urb->status == -EPROTO) {
                        /* spcp8x5 mysteriously fails with -EPROTO */
@@ -755,7 +755,7 @@ static void spcp8x5_read_bulk_callback(struct urb *urb)
                tty_flag = TTY_FRAME;
        dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag);
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (tty && urb->actual_length) {
                tty_buffer_request_room(tty, urb->actual_length + 1);
                /* overrun is special, not associated with a char */
@@ -767,7 +767,7 @@ static void spcp8x5_read_bulk_callback(struct urb *urb)
        }
 
        /* Schedule the next read _if_ we are still open */
-       if (port->open_count) {
+       if (port->port.count) {
                urb->dev = port->serial->dev;
                result = usb_submit_urb(urb , GFP_ATOMIC);
                if (result)
@@ -866,7 +866,7 @@ static void spcp8x5_write_bulk_callback(struct urb *urb)
 }
 
 /* write data to ring buffer. and then start the write transfer */
-static int spcp8x5_write(struct usb_serial_port *port,
+static int spcp8x5_write(struct tty_struct *tty, struct usb_serial_port *port,
                         const unsigned char *buf, int count)
 {
        struct spcp8x5_private *priv = usb_get_serial_port_data(port);
@@ -925,9 +925,10 @@ static int spcp8x5_wait_modem_info(struct usb_serial_port *port,
        return 0;
 }
 
-static int spcp8x5_ioctl(struct usb_serial_port *port, struct file *file,
+static int spcp8x5_ioctl(struct tty_struct *tty, struct file *file,
                         unsigned int cmd, unsigned long arg)
 {
+       struct usb_serial_port *port = tty->driver_data;
        dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd);
 
        switch (cmd) {
@@ -943,9 +944,10 @@ static int spcp8x5_ioctl(struct usb_serial_port *port, struct file *file,
        return -ENOIOCTLCMD;
 }
 
-static int spcp8x5_tiocmset(struct usb_serial_port *port, struct file *file,
+static int spcp8x5_tiocmset(struct tty_struct *tty, struct file *file,
                            unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct spcp8x5_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        u8 control;
@@ -965,8 +967,9 @@ static int spcp8x5_tiocmset(struct usb_serial_port *port, struct file *file,
        return spcp8x5_set_ctrlLine(port->serial->dev, control , priv->type);
 }
 
-static int spcp8x5_tiocmget(struct usb_serial_port *port, struct file *file)
+static int spcp8x5_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct spcp8x5_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        unsigned int mcr;
@@ -989,8 +992,9 @@ static int spcp8x5_tiocmget(struct usb_serial_port *port, struct file *file)
 }
 
 /* get the avail space room in ring buffer */
-static int spcp8x5_write_room(struct usb_serial_port *port)
+static int spcp8x5_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct spcp8x5_private *priv = usb_get_serial_port_data(port);
        int room = 0;
        unsigned long flags;
@@ -1003,8 +1007,9 @@ static int spcp8x5_write_room(struct usb_serial_port *port)
 }
 
 /* get the number of avail data in write ring buffer */
-static int spcp8x5_chars_in_buffer(struct usb_serial_port *port)
+static int spcp8x5_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct spcp8x5_private *priv = usb_get_serial_port_data(port);
        int chars = 0;
        unsigned long flags;
index a26a629dfc4f7d4f6d65ac5d0648537047f3f49c..e39c779e416099ea0a94a28d622851abaf71f13a 100644 (file)
@@ -16,7 +16,7 @@
  * For questions or problems with this driver, contact Texas Instruments
  * technical support, or Al Borchers <alborchers@steinerpoint.com>, or
  * Peter Berger <pberger@brimson.com>.
- * 
+ *
  * This driver needs this hotplug script in /etc/hotplug/usb/ti_usb_3410_5052
  * or in /etc/hotplug.d/usb/ti_usb_3410_5052.hotplug to set the device
  * configuration.
@@ -70,6 +70,7 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/firmware.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/tty.h>
@@ -81,7 +82,7 @@
 #include <linux/serial.h>
 #include <linux/circ_buf.h>
 #include <linux/mutex.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include <linux/firmware.h>
@@ -149,21 +150,24 @@ struct ti_device {
 
 static int ti_startup(struct usb_serial *serial);
 static void ti_shutdown(struct usb_serial *serial);
-static int ti_open(struct usb_serial_port *port, struct file *file);
-static void ti_close(struct usb_serial_port *port, struct file *file);
-static int ti_write(struct usb_serial_port *port, const unsigned char *data,
-       int count);
-static int ti_write_room(struct usb_serial_port *port);
-static int ti_chars_in_buffer(struct usb_serial_port *port);
-static void ti_throttle(struct usb_serial_port *port);
-static void ti_unthrottle(struct usb_serial_port *port);
-static int ti_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg);
-static void ti_set_termios(struct usb_serial_port *port,
-       struct ktermios *old_termios);
-static int ti_tiocmget(struct usb_serial_port *port, struct file *file);
-static int ti_tiocmset(struct usb_serial_port *port, struct file *file,
-       unsigned int set, unsigned int clear);
-static void ti_break(struct usb_serial_port *port, int break_state);
+static int ti_open(struct tty_struct *tty, struct usb_serial_port *port,
+               struct file *file);
+static void ti_close(struct tty_struct *tty, struct usb_serial_port *port,
+               struct file *file);
+static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
+               const unsigned char *data, int count);
+static int ti_write_room(struct tty_struct *tty);
+static int ti_chars_in_buffer(struct tty_struct *tty);
+static void ti_throttle(struct tty_struct *tty);
+static void ti_unthrottle(struct tty_struct *tty);
+static int ti_ioctl(struct tty_struct *tty, struct file *file,
+               unsigned int cmd, unsigned long arg);
+static void ti_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios);
+static int ti_tiocmget(struct tty_struct *tty, struct file *file);
+static int ti_tiocmset(struct tty_struct *tty, struct file *file,
+               unsigned int set, unsigned int clear);
+static void ti_break(struct tty_struct *tty, int break_state);
 static void ti_interrupt_callback(struct urb *urb);
 static void ti_bulk_in_callback(struct urb *urb);
 static void ti_bulk_out_callback(struct urb *urb);
@@ -192,8 +196,7 @@ static int ti_command_in_sync(struct ti_device *tdev, __u8 command,
 static int ti_write_byte(struct ti_device *tdev, unsigned long addr,
        __u8 mask, __u8 byte);
 
-static int ti_download_firmware(struct ti_device *tdev, char *fw_name);
-
+static int ti_download_firmware(struct ti_device *tdev, int type);
 
 /* circular buffer */
 static struct circ_buf *ti_buf_alloc(void);
@@ -325,19 +328,25 @@ module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
 
 module_param(low_latency, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(low_latency, "TTY low_latency flag, 0=off, 1=on, default is off");
+MODULE_PARM_DESC(low_latency,
+               "TTY low_latency flag, 0=off, 1=on, default is off");
 
 module_param(closing_wait, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain in close, in .01 secs, default is 4000");
+MODULE_PARM_DESC(closing_wait,
+    "Maximum wait for data to drain in close, in .01 secs, default is 4000");
 
 module_param_array(vendor_3410, ushort, &vendor_3410_count, S_IRUGO);
-MODULE_PARM_DESC(vendor_3410, "Vendor ids for 3410 based devices, 1-5 short integers");
+MODULE_PARM_DESC(vendor_3410,
+               "Vendor ids for 3410 based devices, 1-5 short integers");
 module_param_array(product_3410, ushort, &product_3410_count, S_IRUGO);
-MODULE_PARM_DESC(product_3410, "Product ids for 3410 based devices, 1-5 short integers");
+MODULE_PARM_DESC(product_3410,
+               "Product ids for 3410 based devices, 1-5 short integers");
 module_param_array(vendor_5052, ushort, &vendor_5052_count, S_IRUGO);
-MODULE_PARM_DESC(vendor_5052, "Vendor ids for 5052 based devices, 1-5 short integers");
+MODULE_PARM_DESC(vendor_5052,
+               "Vendor ids for 5052 based devices, 1-5 short integers");
 module_param_array(product_5052, ushort, &product_5052_count, S_IRUGO);
-MODULE_PARM_DESC(product_5052, "Product ids for 5052 based devices, 1-5 short integers");
+MODULE_PARM_DESC(product_5052,
+               "Product ids for 5052 based devices, 1-5 short integers");
 
 MODULE_DEVICE_TABLE(usb, ti_id_table_combined);
 
@@ -346,18 +355,18 @@ MODULE_DEVICE_TABLE(usb, ti_id_table_combined);
 
 static int __init ti_init(void)
 {
-       int i,j;
+       int i, j;
        int ret;
 
        /* insert extra vendor and product ids */
        j = ARRAY_SIZE(ti_id_table_3410) - TI_EXTRA_VID_PID_COUNT - 1;
-       for (i=0; i<min(vendor_3410_count,product_3410_count); i++,j++) {
+       for (i = 0; i < min(vendor_3410_count, product_3410_count); i++, j++) {
                ti_id_table_3410[j].idVendor = vendor_3410[i];
                ti_id_table_3410[j].idProduct = product_3410[i];
                ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
        }
        j = ARRAY_SIZE(ti_id_table_5052) - TI_EXTRA_VID_PID_COUNT - 1;
-       for (i=0; i<min(vendor_5052_count,product_5052_count); i++,j++) {
+       for (i = 0; i < min(vendor_5052_count, product_5052_count); i++, j++) {
                ti_id_table_5052[j].idVendor = vendor_5052[i];
                ti_id_table_5052[j].idProduct = product_5052[i];
                ti_id_table_5052[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
@@ -426,15 +435,15 @@ static int ti_startup(struct usb_serial *serial)
        /* determine device type */
        if (usb_match_id(serial->interface, ti_id_table_3410))
                tdev->td_is_3410 = 1;
-       dbg("%s - device type is %s", __func__, tdev->td_is_3410 ? "3410" : "5052");
+       dbg("%s - device type is %s", __func__,
+                               tdev->td_is_3410 ? "3410" : "5052");
 
        /* if we have only 1 configuration, download firmware */
        if (dev->descriptor.bNumConfigurations == 1) {
-
                if (tdev->td_is_3410)
-                       status = ti_download_firmware(tdev, "ti_3410.fw");
+                       status = ti_download_firmware(tdev, 3410);
                else
-                       status = ti_download_firmware(tdev, "ti_5052.fw");
+                       status = ti_download_firmware(tdev, 5052);
                if (status)
                        goto free_tdev;
 
@@ -446,7 +455,7 @@ static int ti_startup(struct usb_serial *serial)
 
                status = -ENODEV;
                goto free_tdev;
-       } 
+       }
 
        /* the second configuration must be set (in sysfs by hotplug script) */
        if (dev->actconfig->desc.bConfigurationValue == TI_BOOT_CONFIG) {
@@ -463,7 +472,8 @@ static int ti_startup(struct usb_serial *serial)
                        goto free_tports;
                }
                spin_lock_init(&tport->tp_lock);
-               tport->tp_uart_base_addr = (i == 0 ? TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
+               tport->tp_uart_base_addr = (i == 0 ?
+                               TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
                tport->tp_flags = low_latency ? ASYNC_LOW_LATENCY : 0;
                tport->tp_closing_wait = closing_wait;
                init_waitqueue_head(&tport->tp_msr_wait);
@@ -480,11 +490,11 @@ static int ti_startup(struct usb_serial *serial)
                usb_set_serial_port_data(serial->port[i], tport);
                tport->tp_uart_mode = 0;        /* default is RS232 */
        }
-       
+
        return 0;
 
 free_tports:
-       for (--i; i>=0; --i) {
+       for (--i; i >= 0; --i) {
                tport = usb_get_serial_port_data(serial->port[i]);
                ti_buf_free(tport->tp_write_buf);
                kfree(tport);
@@ -505,7 +515,7 @@ static void ti_shutdown(struct usb_serial *serial)
 
        dbg("%s", __func__);
 
-       for (i=0; i < serial->num_ports; ++i) {
+       for (i = 0; i < serial->num_ports; ++i) {
                tport = usb_get_serial_port_data(serial->port[i]);
                if (tport) {
                        ti_buf_free(tport->tp_write_buf);
@@ -519,7 +529,8 @@ static void ti_shutdown(struct usb_serial *serial)
 }
 
 
-static int ti_open(struct usb_serial_port *port, struct file *file)
+static int ti_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *file)
 {
        struct ti_port *tport = usb_get_serial_port_data(port);
        struct ti_device *tdev;
@@ -527,8 +538,8 @@ static int ti_open(struct usb_serial_port *port, struct file *file)
        struct urb *urb;
        int port_number;
        int status;
-       __u16 open_settings = (__u8)(TI_PIPE_MODE_CONTINOUS | 
-                            TI_PIPE_TIMEOUT_ENABLE | 
+       __u16 open_settings = (__u8)(TI_PIPE_MODE_CONTINOUS |
+                            TI_PIPE_TIMEOUT_ENABLE |
                             (TI_TRANSFER_TIMEOUT << 2));
 
        dbg("%s - port %d", __func__, port->number);
@@ -543,9 +554,9 @@ static int ti_open(struct usb_serial_port *port, struct file *file)
        if (mutex_lock_interruptible(&tdev->td_open_close_lock))
                return -ERESTARTSYS;
 
-       if (port->tty)
-               port->tty->low_latency = 
-                       (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+       if (tty)
+               tty->low_latency =
+                               (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 
        port_number = port->number - port->serial->minor;
 
@@ -559,7 +570,8 @@ static int ti_open(struct usb_serial_port *port, struct file *file)
                dbg("%s - start interrupt in urb", __func__);
                urb = tdev->td_serial->port[0]->interrupt_in_urb;
                if (!urb) {
-                       dev_err(&port->dev, "%s - no interrupt urb\n", __func__);
+                       dev_err(&port->dev, "%s - no interrupt urb\n",
+                                                               __func__);
                        status = -EINVAL;
                        goto release_lock;
                }
@@ -568,18 +580,22 @@ static int ti_open(struct usb_serial_port *port, struct file *file)
                urb->dev = dev;
                status = usb_submit_urb(urb, GFP_KERNEL);
                if (status) {
-                       dev_err(&port->dev, "%s - submit interrupt urb failed, %d\n", __func__, status);
+                       dev_err(&port->dev,
+                               "%s - submit interrupt urb failed, %d\n",
+                                       __func__, status);
                        goto release_lock;
                }
        }
 
-       ti_set_termios(port, port->tty->termios);
+       if (tty)
+               ti_set_termios(tty, port, tty->termios);
 
        dbg("%s - sending TI_OPEN_PORT", __func__);
        status = ti_command_out_sync(tdev, TI_OPEN_PORT,
                (__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0);
        if (status) {
-               dev_err(&port->dev, "%s - cannot send open command, %d\n", __func__, status);
+               dev_err(&port->dev, "%s - cannot send open command, %d\n",
+                                                       __func__, status);
                goto unlink_int_urb;
        }
 
@@ -587,7 +603,8 @@ static int ti_open(struct usb_serial_port *port, struct file *file)
        status = ti_command_out_sync(tdev, TI_START_PORT,
                (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0);
        if (status) {
-               dev_err(&port->dev, "%s - cannot send start command, %d\n", __func__, status);
+               dev_err(&port->dev, "%s - cannot send start command, %d\n",
+                                                       __func__, status);
                goto unlink_int_urb;
        }
 
@@ -595,13 +612,15 @@ static int ti_open(struct usb_serial_port *port, struct file *file)
        status = ti_command_out_sync(tdev, TI_PURGE_PORT,
                (__u8)(TI_UART1_PORT + port_number), TI_PURGE_INPUT, NULL, 0);
        if (status) {
-               dev_err(&port->dev, "%s - cannot clear input buffers, %d\n", __func__, status);
+               dev_err(&port->dev, "%s - cannot clear input buffers, %d\n",
+                                                       __func__, status);
                goto unlink_int_urb;
        }
        status = ti_command_out_sync(tdev, TI_PURGE_PORT,
                (__u8)(TI_UART1_PORT + port_number), TI_PURGE_OUTPUT, NULL, 0);
        if (status) {
-               dev_err(&port->dev, "%s - cannot clear output buffers, %d\n", __func__, status);
+               dev_err(&port->dev, "%s - cannot clear output buffers, %d\n",
+                                                       __func__, status);
                goto unlink_int_urb;
        }
 
@@ -610,13 +629,15 @@ static int ti_open(struct usb_serial_port *port, struct file *file)
        usb_clear_halt(dev, port->write_urb->pipe);
        usb_clear_halt(dev, port->read_urb->pipe);
 
-       ti_set_termios(port, port->tty->termios);
+       if (tty)
+               ti_set_termios(tty, port, tty->termios);
 
        dbg("%s - sending TI_OPEN_PORT (2)", __func__);
        status = ti_command_out_sync(tdev, TI_OPEN_PORT,
                (__u8)(TI_UART1_PORT + port_number), open_settings, NULL, 0);
        if (status) {
-               dev_err(&port->dev, "%s - cannot send open command (2), %d\n", __func__, status);
+               dev_err(&port->dev, "%s - cannot send open command (2), %d\n",
+                                                       __func__, status);
                goto unlink_int_urb;
        }
 
@@ -624,7 +645,8 @@ static int ti_open(struct usb_serial_port *port, struct file *file)
        status = ti_command_out_sync(tdev, TI_START_PORT,
                (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0);
        if (status) {
-               dev_err(&port->dev, "%s - cannot send start command (2), %d\n", __func__, status);
+               dev_err(&port->dev, "%s - cannot send start command (2), %d\n",
+                                                       __func__, status);
                goto unlink_int_urb;
        }
 
@@ -642,7 +664,8 @@ static int ti_open(struct usb_serial_port *port, struct file *file)
        urb->dev = dev;
        status = usb_submit_urb(urb, GFP_KERNEL);
        if (status) {
-               dev_err(&port->dev, "%s - submit read urb failed, %d\n", __func__, status);
+               dev_err(&port->dev, "%s - submit read urb failed, %d\n",
+                                                       __func__, status);
                goto unlink_int_urb;
        }
 
@@ -661,7 +684,8 @@ release_lock:
 }
 
 
-static void ti_close(struct usb_serial_port *port, struct file *file)
+static void ti_close(struct tty_struct *tty, struct usb_serial_port *port,
+                                                       struct file *file)
 {
        struct ti_device *tdev;
        struct ti_port *tport;
@@ -670,7 +694,7 @@ static void ti_close(struct usb_serial_port *port, struct file *file)
        int do_unlock;
 
        dbg("%s - port %d", __func__, port->number);
-                        
+
        tdev = usb_get_serial_data(port->serial);
        tport = usb_get_serial_port_data(port);
        if (tdev == NULL || tport == NULL)
@@ -690,7 +714,9 @@ static void ti_close(struct usb_serial_port *port, struct file *file)
        status = ti_command_out_sync(tdev, TI_CLOSE_PORT,
                     (__u8)(TI_UART1_PORT + port_number), 0, NULL, 0);
        if (status)
-               dev_err(&port->dev, "%s - cannot send close port command, %d\n" , __func__, status);
+               dev_err(&port->dev,
+                       "%s - cannot send close port command, %d\n"
+                                                       , __func__, status);
 
        /* if mutex_lock is interrupted, continue anyway */
        do_unlock = !mutex_lock_interruptible(&tdev->td_open_close_lock);
@@ -707,8 +733,8 @@ static void ti_close(struct usb_serial_port *port, struct file *file)
 }
 
 
-static int ti_write(struct usb_serial_port *port, const unsigned char *data,
-       int count)
+static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
+                       const unsigned char *data, int count)
 {
        struct ti_port *tport = usb_get_serial_port_data(port);
        unsigned long flags;
@@ -733,8 +759,9 @@ static int ti_write(struct usb_serial_port *port, const unsigned char *data,
 }
 
 
-static int ti_write_room(struct usb_serial_port *port)
+static int ti_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ti_port *tport = usb_get_serial_port_data(port);
        int room = 0;
        unsigned long flags;
@@ -743,7 +770,7 @@ static int ti_write_room(struct usb_serial_port *port)
 
        if (tport == NULL)
                return -ENODEV;
-       
+
        spin_lock_irqsave(&tport->tp_lock, flags);
        room = ti_buf_space_avail(tport->tp_write_buf);
        spin_unlock_irqrestore(&tport->tp_lock, flags);
@@ -753,8 +780,9 @@ static int ti_write_room(struct usb_serial_port *port)
 }
 
 
-static int ti_chars_in_buffer(struct usb_serial_port *port)
+static int ti_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ti_port *tport = usb_get_serial_port_data(port);
        int chars = 0;
        unsigned long flags;
@@ -773,32 +801,26 @@ static int ti_chars_in_buffer(struct usb_serial_port *port)
 }
 
 
-static void ti_throttle(struct usb_serial_port *port)
+static void ti_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ti_port *tport = usb_get_serial_port_data(port);
-       struct tty_struct *tty;
 
        dbg("%s - port %d", __func__, port->number);
 
        if (tport == NULL)
                return;
 
-       tty = port->tty;
-       if (!tty) {
-               dbg("%s - no tty", __func__);
-               return;
-       }
-
        if (I_IXOFF(tty) || C_CRTSCTS(tty))
                ti_stop_read(tport, tty);
 
 }
 
 
-static void ti_unthrottle(struct usb_serial_port *port)
+static void ti_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ti_port *tport = usb_get_serial_port_data(port);
-       struct tty_struct *tty;
        int status;
 
        dbg("%s - port %d", __func__, port->number);
@@ -806,23 +828,19 @@ static void ti_unthrottle(struct usb_serial_port *port)
        if (tport == NULL)
                return;
 
-       tty = port->tty;
-       if (!tty) {
-               dbg("%s - no tty", __func__);
-               return;
-       }
-
        if (I_IXOFF(tty) || C_CRTSCTS(tty)) {
                status = ti_restart_read(tport, tty);
                if (status)
-                       dev_err(&port->dev, "%s - cannot restart read, %d\n", __func__, status);
+                       dev_err(&port->dev, "%s - cannot restart read, %d\n",
+                                                       __func__, status);
        }
 }
 
 
-static int ti_ioctl(struct usb_serial_port *port, struct file *file,
+static int ti_ioctl(struct tty_struct *tty, struct file *file,
        unsigned int cmd, unsigned long arg)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ti_port *tport = usb_get_serial_port_data(port);
        struct async_icount cnow;
        struct async_icount cprev;
@@ -833,55 +851,52 @@ static int ti_ioctl(struct usb_serial_port *port, struct file *file,
                return -ENODEV;
 
        switch (cmd) {
-               case TIOCGSERIAL:
-                       dbg("%s - (%d) TIOCGSERIAL", __func__, port->number);
-                       return ti_get_serial_info(tport, (struct serial_struct __user *)arg);
-                       break;
-
-               case TIOCSSERIAL:
-                       dbg("%s - (%d) TIOCSSERIAL", __func__, port->number);
-                       return ti_set_serial_info(tport, (struct serial_struct __user *)arg);
-                       break;
-
-               case TIOCMIWAIT:
-                       dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
-                       cprev = tport->tp_icount;
-                       while (1) {
-                               interruptible_sleep_on(&tport->tp_msr_wait);
-                               if (signal_pending(current))
-                                       return -ERESTARTSYS;
-                               cnow = tport->tp_icount;
-                               if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
-                                   cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
-                                       return -EIO; /* no change => error */
-                               if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
-                                   ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
-                                   ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
-                                   ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
-                                       return 0;
-                               }
-                               cprev = cnow;
-                       }
-                       break;
-
-               case TIOCGICOUNT:
-                       dbg("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __func__, port->number, tport->tp_icount.rx, tport->tp_icount.tx);
-                       if (copy_to_user((void __user *)arg, &tport->tp_icount, sizeof(tport->tp_icount)))
-                               return -EFAULT;
-                       return 0;
+       case TIOCGSERIAL:
+               dbg("%s - (%d) TIOCGSERIAL", __func__, port->number);
+               return ti_get_serial_info(tport,
+                               (struct serial_struct __user *)arg);
+       case TIOCSSERIAL:
+               dbg("%s - (%d) TIOCSSERIAL", __func__, port->number);
+               return ti_set_serial_info(tport,
+                                       (struct serial_struct __user *)arg);
+       case TIOCMIWAIT:
+               dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
+               cprev = tport->tp_icount;
+               while (1) {
+                       interruptible_sleep_on(&tport->tp_msr_wait);
+                       if (signal_pending(current))
+                               return -ERESTARTSYS;
+                       cnow = tport->tp_icount;
+                       if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+                           cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+                               return -EIO; /* no change => error */
+                       if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+                           ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+                           ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+                           ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)))
+                               return 0;
+                       cprev = cnow;
+               }
+               break;
+       case TIOCGICOUNT:
+               dbg("%s - (%d) TIOCGICOUNT RX=%d, TX=%d",
+                               __func__, port->number,
+                               tport->tp_icount.rx, tport->tp_icount.tx);
+               if (copy_to_user((void __user *)arg, &tport->tp_icount,
+                                       sizeof(tport->tp_icount)))
+                       return -EFAULT;
+               return 0;
        }
-
        return -ENOIOCTLCMD;
 }
 
 
-static void ti_set_termios(struct usb_serial_port *port,
-       struct ktermios *old_termios)
+static void ti_set_termios(struct tty_struct *tty,
+               struct usb_serial_port *port, struct ktermios *old_termios)
 {
        struct ti_port *tport = usb_get_serial_port_data(port);
-       struct tty_struct *tty = port->tty;
        struct ti_uart_config *config;
-       tcflag_t cflag,iflag;
+       tcflag_t cflag, iflag;
        int baud;
        int status;
        int port_number = port->number - port->serial->minor;
@@ -893,7 +908,8 @@ static void ti_set_termios(struct usb_serial_port *port,
        iflag = tty->termios->c_iflag;
 
        dbg("%s - cflag %08x, iflag %08x", __func__, cflag, iflag);
-       dbg("%s - old clfag %08x, old iflag %08x", __func__, old_termios->c_cflag, old_termios->c_iflag);
+       dbg("%s - old clfag %08x, old iflag %08x", __func__,
+                               old_termios->c_cflag, old_termios->c_iflag);
 
        if (tport == NULL)
                return;
@@ -912,19 +928,19 @@ static void ti_set_termios(struct usb_serial_port *port,
        config->bUartMode = (__u8)(tport->tp_uart_mode);
 
        switch (cflag & CSIZE) {
-               case CS5:
-                           config->bDataBits = TI_UART_5_DATA_BITS;
-                           break;
-               case CS6:
-                           config->bDataBits = TI_UART_6_DATA_BITS;
-                           break;
-               case CS7:
-                           config->bDataBits = TI_UART_7_DATA_BITS;
-                           break;
-               default:
-               case CS8:
-                           config->bDataBits = TI_UART_8_DATA_BITS;
-                           break;
+       case CS5:
+                   config->bDataBits = TI_UART_5_DATA_BITS;
+                   break;
+       case CS6:
+                   config->bDataBits = TI_UART_6_DATA_BITS;
+                   break;
+       case CS7:
+                   config->bDataBits = TI_UART_7_DATA_BITS;
+                   break;
+       default:
+       case CS8:
+                   config->bDataBits = TI_UART_8_DATA_BITS;
+                   break;
        }
 
        /* CMSPAR isn't supported by this driver */
@@ -940,7 +956,7 @@ static void ti_set_termios(struct usb_serial_port *port,
                }
        } else {
                config->wFlags &= ~TI_UART_ENABLE_PARITY_CHECKING;
-               config->bParity = TI_UART_NO_PARITY;    
+               config->bParity = TI_UART_NO_PARITY;
        }
 
        if (cflag & CSTOPB)
@@ -993,7 +1009,8 @@ static void ti_set_termios(struct usb_serial_port *port,
                (__u8)(TI_UART1_PORT + port_number), 0, (__u8 *)config,
                sizeof(*config));
        if (status)
-               dev_err(&port->dev, "%s - cannot set config on port %d, %d\n", __func__, port_number, status);
+               dev_err(&port->dev, "%s - cannot set config on port %d, %d\n",
+                                       __func__, port_number, status);
 
        /* SET_CONFIG asserts RTS and DTR, reset them correctly */
        mcr = tport->tp_shadow_mcr;
@@ -1002,14 +1019,17 @@ static void ti_set_termios(struct usb_serial_port *port,
                mcr &= ~(TI_MCR_DTR | TI_MCR_RTS);
        status = ti_set_mcr(tport, mcr);
        if (status)
-               dev_err(&port->dev, "%s - cannot set modem control on port %d, %d\n", __func__, port_number, status);
+               dev_err(&port->dev,
+                       "%s - cannot set modem control on port %d, %d\n",
+                                               __func__, port_number, status);
 
        kfree(config);
 }
 
 
-static int ti_tiocmget(struct usb_serial_port *port, struct file *file)
+static int ti_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ti_port *tport = usb_get_serial_port_data(port);
        unsigned int result;
        unsigned int msr;
@@ -1040,9 +1060,10 @@ static int ti_tiocmget(struct usb_serial_port *port, struct file *file)
 }
 
 
-static int ti_tiocmset(struct usb_serial_port *port, struct file *file,
+static int ti_tiocmset(struct tty_struct *tty, struct file *file,
        unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ti_port *tport = usb_get_serial_port_data(port);
        unsigned int mcr;
        unsigned long flags;
@@ -1074,8 +1095,9 @@ static int ti_tiocmset(struct usb_serial_port *port, struct file *file,
 }
 
 
-static void ti_break(struct usb_serial_port *port, int break_state)
+static void ti_break(struct tty_struct *tty, int break_state)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct ti_port *tport = usb_get_serial_port_data(port);
        int status;
 
@@ -1141,10 +1163,12 @@ static void ti_interrupt_callback(struct urb *urb)
        port_number = TI_GET_PORT_FROM_CODE(data[0]);
        function = TI_GET_FUNC_FROM_CODE(data[0]);
 
-       dbg("%s - port_number %d, function %d, data 0x%02X", __func__, port_number, function, data[1]);
+       dbg("%s - port_number %d, function %d, data 0x%02X",
+                               __func__, port_number, function, data[1]);
 
        if (port_number >= serial->num_ports) {
-               dev_err(dev, "%s - bad port number, %d\n", __func__, port_number);
+               dev_err(dev, "%s - bad port number, %d\n",
+                                               __func__, port_number);
                goto exit;
        }
 
@@ -1156,7 +1180,8 @@ static void ti_interrupt_callback(struct urb *urb)
 
        switch (function) {
        case TI_CODE_DATA_ERROR:
-               dev_err(dev, "%s - DATA ERROR, port %d, data 0x%02X\n", __func__, port_number, data[1]);
+               dev_err(dev, "%s - DATA ERROR, port %d, data 0x%02X\n",
+                                       __func__, port_number, data[1]);
                break;
 
        case TI_CODE_MODEM_STATUS:
@@ -1166,7 +1191,8 @@ static void ti_interrupt_callback(struct urb *urb)
                break;
 
        default:
-               dev_err(dev, "%s - unknown interrupt code, 0x%02X\n", __func__, data[1]);
+               dev_err(dev, "%s - unknown interrupt code, 0x%02X\n",
+                                                       __func__, data[1]);
                break;
        }
 
@@ -1200,7 +1226,7 @@ static void ti_bulk_in_callback(struct urb *urb)
                return;
        default:
                dev_err(dev, "%s - nonzero urb status, %d\n",
-                       __func__, status );
+                       __func__, status);
                tport->tp_tdev->td_urb_error = 1;
                wake_up_interruptible(&tport->tp_write_wait);
        }
@@ -1213,15 +1239,16 @@ static void ti_bulk_in_callback(struct urb *urb)
                return;
        }
 
-       if (port->tty && urb->actual_length) {
+       if (port->port.tty && urb->actual_length) {
                usb_serial_debug_data(debug, dev, __func__,
                        urb->actual_length, urb->transfer_buffer);
 
                if (!tport->tp_is_open)
                        dbg("%s - port closed, dropping data", __func__);
                else
-                       ti_recv(&urb->dev->dev, port->tty, urb->transfer_buffer,
-                               urb->actual_length);
+                       ti_recv(&urb->dev->dev, port->port.tty,
+                                               urb->transfer_buffer,
+                                               urb->actual_length);
 
                spin_lock(&tport->tp_lock);
                tport->tp_icount.rx += urb->actual_length;
@@ -1285,8 +1312,9 @@ static void ti_recv(struct device *dev, struct tty_struct *tty,
        do {
                cnt = tty_buffer_request_room(tty, length);
                if (cnt < length) {
-                       dev_err(dev, "%s - dropping data, %d bytes lost\n", __func__, length - cnt);
-                       if(cnt == 0)
+                       dev_err(dev, "%s - dropping data, %d bytes lost\n",
+                                               __func__, length - cnt);
+                       if (cnt == 0)
                                break;
                }
                tty_insert_flip_string(tty, data, cnt);
@@ -1302,7 +1330,7 @@ static void ti_send(struct ti_port *tport)
 {
        int count, result;
        struct usb_serial_port *port = tport->tp_port;
-       struct tty_struct *tty = port->tty;
+       struct tty_struct *tty = port->port.tty;        /* FIXME */
        unsigned long flags;
 
 
@@ -1328,7 +1356,8 @@ static void ti_send(struct ti_port *tport)
 
        spin_unlock_irqrestore(&tport->tp_lock, flags);
 
-       usb_serial_debug_data(debug, &port->dev, __func__, count, port->write_urb->transfer_buffer);
+       usb_serial_debug_data(debug, &port->dev, __func__, count,
+                                       port->write_urb->transfer_buffer);
 
        usb_fill_bulk_urb(port->write_urb, port->serial->dev,
                           usb_sndbulkpipe(port->serial->dev,
@@ -1338,8 +1367,9 @@ static void ti_send(struct ti_port *tport)
 
        result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
        if (result) {
-               dev_err(&port->dev, "%s - submit write urb failed, %d\n", __func__, result);
-               tport->tp_write_urb_in_use = 0; 
+               dev_err(&port->dev, "%s - submit write urb failed, %d\n",
+                                                       __func__, result);
+               tport->tp_write_urb_in_use = 0;
                /* TODO: reschedule ti_send */
        } else {
                spin_lock_irqsave(&tport->tp_lock, flags);
@@ -1374,7 +1404,7 @@ static int ti_set_mcr(struct ti_port *tport, unsigned int mcr)
 
 static int ti_get_lsr(struct ti_port *tport)
 {
-       int size,status;
+       int size, status;
        struct ti_device *tdev = tport->tp_tdev;
        struct usb_serial_port *port = tport->tp_port;
        int port_number = port->number - port->serial->minor;
@@ -1392,7 +1422,9 @@ static int ti_get_lsr(struct ti_port *tport)
        status = ti_command_in_sync(tdev, TI_GET_PORT_STATUS,
                (__u8)(TI_UART1_PORT+port_number), 0, (__u8 *)data, size);
        if (status) {
-               dev_err(&port->dev, "%s - get port status command failed, %d\n", __func__, status);
+               dev_err(&port->dev,
+                       "%s - get port status command failed, %d\n",
+                                                       __func__, status);
                goto free_data;
        }
 
@@ -1442,8 +1474,9 @@ static int ti_set_serial_info(struct ti_port *tport,
                return -EFAULT;
 
        tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS;
-       if (port->tty)
-               port->tty->low_latency =
+       /* FIXME */
+       if (port->port.tty)
+               port->port.tty->low_latency =
                        (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
        tport->tp_closing_wait = new_serial.closing_wait;
 
@@ -1477,7 +1510,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr)
        tport->tp_msr = msr & TI_MSR_MASK;
 
        /* handle CTS flow control */
-       tty = tport->tp_port->tty;
+       tty = tport->tp_port->port.tty;
        if (tty && C_CRTSCTS(tty)) {
                if (msr & TI_MSR_CTS) {
                        tty->hw_stopped = 0;
@@ -1627,7 +1660,8 @@ static int ti_write_byte(struct ti_device *tdev, unsigned long addr,
        struct ti_write_data_bytes *data;
        struct device *dev = &tdev->td_serial->dev->dev;
 
-       dbg("%s - addr 0x%08lX, mask 0x%02X, byte 0x%02X", __func__, addr, mask, byte);
+       dbg("%s - addr 0x%08lX, mask 0x%02X, byte 0x%02X",
+                                       __func__, addr, mask, byte);
 
        size = sizeof(struct ti_write_data_bytes) + 2;
        data = kmalloc(size, GFP_KERNEL);
@@ -1655,67 +1689,68 @@ static int ti_write_byte(struct ti_device *tdev, unsigned long addr,
        return status;
 }
 
-
-static int ti_download_firmware(struct ti_device *tdev,
-                               char *fw_name)
+static int ti_do_download(struct usb_device *dev, int pipe,
+                                               u8 *buffer, int size)
 {
-       const struct firmware *fw;
-       int status = 0;
-       int buffer_size;
        int pos;
-       int len;
+       u8 cs = 0;
        int done;
-       __u8 cs = 0;
-       __u8 *buffer;
-       struct usb_device *dev = tdev->td_serial->dev;
        struct ti_firmware_header *header;
-       unsigned int pipe = usb_sndbulkpipe(dev,
-               tdev->td_serial->port[0]->bulk_out_endpointAddress);
-
-       buffer_size = TI_FIRMWARE_BUF_SIZE + sizeof(struct ti_firmware_header);
-
-       if (request_firmware(&fw, fw_name, &dev->dev)) {
-               dev_err(&dev->dev, "%s - failed to load firmware \"%s\"\n",
-                       __func__, fw_name);
-               return -ENOENT;
-       }
-       if (fw->size > buffer_size) {
-               dev_err(&dev->dev, "%s - firmware \"%s\" is too large\n",
-                       __func__, fw_name);
-               release_firmware(fw);
-               return -EINVAL;
-       }
-
-       buffer = kmalloc(buffer_size, GFP_KERNEL);
-       if (!buffer) {
-               dev_err(&dev->dev, "%s - out of memory\n", __func__);
-               release_firmware(fw);
-               return -ENOMEM;
-       }
-
-       memcpy(buffer, fw->data, fw->size);
-       memset(buffer+fw->size, 0xff, buffer_size-fw->size);
+       int status;
+       int len;
 
-       for(pos = sizeof(struct ti_firmware_header); pos < buffer_size; pos++)
+       for (pos = sizeof(struct ti_firmware_header); pos < size; pos++)
                cs = (__u8)(cs + buffer[pos]);
 
        header = (struct ti_firmware_header *)buffer;
-       header->wLength = cpu_to_le16((__u16)(buffer_size - sizeof(struct ti_firmware_header)));
+       header->wLength = cpu_to_le16((__u16)(size
+                                       - sizeof(struct ti_firmware_header)));
        header->bCheckSum = cs;
 
        dbg("%s - downloading firmware", __func__);
-       for (pos = 0; pos < buffer_size; pos += done) {
-               len = min(buffer_size - pos, TI_DOWNLOAD_MAX_PACKET_SIZE);
-               status = usb_bulk_msg(dev, pipe, buffer+pos, len, &done, 1000);
+       for (pos = 0; pos < size; pos += done) {
+               len = min(size - pos, TI_DOWNLOAD_MAX_PACKET_SIZE);
+               status = usb_bulk_msg(dev, pipe, buffer + pos, len,
+                                                               &done, 1000);
                if (status)
                        break;
        }
+       return status;
+}
 
-       kfree(buffer);
-       release_firmware(fw);
+static int ti_download_firmware(struct ti_device *tdev, int type)
+{
+       int status = -ENOMEM;
+       int buffer_size;
+       __u8 *buffer;
+       struct usb_device *dev = tdev->td_serial->dev;
+       unsigned int pipe = usb_sndbulkpipe(dev,
+               tdev->td_serial->port[0]->bulk_out_endpointAddress);
+       const struct firmware *fw_p;
+       char buf[32];
+       sprintf(buf, "ti_usb-%d.bin", type);
 
+       if (request_firmware(&fw_p, buf, &dev->dev)) {
+               dev_err(&dev->dev, "%s - firmware not found\n", __func__);
+               return -ENOENT;
+       }
+       if (fw_p->size > TI_FIRMWARE_BUF_SIZE) {
+               dev_err(&dev->dev, "%s - firmware too large\n", __func__);
+               return -ENOENT;
+       }
+
+       buffer_size = TI_FIRMWARE_BUF_SIZE + sizeof(struct ti_firmware_header);
+       buffer = kmalloc(buffer_size, GFP_KERNEL);
+       if (buffer) {
+               memcpy(buffer, fw_p->data, fw_p->size);
+               memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size);
+               ti_do_download(dev, pipe, buffer, fw_p->size);
+               kfree(buffer);
+       }
+       release_firmware(fw_p);
        if (status) {
-               dev_err(&dev->dev, "%s - error downloading firmware, %d\n", __func__, status);
+               dev_err(&dev->dev, "%s - error downloading firmware, %d\n",
+                                                       __func__, status);
                return status;
        }
 
@@ -1787,7 +1822,7 @@ static void ti_buf_clear(struct circ_buf *cb)
 
 static int ti_buf_data_avail(struct circ_buf *cb)
 {
-       return CIRC_CNT(cb->head,cb->tail,TI_WRITE_BUF_SIZE);
+       return CIRC_CNT(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
 }
 
 
@@ -1800,7 +1835,7 @@ static int ti_buf_data_avail(struct circ_buf *cb)
 
 static int ti_buf_space_avail(struct circ_buf *cb)
 {
-       return CIRC_SPACE(cb->head,cb->tail,TI_WRITE_BUF_SIZE);
+       return CIRC_SPACE(cb->head, cb->tail, TI_WRITE_BUF_SIZE);
 }
 
 
index 0cb0d77dc429b2b5d0f0dbd916feac063db7a4f6..8c2d531eedea1f3bf2759ec9796dcf96cb8dcfff 100644 (file)
@@ -12,7 +12,8 @@
  * This driver was originally based on the ACM driver by Armin Fuerst (which was
  * based on a driver by Brad Keryan)
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
  *
  */
 
@@ -28,7 +29,7 @@
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
 #include <linux/list.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include "pl2303.h"
@@ -59,7 +60,8 @@ static struct usb_driver usb_serial_driver = {
 */
 
 static int debug;
-static struct usb_serial *serial_table[SERIAL_TTY_MINORS];     /* initially all NULL */
+/* initially all NULL */
+static struct usb_serial *serial_table[SERIAL_TTY_MINORS];
 static DEFINE_MUTEX(table_lock);
 static LIST_HEAD(usb_serial_driver_list);
 
@@ -76,7 +78,8 @@ struct usb_serial *usb_serial_get_by_index(unsigned index)
        return serial;
 }
 
-static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_ports, unsigned int *minor)
+static struct usb_serial *get_free_serial(struct usb_serial *serial,
+                                       int num_ports, unsigned int *minor)
 {
        unsigned int i, j;
        int good_spot;
@@ -122,9 +125,8 @@ static void return_serial(struct usb_serial *serial)
        if (serial == NULL)
                return;
 
-       for (i = 0; i < serial->num_ports; ++i) {
+       for (i = 0; i < serial->num_ports; ++i)
                serial_table[serial->minor + i] = NULL;
-       }
 }
 
 static void destroy_serial(struct kref *kref)
@@ -143,7 +145,7 @@ static void destroy_serial(struct kref *kref)
        return_serial(serial);
 
        for (i = 0; i < serial->num_ports; ++i)
-               serial->port[i]->open_count = 0;
+               serial->port[i]->port.count = 0;
 
        /* the ports are cleaned up and released in port_release() */
        for (i = 0; i < serial->num_ports; ++i)
@@ -156,7 +158,8 @@ static void destroy_serial(struct kref *kref)
         * not get cleaned up in port_release() as it was never registered with
         * the driver core */
        if (serial->num_ports < serial->num_port_pointers) {
-               for (i = serial->num_ports; i < serial->num_port_pointers; ++i) {
+               for (i = serial->num_ports;
+                                       i < serial->num_port_pointers; ++i) {
                        port = serial->port[i];
                        if (!port)
                                continue;
@@ -167,7 +170,7 @@ static void destroy_serial(struct kref *kref)
        usb_put_dev(serial->dev);
 
        /* free up any memory that we allocated */
-       kfree (serial);
+       kfree(serial);
 }
 
 void usb_serial_put(struct usb_serial *serial)
@@ -180,13 +183,13 @@ void usb_serial_put(struct usb_serial *serial)
 /*****************************************************************************
  * Driver tty interface functions
  *****************************************************************************/
-static int serial_open (struct tty_struct *tty, struct file * filp)
+static int serial_open (struct tty_struct *tty, struct file *filp)
 {
        struct usb_serial *serial;
        struct usb_serial_port *port;
        unsigned int portNumber;
        int retval;
-       
+
        dbg("%s", __func__);
 
        /* get the serial object associated with this tty pointer */
@@ -207,15 +210,15 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
                retval = -ERESTARTSYS;
                goto bailout_kref_put;
        }
-        
-       ++port->open_count;
+
+       ++port->port.count;
 
        /* set up our port structure making the tty driver
         * remember our port object, and us it */
        tty->driver_data = port;
-       port->tty = tty;
+       port->port.tty = tty;
 
-       if (port->open_count == 1) {
+       if (port->port.count == 1) {
 
                /* lock this module before we call it
                 * this may fail, which means we must bail out,
@@ -228,9 +231,9 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
                retval = usb_autopm_get_interface(serial->interface);
                if (retval)
                        goto bailout_module_put;
-               /* only call the device specific open if this 
+               /* only call the device specific open if this
                 * is the first time the port is opened */
-               retval = serial->type->open(port, filp);
+               retval = serial->type->open(tty, port, filp);
                if (retval)
                        goto bailout_interface_put;
        }
@@ -243,16 +246,16 @@ bailout_interface_put:
 bailout_module_put:
        module_put(serial->type->driver.owner);
 bailout_mutex_unlock:
-       port->open_count = 0;
+       port->port.count = 0;
        tty->driver_data = NULL;
-       port->tty = NULL;
+       port->port.tty = NULL;
        mutex_unlock(&port->mutex);
 bailout_kref_put:
        usb_serial_put(serial);
        return retval;
 }
 
-static void serial_close(struct tty_struct *tty, struct file * filp)
+static void serial_close(struct tty_struct *tty, struct file *filp)
 {
        struct usb_serial_port *port = tty->driver_data;
 
@@ -263,27 +266,30 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
 
        mutex_lock(&port->mutex);
 
-       if (port->open_count == 0) {
+       if (port->port.count == 0) {
                mutex_unlock(&port->mutex);
                return;
        }
 
-       --port->open_count;
-       if (port->open_count == 0)
-               /* only call the device specific close if this 
+       --port->port.count;
+       if (port->port.count == 0)
+               /* only call the device specific close if this
                 * port is being closed by the last owner */
-               port->serial->type->close(port, filp);
+               port->serial->type->close(tty, port, filp);
 
-       if (port->open_count == (port->console? 1 : 0)) {
-               if (port->tty) {
-                       if (port->tty->driver_data)
-                               port->tty->driver_data = NULL;
-                       port->tty = NULL;
+       if (port->port.count == (port->console? 1 : 0)) {
+               if (port->port.tty) {
+                       if (port->port.tty->driver_data)
+                               port->port.tty->driver_data = NULL;
+                       port->port.tty = NULL;
                }
        }
 
-       if (port->open_count == 0) {
-               usb_autopm_put_interface(port->serial->interface);
+       if (port->port.count == 0) {
+               mutex_lock(&port->serial->disc_mutex);
+               if (!port->serial->disconnected)
+                       usb_autopm_put_interface(port->serial->interface);
+               mutex_unlock(&port->serial->disc_mutex);
                module_put(port->serial->type->driver.owner);
        }
 
@@ -291,7 +297,8 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
        usb_serial_put(port->serial);
 }
 
-static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
+static int serial_write(struct tty_struct *tty, const unsigned char *buf,
+                                                               int count)
 {
        struct usb_serial_port *port = tty->driver_data;
        int retval = -ENODEV;
@@ -301,107 +308,112 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int
 
        dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
 
-       /* open_count is managed under the mutex lock for the tty so cannot
-           drop to zero until after the last close completes */
-       WARN_ON(!port->open_count);
+       /* count is managed under the mutex lock for the tty so cannot
+          drop to zero until after the last close completes */
+       WARN_ON(!port->port.count);
 
        /* pass on to the driver specific version of this function */
-       retval = port->serial->type->write(port, buf, count);
+       retval = port->serial->type->write(tty, port, buf, count);
 
 exit:
        return retval;
 }
 
-static int serial_write_room (struct tty_struct *tty) 
+static int serial_write_room(struct tty_struct *tty)
 {
        struct usb_serial_port *port = tty->driver_data;
        dbg("%s - port %d", __func__, port->number);
-       WARN_ON(!port->open_count);
+       WARN_ON(!port->port.count);
        /* pass on to the driver specific version of this function */
-       return port->serial->type->write_room(port);
+       return port->serial->type->write_room(tty);
 }
 
-static int serial_chars_in_buffer (struct tty_struct *tty) 
+static int serial_chars_in_buffer(struct tty_struct *tty)
 {
        struct usb_serial_port *port = tty->driver_data;
        dbg("%s = port %d", __func__, port->number);
 
-       WARN_ON(!port->open_count);
+       WARN_ON(!port->port.count);
        /* pass on to the driver specific version of this function */
-       return port->serial->type->chars_in_buffer(port);
+       return port->serial->type->chars_in_buffer(tty);
 }
 
-static void serial_throttle (struct tty_struct * tty)
+static void serial_throttle(struct tty_struct *tty)
 {
        struct usb_serial_port *port = tty->driver_data;
        dbg("%s - port %d", __func__, port->number);
 
-       WARN_ON(!port->open_count);
+       WARN_ON(!port->port.count);
        /* pass on to the driver specific version of this function */
        if (port->serial->type->throttle)
-               port->serial->type->throttle(port);
+               port->serial->type->throttle(tty);
 }
 
-static void serial_unthrottle (struct tty_struct * tty)
+static void serial_unthrottle(struct tty_struct *tty)
 {
        struct usb_serial_port *port = tty->driver_data;
        dbg("%s - port %d", __func__, port->number);
 
-       WARN_ON(!port->open_count);
+       WARN_ON(!port->port.count);
        /* pass on to the driver specific version of this function */
        if (port->serial->type->unthrottle)
-               port->serial->type->unthrottle(port);
+               port->serial->type->unthrottle(tty);
 }
 
-static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
+static int serial_ioctl(struct tty_struct *tty, struct file *file,
+                                       unsigned int cmd, unsigned long arg)
 {
        struct usb_serial_port *port = tty->driver_data;
        int retval = -ENODEV;
 
        dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
 
-       WARN_ON(!port->open_count);
+       WARN_ON(!port->port.count);
 
-       /* pass on to the driver specific version of this function if it is available */
+       /* pass on to the driver specific version of this function
+          if it is available */
        if (port->serial->type->ioctl) {
                lock_kernel();
-               retval = port->serial->type->ioctl(port, file, cmd, arg);
+               retval = port->serial->type->ioctl(tty, file, cmd, arg);
                unlock_kernel();
-       }
-       else
+       } else
                retval = -ENOIOCTLCMD;
        return retval;
 }
 
-static void serial_set_termios (struct tty_struct *tty, struct ktermios * old)
+static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
 {
        struct usb_serial_port *port = tty->driver_data;
        dbg("%s - port %d", __func__, port->number);
 
-       WARN_ON(!port->open_count);
-       /* pass on to the driver specific version of this function if it is available */
+       WARN_ON(!port->port.count);
+       /* pass on to the driver specific version of this function
+          if it is available */
        if (port->serial->type->set_termios)
-               port->serial->type->set_termios(port, old);
+               port->serial->type->set_termios(tty, port, old);
        else
                tty_termios_copy_hw(tty->termios, old);
 }
 
-static void serial_break (struct tty_struct *tty, int break_state)
+static int serial_break(struct tty_struct *tty, int break_state)
 {
        struct usb_serial_port *port = tty->driver_data;
 
        dbg("%s - port %d", __func__, port->number);
 
-       WARN_ON(!port->open_count);
-       /* pass on to the driver specific version of this function if it is available */
+       WARN_ON(!port->port.count);
+       /* pass on to the driver specific version of this function
+          if it is available */
        if (port->serial->type->break_ctl) {
                lock_kernel();
-               port->serial->type->break_ctl(port, break_state);
+               port->serial->type->break_ctl(tty, break_state);
                unlock_kernel();
        }
+       return 0;
 }
 
-static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int serial_read_proc(char *page, char **start, off_t off, int count,
+                                                       int *eof, void *data)
 {
        struct usb_serial *serial;
        int length = 0;
@@ -410,26 +422,29 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int
        char tmp[40];
 
        dbg("%s", __func__);
-       length += sprintf (page, "usbserinfo:1.0 driver:2.0\n");
+       length += sprintf(page, "usbserinfo:1.0 driver:2.0\n");
        for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) {
                serial = usb_serial_get_by_index(i);
                if (serial == NULL)
                        continue;
 
-               length += sprintf (page+length, "%d:", i);
+               length += sprintf(page+length, "%d:", i);
                if (serial->type->driver.owner)
-                       length += sprintf (page+length, " module:%s", module_name(serial->type->driver.owner));
-               length += sprintf (page+length, " name:\"%s\"", serial->type->description);
-               length += sprintf (page+length, " vendor:%04x product:%04x", 
-                                  le16_to_cpu(serial->dev->descriptor.idVendor), 
-                                  le16_to_cpu(serial->dev->descriptor.idProduct));
-               length += sprintf (page+length, " num_ports:%d", serial->num_ports);
-               length += sprintf (page+length, " port:%d", i - serial->minor + 1);
-
+                       length += sprintf(page+length, " module:%s",
+                               module_name(serial->type->driver.owner));
+               length += sprintf(page+length, " name:\"%s\"",
+                               serial->type->description);
+               length += sprintf(page+length, " vendor:%04x product:%04x",
+                       le16_to_cpu(serial->dev->descriptor.idVendor),
+                       le16_to_cpu(serial->dev->descriptor.idProduct));
+               length += sprintf(page+length, " num_ports:%d",
+                                                       serial->num_ports);
+               length += sprintf(page+length, " port:%d",
+                                                       i - serial->minor + 1);
                usb_make_path(serial->dev, tmp, sizeof(tmp));
-               length += sprintf (page+length, " path:%s", tmp);
-                       
-               length += sprintf (page+length, "\n");
+               length += sprintf(page+length, " path:%s", tmp);
+
+               length += sprintf(page+length, "\n");
                if ((length + begin) > (off + count)) {
                        usb_serial_put(serial);
                        goto done;
@@ -445,31 +460,31 @@ done:
        if (off >= (length + begin))
                return 0;
        *start = page + (off-begin);
-       return ((count < begin+length-off) ? count : begin+length-off);
+       return (count < begin+length-off) ? count : begin+length-off;
 }
 
-static int serial_tiocmget (struct tty_struct *tty, struct file *file)
+static int serial_tiocmget(struct tty_struct *tty, struct file *file)
 {
        struct usb_serial_port *port = tty->driver_data;
 
        dbg("%s - port %d", __func__, port->number);
 
-       WARN_ON(!port->open_count);
+       WARN_ON(!port->port.count);
        if (port->serial->type->tiocmget)
-               return port->serial->type->tiocmget(port, file);
+               return port->serial->type->tiocmget(tty, file);
        return -EINVAL;
 }
 
-static int serial_tiocmset (struct tty_struct *tty, struct file *file,
+static int serial_tiocmset(struct tty_struct *tty, struct file *file,
                            unsigned int set, unsigned int clear)
 {
        struct usb_serial_port *port = tty->driver_data;
 
        dbg("%s - port %d", __func__, port->number);
 
-       WARN_ON(!port->open_count);
+       WARN_ON(!port->port.count);
        if (port->serial->type->tiocmset)
-               return port->serial->type->tiocmset(port, file, set, clear);
+               return port->serial->type->tiocmset(tty, file, set, clear);
        return -EINVAL;
 }
 
@@ -482,6 +497,7 @@ void usb_serial_port_softint(struct usb_serial_port *port)
 {
        schedule_work(&port->work);
 }
+EXPORT_SYMBOL_GPL(usb_serial_port_softint);
 
 static void usb_serial_port_work(struct work_struct *work)
 {
@@ -490,11 +506,11 @@ static void usb_serial_port_work(struct work_struct *work)
        struct tty_struct *tty;
 
        dbg("%s - port %d", __func__, port->number);
-       
+
        if (!port)
                return;
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (!tty)
                return;
 
@@ -505,7 +521,7 @@ static void port_release(struct device *dev)
 {
        struct usb_serial_port *port = to_usb_serial_port(dev);
 
-       dbg ("%s - %s", __func__, dev->bus_id);
+       dbg ("%s - %s", __func__, dev_name(dev));
        port_free(port);
 }
 
@@ -543,9 +559,9 @@ static void port_free(struct usb_serial_port *port)
        kfree(port);
 }
 
-static struct usb_serial * create_serial (struct usb_device *dev, 
-                                         struct usb_interface *interface,
-                                         struct usb_serial_driver *driver)
+static struct usb_serial *create_serial(struct usb_device *dev,
+                                       struct usb_interface *interface,
+                                       struct usb_serial_driver *driver)
 {
        struct usb_serial *serial;
 
@@ -564,7 +580,7 @@ static struct usb_serial * create_serial (struct usb_device *dev,
 }
 
 static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf,
-                                                   struct usb_serial_driver *drv)
+                                           struct usb_serial_driver *drv)
 {
        struct usb_dynid *dynid;
 
@@ -596,7 +612,8 @@ exit:
        return id;
 }
 
-static struct usb_serial_driver *search_serial_device(struct usb_interface *iface)
+static struct usb_serial_driver *search_serial_device(
+                                       struct usb_interface *iface)
 {
        const struct usb_device_id *id;
        struct usb_serial_driver *drv;
@@ -614,7 +631,7 @@ static struct usb_serial_driver *search_serial_device(struct usb_interface *ifac
 int usb_serial_probe(struct usb_interface *interface,
                               const struct usb_device_id *id)
 {
-       struct usb_device *dev = interface_to_usbdev (interface);
+       struct usb_device *dev = interface_to_usbdev(interface);
        struct usb_serial *serial = NULL;
        struct usb_serial_port *port;
        struct usb_host_interface *iface_desc;
@@ -625,7 +642,7 @@ int usb_serial_probe(struct usb_interface *interface,
        struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];
        struct usb_serial_driver *type = NULL;
        int retval;
-       int minor;
+       unsigned int minor;
        int buffer_size;
        int i;
        int num_interrupt_in = 0;
@@ -643,7 +660,7 @@ int usb_serial_probe(struct usb_interface *interface,
                return -ENODEV;
        }
 
-       serial = create_serial (dev, interface, type);
+       serial = create_serial(dev, interface, type);
        if (!serial) {
                unlock_kernel();
                dev_err(&interface->dev, "%s - out of memory\n", __func__);
@@ -656,8 +673,9 @@ int usb_serial_probe(struct usb_interface *interface,
 
                if (!try_module_get(type->driver.owner)) {
                        unlock_kernel();
-                       dev_err(&interface->dev, "module get failed, exiting\n");
-                       kfree (serial);
+                       dev_err(&interface->dev,
+                               "module get failed, exiting\n");
+                       kfree(serial);
                        return -EIO;
                }
 
@@ -667,8 +685,8 @@ int usb_serial_probe(struct usb_interface *interface,
 
                if (retval) {
                        unlock_kernel();
-                       dbg ("sub driver rejected device");
-                       kfree (serial);
+                       dbg("sub driver rejected device");
+                       kfree(serial);
                        return retval;
                }
        }
@@ -709,7 +727,7 @@ int usb_serial_probe(struct usb_interface *interface,
        }
 
 #if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
-       /* BEGIN HORRIBLE HACK FOR PL2303 */ 
+       /* BEGIN HORRIBLE HACK FOR PL2303 */
        /* this is needed due to the looney way its endpoints are set up */
        if (((le16_to_cpu(dev->descriptor.idVendor) == PL2303_VENDOR_ID) &&
             (le16_to_cpu(dev->descriptor.idProduct) == PL2303_PRODUCT_ID)) ||
@@ -738,7 +756,7 @@ int usb_serial_probe(struct usb_interface *interface,
                if (num_bulk_in == 0 || num_bulk_out == 0) {
                        unlock_kernel();
                        dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n");
-                       kfree (serial);
+                       kfree(serial);
                        return -ENODEV;
                }
        }
@@ -750,8 +768,9 @@ int usb_serial_probe(struct usb_interface *interface,
                num_ports = num_bulk_out;
                if (num_ports == 0) {
                        unlock_kernel();
-                       dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n");
-                       kfree (serial);
+                       dev_err(&interface->dev,
+                           "Generic device with no bulk out, not allowed.\n");
+                       kfree(serial);
                        return -EIO;
                }
        }
@@ -761,11 +780,12 @@ int usb_serial_probe(struct usb_interface *interface,
                if (type->calc_num_ports) {
                        if (!try_module_get(type->driver.owner)) {
                                unlock_kernel();
-                               dev_err(&interface->dev, "module get failed, exiting\n");
-                               kfree (serial);
+                               dev_err(&interface->dev,
+                                       "module get failed, exiting\n");
+                               kfree(serial);
                                return -EIO;
                        }
-                       num_ports = type->calc_num_ports (serial);
+                       num_ports = type->calc_num_ports(serial);
                        module_put(type->driver.owner);
                }
                if (!num_ports)
@@ -783,7 +803,8 @@ int usb_serial_probe(struct usb_interface *interface,
                        type->description);
 
        /* create our ports, we need as many as the max endpoints */
-       /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */
+       /* we don't use num_ports here because some devices have more
+          endpoint pairs than ports */
        max_endpoints = max(num_bulk_in, num_bulk_out);
        max_endpoints = max(max_endpoints, num_interrupt_in);
        max_endpoints = max(max_endpoints, num_interrupt_out);
@@ -791,7 +812,8 @@ int usb_serial_probe(struct usb_interface *interface,
        serial->num_port_pointers = max_endpoints;
        unlock_kernel();
 
-       dbg("%s - setting up %d port structures for this device", __func__, max_endpoints);
+       dbg("%s - setting up %d port structures for this device",
+                                               __func__, max_endpoints);
        for (i = 0; i < max_endpoints; ++i) {
                port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
                if (!port)
@@ -807,7 +829,7 @@ int usb_serial_probe(struct usb_interface *interface,
        for (i = 0; i < num_bulk_in; ++i) {
                endpoint = bulk_in_endpoint[i];
                port = serial->port[i];
-               port->read_urb = usb_alloc_urb (0, GFP_KERNEL);
+               port->read_urb = usb_alloc_urb(0, GFP_KERNEL);
                if (!port->read_urb) {
                        dev_err(&interface->dev, "No free urbs available\n");
                        goto probe_error;
@@ -815,17 +837,17 @@ int usb_serial_probe(struct usb_interface *interface,
                buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
                port->bulk_in_size = buffer_size;
                port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
-               port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
+               port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
                if (!port->bulk_in_buffer) {
-                       dev_err(&interface->dev, "Couldn't allocate bulk_in_buffer\n");
+                       dev_err(&interface->dev,
+                                       "Couldn't allocate bulk_in_buffer\n");
                        goto probe_error;
                }
-               usb_fill_bulk_urb (port->read_urb, dev,
-                                  usb_rcvbulkpipe (dev,
-                                                   endpoint->bEndpointAddress),
-                                  port->bulk_in_buffer, buffer_size,
-                                  serial->type->read_bulk_callback,
-                                  port);
+               usb_fill_bulk_urb(port->read_urb, dev,
+                               usb_rcvbulkpipe(dev,
+                                               endpoint->bEndpointAddress),
+                               port->bulk_in_buffer, buffer_size,
+                               serial->type->read_bulk_callback, port);
        }
 
        for (i = 0; i < num_bulk_out; ++i) {
@@ -839,17 +861,17 @@ int usb_serial_probe(struct usb_interface *interface,
                buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
                port->bulk_out_size = buffer_size;
                port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
-               port->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
+               port->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
                if (!port->bulk_out_buffer) {
-                       dev_err(&interface->dev, "Couldn't allocate bulk_out_buffer\n");
+                       dev_err(&interface->dev,
+                                       "Couldn't allocate bulk_out_buffer\n");
                        goto probe_error;
                }
-               usb_fill_bulk_urb (port->write_urb, dev,
-                                  usb_sndbulkpipe (dev,
-                                                   endpoint->bEndpointAddress),
-                                  port->bulk_out_buffer, buffer_size, 
-                                  serial->type->write_bulk_callback,
-                                  port);
+               usb_fill_bulk_urb(port->write_urb, dev,
+                               usb_sndbulkpipe(dev,
+                                       endpoint->bEndpointAddress),
+                               port->bulk_out_buffer, buffer_size,
+                               serial->type->write_bulk_callback, port);
        }
 
        if (serial->type->read_int_callback) {
@@ -858,73 +880,82 @@ int usb_serial_probe(struct usb_interface *interface,
                        port = serial->port[i];
                        port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
                        if (!port->interrupt_in_urb) {
-                               dev_err(&interface->dev, "No free urbs available\n");
+                               dev_err(&interface->dev,
+                                               "No free urbs available\n");
                                goto probe_error;
                        }
                        buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
-                       port->interrupt_in_endpointAddress = endpoint->bEndpointAddress;
-                       port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
+                       port->interrupt_in_endpointAddress =
+                                               endpoint->bEndpointAddress;
+                       port->interrupt_in_buffer = kmalloc(buffer_size,
+                                                               GFP_KERNEL);
                        if (!port->interrupt_in_buffer) {
-                               dev_err(&interface->dev, "Couldn't allocate interrupt_in_buffer\n");
+                               dev_err(&interface->dev,
+                                   "Couldn't allocate interrupt_in_buffer\n");
                                goto probe_error;
                        }
-                       usb_fill_int_urb (port->interrupt_in_urb, dev, 
-                                         usb_rcvintpipe (dev,
-                                                         endpoint->bEndpointAddress),
-                                         port->interrupt_in_buffer, buffer_size, 
-                                         serial->type->read_int_callback, port, 
-                                         endpoint->bInterval);
+                       usb_fill_int_urb(port->interrupt_in_urb, dev,
+                               usb_rcvintpipe(dev,
+                                               endpoint->bEndpointAddress),
+                               port->interrupt_in_buffer, buffer_size,
+                               serial->type->read_int_callback, port,
+                               endpoint->bInterval);
                }
        } else if (num_interrupt_in) {
                dbg("the device claims to support interrupt in transfers, but read_int_callback is not defined");
        }
-       
+
        if (serial->type->write_int_callback) {
                for (i = 0; i < num_interrupt_out; ++i) {
                        endpoint = interrupt_out_endpoint[i];
                        port = serial->port[i];
                        port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
                        if (!port->interrupt_out_urb) {
-                               dev_err(&interface->dev, "No free urbs available\n");
+                               dev_err(&interface->dev,
+                                               "No free urbs available\n");
                                goto probe_error;
                        }
                        buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
                        port->interrupt_out_size = buffer_size;
-                       port->interrupt_out_endpointAddress = endpoint->bEndpointAddress;
-                       port->interrupt_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
+                       port->interrupt_out_endpointAddress =
+                                               endpoint->bEndpointAddress;
+                       port->interrupt_out_buffer = kmalloc(buffer_size,
+                                                               GFP_KERNEL);
                        if (!port->interrupt_out_buffer) {
-                               dev_err(&interface->dev, "Couldn't allocate interrupt_out_buffer\n");
+                               dev_err(&interface->dev,
+                                 "Couldn't allocate interrupt_out_buffer\n");
                                goto probe_error;
                        }
-                       usb_fill_int_urb (port->interrupt_out_urb, dev,
-                                         usb_sndintpipe (dev,
-                                                         endpoint->bEndpointAddress),
-                                         port->interrupt_out_buffer, buffer_size,
-                                         serial->type->write_int_callback, port,
-                                         endpoint->bInterval);
+                       usb_fill_int_urb(port->interrupt_out_urb, dev,
+                               usb_sndintpipe(dev,
+                                                 endpoint->bEndpointAddress),
+                               port->interrupt_out_buffer, buffer_size,
+                               serial->type->write_int_callback, port,
+                               endpoint->bInterval);
                }
        } else if (num_interrupt_out) {
                dbg("the device claims to support interrupt out transfers, but write_int_callback is not defined");
        }
-       
+
        /* if this device type has an attach function, call it */
        if (type->attach) {
                if (!try_module_get(type->driver.owner)) {
-                       dev_err(&interface->dev, "module get failed, exiting\n");
+                       dev_err(&interface->dev,
+                                       "module get failed, exiting\n");
                        goto probe_error;
                }
-               retval = type->attach (serial);
+               retval = type->attach(serial);
                module_put(type->driver.owner);
                if (retval < 0)
                        goto probe_error;
                if (retval > 0) {
-                       /* quietly accept this device, but don't bind to a serial port
-                        * as it's about to disappear */
+                       /* quietly accept this device, but don't bind to a
+                          serial port as it's about to disappear */
                        goto exit;
                }
        }
 
-       if (get_free_serial (serial, num_ports, &minor) == NULL) {
+       if (get_free_serial(serial, num_ports, &minor) == NULL) {
                dev_err(&interface->dev, "No more free serial devices\n");
                goto probe_error;
        }
@@ -938,19 +969,19 @@ int usb_serial_probe(struct usb_interface *interface,
                port->dev.bus = &usb_serial_bus_type;
                port->dev.release = &port_release;
 
-               snprintf (&port->dev.bus_id[0], sizeof(port->dev.bus_id), "ttyUSB%d", port->number);
-               dbg ("%s - registering %s", __func__, port->dev.bus_id);
+               dev_set_name(&port->dev, "ttyUSB%d", port->number);
+               dbg ("%s - registering %s", __func__, dev_name(&port->dev));
                retval = device_register(&port->dev);
                if (retval)
                        dev_err(&port->dev, "Error registering port device, "
                                "continuing\n");
        }
 
-       usb_serial_console_init (debug, minor);
+       usb_serial_console_init(debug, minor);
 
 exit:
        /* success */
-       usb_set_intfdata (interface, serial);
+       usb_set_intfdata(interface, serial);
        return 0;
 
 probe_error:
@@ -986,29 +1017,30 @@ probe_error:
        /* free up any memory that we allocated */
        for (i = 0; i < serial->num_port_pointers; ++i)
                kfree(serial->port[i]);
-       kfree (serial);
+       kfree(serial);
        return -EIO;
 }
+EXPORT_SYMBOL_GPL(usb_serial_probe);
 
 void usb_serial_disconnect(struct usb_interface *interface)
 {
        int i;
-       struct usb_serial *serial = usb_get_intfdata (interface);
+       struct usb_serial *serial = usb_get_intfdata(interface);
        struct device *dev = &interface->dev;
        struct usb_serial_port *port;
 
        usb_serial_console_disconnect(serial);
-       dbg ("%s", __func__);
+       dbg("%s", __func__);
 
        mutex_lock(&serial->disc_mutex);
-       usb_set_intfdata (interface, NULL);
+       usb_set_intfdata(interface, NULL);
        /* must set a flag, to signal subdrivers */
        serial->disconnected = 1;
        for (i = 0; i < serial->num_ports; ++i) {
                port = serial->port[i];
                if (port) {
-                       if (port->tty)
-                               tty_hangup(port->tty);
+                       if (port->port.tty)
+                               tty_hangup(port->port.tty);
                        kill_traffic(port);
                }
        }
@@ -1018,6 +1050,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
        usb_serial_put(serial);
        dev_info(dev, "device disconnected\n");
 }
+EXPORT_SYMBOL_GPL(usb_serial_disconnect);
 
 int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
 {
@@ -1076,9 +1109,8 @@ static int __init usb_serial_init(void)
                return -ENOMEM;
 
        /* Initialize our global data */
-       for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
+       for (i = 0; i < SERIAL_TTY_MINORS; ++i)
                serial_table[i] = NULL;
-       }
 
        result = bus_register(&usb_serial_bus_type);
        if (result) {
@@ -1093,9 +1125,11 @@ static int __init usb_serial_init(void)
        usb_serial_tty_driver->minor_start = 0;
        usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
        usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL;
-       usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+       usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW |
+                                               TTY_DRIVER_DYNAMIC_DEV;
        usb_serial_tty_driver->init_termios = tty_std_termios;
-       usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+       usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD
+                                                       | HUPCL | CLOCAL;
        usb_serial_tty_driver->init_termios.c_ispeed = 9600;
        usb_serial_tty_driver->init_termios.c_ospeed = 9600;
        tty_set_operations(usb_serial_tty_driver, &serial_ops);
@@ -1133,7 +1167,7 @@ exit_reg_driver:
        bus_unregister(&usb_serial_bus_type);
 
 exit_bus:
-       err ("%s - returning with error %d", __func__, result);
+       err("%s - returning with error %d", __func__, result);
        put_tty_driver(usb_serial_tty_driver);
        return result;
 }
@@ -1160,7 +1194,7 @@ module_exit(usb_serial_exit);
                if (!type->function) {                                  \
                        type->function = usb_serial_generic_##function; \
                        dbg("Had to override the " #function            \
-                                " usb serial operation with the generic one.");\
+                               " usb serial operation with the generic one.");\
                        }                                               \
        } while (0)
 
@@ -1177,8 +1211,9 @@ static void fixup_generic(struct usb_serial_driver *device)
        set_to_generic_if_null(device, resume);
 }
 
-int usb_serial_register(struct usb_serial_driver *driver) /* must be called with BKL held */
+int usb_serial_register(struct usb_serial_driver *driver)
 {
+       /* must be called with BKL held */
        int retval;
 
        fixup_generic(driver);
@@ -1191,37 +1226,30 @@ int usb_serial_register(struct usb_serial_driver *driver) /* must be called with
 
        retval = usb_serial_bus_register(driver);
        if (retval) {
-               err("problem %d when registering driver %s", retval, driver->description);
+               err("problem %d when registering driver %s",
+                                               retval, driver->description);
                list_del(&driver->driver_list);
-       }
-       else
-               info("USB Serial support registered for %s", driver->description);
+       } else
+               info("USB Serial support registered for %s",
+                                               driver->description);
 
        return retval;
 }
+EXPORT_SYMBOL_GPL(usb_serial_register);
 
 
-void usb_serial_deregister(struct usb_serial_driver *device) /* must be called with BKL held */
+void usb_serial_deregister(struct usb_serial_driver *device)
 {
+       /* must be called with BKL held */
        info("USB Serial deregistering driver %s", device->description);
        list_del(&device->driver_list);
        usb_serial_bus_deregister(device);
 }
-
-
-
-/* If the usb-serial core is built into the core, the usb-serial drivers
-   need these symbols to load properly as modules. */
-EXPORT_SYMBOL_GPL(usb_serial_register);
 EXPORT_SYMBOL_GPL(usb_serial_deregister);
-EXPORT_SYMBOL_GPL(usb_serial_probe);
-EXPORT_SYMBOL_GPL(usb_serial_disconnect);
-EXPORT_SYMBOL_GPL(usb_serial_port_softint);
-
 
 /* Module information */
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
index f9fc926b56d87896577280da6c7d8b39d6b10cc6..fc5d9952b03b0aceb901d2f4fb0f95eb62d54bbd 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
+#define USB_DEBUG_MAX_PACKET_SIZE      8
+
 static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x0525, 0x127a) },
        { },
@@ -29,6 +31,13 @@ static struct usb_driver debug_driver = {
        .no_dynamic_id =        1,
 };
 
+int usb_debug_open(struct tty_struct *tty, struct usb_serial_port *port,
+                                                       struct file *filp)
+{
+       port->bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE;
+       return usb_serial_generic_open(tty, port, filp);
+}
+
 static struct usb_serial_driver debug_device = {
        .driver = {
                .owner =        THIS_MODULE,
@@ -36,6 +45,7 @@ static struct usb_serial_driver debug_device = {
        },
        .id_table =             id_table,
        .num_ports =            1,
+       .open =                 usb_debug_open,
 };
 
 static int __init debug_init(void)
index 5fc20122145f3a31dbd4038377e27680fc0a2f93..cf8924f9a2cc1d461436caaefcbcfeb81b0f0168 100644 (file)
@@ -9,7 +9,8 @@
  *     modify it under the terms of the GNU General Public License version
  *     2 as published by the Free Software Foundation.
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
  *
  */
 
@@ -23,7 +24,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/spinlock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 #include "visor.h"
 #define DRIVER_DESC "USB HandSpring Visor / Palm OS driver"
 
 /* function prototypes for a handspring visor */
-static int  visor_open         (struct usb_serial_port *port, struct file *filp);
-static void visor_close                (struct usb_serial_port *port, struct file *filp);
-static int  visor_write                (struct usb_serial_port *port, const unsigned char *buf, int count);
-static int  visor_write_room           (struct usb_serial_port *port);
-static int  visor_chars_in_buffer      (struct usb_serial_port *port);
-static void visor_throttle     (struct usb_serial_port *port);
-static void visor_unthrottle   (struct usb_serial_port *port);
-static int  visor_probe                (struct usb_serial *serial, const struct usb_device_id *id);
+static int  visor_open(struct tty_struct *tty, struct usb_serial_port *port,
+                                       struct file *filp);
+static void visor_close(struct tty_struct *tty, struct usb_serial_port *port,
+                                       struct file *filp);
+static int  visor_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                       const unsigned char *buf, int count);
+static int  visor_write_room(struct tty_struct *tty);
+static void visor_throttle(struct tty_struct *tty);
+static void visor_unthrottle(struct tty_struct *tty);
+static int  visor_probe(struct usb_serial *serial,
+                                       const struct usb_device_id *id);
 static int  visor_calc_num_ports(struct usb_serial *serial);
-static void visor_shutdown     (struct usb_serial *serial);
-static int  visor_ioctl                (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void visor_write_bulk_callback  (struct urb *urb);
-static void visor_read_bulk_callback   (struct urb *urb);
-static void visor_read_int_callback    (struct urb *urb);
-static int  clie_3_5_startup   (struct usb_serial *serial);
-static int  treo_attach                (struct usb_serial *serial);
-static int clie_5_attach (struct usb_serial *serial);
-static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_id *id);
-static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_id *id);
+static void visor_shutdown(struct usb_serial *serial);
+static void visor_write_bulk_callback(struct urb *urb);
+static void visor_read_bulk_callback(struct urb *urb);
+static void visor_read_int_callback(struct urb *urb);
+static int  clie_3_5_startup(struct usb_serial *serial);
+static int  treo_attach(struct usb_serial *serial);
+static int clie_5_attach(struct usb_serial *serial);
+static int palm_os_3_probe(struct usb_serial *serial,
+                                       const struct usb_device_id *id);
+static int palm_os_4_probe(struct usb_serial *serial,
+                                       const struct usb_device_id *id);
 
 /* Parameters that may be passed into the module. */
 static int debug;
@@ -105,13 +110,13 @@ static struct usb_device_id id_table [] = {
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
-       { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), 
+       { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
-       { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), 
+       { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
-       { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID), 
+       { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
@@ -170,7 +175,7 @@ static struct usb_device_id id_table_combined [] = {
        { }                                     /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
 
 static struct usb_driver visor_driver = {
        .name =         "visor",
@@ -180,7 +185,8 @@ static struct usb_driver visor_driver = {
        .no_dynamic_id =        1,
 };
 
-/* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */
+/* All of the device info needed for the Handspring Visor,
+   and Palm 4.0 devices */
 static struct usb_serial_driver handspring_device = {
        .driver = {
                .owner =        THIS_MODULE,
@@ -198,10 +204,8 @@ static struct usb_serial_driver handspring_device = {
        .probe =                visor_probe,
        .calc_num_ports =       visor_calc_num_ports,
        .shutdown =             visor_shutdown,
-       .ioctl =                visor_ioctl,
        .write =                visor_write,
        .write_room =           visor_write_room,
-       .chars_in_buffer =      visor_chars_in_buffer,
        .write_bulk_callback =  visor_write_bulk_callback,
        .read_bulk_callback =   visor_read_bulk_callback,
        .read_int_callback =    visor_read_int_callback,
@@ -225,10 +229,8 @@ static struct usb_serial_driver clie_5_device = {
        .probe =                visor_probe,
        .calc_num_ports =       visor_calc_num_ports,
        .shutdown =             visor_shutdown,
-       .ioctl =                visor_ioctl,
        .write =                visor_write,
        .write_room =           visor_write_room,
-       .chars_in_buffer =      visor_chars_in_buffer,
        .write_bulk_callback =  visor_write_bulk_callback,
        .read_bulk_callback =   visor_read_bulk_callback,
        .read_int_callback =    visor_read_int_callback,
@@ -249,10 +251,8 @@ static struct usb_serial_driver clie_3_5_device = {
        .throttle =             visor_throttle,
        .unthrottle =           visor_unthrottle,
        .attach =               clie_3_5_startup,
-       .ioctl =                visor_ioctl,
        .write =                visor_write,
        .write_room =           visor_write_room,
-       .chars_in_buffer =      visor_chars_in_buffer,
        .write_bulk_callback =  visor_write_bulk_callback,
        .read_bulk_callback =   visor_read_bulk_callback,
 };
@@ -274,7 +274,8 @@ static int stats;
 /******************************************************************************
  * Handspring Visor specific driver functions
  ******************************************************************************/
-static int visor_open (struct usb_serial_port *port, struct file *filp)
+static int visor_open(struct tty_struct *tty, struct usb_serial_port *port,
+                                                       struct file *filp)
 {
        struct usb_serial *serial = port->serial;
        struct visor_private *priv = usb_get_serial_port_data(port);
@@ -300,42 +301,45 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
         * through, otherwise it is scheduled, and with high data rates (like
         * with OHCI) data can get lost.
         */
-       if (port->tty)
-               port->tty->low_latency = 1;
+       if (tty)
+               tty->low_latency = 1;
 
        /* Start reading from the device */
-       usb_fill_bulk_urb (port->read_urb, serial->dev,
-                          usb_rcvbulkpipe (serial->dev, 
+       usb_fill_bulk_urb(port->read_urb, serial->dev,
+                          usb_rcvbulkpipe(serial->dev,
                                            port->bulk_in_endpointAddress),
                           port->read_urb->transfer_buffer,
                           port->read_urb->transfer_buffer_length,
                           visor_read_bulk_callback, port);
        result = usb_submit_urb(port->read_urb, GFP_KERNEL);
        if (result) {
-               dev_err(&port->dev, "%s - failed submitting read urb, error %d\n",
-                       __func__, result);
+               dev_err(&port->dev,
+                       "%s - failed submitting read urb, error %d\n",
+                                                       __func__, result);
                goto exit;
        }
-       
+
        if (port->interrupt_in_urb) {
                dbg("%s - adding interrupt input for treo", __func__);
                result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
                if (result)
-                       dev_err(&port->dev, "%s - failed submitting interrupt urb, error %d\n",
-                               __func__, result);
+                       dev_err(&port->dev,
+                           "%s - failed submitting interrupt urb, error %d\n",
+                                                       __func__, result);
        }
-exit:  
+exit:
        return result;
 }
 
 
-static void visor_close (struct usb_serial_port *port, struct file * filp)
+static void visor_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct visor_private *priv = usb_get_serial_port_data(port);
        unsigned char *transfer_buffer;
 
        dbg("%s - port %d", __func__, port->number);
-                        
+
        /* shutdown our urbs */
        usb_kill_urb(port->read_urb);
        usb_kill_urb(port->interrupt_in_urb);
@@ -343,14 +347,14 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
        mutex_lock(&port->serial->disc_mutex);
        if (!port->serial->disconnected) {
                /* Try to send shutdown message, unless the device is gone */
-               transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
+               transfer_buffer =  kmalloc(0x12, GFP_KERNEL);
                if (transfer_buffer) {
-                       usb_control_msg (port->serial->dev,
+                       usb_control_msg(port->serial->dev,
                                         usb_rcvctrlpipe(port->serial->dev, 0),
                                         VISOR_CLOSE_NOTIFICATION, 0xc2,
                                         0x0000, 0x0000,
                                         transfer_buffer, 0x12, 300);
-                       kfree (transfer_buffer);
+                       kfree(transfer_buffer);
                }
        }
        mutex_unlock(&port->serial->disc_mutex);
@@ -361,7 +365,8 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
 }
 
 
-static int visor_write (struct usb_serial_port *port, const unsigned char *buf, int count)
+static int visor_write(struct tty_struct *tty, struct usb_serial_port *port,
+                                       const unsigned char *buf, int count)
 {
        struct visor_private *priv = usb_get_serial_port_data(port);
        struct usb_serial *serial = port->serial;
@@ -381,7 +386,7 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
        priv->outstanding_urbs++;
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       buffer = kmalloc (count, GFP_ATOMIC);
+       buffer = kmalloc(count, GFP_ATOMIC);
        if (!buffer) {
                dev_err(&port->dev, "out of memory\n");
                count = -ENOMEM;
@@ -395,21 +400,22 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
                goto error_no_urb;
        }
 
-       memcpy (buffer, buf, count);
+       memcpy(buffer, buf, count);
 
        usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);
 
-       usb_fill_bulk_urb (urb, serial->dev,
-                          usb_sndbulkpipe (serial->dev,
+       usb_fill_bulk_urb(urb, serial->dev,
+                          usb_sndbulkpipe(serial->dev,
                                            port->bulk_out_endpointAddress),
-                          buffer, count, 
+                          buffer, count,
                           visor_write_bulk_callback, port);
 
        /* send it down the pipe */
        status = usb_submit_urb(urb, GFP_ATOMIC);
        if (status) {
-               dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n",
-                       __func__, status);
+               dev_err(&port->dev,
+                  "%s - usb_submit_urb(write bulk) failed with status = %d\n",
+                                                       __func__, status);
                count = status;
                goto error;
        } else {
@@ -435,8 +441,9 @@ error_no_buffer:
 }
 
 
-static int visor_write_room (struct usb_serial_port *port)
+static int visor_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct visor_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
 
@@ -460,23 +467,7 @@ static int visor_write_room (struct usb_serial_port *port)
 }
 
 
-static int visor_chars_in_buffer (struct usb_serial_port *port)
-{
-       dbg("%s - port %d", __func__, port->number);
-
-       /* 
-        * We can't really account for how much data we
-        * have sent out, but hasn't made it through to the
-        * device, so just tell the tty layer that everything
-        * is flushed.
-        *
-        * FIXME: Should walk outstanding_urbs
-        */
-       return 0;
-}
-
-
-static void visor_write_bulk_callback (struct urb *urb)
+static void visor_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct visor_private *priv = usb_get_serial_port_data(port);
@@ -484,7 +475,7 @@ static void visor_write_bulk_callback (struct urb *urb)
        unsigned long flags;
 
        /* free up the transfer buffer, as usb_free_urb() does not do this */
-       kfree (urb->transfer_buffer);
+       kfree(urb->transfer_buffer);
 
        dbg("%s - port %d", __func__, port->number);
 
@@ -500,7 +491,7 @@ static void visor_write_bulk_callback (struct urb *urb)
 }
 
 
-static void visor_read_bulk_callback (struct urb *urb)
+static void visor_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct visor_private *priv = usb_get_serial_port_data(port);
@@ -518,11 +509,13 @@ static void visor_read_bulk_callback (struct urb *urb)
                return;
        }
 
-       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+       usb_serial_debug_data(debug, &port->dev, __func__,
+                                               urb->actual_length, data);
 
-       tty = port->tty;
+       tty = port->port.tty;
        if (tty && urb->actual_length) {
-               available_room = tty_buffer_request_room(tty, urb->actual_length);
+               available_room = tty_buffer_request_room(tty,
+                                                       urb->actual_length);
                if (available_room) {
                        tty_insert_flip_string(tty, data, available_room);
                        tty_flip_buffer_push(tty);
@@ -536,22 +529,23 @@ static void visor_read_bulk_callback (struct urb *urb)
 
        /* Continue trying to always read if we should */
        if (!priv->throttled) {
-               usb_fill_bulk_urb (port->read_urb, port->serial->dev,
+               usb_fill_bulk_urb(port->read_urb, port->serial->dev,
                                   usb_rcvbulkpipe(port->serial->dev,
-                                                  port->bulk_in_endpointAddress),
+                                          port->bulk_in_endpointAddress),
                                   port->read_urb->transfer_buffer,
                                   port->read_urb->transfer_buffer_length,
                                   visor_read_bulk_callback, port);
                result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
                if (result)
-                       dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result);
-       } else {
+                       dev_err(&port->dev,
+                           "%s - failed resubmitting read urb, error %d\n",
+                                                       __func__, result);
+       } else
                priv->actually_throttled = 1;
-       }
        spin_unlock(&priv->lock);
 }
 
-static void visor_read_int_callback (struct urb *urb)
+static void visor_read_int_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        int status = urb->status;
@@ -585,14 +579,16 @@ static void visor_read_int_callback (struct urb *urb)
                              urb->actual_length, urb->transfer_buffer);
 
 exit:
-       result = usb_submit_urb (urb, GFP_ATOMIC);
+       result = usb_submit_urb(urb, GFP_ATOMIC);
        if (result)
-               dev_err(&urb->dev->dev, "%s - Error %d submitting interrupt urb\n",
-                       __func__, result);
+               dev_err(&urb->dev->dev,
+                               "%s - Error %d submitting interrupt urb\n",
+                                                       __func__, result);
 }
 
-static void visor_throttle (struct usb_serial_port *port)
+static void visor_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct visor_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
 
@@ -603,8 +599,9 @@ static void visor_throttle (struct usb_serial_port *port)
 }
 
 
-static void visor_unthrottle (struct usb_serial_port *port)
+static void visor_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct visor_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
        int result;
@@ -618,10 +615,13 @@ static void visor_unthrottle (struct usb_serial_port *port)
        port->read_urb->dev = port->serial->dev;
        result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
        if (result)
-               dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __func__, result);
+               dev_err(&port->dev,
+                       "%s - failed submitting read urb, error %d\n",
+                                                       __func__, result);
 }
 
-static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_id *id)
+static int palm_os_3_probe(struct usb_serial *serial,
+                                               const struct usb_device_id *id)
 {
        struct device *dev = &serial->dev->dev;
        struct visor_connection_info *connection_info;
@@ -633,7 +633,7 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i
 
        dbg("%s", __func__);
 
-       transfer_buffer = kmalloc (sizeof (*connection_info), GFP_KERNEL);
+       transfer_buffer = kmalloc(sizeof(*connection_info), GFP_KERNEL);
        if (!transfer_buffer) {
                dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __func__,
                        sizeof(*connection_info));
@@ -641,7 +641,7 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i
        }
 
        /* send a get connection info request */
-       retval = usb_control_msg (serial->dev,
+       retval = usb_control_msg(serial->dev,
                                  usb_rcvctrlpipe(serial->dev, 0),
                                  VISOR_GET_CONNECTION_INFORMATION,
                                  0xc2, 0x0000, 0x0000, transfer_buffer,
@@ -653,29 +653,31 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i
        }
 
        if (retval == sizeof(*connection_info)) {
-               connection_info = (struct visor_connection_info *)transfer_buffer;
+                       connection_info = (struct visor_connection_info *)
+                                                       transfer_buffer;
 
                num_ports = le16_to_cpu(connection_info->num_ports);
                for (i = 0; i < num_ports; ++i) {
-                       switch (connection_info->connections[i].port_function_id) {
-                               case VISOR_FUNCTION_GENERIC:
-                                       string = "Generic";
-                                       break;
-                               case VISOR_FUNCTION_DEBUGGER:
-                                       string = "Debugger";
-                                       break;
-                               case VISOR_FUNCTION_HOTSYNC:
-                                       string = "HotSync";
-                                       break;
-                               case VISOR_FUNCTION_CONSOLE:
-                                       string = "Console";
-                                       break;
-                               case VISOR_FUNCTION_REMOTE_FILE_SYS:
-                                       string = "Remote File System";
-                                       break;
-                               default:
-                                       string = "unknown";
-                                       break;
+                       switch (
+                          connection_info->connections[i].port_function_id) {
+                       case VISOR_FUNCTION_GENERIC:
+                               string = "Generic";
+                               break;
+                       case VISOR_FUNCTION_DEBUGGER:
+                               string = "Debugger";
+                               break;
+                       case VISOR_FUNCTION_HOTSYNC:
+                               string = "HotSync";
+                               break;
+                       case VISOR_FUNCTION_CONSOLE:
+                               string = "Console";
+                               break;
+                       case VISOR_FUNCTION_REMOTE_FILE_SYS:
+                               string = "Remote File System";
+                               break;
+                       default:
+                               string = "unknown";
+                               break;
                        }
                        dev_info(dev, "%s: port %d, is for %s use\n",
                                serial->type->description,
@@ -686,11 +688,11 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i
        * Handle devices that report invalid stuff here.
        */
        if (num_ports == 0 || num_ports > 2) {
-               dev_warn (dev, "%s: No valid connect info available\n",
+               dev_warn(dev, "%s: No valid connect info available\n",
                        serial->type->description);
                num_ports = 2;
        }
-  
+
        dev_info(dev, "%s: Number of ports: %d\n", serial->type->description,
                num_ports);
 
@@ -700,8 +702,9 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i
         */
        usb_set_serial_data(serial, (void *)(long)num_ports);
 
-       /* ask for the number of bytes available, but ignore the response as it is broken */
-       retval = usb_control_msg (serial->dev,
+       /* ask for the number of bytes available, but ignore the
+          response as it is broken */
+       retval = usb_control_msg(serial->dev,
                                  usb_rcvctrlpipe(serial->dev, 0),
                                  VISOR_REQUEST_BYTES_AVAILABLE,
                                  0xc2, 0x0000, 0x0005, transfer_buffer,
@@ -712,12 +715,13 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_i
        retval = 0;
 
 exit:
-       kfree (transfer_buffer);
+       kfree(transfer_buffer);
 
        return retval;
 }
 
-static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_id *id)
+static int palm_os_4_probe(struct usb_serial *serial,
+                                               const struct usb_device_id *id)
 {
        struct device *dev = &serial->dev->dev;
        struct palm_ext_connection_info *connection_info;
@@ -726,18 +730,18 @@ static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_i
 
        dbg("%s", __func__);
 
-       transfer_buffer =  kmalloc (sizeof (*connection_info), GFP_KERNEL);
+       transfer_buffer =  kmalloc(sizeof(*connection_info), GFP_KERNEL);
        if (!transfer_buffer) {
                dev_err(dev, "%s - kmalloc(%Zd) failed.\n", __func__,
                        sizeof(*connection_info));
                return -ENOMEM;
        }
 
-       retval = usb_control_msg (serial->dev,
-                                 usb_rcvctrlpipe(serial->dev, 0), 
+       retval = usb_control_msg(serial->dev,
+                                 usb_rcvctrlpipe(serial->dev, 0),
                                  PALM_GET_EXT_CONNECTION_INFORMATION,
                                  0xc2, 0x0000, 0x0000, transfer_buffer,
-                                 sizeof (*connection_info), 300);
+                                 sizeof(*connection_info), 300);
        if (retval < 0)
                dev_err(dev, "%s - error %d getting connection info\n",
                        __func__, retval);
@@ -745,15 +749,17 @@ static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_i
                usb_serial_debug_data(debug, &serial->dev->dev, __func__,
                                      retval, transfer_buffer);
 
-       kfree (transfer_buffer);
+       kfree(transfer_buffer);
        return 0;
 }
 
 
-static int visor_probe (struct usb_serial *serial, const struct usb_device_id *id)
+static int visor_probe(struct usb_serial *serial,
+                                       const struct usb_device_id *id)
 {
        int retval = 0;
-       int (*startup) (struct usb_serial *serial, const struct usb_device_id *id);
+       int (*startup)(struct usb_serial *serial,
+                                       const struct usb_device_id *id);
 
        dbg("%s", __func__);
 
@@ -771,7 +777,7 @@ static int visor_probe (struct usb_serial *serial, const struct usb_device_id *i
        return retval;
 }
 
-static int visor_calc_num_ports (struct usb_serial *serial)
+static int visor_calc_num_ports(struct usb_serial *serial)
 {
        int num_ports = (int)(long)(usb_get_serial_data(serial));
 
@@ -788,7 +794,7 @@ static int generic_startup(struct usb_serial *serial)
        int i;
 
        for (i = 0; i < serial->num_ports; ++i) {
-               priv = kzalloc (sizeof(*priv), GFP_KERNEL);
+               priv = kzalloc(sizeof(*priv), GFP_KERNEL);
                if (!priv) {
                        while (i-- != 0) {
                                priv = usb_get_serial_port_data(ports[i]);
@@ -803,7 +809,7 @@ static int generic_startup(struct usb_serial *serial)
        return 0;
 }
 
-static int clie_3_5_startup (struct usb_serial *serial)
+static int clie_3_5_startup(struct usb_serial *serial)
 {
        struct device *dev = &serial->dev->dev;
        int result;
@@ -816,62 +822,72 @@ static int clie_3_5_startup (struct usb_serial *serial)
         */
 
        /* get the config number */
-       result = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+       result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                                  USB_REQ_GET_CONFIGURATION, USB_DIR_IN,
                                  0, 0, &data, 1, 3000);
        if (result < 0) {
-               dev_err(dev, "%s: get config number failed: %d\n", __func__, result);
+               dev_err(dev, "%s: get config number failed: %d\n",
+                                                       __func__, result);
                return result;
        }
        if (result != 1) {
-               dev_err(dev, "%s: get config number bad return length: %d\n", __func__, result);
+               dev_err(dev, "%s: get config number bad return length: %d\n",
+                                                       __func__, result);
                return -EIO;
        }
 
        /* get the interface number */
-       result = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0),
-                                 USB_REQ_GET_INTERFACE, 
+       result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                                 USB_REQ_GET_INTERFACE,
                                  USB_DIR_IN | USB_RECIP_INTERFACE,
                                  0, 0, &data, 1, 3000);
        if (result < 0) {
-               dev_err(dev, "%s: get interface number failed: %d\n", __func__, result);
+               dev_err(dev, "%s: get interface number failed: %d\n",
+                                                       __func__, result);
                return result;
        }
        if (result != 1) {
-               dev_err(dev, "%s: get interface number bad return length: %d\n", __func__, result);
+               dev_err(dev,
+                       "%s: get interface number bad return length: %d\n",
+                                                       __func__, result);
                return -EIO;
        }
 
        return generic_startup(serial);
 }
-static int treo_attach (struct usb_serial *serial)
+
+static int treo_attach(struct usb_serial *serial)
 {
        struct usb_serial_port *swap_port;
 
        /* Only do this endpoint hack for the Handspring devices with
         * interrupt in endpoints, which for now are the Treo devices. */
-       if (!((le16_to_cpu(serial->dev->descriptor.idVendor) == HANDSPRING_VENDOR_ID) ||
-             (le16_to_cpu(serial->dev->descriptor.idVendor) == KYOCERA_VENDOR_ID)) ||
-           (serial->num_interrupt_in == 0))
+       if (!((le16_to_cpu(serial->dev->descriptor.idVendor)
+                                               == HANDSPRING_VENDOR_ID) ||
+               (le16_to_cpu(serial->dev->descriptor.idVendor)
+                                               == KYOCERA_VENDOR_ID)) ||
+               (serial->num_interrupt_in == 0))
                goto generic_startup;
 
        dbg("%s", __func__);
 
        /*
-       * It appears that Treos and Kyoceras want to use the 
-       * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint, 
-       * so let's swap the 1st and 2nd bulk in and interrupt endpoints.  
-       * Note that swapping the bulk out endpoints would break lots of 
+       * It appears that Treos and Kyoceras want to use the
+       * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
+       * so let's swap the 1st and 2nd bulk in and interrupt endpoints.
+       * Note that swapping the bulk out endpoints would break lots of
        * apps that want to communicate on the second port.
        */
 #define COPY_PORT(dest, src)                                           \
-       dest->read_urb = src->read_urb;                                 \
-       dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;   \
-       dest->bulk_in_buffer = src->bulk_in_buffer;                     \
-       dest->interrupt_in_urb = src->interrupt_in_urb;                 \
-       dest->interrupt_in_endpointAddress = src->interrupt_in_endpointAddress; \
-       dest->interrupt_in_buffer = src->interrupt_in_buffer;
+       do { \
+               dest->read_urb = src->read_urb;                         \
+               dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\
+               dest->bulk_in_buffer = src->bulk_in_buffer;             \
+               dest->interrupt_in_urb = src->interrupt_in_urb;         \
+               dest->interrupt_in_endpointAddress = \
+                                       src->interrupt_in_endpointAddress;\
+               dest->interrupt_in_buffer = src->interrupt_in_buffer;   \
+       } while (0);
 
        swap_port = kmalloc(sizeof(*swap_port), GFP_KERNEL);
        if (!swap_port)
@@ -885,28 +901,30 @@ generic_startup:
        return generic_startup(serial);
 }
 
-static int clie_5_attach (struct usb_serial *serial)
+static int clie_5_attach(struct usb_serial *serial)
 {
        dbg("%s", __func__);
 
-       /* TH55 registers 2 ports. 
-          Communication in from the UX50/TH55 uses bulk_in_endpointAddress from port 0 
-          Communication out to the UX50/TH55 uses bulk_out_endpointAddress from port 1 
-          
+       /* TH55 registers 2 ports.
+          Communication in from the UX50/TH55 uses bulk_in_endpointAddress
+          from port 0. Communication out to the UX50/TH55 uses
+          bulk_out_endpointAddress from port 1
+
           Lets do a quick and dirty mapping
         */
-       
+
        /* some sanity check */
        if (serial->num_ports < 2)
                return -1;
-               
+
        /* port 0 now uses the modified endpoint Address */
-       serial->port[0]->bulk_out_endpointAddress = serial->port[1]->bulk_out_endpointAddress;
+       serial->port[0]->bulk_out_endpointAddress =
+                               serial->port[1]->bulk_out_endpointAddress;
 
        return generic_startup(serial);
 }
 
-static void visor_shutdown (struct usb_serial *serial)
+static void visor_shutdown(struct usb_serial *serial)
 {
        struct visor_private *priv;
        int i;
@@ -922,37 +940,35 @@ static void visor_shutdown (struct usb_serial *serial)
        }
 }
 
-static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
-{
-       dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
-
-       return -ENOIOCTLCMD;
-}
-
-static int __init visor_init (void)
+static int __init visor_init(void)
 {
        int i, retval;
        /* Only if parameters were passed to us */
-       if ((vendor>0) && (product>0)) {
-               struct usb_device_id usb_dev_temp[]=
-                       {{USB_DEVICE(vendor, product),
-                       .driver_info = (kernel_ulong_t)&palm_os_4_probe }};
+       if (vendor > 0 && product > 0) {
+               struct usb_device_id usb_dev_temp[] = {
+                       {
+                               USB_DEVICE(vendor, product),
+                               .driver_info =
+                                       (kernel_ulong_t) &palm_os_4_probe
+                       }
+               };
 
                /* Find the last entry in id_table */
-               for (i=0; ; i++) {
-                       if (id_table[i].idVendor==0) {
+               for (i = 0;; i++) {
+                       if (id_table[i].idVendor == 0) {
                                id_table[i] = usb_dev_temp[0];
                                break;
                        }
                }
                /* Find the last entry in id_table_combined */
-               for (i=0; ; i++) {
-                       if (id_table_combined[i].idVendor==0) {
+               for (i = 0;; i++) {
+                       if (id_table_combined[i].idVendor == 0) {
                                id_table_combined[i] = usb_dev_temp[0];
                                break;
                        }
                }
-               info("Untested USB device specified at time of module insertion");
+               info(
+                 "Untested USB device specified at time of module insertion");
                info("Warning: This is not guaranteed to work");
                info("Using a newer kernel is preferred to this method");
                info("Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x",
@@ -968,7 +984,7 @@ static int __init visor_init (void)
        if (retval)
                goto failed_clie_5_register;
        retval = usb_register(&visor_driver);
-       if (retval) 
+       if (retval)
                goto failed_usb_register;
        info(DRIVER_DESC);
 
@@ -986,18 +1002,18 @@ failed_handspring_register:
 
 static void __exit visor_exit (void)
 {
-       usb_deregister (&visor_driver);
-       usb_serial_deregister (&handspring_device);
-       usb_serial_deregister (&clie_3_5_device);
-       usb_serial_deregister (&clie_5_device);
+       usb_deregister(&visor_driver);
+       usb_serial_deregister(&handspring_device);
+       usb_serial_deregister(&clie_3_5_device);
+       usb_serial_deregister(&clie_5_device);
 }
 
 
 module_init(visor_init);
 module_exit(visor_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
index 665aa77a917b1c464c5f6da22860a54a6afd1fd6..3a9d14384a4380a85ec0072d1bda7aa653ad5d7c 100644 (file)
  *     the Free Software Foundation; either version 2 of the License, or
  *     (at your option) any later version.
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
  *
  * (10/09/2002) Stuart MacDonald (stuartm@connecttech.com)
  *     Upgrade to full working driver
  *
  * (05/30/2001) gkh
- *     switched from using spinlock to a semaphore, which fixes lots of problems.
+ *     switched from using spinlock to a semaphore, which fixes lots of
+ *     problems.
  *
  * (04/08/2001) gb
  *     Identify version on module load.
- * 
+ *
  * 2001_Mar_19 gkh
- *     Fixed MOD_INC and MOD_DEC logic, the ability to open a port more 
+ *     Fixed MOD_INC and MOD_DEC logic, the ability to open a port more
  *     than once, and the got the proper usb_device_id table entries so
  *     the driver works again.
  *
  * (11/01/2000) Adam J. Richter
  *     usb_device_id table support
- * 
+ *
  * (10/05/2000) gkh
  *     Fixed bug with urb->dev not being set properly, now that the usb
  *     core needs it.
- * 
+ *
  * (10/03/2000) smd
  *     firmware is improved to guard against crap sent to device
  *     firmware now replies CMD_FAILURE on bad things
@@ -52,9 +54,9 @@
  *     Fixed bug with port->minor that was found by Al Borchers
  *
  * (07/04/2000) gkh
- *     Added support for port settings. Baud rate can now be changed. Line signals
- *     are not transferred to and from the tty layer yet, but things seem to be 
- *     working well now.
+ *     Added support for port settings. Baud rate can now be changed. Line
+ *     signals are not transferred to and from the tty layer yet, but things
+ *     seem to be working well now.
  *
  * (05/04/2000) gkh
  *     First cut at open and close commands. Data can flow through the ports at
@@ -62,7 +64,7 @@
  *
  * (03/26/2000) gkh
  *     Split driver up into device specific pieces.
- * 
+ *
  */
 
 #include <linux/kernel.h>
@@ -75,7 +77,7 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <asm/termbits.h>
 #include <linux/usb.h>
 #include <linux/serial_reg.h>
@@ -125,7 +127,7 @@ static struct usb_device_id id_table_combined [] = {
        { }                                             /* Terminating entry */
 };
 
-MODULE_DEVICE_TABLE (usb, id_table_combined);
+MODULE_DEVICE_TABLE(usb, id_table_combined);
 
 static struct usb_driver whiteheat_driver = {
        .name =         "whiteheat",
@@ -136,26 +138,34 @@ static struct usb_driver whiteheat_driver = {
 };
 
 /* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */
-static int  whiteheat_firmware_download        (struct usb_serial *serial, const struct usb_device_id *id);
-static int  whiteheat_firmware_attach  (struct usb_serial *serial);
+static int  whiteheat_firmware_download(struct usb_serial *serial,
+                                       const struct usb_device_id *id);
+static int  whiteheat_firmware_attach(struct usb_serial *serial);
 
 /* function prototypes for the Connect Tech WhiteHEAT serial converter */
-static int  whiteheat_attach           (struct usb_serial *serial);
-static void whiteheat_shutdown         (struct usb_serial *serial);
-static int  whiteheat_open             (struct usb_serial_port *port, struct file *filp);
-static void whiteheat_close            (struct usb_serial_port *port, struct file *filp);
-static int  whiteheat_write            (struct usb_serial_port *port, const unsigned char *buf, int count);
-static int  whiteheat_write_room       (struct usb_serial_port *port);
-static int  whiteheat_ioctl            (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
-static void whiteheat_set_termios      (struct usb_serial_port *port, struct ktermios * old);
-static int  whiteheat_tiocmget         (struct usb_serial_port *port, struct file *file);
-static int  whiteheat_tiocmset         (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
-static void whiteheat_break_ctl                (struct usb_serial_port *port, int break_state);
-static int  whiteheat_chars_in_buffer  (struct usb_serial_port *port);
-static void whiteheat_throttle         (struct usb_serial_port *port);
-static void whiteheat_unthrottle       (struct usb_serial_port *port);
-static void whiteheat_read_callback    (struct urb *urb);
-static void whiteheat_write_callback   (struct urb *urb);
+static int  whiteheat_attach(struct usb_serial *serial);
+static void whiteheat_shutdown(struct usb_serial *serial);
+static int  whiteheat_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static void whiteheat_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+static int  whiteheat_write(struct tty_struct *tty,
+                       struct usb_serial_port *port,
+                       const unsigned char *buf, int count);
+static int  whiteheat_write_room(struct tty_struct *tty);
+static int  whiteheat_ioctl(struct tty_struct *tty, struct file *file,
+                       unsigned int cmd, unsigned long arg);
+static void whiteheat_set_termios(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct ktermios *old);
+static int  whiteheat_tiocmget(struct tty_struct *tty, struct file *file);
+static int  whiteheat_tiocmset(struct tty_struct *tty, struct file *file,
+                       unsigned int set, unsigned int clear);
+static void whiteheat_break_ctl(struct tty_struct *tty, int break_state);
+static int  whiteheat_chars_in_buffer(struct tty_struct *tty);
+static void whiteheat_throttle(struct tty_struct *tty);
+static void whiteheat_unthrottle(struct tty_struct *tty);
+static void whiteheat_read_callback(struct urb *urb);
+static void whiteheat_write_callback(struct urb *urb);
 
 static struct usb_serial_driver whiteheat_fake_device = {
        .driver = {
@@ -202,7 +212,9 @@ struct whiteheat_command_private {
        struct mutex            mutex;
        __u8                    port_running;
        __u8                    command_finished;
-       wait_queue_head_t       wait_command;   /* for handling sleeping while waiting for a command to finish */
+       wait_queue_head_t       wait_command; /* for handling sleeping whilst
+                                                waiting for a command to
+                                                finish */
        __u8                    result_buffer[64];
 };
 
@@ -239,14 +251,16 @@ static void command_port_write_callback(struct urb *urb);
 static void command_port_read_callback(struct urb *urb);
 
 static int start_port_read(struct usb_serial_port *port);
-static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb, struct list_head *head);
+static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
+                                               struct list_head *head);
 static struct list_head *list_first(struct list_head *head);
 static void rx_data_softint(struct work_struct *work);
 
-static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize);
+static int firm_send_command(struct usb_serial_port *port, __u8 command,
+                                               __u8 *data, __u8 datasize);
 static int firm_open(struct usb_serial_port *port);
 static int firm_close(struct usb_serial_port *port);
-static int firm_setup_port(struct usb_serial_port *port);
+static int firm_setup_port(struct tty_struct *tty);
 static int firm_set_rts(struct usb_serial_port *port, __u8 onoff);
 static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff);
 static int firm_set_break(struct usb_serial_port *port, __u8 onoff);
@@ -278,7 +292,8 @@ static int firm_report_tx_done(struct usb_serial_port *port);
  - device renumerated itself and comes up as new device id with all
    firmware download completed.
 */
-static int whiteheat_firmware_download (struct usb_serial *serial, const struct usb_device_id *id)
+static int whiteheat_firmware_download(struct usb_serial *serial,
+                                       const struct usb_device_id *id)
 {
        int response, ret = -ENOENT;
        const struct firmware *loader_fw = NULL, *firmware_fw = NULL;
@@ -313,7 +328,7 @@ static int whiteheat_firmware_download (struct usb_serial *serial, const struct
                record = ihex_next_binrec(record);
        }
 
-       response = ezusb_set_reset (serial, 0);
+       response = ezusb_set_reset(serial, 0);
 
        record = (const struct ihex_binrec *)firmware_fw->data;
        while (record && be32_to_cpu(record->addr) < 0x1b40)
@@ -330,8 +345,8 @@ static int whiteheat_firmware_download (struct usb_serial *serial, const struct
                }
                ++record;
        }
-       
-       response = ezusb_set_reset (serial, 1);
+
+       response = ezusb_set_reset(serial, 1);
 
        record = (const struct ihex_binrec *)firmware_fw->data;
        while (record && be32_to_cpu(record->addr) < 0x1b40) {
@@ -355,7 +370,7 @@ static int whiteheat_firmware_download (struct usb_serial *serial, const struct
 }
 
 
-static int whiteheat_firmware_attach (struct usb_serial *serial)
+static int whiteheat_firmware_attach(struct usb_serial *serial)
 {
        /* We want this device to fail to have a driver assigned to it */
        return 1;
@@ -365,7 +380,7 @@ static int whiteheat_firmware_attach (struct usb_serial *serial)
 /*****************************************************************************
  * Connect Tech's White Heat serial driver functions
  *****************************************************************************/
-static int whiteheat_attach (struct usb_serial *serial)
+static int whiteheat_attach(struct usb_serial *serial)
 {
        struct usb_serial_port *command_port;
        struct whiteheat_command_private *command_info;
@@ -386,43 +401,52 @@ static int whiteheat_attach (struct usb_serial *serial)
 
        command_port = serial->port[COMMAND_PORT];
 
-       pipe = usb_sndbulkpipe (serial->dev, command_port->bulk_out_endpointAddress);
+       pipe = usb_sndbulkpipe(serial->dev,
+                       command_port->bulk_out_endpointAddress);
        command = kmalloc(2, GFP_KERNEL);
        if (!command)
                goto no_command_buffer;
        command[0] = WHITEHEAT_GET_HW_INFO;
        command[1] = 0;
-       
+
        result = kmalloc(sizeof(*hw_info) + 1, GFP_KERNEL);
        if (!result)
                goto no_result_buffer;
        /*
         * When the module is reloaded the firmware is still there and
         * the endpoints are still in the usb core unchanged. This is the
-         * unlinking bug in disguise. Same for the call below.
-         */
+        * unlinking bug in disguise. Same for the call below.
+        */
        usb_clear_halt(serial->dev, pipe);
-       ret = usb_bulk_msg (serial->dev, pipe, command, 2, &alen, COMMAND_TIMEOUT_MS);
+       ret = usb_bulk_msg(serial->dev, pipe, command, 2,
+                                               &alen, COMMAND_TIMEOUT_MS);
        if (ret) {
-               err("%s: Couldn't send command [%d]", serial->type->description, ret);
+               err("%s: Couldn't send command [%d]",
+                               serial->type->description, ret);
                goto no_firmware;
        } else if (alen != 2) {
-               err("%s: Send command incomplete [%d]", serial->type->description, alen);
+               err("%s: Send command incomplete [%d]",
+                               serial->type->description, alen);
                goto no_firmware;
        }
 
-       pipe = usb_rcvbulkpipe (serial->dev, command_port->bulk_in_endpointAddress);
+       pipe = usb_rcvbulkpipe(serial->dev,
+                               command_port->bulk_in_endpointAddress);
        /* See the comment on the usb_clear_halt() above */
        usb_clear_halt(serial->dev, pipe);
-       ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS);
+       ret = usb_bulk_msg(serial->dev, pipe, result,
+                       sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS);
        if (ret) {
-               err("%s: Couldn't get results [%d]", serial->type->description, ret);
+               err("%s: Couldn't get results [%d]",
+                               serial->type->description, ret);
                goto no_firmware;
        } else if (alen != sizeof(*hw_info) + 1) {
-               err("%s: Get results incomplete [%d]", serial->type->description, alen);
+               err("%s: Get results incomplete [%d]",
+                               serial->type->description, alen);
                goto no_firmware;
        } else if (result[0] != command[0]) {
-               err("%s: Command failed [%d]", serial->type->description, result[0]);
+               err("%s: Command failed [%d]",
+                               serial->type->description, result[0]);
                goto no_firmware;
        }
 
@@ -436,7 +460,8 @@ static int whiteheat_attach (struct usb_serial *serial)
 
                info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL);
                if (info == NULL) {
-                       err("%s: Out of memory for port structures\n", serial->type->description);
+                       err("%s: Out of memory for port structures\n",
+                                       serial->type->description);
                        goto no_private;
                }
 
@@ -506,9 +531,11 @@ static int whiteheat_attach (struct usb_serial *serial)
                usb_set_serial_port_data(port, info);
        }
 
-       command_info = kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL);
+       command_info = kmalloc(sizeof(struct whiteheat_command_private),
+                                                               GFP_KERNEL);
        if (command_info == NULL) {
-               err("%s: Out of memory for port structures\n", serial->type->description);
+               err("%s: Out of memory for port structures\n",
+                                       serial->type->description);
                goto no_command_private;
        }
 
@@ -525,9 +552,12 @@ static int whiteheat_attach (struct usb_serial *serial)
 
 no_firmware:
        /* Firmware likely not running */
-       err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->description);
-       err("%s: If the firmware is not running (status led not blinking)\n", serial->type->description);
-       err("%s: please contact support@connecttech.com\n", serial->type->description);
+       err("%s: Unable to retrieve firmware version, try replugging\n",
+                                       serial->type->description);
+       err("%s: If the firmware is not running (status led not blinking)\n",
+                                       serial->type->description);
+       err("%s: please contact support@connecttech.com\n",
+                                       serial->type->description);
        kfree(result);
        return -ENODEV;
 
@@ -570,7 +600,7 @@ no_command_buffer:
 }
 
 
-static void whiteheat_shutdown (struct usb_serial *serial)
+static void whiteheat_shutdown(struct usb_serial *serial)
 {
        struct usb_serial_port *command_port;
        struct usb_serial_port *port;
@@ -585,7 +615,7 @@ static void whiteheat_shutdown (struct usb_serial *serial)
 
        /* free up our private data for our command port */
        command_port = serial->port[COMMAND_PORT];
-       kfree (usb_get_serial_port_data(command_port));
+       kfree(usb_get_serial_port_data(command_port));
 
        for (i = 0; i < serial->num_ports; i++) {
                port = serial->port[i];
@@ -612,11 +642,10 @@ static void whiteheat_shutdown (struct usb_serial *serial)
        return;
 }
 
-
-static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
+static int whiteheat_open(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        int             retval = 0;
-       struct ktermios old_term;
 
        dbg("%s - port %d", __func__, port->number);
 
@@ -624,7 +653,8 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
        if (retval)
                goto exit;
 
-       port->tty->low_latency = 1;
+       if (tty)
+               tty->low_latency = 1;
 
        /* send an open port command */
        retval = firm_open(port);
@@ -640,9 +670,8 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
                goto exit;
        }
 
-       old_term.c_cflag = ~port->tty->termios->c_cflag;
-       old_term.c_iflag = ~port->tty->termios->c_iflag;
-       whiteheat_set_termios(port, &old_term);
+       if (tty)
+               firm_setup_port(tty);
 
        /* Work around HCD bugs */
        usb_clear_halt(port->serial->dev, port->read_urb->pipe);
@@ -651,7 +680,8 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
        /* Start reading from the device */
        retval = start_port_read(port);
        if (retval) {
-               err("%s - failed submitting read urb, error %d", __func__, retval);
+               err("%s - failed submitting read urb, error %d",
+                               __func__, retval);
                firm_close(port);
                stop_command_port(port->serial);
                goto exit;
@@ -663,7 +693,8 @@ exit:
 }
 
 
-static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
+static void whiteheat_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp)
 {
        struct whiteheat_private *info = usb_get_serial_port_data(port);
        struct whiteheat_urb_wrap *wrap;
@@ -681,7 +712,7 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
        }
        mutex_unlock(&port->serial->disc_mutex);
 
-       port->tty->closing = 1;
+       tty->closing = 1;
 
 /*
  * Not currently in use; tty_wait_until_sent() calls
@@ -689,12 +720,12 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
  * acquisition. This should be fixed at some point. Greg's been
  * notified.
        if ((filp->f_flags & (O_NDELAY | O_NONBLOCK)) == 0) {
-               tty_wait_until_sent(port->tty, CLOSING_DELAY);
+               tty_wait_until_sent(tty, CLOSING_DELAY);
        }
 */
 
-       tty_driver_flush_buffer(port->tty);
-       tty_ldisc_flush(port->tty);
+       tty_driver_flush_buffer(tty);
+       tty_ldisc_flush(tty);
 
        firm_report_tx_done(port);
 
@@ -728,11 +759,12 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
 
        stop_command_port(port->serial);
 
-       port->tty->closing = 0;
+       tty->closing = 0;
 }
 
 
-static int whiteheat_write(struct usb_serial_port *port, const unsigned char *buf, int count)
+static int whiteheat_write(struct tty_struct *tty,
+       struct usb_serial_port *port, const unsigned char *buf, int count)
 {
        struct usb_serial *serial = port->serial;
        struct whiteheat_private *info = usb_get_serial_port_data(port);
@@ -763,16 +795,19 @@ static int whiteheat_write(struct usb_serial_port *port, const unsigned char *bu
 
                wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
                urb = wrap->urb;
-               bytes = (count > port->bulk_out_size) ? port->bulk_out_size : count;
-               memcpy (urb->transfer_buffer, buf + sent, bytes);
+               bytes = (count > port->bulk_out_size) ?
+                                       port->bulk_out_size : count;
+               memcpy(urb->transfer_buffer, buf + sent, bytes);
 
-               usb_serial_debug_data(debug, &port->dev, __func__, bytes, urb->transfer_buffer);
+               usb_serial_debug_data(debug, &port->dev,
+                               __func__, bytes, urb->transfer_buffer);
 
                urb->dev = serial->dev;
                urb->transfer_buffer_length = bytes;
                result = usb_submit_urb(urb, GFP_ATOMIC);
                if (result) {
-                       err("%s - failed submitting write urb, error %d", __func__, result);
+                       err("%s - failed submitting write urb, error %d",
+                                                       __func__, result);
                        sent = result;
                        spin_lock_irqsave(&info->lock, flags);
                        list_add(tmp, &info->tx_urbs_free);
@@ -790,16 +825,16 @@ static int whiteheat_write(struct usb_serial_port *port, const unsigned char *bu
        return sent;
 }
 
-
-static int whiteheat_write_room(struct usb_serial_port *port)
+static int whiteheat_write_room(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct whiteheat_private *info = usb_get_serial_port_data(port);
        struct list_head *tmp;
        int room = 0;
        unsigned long flags;
 
        dbg("%s - port %d", __func__, port->number);
-       
+
        spin_lock_irqsave(&info->lock, flags);
        list_for_each(tmp, &info->tx_urbs_free)
                room++;
@@ -810,9 +845,9 @@ static int whiteheat_write_room(struct usb_serial_port *port)
        return (room);
 }
 
-
-static int whiteheat_tiocmget (struct usb_serial_port *port, struct file *file)
+static int whiteheat_tiocmget(struct tty_struct *tty, struct file *file)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct whiteheat_private *info = usb_get_serial_port_data(port);
        unsigned int modem_signals = 0;
 
@@ -827,10 +862,10 @@ static int whiteheat_tiocmget (struct usb_serial_port *port, struct file *file)
        return modem_signals;
 }
 
-
-static int whiteheat_tiocmset (struct usb_serial_port *port, struct file *file,
+static int whiteheat_tiocmset(struct tty_struct *tty, struct file *file,
                               unsigned int set, unsigned int clear)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct whiteheat_private *info = usb_get_serial_port_data(port);
 
        dbg("%s - port %d", __func__, port->number);
@@ -851,65 +886,55 @@ static int whiteheat_tiocmset (struct usb_serial_port *port, struct file *file,
 }
 
 
-static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
+static int whiteheat_ioctl(struct tty_struct *tty, struct file *file,
+                                       unsigned int cmd, unsigned long arg)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct serial_struct serstruct;
        void __user *user_arg = (void __user *)arg;
 
        dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);
 
        switch (cmd) {
-               case TIOCGSERIAL:
-                       memset(&serstruct, 0, sizeof(serstruct));
-                       serstruct.type = PORT_16654;
-                       serstruct.line = port->serial->minor;
-                       serstruct.port = port->number;
-                       serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
-                       serstruct.xmit_fifo_size = port->bulk_out_size;
-                       serstruct.custom_divisor = 0;
-                       serstruct.baud_base = 460800;
-                       serstruct.close_delay = CLOSING_DELAY;
-                       serstruct.closing_wait = CLOSING_DELAY;
-
-                       if (copy_to_user(user_arg, &serstruct, sizeof(serstruct)))
-                               return -EFAULT;
-
-                       break;
-
-               case TIOCSSERIAL:
-                       if (copy_from_user(&serstruct, user_arg, sizeof(serstruct)))
-                               return -EFAULT;
-
-                       /*
-                        * For now this is ignored. dip sets the ASYNC_[V]HI flags
-                        * but this isn't used by us at all. Maybe someone somewhere
-                        * will need the custom_divisor setting.
-                        */
-
-                       break;
-
-               default:
-                       break;
+       case TIOCGSERIAL:
+               memset(&serstruct, 0, sizeof(serstruct));
+               serstruct.type = PORT_16654;
+               serstruct.line = port->serial->minor;
+               serstruct.port = port->number;
+               serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
+               serstruct.xmit_fifo_size = port->bulk_out_size;
+               serstruct.custom_divisor = 0;
+               serstruct.baud_base = 460800;
+               serstruct.close_delay = CLOSING_DELAY;
+               serstruct.closing_wait = CLOSING_DELAY;
+
+               if (copy_to_user(user_arg, &serstruct, sizeof(serstruct)))
+                       return -EFAULT;
+               break;
+       default:
+               break;
        }
 
        return -ENOIOCTLCMD;
 }
 
 
-static void whiteheat_set_termios(struct usb_serial_port *port, struct ktermios *old_termios)
+static void whiteheat_set_termios(struct tty_struct *tty,
+       struct usb_serial_port *port, struct ktermios *old_termios)
 {
-       dbg("%s -port %d", __func__, port->number);
-       firm_setup_port(port);
+       firm_setup_port(tty);
 }
 
-
-static void whiteheat_break_ctl(struct usb_serial_port *port, int break_state) {
+static void whiteheat_break_ctl(struct tty_struct *tty, int break_state)
+{
+       struct usb_serial_port *port = tty->driver_data;
        firm_set_break(port, break_state);
 }
 
 
-static int whiteheat_chars_in_buffer(struct usb_serial_port *port)
+static int whiteheat_chars_in_buffer(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct whiteheat_private *info = usb_get_serial_port_data(port);
        struct list_head *tmp;
        struct whiteheat_urb_wrap *wrap;
@@ -925,13 +950,14 @@ static int whiteheat_chars_in_buffer(struct usb_serial_port *port)
        }
        spin_unlock_irqrestore(&info->lock, flags);
 
-       dbg ("%s - returns %d", __func__, chars);
+       dbg("%s - returns %d", __func__, chars);
        return chars;
 }
 
 
-static void whiteheat_throttle (struct usb_serial_port *port)
+static void whiteheat_throttle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct whiteheat_private *info = usb_get_serial_port_data(port);
        unsigned long flags;
 
@@ -945,8 +971,9 @@ static void whiteheat_throttle (struct usb_serial_port *port)
 }
 
 
-static void whiteheat_unthrottle (struct usb_serial_port *port)
+static void whiteheat_unthrottle(struct tty_struct *tty)
 {
+       struct usb_serial_port *port = tty->driver_data;
        struct whiteheat_private *info = usb_get_serial_port_data(port);
        int actually_throttled;
        unsigned long flags;
@@ -993,7 +1020,7 @@ static void command_port_read_callback(struct urb *urb)
 
        command_info = usb_get_serial_port_data(command_port);
        if (!command_info) {
-               dbg ("%s - command_info is NULL, exiting.", __func__);
+               dbg("%s - command_info is NULL, exiting.", __func__);
                return;
        }
        if (status) {
@@ -1004,7 +1031,8 @@ static void command_port_read_callback(struct urb *urb)
                return;
        }
 
-       usb_serial_debug_data(debug, &command_port->dev, __func__, urb->actual_length, data);
+       usb_serial_debug_data(debug, &command_port->dev,
+                               __func__, urb->actual_length, data);
 
        if (data[0] == WHITEHEAT_CMD_COMPLETE) {
                command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
@@ -1013,21 +1041,23 @@ static void command_port_read_callback(struct urb *urb)
                command_info->command_finished = WHITEHEAT_CMD_FAILURE;
                wake_up(&command_info->wait_command);
        } else if (data[0] == WHITEHEAT_EVENT) {
-               /* These are unsolicited reports from the firmware, hence no waiting command to wakeup */
+               /* These are unsolicited reports from the firmware, hence no
+                  waiting command to wakeup */
                dbg("%s - event received", __func__);
        } else if (data[0] == WHITEHEAT_GET_DTR_RTS) {
-               memcpy(command_info->result_buffer, &data[1], urb->actual_length - 1);
+               memcpy(command_info->result_buffer, &data[1],
+                                               urb->actual_length - 1);
                command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
                wake_up(&command_info->wait_command);
-       } else {
+       } else
                dbg("%s - bad reply from firmware", __func__);
-       }
-       
+
        /* Continue trying to always read */
        command_port->read_urb->dev = command_port->serial->dev;
        result = usb_submit_urb(command_port->read_urb, GFP_ATOMIC);
        if (result)
-               dbg("%s - failed resubmitting read urb, error %d", __func__, result);
+               dbg("%s - failed resubmitting read urb, error %d",
+                       __func__, result);
 }
 
 
@@ -1060,7 +1090,8 @@ static void whiteheat_read_callback(struct urb *urb)
                return;
        }
 
-       usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
+       usb_serial_debug_data(debug, &port->dev,
+                               __func__, urb->actual_length, data);
 
        spin_lock(&info->lock);
        list_add_tail(&wrap->list, &info->rx_urb_q);
@@ -1107,7 +1138,8 @@ static void whiteheat_write_callback(struct urb *urb)
 /*****************************************************************************
  * Connect Tech's White Heat firmware interface
  *****************************************************************************/
-static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize)
+static int firm_send_command(struct usb_serial_port *port, __u8 command,
+                                               __u8 *data, __u8 datasize)
 {
        struct usb_serial_port *command_port;
        struct whiteheat_command_private *command_info;
@@ -1122,13 +1154,13 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *d
        command_info = usb_get_serial_port_data(command_port);
        mutex_lock(&command_info->mutex);
        command_info->command_finished = false;
-       
+
        transfer_buffer = (__u8 *)command_port->write_urb->transfer_buffer;
        transfer_buffer[0] = command;
-       memcpy (&transfer_buffer[1], data, datasize);
+       memcpy(&transfer_buffer[1], data, datasize);
        command_port->write_urb->transfer_buffer_length = datasize + 1;
        command_port->write_urb->dev = port->serial->dev;
-       retval = usb_submit_urb (command_port->write_urb, GFP_NOIO);
+       retval = usb_submit_urb(command_port->write_urb, GFP_NOIO);
        if (retval) {
                dbg("%s - submit urb failed", __func__);
                goto exit;
@@ -1155,51 +1187,57 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *d
        if (command_info->command_finished == WHITEHEAT_CMD_COMPLETE) {
                dbg("%s - command completed.", __func__);
                switch (command) {
-                       case WHITEHEAT_GET_DTR_RTS:
-                               info = usb_get_serial_port_data(port);
-                               memcpy(&info->mcr, command_info->result_buffer, sizeof(struct whiteheat_dr_info));
+               case WHITEHEAT_GET_DTR_RTS:
+                       info = usb_get_serial_port_data(port);
+                       memcpy(&info->mcr, command_info->result_buffer,
+                                       sizeof(struct whiteheat_dr_info));
                                break;
                }
        }
-
 exit:
        mutex_unlock(&command_info->mutex);
        return retval;
 }
 
 
-static int firm_open(struct usb_serial_port *port) {
+static int firm_open(struct usb_serial_port *port)
+{
        struct whiteheat_simple open_command;
 
        open_command.port = port->number - port->serial->minor + 1;
-       return firm_send_command(port, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command));
+       return firm_send_command(port, WHITEHEAT_OPEN,
+               (__u8 *)&open_command, sizeof(open_command));
 }
 
 
-static int firm_close(struct usb_serial_port *port) {
+static int firm_close(struct usb_serial_port *port)
+{
        struct whiteheat_simple close_command;
 
        close_command.port = port->number - port->serial->minor + 1;
-       return firm_send_command(port, WHITEHEAT_CLOSE, (__u8 *)&close_command, sizeof(close_command));
+       return firm_send_command(port, WHITEHEAT_CLOSE,
+                       (__u8 *)&close_command, sizeof(close_command));
 }
 
 
-static int firm_setup_port(struct usb_serial_port *port) {
+static int firm_setup_port(struct tty_struct *tty)
+{
+       struct usb_serial_port *port = tty->driver_data;
        struct whiteheat_port_settings port_settings;
-       unsigned int cflag = port->tty->termios->c_cflag;
+       unsigned int cflag = tty->termios->c_cflag;
 
        port_settings.port = port->number + 1;
 
        /* get the byte size */
        switch (cflag & CSIZE) {
-               case CS5:       port_settings.bits = 5;   break;
-               case CS6:       port_settings.bits = 6;   break;
-               case CS7:       port_settings.bits = 7;   break;
-               default:
-               case CS8:       port_settings.bits = 8;   break;
+       case CS5:       port_settings.bits = 5;   break;
+       case CS6:       port_settings.bits = 6;   break;
+       case CS7:       port_settings.bits = 7;   break;
+       default:
+       case CS8:       port_settings.bits = 8;   break;
        }
        dbg("%s - data bits = %d", __func__, port_settings.bits);
-       
+
        /* determine the parity */
        if (cflag & PARENB)
                if (cflag & CMSPAR)
@@ -1225,7 +1263,8 @@ static int firm_setup_port(struct usb_serial_port *port) {
 
        /* figure out the flow control settings */
        if (cflag & CRTSCTS)
-               port_settings.hflow = (WHITEHEAT_HFLOW_CTS | WHITEHEAT_HFLOW_RTS);
+               port_settings.hflow = (WHITEHEAT_HFLOW_CTS |
+                                               WHITEHEAT_HFLOW_RTS);
        else
                port_settings.hflow = WHITEHEAT_HFLOW_NONE;
        dbg("%s - hardware flow control = %s %s %s %s", __func__,
@@ -1233,81 +1272,95 @@ static int firm_setup_port(struct usb_serial_port *port) {
            (port_settings.hflow & WHITEHEAT_HFLOW_RTS) ? "RTS" : "",
            (port_settings.hflow & WHITEHEAT_HFLOW_DSR) ? "DSR" : "",
            (port_settings.hflow & WHITEHEAT_HFLOW_DTR) ? "DTR" : "");
-       
+
        /* determine software flow control */
-       if (I_IXOFF(port->tty))
+       if (I_IXOFF(tty))
                port_settings.sflow = WHITEHEAT_SFLOW_RXTX;
        else
                port_settings.sflow = WHITEHEAT_SFLOW_NONE;
        dbg("%s - software flow control = %c", __func__, port_settings.sflow);
-       
-       port_settings.xon = START_CHAR(port->tty);
-       port_settings.xoff = STOP_CHAR(port->tty);
-       dbg("%s - XON = %2x, XOFF = %2x", __func__, port_settings.xon, port_settings.xoff);
+
+       port_settings.xon = START_CHAR(tty);
+       port_settings.xoff = STOP_CHAR(tty);
+       dbg("%s - XON = %2x, XOFF = %2x",
+                       __func__, port_settings.xon, port_settings.xoff);
 
        /* get the baud rate wanted */
-       port_settings.baud = tty_get_baud_rate(port->tty);
+       port_settings.baud = tty_get_baud_rate(tty);
        dbg("%s - baud rate = %d", __func__, port_settings.baud);
 
        /* fixme: should set validated settings */
-       tty_encode_baud_rate(port->tty, port_settings.baud, port_settings.baud);
+       tty_encode_baud_rate(tty, port_settings.baud, port_settings.baud);
        /* handle any settings that aren't specified in the tty structure */
        port_settings.lloop = 0;
-       
+
        /* now send the message to the device */
-       return firm_send_command(port, WHITEHEAT_SETUP_PORT, (__u8 *)&port_settings, sizeof(port_settings));
+       return firm_send_command(port, WHITEHEAT_SETUP_PORT,
+                       (__u8 *)&port_settings, sizeof(port_settings));
 }
 
 
-static int firm_set_rts(struct usb_serial_port *port, __u8 onoff) {
+static int firm_set_rts(struct usb_serial_port *port, __u8 onoff)
+{
        struct whiteheat_set_rdb rts_command;
 
        rts_command.port = port->number - port->serial->minor + 1;
        rts_command.state = onoff;
-       return firm_send_command(port, WHITEHEAT_SET_RTS, (__u8 *)&rts_command, sizeof(rts_command));
+       return firm_send_command(port, WHITEHEAT_SET_RTS,
+                       (__u8 *)&rts_command, sizeof(rts_command));
 }
 
 
-static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff) {
+static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff)
+{
        struct whiteheat_set_rdb dtr_command;
 
        dtr_command.port = port->number - port->serial->minor + 1;
        dtr_command.state = onoff;
-       return firm_send_command(port, WHITEHEAT_SET_RTS, (__u8 *)&dtr_command, sizeof(dtr_command));
+       return firm_send_command(port, WHITEHEAT_SET_DTR,
+                       (__u8 *)&dtr_command, sizeof(dtr_command));
 }
 
 
-static int firm_set_break(struct usb_serial_port *port, __u8 onoff) {
+static int firm_set_break(struct usb_serial_port *port, __u8 onoff)
+{
        struct whiteheat_set_rdb break_command;
 
        break_command.port = port->number - port->serial->minor + 1;
        break_command.state = onoff;
-       return firm_send_command(port, WHITEHEAT_SET_RTS, (__u8 *)&break_command, sizeof(break_command));
+       return firm_send_command(port, WHITEHEAT_SET_BREAK,
+                       (__u8 *)&break_command, sizeof(break_command));
 }
 
 
-static int firm_purge(struct usb_serial_port *port, __u8 rxtx) {
+static int firm_purge(struct usb_serial_port *port, __u8 rxtx)
+{
        struct whiteheat_purge purge_command;
 
        purge_command.port = port->number - port->serial->minor + 1;
        purge_command.what = rxtx;
-       return firm_send_command(port, WHITEHEAT_PURGE, (__u8 *)&purge_command, sizeof(purge_command));
+       return firm_send_command(port, WHITEHEAT_PURGE,
+                       (__u8 *)&purge_command, sizeof(purge_command));
 }
 
 
-static int firm_get_dtr_rts(struct usb_serial_port *port) {
+static int firm_get_dtr_rts(struct usb_serial_port *port)
+{
        struct whiteheat_simple get_dr_command;
 
        get_dr_command.port = port->number - port->serial->minor + 1;
-       return firm_send_command(port, WHITEHEAT_GET_DTR_RTS, (__u8 *)&get_dr_command, sizeof(get_dr_command));
+       return firm_send_command(port, WHITEHEAT_GET_DTR_RTS,
+                       (__u8 *)&get_dr_command, sizeof(get_dr_command));
 }
 
 
-static int firm_report_tx_done(struct usb_serial_port *port) {
+static int firm_report_tx_done(struct usb_serial_port *port)
+{
        struct whiteheat_simple close_command;
 
        close_command.port = port->number - port->serial->minor + 1;
-       return firm_send_command(port, WHITEHEAT_REPORT_TX_DONE, (__u8 *)&close_command, sizeof(close_command));
+       return firm_send_command(port, WHITEHEAT_REPORT_TX_DONE,
+                       (__u8 *)&close_command, sizeof(close_command));
 }
 
 
@@ -1319,7 +1372,7 @@ static int start_command_port(struct usb_serial *serial)
        struct usb_serial_port *command_port;
        struct whiteheat_command_private *command_info;
        int retval = 0;
-       
+
        command_port = serial->port[COMMAND_PORT];
        command_info = usb_get_serial_port_data(command_port);
        mutex_lock(&command_info->mutex);
@@ -1330,7 +1383,8 @@ static int start_command_port(struct usb_serial *serial)
                command_port->read_urb->dev = serial->dev;
                retval = usb_submit_urb(command_port->read_urb, GFP_KERNEL);
                if (retval) {
-                       err("%s - failed submitting read urb, error %d", __func__, retval);
+                       err("%s - failed submitting read urb, error %d",
+                                                       __func__, retval);
                        goto exit;
                }
        }
@@ -1400,7 +1454,8 @@ static int start_port_read(struct usb_serial_port *port)
 }
 
 
-static struct whiteheat_urb_wrap *urb_to_wrap(struct urb* urb, struct list_head *head)
+static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
+                                               struct list_head *head)
 {
        struct whiteheat_urb_wrap *wrap;
        struct list_head *tmp;
@@ -1426,7 +1481,7 @@ static void rx_data_softint(struct work_struct *work)
        struct whiteheat_private *info =
                container_of(work, struct whiteheat_private, rx_work);
        struct usb_serial_port *port = info->port;
-       struct tty_struct *tty = port->tty;
+       struct tty_struct *tty = port->port.tty;
        struct whiteheat_urb_wrap *wrap;
        struct urb *urb;
        unsigned long flags;
@@ -1449,7 +1504,8 @@ static void rx_data_softint(struct work_struct *work)
                urb = wrap->urb;
 
                if (tty && urb->actual_length) {
-                       int len = tty_buffer_request_room(tty, urb->actual_length);
+                       int len = tty_buffer_request_room(tty,
+                                                       urb->actual_length);
                        /* This stuff can go away now I suspect */
                        if (unlikely(len < urb->actual_length)) {
                                spin_lock_irqsave(&info->lock, flags);
@@ -1466,7 +1522,8 @@ static void rx_data_softint(struct work_struct *work)
                urb->dev = port->serial->dev;
                result = usb_submit_urb(urb, GFP_ATOMIC);
                if (result) {
-                       err("%s - failed resubmitting read urb, error %d", __func__, result);
+                       err("%s - failed resubmitting read urb, error %d",
+                               __func__, result);
                        spin_lock_irqsave(&info->lock, flags);
                        list_add(tmp, &info->rx_urbs_free);
                        continue;
@@ -1485,7 +1542,7 @@ static void rx_data_softint(struct work_struct *work)
 /*****************************************************************************
  * Connect Tech's White Heat module functions
  *****************************************************************************/
-static int __init whiteheat_init (void)
+static int __init whiteheat_init(void)
 {
        int retval;
        retval = usb_serial_register(&whiteheat_fake_device);
@@ -1508,19 +1565,19 @@ failed_fake_register:
 }
 
 
-static void __exit whiteheat_exit (void)
+static void __exit whiteheat_exit(void)
 {
-       usb_deregister (&whiteheat_driver);
-       usb_serial_deregister (&whiteheat_fake_device);
-       usb_serial_deregister (&whiteheat_device);
+       usb_deregister(&whiteheat_driver);
+       usb_serial_deregister(&whiteheat_fake_device);
+       usb_serial_deregister(&whiteheat_device);
 }
 
 
 module_init(whiteheat_init);
 module_exit(whiteheat_exit);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
 MODULE_FIRMWARE("whiteheat.fw");
index f16079705664b8b43a594585c7df06feedf8c257..38065df4d2d8217f10f24cf552127597411768b9 100644 (file)
@@ -2,7 +2,7 @@
  * USB ConnectTech WhiteHEAT driver
  *
  *      Copyright (C) 2002
- *          Connect Tech Inc.  
+ *          Connect Tech Inc.
  *
  *      Copyright (C) 1999, 2000
  *          Greg Kroah-Hartman (greg@kroah.com)
@@ -12,7 +12,8 @@
  *      the Free Software Foundation; either version 2 of the License, or
  *      (at your option) any later version.
  *
- * See Documentation/usb/usb-serial.txt for more information on using this driver
+ * See Documentation/usb/usb-serial.txt for more information on using this
+ * driver
  *
  */
 
 #define WHITEHEAT_DUMP                 7       /* dump memory */
 #define WHITEHEAT_STATUS               8       /* get status */
 #define WHITEHEAT_PURGE                        9       /* clear the UART fifos */
-#define WHITEHEAT_GET_DTR_RTS          10      /* get the state of DTR and RTS for a port */
-#define WHITEHEAT_GET_HW_INFO          11      /* get EEPROM info and hardware ID */
+#define WHITEHEAT_GET_DTR_RTS          10      /* get the state of DTR and RTS
+                                                       for a port */
+#define WHITEHEAT_GET_HW_INFO          11      /* get EEPROM info and
+                                                       hardware ID */
 #define WHITEHEAT_REPORT_TX_DONE       12      /* get the next TX done */
 #define WHITEHEAT_EVENT                        13      /* unsolicited status events */
-#define WHITEHEAT_ECHO                 14      /* send data to the indicated IN endpoint */
-#define WHITEHEAT_DO_TEST              15      /* perform the specified test */
-#define WHITEHEAT_CMD_COMPLETE         16      /* reply for certain commands */
+#define WHITEHEAT_ECHO                 14      /* send data to the indicated
+                                                  IN endpoint */
+#define WHITEHEAT_DO_TEST              15      /* perform specified test */
+#define WHITEHEAT_CMD_COMPLETE         16      /* reply for some commands */
 #define WHITEHEAT_CMD_FAILURE          17      /* reply for failed commands */
 
 
@@ -67,20 +71,28 @@ struct whiteheat_simple {
 #define WHITEHEAT_PAR_MARK     '1'     /* mark (force 1) parity */
 
 #define WHITEHEAT_SFLOW_NONE   'n'     /* no software flow control */
-#define WHITEHEAT_SFLOW_RX     'r'     /* XOFF/ON is sent when RX fills/empties */
-#define WHITEHEAT_SFLOW_TX     't'     /* when received XOFF/ON will stop/start TX */
+#define WHITEHEAT_SFLOW_RX     'r'     /* XOFF/ON is sent when RX
+                                          fills/empties */
+#define WHITEHEAT_SFLOW_TX     't'     /* when received XOFF/ON will
+                                          stop/start TX */
 #define WHITEHEAT_SFLOW_RXTX   'b'     /* both SFLOW_RX and SFLOW_TX */
 
 #define WHITEHEAT_HFLOW_NONE           0x00    /* no hardware flow control */
-#define WHITEHEAT_HFLOW_RTS_TOGGLE     0x01    /* RTS is on during transmit, off otherwise */
-#define WHITEHEAT_HFLOW_DTR            0x02    /* DTR is off/on when RX fills/empties */
-#define WHITEHEAT_HFLOW_CTS            0x08    /* when received CTS off/on will stop/start TX */
-#define WHITEHEAT_HFLOW_DSR            0x10    /* when received DSR off/on will stop/start TX */
-#define WHITEHEAT_HFLOW_RTS            0x80    /* RTS is off/on when RX fills/empties */
+#define WHITEHEAT_HFLOW_RTS_TOGGLE     0x01    /* RTS is on during transmit,
+                                                  off otherwise */
+#define WHITEHEAT_HFLOW_DTR            0x02    /* DTR is off/on when RX
+                                                  fills/empties */
+#define WHITEHEAT_HFLOW_CTS            0x08    /* when received CTS off/on
+                                                  will stop/start TX */
+#define WHITEHEAT_HFLOW_DSR            0x10    /* when received DSR off/on
+                                                  will stop/start TX */
+#define WHITEHEAT_HFLOW_RTS            0x80    /* RTS is off/on when RX
+                                                  fills/empties */
 
 struct whiteheat_port_settings {
        __u8    port;           /* port number (1 to N) */
-       __u32   baud;           /* any value 7 - 460800, firmware calculates best fit; arrives little endian */
+       __u32   baud;           /* any value 7 - 460800, firmware calculates
+                                  best fit; arrives little endian */
        __u8    bits;           /* 5, 6, 7, or 8 */
        __u8    stop;           /* 1 or 2, default 1 (2 = 1.5 if bits = 5) */
        __u8    parity;         /* see WHITEHEAT_PAR_* above */
@@ -167,12 +179,14 @@ struct whiteheat_echo {
  */
 #define WHITEHEAT_TEST_UART_RW         0x01  /* read/write uart registers */
 #define WHITEHEAT_TEST_UART_INTR       0x02  /* uart interrupt */
-#define WHITEHEAT_TEST_SETUP_CONT      0x03  /* setup for PORT_CONT/PORT_DISCONT */
+#define WHITEHEAT_TEST_SETUP_CONT      0x03  /* setup for
+                                               PORT_CONT/PORT_DISCONT */
 #define WHITEHEAT_TEST_PORT_CONT       0x04  /* port connect */
 #define WHITEHEAT_TEST_PORT_DISCONT    0x05  /* port disconnect */
 #define WHITEHEAT_TEST_UART_CLK_START  0x06  /* uart clock test start */
 #define WHITEHEAT_TEST_UART_CLK_STOP   0x07  /* uart clock test stop */
-#define WHITEHEAT_TEST_MODEM_FT                0x08  /* modem signals, requires a loopback cable/connector */
+#define WHITEHEAT_TEST_MODEM_FT                0x08  /* modem signals, requires a
+                                               loopback cable/connector */
 #define WHITEHEAT_TEST_ERASE_EEPROM    0x09  /* erase eeprom */
 #define WHITEHEAT_TEST_READ_EEPROM     0x0a  /* read eeprom */
 #define WHITEHEAT_TEST_PROGRAM_EEPROM  0x0b  /* program eeprom */
@@ -198,19 +212,27 @@ struct whiteheat_test {
 #define WHITEHEAT_EVENT_CONNECT                0x08    /* connect field is valid */
 
 #define WHITEHEAT_FLOW_NONE            0x00    /* no flow control active */
-#define WHITEHEAT_FLOW_HARD_OUT                0x01    /* TX is stopped by CTS (waiting for CTS to go on) */
-#define WHITEHEAT_FLOW_HARD_IN         0x02    /* remote TX is stopped by RTS */
-#define WHITEHEAT_FLOW_SOFT_OUT                0x04    /* TX is stopped by XOFF received (waiting for XON) */
-#define WHITEHEAT_FLOW_SOFT_IN         0x08    /* remote TX is stopped by XOFF transmitted */
+#define WHITEHEAT_FLOW_HARD_OUT                0x01    /* TX is stopped by CTS
+                                                 (waiting for CTS to go on) */
+#define WHITEHEAT_FLOW_HARD_IN         0x02    /* remote TX is stopped
+                                                 by RTS */
+#define WHITEHEAT_FLOW_SOFT_OUT                0x04    /* TX is stopped by XOFF
+                                                 received (waiting for XON) */
+#define WHITEHEAT_FLOW_SOFT_IN         0x08    /* remote TX is stopped by XOFF
+                                                 transmitted */
 #define WHITEHEAT_FLOW_TX_DONE         0x80    /* TX has completed */
 
 struct whiteheat_status_info {
        __u8    port;           /* port number (1 to N) */
-       __u8    event;          /* indicates what the current event is, see WHITEHEAT_EVENT_* above */
-       __u8    modem;          /* modem signal status (copy of uart's MSR register) */
+       __u8    event;          /* indicates what the current event is,
+                                       see WHITEHEAT_EVENT_* above */
+       __u8    modem;          /* modem signal status (copy of uart's
+                                       MSR register) */
        __u8    error;          /* line status (copy of uart's LSR register) */
-       __u8    flow;           /* flow control state, see WHITEHEAT_FLOW_* above */
-       __u8    connect;        /* 0 means not connected, non-zero means connected */
+       __u8    flow;           /* flow control state, see WHITEHEAT_FLOW_*
+                                       above */
+       __u8    connect;        /* 0 means not connected, non-zero means
+                                       connected */
 };
 
 
@@ -256,7 +278,8 @@ struct whiteheat_hw_info {
 struct whiteheat_event_info {
        __u8    port;           /* port number (1 to N) */
        __u8    event;          /* see whiteheat_status_info.event */
-       __u8    info;           /* see whiteheat_status_info.modem, .error, .flow, .connect */
+       __u8    info;           /* see whiteheat_status_info.modem, .error,
+                                       .flow, .connect */
 };
 
 
@@ -269,7 +292,8 @@ struct whiteheat_event_info {
 
 struct whiteheat_test_info {
        __u8    port;           /* port number (1 to N) */
-       __u8    test;           /* indicates which test this is a response for, see WHITEHEAT_DO_TEST above */
+       __u8    test;           /* indicates which test this is a response for,
+                                  see WHITEHEAT_DO_TEST above */
        __u8    status;         /* see WHITEHEAT_TEST_* above */
        __u8    results[32];    /* test-dependent results */
 };
index 579e9f52053adac18b5720271b4e443cc3e18821..17f1ae232919ebc5123e778f6c10d404f7651d49 100644 (file)
@@ -1,6 +1,4 @@
 /* Driver for Datafab USB Compact Flash reader
- *
- * $Id: datafab.c,v 1.7 2002/02/25 00:40:13 mdharm Exp $
  *
  * datafab driver v0.1:
  *
index 01e430654a131a5a353afd09c8639f6ddeb6cedb..a2b5526c9fa09e742e6d34969326af6b3712214f 100644 (file)
@@ -1,8 +1,6 @@
 /* Driver for USB Mass Storage compliant devices
  * Debugging Functions Source Code File
  *
- * $Id: debug.c,v 1.9 2002/04/22 03:39:43 mdharm Exp $
- *
  * Current development and maintenance by:
  *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
index 77e244a8c37662c8db8773acc7c52802e7d224c8..dbb985d52423f33d4a997ee2835ab8e93a9617a4 100644 (file)
@@ -1,8 +1,6 @@
 /* Driver for USB Mass Storage compliant devices
  * Debugging Functions Header File
  *
- * $Id: debug.h,v 1.6 2001/01/12 23:51:04 mdharm Exp $
- *
  * Current development and maintenance by:
  *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
index 9a410b5a6e5b06e946cbf3865faa9961b37cd3a6..939923471af4015b2454aef692d041774d1a50f5 100644 (file)
@@ -1,6 +1,4 @@
 /* Driver for Microtech DPCM-USB CompactFlash/SmartMedia reader
- *
- * $Id: dpcm.c,v 1.4 2001/06/11 02:54:25 mdharm Exp $
  *
  * DPCM driver v0.1:
  *
index 81b464cfcc1e63f458b41142210d93845bf979cf..e7b7b0f120d795385ff4cf420bdc3393448fadd2 100644 (file)
@@ -1,6 +1,4 @@
 /* Driver for Microtech DPCM-USB CompactFlash/SmartMedia reader
- *
- * $Id: dpcm.h,v 1.2 2000/08/25 00:13:51 mdharm Exp $
  *
  * DPCM driver v0.1:
  *
index f5a4e8d6a3b1460274eb551343982f071e16ab0b..7a4d456772278c6ebfd146d57f830ad0518319a9 100644 (file)
@@ -1,6 +1,4 @@
 /* Driver for Freecom USB/IDE adaptor
- *
- * $Id: freecom.c,v 1.22 2002/04/22 03:39:43 mdharm Exp $
  *
  * Freecom v0.1:
  *
index 1b012d62d0a8a27104bdef4830d9ae4a265c9e45..20d0fe6ba0c89f4c3af6fed1032767522a6cac33 100644 (file)
@@ -1,6 +1,4 @@
 /* Driver for Freecom USB/IDE adaptor
- *
- * $Id: freecom.h,v 1.4 2000/08/29 14:49:15 dlbrown Exp $
  *
  * Freecom v0.1:
  *
index 187dd1e01093584c47d9da7f7c22f0f596a37c3c..4995bb595aef027367134f7043edab080128a52f 100644 (file)
@@ -1,6 +1,4 @@
 /* Special Initializers for certain USB Mass Storage devices
- *
- * $Id: initializers.c,v 1.2 2000/09/06 22:35:57 mdharm Exp $
  *
  * Current development and maintenance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
index ad3ffd4236c2af961039f36e3943978ee07fd66a..529327fbb06be1b6876e8802b84bd281287291c3 100644 (file)
@@ -1,6 +1,4 @@
 /* Header file for Special Initializers for certain USB Mass Storage devices
- *
- * $Id: initializers.h,v 1.1 2000/08/29 23:07:02 mdharm Exp $
  *
  * Current development and maintenance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
index 3addcd8f827bd3d17463dbc67395c072cfae4d81..383abf2516a520a6756c99349a854fb9ee89a2ab 100644 (file)
@@ -1,6 +1,4 @@
 /* Transport & Protocol Driver for In-System Design, Inc. ISD200 ASIC
- *
- * $Id: isd200.c,v 1.16 2002/04/22 03:39:43 mdharm Exp $
  *
  * Current development and maintenance:
  *   (C) 2001-2002 Björn Stenberg (bjorn@haxx.se)
@@ -586,7 +584,7 @@ static void isd200_invoke_transport( struct us_data *us,
        /* if the command gets aborted by the higher layers, we need to
         * short-circuit all other processing
         */
-       if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) {
+       if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
                US_DEBUGP("-- command was aborted\n");
                goto Handle_Abort;
        }
@@ -633,7 +631,7 @@ static void isd200_invoke_transport( struct us_data *us,
 
        if (need_auto_sense) {
                result = isd200_read_regs(us);
-               if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) {
+               if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
                        US_DEBUGP("-- auto-sense aborted\n");
                        goto Handle_Abort;
                }
@@ -663,7 +661,7 @@ static void isd200_invoke_transport( struct us_data *us,
        srb->result = DID_ABORT << 16;
 
        /* permit the reset transfer to take place */
-       clear_bit(US_FLIDX_ABORTING, &us->flags);
+       clear_bit(US_FLIDX_ABORTING, &us->dflags);
        /* Need reset here */
 }
 
index 61097cbb1585047e6893a8f59aec52de4771afdc..df67f13c9e73ebcc3dc85a8d354acd0568d7e145 100644 (file)
@@ -1,6 +1,4 @@
 /* Driver for Lexar "Jumpshot" Compact Flash reader
- *
- * $Id: jumpshot.c,v 1.7 2002/02/25 00:40:13 mdharm Exp $
  *
  * jumpshot driver v0.1:
  *
index b9b8ede61fb337bf4927ef2638640bc6723d8102..3b3357e20ea70ba6b8a802204211bb6fadf47db1 100644 (file)
@@ -1,6 +1,4 @@
 /* Driver for USB Mass Storage compliant devices
- *
- * $Id: protocol.c,v 1.14 2002/04/22 03:39:43 mdharm Exp $
  *
  * Current development and maintenance by:
  *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
index 8737a36891caa6514d6ab8f01f04600774f7d731..487056ffb516df3c00480113dd0ba5d8b80e8cb2 100644 (file)
@@ -1,8 +1,6 @@
 /* Driver for USB Mass Storage compliant devices
  * Protocol Functions Header File
  *
- * $Id: protocol.h,v 1.4 2001/02/13 07:10:03 mdharm Exp $
- *
  * Current development and maintenance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
index 3fcde9f0fa5fe64df4484fbcb068b5109b858650..09779f6a8179944c922b9e5d7c43b1839c5fbc06 100644 (file)
@@ -1,8 +1,6 @@
 /* Driver for USB Mass Storage compliant devices
  * SCSI layer glue code
  *
- * $Id: scsiglue.c,v 1.26 2002/04/22 03:39:43 mdharm Exp $
- *
  * Current development and maintenance by:
  *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
@@ -73,7 +71,6 @@ static const char* host_info(struct Scsi_Host *host)
 static int slave_alloc (struct scsi_device *sdev)
 {
        struct us_data *us = host_to_us(sdev->host);
-       struct usb_host_endpoint *bulk_in_ep;
 
        /*
         * Set the INQUIRY transfer length to 36.  We don't use any of
@@ -82,16 +79,22 @@ static int slave_alloc (struct scsi_device *sdev)
         */
        sdev->inquiry_len = 36;
 
-       /* Scatter-gather buffers (all but the last) must have a length
-        * divisible by the bulk maxpacket size.  Otherwise a data packet
-        * would end up being short, causing a premature end to the data
-        * transfer.  We'll use the maxpacket value of the bulk-IN pipe
-        * to set the SCSI device queue's DMA alignment mask.
+       /* USB has unusual DMA-alignment requirements: Although the
+        * starting address of each scatter-gather element doesn't matter,
+        * the length of each element except the last must be divisible
+        * by the Bulk maxpacket value.  There's currently no way to
+        * express this by block-layer constraints, so we'll cop out
+        * and simply require addresses to be aligned at 512-byte
+        * boundaries.  This is okay since most block I/O involves
+        * hardware sectors that are multiples of 512 bytes in length,
+        * and since host controllers up through USB 2.0 have maxpacket
+        * values no larger than 512.
+        *
+        * But it doesn't suffice for Wireless USB, where Bulk maxpacket
+        * values can be as large as 2048.  To make that work properly
+        * will require changes to the block layer.
         */
-       bulk_in_ep = us->pusb_dev->ep_in[usb_pipeendpoint(us->recv_bulk_pipe)];
-       blk_queue_update_dma_alignment(sdev->request_queue,
-                       le16_to_cpu(bulk_in_ep->desc.wMaxPacketSize) - 1);
-                       /* wMaxPacketSize must be a power of 2 */
+       blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1));
 
        /*
         * The UFI spec treates the Peripheral Qualifier bits in an
@@ -116,10 +119,10 @@ static int slave_configure(struct scsi_device *sdev)
         * while others have trouble with more than 64K. At this time we
         * are limiting both to 32K (64 sectores).
         */
-       if (us->flags & (US_FL_MAX_SECTORS_64 | US_FL_MAX_SECTORS_MIN)) {
+       if (us->fflags & (US_FL_MAX_SECTORS_64 | US_FL_MAX_SECTORS_MIN)) {
                unsigned int max_sectors = 64;
 
-               if (us->flags & US_FL_MAX_SECTORS_MIN)
+               if (us->fflags & US_FL_MAX_SECTORS_MIN)
                        max_sectors = PAGE_CACHE_SIZE >> 9;
                if (sdev->request_queue->max_sectors > max_sectors)
                        blk_queue_max_sectors(sdev->request_queue,
@@ -148,7 +151,7 @@ static int slave_configure(struct scsi_device *sdev)
                 * majority of devices work fine, but a few still can't
                 * handle it.  The sd driver will simply assume those
                 * devices are write-enabled. */
-               if (us->flags & US_FL_NO_WP_DETECT)
+               if (us->fflags & US_FL_NO_WP_DETECT)
                        sdev->skip_ms_page_3f = 1;
 
                /* A number of devices have problems with MODE SENSE for
@@ -158,13 +161,13 @@ static int slave_configure(struct scsi_device *sdev)
                /* Some disks return the total number of blocks in response
                 * to READ CAPACITY rather than the highest block number.
                 * If this device makes that mistake, tell the sd driver. */
-               if (us->flags & US_FL_FIX_CAPACITY)
+               if (us->fflags & US_FL_FIX_CAPACITY)
                        sdev->fix_capacity = 1;
 
                /* A few disks have two indistinguishable version, one of
                 * which reports the correct capacity and the other does not.
                 * The sd driver has to guess which is the case. */
-               if (us->flags & US_FL_CAPACITY_HEURISTICS)
+               if (us->fflags & US_FL_CAPACITY_HEURISTICS)
                        sdev->guess_capacity = 1;
 
                /* Some devices report a SCSI revision level above 2 but are
@@ -213,7 +216,7 @@ static int slave_configure(struct scsi_device *sdev)
 
        /* Some devices choke when they receive a PREVENT-ALLOW MEDIUM
         * REMOVAL command, so suppress those commands. */
-       if (us->flags & US_FL_NOT_LOCKABLE)
+       if (us->fflags & US_FL_NOT_LOCKABLE)
                sdev->lockable = 0;
 
        /* this is to satisfy the compiler, tho I don't think the 
@@ -238,7 +241,7 @@ static int queuecommand(struct scsi_cmnd *srb,
        }
 
        /* fail the command if we are disconnecting */
-       if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+       if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
                US_DEBUGP("Fail command during disconnect\n");
                srb->result = DID_NO_CONNECT << 16;
                done(srb);
@@ -248,7 +251,7 @@ static int queuecommand(struct scsi_cmnd *srb,
        /* enqueue the command and wake up the control thread */
        srb->scsi_done = done;
        us->srb = srb;
-       up(&(us->sema));
+       complete(&us->cmnd_ready);
 
        return 0;
 }
@@ -280,9 +283,9 @@ static int command_abort(struct scsi_cmnd *srb)
         * with the reset).  Note that we must retain the host lock while
         * calling usb_stor_stop_transport(); otherwise it might interfere
         * with an auto-reset that begins as soon as we release the lock. */
-       set_bit(US_FLIDX_TIMED_OUT, &us->flags);
-       if (!test_bit(US_FLIDX_RESETTING, &us->flags)) {
-               set_bit(US_FLIDX_ABORTING, &us->flags);
+       set_bit(US_FLIDX_TIMED_OUT, &us->dflags);
+       if (!test_bit(US_FLIDX_RESETTING, &us->dflags)) {
+               set_bit(US_FLIDX_ABORTING, &us->dflags);
                usb_stor_stop_transport(us);
        }
        scsi_unlock(us_to_host(us));
@@ -329,7 +332,7 @@ void usb_stor_report_device_reset(struct us_data *us)
        struct Scsi_Host *host = us_to_host(us);
 
        scsi_report_device_reset(host, 0, 0);
-       if (us->flags & US_FL_SCM_MULT_TARG) {
+       if (us->fflags & US_FL_SCM_MULT_TARG) {
                for (i = 1; i < host->max_id; ++i)
                        scsi_report_device_reset(host, 0, i);
        }
@@ -400,7 +403,7 @@ static int proc_info (struct Scsi_Host *host, char *buffer,
                pos += sprintf(pos, "       Quirks:");
 
 #define US_FLAG(name, value) \
-       if (us->flags & value) pos += sprintf(pos, " " #name);
+       if (us->fflags & value) pos += sprintf(pos, " " #name);
 US_DO_ALL_FLAGS
 #undef US_FLAG
 
index 737e4fa6045f8395aa6bf26759adefc03a72555c..ffa1cca93d2cfc2c20bb9c44e57cec9bb0b4bb2b 100644 (file)
@@ -1,8 +1,6 @@
 /* Driver for USB Mass Storage compliant devices
  * SCSI Connecting Glue Header File
  *
- * $Id: scsiglue.h,v 1.4 2000/08/25 00:13:51 mdharm Exp $
- *
  * Current development and maintenance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
index 8972b17da843d219e798199fdb056f8d150714a1..c5a54b872c2426cae14927264558eb99f17987d6 100644 (file)
@@ -1,6 +1,5 @@
 /* Driver for SanDisk SDDR-09 SmartMedia reader
  *
- * $Id: sddr09.c,v 1.24 2002/04/22 03:39:43 mdharm Exp $
  *   (c) 2000, 2001 Robert Baruch (autophile@starband.net)
  *   (c) 2002 Andries Brouwer (aeb@cwi.nl)
  * Developed with the assistance of:
index c03089a9ec3899b33e6582852b41e6bcd4127488..e50033ad7b195be471c5a3ad5ad949018621dde2 100644 (file)
@@ -1,8 +1,6 @@
 /* Driver for SanDisk SDDR-09 SmartMedia reader
  * Header File
  *
- * $Id: sddr09.h,v 1.5 2000/08/25 00:13:51 mdharm Exp $
- *
  * Current development and maintenance by:
  *   (c) 2000 Robert Baruch (autophile@dol.net)
  *   (c) 2002 Andries Brouwer (aeb@cwi.nl)
index 6d14327c921d2e2be47cb3370ca9a2a1a349c9fb..0d8df7577899e3c3d7de0e580e54fee0889fd57e 100644 (file)
@@ -1,6 +1,4 @@
 /* Driver for SanDisk SDDR-55 SmartMedia reader
- *
- * $Id:$
  *
  * SDDR55 driver v0.1:
  *
index d6bd32f6c9f3d5ca3e341d283fe44e14cdb95dfb..a815a0470c84707bd14b47f32cc2502e84fd5e7d 100644 (file)
@@ -1,8 +1,6 @@
 /* Driver for SanDisk SDDR-55 SmartMedia reader
  * Header File
  *
- * $Id:$
- *
  * Current development and maintenance by:
  *   (c) 2002 Simon Munton
  *
index 570c1250f6f320e46284e7fa1554875d2d753982..ae6d64810d2a9d4cc8fc9db09fd68047136df801 100644 (file)
@@ -1,6 +1,4 @@
 /* Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable
- *
- * $Id: shuttle_usbat.c,v 1.17 2002/04/22 03:39:43 mdharm Exp $
  *
  * Current development and maintenance by:
  *   (c) 2000, 2001 Robert Baruch (autophile@starband.net)
index 3ddf143a1dec25c05a805c0fd33f625a51a21326..d8bfc43e9044dfa0aeb63f5cec52e2548b2cb552 100644 (file)
@@ -1,8 +1,6 @@
 /* Driver for SCM Microsystems USB-ATAPI cable
  * Header File
  *
- * $Id: shuttle_usbat.h,v 1.5 2000/09/17 14:44:52 groovyjava Exp $
- *
  * Current development and maintenance by:
  *   (c) 2000 Robert Baruch (autophile@dol.net)
  *   (c) 2004, 2005 Daniel Drake <dsd@gentoo.org>
index 6610d2dd1e7f4f099261788321765b486300ca47..fcbbfdb7b2b0298edc3625ff6987b99be36a1b58 100644 (file)
@@ -1,6 +1,4 @@
 /* Driver for USB Mass Storage compliant devices
- *
- * $Id: transport.c,v 1.47 2002/04/22 03:39:43 mdharm Exp $
  *
  * Current development and maintenance by:
  *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  * by a separate code path.)
  *
  * The abort function (usb_storage_command_abort() in scsiglue.c) first
- * sets the machine state and the ABORTING bit in us->flags to prevent
+ * sets the machine state and the ABORTING bit in us->dflags to prevent
  * new URBs from being submitted.  It then calls usb_stor_stop_transport()
- * below, which atomically tests-and-clears the URB_ACTIVE bit in us->flags
+ * below, which atomically tests-and-clears the URB_ACTIVE bit in us->dflags
  * to see if the current_urb needs to be stopped.  Likewise, the SG_ACTIVE
  * bit is tested to see if the current_sg scatter-gather request needs to be
  * stopped.  The timeout callback routine does much the same thing.
  *
- * When a disconnect occurs, the DISCONNECTING bit in us->flags is set to
+ * When a disconnect occurs, the DISCONNECTING bit in us->dflags is set to
  * prevent new URBs from being submitted, and usb_stor_stop_transport() is
  * called to stop any ongoing requests.
  *
@@ -127,8 +125,8 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
        long timeleft;
        int status;
 
-       /* don't submit URBs during abort/disconnect processing */
-       if (us->flags & ABORTING_OR_DISCONNECTING)
+       /* don't submit URBs during abort processing */
+       if (test_bit(US_FLIDX_ABORTING, &us->dflags))
                return -EIO;
 
        /* set up data structures for the wakeup system */
@@ -159,13 +157,13 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
 
        /* since the URB has been submitted successfully, it's now okay
         * to cancel it */
-       set_bit(US_FLIDX_URB_ACTIVE, &us->flags);
+       set_bit(US_FLIDX_URB_ACTIVE, &us->dflags);
 
-       /* did an abort/disconnect occur during the submission? */
-       if (us->flags & ABORTING_OR_DISCONNECTING) {
+       /* did an abort occur during the submission? */
+       if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {
 
                /* cancel the URB, if it hasn't been cancelled already */
-               if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->flags)) {
+               if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) {
                        US_DEBUGP("-- cancelling URB\n");
                        usb_unlink_urb(us->current_urb);
                }
@@ -175,7 +173,7 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
        timeleft = wait_for_completion_interruptible_timeout(
                        &urb_done, timeout ? : MAX_SCHEDULE_TIMEOUT);
  
-       clear_bit(US_FLIDX_URB_ACTIVE, &us->flags);
+       clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags);
 
        if (timeleft <= 0) {
                US_DEBUGP("%s -- cancelling URB\n",
@@ -419,8 +417,8 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
 {
        int result;
 
-       /* don't submit s-g requests during abort/disconnect processing */
-       if (us->flags & ABORTING_OR_DISCONNECTING)
+       /* don't submit s-g requests during abort processing */
+       if (test_bit(US_FLIDX_ABORTING, &us->dflags))
                return USB_STOR_XFER_ERROR;
 
        /* initialize the scatter-gather request block */
@@ -435,13 +433,13 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
 
        /* since the block has been initialized successfully, it's now
         * okay to cancel it */
-       set_bit(US_FLIDX_SG_ACTIVE, &us->flags);
+       set_bit(US_FLIDX_SG_ACTIVE, &us->dflags);
 
-       /* did an abort/disconnect occur during the submission? */
-       if (us->flags & ABORTING_OR_DISCONNECTING) {
+       /* did an abort occur during the submission? */
+       if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {
 
                /* cancel the request, if it hasn't been cancelled already */
-               if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) {
+               if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) {
                        US_DEBUGP("-- cancelling sg request\n");
                        usb_sg_cancel(&us->current_sg);
                }
@@ -449,7 +447,7 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
 
        /* wait for the completion of the transfer */
        usb_sg_wait(&us->current_sg);
-       clear_bit(US_FLIDX_SG_ACTIVE, &us->flags);
+       clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags);
 
        result = us->current_sg.status;
        if (act_len)
@@ -530,7 +528,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
        /* if the command gets aborted by the higher layers, we need to
         * short-circuit all other processing
         */
-       if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) {
+       if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
                US_DEBUGP("-- command was aborted\n");
                srb->result = DID_ABORT << 16;
                goto Handle_Errors;
@@ -616,7 +614,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
                /* let's clean up right away */
                scsi_eh_restore_cmnd(srb, &ses);
 
-               if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) {
+               if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
                        US_DEBUGP("-- auto-sense aborted\n");
                        srb->result = DID_ABORT << 16;
                        goto Handle_Errors;
@@ -629,7 +627,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
                         * auto-sense is perfectly valid
                         */
                        srb->result = DID_ERROR << 16;
-                       if (!(us->flags & US_FL_SCM_MULT_TARG))
+                       if (!(us->fflags & US_FL_SCM_MULT_TARG))
                                goto Handle_Errors;
                        return;
                }
@@ -679,8 +677,8 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
        /* Set the RESETTING bit, and clear the ABORTING bit so that
         * the reset may proceed. */
        scsi_lock(us_to_host(us));
-       set_bit(US_FLIDX_RESETTING, &us->flags);
-       clear_bit(US_FLIDX_ABORTING, &us->flags);
+       set_bit(US_FLIDX_RESETTING, &us->dflags);
+       clear_bit(US_FLIDX_ABORTING, &us->dflags);
        scsi_unlock(us_to_host(us));
 
        /* We must release the device lock because the pre_reset routine
@@ -695,7 +693,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
                scsi_unlock(us_to_host(us));
                us->transport_reset(us);
        }
-       clear_bit(US_FLIDX_RESETTING, &us->flags);
+       clear_bit(US_FLIDX_RESETTING, &us->dflags);
 }
 
 /* Stop the current URB transfer */
@@ -707,13 +705,13 @@ void usb_stor_stop_transport(struct us_data *us)
         * let's wake it up.  The test_and_clear_bit() call
         * guarantees that if a URB has just been submitted,
         * it won't be cancelled more than once. */
-       if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->flags)) {
+       if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) {
                US_DEBUGP("-- cancelling URB\n");
                usb_unlink_urb(us->current_urb);
        }
 
        /* If we are waiting for a scatter-gather operation, cancel it. */
-       if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) {
+       if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) {
                US_DEBUGP("-- cancelling sg request\n");
                usb_sg_cancel(&us->current_sg);
        }
@@ -914,7 +912,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
        unsigned int cbwlen = US_BULK_CB_WRAP_LEN;
 
        /* Take care of BULK32 devices; set extra byte to 0 */
-       if ( unlikely(us->flags & US_FL_BULK32)) {
+       if (unlikely(us->fflags & US_FL_BULK32)) {
                cbwlen = 32;
                us->iobuf[31] = 0;
        }
@@ -925,7 +923,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
        bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? 1 << 7 : 0;
        bcb->Tag = ++us->tag;
        bcb->Lun = srb->device->lun;
-       if (us->flags & US_FL_SCM_MULT_TARG)
+       if (us->fflags & US_FL_SCM_MULT_TARG)
                bcb->Lun |= srb->device->id << 4;
        bcb->Length = srb->cmd_len;
 
@@ -951,7 +949,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
        /* Some USB-IDE converter chips need a 100us delay between the
         * command phase and the data phase.  Some devices need a little
         * more than that, probably because of clock rate inaccuracies. */
-       if (unlikely(us->flags & US_FL_GO_SLOW))
+       if (unlikely(us->fflags & US_FL_GO_SLOW))
                udelay(125);
 
        if (transfer_length) {
@@ -1010,7 +1008,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
        US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
                        le32_to_cpu(bcs->Signature), bcs->Tag, 
                        residue, bcs->Status);
-       if (!(bcs->Tag == us->tag || (us->flags & US_FL_BULK_IGNORE_TAG)) ||
+       if (!(bcs->Tag == us->tag || (us->fflags & US_FL_BULK_IGNORE_TAG)) ||
                bcs->Status > US_BULK_STAT_PHASE) {
                US_DEBUGP("Bulk logical error\n");
                return USB_STOR_TRANSPORT_ERROR;
@@ -1035,7 +1033,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
        /* try to compute the actual residue, based on how much data
         * was really transferred and what the device tells us */
        if (residue) {
-               if (!(us->flags & US_FL_IGNORE_RESIDUE)) {
+               if (!(us->fflags & US_FL_IGNORE_RESIDUE)) {
                        residue = min(residue, transfer_length);
                        scsi_set_resid(srb, max(scsi_get_resid(srb),
                                                               (int) residue));
@@ -1090,7 +1088,7 @@ static int usb_stor_reset_common(struct us_data *us,
        int result;
        int result2;
 
-       if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+       if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
                US_DEBUGP("No reset during disconnect\n");
                return -EIO;
        }
@@ -1103,12 +1101,12 @@ static int usb_stor_reset_common(struct us_data *us,
                return result;
        }
 
-       /* Give the device some time to recover from the reset,
-        * but don't delay disconnect processing. */
-       wait_event_interruptible_timeout(us->delay_wait,
-                       test_bit(US_FLIDX_DISCONNECTING, &us->flags),
-                       HZ*6);
-       if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+       /* Give the device some time to recover from the reset,
+        * but don't delay disconnect processing. */
+       wait_event_interruptible_timeout(us->delay_wait,
+                       test_bit(US_FLIDX_DISCONNECTING, &us->dflags),
+                       HZ*6);
+       if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
                US_DEBUGP("Reset interrupted by disconnect\n");
                return -EIO;
        }
@@ -1170,13 +1168,12 @@ int usb_stor_port_reset(struct us_data *us)
                US_DEBUGP("unable to lock device for reset: %d\n", result);
        else {
                /* Were we disconnected while waiting for the lock? */
-               if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+               if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
                        result = -EIO;
                        US_DEBUGP("No reset during disconnect\n");
                } else {
-                       result = usb_reset_composite_device(
-                                       us->pusb_dev, us->pusb_intf);
-                       US_DEBUGP("usb_reset_composite_device returns %d\n",
+                       result = usb_reset_device(us->pusb_dev);
+                       US_DEBUGP("usb_reset_device returns %d\n",
                                        result);
                }
                if (rc_lock)
index ada7c2f43f8475552d735734f85bfda0a051e95a..e70b88182f0ee8713f0f0676c879252b6b8d379e 100644 (file)
@@ -1,8 +1,6 @@
 /* Driver for USB Mass Storage compliant devices
  * Transport Functions Header File
  *
- * $Id: transport.h,v 1.18 2002/04/21 02:57:59 mdharm Exp $
- *
  * Current development and maintenance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
index 39a7c11795c49bbce9a320eff2189de7cc63eb07..7ae69f55aa966a72fd68d7cda7330d11f2e3a9e1 100644 (file)
@@ -1,8 +1,6 @@
 /* Driver for USB Mass Storage compliant devices
  * Unusual Devices File
  *
- * $Id: unusual_devs.h,v 1.32 2002/02/25 02:41:24 mdharm Exp $
- *
  * Current development and maintenance by:
  *   (c) 2000-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
@@ -1234,6 +1232,17 @@ UNUSUAL_DEV(  0x0851, 0x1543, 0x0200, 0x0200,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_NOT_LOCKABLE),
 
+/* Andrew Lunn <andrew@lunn.ch>
+ * PanDigital Digital Picture Frame. Does not like ALLOW_MEDIUM_REMOVAL
+ * on LUN 4.
+ * Note: Vend:Prod clash with "Ltd Maxell WS30 Slim Digital Camera"
+*/
+UNUSUAL_DEV(  0x0851, 0x1543, 0x0200, 0x0200,
+               "PanDigital",
+               "Photo Frame",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_NOT_LOCKABLE),
+
 /* Submitted by Jan De Luyck <lkml@kcore.org> */
 UNUSUAL_DEV(  0x08bd, 0x1100, 0x0000, 0x0000,
                "CITIZEN",
index e268aacb773a57e5041aac509389543b853614a0..bfea851be9850ff9662e9f2c647f196db18bdffc 100644 (file)
@@ -1,6 +1,4 @@
 /* Driver for USB Mass Storage compliant devices
- *
- * $Id: usb.c,v 1.75 2002/04/22 03:39:43 mdharm Exp $
  *
  * Current development and maintenance by:
  *   (c) 1999-2003 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
@@ -312,26 +310,27 @@ static int usb_stor_control_thread(void * __us)
 
        for(;;) {
                US_DEBUGP("*** thread sleeping.\n");
-               if(down_interruptible(&us->sema))
+               if (wait_for_completion_interruptible(&us->cmnd_ready))
                        break;
-                       
+
                US_DEBUGP("*** thread awakened.\n");
 
                /* lock the device pointers */
                mutex_lock(&(us->dev_mutex));
 
-               /* if the device has disconnected, we are free to exit */
-               if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
-                       US_DEBUGP("-- exiting\n");
+               /* lock access to the state */
+               scsi_lock(host);
+
+               /* When we are called with no command pending, we're done */
+               if (us->srb == NULL) {
+                       scsi_unlock(host);
                        mutex_unlock(&us->dev_mutex);
+                       US_DEBUGP("-- exiting\n");
                        break;
                }
 
-               /* lock access to the state */
-               scsi_lock(host);
-
                /* has the command timed out *already* ? */
-               if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) {
+               if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
                        us->srb->result = DID_ABORT << 16;
                        goto SkipForAbort;
                }
@@ -350,7 +349,7 @@ static int usb_stor_control_thread(void * __us)
                 * the maximum known LUN
                 */
                else if (us->srb->device->id && 
-                               !(us->flags & US_FL_SCM_MULT_TARG)) {
+                               !(us->fflags & US_FL_SCM_MULT_TARG)) {
                        US_DEBUGP("Bad target number (%d:%d)\n",
                                  us->srb->device->id, us->srb->device->lun);
                        us->srb->result = DID_BAD_TARGET << 16;
@@ -365,7 +364,7 @@ static int usb_stor_control_thread(void * __us)
                /* Handle those devices which need us to fake 
                 * their inquiry data */
                else if ((us->srb->cmnd[0] == INQUIRY) &&
-                           (us->flags & US_FL_FIX_INQUIRY)) {
+                           (us->fflags & US_FL_FIX_INQUIRY)) {
                        unsigned char data_ptr[36] = {
                            0x00, 0x80, 0x02, 0x02,
                            0x1F, 0x00, 0x00, 0x00};
@@ -384,12 +383,8 @@ static int usb_stor_control_thread(void * __us)
                /* lock access to the state */
                scsi_lock(host);
 
-               /* did the command already complete because of a disconnect? */
-               if (!us->srb)
-                       ;               /* nothing to do */
-
                /* indicate that the command is done */
-               else if (us->srb->result != DID_ABORT << 16) {
+               if (us->srb->result != DID_ABORT << 16) {
                        US_DEBUGP("scsi cmd done, result=0x%x\n", 
                                   us->srb->result);
                        us->srb->scsi_done(us->srb);
@@ -403,12 +398,12 @@ SkipForAbort:
                 * the TIMED_OUT flag, not srb->result == DID_ABORT, because
                 * the timeout might have occurred after the command had
                 * already completed with a different result code. */
-               if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) {
+               if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
                        complete(&(us->notify));
 
                        /* Allow USB transfers to resume */
-                       clear_bit(US_FLIDX_ABORTING, &us->flags);
-                       clear_bit(US_FLIDX_TIMED_OUT, &us->flags);
+                       clear_bit(US_FLIDX_ABORTING, &us->dflags);
+                       clear_bit(US_FLIDX_TIMED_OUT, &us->dflags);
                }
 
                /* finished working on this command */
@@ -500,9 +495,9 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id)
        us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ?
                        idesc->bInterfaceProtocol :
                        unusual_dev->useTransport;
-       us->flags = USB_US_ORIG_FLAGS(id->driver_info);
+       us->fflags = USB_US_ORIG_FLAGS(id->driver_info);
 
-       if (us->flags & US_FL_IGNORE_DEVICE) {
+       if (us->fflags & US_FL_IGNORE_DEVICE) {
                printk(KERN_INFO USB_STORAGE "device ignored\n");
                return -ENODEV;
        }
@@ -512,7 +507,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id)
         * disable it if we're in full-speed
         */
        if (dev->speed != USB_SPEED_HIGH)
-               us->flags &= ~US_FL_GO_SLOW;
+               us->fflags &= ~US_FL_GO_SLOW;
 
        /* Log a message if a non-generic unusual_dev entry contains an
         * unnecessary subclass or protocol override.  This may stimulate
@@ -533,7 +528,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id)
                if (unusual_dev->useTransport != US_PR_DEVICE &&
                        us->protocol == idesc->bInterfaceProtocol)
                        msg += 2;
-               if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE))
+               if (msg >= 0 && !(us->fflags & US_FL_NEED_OVERRIDE))
                        printk(KERN_NOTICE USB_STORAGE "This device "
                                "(%04x,%04x,%04x S %02x P %02x)"
                                " has %s in unusual_devs.h (kernel"
@@ -663,7 +658,7 @@ static int get_transport(struct us_data *us)
        US_DEBUGP("Transport: %s\n", us->transport_name);
 
        /* fix for single-lun devices */
-       if (us->flags & US_FL_SINGLE_LUN)
+       if (us->fflags & US_FL_SINGLE_LUN)
                us->max_lun = 0;
        return 0;
 }
@@ -820,12 +815,11 @@ static void usb_stor_release_resources(struct us_data *us)
        US_DEBUGP("-- %s\n", __func__);
 
        /* Tell the control thread to exit.  The SCSI host must
-        * already have been removed so it won't try to queue
-        * any more commands.
+        * already have been removed and the DISCONNECTING flag set
+        * so that we won't accept any more commands.
         */
        US_DEBUGP("-- sending exit command to thread\n");
-       set_bit(US_FLIDX_DISCONNECTING, &us->flags);
-       up(&us->sema);
+       complete(&us->cmnd_ready);
        if (us->ctl_thread)
                kthread_stop(us->ctl_thread);
 
@@ -859,39 +853,36 @@ static void dissociate_dev(struct us_data *us)
        usb_set_intfdata(us->pusb_intf, NULL);
 }
 
-/* First stage of disconnect processing: stop all commands and remove
- * the host */
+/* First stage of disconnect processing: stop SCSI scanning,
+ * remove the host, and stop accepting new commands
+ */
 static void quiesce_and_remove_host(struct us_data *us)
 {
        struct Scsi_Host *host = us_to_host(us);
 
-       /* Prevent new USB transfers, stop the current command, and
-        * interrupt a SCSI-scan or device-reset delay */
-       scsi_lock(host);
-       set_bit(US_FLIDX_DISCONNECTING, &us->flags);
-       scsi_unlock(host);
-       usb_stor_stop_transport(us);
-       wake_up(&us->delay_wait);
+       /* If the device is really gone, cut short reset delays */
+       if (us->pusb_dev->state == USB_STATE_NOTATTACHED)
+               set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
 
-       /* queuecommand won't accept any new commands and the control
-        * thread won't execute a previously-queued command.  If there
-        * is such a command pending, complete it with an error. */
-       mutex_lock(&us->dev_mutex);
-       if (us->srb) {
-               us->srb->result = DID_NO_CONNECT << 16;
-               scsi_lock(host);
-               us->srb->scsi_done(us->srb);
-               us->srb = NULL;
-               complete(&us->notify);          /* in case of an abort */
-               scsi_unlock(host);
-       }
-       mutex_unlock(&us->dev_mutex);
+       /* Prevent SCSI-scanning (if it hasn't started yet)
+        * and wait for the SCSI-scanning thread to stop.
+        */
+       set_bit(US_FLIDX_DONT_SCAN, &us->dflags);
+       wake_up(&us->delay_wait);
+       wait_for_completion(&us->scanning_done);
 
-       /* Now we own no commands so it's safe to remove the SCSI host */
+       /* Removing the host will perform an orderly shutdown: caches
+        * synchronized, disks spun down, etc.
+        */
        scsi_remove_host(host);
 
-       /* Wait for the SCSI-scanning thread to stop */
-       wait_for_completion(&us->scanning_done);
+       /* Prevent any new commands from being accepted and cut short
+        * reset delays.
+        */
+       scsi_lock(host);
+       set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
+       scsi_unlock(host);
+       wake_up(&us->delay_wait);
 }
 
 /* Second stage of disconnect processing: deallocate all resources */
@@ -919,16 +910,16 @@ static int usb_stor_scan_thread(void * __us)
                printk(KERN_DEBUG "usb-storage: waiting for device "
                                "to settle before scanning\n");
                wait_event_freezable_timeout(us->delay_wait,
-                               test_bit(US_FLIDX_DISCONNECTING, &us->flags),
+                               test_bit(US_FLIDX_DONT_SCAN, &us->dflags),
                                delay_use * HZ);
        }
 
        /* If the device is still connected, perform the scanning */
-       if (!test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+       if (!test_bit(US_FLIDX_DONT_SCAN, &us->dflags)) {
 
                /* For bulk-only devices, determine the max LUN value */
                if (us->protocol == US_PR_BULK &&
-                               !(us->flags & US_FL_SINGLE_LUN)) {
+                               !(us->fflags & US_FL_SINGLE_LUN)) {
                        mutex_lock(&us->dev_mutex);
                        us->max_lun = usb_stor_Bulk_max_lun(us);
                        mutex_unlock(&us->dev_mutex);
@@ -975,7 +966,7 @@ static int storage_probe(struct usb_interface *intf,
        us = host_to_us(host);
        memset(us, 0, sizeof(struct us_data));
        mutex_init(&(us->dev_mutex));
-       init_MUTEX_LOCKED(&(us->sema));
+       init_completion(&us->cmnd_ready);
        init_completion(&(us->notify));
        init_waitqueue_head(&us->delay_wait);
        init_completion(&us->scanning_done);
@@ -1023,6 +1014,7 @@ static int storage_probe(struct usb_interface *intf,
        if (IS_ERR(th)) {
                printk(KERN_WARNING USB_STORAGE 
                       "Unable to start the device-scanning thread\n");
+               complete(&us->scanning_done);
                quiesce_and_remove_host(us);
                result = PTR_ERR(th);
                goto BadDevice;
@@ -1065,6 +1057,7 @@ static struct usb_driver usb_storage_driver = {
        .pre_reset =    storage_pre_reset,
        .post_reset =   storage_post_reset,
        .id_table =     storage_usb_ids,
+       .soft_unbind =  1,
 };
 
 static int __init usb_stor_init(void)
index 8d87503e256072efa90c16672b22db4a00fded87..a4ad73bd832df76c0bffc53593c34ac73fabd9d1 100644 (file)
@@ -1,8 +1,6 @@
 /* Driver for USB Mass Storage compliant devices
  * Main Header File
  *
- * $Id: usb.h,v 1.21 2002/04/21 02:57:59 mdharm Exp $
- *
  * Current development and maintenance by:
  *   (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
@@ -67,16 +65,14 @@ struct us_unusual_dev {
 };
 
 
-/* Dynamic flag definitions: used in set_bit() etc. */
-#define US_FLIDX_URB_ACTIVE    18  /* 0x00040000  current_urb is in use  */
-#define US_FLIDX_SG_ACTIVE     19  /* 0x00080000  current_sg is in use   */
-#define US_FLIDX_ABORTING      20  /* 0x00100000  abort is in progress   */
-#define US_FLIDX_DISCONNECTING 21  /* 0x00200000  disconnect in progress */
-#define ABORTING_OR_DISCONNECTING      ((1UL << US_FLIDX_ABORTING) | \
-                                        (1UL << US_FLIDX_DISCONNECTING))
-#define US_FLIDX_RESETTING     22  /* 0x00400000  device reset in progress */
-#define US_FLIDX_TIMED_OUT     23  /* 0x00800000  SCSI midlayer timed out  */
-
+/* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */
+#define US_FLIDX_URB_ACTIVE    0       /* current_urb is in use    */
+#define US_FLIDX_SG_ACTIVE     1       /* current_sg is in use     */
+#define US_FLIDX_ABORTING      2       /* abort is in progress     */
+#define US_FLIDX_DISCONNECTING 3       /* disconnect in progress   */
+#define US_FLIDX_RESETTING     4       /* device reset in progress */
+#define US_FLIDX_TIMED_OUT     5       /* SCSI midlayer timed out  */
+#define US_FLIDX_DONT_SCAN     6       /* don't scan (disconnect)  */
 
 #define USB_STOR_STRING_LEN 32
 
@@ -109,7 +105,8 @@ struct us_data {
        struct usb_device       *pusb_dev;       /* this usb_device */
        struct usb_interface    *pusb_intf;      /* this interface */
        struct us_unusual_dev   *unusual_dev;    /* device-filter entry     */
-       unsigned long           flags;           /* from filter initially */
+       unsigned long           fflags;          /* fixed flags from filter */
+       unsigned long           dflags;          /* dynamic atomic bitflags */
        unsigned int            send_bulk_pipe;  /* cached pipe values */
        unsigned int            recv_bulk_pipe;
        unsigned int            send_ctrl_pipe;
@@ -147,7 +144,7 @@ struct us_data {
        struct task_struct      *ctl_thread;     /* the control thread   */
 
        /* mutual exclusion and synchronization structures */
-       struct semaphore        sema;            /* to sleep thread on      */
+       struct completion       cmnd_ready;      /* to sleep thread on      */
        struct completion       notify;          /* thread begin/end        */
        wait_queue_head_t       delay_wait;      /* wait during scan, reset */
        struct completion       scanning_done;   /* wait for scan thread    */
index 24ee96c4e9e9e5c816254444b7f002863363eda7..07b6addbb3c1a2631990db635e238703a891a82c 100644 (file)
@@ -1872,7 +1872,7 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
        struct fb_info *info = pci_get_drvdata(pdev);
        struct aty128fb_par *par = info->par;
        struct fb_var_screeninfo var;
-       char video_card[DEVICE_NAME_SIZE];
+       char video_card[50];
        u8 chip_rev;
        u32 dac;
 
index c347e38cd0b084719437e8157477aa220ef9e6f6..ccbfffd128056c57392f02ff59f2dfe318f5b24e 100644 (file)
@@ -289,7 +289,7 @@ struct radeonfb_info {
        struct radeon_regs      state;
        struct radeon_regs      init_state;
 
-       char                    name[DEVICE_NAME_SIZE];
+       char                    name[50];
 
        unsigned long           mmio_base_phys;
        unsigned long           fb_base_phys;
index 97aff8db10bf1e53435ef2a3441b83ab9f5ed774..4be3b46c069be3e33853fc7dd4b83023576eb8f1 100644 (file)
@@ -3586,7 +3586,8 @@ static int __init fb_console_init(void)
 
        acquire_console_sem();
        fb_register_client(&fbcon_event_notifier);
-       fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), "fbcon");
+       fbcon_device = device_create_drvdata(fb_class, NULL, MKDEV(0, 0),
+                                            NULL, "fbcon");
 
        if (IS_ERR(fbcon_device)) {
                printk(KERN_WARNING "Unable to create device "
index 33ebdb198dafbf5776ff5a5ac4a39c35fecf1464..1cd5071e53621f26a1cfe77b784a9dd8da725799 100644 (file)
@@ -1439,8 +1439,9 @@ register_framebuffer(struct fb_info *fb_info)
                        break;
        fb_info->node = i;
 
-       fb_info->dev = device_create(fb_class, fb_info->device,
-                                    MKDEV(FB_MAJOR, i), "fb%d", i);
+       fb_info->dev = device_create_drvdata(fb_class, fb_info->device,
+                                            MKDEV(FB_MAJOR, i), NULL,
+                                            "fb%d", i);
        if (IS_ERR(fb_info->dev)) {
                /* Not fatal */
                printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev));
index d7b3dcc0dc4388bb18d2614bd17efe4d9c2ea69e..e1d9eeb1aeafe432f1e240e4bf30d895cc72c80d 100644 (file)
@@ -47,6 +47,7 @@ enum {
        cmap_M3B,               /* ATI Rage Mobility M3 Head B */
        cmap_radeon,            /* ATI Radeon */
        cmap_gxt2000,           /* IBM GXT2000 */
+       cmap_avivo,             /* ATI R5xx */
 };
 
 struct offb_par {
@@ -58,26 +59,36 @@ struct offb_par {
 
 struct offb_par default_par;
 
-    /*
-     *  Interface used by the world
-     */
-
-static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-                         u_int transp, struct fb_info *info);
-static int offb_blank(int blank, struct fb_info *info);
-
 #ifdef CONFIG_PPC32
 extern boot_infos_t *boot_infos;
 #endif
 
-static struct fb_ops offb_ops = {
-       .owner          = THIS_MODULE,
-       .fb_setcolreg   = offb_setcolreg,
-       .fb_blank       = offb_blank,
-       .fb_fillrect    = cfb_fillrect,
-       .fb_copyarea    = cfb_copyarea,
-       .fb_imageblit   = cfb_imageblit,
-};
+/* Definitions used by the Avivo palette hack */
+#define AVIVO_DC_LUT_RW_SELECT                  0x6480
+#define AVIVO_DC_LUT_RW_MODE                    0x6484
+#define AVIVO_DC_LUT_RW_INDEX                   0x6488
+#define AVIVO_DC_LUT_SEQ_COLOR                  0x648c
+#define AVIVO_DC_LUT_PWL_DATA                   0x6490
+#define AVIVO_DC_LUT_30_COLOR                   0x6494
+#define AVIVO_DC_LUT_READ_PIPE_SELECT           0x6498
+#define AVIVO_DC_LUT_WRITE_EN_MASK              0x649c
+#define AVIVO_DC_LUT_AUTOFILL                   0x64a0
+
+#define AVIVO_DC_LUTA_CONTROL                   0x64c0
+#define AVIVO_DC_LUTA_BLACK_OFFSET_BLUE         0x64c4
+#define AVIVO_DC_LUTA_BLACK_OFFSET_GREEN        0x64c8
+#define AVIVO_DC_LUTA_BLACK_OFFSET_RED          0x64cc
+#define AVIVO_DC_LUTA_WHITE_OFFSET_BLUE         0x64d0
+#define AVIVO_DC_LUTA_WHITE_OFFSET_GREEN        0x64d4
+#define AVIVO_DC_LUTA_WHITE_OFFSET_RED          0x64d8
+
+#define AVIVO_DC_LUTB_CONTROL                   0x6cc0
+#define AVIVO_DC_LUTB_BLACK_OFFSET_BLUE         0x6cc4
+#define AVIVO_DC_LUTB_BLACK_OFFSET_GREEN        0x6cc8
+#define AVIVO_DC_LUTB_BLACK_OFFSET_RED          0x6ccc
+#define AVIVO_DC_LUTB_WHITE_OFFSET_BLUE         0x6cd0
+#define AVIVO_DC_LUTB_WHITE_OFFSET_GREEN        0x6cd4
+#define AVIVO_DC_LUTB_WHITE_OFFSET_RED          0x6cd8
 
     /*
      *  Set a single color register. The values supplied are already
@@ -160,6 +171,17 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                out_le32(((unsigned __iomem *) par->cmap_adr) + regno,
                         (red << 16 | green << 8 | blue));
                break;
+       case cmap_avivo:
+               /* Write to both LUTs for now */
+               writel(1, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
+               writeb(regno, par->cmap_adr + AVIVO_DC_LUT_RW_INDEX);
+               writel(((red) << 22) | ((green) << 12) | ((blue) << 2),
+                      par->cmap_adr + AVIVO_DC_LUT_30_COLOR);
+               writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
+               writeb(regno, par->cmap_adr + AVIVO_DC_LUT_RW_INDEX);
+               writel(((red) << 22) | ((green) << 12) | ((blue) << 2),
+                      par->cmap_adr + AVIVO_DC_LUT_30_COLOR);
+               break;
        }
 
        return 0;
@@ -216,12 +238,59 @@ static int offb_blank(int blank, struct fb_info *info)
                                out_le32(((unsigned __iomem *) par->cmap_adr) + i,
                                         0);
                                break;
+                       case cmap_avivo:
+                               writel(1, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
+                               writeb(i, par->cmap_adr + AVIVO_DC_LUT_RW_INDEX);
+                               writel(0, par->cmap_adr + AVIVO_DC_LUT_30_COLOR);
+                               writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
+                               writeb(i, par->cmap_adr + AVIVO_DC_LUT_RW_INDEX);
+                               writel(0, par->cmap_adr + AVIVO_DC_LUT_30_COLOR);
+                               break;
                        }
        } else
                fb_set_cmap(&info->cmap, info);
        return 0;
 }
 
+static int offb_set_par(struct fb_info *info)
+{
+       struct offb_par *par = (struct offb_par *) info->par;
+
+       /* On avivo, initialize palette control */
+       if (par->cmap_type == cmap_avivo) {
+               writel(0, par->cmap_adr + AVIVO_DC_LUTA_CONTROL);
+               writel(0, par->cmap_adr + AVIVO_DC_LUTA_BLACK_OFFSET_BLUE);
+               writel(0, par->cmap_adr + AVIVO_DC_LUTA_BLACK_OFFSET_GREEN);
+               writel(0, par->cmap_adr + AVIVO_DC_LUTA_BLACK_OFFSET_RED);
+               writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTA_WHITE_OFFSET_BLUE);
+               writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTA_WHITE_OFFSET_GREEN);
+               writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTA_WHITE_OFFSET_RED);
+               writel(0, par->cmap_adr + AVIVO_DC_LUTB_CONTROL);
+               writel(0, par->cmap_adr + AVIVO_DC_LUTB_BLACK_OFFSET_BLUE);
+               writel(0, par->cmap_adr + AVIVO_DC_LUTB_BLACK_OFFSET_GREEN);
+               writel(0, par->cmap_adr + AVIVO_DC_LUTB_BLACK_OFFSET_RED);
+               writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTB_WHITE_OFFSET_BLUE);
+               writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTB_WHITE_OFFSET_GREEN);
+               writel(0x0000ffff, par->cmap_adr + AVIVO_DC_LUTB_WHITE_OFFSET_RED);
+               writel(1, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
+               writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_MODE);
+               writel(0x0000003f, par->cmap_adr + AVIVO_DC_LUT_WRITE_EN_MASK);
+               writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_SELECT);
+               writel(0, par->cmap_adr + AVIVO_DC_LUT_RW_MODE);
+               writel(0x0000003f, par->cmap_adr + AVIVO_DC_LUT_WRITE_EN_MASK);
+       }
+       return 0;
+}
+
+static struct fb_ops offb_ops = {
+       .owner          = THIS_MODULE,
+       .fb_setcolreg   = offb_setcolreg,
+       .fb_set_par     = offb_set_par,
+       .fb_blank       = offb_blank,
+       .fb_fillrect    = cfb_fillrect,
+       .fb_copyarea    = cfb_copyarea,
+       .fb_imageblit   = cfb_imageblit,
+};
 
 static void __iomem *offb_map_reg(struct device_node *np, int index,
                                  unsigned long offset, unsigned long size)
@@ -245,6 +314,59 @@ static void __iomem *offb_map_reg(struct device_node *np, int index,
        return ioremap(taddr + offset, size);
 }
 
+static void offb_init_palette_hacks(struct fb_info *info, struct device_node *dp,
+                                   const char *name, unsigned long address)
+{
+       struct offb_par *par = (struct offb_par *) info->par;
+
+       if (dp && !strncmp(name, "ATY,Rage128", 11)) {
+               par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
+               if (par->cmap_adr)
+                       par->cmap_type = cmap_r128;
+       } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
+                         || !strncmp(name, "ATY,RageM3p12A", 14))) {
+               par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
+               if (par->cmap_adr)
+                       par->cmap_type = cmap_M3A;
+       } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
+               par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
+               if (par->cmap_adr)
+                       par->cmap_type = cmap_M3B;
+       } else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
+               par->cmap_adr = offb_map_reg(dp, 1, 0, 0x1fff);
+               if (par->cmap_adr)
+                       par->cmap_type = cmap_radeon;
+       } else if (!strncmp(name, "ATY,", 4)) {
+               unsigned long base = address & 0xff000000UL;
+               par->cmap_adr =
+                       ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
+               par->cmap_data = par->cmap_adr + 1;
+               par->cmap_type = cmap_m64;
+       } else if (dp && (of_device_is_compatible(dp, "pci1014,b7") ||
+                         of_device_is_compatible(dp, "pci1014,21c"))) {
+               par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
+               if (par->cmap_adr)
+                       par->cmap_type = cmap_gxt2000;
+       } else if (dp && !strncmp(name, "vga,Display-", 12)) {
+               /* Look for AVIVO initialized by SLOF */
+               struct device_node *pciparent = of_get_parent(dp);
+               const u32 *vid, *did;
+               vid = of_get_property(pciparent, "vendor-id", NULL);
+               did = of_get_property(pciparent, "device-id", NULL);
+               /* This will match most R5xx */
+               if (vid && did && *vid == 0x1002 &&
+                   ((*did >= 0x7100 && *did < 0x7800) ||
+                    (*did >= 0x9400))) {
+                       par->cmap_adr = offb_map_reg(pciparent, 2, 0, 0x10000);
+                       if (par->cmap_adr)
+                               par->cmap_type = cmap_avivo;
+               }
+               of_node_put(pciparent);
+       }
+       info->fix.visual = (par->cmap_type != cmap_unknown) ?
+               FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR;
+}
+
 static void __init offb_init_fb(const char *name, const char *full_name,
                                int width, int height, int depth,
                                int pitch, unsigned long address,
@@ -283,6 +405,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
 
        fix = &info->fix;
        var = &info->var;
+       info->par = par;
 
        strcpy(fix->id, "OFfb ");
        strncat(fix->id, name, sizeof(fix->id) - sizeof("OFfb "));
@@ -298,39 +421,9 @@ static void __init offb_init_fb(const char *name, const char *full_name,
        fix->type_aux = 0;
 
        par->cmap_type = cmap_unknown;
-       if (depth == 8) {
-               if (dp && !strncmp(name, "ATY,Rage128", 11)) {
-                       par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
-                       if (par->cmap_adr)
-                               par->cmap_type = cmap_r128;
-               } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12)
-                                 || !strncmp(name, "ATY,RageM3p12A", 14))) {
-                       par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
-                       if (par->cmap_adr)
-                               par->cmap_type = cmap_M3A;
-               } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
-                       par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
-                       if (par->cmap_adr)
-                               par->cmap_type = cmap_M3B;
-               } else if (dp && !strncmp(name, "ATY,Rage6", 9)) {
-                       par->cmap_adr = offb_map_reg(dp, 1, 0, 0x1fff);
-                       if (par->cmap_adr)
-                               par->cmap_type = cmap_radeon;
-               } else if (!strncmp(name, "ATY,", 4)) {
-                       unsigned long base = address & 0xff000000UL;
-                       par->cmap_adr =
-                           ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
-                       par->cmap_data = par->cmap_adr + 1;
-                       par->cmap_type = cmap_m64;
-               } else if (dp && (of_device_is_compatible(dp, "pci1014,b7") ||
-                                 of_device_is_compatible(dp, "pci1014,21c"))) {
-                       par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
-                       if (par->cmap_adr)
-                               par->cmap_type = cmap_gxt2000;
-               }
-               fix->visual = (par->cmap_type != cmap_unknown) ?
-                       FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR;
-       } else
+       if (depth == 8)
+               offb_init_palette_hacks(info, dp, name, address);
+       else
                fix->visual = FB_VISUAL_TRUECOLOR;
 
        var->xoffset = var->yoffset = 0;
@@ -395,7 +488,6 @@ static void __init offb_init_fb(const char *name, const char *full_name,
 
        info->fbops = &offb_ops;
        info->screen_base = ioremap(address, fix->smem_len);
-       info->par = par;
        info->pseudo_palette = (void *) (info + 1);
        info->flags = FBINFO_DEFAULT | foreign_endian;
 
index dc3af1c78c56ce2fff1fa32a5f8961ae727a496a..4b5d807719041e99aa7f1d70afb1b9a308c21fa6 100644 (file)
@@ -1297,6 +1297,7 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
 
 static struct ps3_system_bus_driver ps3fb_driver = {
        .match_id       = PS3_MATCH_ID_GRAPHICS,
+       .match_sub_id   = PS3_MATCH_SUB_ID_FB,
        .core.name      = DEVICE_NAME,
        .core.owner     = THIS_MODULE,
        .probe          = ps3fb_probe,
index d0746261c95751a9f90412e4a15c63974444c1b3..bb2514369507aa9171c361472b3ed0add14eff16 100644 (file)
@@ -227,6 +227,22 @@ static int pxafb_bpp_to_lccr3(struct fb_var_screeninfo *var)
        case 4:  ret = LCCR3_4BPP; break;
        case 8:  ret = LCCR3_8BPP; break;
        case 16: ret = LCCR3_16BPP; break;
+       case 24:
+               switch (var->red.length + var->green.length +
+                               var->blue.length + var->transp.length) {
+               case 18: ret = LCCR3_18BPP_P | LCCR3_PDFOR_3; break;
+               case 19: ret = LCCR3_19BPP_P; break;
+               }
+               break;
+       case 32:
+               switch (var->red.length + var->green.length +
+                               var->blue.length + var->transp.length) {
+               case 18: ret = LCCR3_18BPP | LCCR3_PDFOR_3; break;
+               case 19: ret = LCCR3_19BPP; break;
+               case 24: ret = LCCR3_24BPP | LCCR3_PDFOR_3; break;
+               case 25: ret = LCCR3_25BPP; break;
+               }
+               break;
        }
        return ret;
 }
@@ -345,6 +361,41 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
                var->green.offset = 5;  var->green.length = 6;
                var->blue.offset  = 0;  var->blue.length  = 5;
                var->transp.offset = var->transp.length = 0;
+       } else if (var->bits_per_pixel > 16) {
+               struct pxafb_mode_info *mode;
+
+               mode = pxafb_getmode(inf, var);
+               if (!mode)
+                       return -EINVAL;
+
+               switch (mode->depth) {
+               case 18: /* RGB666 */
+                       var->transp.offset = var->transp.length     = 0;
+                       var->red.offset    = 12; var->red.length    = 6;
+                       var->green.offset  = 6;  var->green.length  = 6;
+                       var->blue.offset   = 0;  var->blue.length   = 6;
+                       break;
+               case 19: /* RGBT666 */
+                       var->transp.offset = 18; var->transp.length = 1;
+                       var->red.offset    = 12; var->red.length    = 6;
+                       var->green.offset  = 6;  var->green.length  = 6;
+                       var->blue.offset   = 0;  var->blue.length   = 6;
+                       break;
+               case 24: /* RGB888 */
+                       var->transp.offset = var->transp.length     = 0;
+                       var->red.offset    = 16; var->red.length    = 8;
+                       var->green.offset  = 8;  var->green.length  = 8;
+                       var->blue.offset   = 0;  var->blue.length   = 8;
+                       break;
+               case 25: /* RGBT888 */
+                       var->transp.offset = 24; var->transp.length = 1;
+                       var->red.offset    = 16; var->red.length    = 8;
+                       var->green.offset  = 8;  var->green.length  = 8;
+                       var->blue.offset   = 0;  var->blue.length   = 8;
+                       break;
+               default:
+                       return -EINVAL;
+               }
        } else {
                var->red.offset = var->green.offset = 0;
                var->blue.offset = var->transp.offset = 0;
@@ -376,7 +427,7 @@ static int pxafb_set_par(struct fb_info *info)
        struct pxafb_info *fbi = (struct pxafb_info *)info;
        struct fb_var_screeninfo *var = &info->var;
 
-       if (var->bits_per_pixel == 16)
+       if (var->bits_per_pixel >= 16)
                fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR;
        else if (!fbi->cmap_static)
                fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
@@ -391,7 +442,7 @@ static int pxafb_set_par(struct fb_info *info)
 
        fbi->fb.fix.line_length = var->xres_virtual *
                                  var->bits_per_pixel / 8;
-       if (var->bits_per_pixel == 16)
+       if (var->bits_per_pixel >= 16)
                fbi->palette_size = 0;
        else
                fbi->palette_size = var->bits_per_pixel == 1 ?
@@ -404,7 +455,7 @@ static int pxafb_set_par(struct fb_info *info)
         */
        pxafb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR);
 
-       if (fbi->fb.var.bits_per_pixel == 16)
+       if (fbi->fb.var.bits_per_pixel >= 16)
                fb_dealloc_cmap(&fbi->fb.cmap);
        else
                fb_alloc_cmap(&fbi->fb.cmap, 1<<fbi->fb.var.bits_per_pixel, 0);
@@ -831,6 +882,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
                case 4:
                case 8:
                case 16:
+               case 24:
+               case 32:
                        break;
                default:
                        printk(KERN_ERR "%s: invalid bit depth %d\n",
@@ -968,6 +1021,11 @@ static void pxafb_setup_gpio(struct pxafb_info *fbi)
 
        for (gpio = 58; ldd_bits; gpio++, ldd_bits--)
                pxa_gpio_mode(gpio | GPIO_ALT_FN_2_OUT);
+       /* 18 bit interface */
+       if (fbi->fb.var.bits_per_pixel > 16) {
+               pxa_gpio_mode(86 | GPIO_ALT_FN_2_OUT);
+               pxa_gpio_mode(87 | GPIO_ALT_FN_2_OUT);
+       }
        pxa_gpio_mode(GPIO74_LCD_FCLK_MD);
        pxa_gpio_mode(GPIO75_LCD_LCLK_MD);
        pxa_gpio_mode(GPIO76_LCD_PCLK_MD);
index 591bc29b55f5acf0f8dbe97e360ddd279020e9b2..d4427cb869791cd0f1b910f5371f78aefe42c626 100644 (file)
@@ -610,6 +610,7 @@ static ssize_t show_target_kb(struct sys_device *dev, char *buf)
 }
 
 static ssize_t store_target_kb(struct sys_device *dev,
+                              struct sysdev_attribute *attr,
                               const char *buf,
                               size_t count)
 {
index 332dd63750a01d41342844bc3f72e25891c4eab4..0e0c28574af8701213d35dac28ca8308d03e1029 100644 (file)
@@ -734,6 +734,33 @@ static void restore_cpu_ipis(unsigned int cpu)
        }
 }
 
+/* Clear an irq's pending state, in preparation for polling on it */
+void xen_clear_irq_pending(int irq)
+{
+       int evtchn = evtchn_from_irq(irq);
+
+       if (VALID_EVTCHN(evtchn))
+               clear_evtchn(evtchn);
+}
+
+/* Poll waiting for an irq to become pending.  In the usual case, the
+   irq will be disabled so it won't deliver an interrupt. */
+void xen_poll_irq(int irq)
+{
+       evtchn_port_t evtchn = evtchn_from_irq(irq);
+
+       if (VALID_EVTCHN(evtchn)) {
+               struct sched_poll poll;
+
+               poll.nr_ports = 1;
+               poll.timeout = 0;
+               poll.ports = &evtchn;
+
+               if (HYPERVISOR_sched_op(SCHEDOP_poll, &poll) != 0)
+                       BUG();
+       }
+}
+
 void xen_irq_resume(void)
 {
        unsigned int cpu, irq, evtchn;
index 5b546e365f007d028843eea0ee84e77a0def1f58..a5bc91ae6ff69f5d5d4b2e9f49e308acd9126b20 100644 (file)
@@ -63,11 +63,12 @@ static int xen_suspend(void *data)
        gnttab_resume();
        xen_mm_unpin_all();
 
-       device_power_up();
+       device_power_up(PMSG_RESUME);
 
        if (!*cancelled) {
                xen_irq_resume();
                xen_console_resume();
+               xen_timer_resume();
        }
 
        return 0;
@@ -107,12 +108,13 @@ static void do_suspend(void)
                goto out;
        }
 
-       if (!cancelled)
+       if (!cancelled) {
+               xen_arch_resume();
                xenbus_resume();
-       else
+       else
                xenbus_suspend_cancel();
 
-       device_resume();
+       device_resume(PMSG_RESUME);
 
        /* Make sure timer events get retriggered on all CPUs */
        clock_was_set();
index d48ff5f370f4e5122c3402ed44889564366ad317..639d2d8b57106ac6e524c4ab7c940ea2fad895da 100644 (file)
@@ -204,6 +204,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
        NEW_AUX_ENT(AT_GID, tsk->gid);
        NEW_AUX_ENT(AT_EGID, tsk->egid);
        NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
+       NEW_AUX_ENT(AT_EXECFN, bprm->exec);
        if (k_platform) {
                NEW_AUX_ENT(AT_PLATFORM,
                            (elf_addr_t)(unsigned long)u_platform);
index e3eb3556622b6808c6d15515e18e597a0ddc4f5b..40c36f7352a609a061cabdd1704e8074c0e0ee2e 100644 (file)
@@ -362,8 +362,9 @@ static int init_coda_psdev(void)
                goto out_chrdev;
        }               
        for (i = 0; i < MAX_CODADEVS; i++)
-               device_create(coda_psdev_class, NULL,
-                             MKDEV(CODA_PSDEV_MAJOR,i), "cfs%d", i);
+               device_create_drvdata(coda_psdev_class, NULL,
+                                     MKDEV(CODA_PSDEV_MAJOR, i),
+                                     NULL, "cfs%d", i);
        coda_sysctl_init();
        goto out;
 
index e9602d85c11d0220d5cbccf7817c25b10a6d068e..08e28c9bb4164f5e2f549535959fd816d92521ed 100644 (file)
@@ -309,6 +309,31 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
 }
 EXPORT_SYMBOL_GPL(debugfs_create_symlink);
 
+static void __debugfs_remove(struct dentry *dentry, struct dentry *parent)
+{
+       int ret = 0;
+
+       if (debugfs_positive(dentry)) {
+               if (dentry->d_inode) {
+                       dget(dentry);
+                       switch (dentry->d_inode->i_mode & S_IFMT) {
+                       case S_IFDIR:
+                               ret = simple_rmdir(parent->d_inode, dentry);
+                               break;
+                       case S_IFLNK:
+                               kfree(dentry->d_inode->i_private);
+                               /* fall through */
+                       default:
+                               simple_unlink(parent->d_inode, dentry);
+                               break;
+                       }
+                       if (!ret)
+                               d_delete(dentry);
+                       dput(dentry);
+               }
+       }
+}
+
 /**
  * debugfs_remove - removes a file or directory from the debugfs filesystem
  * @dentry: a pointer to a the dentry of the file or directory to be
@@ -325,7 +350,6 @@ EXPORT_SYMBOL_GPL(debugfs_create_symlink);
 void debugfs_remove(struct dentry *dentry)
 {
        struct dentry *parent;
-       int ret = 0;
        
        if (!dentry)
                return;
@@ -335,29 +359,83 @@ void debugfs_remove(struct dentry *dentry)
                return;
 
        mutex_lock(&parent->d_inode->i_mutex);
-       if (debugfs_positive(dentry)) {
-               if (dentry->d_inode) {
-                       dget(dentry);
-                       switch (dentry->d_inode->i_mode & S_IFMT) {
-                       case S_IFDIR:
-                               ret = simple_rmdir(parent->d_inode, dentry);
-                               break;
-                       case S_IFLNK:
-                               kfree(dentry->d_inode->i_private);
-                               /* fall through */
-                       default:
-                               simple_unlink(parent->d_inode, dentry);
+       __debugfs_remove(dentry, parent);
+       mutex_unlock(&parent->d_inode->i_mutex);
+       simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+}
+EXPORT_SYMBOL_GPL(debugfs_remove);
+
+/**
+ * debugfs_remove_recursive - recursively removes a directory
+ * @dentry: a pointer to a the dentry of the directory to be removed.
+ *
+ * This function recursively removes a directory tree in debugfs that
+ * was previously created with a call to another debugfs function
+ * (like debugfs_create_file() or variants thereof.)
+ *
+ * This function is required to be called in order for the file to be
+ * removed, no automatic cleanup of files will happen when a module is
+ * removed, you are responsible here.
+ */
+void debugfs_remove_recursive(struct dentry *dentry)
+{
+       struct dentry *child;
+       struct dentry *parent;
+
+       if (!dentry)
+               return;
+
+       parent = dentry->d_parent;
+       if (!parent || !parent->d_inode)
+               return;
+
+       parent = dentry;
+       mutex_lock(&parent->d_inode->i_mutex);
+
+       while (1) {
+               /*
+                * When all dentries under "parent" has been removed,
+                * walk up the tree until we reach our starting point.
+                */
+               if (list_empty(&parent->d_subdirs)) {
+                       mutex_unlock(&parent->d_inode->i_mutex);
+                       if (parent == dentry)
                                break;
-                       }
-                       if (!ret)
-                               d_delete(dentry);
-                       dput(dentry);
+                       parent = parent->d_parent;
+                       mutex_lock(&parent->d_inode->i_mutex);
+               }
+               child = list_entry(parent->d_subdirs.next, struct dentry,
+                               d_u.d_child);
+
+               /*
+                * If "child" isn't empty, walk down the tree and
+                * remove all its descendants first.
+                */
+               if (!list_empty(&child->d_subdirs)) {
+                       mutex_unlock(&parent->d_inode->i_mutex);
+                       parent = child;
+                       mutex_lock(&parent->d_inode->i_mutex);
+                       continue;
                }
+               __debugfs_remove(child, parent);
+               if (parent->d_subdirs.next == &child->d_u.d_child) {
+                       /*
+                        * Avoid infinite loop if we fail to remove
+                        * one dentry.
+                        */
+                       mutex_unlock(&parent->d_inode->i_mutex);
+                       break;
+               }
+               simple_release_fs(&debugfs_mount, &debugfs_mount_count);
        }
+
+       parent = dentry->d_parent;
+       mutex_lock(&parent->d_inode->i_mutex);
+       __debugfs_remove(dentry, parent);
        mutex_unlock(&parent->d_inode->i_mutex);
        simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 }
-EXPORT_SYMBOL_GPL(debugfs_remove);
+EXPORT_SYMBOL_GPL(debugfs_remove_recursive);
 
 /**
  * debugfs_rename - rename a file/directory in the debugfs filesystem
index 6149e4b58c887a62cd11e4776650b1880745af2a..efef715135d34e459ce450eb24ca41e4234cf471 100644 (file)
@@ -401,7 +401,7 @@ void register_disk(struct gendisk *disk)
        disk->dev.parent = disk->driverfs_dev;
        disk->dev.devt = MKDEV(disk->major, disk->first_minor);
 
-       strlcpy(disk->dev.bus_id, disk->disk_name, KOBJ_NAME_LEN);
+       strlcpy(disk->dev.bus_id, disk->disk_name, BUS_ID_SIZE);
        /* ewww... some of these buggers have / in the name... */
        s = strchr(disk->dev.bus_id, '/');
        if (s)
index b224a28e0c15fc7cc3d219cdbc01ccdf60c7b1b7..7bc296f424aebcb66cf89b2f0c9678f787c37a1d 100644 (file)
 #include "internal.h"
 
 
+static struct net *get_proc_net(const struct inode *inode)
+{
+       return maybe_get_net(PDE_NET(PDE(inode)));
+}
+
 int seq_open_net(struct inode *ino, struct file *f,
                 const struct seq_operations *ops, int size)
 {
@@ -185,12 +190,6 @@ void proc_net_remove(struct net *net, const char *name)
 }
 EXPORT_SYMBOL_GPL(proc_net_remove);
 
-struct net *get_proc_net(const struct inode *inode)
-{
-       return maybe_get_net(PDE_NET(PDE(inode)));
-}
-EXPORT_SYMBOL_GPL(get_proc_net);
-
 static __net_init int proc_net_ns_init(struct net *net)
 {
        struct proc_dir_entry *netd, *net_statd;
index 164bd9f9ede3024188285d071bbc6caa47cb94f8..7546a918f7907612b078c411d8eeb288b099ffc2 100644 (file)
@@ -636,7 +636,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
        struct pagemapread pm;
        int pagecount;
        int ret = -ESRCH;
-       struct mm_walk pagemap_walk;
+       struct mm_walk pagemap_walk = {};
        unsigned long src;
        unsigned long svpfn;
        unsigned long start_vaddr;
index 8c0e4b92574f6ad71a473c9220bcb980e9b5a7c3..c1a7efb310bf3517ab1bf52bb1312a79a517f2d6 100644 (file)
@@ -398,7 +398,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
 }
 
 /**
- *     sysfs_add_one - add sysfs_dirent to parent
+ *     __sysfs_add_one - add sysfs_dirent to parent without warning
  *     @acxt: addrm context to use
  *     @sd: sysfs_dirent to be added
  *
@@ -417,7 +417,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
  *     0 on success, -EEXIST if entry with the given name already
  *     exists.
  */
-int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
+int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
 {
        if (sysfs_find_dirent(acxt->parent_sd, sd->s_name))
                return -EEXIST;
@@ -434,6 +434,39 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
        return 0;
 }
 
+/**
+ *     sysfs_add_one - add sysfs_dirent to parent
+ *     @acxt: addrm context to use
+ *     @sd: sysfs_dirent to be added
+ *
+ *     Get @acxt->parent_sd and set sd->s_parent to it and increment
+ *     nlink of parent inode if @sd is a directory and link into the
+ *     children list of the parent.
+ *
+ *     This function should be called between calls to
+ *     sysfs_addrm_start() and sysfs_addrm_finish() and should be
+ *     passed the same @acxt as passed to sysfs_addrm_start().
+ *
+ *     LOCKING:
+ *     Determined by sysfs_addrm_start().
+ *
+ *     RETURNS:
+ *     0 on success, -EEXIST if entry with the given name already
+ *     exists.
+ */
+int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
+{
+       int ret;
+
+       ret = __sysfs_add_one(acxt, sd);
+       if (ret == -EEXIST) {
+               printk(KERN_WARNING "sysfs: duplicate filename '%s' "
+                      "can not be created\n", sd->s_name);
+               WARN_ON(1);
+       }
+       return ret;
+}
+
 /**
  *     sysfs_remove_one - remove sysfs_dirent from parent
  *     @acxt: addrm context to use
index e7735f643cd1b03eab8560479d6f691e387ce218..3f07893ff8968a483f4c5fc45646c80e3535966f 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kobject.h>
 #include <linux/kallsyms.h>
 #include <linux/slab.h>
+#include <linux/fsnotify.h>
 #include <linux/namei.h>
 #include <linux/poll.h>
 #include <linux/list.h>
@@ -585,9 +586,11 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
 
        newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
        newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-       rc = notify_change(victim, &newattrs);
+       newattrs.ia_ctime = current_fs_time(inode->i_sb);
+       rc = sysfs_setattr(victim, &newattrs);
 
        if (rc == 0) {
+               fsnotify_change(victim, newattrs.ia_valid);
                mutex_lock(&sysfs_mutex);
                victim_sd->s_mode = newattrs.ia_mode;
                mutex_unlock(&sysfs_mutex);
index 817f5966edcac2c2e36033902f2ac2ce0f89f626..a3ba217fbe74f4313a1dca88a8cc863e14766341 100644 (file)
 
 #include "sysfs.h"
 
-/**
- *     sysfs_create_link - create symlink between two objects.
- *     @kobj:  object whose directory we're creating the link in.
- *     @target:        object we're pointing to.
- *     @name:          name of the symlink.
- */
-int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
+static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
+                               const char *name, int warn)
 {
        struct sysfs_dirent *parent_sd = NULL;
        struct sysfs_dirent *target_sd = NULL;
@@ -65,7 +60,10 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
        target_sd = NULL;       /* reference is now owned by the symlink */
 
        sysfs_addrm_start(&acxt, parent_sd);
-       error = sysfs_add_one(&acxt, sd);
+       if (warn)
+               error = sysfs_add_one(&acxt, sd);
+       else
+               error = __sysfs_add_one(&acxt, sd);
        sysfs_addrm_finish(&acxt);
 
        if (error)
@@ -79,6 +77,33 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
        return error;
 }
 
+/**
+ *     sysfs_create_link - create symlink between two objects.
+ *     @kobj:  object whose directory we're creating the link in.
+ *     @target:        object we're pointing to.
+ *     @name:          name of the symlink.
+ */
+int sysfs_create_link(struct kobject *kobj, struct kobject *target,
+                     const char *name)
+{
+       return sysfs_do_create_link(kobj, target, name, 1);
+}
+
+/**
+ *     sysfs_create_link_nowarn - create symlink between two objects.
+ *     @kobj:  object whose directory we're creating the link in.
+ *     @target:        object we're pointing to.
+ *     @name:          name of the symlink.
+ *
+ *     This function does the same as sysf_create_link(), but it
+ *     doesn't warn if the link already exists.
+ */
+int sysfs_create_link_nowarn(struct kobject *kobj, struct kobject *target,
+                            const char *name)
+{
+       return sysfs_do_create_link(kobj, target, name, 0);
+}
+
 /**
  *     sysfs_remove_link - remove symlink in object's directory.
  *     @kobj:  object we're acting for.
index ce4e15f8aaebce521b4e8b4469c5923307cedad3..a5db496f71c717ce63073440a3c9a23138b67d47 100644 (file)
@@ -107,6 +107,7 @@ struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd);
 void sysfs_put_active_two(struct sysfs_dirent *sd);
 void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
                       struct sysfs_dirent *parent_sd);
+int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
 int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
 void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
 void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
index 90d14ee564f567c2515dbced773eebda2d494063..ef4f5da2029f30af6e493e4ff9082d34abd0c40c 100644 (file)
@@ -198,17 +198,13 @@ iop_chan_memset_slot_count(size_t len, int *slots_per_op)
 static inline int
 iop_chan_xor_slot_count(size_t len, int src_cnt, int *slots_per_op)
 {
-       int num_slots;
-       /* slots_to_find = 1 for basic descriptor + 1 per 4 sources above 1
-        * (1 source => 8 bytes) (1 slot => 32 bytes)
-        */
-       num_slots = 1 + (((src_cnt - 1) << 3) >> 5);
-       if (((src_cnt - 1) << 3) & 0x1f)
-               num_slots++;
-
-       *slots_per_op = num_slots;
-
-       return num_slots;
+       static const char slot_count_table[] = { 1, 2, 2, 2,
+                                                2, 3, 3, 3,
+                                                3, 4, 4, 4,
+                                                4, 5, 5, 5,
+                                               };
+       *slots_per_op = slot_count_table[src_cnt - 1];
+       return *slots_per_op;
 }
 
 #define ADMA_MAX_BYTE_COUNT    (16 * 1024 * 1024)
diff --git a/include/asm-arm/arch-pxa/cm-x270.h b/include/asm-arm/arch-pxa/cm-x270.h
deleted file mode 100644 (file)
index f8fac9e..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * linux/include/asm/arch-pxa/cm-x270.h
- *
- * Copyright Compulab Ltd., 2003, 2007
- * Mike Rapoport <mike@compulab.co.il>
- *
- * 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.
- */
-
-
-/* CM-x270 device physical addresses */
-#define CMX270_CS1_PHYS                (PXA_CS1_PHYS)
-#define MARATHON_PHYS          (PXA_CS2_PHYS)
-#define CMX270_IDE104_PHYS     (PXA_CS3_PHYS)
-#define CMX270_IT8152_PHYS     (PXA_CS4_PHYS)
-
-/* Statically mapped regions */
-#define CMX270_VIRT_BASE               (0xe8000000)
-#define CMX270_IT8152_VIRT             (CMX270_VIRT_BASE)
-#define CMX270_IDE104_VIRT             (CMX270_IT8152_VIRT + SZ_64M)
-
-/* GPIO related definitions */
-#define GPIO_IT8152_IRQ                        (22)
-
-#define IRQ_GPIO_IT8152_IRQ    IRQ_GPIO(GPIO_IT8152_IRQ)
-#define PME_IRQ                        IRQ_GPIO(0)
-#define CMX270_IDE_IRQ         IRQ_GPIO(100)
-#define CMX270_GPIRQ1          IRQ_GPIO(101)
-#define CMX270_TOUCHIRQ                IRQ_GPIO(96)
-#define CMX270_ETHIRQ          IRQ_GPIO(10)
-#define CMX270_GFXIRQ          IRQ_GPIO(95)
-#define CMX270_NANDIRQ         IRQ_GPIO(89)
-#define CMX270_MMC_IRQ         IRQ_GPIO(83)
-
-/* PCMCIA related definitions */
-#define PCC_DETECT(x)  (GPLR(84 - (x)) & GPIO_bit(84 - (x)))
-#define PCC_READY(x)   (GPLR(82 - (x)) & GPIO_bit(82 - (x)))
-
-#define PCMCIA_S0_CD_VALID             IRQ_GPIO(84)
-#define PCMCIA_S0_CD_VALID_EDGE                GPIO_BOTH_EDGES
-
-#define PCMCIA_S1_CD_VALID             IRQ_GPIO(83)
-#define PCMCIA_S1_CD_VALID_EDGE                GPIO_BOTH_EDGES
-
-#define PCMCIA_S0_RDYINT               IRQ_GPIO(82)
-#define PCMCIA_S1_RDYINT               IRQ_GPIO(81)
-
-#define PCMCIA_RESET_GPIO              53
diff --git a/include/asm-arm/arch-pxa/eseries-gpio.h b/include/asm-arm/arch-pxa/eseries-gpio.h
new file mode 100644 (file)
index 0000000..4c90b13
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  eseries-gpio.h
+ *
+ *  Copyright (C) Ian Molton <spyro@f2s.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.
+ *
+ */
+
+/* e-series power button */
+#define GPIO_ESERIES_POWERBTN     0
+
+/* UDC GPIO definitions */
+#define GPIO_E7XX_USB_DISC       13
+#define GPIO_E7XX_USB_PULLUP      3
+
+#define GPIO_E800_USB_DISC        4
+#define GPIO_E800_USB_PULLUP     84
+
+/* e740 PCMCIA GPIO definitions */
+/* Note: PWR1 seems to be inverted */
+#define GPIO_E740_PCMCIA_CD0      8
+#define GPIO_E740_PCMCIA_CD1     44
+#define GPIO_E740_PCMCIA_RDY0    11
+#define GPIO_E740_PCMCIA_RDY1     6
+#define GPIO_E740_PCMCIA_RST0    27
+#define GPIO_E740_PCMCIA_RST1    24
+#define GPIO_E740_PCMCIA_PWR0    20
+#define GPIO_E740_PCMCIA_PWR1    23
+
+/* e750 PCMCIA GPIO definitions */
+#define GPIO_E750_PCMCIA_CD0      8
+#define GPIO_E750_PCMCIA_RDY0    12
+#define GPIO_E750_PCMCIA_RST0    27
+#define GPIO_E750_PCMCIA_PWR0    20
+
+/* e800 PCMCIA GPIO definitions */
+#define GPIO_E800_PCMCIA_RST0    69
+#define GPIO_E800_PCMCIA_RST1    72
+#define GPIO_E800_PCMCIA_PWR0    20
+#define GPIO_E800_PCMCIA_PWR1    73
+
+/* e7xx IrDA power control */
+#define GPIO_E7XX_IR_ON          38
+
+/* ASIC related GPIOs */
+#define GPIO_ESERIES_TMIO_IRQ        5
+#define GPIO_E800_ANGELX_IRQ      8
diff --git a/include/asm-arm/arch-pxa/eseries-irq.h b/include/asm-arm/arch-pxa/eseries-irq.h
new file mode 100644 (file)
index 0000000..f2a93d5
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  eseries-irq.h
+ *
+ *  Copyright (C) Ian Molton <spyro@f2s.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.
+ *
+ */
+
+#define ANGELX_IRQ_BASE (IRQ_BOARD_START+8)
+#define IRQ_ANGELX(n) (ANGELX_IRQ_BASE + (n))
+
+#define ANGELX_RDY0_IRQ IRQ_ANGELX(0)
+#define ANGELX_ST0_IRQ  IRQ_ANGELX(1)
+#define ANGELX_CD0_IRQ  IRQ_ANGELX(2)
+#define ANGELX_RDY1_IRQ IRQ_ANGELX(3)
+#define ANGELX_ST1_IRQ  IRQ_ANGELX(4)
+#define ANGELX_CD1_IRQ  IRQ_ANGELX(5)
+
+#define TMIO_IRQ_BASE (IRQ_BOARD_START+0)
+#define IRQ_TMIO(n) (TMIO_IRQ_BASE + (n))
+
+#define TMIO_SD_IRQ     IRQ_TMIO(1)
+#define TMIO_USB_IRQ    IRQ_TMIO(2)
+
index d9af6dabc89956c35981bbc8736fa8da68edb015..979a45695d7d43c83681314c0b9021c55f84a410 100644 (file)
                _id == 0x212;                           \
        })
 
+#define __cpu_is_pxa255(id)                             \
+       ({                                              \
+               unsigned int _id = (id) >> 4 & 0xfff;   \
+               _id == 0x2d0;                           \
+        })
+
 #define __cpu_is_pxa25x(id)                            \
        ({                                              \
                unsigned int _id = (id) >> 4 & 0xfff;   \
@@ -76,6 +82,7 @@
        })
 #else
 #define __cpu_is_pxa21x(id)    (0)
+#define __cpu_is_pxa255(id)    (0)
 #define __cpu_is_pxa25x(id)    (0)
 #endif
 
 #define __cpu_is_pxa320(id)    (0)
 #endif
 
+#ifdef CONFIG_CPU_PXA930
+#define __cpu_is_pxa930(id)                            \
+       ({                                              \
+               unsigned int _id = (id) >> 4 & 0xfff;   \
+               _id == 0x683;           \
+        })
+#else
+#define __cpu_is_pxa930(id)    (0)
+#endif
+
 #define cpu_is_pxa21x()                                        \
        ({                                              \
                __cpu_is_pxa21x(read_cpuid_id());       \
        })
 
+#define cpu_is_pxa255()                                 \
+       ({                                              \
+               __cpu_is_pxa255(read_cpuid_id());       \
+       })
+
 #define cpu_is_pxa25x()                                        \
        ({                                              \
                __cpu_is_pxa25x(read_cpuid_id());       \
                __cpu_is_pxa320(read_cpuid_id());       \
         })
 
+#define cpu_is_pxa930()                                        \
+       ({                                              \
+               unsigned int id = read_cpuid(CPUID_ID); \
+               __cpu_is_pxa930(id);                    \
+        })
+
 /*
  * CPUID Core Generation Bit
  * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x
@@ -196,6 +224,11 @@ extern void pxa_gpio_set_value(unsigned gpio, int value);
  */
 extern unsigned int get_memclk_frequency_10khz(void);
 
+/*
+ * register GPIO as reset generator
+ */
+extern int init_gpio_reset(int gpio);
+
 #endif
 
 #if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
index b6c8fe37768315bcc5081490572e2493e15910cf..9413121b0ed9cad890650235b1018e7cf291b1cc 100644 (file)
 #define NR_IRQS                        (IRQ_LOCOMO_SPI_TEND + 1)
 #elif defined(CONFIG_ARCH_LUBBOCK) || \
       defined(CONFIG_MACH_LOGICPD_PXA270) || \
+      defined(CONFIG_MACH_TOSA) || \
       defined(CONFIG_MACH_MAINSTONE) || \
       defined(CONFIG_MACH_PCM027) || \
       defined(CONFIG_MACH_MAGICIAN)
 #define NR_IRQS                        (IRQ_BOARD_END)
+#elif defined(CONFIG_MACH_ZYLONITE)
+#define NR_IRQS                        (IRQ_BOARD_START + 32)
 #else
 #define NR_IRQS                        (IRQ_BOARD_START)
 #endif
index db8d890d237cab93c1ebf7ab493b16244e80a5d2..8de1c0dae624a29ff25b904a063dcf9633f290d2 100644 (file)
 #define GPIO84_GPIO    MFP_CFG_IN(GPIO84, AF0)
 
 extern void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num);
+extern void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm);
 extern int gpio_set_wake(unsigned int gpio, unsigned int on);
 #endif /* __ASM_ARCH_MFP_PXA2XX_H */
diff --git a/include/asm-arm/arch-pxa/mfp-pxa930.h b/include/asm-arm/arch-pxa/mfp-pxa930.h
new file mode 100644 (file)
index 0000000..c4e945a
--- /dev/null
@@ -0,0 +1,491 @@
+/*
+ * linux/include/asm-arm/arch-pxa/mfp-pxa930.h
+ *
+ * PXA930 specific MFP configuration definitions
+ *
+ * Copyright (C) 2007-2008 Marvell International Ltd.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MFP_PXA9xx_H
+#define __ASM_ARCH_MFP_PXA9xx_H
+
+#include <asm/arch/mfp.h>
+#include <asm/arch/mfp-pxa3xx.h>
+
+/* GPIO */
+#define GPIO46_GPIO            MFP_CFG(GPIO46, AF0)
+#define GPIO49_GPIO            MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO            MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO            MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO            MFP_CFG(GPIO52, AF0)
+#define GPIO56_GPIO            MFP_CFG(GPIO56, AF0)
+#define GPIO58_GPIO            MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO            MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO            MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO            MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO            MFP_CFG(GPIO62, AF0)
+
+#define GSIM_UCLK_GPIO_79      MFP_CFG(GSIM_UCLK, AF0)
+#define GSIM_UIO_GPIO_80       MFP_CFG(GSIM_UIO, AF0)
+#define GSIM_nURST_GPIO_81     MFP_CFG(GSIM_nURST, AF0)
+#define GSIM_UDET_GPIO_82      MFP_CFG(GSIM_UDET, AF0)
+
+#define DF_IO15_GPIO_28                MFP_CFG(DF_IO15, AF0)
+#define DF_IO14_GPIO_29                MFP_CFG(DF_IO14, AF0)
+#define DF_IO13_GPIO_30                MFP_CFG(DF_IO13, AF0)
+#define DF_IO12_GPIO_31                MFP_CFG(DF_IO12, AF0)
+#define DF_IO11_GPIO_32                MFP_CFG(DF_IO11, AF0)
+#define DF_IO10_GPIO_33                MFP_CFG(DF_IO10, AF0)
+#define DF_IO9_GPIO_34         MFP_CFG(DF_IO9, AF0)
+#define DF_IO8_GPIO_35         MFP_CFG(DF_IO8, AF0)
+#define DF_IO7_GPIO_36         MFP_CFG(DF_IO7, AF0)
+#define DF_IO6_GPIO_37         MFP_CFG(DF_IO6, AF0)
+#define DF_IO5_GPIO_38         MFP_CFG(DF_IO5, AF0)
+#define DF_IO4_GPIO_39         MFP_CFG(DF_IO4, AF0)
+#define DF_IO3_GPIO_40         MFP_CFG(DF_IO3, AF0)
+#define DF_IO2_GPIO_41         MFP_CFG(DF_IO2, AF0)
+#define DF_IO1_GPIO_42         MFP_CFG(DF_IO1, AF0)
+#define DF_IO0_GPIO_43         MFP_CFG(DF_IO0, AF0)
+#define DF_nCS0_GPIO_44                MFP_CFG(DF_nCS0, AF0)
+#define DF_nCS1_GPIO_45                MFP_CFG(DF_nCS1, AF0)
+#define DF_nWE_GPIO_46         MFP_CFG(DF_nWE, AF0)
+#define DF_nRE_nOE_GPIO_47     MFP_CFG(DF_nRE_nOE, AF0)
+#define DF_CLE_nOE_GPIO_48     MFP_CFG(DF_CLE_nOE, AF0)
+#define DF_nADV1_ALE_GPIO_49   MFP_CFG(DF_nADV1_ALE, AF0)
+#define DF_nADV2_ALE_GPIO_50   MFP_CFG(DF_nADV2_ALE, AF0)
+#define DF_INT_RnB_GPIO_51     MFP_CFG(DF_INT_RnB, AF0)
+#define DF_SCLK_E_GPIO_52      MFP_CFG(DF_SCLK_E, AF0)
+
+#define DF_ADDR0_GPIO_53       MFP_CFG(DF_ADDR0, AF0)
+#define DF_ADDR1_GPIO_54       MFP_CFG(DF_ADDR1, AF0)
+#define DF_ADDR2_GPIO_55       MFP_CFG(DF_ADDR2, AF0)
+#define DF_ADDR3_GPIO_56       MFP_CFG(DF_ADDR3, AF0)
+#define nXCVREN_GPIO_57                MFP_CFG(nXCVREN, AF0)
+#define nLUA_GPIO_58           MFP_CFG(nLUA, AF0)
+#define nLLA_GPIO_59           MFP_CFG(nLLA, AF0)
+#define nBE0_GPIO_60           MFP_CFG(nBE0, AF0)
+#define nBE1_GPIO_61           MFP_CFG(nBE1, AF0)
+#define RDY_GPIO_62            MFP_CFG(RDY, AF0)
+
+/* Chip Select */
+#define DF_nCS0_nCS2           MFP_CFG_LPM(DF_nCS0, AF3, PULL_HIGH)
+#define DF_nCS1_nCS3           MFP_CFG_LPM(DF_nCS1, AF3, PULL_HIGH)
+
+/* AC97 */
+#define GPIO83_BAC97_SYSCLK    MFP_CFG(GPIO83, AF3)
+#define GPIO84_BAC97_SDATA_IN0 MFP_CFG(GPIO84, AF3)
+#define GPIO85_BAC97_BITCLK    MFP_CFG(GPIO85, AF3)
+#define GPIO86_BAC97_nRESET    MFP_CFG(GPIO86, AF3)
+#define GPIO87_BAC97_SYNC      MFP_CFG(GPIO87, AF3)
+#define GPIO88_BAC97_SDATA_OUT MFP_CFG(GPIO88, AF3)
+
+/* I2C */
+#define GPIO39_CI2C_SCL                MFP_CFG_LPM(GPIO39, AF3, PULL_HIGH)
+#define GPIO40_CI2C_SDA                MFP_CFG_LPM(GPIO40, AF3, PULL_HIGH)
+
+#define GPIO51_CI2C_SCL                MFP_CFG_LPM(GPIO51, AF3, PULL_HIGH)
+#define GPIO52_CI2C_SDA                MFP_CFG_LPM(GPIO52, AF3, PULL_HIGH)
+
+#define GPIO63_CI2C_SCL                MFP_CFG_LPM(GPIO63, AF4, PULL_HIGH)
+#define GPIO64_CI2C_SDA                MFP_CFG_LPM(GPIO64, AF4, PULL_HIGH)
+
+#define GPIO77_CI2C_SCL                MFP_CFG_LPM(GPIO77, AF2, PULL_HIGH)
+#define GPIO78_CI2C_SDA                MFP_CFG_LPM(GPIO78, AF2, PULL_HIGH)
+
+#define GPIO89_CI2C_SCL                MFP_CFG_LPM(GPIO89, AF1, PULL_HIGH)
+#define GPIO90_CI2C_SDA                MFP_CFG_LPM(GPIO90, AF1, PULL_HIGH)
+
+#define GPIO95_CI2C_SCL                MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
+#define GPIO96_CI2C_SDA                MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
+
+#define GPIO97_CI2C_SCL                MFP_CFG_LPM(GPIO97, AF3, PULL_HIGH)
+#define GPIO98_CI2C_SDA                MFP_CFG_LPM(GPIO98, AF3, PULL_HIGH)
+
+/* QCI */
+#define GPIO63_CI_DD_9         MFP_CFG_LPM(GPIO63, AF1, PULL_LOW)
+#define GPIO64_CI_DD_8         MFP_CFG_LPM(GPIO64, AF1, PULL_LOW)
+#define GPIO65_CI_DD_7         MFP_CFG_LPM(GPIO65, AF1, PULL_LOW)
+#define GPIO66_CI_DD_6         MFP_CFG_LPM(GPIO66, AF1, PULL_LOW)
+#define GPIO67_CI_DD_5         MFP_CFG_LPM(GPIO67, AF1, PULL_LOW)
+#define GPIO68_CI_DD_4         MFP_CFG_LPM(GPIO68, AF1, PULL_LOW)
+#define GPIO69_CI_DD_3         MFP_CFG_LPM(GPIO69, AF1, PULL_LOW)
+#define GPIO70_CI_DD_2         MFP_CFG_LPM(GPIO70, AF1, PULL_LOW)
+#define GPIO71_CI_DD_1         MFP_CFG_LPM(GPIO71, AF1, PULL_LOW)
+#define GPIO72_CI_DD_0         MFP_CFG_LPM(GPIO72, AF1, PULL_LOW)
+#define GPIO73_CI_HSYNC                MFP_CFG_LPM(GPIO73, AF1, PULL_LOW)
+#define GPIO74_CI_VSYNC                MFP_CFG_LPM(GPIO74, AF1, PULL_LOW)
+#define GPIO75_CI_MCLK         MFP_CFG_LPM(GPIO75, AF1, PULL_LOW)
+#define GPIO76_CI_PCLK         MFP_CFG_LPM(GPIO76, AF1, PULL_LOW)
+
+/* KEYPAD */
+#define GPIO4_KP_DKIN_4                MFP_CFG_LPM(GPIO4, AF3, FLOAT)
+#define GPIO5_KP_DKIN_5                MFP_CFG_LPM(GPIO5, AF3, FLOAT)
+#define GPIO6_KP_DKIN_6                MFP_CFG_LPM(GPIO6, AF3, FLOAT)
+#define GPIO7_KP_DKIN_7                MFP_CFG_LPM(GPIO7, AF3, FLOAT)
+#define GPIO8_KP_DKIN_4                MFP_CFG_LPM(GPIO8, AF3, FLOAT)
+#define GPIO9_KP_DKIN_5                MFP_CFG_LPM(GPIO9, AF3, FLOAT)
+#define GPIO10_KP_DKIN_6       MFP_CFG_LPM(GPIO10, AF3, FLOAT)
+#define GPIO11_KP_DKIN_7       MFP_CFG_LPM(GPIO11, AF3, FLOAT)
+
+#define GPIO12_KP_DKIN_0       MFP_CFG_LPM(GPIO12, AF2, FLOAT)
+#define GPIO13_KP_DKIN_1       MFP_CFG_LPM(GPIO13, AF2, FLOAT)
+#define GPIO14_KP_DKIN_2       MFP_CFG_LPM(GPIO14, AF2, FLOAT)
+#define GPIO15_KP_DKIN_3       MFP_CFG_LPM(GPIO15, AF2, FLOAT)
+
+#define GPIO41_KP_DKIN_0       MFP_CFG_LPM(GPIO41, AF2, FLOAT)
+#define GPIO42_KP_DKIN_1       MFP_CFG_LPM(GPIO42, AF2, FLOAT)
+#define GPIO43_KP_DKIN_2       MFP_CFG_LPM(GPIO43, AF2, FLOAT)
+#define GPIO44_KP_DKIN_3       MFP_CFG_LPM(GPIO44, AF2, FLOAT)
+#define GPIO41_KP_DKIN_4       MFP_CFG_LPM(GPIO41, AF4, FLOAT)
+#define GPIO42_KP_DKIN_5       MFP_CFG_LPM(GPIO42, AF4, FLOAT)
+
+#define GPIO0_KP_MKIN_0                MFP_CFG_LPM(GPIO0, AF1, FLOAT)
+#define GPIO2_KP_MKIN_1                MFP_CFG_LPM(GPIO2, AF1, FLOAT)
+#define GPIO4_KP_MKIN_2                MFP_CFG_LPM(GPIO4, AF1, FLOAT)
+#define GPIO6_KP_MKIN_3                MFP_CFG_LPM(GPIO6, AF1, FLOAT)
+#define GPIO8_KP_MKIN_4                MFP_CFG_LPM(GPIO8, AF1, FLOAT)
+#define GPIO10_KP_MKIN_5       MFP_CFG_LPM(GPIO10, AF1, FLOAT)
+#define GPIO12_KP_MKIN_6       MFP_CFG_LPM(GPIO12, AF1, FLOAT)
+#define GPIO14_KP_MKIN_7       MFP_CFG(GPIO14, AF1)
+#define GPIO35_KP_MKIN_5       MFP_CFG(GPIO35, AF4)
+
+#define GPIO1_KP_MKOUT_0       MFP_CFG_LPM(GPIO1, AF1, DRIVE_HIGH)
+#define GPIO3_KP_MKOUT_1       MFP_CFG_LPM(GPIO3, AF1, DRIVE_HIGH)
+#define GPIO5_KP_MKOUT_2       MFP_CFG_LPM(GPIO5, AF1, DRIVE_HIGH)
+#define GPIO7_KP_MKOUT_3       MFP_CFG_LPM(GPIO7, AF1, DRIVE_HIGH)
+#define GPIO9_KP_MKOUT_4       MFP_CFG_LPM(GPIO9, AF1, DRIVE_HIGH)
+#define GPIO11_KP_MKOUT_5      MFP_CFG_LPM(GPIO11, AF1, DRIVE_HIGH)
+#define GPIO13_KP_MKOUT_6      MFP_CFG_LPM(GPIO13, AF1, DRIVE_HIGH)
+#define GPIO15_KP_MKOUT_7      MFP_CFG_LPM(GPIO15, AF1, DRIVE_HIGH)
+#define GPIO36_KP_MKOUT_5      MFP_CFG_LPM(GPIO36, AF4, DRIVE_HIGH)
+
+/* LCD */
+#define GPIO17_LCD_FCLK_RD     MFP_CFG(GPIO17, AF1)
+#define GPIO18_LCD_LCLK_A0     MFP_CFG(GPIO18, AF1)
+#define GPIO19_LCD_PCLK_WR     MFP_CFG(GPIO19, AF1)
+#define GPIO20_LCD_BIAS                MFP_CFG(GPIO20, AF1)
+#define GPIO21_LCD_CS          MFP_CFG(GPIO21, AF1)
+#define GPIO22_LCD_CS2         MFP_CFG(GPIO22, AF2)
+#define GPIO22_LCD_VSYNC       MFP_CFG(GPIO22, AF1)
+#define GPIO23_LCD_DD0         MFP_CFG(GPIO23, AF1)
+#define GPIO24_LCD_DD1         MFP_CFG(GPIO24, AF1)
+#define GPIO25_LCD_DD2         MFP_CFG(GPIO25, AF1)
+#define GPIO26_LCD_DD3         MFP_CFG(GPIO26, AF1)
+#define GPIO27_LCD_DD4         MFP_CFG(GPIO27, AF1)
+#define GPIO28_LCD_DD5         MFP_CFG(GPIO28, AF1)
+#define GPIO29_LCD_DD6         MFP_CFG(GPIO29, AF1)
+#define GPIO30_LCD_DD7         MFP_CFG(GPIO30, AF1)
+#define GPIO31_LCD_DD8         MFP_CFG(GPIO31, AF1)
+#define GPIO32_LCD_DD9         MFP_CFG(GPIO32, AF1)
+#define GPIO33_LCD_DD10                MFP_CFG(GPIO33, AF1)
+#define GPIO34_LCD_DD11                MFP_CFG(GPIO34, AF1)
+#define GPIO35_LCD_DD12                MFP_CFG(GPIO35, AF1)
+#define GPIO36_LCD_DD13                MFP_CFG(GPIO36, AF1)
+#define GPIO37_LCD_DD14                MFP_CFG(GPIO37, AF1)
+#define GPIO38_LCD_DD15                MFP_CFG(GPIO38, AF1)
+#define GPIO39_LCD_DD16                MFP_CFG(GPIO39, AF1)
+#define GPIO40_LCD_DD17                MFP_CFG(GPIO40, AF1)
+#define GPIO41_LCD_CS2         MFP_CFG(GPIO41, AF3)
+#define GPIO42_LCD_VSYNC2      MFP_CFG(GPIO42, AF3)
+#define GPIO44_LCD_DD7         MFP_CFG(GPIO44, AF1)
+
+/* Mini-LCD */
+#define GPIO17_MLCD_FCLK       MFP_CFG(GPIO17, AF3)
+#define GPIO18_MLCD_LCLK       MFP_CFG(GPIO18, AF3)
+#define GPIO19_MLCD_PCLK       MFP_CFG(GPIO19, AF3)
+#define GPIO20_MLCD_BIAS       MFP_CFG(GPIO20, AF3)
+#define GPIO23_MLCD_DD0                MFP_CFG(GPIO23, AF3)
+#define GPIO24_MLCD_DD1                MFP_CFG(GPIO24, AF3)
+#define GPIO25_MLCD_DD2                MFP_CFG(GPIO25, AF3)
+#define GPIO26_MLCD_DD3                MFP_CFG(GPIO26, AF3)
+#define GPIO27_MLCD_DD4                MFP_CFG(GPIO27, AF3)
+#define GPIO28_MLCD_DD5                MFP_CFG(GPIO28, AF3)
+#define GPIO29_MLCD_DD6                MFP_CFG(GPIO29, AF3)
+#define GPIO30_MLCD_DD7                MFP_CFG(GPIO30, AF3)
+#define GPIO31_MLCD_DD8                MFP_CFG(GPIO31, AF3)
+#define GPIO32_MLCD_DD9                MFP_CFG(GPIO32, AF3)
+#define GPIO33_MLCD_DD10       MFP_CFG(GPIO33, AF3)
+#define GPIO34_MLCD_DD11       MFP_CFG(GPIO34, AF3)
+#define GPIO35_MLCD_DD12       MFP_CFG(GPIO35, AF3)
+#define GPIO36_MLCD_DD13       MFP_CFG(GPIO36, AF3)
+#define GPIO37_MLCD_DD14       MFP_CFG(GPIO37, AF3)
+#define GPIO38_MLCD_DD15       MFP_CFG(GPIO38, AF3)
+#define GPIO44_MLCD_DD7                MFP_CFG(GPIO44, AF5)
+
+/* MMC1 */
+#define GPIO10_MMC1_DAT3       MFP_CFG(GPIO10, AF4)
+#define GPIO11_MMC1_DAT2       MFP_CFG(GPIO11, AF4)
+#define GPIO12_MMC1_DAT1       MFP_CFG(GPIO12, AF4)
+#define GPIO13_MMC1_DAT0       MFP_CFG(GPIO13, AF4)
+#define GPIO14_MMC1_CMD                MFP_CFG(GPIO14, AF4)
+#define GPIO15_MMC1_CLK                MFP_CFG(GPIO15, AF4)
+#define GPIO55_MMC1_CMD                MFP_CFG(GPIO55, AF3)
+#define GPIO56_MMC1_CLK                MFP_CFG(GPIO56, AF3)
+#define GPIO57_MMC1_DAT0       MFP_CFG(GPIO57, AF3)
+#define GPIO58_MMC1_DAT1       MFP_CFG(GPIO58, AF3)
+#define GPIO59_MMC1_DAT2       MFP_CFG(GPIO59, AF3)
+#define GPIO60_MMC1_DAT3       MFP_CFG(GPIO60, AF3)
+
+#define DF_ADDR0_MMC1_CLK      MFP_CFG(DF_ADDR0, AF2)
+#define DF_ADDR1_MMC1_CMD      MFP_CFG(DF_ADDR1, AF2)
+#define DF_ADDR2_MMC1_DAT0     MFP_CFG(DF_ADDR2, AF2)
+#define DF_ADDR3_MMC1_DAT1     MFP_CFG(DF_ADDR3, AF3)
+#define nXCVREN_MMC1_DAT2      MFP_CFG(nXCVREN, AF2)
+
+/* MMC2 */
+#define GPIO31_MMC2_CMD                MFP_CFG(GPIO31, AF7)
+#define GPIO32_MMC2_CLK                MFP_CFG(GPIO32, AF7)
+#define GPIO33_MMC2_DAT0       MFP_CFG(GPIO33, AF7)
+#define GPIO34_MMC2_DAT1       MFP_CFG(GPIO34, AF7)
+#define GPIO35_MMC2_DAT2       MFP_CFG(GPIO35, AF7)
+#define GPIO36_MMC2_DAT3       MFP_CFG(GPIO36, AF7)
+
+#define GPIO101_MMC2_DAT3      MFP_CFG(GPIO101, AF1)
+#define GPIO102_MMC2_DAT2      MFP_CFG(GPIO102, AF1)
+#define GPIO103_MMC2_DAT1      MFP_CFG(GPIO103, AF1)
+#define GPIO104_MMC2_DAT0      MFP_CFG(GPIO104, AF1)
+#define GPIO105_MMC2_CMD       MFP_CFG(GPIO105, AF1)
+#define GPIO106_MMC2_CLK       MFP_CFG(GPIO106, AF1)
+
+#define DF_IO10_MMC2_DAT3      MFP_CFG(DF_IO10, AF3)
+#define DF_IO11_MMC2_DAT2      MFP_CFG(DF_IO11, AF3)
+#define DF_IO12_MMC2_DAT1      MFP_CFG(DF_IO12, AF3)
+#define DF_IO13_MMC2_DAT0      MFP_CFG(DF_IO13, AF3)
+#define DF_IO14_MMC2_CLK       MFP_CFG(DF_IO14, AF3)
+#define DF_IO15_MMC2_CMD       MFP_CFG(DF_IO15, AF3)
+
+/* BSSP1 */
+#define GPIO12_BSSP1_CLK       MFP_CFG(GPIO12, AF3)
+#define GPIO13_BSSP1_FRM       MFP_CFG(GPIO13, AF3)
+#define GPIO14_BSSP1_RXD       MFP_CFG(GPIO14, AF3)
+#define GPIO15_BSSP1_TXD       MFP_CFG(GPIO15, AF3)
+#define GPIO97_BSSP1_CLK       MFP_CFG(GPIO97, AF5)
+#define GPIO98_BSSP1_FRM       MFP_CFG(GPIO98, AF5)
+
+/* BSSP2 */
+#define GPIO84_BSSP2_SDATA_IN  MFP_CFG(GPIO84, AF1)
+#define GPIO85_BSSP2_BITCLK    MFP_CFG(GPIO85, AF1)
+#define GPIO86_BSSP2_SYSCLK    MFP_CFG(GPIO86, AF1)
+#define GPIO87_BSSP2_SYNC      MFP_CFG(GPIO87, AF1)
+#define GPIO88_BSSP2_DATA_OUT  MFP_CFG(GPIO88, AF1)
+#define GPIO86_BSSP2_SDATA_IN  MFP_CFG(GPIO86, AF4)
+
+/* BSSP3 */
+#define GPIO79_BSSP3_CLK       MFP_CFG(GPIO79, AF1)
+#define GPIO80_BSSP3_FRM       MFP_CFG(GPIO80, AF1)
+#define GPIO81_BSSP3_TXD       MFP_CFG(GPIO81, AF1)
+#define GPIO82_BSSP3_RXD       MFP_CFG(GPIO82, AF1)
+#define GPIO83_BSSP3_SYSCLK    MFP_CFG(GPIO83, AF1)
+
+/* BSSP4 */
+#define GPIO43_BSSP4_CLK       MFP_CFG(GPIO43, AF4)
+#define GPIO44_BSSP4_FRM       MFP_CFG(GPIO44, AF4)
+#define GPIO45_BSSP4_TXD       MFP_CFG(GPIO45, AF4)
+#define GPIO46_BSSP4_RXD       MFP_CFG(GPIO46, AF4)
+
+#define GPIO51_BSSP4_CLK       MFP_CFG(GPIO51, AF4)
+#define GPIO52_BSSP4_FRM       MFP_CFG(GPIO52, AF4)
+#define GPIO53_BSSP4_TXD       MFP_CFG(GPIO53, AF4)
+#define GPIO54_BSSP4_RXD       MFP_CFG(GPIO54, AF4)
+
+/* GSSP1 */
+#define GPIO79_GSSP1_CLK       MFP_CFG(GPIO79, AF2)
+#define GPIO80_GSSP1_FRM       MFP_CFG(GPIO80, AF2)
+#define GPIO81_GSSP1_TXD       MFP_CFG(GPIO81, AF2)
+#define GPIO82_GSSP1_RXD       MFP_CFG(GPIO82, AF2)
+#define GPIO83_GSSP1_SYSCLK    MFP_CFG(GPIO83, AF2)
+
+#define GPIO93_GSSP1_CLK       MFP_CFG(GPIO93, AF4)
+#define GPIO94_GSSP1_FRM       MFP_CFG(GPIO94, AF4)
+#define GPIO95_GSSP1_TXD       MFP_CFG(GPIO95, AF4)
+#define GPIO96_GSSP1_RXD       MFP_CFG(GPIO96, AF4)
+
+/* GSSP2 */
+#define GPIO47_GSSP2_CLK       MFP_CFG(GPIO47, AF4)
+#define GPIO48_GSSP2_FRM       MFP_CFG(GPIO48, AF4)
+#define GPIO49_GSSP2_RXD       MFP_CFG(GPIO49, AF4)
+#define GPIO50_GSSP2_TXD       MFP_CFG(GPIO50, AF4)
+
+#define GPIO69_GSSP2_CLK       MFP_CFG(GPIO69, AF4)
+#define GPIO70_GSSP2_FRM       MFP_CFG(GPIO70, AF4)
+#define GPIO71_GSSP2_RXD       MFP_CFG(GPIO71, AF4)
+#define GPIO72_GSSP2_TXD       MFP_CFG(GPIO72, AF4)
+
+#define GPIO84_GSSP2_RXD       MFP_CFG(GPIO84, AF2)
+#define GPIO85_GSSP2_CLK       MFP_CFG(GPIO85, AF2)
+#define GPIO86_GSSP2_SYSCLK    MFP_CFG(GPIO86, AF2)
+#define GPIO87_GSSP2_FRM       MFP_CFG(GPIO87, AF2)
+#define GPIO88_GSSP2_TXD       MFP_CFG(GPIO88, AF2)
+#define GPIO86_GSSP2_RXD       MFP_CFG(GPIO86, AF5)
+
+#define GPIO103_GSSP2_CLK      MFP_CFG(GPIO103, AF2)
+#define GPIO104_GSSP2_FRM      MFP_CFG(GPIO104, AF2)
+#define GPIO105_GSSP2_RXD      MFP_CFG(GPIO105, AF2)
+#define GPIO106_GSSP2_TXD      MFP_CFG(GPIO106, AF2)
+
+/* UART1 - FFUART */
+#define GPIO47_UART1_DSR_N     MFP_CFG(GPIO47, AF1)
+#define GPIO48_UART1_DTR_N     MFP_CFG(GPIO48, AF1)
+#define GPIO49_UART1_RI                MFP_CFG(GPIO49, AF1)
+#define GPIO50_UART1_DCD       MFP_CFG(GPIO50, AF1)
+#define GPIO51_UART1_CTS       MFP_CFG(GPIO51, AF1)
+#define GPIO52_UART1_RTS       MFP_CFG(GPIO52, AF1)
+#define GPIO53_UART1_RXD       MFP_CFG(GPIO53, AF1)
+#define GPIO54_UART1_TXD       MFP_CFG(GPIO54, AF1)
+
+#define GPIO63_UART1_TXD       MFP_CFG(GPIO63, AF2)
+#define GPIO64_UART1_RXD       MFP_CFG(GPIO64, AF2)
+#define GPIO65_UART1_DSR       MFP_CFG(GPIO65, AF2)
+#define GPIO66_UART1_DTR       MFP_CFG(GPIO66, AF2)
+#define GPIO67_UART1_RI                MFP_CFG(GPIO67, AF2)
+#define GPIO68_UART1_DCD       MFP_CFG(GPIO68, AF2)
+#define GPIO69_UART1_CTS       MFP_CFG(GPIO69, AF2)
+#define GPIO70_UART1_RTS       MFP_CFG(GPIO70, AF2)
+
+/* UART2 - BTUART */
+#define GPIO91_UART2_RXD       MFP_CFG(GPIO91, AF1)
+#define GPIO92_UART2_TXD       MFP_CFG(GPIO92, AF1)
+#define GPIO93_UART2_CTS       MFP_CFG(GPIO93, AF1)
+#define GPIO94_UART2_RTS       MFP_CFG(GPIO94, AF1)
+
+/* UART3 - STUART */
+#define GPIO43_UART3_RTS       MFP_CFG(GPIO43, AF3)
+#define GPIO44_UART3_CTS       MFP_CFG(GPIO44, AF3)
+#define GPIO45_UART3_RXD       MFP_CFG(GPIO45, AF3)
+#define GPIO46_UART3_TXD       MFP_CFG(GPIO46, AF3)
+
+#define GPIO75_UART3_RTS       MFP_CFG(GPIO75, AF5)
+#define GPIO76_UART3_CTS       MFP_CFG(GPIO76, AF5)
+#define GPIO77_UART3_TXD       MFP_CFG(GPIO77, AF5)
+#define GPIO78_UART3_RXD       MFP_CFG(GPIO78, AF5)
+
+/* DFI */
+#define DF_IO0_DF_IO0          MFP_CFG(DF_IO0, AF2)
+#define DF_IO1_DF_IO1          MFP_CFG(DF_IO1, AF2)
+#define DF_IO2_DF_IO2          MFP_CFG(DF_IO2, AF2)
+#define DF_IO3_DF_IO3          MFP_CFG(DF_IO3, AF2)
+#define DF_IO4_DF_IO4          MFP_CFG(DF_IO4, AF2)
+#define DF_IO5_DF_IO5          MFP_CFG(DF_IO5, AF2)
+#define DF_IO6_DF_IO6          MFP_CFG(DF_IO6, AF2)
+#define DF_IO7_DF_IO7          MFP_CFG(DF_IO7, AF2)
+#define DF_IO8_DF_IO8          MFP_CFG(DF_IO8, AF2)
+#define DF_IO9_DF_IO9          MFP_CFG(DF_IO9, AF2)
+#define DF_IO10_DF_IO10                MFP_CFG(DF_IO10, AF2)
+#define DF_IO11_DF_IO11                MFP_CFG(DF_IO11, AF2)
+#define DF_IO12_DF_IO12                MFP_CFG(DF_IO12, AF2)
+#define DF_IO13_DF_IO13                MFP_CFG(DF_IO13, AF2)
+#define DF_IO14_DF_IO14                MFP_CFG(DF_IO14, AF2)
+#define DF_IO15_DF_IO15                MFP_CFG(DF_IO15, AF2)
+#define DF_nADV1_ALE_DF_nADV1  MFP_CFG(DF_nADV1_ALE, AF2)
+#define DF_nADV2_ALE_DF_nADV2  MFP_CFG(DF_nADV2_ALE, AF2)
+#define DF_nCS0_DF_nCS0                MFP_CFG(DF_nCS0, AF2)
+#define DF_nCS1_DF_nCS1                MFP_CFG(DF_nCS1, AF2)
+#define DF_nRE_nOE_DF_nOE      MFP_CFG(DF_nRE_nOE, AF2)
+#define DF_nWE_DF_nWE          MFP_CFG(DF_nWE, AF2)
+
+/* DFI - NAND */
+#define DF_CLE_nOE_ND_CLE      MFP_CFG_LPM(DF_CLE_nOE, AF1, PULL_HIGH)
+#define DF_INT_RnB_ND_INT_RnB  MFP_CFG_LPM(DF_INT_RnB, AF1, PULL_LOW)
+#define DF_IO0_ND_IO0          MFP_CFG_LPM(DF_IO0, AF1, PULL_LOW)
+#define DF_IO1_ND_IO1          MFP_CFG_LPM(DF_IO1, AF1, PULL_LOW)
+#define DF_IO2_ND_IO2          MFP_CFG_LPM(DF_IO2, AF1, PULL_LOW)
+#define DF_IO3_ND_IO3          MFP_CFG_LPM(DF_IO3, AF1, PULL_LOW)
+#define DF_IO4_ND_IO4          MFP_CFG_LPM(DF_IO4, AF1, PULL_LOW)
+#define DF_IO5_ND_IO5          MFP_CFG_LPM(DF_IO5, AF1, PULL_LOW)
+#define DF_IO6_ND_IO6          MFP_CFG_LPM(DF_IO6, AF1, PULL_LOW)
+#define DF_IO7_ND_IO7          MFP_CFG_LPM(DF_IO7, AF1, PULL_LOW)
+#define DF_IO8_ND_IO8          MFP_CFG_LPM(DF_IO8, AF1, PULL_LOW)
+#define DF_IO9_ND_IO9          MFP_CFG_LPM(DF_IO9, AF1, PULL_LOW)
+#define DF_IO10_ND_IO10                MFP_CFG_LPM(DF_IO10, AF1, PULL_LOW)
+#define DF_IO11_ND_IO11                MFP_CFG_LPM(DF_IO11, AF1, PULL_LOW)
+#define DF_IO12_ND_IO12                MFP_CFG_LPM(DF_IO12, AF1, PULL_LOW)
+#define DF_IO13_ND_IO13                MFP_CFG_LPM(DF_IO13, AF1, PULL_LOW)
+#define DF_IO14_ND_IO14                MFP_CFG_LPM(DF_IO14, AF1, PULL_LOW)
+#define DF_IO15_ND_IO15                MFP_CFG_LPM(DF_IO15, AF1, PULL_LOW)
+#define DF_nADV1_ALE_ND_ALE    MFP_CFG_LPM(DF_nADV1_ALE, AF1, PULL_HIGH)
+#define DF_nADV2_ALE_ND_ALE    MFP_CFG_LPM(DF_nADV2_ALE, AF1, PULL_HIGH)
+#define        DF_nADV2_ALE_nCS3       MFP_CFG_LPM(DF_nADV2_ALE, AF3, PULL_HIGH)
+#define DF_nCS0_ND_nCS0                MFP_CFG_LPM(DF_nCS0, AF1, PULL_HIGH)
+#define DF_nCS1_ND_nCS1                MFP_CFG_LPM(DF_nCS1, AF1, PULL_HIGH)
+#define DF_nRE_nOE_ND_nRE      MFP_CFG_LPM(DF_nRE_nOE, AF1, PULL_HIGH)
+#define DF_nWE_ND_nWE          MFP_CFG_LPM(DF_nWE, AF1, PULL_HIGH)
+
+/* PWM */
+#define GPIO41_PWM0            MFP_CFG_LPM(GPIO41, AF1, PULL_LOW)
+#define GPIO42_PWM1            MFP_CFG_LPM(GPIO42, AF1, PULL_LOW)
+#define GPIO43_PWM3            MFP_CFG_LPM(GPIO43, AF1, PULL_LOW)
+#define GPIO20_PWM0            MFP_CFG_LPM(GPIO20, AF2, PULL_LOW)
+#define GPIO21_PWM2            MFP_CFG_LPM(GPIO21, AF3, PULL_LOW)
+#define GPIO22_PWM3            MFP_CFG_LPM(GPIO22, AF3, PULL_LOW)
+
+/* CIR */
+#define GPIO46_CIR_OUT         MFP_CFG(GPIO46, AF1)
+#define GPIO77_CIR_OUT         MFP_CFG(GPIO77, AF3)
+
+/* USB P2 */
+#define GPIO0_USB_P2_7         MFP_CFG(GPIO0, AF3)
+#define GPIO15_USB_P2_7                MFP_CFG(GPIO15, AF5)
+#define GPIO16_USB_P2_7                MFP_CFG(GPIO16, AF2)
+#define GPIO48_USB_P2_7                MFP_CFG(GPIO48, AF7)
+#define GPIO49_USB_P2_7                MFP_CFG(GPIO49, AF6)
+#define DF_IO9_USB_P2_7                MFP_CFG(DF_IO9, AF3)
+
+#define GPIO48_USB_P2_8                MFP_CFG(GPIO48, AF2)
+#define GPIO50_USB_P2_7                MFP_CFG_X(GPIO50, AF2, DS02X, FLOAT)
+#define GPIO51_USB_P2_5                MFP_CFG(GPIO51, AF2)
+#define GPIO47_USB_P2_4                MFP_CFG(GPIO47, AF2)
+#define GPIO53_USB_P2_3                MFP_CFG(GPIO53, AF2)
+#define GPIO54_USB_P2_6                MFP_CFG(GPIO54, AF2)
+#define GPIO49_USB_P2_2                MFP_CFG(GPIO49, AF2)
+#define GPIO52_USB_P2_1                MFP_CFG(GPIO52, AF2)
+
+#define GPIO63_USB_P2_8                MFP_CFG(GPIO63, AF3)
+#define GPIO64_USB_P2_7                MFP_CFG(GPIO64, AF3)
+#define GPIO65_USB_P2_6                MFP_CFG(GPIO65, AF3)
+#define GPIO66_USG_P2_5                MFP_CFG(GPIO66, AF3)
+#define GPIO67_USB_P2_4                MFP_CFG(GPIO67, AF3)
+#define GPIO68_USB_P2_3                MFP_CFG(GPIO68, AF3)
+#define GPIO69_USB_P2_2                MFP_CFG(GPIO69, AF3)
+#define GPIO70_USB_P2_1                MFP_CFG(GPIO70, AF3)
+
+/* ULPI */
+#define GPIO31_USB_ULPI_D0     MFP_CFG(GPIO31, AF4)
+#define GPIO30_USB_ULPI_D1     MFP_CFG(GPIO30, AF7)
+#define GPIO33_USB_ULPI_D2     MFP_CFG(GPIO33, AF5)
+#define GPIO34_USB_ULPI_D3     MFP_CFG(GPIO34, AF5)
+#define GPIO35_USB_ULPI_D4     MFP_CFG(GPIO35, AF5)
+#define GPIO36_USB_ULPI_D5     MFP_CFG(GPIO36, AF5)
+#define GPIO41_USB_ULPI_D6     MFP_CFG(GPIO41, AF5)
+#define GPIO42_USB_ULPI_D7     MFP_CFG(GPIO42, AF5)
+#define GPIO37_USB_ULPI_DIR    MFP_CFG(GPIO37, AF4)
+#define GPIO38_USB_ULPI_CLK    MFP_CFG(GPIO38, AF4)
+#define GPIO39_USB_ULPI_STP    MFP_CFG(GPIO39, AF4)
+#define GPIO40_USB_ULPI_NXT    MFP_CFG(GPIO40, AF4)
+
+#define GPIO3_CLK26MOUTDMD     MFP_CFG(GPIO3, AF3)
+#define GPIO40_CLK26MOUTDMD    MFP_CFG(GPIO40, AF7)
+#define GPIO94_CLK26MOUTDMD    MFP_CFG(GPIO94, AF5)
+#define GPIO104_CLK26MOUTDMD   MFP_CFG(GPIO104, AF4)
+#define DF_ADDR1_CLK26MOUTDMD  MFP_CFG(DF_ADDR2, AF3)
+#define DF_ADDR3_CLK26MOUTDMD  MFP_CFG(DF_ADDR3, AF3)
+
+#define GPIO14_CLK26MOUT       MFP_CFG(GPIO14, AF5)
+#define GPIO38_CLK26MOUT       MFP_CFG(GPIO38, AF7)
+#define GPIO92_CLK26MOUT       MFP_CFG(GPIO92, AF5)
+#define GPIO105_CLK26MOUT      MFP_CFG(GPIO105, AF4)
+
+#define GPIO2_CLK13MOUTDMD     MFP_CFG(GPIO2, AF3)
+#define GPIO39_CLK13MOUTDMD    MFP_CFG(GPIO39, AF7)
+#define GPIO50_CLK13MOUTDMD    MFP_CFG(GPIO50, AF3)
+#define GPIO93_CLK13MOUTDMD    MFP_CFG(GPIO93, AF5)
+#define GPIO103_CLK13MOUTDMD   MFP_CFG(GPIO103, AF4)
+#define DF_ADDR2_CLK13MOUTDMD  MFP_CFG(DF_ADDR2, AF3)
+
+/* 1 wire */
+#define GPIO95_OW_DQ_IN                MFP_CFG(GPIO95, AF5)
+
+#endif /* __ASM_ARCH_MFP_PXA9xx_H */
index 02f6157396d3b8f0b70b63922ec3ae30f26cdcfc..e7d58798da6769e1b4922419d565617c1313f22b 100644 (file)
@@ -210,6 +210,14 @@ enum {
        MFP_PIN_DF_IO14,
        MFP_PIN_DF_IO15,
 
+       /* additional pins on PXA930 */
+       MFP_PIN_GSIM_UIO,
+       MFP_PIN_GSIM_UCLK,
+       MFP_PIN_GSIM_UDET,
+       MFP_PIN_GSIM_nURST,
+       MFP_PIN_PMIC_INT,
+       MFP_PIN_RDY,
+
        MFP_PIN_MAX,
 };
 
diff --git a/include/asm-arm/arch-pxa/palmtx.h b/include/asm-arm/arch-pxa/palmtx.h
new file mode 100644 (file)
index 0000000..1e8bccb
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * GPIOs and interrupts for Palm T|X Handheld Computer
+ *
+ * Based on palmld-gpio.h by Alex Osborne
+ *
+ * Authors:    Marek Vasut <marek.vasut@gmail.com>
+ *             Cristiano P. <cristianop@users.sourceforge.net>
+ *             Jan Herman <2hp@seznam.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _INCLUDE_PALMTX_H_
+#define _INCLUDE_PALMTX_H_
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMTX_GPIO_RESET              1
+
+#define GPIO_NR_PALMTX_POWER_DETECT            12 /* 90 */
+#define GPIO_NR_PALMTX_HOTSYNC_BUTTON_N                10
+#define GPIO_NR_PALMTX_EARPHONE_DETECT         107
+
+/* SD/MMC */
+#define GPIO_NR_PALMTX_SD_DETECT_N             14
+#define GPIO_NR_PALMTX_SD_POWER                        114 /* probably */
+#define GPIO_NR_PALMTX_SD_READONLY             115 /* probably */
+
+/* TOUCHSCREEN */
+#define GPIO_NR_PALMTX_WM9712_IRQ              27
+
+/* IRDA -  disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
+#define GPIO_NR_PALMTX_IR_DISABLE              40
+
+/* USB */
+#define GPIO_NR_PALMTX_USB_DETECT_N            13
+#define GPIO_NR_PALMTX_USB_POWER               95
+#define GPIO_NR_PALMTX_USB_PULLUP              93
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMTX_BL_POWER                        84
+#define GPIO_NR_PALMTX_LCD_POWER               96
+
+/* LCD BORDER */
+#define GPIO_NR_PALMTX_BORDER_SWITCH           98
+#define GPIO_NR_PALMTX_BORDER_SELECT           22
+
+/* BLUETOOTH */
+#define GPIO_NR_PALMTX_BT_POWER                        17
+#define GPIO_NR_PALMTX_BT_RESET                        83
+
+/* PCMCIA (WiFi) */
+#define GPIO_NR_PALMTX_PCMCIA_POWER1           94
+#define GPIO_NR_PALMTX_PCMCIA_POWER2           108
+#define GPIO_NR_PALMTX_PCMCIA_RESET            79
+#define GPIO_NR_PALMTX_PCMCIA_READY            116
+
+/* NAND Flash ... this GPIO may be incorrect! */
+#define GPIO_NR_PALMTX_NAND_BUFFER_DIR         79
+
+/* INTERRUPTS */
+#define IRQ_GPIO_PALMTX_SD_DETECT_N    IRQ_GPIO(GPIO_NR_PALMTX_SD_DETECT_N)
+#define IRQ_GPIO_PALMTX_WM9712_IRQ     IRQ_GPIO(GPIO_NR_PALMTX_WM9712_IRQ)
+#define IRQ_GPIO_PALMTX_USB_DETECT     IRQ_GPIO(GPIO_NR_PALMTX_USB_DETECT)
+#define IRQ_GPIO_PALMTX_GPIO_RESET     IRQ_GPIO(GPIO_NR_PALMTX_GPIO_RESET)
+
+/** HERE ARE INIT VALUES **/
+
+/* Various addresses  */
+#define PALMTX_PCMCIA_PHYS     0x28000000
+#define PALMTX_PCMCIA_VIRT     0xf0000000
+#define PALMTX_PCMCIA_SIZE     0x100000
+
+#define PALMTX_PHYS_RAM_START  0xa0000000
+#define PALMTX_PHYS_IO_START   0x40000000
+
+#define PALMTX_PHYS_FLASH_START        PXA_CS0_PHYS    /* ChipSelect 0 */
+#define PALMTX_PHYS_NAND_START PXA_CS1_PHYS    /* ChipSelect 1 */
+
+/* TOUCHSCREEN */
+#define AC97_LINK_FRAME                        21
+
+
+/* BATTERY */
+#define PALMTX_BAT_MAX_VOLTAGE         4000    /* 4.00v current voltage */
+#define PALMTX_BAT_MIN_VOLTAGE         3550    /* 3.55v critical voltage */
+#define PALMTX_BAT_MAX_CURRENT         0       /* unknokn */
+#define PALMTX_BAT_MIN_CURRENT         0       /* unknown */
+#define PALMTX_BAT_MAX_CHARGE          1       /* unknown */
+#define PALMTX_BAT_MIN_CHARGE          1       /* unknown */
+#define PALMTX_MAX_LIFE_MINS           360     /* on-life in minutes */
+
+#define PALMTX_BAT_MEASURE_DELAY       (HZ * 1)
+
+/* BACKLIGHT */
+#define PALMTX_MAX_INTENSITY           0xFE
+#define PALMTX_DEFAULT_INTENSITY       0x7E
+#define PALMTX_LIMIT_MASK              0x7F
+#define PALMTX_PRESCALER               0x3F
+#define PALMTX_PERIOD_NS               3500
+
+#endif
index bc1cf7d0773a6873b533211f76aaca2b84ea1da7..ab1443f8bd89a3ebad4b57cbfe4315bda6a02210 100644 (file)
@@ -97,7 +97,7 @@
 #define UP2OCR_IDON            (1 << 10)       /* OTG ID Read Enable */
 #define UP2OCR_HXS             (1 << 16)       /* Host Port 2 Transceiver Output Select */
 #define UP2OCR_HXOE            (1 << 17)       /* Host Port 2 Transceiver Output Enable */
-#define UP2OCR_SEOS            (1 << 24)       /* Single-Ended Output Select */
+#define UP2OCR_SEOS(x)         ((x & 7) << 24) /* Single-Ended Output Select */
 
 #define UDCCSN(x)      __REG2(0x40600100, (x) << 2)
 #define UDCCSR0         __REG(0x40600100) /* UDC Control/Status register - Endpoint 0 */
index 3459fb26ce978c2b04a129bcf036360b04fcdca2..2206cb61a9f918060d2416adea78fa83b1cfeae9 100644 (file)
@@ -41,4 +41,6 @@ struct pxa2xx_spi_chip {
        void (*cs_control)(u32 command);
 };
 
+extern void pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info);
+
 #endif /*PXA2XX_SPI_H_*/
index 81a8937486cbbcf1ef21ef7f6ff9d867c5cb0d98..eb4b190b6657256898dfbc2da475a32a98ee6f4d 100644 (file)
@@ -15,4 +15,6 @@ struct pxa3xx_nand_platform_data {
        struct mtd_partition *parts;
        unsigned int    nr_parts;
 };
+
+extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info);
 #endif /* __ASM_ARCH_PXA3XX_NAND_H */
index bbd22396841ae15d0eefcd235ffeccd9abdacb8b..daf018d0c60409cbaa4ad53bf6b181fd1e5bbcc7 100644 (file)
@@ -71,7 +71,8 @@ struct pxafb_mode_info {
 
        u_char          bpp;
        u_int           cmap_greyscale:1,
-                       unused:31;
+                       depth:8,
+                       unused:23;
 
        /* Parallel Mode Timing */
        u_char          hsync_len;
index 3ba464c913a5d9afa891e1d4a761973f2f5889bb..820a189684a9308109ecb712fade173302c5a345 100644 (file)
 #define LCCR3_4BPP     (2 << 24)
 #define LCCR3_8BPP     (3 << 24)
 #define LCCR3_16BPP    (4 << 24)
+#define LCCR3_18BPP    (5 << 24)
+#define LCCR3_18BPP_P  (6 << 24)
+#define LCCR3_19BPP    (7 << 24)
+#define LCCR3_19BPP_P  (1 << 29)
+#define LCCR3_24BPP    ((1 << 29) | (1 << 24))
+#define LCCR3_25BPP    ((1 << 29) | (2 << 24))
 
 #define LCCR3_PDFOR_0  (0 << 30)
 #define LCCR3_PDFOR_1  (1 << 30)
index 0255328c3c18814d0ed94762c39c9162cca153e7..3c04cde2cf1f9f1b9fb97cad1c355fd0d0b17329 100644 (file)
 #define SSTSS          (0x38)  /* SSP Timeslot Status */
 #define SSACD          (0x3C)  /* SSP Audio Clock Divider */
 
+#if defined(CONFIG_PXA3xx)
+#define SSACDD         (0x40)  /* SSP Audio Clock Dither Divider */
+#endif
+
 /* Common PXA2xx bits first */
 #define SSCR0_DSS      (0x0000000f)    /* Data Size Select (mask) */
 #define SSCR0_DataSize(x)  ((x) - 1)   /* Data Size Select [4..16] */
 #define SSCR0_National (0x2 << 4)      /* National Microwire */
 #define SSCR0_ECS      (1 << 6)        /* External clock select */
 #define SSCR0_SSE      (1 << 7)        /* Synchronous Serial Port Enable */
+
 #if defined(CONFIG_PXA25x)
 #define SSCR0_SCR      (0x0000ff00)    /* Serial Clock Rate (mask) */
 #define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */
-#elif defined(CONFIG_PXA27x)
+
+#elif defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #define SSCR0_SCR      (0x000fff00)    /* Serial Clock Rate (mask) */
 #define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */
 #define SSCR0_EDSS     (1 << 20)       /* Extended data size select */
 #define SSCR0_MOD      (1 << 31)       /* Mode (normal or network) */
 #endif
 
+#if defined(CONFIG_PXA3xx)
+#define SSCR0_FPCKE    (1 << 29)       /* FIFO packing enable */
+#endif
+
 #define SSCR1_RIE      (1 << 0)        /* Receive FIFO Interrupt Enable */
 #define SSCR1_TIE      (1 << 1)        /* Transmit FIFO Interrupt Enable */
 #define SSCR1_LBM      (1 << 2)        /* Loop-Back Mode */
 #define SSACD_SCDB             (1 << 3)        /* SSPSYSCLK Divider Bypass */
 #define SSACD_ACPS(x)          ((x) << 4)      /* Audio clock PLL select */
 #define SSACD_ACDS(x)          ((x) << 0)      /* Audio clock divider select */
+#if defined(CONFIG_PXA3xx)
+#define SSACD_SCDX8            (1 << 7)        /* SYSCLK division ratio select */
+#endif
+
 
 #endif /* __ASM_ARCH_REGS_SSP_H */
index ba7e132de1b3810e27f842b97596657bcf98a720..6956fc5235f837eed8b0d7661968bc69a8acc268 100644 (file)
@@ -21,19 +21,4 @@ static inline void arch_idle(void)
 }
 
 
-static inline void arch_reset(char mode)
-{
-       if (cpu_is_pxa2xx())
-               RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
-       if (mode == 's') {
-               /* Jump into ROM at address 0 */
-               cpu_reset(0);
-       } else {
-               /* Initialize the watchdog and let it fire */
-               OWER = OWER_WME;
-               OSSR = OSSR_M3;
-               OSMR3 = OSCR + 368640;  /* ... in 100 ms */
-       }
-}
-
+void arch_reset(char mode);
index c5b6fde6907c4f0fc743827381f5d7b6c65f673a..a72803f0461bbe4320cebcaad410d2c17e5f685f 100644 (file)
  */
 #define TOSA_SCOOP_GPIO_BASE           NR_BUILTIN_GPIO
 #define TOSA_SCOOP_PXA_VCORE1          SCOOP_GPCR_PA11
-#define TOSA_SCOOP_TC6393_REST_IN      SCOOP_GPCR_PA12
+#define TOSA_GPIO_TC6393XB_REST_IN     (TOSA_SCOOP_GPIO_BASE + 1)
 #define TOSA_GPIO_IR_POWERDWN          (TOSA_SCOOP_GPIO_BASE + 2)
 #define TOSA_GPIO_SD_WP                        (TOSA_SCOOP_GPIO_BASE + 3)
 #define TOSA_GPIO_PWR_ON               (TOSA_SCOOP_GPIO_BASE + 4)
 #define TOSA_SCOOP_AUD_PWR_ON          SCOOP_GPCR_PA16
-#define TOSA_SCOOP_BT_RESET            SCOOP_GPCR_PA17
-#define TOSA_SCOOP_BT_PWR_EN           SCOOP_GPCR_PA18
+#define TOSA_GPIO_BT_RESET             (TOSA_SCOOP_GPIO_BASE + 6)
+#define TOSA_GPIO_BT_PWR_EN            (TOSA_SCOOP_GPIO_BASE + 7)
 #define TOSA_SCOOP_AC_IN_OL            SCOOP_GPCR_PA19
 
 /* GPIO Direction   1 : output mode / 0:input mode */
-#define TOSA_SCOOP_IO_DIR     ( TOSA_SCOOP_PXA_VCORE1 | TOSA_SCOOP_TC6393_REST_IN | \
-               TOSA_SCOOP_AUD_PWR_ON |\
-               TOSA_SCOOP_BT_RESET | TOSA_SCOOP_BT_PWR_EN )
-/* GPIO out put level when init   1: Hi */
-#define TOSA_SCOOP_IO_OUT     ( TOSA_SCOOP_TC6393_REST_IN )
+#define TOSA_SCOOP_IO_DIR     (TOSA_SCOOP_PXA_VCORE1 | \
+               TOSA_SCOOP_AUD_PWR_ON)
 
 /*
  * SCOOP2 jacket GPIOs
 #define TOSA_GPIO_NOTE_LED             (TOSA_SCOOP_JC_GPIO_BASE + 1)
 #define TOSA_GPIO_CHRG_ERR_LED         (TOSA_SCOOP_JC_GPIO_BASE + 2)
 #define TOSA_GPIO_USB_PULLUP           (TOSA_SCOOP_JC_GPIO_BASE + 3)
-#define TOSA_SCOOP_JC_TC6393_SUSPEND   SCOOP_GPCR_PA15
-#define TOSA_SCOOP_JC_TC3693_L3V_ON    SCOOP_GPCR_PA16
+#define TOSA_GPIO_TC6393XB_SUSPEND     (TOSA_SCOOP_JC_GPIO_BASE + 4)
+#define TOSA_GPIO_TC6393XB_L3V_ON      (TOSA_SCOOP_JC_GPIO_BASE + 5)
 #define TOSA_SCOOP_JC_WLAN_DETECT      SCOOP_GPCR_PA17
 #define TOSA_GPIO_WLAN_LED             (TOSA_SCOOP_JC_GPIO_BASE + 7)
 #define TOSA_SCOOP_JC_CARD_LIMIT_SEL   SCOOP_GPCR_PA19
 
 /* GPIO Direction   1 : output mode / 0:input mode */
-#define TOSA_SCOOP_JC_IO_DIR ( \
-               TOSA_SCOOP_JC_TC6393_SUSPEND | TOSA_SCOOP_JC_TC3693_L3V_ON | \
-               TOSA_SCOOP_JC_CARD_LIMIT_SEL )
+#define TOSA_SCOOP_JC_IO_DIR (TOSA_SCOOP_JC_CARD_LIMIT_SEL)
+
+/*
+ * TC6393XB GPIOs
+ */
+#define TOSA_TC6393XB_GPIO_BASE                (NR_BUILTIN_GPIO + 2 * 12)
+#define TOSA_TC6393XB_GPIO(i)          (TOSA_TC6393XB_GPIO_BASE + (i))
+#define TOSA_TC6393XB_GPIO_BIT(gpio)   (1 << (gpio - TOSA_TC6393XB_GPIO_BASE))
+
+#define TOSA_GPIO_TG_ON                        (TOSA_TC6393XB_GPIO_BASE + 0)
+#define TOSA_GPIO_L_MUTE               (TOSA_TC6393XB_GPIO_BASE + 1)
+#define TOSA_GPIO_BL_C20MA             (TOSA_TC6393XB_GPIO_BASE + 3)
+#define TOSA_GPIO_CARD_VCC_ON          (TOSA_TC6393XB_GPIO_BASE + 4)
+#define TOSA_GPIO_CHARGE_OFF           (TOSA_TC6393XB_GPIO_BASE + 6)
+#define TOSA_GPIO_CHARGE_OFF_JC                (TOSA_TC6393XB_GPIO_BASE + 7)
+#define TOSA_GPIO_BAT0_V_ON            (TOSA_TC6393XB_GPIO_BASE + 9)
+#define TOSA_GPIO_BAT1_V_ON            (TOSA_TC6393XB_GPIO_BASE + 10)
+#define TOSA_GPIO_BU_CHRG_ON           (TOSA_TC6393XB_GPIO_BASE + 11)
+#define TOSA_GPIO_BAT_SW_ON            (TOSA_TC6393XB_GPIO_BASE + 12)
+#define TOSA_GPIO_BAT0_TH_ON           (TOSA_TC6393XB_GPIO_BASE + 14)
+#define TOSA_GPIO_BAT1_TH_ON           (TOSA_TC6393XB_GPIO_BASE + 15)
 
 /*
  * Timing Generator
 #define TOSA_GPIO_JACKET_DETECT                (7)
 #define TOSA_GPIO_nSD_DETECT           (9)
 #define TOSA_GPIO_nSD_INT              (10)
-#define TOSA_GPIO_TC6393_CLK           (11)
+#define TOSA_GPIO_TC6393XB_CLK         (11)
 #define TOSA_GPIO_BAT1_CRG             (12)
 #define TOSA_GPIO_CF_CD                        (13)
 #define TOSA_GPIO_BAT0_CRG             (14)
-#define TOSA_GPIO_TC6393_INT           (15)
+#define TOSA_GPIO_TC6393XB_INT         (15)
 #define TOSA_GPIO_BAT0_LOW             (17)
-#define TOSA_GPIO_TC6393_RDY           (18)
+#define TOSA_GPIO_TC6393XB_RDY         (18)
 #define TOSA_GPIO_ON_RESET             (19)
 #define TOSA_GPIO_EAR_IN               (20)
 #define TOSA_GPIO_CF_IRQ               (21)    /* CF slot0 Ready */
 #define TOSA_GPIO_TP_INT               (32)    /* Touch Panel pen down interrupt */
 #define TOSA_GPIO_JC_CF_IRQ            (36)    /* CF slot1 Ready */
 #define TOSA_GPIO_BAT_LOCKED           (38)    /* Battery locked */
+#define TOSA_GPIO_IRDA_TX              (47)
 #define TOSA_GPIO_TG_SPI_SCLK          (81)
 #define TOSA_GPIO_TG_SPI_CS            (82)
 #define TOSA_GPIO_TG_SPI_MOSI          (83)
 #define TOSA_IRQ_GPIO_BAT1_CRG         IRQ_GPIO(TOSA_GPIO_BAT1_CRG)
 #define TOSA_IRQ_GPIO_CF_CD            IRQ_GPIO(TOSA_GPIO_CF_CD)
 #define TOSA_IRQ_GPIO_BAT0_CRG         IRQ_GPIO(TOSA_GPIO_BAT0_CRG)
-#define TOSA_IRQ_GPIO_TC6393_INT       IRQ_GPIO(TOSA_GPIO_TC6393_INT)
+#define TOSA_IRQ_GPIO_TC6393XB_INT     IRQ_GPIO(TOSA_GPIO_TC6393XB_INT)
 #define TOSA_IRQ_GPIO_BAT0_LOW         IRQ_GPIO(TOSA_GPIO_BAT0_LOW)
 #define TOSA_IRQ_GPIO_EAR_IN           IRQ_GPIO(TOSA_GPIO_EAR_IN)
 #define TOSA_IRQ_GPIO_CF_IRQ           IRQ_GPIO(TOSA_GPIO_CF_IRQ)
diff --git a/include/asm-arm/arch-pxa/tosa_bt.h b/include/asm-arm/arch-pxa/tosa_bt.h
new file mode 100644 (file)
index 0000000..efc3c3d
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Tosa bluetooth built-in chip control.
+ *
+ * Later it may be shared with some other platforms.
+ *
+ * Copyright (c) 2008 Dmitry Baryshkov
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef TOSA_BT_H
+#define TOSA_BT_H
+
+struct tosa_bt_data {
+       int gpio_pwr;
+       int gpio_reset;
+};
+
+#endif
+
index dadf4c20b6222409c2912f4121230f6e3c76fd35..f4551269aaf2e667ed7829857df75c65ed82e6a4 100644 (file)
 
 #include <linux/serial_reg.h>
 #include <asm/arch/pxa-regs.h>
+#include <asm/mach-types.h>
 
-#define __REG(x)       ((volatile unsigned long *)x)
-
-#define UART           FFUART
+#define __REG(x)       ((volatile unsigned long *)x)
 
+static volatile unsigned long *UART = FFUART;
 
 static inline void putc(char c)
 {
@@ -33,8 +33,13 @@ static inline void flush(void)
 {
 }
 
+static inline void arch_decomp_setup(void)
+{
+       if (machine_is_littleton())
+               UART = STUART;
+}
+
 /*
  * nothing to do
  */
-#define arch_decomp_setup()
 #define arch_decomp_wdog()
index de577de8d18c9dc5994c75a77408e789cd14329d..0d35ca04731e485fa655c5dccd087c59fd58fb0d 100644 (file)
@@ -16,6 +16,8 @@ struct platform_mmc_slot {
 extern struct platform_mmc_slot zylonite_mmc_slot[];
 
 extern int gpio_eth_irq;
+extern int gpio_debug_led1;
+extern int gpio_debug_led2;
 
 extern int wm9713_irq;
 
index a32b86ac62aa4f4e325dd7c035270a88b072c392..af64676650a22b7f6817d0d809d4fc6d82d8966d 100644 (file)
@@ -260,7 +260,7 @@ static inline int iop_chan_memset_slot_count(size_t len, int *slots_per_op)
 static inline int iop3xx_aau_xor_slot_count(size_t len, int src_cnt,
                                        int *slots_per_op)
 {
-       static const int slot_count_table[] = { 0,
+       static const char slot_count_table[] = {
                                                1, 1, 1, 1, /* 01 - 04 */
                                                2, 2, 2, 2, /* 05 - 08 */
                                                4, 4, 4, 4, /* 09 - 12 */
@@ -270,7 +270,7 @@ static inline int iop3xx_aau_xor_slot_count(size_t len, int src_cnt,
                                                8, 8, 8, 8, /* 25 - 28 */
                                                8, 8, 8, 8, /* 29 - 32 */
                                              };
-       *slots_per_op = slot_count_table[src_cnt];
+       *slots_per_op = slot_count_table[src_cnt - 1];
        return *slots_per_op;
 }
 
diff --git a/include/asm-arm/kgdb.h b/include/asm-arm/kgdb.h
new file mode 100644 (file)
index 0000000..67af4b8
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * ARM KGDB support
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2002 MontaVista Software Inc.
+ *
+ */
+
+#ifndef __ARM_KGDB_H__
+#define __ARM_KGDB_H__
+
+#include <linux/ptrace.h>
+
+/*
+ * GDB assumes that we're a user process being debugged, so
+ * it will send us an SWI command to write into memory as the
+ * debug trap. When an SWI occurs, the next instruction addr is
+ * placed into R14_svc before jumping to the vector trap.
+ * This doesn't work for kernel debugging as we are already in SVC
+ * we would loose the kernel's LR, which is a bad thing. This
+ * is  bad thing.
+ *
+ * By doing this as an undefined instruction trap, we force a mode
+ * switch from SVC to UND mode, allowing us to save full kernel state.
+ *
+ * We also define a KGDB_COMPILED_BREAK which can be used to compile
+ * in breakpoints. This is important for things like sysrq-G and for
+ * the initial breakpoint from trap_init().
+ *
+ * Note to ARM HW designers: Add real trap support like SH && PPC to
+ * make our lives much much simpler. :)
+ */
+#define BREAK_INSTR_SIZE       4
+#define GDB_BREAKINST          0xef9f0001
+#define KGDB_BREAKINST         0xe7ffdefe
+#define KGDB_COMPILED_BREAK    0xe7ffdeff
+#define CACHE_FLUSH_IS_SAFE    1
+
+#ifndef        __ASSEMBLY__
+
+static inline void arch_kgdb_breakpoint(void)
+{
+       asm(".word 0xe7ffdeff");
+}
+
+extern void kgdb_handle_bus_error(void);
+extern int kgdb_fault_expected;
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * From Kevin Hilman:
+ *
+ * gdb is expecting the following registers layout.
+ *
+ * r0-r15: 1 long word each
+ * f0-f7:  unused, 3 long words each !!
+ * fps:    unused, 1 long word
+ * cpsr:   1 long word
+ *
+ * Even though f0-f7 and fps are not used, they need to be
+ * present in the registers sent for correct processing in
+ * the host-side gdb.
+ *
+ * In particular, it is crucial that CPSR is in the right place,
+ * otherwise gdb will not be able to correctly interpret stepping over
+ * conditional branches.
+ */
+#define _GP_REGS               16
+#define _FP_REGS               8
+#define _EXTRA_REGS            2
+#define GDB_MAX_REGS           (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS)
+
+#define KGDB_MAX_NO_CPUS       1
+#define BUFMAX                 400
+#define NUMREGBYTES            (GDB_MAX_REGS << 2)
+#define NUMCRITREGBYTES                (32 << 2)
+
+#define _R0                    0
+#define _R1                    1
+#define _R2                    2
+#define _R3                    3
+#define _R4                    4
+#define _R5                    5
+#define _R6                    6
+#define _R7                    7
+#define _R8                    8
+#define _R9                    9
+#define _R10                   10
+#define _FP                    11
+#define _IP                    12
+#define _SPT                   13
+#define _LR                    14
+#define _PC                    15
+#define _CPSR                  (GDB_MAX_REGS - 1)
+
+/*
+ * So that we can denote the end of a frame for tracing,
+ * in the simple case:
+ */
+#define CFI_END_FRAME(func)    __CFI_END_FRAME(_PC, _SPT, func)
+
+#endif /* __ASM_KGDB_H__ */
index f9f3606986c27fedea03382b9de34ba1a7667e89..9e5ed7c0f27fb50150f84a303b61a205eb881bc2 100644 (file)
@@ -23,6 +23,7 @@ struct pxa2xx_udc_mach_info {
         */
        bool    gpio_vbus_inverted;
        u16     gpio_vbus;                      /* high == vbus present */
+       bool    gpio_pullup_inverted;
        u16     gpio_pullup;                    /* high == pullup activated */
 };
 
diff --git a/include/asm-arm/plat-orion/mv_xor.h b/include/asm-arm/plat-orion/mv_xor.h
new file mode 100644 (file)
index 0000000..c349e8f
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Marvell XOR platform device data definition file.
+ */
+
+#ifndef __ASM_PLAT_ORION_MV_XOR_H
+#define __ASM_PLAT_ORION_MV_XOR_H
+
+#include <linux/dmaengine.h>
+#include <linux/mbus.h>
+
+#define MV_XOR_SHARED_NAME     "mv_xor_shared"
+#define MV_XOR_NAME            "mv_xor"
+
+struct mbus_dram_target_info;
+
+struct mv_xor_platform_shared_data {
+       struct mbus_dram_target_info    *dram;
+};
+
+struct mv_xor_platform_data {
+       struct platform_device          *shared;
+       int                             hw_id;
+       dma_cap_mask_t                  cap_mask;
+       size_t                          pool_size;
+};
+
+
+#endif
index f1541afcf85c200c457fb48fc93d5c88d250902d..aa399aec568ef02533c2d6694f192f91a8446ab5 100644 (file)
@@ -24,4 +24,6 @@ static inline int in_exception_text(unsigned long ptr)
               ptr < (unsigned long)&__exception_text_end;
 }
 
+extern void __init early_trap_init(void);
+
 #endif
index 31e48b0e732414aff872d901dd4c0f33a5f5b54d..d18a3053be0d33b909ce665b41aaa62211e37a0a 100644 (file)
 #define GPIO_PIN_PD(N) (GPIO_PIOD_BASE + (N))
 #define GPIO_PIN_PE(N) (GPIO_PIOE_BASE + (N))
 
+
+/*
+ * DMAC peripheral hardware handshaking interfaces, used with dw_dmac
+ */
+#define DMAC_MCI_RX            0
+#define DMAC_MCI_TX            1
+#define DMAC_DAC_TX            2
+#define DMAC_AC97_A_RX         3
+#define DMAC_AC97_A_TX         4
+#define DMAC_AC97_B_RX         5
+#define DMAC_AC97_B_TX         6
+#define DMAC_DMAREQ_0          7
+#define DMAC_DMAREQ_1          8
+#define DMAC_DMAREQ_2          9
+#define DMAC_DMAREQ_3          10
+
 #endif /* __ASM_ARCH_AT32AP700X_H__ */
index eb24a3f47caa212b94b7d2c1736ea7be2b59e992..ccbe8ae47a6127730741335b3d2362ff298409d5 100644 (file)
@@ -5,12 +5,12 @@ header-y += fpu.h
 header-y += fpswa.h
 header-y += ia64regs.h
 header-y += intel_intrin.h
-header-y += intrinsics.h
 header-y += perfmon_default_smpl.h
 header-y += ptrace_offsets.h
 header-y += rse.h
 header-y += ucontext.h
 
 unifdef-y += gcc_intrin.h
+unifdef-y += intrinsics.h
 unifdef-y += perfmon.h
 unifdef-y += ustack.h
index 2fe292c275fe9ab142271e0015b1a87391698f38..0f5b559217580cf5a19b83df0f35c138d22b5308 100644 (file)
@@ -32,7 +32,7 @@ extern void ia64_bad_param_for_getreg (void);
 register unsigned long ia64_r13 asm ("r13") __used;
 #endif
 
-#define ia64_setreg(regnum, val)                                               \
+#define ia64_native_setreg(regnum, val)                                                \
 ({                                                                             \
        switch (regnum) {                                                       \
            case _IA64_REG_PSR_L:                                               \
@@ -61,7 +61,7 @@ register unsigned long ia64_r13 asm ("r13") __used;
        }                                                                       \
 })
 
-#define ia64_getreg(regnum)                                                    \
+#define ia64_native_getreg(regnum)                                             \
 ({                                                                             \
        __u64 ia64_intri_res;                                                   \
                                                                                \
@@ -385,7 +385,7 @@ register unsigned long ia64_r13 asm ("r13") __used;
 
 #define ia64_invala() asm volatile ("invala" ::: "memory")
 
-#define ia64_thash(addr)                                                       \
+#define ia64_native_thash(addr)                                                        \
 ({                                                                             \
        __u64 ia64_intri_res;                                                   \
        asm volatile ("thash %0=%1" : "=r"(ia64_intri_res) : "r" (addr));       \
@@ -438,10 +438,10 @@ register unsigned long ia64_r13 asm ("r13") __used;
 #define ia64_set_pmd(index, val)                                               \
        asm volatile ("mov pmd[%0]=%1" :: "r"(index), "r"(val) : "memory")
 
-#define ia64_set_rr(index, val)                                                        \
+#define ia64_native_set_rr(index, val)                                                 \
        asm volatile ("mov rr[%0]=%1" :: "r"(index), "r"(val) : "memory");
 
-#define ia64_get_cpuid(index)                                                          \
+#define ia64_native_get_cpuid(index)                                                   \
 ({                                                                                     \
        __u64 ia64_intri_res;                                                           \
        asm volatile ("mov %0=cpuid[%r1]" : "=r"(ia64_intri_res) : "rO"(index));        \
@@ -477,33 +477,33 @@ register unsigned long ia64_r13 asm ("r13") __used;
 })
 
 
-#define ia64_get_pmd(index)                                                    \
+#define ia64_native_get_pmd(index)                                             \
 ({                                                                             \
        __u64 ia64_intri_res;                                                   \
        asm volatile ("mov %0=pmd[%1]" : "=r"(ia64_intri_res) : "r"(index));    \
        ia64_intri_res;                                                         \
 })
 
-#define ia64_get_rr(index)                                                     \
+#define ia64_native_get_rr(index)                                              \
 ({                                                                             \
        __u64 ia64_intri_res;                                                   \
        asm volatile ("mov %0=rr[%1]" : "=r"(ia64_intri_res) : "r" (index));    \
        ia64_intri_res;                                                         \
 })
 
-#define ia64_fc(addr)  asm volatile ("fc %0" :: "r"(addr) : "memory")
+#define ia64_native_fc(addr)   asm volatile ("fc %0" :: "r"(addr) : "memory")
 
 
 #define ia64_sync_i()  asm volatile (";; sync.i" ::: "memory")
 
-#define ia64_ssm(mask) asm volatile ("ssm %0":: "i"((mask)) : "memory")
-#define ia64_rsm(mask) asm volatile ("rsm %0":: "i"((mask)) : "memory")
+#define ia64_native_ssm(mask)  asm volatile ("ssm %0":: "i"((mask)) : "memory")
+#define ia64_native_rsm(mask)  asm volatile ("rsm %0":: "i"((mask)) : "memory")
 #define ia64_sum(mask) asm volatile ("sum %0":: "i"((mask)) : "memory")
 #define ia64_rum(mask) asm volatile ("rum %0":: "i"((mask)) : "memory")
 
 #define ia64_ptce(addr)        asm volatile ("ptc.e %0" :: "r"(addr))
 
-#define ia64_ptcga(addr, size)                                                 \
+#define ia64_native_ptcga(addr, size)                                          \
 do {                                                                           \
        asm volatile ("ptc.ga %0,%1" :: "r"(addr), "r"(size) : "memory");       \
        ia64_dv_serialize_data();                                               \
@@ -608,7 +608,7 @@ do {                                                                                \
         }                                                              \
 })
 
-#define ia64_intrin_local_irq_restore(x)                       \
+#define ia64_native_intrin_local_irq_restore(x)                        \
 do {                                                           \
        asm volatile (";;   cmp.ne p6,p7=%0,r0;;"               \
                      "(p6) ssm psr.i;"                         \
index 76366dc9c1a0473ead7124ddce204252537d8ebc..5c99cbcb8a0d29a2438cbd6529540fbce72f0aa0 100644 (file)
 #include <asm/ptrace.h>
 #include <asm/smp.h>
 
+#ifndef CONFIG_PARAVIRT
 typedef u8 ia64_vector;
+#else
+typedef u16 ia64_vector;
+#endif
 
 /*
  * 0 special
@@ -104,13 +108,24 @@ DECLARE_PER_CPU(int[IA64_NUM_VECTORS], vector_irq);
 
 extern struct hw_interrupt_type irq_type_ia64_lsapic;  /* CPU-internal interrupt controller */
 
+#ifdef CONFIG_PARAVIRT_GUEST
+#include <asm/paravirt.h>
+#else
+#define ia64_register_ipi      ia64_native_register_ipi
+#define assign_irq_vector      ia64_native_assign_irq_vector
+#define free_irq_vector                ia64_native_free_irq_vector
+#define register_percpu_irq    ia64_native_register_percpu_irq
+#define ia64_resend_irq                ia64_native_resend_irq
+#endif
+
+extern void ia64_native_register_ipi(void);
 extern int bind_irq_vector(int irq, int vector, cpumask_t domain);
-extern int assign_irq_vector (int irq);        /* allocate a free vector */
-extern void free_irq_vector (int vector);
+extern int ia64_native_assign_irq_vector (int irq);    /* allocate a free vector */
+extern void ia64_native_free_irq_vector (int vector);
 extern int reserve_irq_vector (int vector);
 extern void __setup_vector_irq(int cpu);
 extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
-extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
+extern void ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action);
 extern int check_irq_used (int irq);
 extern void destroy_and_reserve_irq (unsigned int irq);
 
@@ -122,7 +137,7 @@ static inline int irq_prepare_move(int irq, int cpu) { return 0; }
 static inline void irq_complete_move(unsigned int irq) {}
 #endif
 
-static inline void ia64_resend_irq(unsigned int vector)
+static inline void ia64_native_resend_irq(unsigned int vector)
 {
        platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
 }
index a520d103d80869d358a5e3d442c5b63a144dbdbc..53cec577558a9aac345a6661acb43213b1015a25 100644 (file)
@@ -16,8 +16,8 @@
                         * intrinsic
                         */
 
-#define ia64_getreg            __getReg
-#define ia64_setreg            __setReg
+#define ia64_native_getreg     __getReg
+#define ia64_native_setreg     __setReg
 
 #define ia64_hint              __hint
 #define ia64_hint_pause                __hint_pause
 #define ia64_invala_fr         __invala_fr
 #define ia64_nop               __nop
 #define ia64_sum               __sum
-#define ia64_ssm               __ssm
+#define ia64_native_ssm                __ssm
 #define ia64_rum               __rum
-#define ia64_rsm               __rsm
-#define ia64_fc                __fc
+#define ia64_native_rsm                __rsm
+#define ia64_native_fc                 __fc
 
 #define ia64_ldfs              __ldfs
 #define ia64_ldfd              __ldfd
                __setIndReg(_IA64_REG_INDR_PMC, index, val)
 #define ia64_set_pmd(index, val)       \
                __setIndReg(_IA64_REG_INDR_PMD, index, val)
-#define ia64_set_rr(index, val)        \
+#define ia64_native_set_rr(index, val) \
                __setIndReg(_IA64_REG_INDR_RR, index, val)
 
-#define ia64_get_cpuid(index)  __getIndReg(_IA64_REG_INDR_CPUID, index)
-#define __ia64_get_dbr(index)  __getIndReg(_IA64_REG_INDR_DBR, index)
-#define ia64_get_ibr(index)    __getIndReg(_IA64_REG_INDR_IBR, index)
-#define ia64_get_pkr(index)    __getIndReg(_IA64_REG_INDR_PKR, index)
-#define ia64_get_pmc(index)    __getIndReg(_IA64_REG_INDR_PMC, index)
-#define ia64_get_pmd(index)    __getIndReg(_IA64_REG_INDR_PMD, index)
-#define ia64_get_rr(index)     __getIndReg(_IA64_REG_INDR_RR, index)
+#define ia64_native_get_cpuid(index)   \
+               __getIndReg(_IA64_REG_INDR_CPUID, index)
+#define __ia64_get_dbr(index)          __getIndReg(_IA64_REG_INDR_DBR, index)
+#define ia64_get_ibr(index)            __getIndReg(_IA64_REG_INDR_IBR, index)
+#define ia64_get_pkr(index)            __getIndReg(_IA64_REG_INDR_PKR, index)
+#define ia64_get_pmc(index)            __getIndReg(_IA64_REG_INDR_PMC, index)
+#define ia64_native_get_pmd(index)     __getIndReg(_IA64_REG_INDR_PMD, index)
+#define ia64_native_get_rr(index)      __getIndReg(_IA64_REG_INDR_RR, index)
 
 #define ia64_srlz_d            __dsrlz
 #define ia64_srlz_i            __isrlz
 #define ia64_ld8_acq           __ld8_acq
 
 #define ia64_sync_i            __synci
-#define ia64_thash             __thash
-#define ia64_ttag              __ttag
+#define ia64_native_thash      __thash
+#define ia64_native_ttag       __ttag
 #define ia64_itcd              __itcd
 #define ia64_itci              __itci
 #define ia64_itrd              __itrd
 #define ia64_itri              __itri
 #define ia64_ptce              __ptce
 #define ia64_ptcl              __ptcl
-#define ia64_ptcg              __ptcg
-#define ia64_ptcga             __ptcga
+#define ia64_native_ptcg       __ptcg
+#define ia64_native_ptcga      __ptcga
 #define ia64_ptri              __ptri
 #define ia64_ptrd              __ptrd
 #define ia64_dep_mi            _m64_dep_mi
 #define ia64_lfetch_fault      __lfetch_fault
 #define ia64_lfetch_fault_excl __lfetch_fault_excl
 
-#define ia64_intrin_local_irq_restore(x)               \
+#define ia64_native_intrin_local_irq_restore(x)                \
 do {                                                   \
        if ((x) != 0) {                                 \
-               ia64_ssm(IA64_PSR_I);                   \
+               ia64_native_ssm(IA64_PSR_I);            \
                ia64_srlz_d();                          \
        } else {                                        \
-               ia64_rsm(IA64_PSR_I);                   \
+               ia64_native_rsm(IA64_PSR_I);            \
        }                                               \
 } while (0)
 
index f1135b5b94c3df8483f8fc2af0ec32f07b563130..47d686dba1ebf5b91dae6a2e906de3477c691851 100644 (file)
 # include <asm/gcc_intrin.h>
 #endif
 
+#define ia64_native_get_psr_i()        (ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I)
+
+#define ia64_native_set_rr0_to_rr4(val0, val1, val2, val3, val4)       \
+do {                                                                   \
+       ia64_native_set_rr(0x0000000000000000UL, (val0));               \
+       ia64_native_set_rr(0x2000000000000000UL, (val1));               \
+       ia64_native_set_rr(0x4000000000000000UL, (val2));               \
+       ia64_native_set_rr(0x6000000000000000UL, (val3));               \
+       ia64_native_set_rr(0x8000000000000000UL, (val4));               \
+} while (0)
+
 /*
  * Force an unresolved reference if someone tries to use
  * ia64_fetch_and_add() with a bad value.
@@ -183,4 +194,48 @@ extern long ia64_cmpxchg_called_with_bad_pointer (void);
 #endif /* !CONFIG_IA64_DEBUG_CMPXCHG */
 
 #endif
+
+#ifdef __KERNEL__
+#include <asm/paravirt_privop.h>
+#endif
+
+#ifndef __ASSEMBLY__
+#if defined(CONFIG_PARAVIRT) && defined(__KERNEL__)
+#define IA64_INTRINSIC_API(name)       pv_cpu_ops.name
+#define IA64_INTRINSIC_MACRO(name)     paravirt_ ## name
+#else
+#define IA64_INTRINSIC_API(name)       ia64_native_ ## name
+#define IA64_INTRINSIC_MACRO(name)     ia64_native_ ## name
+#endif
+
+/************************************************/
+/* Instructions paravirtualized for correctness */
+/************************************************/
+/* fc, thash, get_cpuid, get_pmd, get_eflags, set_eflags */
+/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
+ * is not currently used (though it may be in a long-format VHPT system!)
+ */
+#define ia64_fc                                IA64_INTRINSIC_API(fc)
+#define ia64_thash                     IA64_INTRINSIC_API(thash)
+#define ia64_get_cpuid                 IA64_INTRINSIC_API(get_cpuid)
+#define ia64_get_pmd                   IA64_INTRINSIC_API(get_pmd)
+
+
+/************************************************/
+/* Instructions paravirtualized for performance */
+/************************************************/
+#define ia64_ssm                       IA64_INTRINSIC_MACRO(ssm)
+#define ia64_rsm                       IA64_INTRINSIC_MACRO(rsm)
+#define ia64_getreg                    IA64_INTRINSIC_API(getreg)
+#define ia64_setreg                    IA64_INTRINSIC_API(setreg)
+#define ia64_set_rr                    IA64_INTRINSIC_API(set_rr)
+#define ia64_get_rr                    IA64_INTRINSIC_API(get_rr)
+#define ia64_ptcga                     IA64_INTRINSIC_API(ptcga)
+#define ia64_get_psr_i                 IA64_INTRINSIC_API(get_psr_i)
+#define ia64_intrin_local_irq_restore  \
+       IA64_INTRINSIC_API(intrin_local_irq_restore)
+#define ia64_set_rr0_to_rr4            IA64_INTRINSIC_API(set_rr0_to_rr4)
+
+#endif /* !__ASSEMBLY__ */
+
 #endif /* _ASM_IA64_INTRINSICS_H */
index a3a4288daae81186ecbb112c8645035f2ba26936..b9c102e15f22b196cd429d326c9cb674a9136009 100644 (file)
 
 #define NR_IOSAPICS                    256
 
-static inline unsigned int __iosapic_read(char __iomem *iosapic, unsigned int reg)
+#ifdef CONFIG_PARAVIRT_GUEST
+#include <asm/paravirt.h>
+#else
+#define iosapic_pcat_compat_init       ia64_native_iosapic_pcat_compat_init
+#define __iosapic_read                 __ia64_native_iosapic_read
+#define __iosapic_write                        __ia64_native_iosapic_write
+#define iosapic_get_irq_chip           ia64_native_iosapic_get_irq_chip
+#endif
+
+extern void __init ia64_native_iosapic_pcat_compat_init(void);
+extern struct irq_chip *ia64_native_iosapic_get_irq_chip(unsigned long trigger);
+
+static inline unsigned int
+__ia64_native_iosapic_read(char __iomem *iosapic, unsigned int reg)
 {
        writel(reg, iosapic + IOSAPIC_REG_SELECT);
        return readl(iosapic + IOSAPIC_WINDOW);
 }
 
-static inline void __iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
+static inline void
+__ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
 {
        writel(reg, iosapic + IOSAPIC_REG_SELECT);
        writel(val, iosapic + IOSAPIC_WINDOW);
index a66d26827cbbe23c2864c053f81d6e5332a99a04..3627116fb0e25238567fb68c42afe9c6381a8801 100644 (file)
 
 #include <linux/types.h>
 #include <linux/cpumask.h>
-
-#define NR_VECTORS     256
-
-#if (NR_VECTORS + 32 * NR_CPUS) < 1024
-#define NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
-#else
-#define NR_IRQS 1024
-#endif
+#include <asm-ia64/nr-irqs.h>
 
 static __inline__ int
 irq_canonicalize (int irq)
index cef2400983fafe3fd1961895a4d355f11a14d34b..040bc87db9304766b5379abefcd563c25aa3c01c 100644 (file)
@@ -152,11 +152,7 @@ reload_context (nv_mm_context_t context)
 #  endif
 #endif
 
-       ia64_set_rr(0x0000000000000000UL, rr0);
-       ia64_set_rr(0x2000000000000000UL, rr1);
-       ia64_set_rr(0x4000000000000000UL, rr2);
-       ia64_set_rr(0x6000000000000000UL, rr3);
-       ia64_set_rr(0x8000000000000000UL, rr4);
+       ia64_set_rr0_to_rr4(rr0, rr1, rr2, rr3, rr4);
        ia64_srlz_i();                  /* srlz.i implies srlz.d */
 }
 
diff --git a/include/asm-ia64/native/inst.h b/include/asm-ia64/native/inst.h
new file mode 100644 (file)
index 0000000..c953a2c
--- /dev/null
@@ -0,0 +1,175 @@
+/******************************************************************************
+ * include/asm-ia64/native/inst.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 DO_SAVE_MIN            IA64_NATIVE_DO_SAVE_MIN
+
+#define __paravirt_switch_to                   ia64_native_switch_to
+#define __paravirt_leave_syscall               ia64_native_leave_syscall
+#define __paravirt_work_processed_syscall      ia64_native_work_processed_syscall
+#define __paravirt_leave_kernel                        ia64_native_leave_kernel
+#define __paravirt_pending_syscall_end         ia64_work_pending_syscall_end
+#define __paravirt_work_processed_syscall_target \
+                                               ia64_work_processed_syscall
+
+#ifdef CONFIG_PARAVIRT_GUEST_ASM_CLOBBER_CHECK
+# define PARAVIRT_POISON       0xdeadbeefbaadf00d
+# define CLOBBER(clob)                         \
+       ;;                                      \
+       movl clob = PARAVIRT_POISON;            \
+       ;;
+#else
+# define CLOBBER(clob)         /* nothing */
+#endif
+
+#define MOV_FROM_IFA(reg)      \
+       mov reg = cr.ifa
+
+#define MOV_FROM_ITIR(reg)     \
+       mov reg = cr.itir
+
+#define MOV_FROM_ISR(reg)      \
+       mov reg = cr.isr
+
+#define MOV_FROM_IHA(reg)      \
+       mov reg = cr.iha
+
+#define MOV_FROM_IPSR(pred, reg)       \
+(pred) mov reg = cr.ipsr
+
+#define MOV_FROM_IIM(reg)      \
+       mov reg = cr.iim
+
+#define MOV_FROM_IIP(reg)      \
+       mov reg = cr.iip
+
+#define MOV_FROM_IVR(reg, clob)        \
+       mov reg = cr.ivr        \
+       CLOBBER(clob)
+
+#define MOV_FROM_PSR(pred, reg, clob)  \
+(pred) mov reg = psr                   \
+       CLOBBER(clob)
+
+#define MOV_TO_IFA(reg, clob)  \
+       mov cr.ifa = reg        \
+       CLOBBER(clob)
+
+#define MOV_TO_ITIR(pred, reg, clob)   \
+(pred) mov cr.itir = reg               \
+       CLOBBER(clob)
+
+#define MOV_TO_IHA(pred, reg, clob)    \
+(pred) mov cr.iha = reg                \
+       CLOBBER(clob)
+
+#define MOV_TO_IPSR(pred, reg, clob)           \
+(pred) mov cr.ipsr = reg                       \
+       CLOBBER(clob)
+
+#define MOV_TO_IFS(pred, reg, clob)    \
+(pred) mov cr.ifs = reg                \
+       CLOBBER(clob)
+
+#define MOV_TO_IIP(reg, clob)  \
+       mov cr.iip = reg        \
+       CLOBBER(clob)
+
+#define MOV_TO_KR(kr, reg, clob0, clob1)       \
+       mov IA64_KR(kr) = reg                   \
+       CLOBBER(clob0)                          \
+       CLOBBER(clob1)
+
+#define ITC_I(pred, reg, clob) \
+(pred) itc.i reg               \
+       CLOBBER(clob)
+
+#define ITC_D(pred, reg, clob) \
+(pred) itc.d reg               \
+       CLOBBER(clob)
+
+#define ITC_I_AND_D(pred_i, pred_d, reg, clob) \
+(pred_i) itc.i reg;                            \
+(pred_d) itc.d reg                             \
+       CLOBBER(clob)
+
+#define THASH(pred, reg0, reg1, clob)          \
+(pred) thash reg0 = reg1                       \
+       CLOBBER(clob)
+
+#define SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(clob0, clob1)           \
+       ssm psr.ic | PSR_DEFAULT_BITS                                   \
+       CLOBBER(clob0)                                                  \
+       CLOBBER(clob1)                                                  \
+       ;;                                                              \
+       srlz.i /* guarantee that interruption collectin is on */        \
+       ;;
+
+#define SSM_PSR_IC_AND_SRLZ_D(clob0, clob1)    \
+       ssm psr.ic                              \
+       CLOBBER(clob0)                          \
+       CLOBBER(clob1)                          \
+       ;;                                      \
+       srlz.d
+
+#define RSM_PSR_IC(clob)       \
+       rsm psr.ic              \
+       CLOBBER(clob)
+
+#define SSM_PSR_I(pred, pred_clob, clob)       \
+(pred) ssm psr.i                               \
+       CLOBBER(clob)
+
+#define RSM_PSR_I(pred, clob0, clob1)  \
+(pred) rsm psr.i                       \
+       CLOBBER(clob0)                  \
+       CLOBBER(clob1)
+
+#define RSM_PSR_I_IC(clob0, clob1, clob2)      \
+       rsm psr.i | psr.ic                      \
+       CLOBBER(clob0)                          \
+       CLOBBER(clob1)                          \
+       CLOBBER(clob2)
+
+#define RSM_PSR_DT             \
+       rsm psr.dt
+
+#define SSM_PSR_DT_AND_SRLZ_I  \
+       ssm psr.dt              \
+       ;;                      \
+       srlz.i
+
+#define BSW_0(clob0, clob1, clob2)     \
+       bsw.0                           \
+       CLOBBER(clob0)                  \
+       CLOBBER(clob1)                  \
+       CLOBBER(clob2)
+
+#define BSW_1(clob0, clob1)    \
+       bsw.1                   \
+       CLOBBER(clob0)          \
+       CLOBBER(clob1)
+
+#define COVER  \
+       cover
+
+#define RFI    \
+       rfi
diff --git a/include/asm-ia64/native/irq.h b/include/asm-ia64/native/irq.h
new file mode 100644 (file)
index 0000000..efe9ff7
--- /dev/null
@@ -0,0 +1,35 @@
+/******************************************************************************
+ * include/asm-ia64/native/irq.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * moved from linux/include/asm-ia64/irq.h.
+ */
+
+#ifndef _ASM_IA64_NATIVE_IRQ_H
+#define _ASM_IA64_NATIVE_IRQ_H
+
+#define NR_VECTORS     256
+
+#if (NR_VECTORS + 32 * NR_CPUS) < 1024
+#define IA64_NATIVE_NR_IRQS (NR_VECTORS + 32 * NR_CPUS)
+#else
+#define IA64_NATIVE_NR_IRQS 1024
+#endif
+
+#endif /* _ASM_IA64_NATIVE_IRQ_H */
diff --git a/include/asm-ia64/paravirt.h b/include/asm-ia64/paravirt.h
new file mode 100644 (file)
index 0000000..1b4df12
--- /dev/null
@@ -0,0 +1,255 @@
+/******************************************************************************
+ * include/asm-ia64/paravirt.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 __ASM_PARAVIRT_H
+#define __ASM_PARAVIRT_H
+
+#ifdef CONFIG_PARAVIRT_GUEST
+
+#define PARAVIRT_HYPERVISOR_TYPE_DEFAULT       0
+#define PARAVIRT_HYPERVISOR_TYPE_XEN           1
+
+#ifndef __ASSEMBLY__
+
+#include <asm/hw_irq.h>
+#include <asm/meminit.h>
+
+/******************************************************************************
+ * general info
+ */
+struct pv_info {
+       unsigned int kernel_rpl;
+       int paravirt_enabled;
+       const char *name;
+};
+
+extern struct pv_info pv_info;
+
+static inline int paravirt_enabled(void)
+{
+       return pv_info.paravirt_enabled;
+}
+
+static inline unsigned int get_kernel_rpl(void)
+{
+       return pv_info.kernel_rpl;
+}
+
+/******************************************************************************
+ * initialization hooks.
+ */
+struct rsvd_region;
+
+struct pv_init_ops {
+       void (*banner)(void);
+
+       int (*reserve_memory)(struct rsvd_region *region);
+
+       void (*arch_setup_early)(void);
+       void (*arch_setup_console)(char **cmdline_p);
+       int (*arch_setup_nomca)(void);
+
+       void (*post_smp_prepare_boot_cpu)(void);
+};
+
+extern struct pv_init_ops pv_init_ops;
+
+static inline void paravirt_banner(void)
+{
+       if (pv_init_ops.banner)
+               pv_init_ops.banner();
+}
+
+static inline int paravirt_reserve_memory(struct rsvd_region *region)
+{
+       if (pv_init_ops.reserve_memory)
+               return pv_init_ops.reserve_memory(region);
+       return 0;
+}
+
+static inline void paravirt_arch_setup_early(void)
+{
+       if (pv_init_ops.arch_setup_early)
+               pv_init_ops.arch_setup_early();
+}
+
+static inline void paravirt_arch_setup_console(char **cmdline_p)
+{
+       if (pv_init_ops.arch_setup_console)
+               pv_init_ops.arch_setup_console(cmdline_p);
+}
+
+static inline int paravirt_arch_setup_nomca(void)
+{
+       if (pv_init_ops.arch_setup_nomca)
+               return pv_init_ops.arch_setup_nomca();
+       return 0;
+}
+
+static inline void paravirt_post_smp_prepare_boot_cpu(void)
+{
+       if (pv_init_ops.post_smp_prepare_boot_cpu)
+               pv_init_ops.post_smp_prepare_boot_cpu();
+}
+
+/******************************************************************************
+ * replacement of iosapic operations.
+ */
+
+struct pv_iosapic_ops {
+       void (*pcat_compat_init)(void);
+
+       struct irq_chip *(*get_irq_chip)(unsigned long trigger);
+
+       unsigned int (*__read)(char __iomem *iosapic, unsigned int reg);
+       void (*__write)(char __iomem *iosapic, unsigned int reg, u32 val);
+};
+
+extern struct pv_iosapic_ops pv_iosapic_ops;
+
+static inline void
+iosapic_pcat_compat_init(void)
+{
+       if (pv_iosapic_ops.pcat_compat_init)
+               pv_iosapic_ops.pcat_compat_init();
+}
+
+static inline struct irq_chip*
+iosapic_get_irq_chip(unsigned long trigger)
+{
+       return pv_iosapic_ops.get_irq_chip(trigger);
+}
+
+static inline unsigned int
+__iosapic_read(char __iomem *iosapic, unsigned int reg)
+{
+       return pv_iosapic_ops.__read(iosapic, reg);
+}
+
+static inline void
+__iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
+{
+       return pv_iosapic_ops.__write(iosapic, reg, val);
+}
+
+/******************************************************************************
+ * replacement of irq operations.
+ */
+
+struct pv_irq_ops {
+       void (*register_ipi)(void);
+
+       int (*assign_irq_vector)(int irq);
+       void (*free_irq_vector)(int vector);
+
+       void (*register_percpu_irq)(ia64_vector vec,
+                                   struct irqaction *action);
+
+       void (*resend_irq)(unsigned int vector);
+};
+
+extern struct pv_irq_ops pv_irq_ops;
+
+static inline void
+ia64_register_ipi(void)
+{
+       pv_irq_ops.register_ipi();
+}
+
+static inline int
+assign_irq_vector(int irq)
+{
+       return pv_irq_ops.assign_irq_vector(irq);
+}
+
+static inline void
+free_irq_vector(int vector)
+{
+       return pv_irq_ops.free_irq_vector(vector);
+}
+
+static inline void
+register_percpu_irq(ia64_vector vec, struct irqaction *action)
+{
+       pv_irq_ops.register_percpu_irq(vec, action);
+}
+
+static inline void
+ia64_resend_irq(unsigned int vector)
+{
+       pv_irq_ops.resend_irq(vector);
+}
+
+/******************************************************************************
+ * replacement of time operations.
+ */
+
+extern struct itc_jitter_data_t itc_jitter_data;
+extern volatile int time_keeper_id;
+
+struct pv_time_ops {
+       void (*init_missing_ticks_accounting)(int cpu);
+       int (*do_steal_accounting)(unsigned long *new_itm);
+
+       void (*clocksource_resume)(void);
+};
+
+extern struct pv_time_ops pv_time_ops;
+
+static inline void
+paravirt_init_missing_ticks_accounting(int cpu)
+{
+       if (pv_time_ops.init_missing_ticks_accounting)
+               pv_time_ops.init_missing_ticks_accounting(cpu);
+}
+
+static inline int
+paravirt_do_steal_accounting(unsigned long *new_itm)
+{
+       return pv_time_ops.do_steal_accounting(new_itm);
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#else
+/* fallback for native case */
+
+#ifndef __ASSEMBLY__
+
+#define paravirt_banner()                              do { } while (0)
+#define paravirt_reserve_memory(region)                        0
+
+#define paravirt_arch_setup_early()                    do { } while (0)
+#define paravirt_arch_setup_console(cmdline_p)         do { } while (0)
+#define paravirt_arch_setup_nomca()                    0
+#define paravirt_post_smp_prepare_boot_cpu()           do { } while (0)
+
+#define paravirt_init_missing_ticks_accounting(cpu)    do { } while (0)
+#define paravirt_do_steal_accounting(new_itm)          0
+
+#endif /* __ASSEMBLY__ */
+
+
+#endif /* CONFIG_PARAVIRT_GUEST */
+
+#endif /* __ASM_PARAVIRT_H */
diff --git a/include/asm-ia64/paravirt_privop.h b/include/asm-ia64/paravirt_privop.h
new file mode 100644 (file)
index 0000000..52482e6
--- /dev/null
@@ -0,0 +1,114 @@
+/******************************************************************************
+ * include/asm-ia64/paravirt_privops.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 _ASM_IA64_PARAVIRT_PRIVOP_H
+#define _ASM_IA64_PARAVIRT_PRIVOP_H
+
+#ifdef CONFIG_PARAVIRT
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <asm/kregs.h> /* for IA64_PSR_I */
+
+/******************************************************************************
+ * replacement of intrinsics operations.
+ */
+
+struct pv_cpu_ops {
+       void (*fc)(unsigned long addr);
+       unsigned long (*thash)(unsigned long addr);
+       unsigned long (*get_cpuid)(int index);
+       unsigned long (*get_pmd)(int index);
+       unsigned long (*getreg)(int reg);
+       void (*setreg)(int reg, unsigned long val);
+       void (*ptcga)(unsigned long addr, unsigned long size);
+       unsigned long (*get_rr)(unsigned long index);
+       void (*set_rr)(unsigned long index, unsigned long val);
+       void (*set_rr0_to_rr4)(unsigned long val0, unsigned long val1,
+                              unsigned long val2, unsigned long val3,
+                              unsigned long val4);
+       void (*ssm_i)(void);
+       void (*rsm_i)(void);
+       unsigned long (*get_psr_i)(void);
+       void (*intrin_local_irq_restore)(unsigned long flags);
+};
+
+extern struct pv_cpu_ops pv_cpu_ops;
+
+extern void ia64_native_setreg_func(int regnum, unsigned long val);
+extern unsigned long ia64_native_getreg_func(int regnum);
+
+/************************************************/
+/* Instructions paravirtualized for performance */
+/************************************************/
+
+/* mask for ia64_native_ssm/rsm() must be constant.("i" constraing).
+ * static inline function doesn't satisfy it. */
+#define paravirt_ssm(mask)                     \
+       do {                                    \
+               if ((mask) == IA64_PSR_I)       \
+                       pv_cpu_ops.ssm_i();     \
+               else                            \
+                       ia64_native_ssm(mask);  \
+       } while (0)
+
+#define paravirt_rsm(mask)                     \
+       do {                                    \
+               if ((mask) == IA64_PSR_I)       \
+                       pv_cpu_ops.rsm_i();     \
+               else                            \
+                       ia64_native_rsm(mask);  \
+       } while (0)
+
+/******************************************************************************
+ * replacement of hand written assembly codes.
+ */
+struct pv_cpu_asm_switch {
+       unsigned long switch_to;
+       unsigned long leave_syscall;
+       unsigned long work_processed_syscall;
+       unsigned long leave_kernel;
+};
+void paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch);
+
+#endif /* __ASSEMBLY__ */
+
+#define IA64_PARAVIRT_ASM_FUNC(name)   paravirt_ ## name
+
+#else
+
+/* fallback for native case */
+#define IA64_PARAVIRT_ASM_FUNC(name)   ia64_native_ ## name
+
+#endif /* CONFIG_PARAVIRT */
+
+/* these routines utilize privilege-sensitive or performance-sensitive
+ * privileged instructions so the code must be replaced with
+ * paravirtualized versions */
+#define ia64_switch_to                 IA64_PARAVIRT_ASM_FUNC(switch_to)
+#define ia64_leave_syscall             IA64_PARAVIRT_ASM_FUNC(leave_syscall)
+#define ia64_work_processed_syscall    \
+       IA64_PARAVIRT_ASM_FUNC(work_processed_syscall)
+#define ia64_leave_kernel              IA64_PARAVIRT_ASM_FUNC(leave_kernel)
+
+#endif /* _ASM_IA64_PARAVIRT_PRIVOP_H */
index 27731e032ee999be767993dbdb47b8c3a7334086..12d96e0cd5134d9d95e01e6714b5b75179dcfcf7 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/cpumask.h>
 #include <linux/bitops.h>
+#include <linux/irqreturn.h>
 
 #include <asm/io.h>
 #include <asm/param.h>
@@ -120,6 +121,7 @@ extern void __init smp_build_cpu_map(void);
 extern void __init init_smp_config (void);
 extern void smp_do_timer (struct pt_regs *regs);
 
+extern irqreturn_t handle_IPI(int irq, void *dev_id);
 extern void smp_send_reschedule (int cpu);
 extern void identify_siblings (struct cpuinfo_ia64 *);
 extern int is_multithreading_enabled(void);
index 26e250bfb91211580635ac4665734389d46cd45b..927a381c20ca06e35c7ba7ed10a6ef35e1826752 100644 (file)
@@ -26,6 +26,7 @@
  */
 #define KERNEL_START            (GATE_ADDR+__IA64_UL_CONST(0x100000000))
 #define PERCPU_ADDR            (-PERCPU_PAGE_SIZE)
+#define LOAD_OFFSET            (KERNEL_START - KERNEL_TR_PAGE_SIZE)
 
 #ifndef __ASSEMBLY__
 
@@ -122,10 +123,16 @@ extern struct ia64_boot_param {
  *   write a floating-point register right before reading the PSR
  *   and that writes to PSR.mfl
  */
+#ifdef CONFIG_PARAVIRT
+#define __local_save_flags()   ia64_get_psr_i()
+#else
+#define __local_save_flags()   ia64_getreg(_IA64_REG_PSR)
+#endif
+
 #define __local_irq_save(x)                    \
 do {                                           \
        ia64_stop();                            \
-       (x) = ia64_getreg(_IA64_REG_PSR);       \
+       (x) = __local_save_flags();             \
        ia64_stop();                            \
        ia64_rsm(IA64_PSR_I);                   \
 } while (0)
@@ -173,7 +180,7 @@ do {                                                                \
 #endif /* !CONFIG_IA64_DEBUG_IRQ */
 
 #define local_irq_enable()     ({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); })
-#define local_save_flags(flags)        ({ ia64_stop(); (flags) = ia64_getreg(_IA64_REG_PSR); })
+#define local_save_flags(flags)        ({ ia64_stop(); (flags) = __local_save_flags(); })
 
 #define irqs_disabled()                                \
 ({                                             \
index 1cc1dbb0182f6bdb73d6fa0c53451d5ffce129a9..c149ef085437f22cc46b2ad6db09c1ec0520d45f 100644 (file)
 #ifndef __ASM_IA64_UV_MMRS__
 #define __ASM_IA64_UV_MMRS__
 
-/*
- *       AUTO GENERATED - Do not edit
- */
+#define UV_MMR_ENABLE          (1UL << 63)
+
+/* ========================================================================= */
+/*                           UVH_BAU_DATA_CONFIG                             */
+/* ========================================================================= */
+#define UVH_BAU_DATA_CONFIG 0x61680UL
+#define UVH_BAU_DATA_CONFIG_32 0x0438
+
+#define UVH_BAU_DATA_CONFIG_VECTOR_SHFT 0
+#define UVH_BAU_DATA_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_BAU_DATA_CONFIG_DM_SHFT 8
+#define UVH_BAU_DATA_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_BAU_DATA_CONFIG_DESTMODE_SHFT 11
+#define UVH_BAU_DATA_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_BAU_DATA_CONFIG_STATUS_SHFT 12
+#define UVH_BAU_DATA_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_BAU_DATA_CONFIG_P_SHFT 13
+#define UVH_BAU_DATA_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_BAU_DATA_CONFIG_T_SHFT 15
+#define UVH_BAU_DATA_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_BAU_DATA_CONFIG_M_SHFT 16
+#define UVH_BAU_DATA_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_BAU_DATA_CONFIG_APIC_ID_SHFT 32
+#define UVH_BAU_DATA_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_bau_data_config_u {
+    unsigned long      v;
+    struct uvh_bau_data_config_s {
+       unsigned long   vector_  :  8;  /* RW */
+       unsigned long   dm       :  3;  /* RW */
+       unsigned long   destmode :  1;  /* RW */
+       unsigned long   status   :  1;  /* RO */
+       unsigned long   p        :  1;  /* RO */
+       unsigned long   rsvd_14  :  1;  /*    */
+       unsigned long   t        :  1;  /* RO */
+       unsigned long   m        :  1;  /* RW */
+       unsigned long   rsvd_17_31: 15;  /*    */
+       unsigned long   apic_id  : 32;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
+/*                           UVH_EVENT_OCCURRED0                             */
+/* ========================================================================= */
+#define UVH_EVENT_OCCURRED0 0x70000UL
+#define UVH_EVENT_OCCURRED0_32 0x005e8
+
+#define UVH_EVENT_OCCURRED0_LB_HCERR_SHFT 0
+#define UVH_EVENT_OCCURRED0_LB_HCERR_MASK 0x0000000000000001UL
+#define UVH_EVENT_OCCURRED0_GR0_HCERR_SHFT 1
+#define UVH_EVENT_OCCURRED0_GR0_HCERR_MASK 0x0000000000000002UL
+#define UVH_EVENT_OCCURRED0_GR1_HCERR_SHFT 2
+#define UVH_EVENT_OCCURRED0_GR1_HCERR_MASK 0x0000000000000004UL
+#define UVH_EVENT_OCCURRED0_LH_HCERR_SHFT 3
+#define UVH_EVENT_OCCURRED0_LH_HCERR_MASK 0x0000000000000008UL
+#define UVH_EVENT_OCCURRED0_RH_HCERR_SHFT 4
+#define UVH_EVENT_OCCURRED0_RH_HCERR_MASK 0x0000000000000010UL
+#define UVH_EVENT_OCCURRED0_XN_HCERR_SHFT 5
+#define UVH_EVENT_OCCURRED0_XN_HCERR_MASK 0x0000000000000020UL
+#define UVH_EVENT_OCCURRED0_SI_HCERR_SHFT 6
+#define UVH_EVENT_OCCURRED0_SI_HCERR_MASK 0x0000000000000040UL
+#define UVH_EVENT_OCCURRED0_LB_AOERR0_SHFT 7
+#define UVH_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000000080UL
+#define UVH_EVENT_OCCURRED0_GR0_AOERR0_SHFT 8
+#define UVH_EVENT_OCCURRED0_GR0_AOERR0_MASK 0x0000000000000100UL
+#define UVH_EVENT_OCCURRED0_GR1_AOERR0_SHFT 9
+#define UVH_EVENT_OCCURRED0_GR1_AOERR0_MASK 0x0000000000000200UL
+#define UVH_EVENT_OCCURRED0_LH_AOERR0_SHFT 10
+#define UVH_EVENT_OCCURRED0_LH_AOERR0_MASK 0x0000000000000400UL
+#define UVH_EVENT_OCCURRED0_RH_AOERR0_SHFT 11
+#define UVH_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL
+#define UVH_EVENT_OCCURRED0_XN_AOERR0_SHFT 12
+#define UVH_EVENT_OCCURRED0_XN_AOERR0_MASK 0x0000000000001000UL
+#define UVH_EVENT_OCCURRED0_SI_AOERR0_SHFT 13
+#define UVH_EVENT_OCCURRED0_SI_AOERR0_MASK 0x0000000000002000UL
+#define UVH_EVENT_OCCURRED0_LB_AOERR1_SHFT 14
+#define UVH_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000004000UL
+#define UVH_EVENT_OCCURRED0_GR0_AOERR1_SHFT 15
+#define UVH_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000000008000UL
+#define UVH_EVENT_OCCURRED0_GR1_AOERR1_SHFT 16
+#define UVH_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000000010000UL
+#define UVH_EVENT_OCCURRED0_LH_AOERR1_SHFT 17
+#define UVH_EVENT_OCCURRED0_LH_AOERR1_MASK 0x0000000000020000UL
+#define UVH_EVENT_OCCURRED0_RH_AOERR1_SHFT 18
+#define UVH_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000040000UL
+#define UVH_EVENT_OCCURRED0_XN_AOERR1_SHFT 19
+#define UVH_EVENT_OCCURRED0_XN_AOERR1_MASK 0x0000000000080000UL
+#define UVH_EVENT_OCCURRED0_SI_AOERR1_SHFT 20
+#define UVH_EVENT_OCCURRED0_SI_AOERR1_MASK 0x0000000000100000UL
+#define UVH_EVENT_OCCURRED0_RH_VPI_INT_SHFT 21
+#define UVH_EVENT_OCCURRED0_RH_VPI_INT_MASK 0x0000000000200000UL
+#define UVH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 22
+#define UVH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000400000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 23
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000000800000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 24
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000001000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 25
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000002000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 26
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000004000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 27
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000000008000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 28
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000000010000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 29
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000000020000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 30
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000000040000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 31
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000000080000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 32
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000000100000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 33
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000000200000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 34
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000000400000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 35
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000000800000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 36
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000001000000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 37
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000002000000000UL
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 38
+#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000004000000000UL
+#define UVH_EVENT_OCCURRED0_L1_NMI_INT_SHFT 39
+#define UVH_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0000008000000000UL
+#define UVH_EVENT_OCCURRED0_STOP_CLOCK_SHFT 40
+#define UVH_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0000010000000000UL
+#define UVH_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 41
+#define UVH_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0000020000000000UL
+#define UVH_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 42
+#define UVH_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0000040000000000UL
+#define UVH_EVENT_OCCURRED0_LTC_INT_SHFT 43
+#define UVH_EVENT_OCCURRED0_LTC_INT_MASK 0x0000080000000000UL
+#define UVH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 44
+#define UVH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0000100000000000UL
+#define UVH_EVENT_OCCURRED0_IPI_INT_SHFT 45
+#define UVH_EVENT_OCCURRED0_IPI_INT_MASK 0x0000200000000000UL
+#define UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT 46
+#define UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0000400000000000UL
+#define UVH_EVENT_OCCURRED0_EXTIO_INT1_SHFT 47
+#define UVH_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0000800000000000UL
+#define UVH_EVENT_OCCURRED0_EXTIO_INT2_SHFT 48
+#define UVH_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0001000000000000UL
+#define UVH_EVENT_OCCURRED0_EXTIO_INT3_SHFT 49
+#define UVH_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0002000000000000UL
+#define UVH_EVENT_OCCURRED0_PROFILE_INT_SHFT 50
+#define UVH_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0004000000000000UL
+#define UVH_EVENT_OCCURRED0_RTC0_SHFT 51
+#define UVH_EVENT_OCCURRED0_RTC0_MASK 0x0008000000000000UL
+#define UVH_EVENT_OCCURRED0_RTC1_SHFT 52
+#define UVH_EVENT_OCCURRED0_RTC1_MASK 0x0010000000000000UL
+#define UVH_EVENT_OCCURRED0_RTC2_SHFT 53
+#define UVH_EVENT_OCCURRED0_RTC2_MASK 0x0020000000000000UL
+#define UVH_EVENT_OCCURRED0_RTC3_SHFT 54
+#define UVH_EVENT_OCCURRED0_RTC3_MASK 0x0040000000000000UL
+#define UVH_EVENT_OCCURRED0_BAU_DATA_SHFT 55
+#define UVH_EVENT_OCCURRED0_BAU_DATA_MASK 0x0080000000000000UL
+#define UVH_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_SHFT 56
+#define UVH_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_MASK 0x0100000000000000UL
+union uvh_event_occurred0_u {
+    unsigned long      v;
+    struct uvh_event_occurred0_s {
+       unsigned long   lb_hcerr             :  1;  /* RW, W1C */
+       unsigned long   gr0_hcerr            :  1;  /* RW, W1C */
+       unsigned long   gr1_hcerr            :  1;  /* RW, W1C */
+       unsigned long   lh_hcerr             :  1;  /* RW, W1C */
+       unsigned long   rh_hcerr             :  1;  /* RW, W1C */
+       unsigned long   xn_hcerr             :  1;  /* RW, W1C */
+       unsigned long   si_hcerr             :  1;  /* RW, W1C */
+       unsigned long   lb_aoerr0            :  1;  /* RW, W1C */
+       unsigned long   gr0_aoerr0           :  1;  /* RW, W1C */
+       unsigned long   gr1_aoerr0           :  1;  /* RW, W1C */
+       unsigned long   lh_aoerr0            :  1;  /* RW, W1C */
+       unsigned long   rh_aoerr0            :  1;  /* RW, W1C */
+       unsigned long   xn_aoerr0            :  1;  /* RW, W1C */
+       unsigned long   si_aoerr0            :  1;  /* RW, W1C */
+       unsigned long   lb_aoerr1            :  1;  /* RW, W1C */
+       unsigned long   gr0_aoerr1           :  1;  /* RW, W1C */
+       unsigned long   gr1_aoerr1           :  1;  /* RW, W1C */
+       unsigned long   lh_aoerr1            :  1;  /* RW, W1C */
+       unsigned long   rh_aoerr1            :  1;  /* RW, W1C */
+       unsigned long   xn_aoerr1            :  1;  /* RW, W1C */
+       unsigned long   si_aoerr1            :  1;  /* RW, W1C */
+       unsigned long   rh_vpi_int           :  1;  /* RW, W1C */
+       unsigned long   system_shutdown_int  :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_0         :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_1         :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_2         :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_3         :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_4         :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_5         :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_6         :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_7         :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_8         :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_9         :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_10        :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_11        :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_12        :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_13        :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_14        :  1;  /* RW, W1C */
+       unsigned long   lb_irq_int_15        :  1;  /* RW, W1C */
+       unsigned long   l1_nmi_int           :  1;  /* RW, W1C */
+       unsigned long   stop_clock           :  1;  /* RW, W1C */
+       unsigned long   asic_to_l1           :  1;  /* RW, W1C */
+       unsigned long   l1_to_asic           :  1;  /* RW, W1C */
+       unsigned long   ltc_int              :  1;  /* RW, W1C */
+       unsigned long   la_seq_trigger       :  1;  /* RW, W1C */
+       unsigned long   ipi_int              :  1;  /* RW, W1C */
+       unsigned long   extio_int0           :  1;  /* RW, W1C */
+       unsigned long   extio_int1           :  1;  /* RW, W1C */
+       unsigned long   extio_int2           :  1;  /* RW, W1C */
+       unsigned long   extio_int3           :  1;  /* RW, W1C */
+       unsigned long   profile_int          :  1;  /* RW, W1C */
+       unsigned long   rtc0                 :  1;  /* RW, W1C */
+       unsigned long   rtc1                 :  1;  /* RW, W1C */
+       unsigned long   rtc2                 :  1;  /* RW, W1C */
+       unsigned long   rtc3                 :  1;  /* RW, W1C */
+       unsigned long   bau_data             :  1;  /* RW, W1C */
+       unsigned long   power_management_req :  1;  /* RW, W1C */
+       unsigned long   rsvd_57_63           :  7;  /*    */
+    } s;
+};
+
+/* ========================================================================= */
+/*                        UVH_EVENT_OCCURRED0_ALIAS                          */
+/* ========================================================================= */
+#define UVH_EVENT_OCCURRED0_ALIAS 0x0000000000070008UL
+#define UVH_EVENT_OCCURRED0_ALIAS_32 0x005f0
+
+/* ========================================================================= */
+/*                               UVH_INT_CMPB                                */
+/* ========================================================================= */
+#define UVH_INT_CMPB 0x22080UL
+
+#define UVH_INT_CMPB_REAL_TIME_CMPB_SHFT 0
+#define UVH_INT_CMPB_REAL_TIME_CMPB_MASK 0x00ffffffffffffffUL
+
+union uvh_int_cmpb_u {
+    unsigned long      v;
+    struct uvh_int_cmpb_s {
+       unsigned long   real_time_cmpb : 56;  /* RW */
+       unsigned long   rsvd_56_63     :  8;  /*    */
+    } s;
+};
+
+/* ========================================================================= */
+/*                               UVH_INT_CMPC                                */
+/* ========================================================================= */
+#define UVH_INT_CMPC 0x22100UL
+
+#define UVH_INT_CMPC_REAL_TIME_CMPC_SHFT 0
+#define UVH_INT_CMPC_REAL_TIME_CMPC_MASK 0x00ffffffffffffffUL
+
+union uvh_int_cmpc_u {
+    unsigned long      v;
+    struct uvh_int_cmpc_s {
+       unsigned long   real_time_cmpc : 56;  /* RW */
+       unsigned long   rsvd_56_63     :  8;  /*    */
+    } s;
+};
 
- #define UV_MMR_ENABLE         (1UL << 63)
+/* ========================================================================= */
+/*                               UVH_INT_CMPD                                */
+/* ========================================================================= */
+#define UVH_INT_CMPD 0x22180UL
+
+#define UVH_INT_CMPD_REAL_TIME_CMPD_SHFT 0
+#define UVH_INT_CMPD_REAL_TIME_CMPD_MASK 0x00ffffffffffffffUL
+
+union uvh_int_cmpd_u {
+    unsigned long      v;
+    struct uvh_int_cmpd_s {
+       unsigned long   real_time_cmpd : 56;  /* RW */
+       unsigned long   rsvd_56_63     :  8;  /*    */
+    } s;
+};
 
 /* ========================================================================= */
 /*                               UVH_NODE_ID                                 */
@@ -111,8 +384,8 @@ union uvh_rh_gam_alias210_redirect_config_2_mmr_u {
 
 #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28
 #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_SHFT 46
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_MASK 0x0000400000000000UL
+#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_SHFT 48
+#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_MASK 0x0001000000000000UL
 #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52
 #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL
 #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
@@ -123,8 +396,9 @@ union uvh_rh_gam_gru_overlay_config_mmr_u {
     struct uvh_rh_gam_gru_overlay_config_mmr_s {
        unsigned long   rsvd_0_27: 28;  /*    */
        unsigned long   base   : 18;  /* RW */
+       unsigned long   rsvd_46_47:  2;  /*    */
        unsigned long   gr4    :  1;  /* RW */
-       unsigned long   rsvd_47_51:  5;  /*    */
+       unsigned long   rsvd_49_51:  3;  /*    */
        unsigned long   n_gru  :  4;  /* RW */
        unsigned long   rsvd_56_62:  7;  /*    */
        unsigned long   enable :  1;  /* RW */
@@ -157,7 +431,7 @@ union uvh_rh_gam_mmr_overlay_config_mmr_u {
 /* ========================================================================= */
 /*                                 UVH_RTC                                   */
 /* ========================================================================= */
-#define UVH_RTC 0x28000UL
+#define UVH_RTC 0x340000UL
 
 #define UVH_RTC_REAL_TIME_CLOCK_SHFT 0
 #define UVH_RTC_REAL_TIME_CLOCK_MASK 0x00ffffffffffffffUL
@@ -170,6 +444,139 @@ union uvh_rtc_u {
     } s;
 };
 
+/* ========================================================================= */
+/*                           UVH_RTC1_INT_CONFIG                             */
+/* ========================================================================= */
+#define UVH_RTC1_INT_CONFIG 0x615c0UL
+
+#define UVH_RTC1_INT_CONFIG_VECTOR_SHFT 0
+#define UVH_RTC1_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_RTC1_INT_CONFIG_DM_SHFT 8
+#define UVH_RTC1_INT_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_RTC1_INT_CONFIG_DESTMODE_SHFT 11
+#define UVH_RTC1_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_RTC1_INT_CONFIG_STATUS_SHFT 12
+#define UVH_RTC1_INT_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_RTC1_INT_CONFIG_P_SHFT 13
+#define UVH_RTC1_INT_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_RTC1_INT_CONFIG_T_SHFT 15
+#define UVH_RTC1_INT_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_RTC1_INT_CONFIG_M_SHFT 16
+#define UVH_RTC1_INT_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_RTC1_INT_CONFIG_APIC_ID_SHFT 32
+#define UVH_RTC1_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_rtc1_int_config_u {
+    unsigned long      v;
+    struct uvh_rtc1_int_config_s {
+       unsigned long   vector_  :  8;  /* RW */
+       unsigned long   dm       :  3;  /* RW */
+       unsigned long   destmode :  1;  /* RW */
+       unsigned long   status   :  1;  /* RO */
+       unsigned long   p        :  1;  /* RO */
+       unsigned long   rsvd_14  :  1;  /*    */
+       unsigned long   t        :  1;  /* RO */
+       unsigned long   m        :  1;  /* RW */
+       unsigned long   rsvd_17_31: 15;  /*    */
+       unsigned long   apic_id  : 32;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
+/*                           UVH_RTC2_INT_CONFIG                             */
+/* ========================================================================= */
+#define UVH_RTC2_INT_CONFIG 0x61600UL
+
+#define UVH_RTC2_INT_CONFIG_VECTOR_SHFT 0
+#define UVH_RTC2_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_RTC2_INT_CONFIG_DM_SHFT 8
+#define UVH_RTC2_INT_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_RTC2_INT_CONFIG_DESTMODE_SHFT 11
+#define UVH_RTC2_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_RTC2_INT_CONFIG_STATUS_SHFT 12
+#define UVH_RTC2_INT_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_RTC2_INT_CONFIG_P_SHFT 13
+#define UVH_RTC2_INT_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_RTC2_INT_CONFIG_T_SHFT 15
+#define UVH_RTC2_INT_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_RTC2_INT_CONFIG_M_SHFT 16
+#define UVH_RTC2_INT_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_RTC2_INT_CONFIG_APIC_ID_SHFT 32
+#define UVH_RTC2_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_rtc2_int_config_u {
+    unsigned long      v;
+    struct uvh_rtc2_int_config_s {
+       unsigned long   vector_  :  8;  /* RW */
+       unsigned long   dm       :  3;  /* RW */
+       unsigned long   destmode :  1;  /* RW */
+       unsigned long   status   :  1;  /* RO */
+       unsigned long   p        :  1;  /* RO */
+       unsigned long   rsvd_14  :  1;  /*    */
+       unsigned long   t        :  1;  /* RO */
+       unsigned long   m        :  1;  /* RW */
+       unsigned long   rsvd_17_31: 15;  /*    */
+       unsigned long   apic_id  : 32;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
+/*                           UVH_RTC3_INT_CONFIG                             */
+/* ========================================================================= */
+#define UVH_RTC3_INT_CONFIG 0x61640UL
+
+#define UVH_RTC3_INT_CONFIG_VECTOR_SHFT 0
+#define UVH_RTC3_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_RTC3_INT_CONFIG_DM_SHFT 8
+#define UVH_RTC3_INT_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_RTC3_INT_CONFIG_DESTMODE_SHFT 11
+#define UVH_RTC3_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_RTC3_INT_CONFIG_STATUS_SHFT 12
+#define UVH_RTC3_INT_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_RTC3_INT_CONFIG_P_SHFT 13
+#define UVH_RTC3_INT_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_RTC3_INT_CONFIG_T_SHFT 15
+#define UVH_RTC3_INT_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_RTC3_INT_CONFIG_M_SHFT 16
+#define UVH_RTC3_INT_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_RTC3_INT_CONFIG_APIC_ID_SHFT 32
+#define UVH_RTC3_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_rtc3_int_config_u {
+    unsigned long      v;
+    struct uvh_rtc3_int_config_s {
+       unsigned long   vector_  :  8;  /* RW */
+       unsigned long   dm       :  3;  /* RW */
+       unsigned long   destmode :  1;  /* RW */
+       unsigned long   status   :  1;  /* RO */
+       unsigned long   p        :  1;  /* RO */
+       unsigned long   rsvd_14  :  1;  /*    */
+       unsigned long   t        :  1;  /* RO */
+       unsigned long   m        :  1;  /* RW */
+       unsigned long   rsvd_17_31: 15;  /*    */
+       unsigned long   apic_id  : 32;  /* RW */
+    } s;
+};
+
+/* ========================================================================= */
+/*                            UVH_RTC_INC_RATIO                              */
+/* ========================================================================= */
+#define UVH_RTC_INC_RATIO 0x350000UL
+
+#define UVH_RTC_INC_RATIO_FRACTION_SHFT 0
+#define UVH_RTC_INC_RATIO_FRACTION_MASK 0x00000000000fffffUL
+#define UVH_RTC_INC_RATIO_RATIO_SHFT 20
+#define UVH_RTC_INC_RATIO_RATIO_MASK 0x0000000000700000UL
+
+union uvh_rtc_inc_ratio_u {
+    unsigned long      v;
+    struct uvh_rtc_inc_ratio_s {
+       unsigned long   fraction : 20;  /* RW */
+       unsigned long   ratio    :  3;  /* RW */
+       unsigned long   rsvd_23_63: 41;  /*    */
+    } s;
+};
+
 /* ========================================================================= */
 /*                          UVH_SI_ADDR_MAP_CONFIG                           */
 /* ========================================================================= */
index 8ec2e1da68bf7573f99cf68697b3bf0d54cf2b73..8f0fe797194992829dd5926ef2d80605415e5059 100644 (file)
@@ -22,6 +22,7 @@
 #define PPC_STL                stringify_in_c(std)
 #define PPC_LCMPI      stringify_in_c(cmpdi)
 #define PPC_LONG       stringify_in_c(.llong)
+#define PPC_LONG_ALIGN stringify_in_c(.balign 8)
 #define PPC_TLNEI      stringify_in_c(tdnei)
 #define PPC_LLARX      stringify_in_c(ldarx)
 #define PPC_STLCX      stringify_in_c(stdcx.)
@@ -43,6 +44,7 @@
 #define PPC_STL                stringify_in_c(stw)
 #define PPC_LCMPI      stringify_in_c(cmpwi)
 #define PPC_LONG       stringify_in_c(.long)
+#define PPC_LONG_ALIGN stringify_in_c(.balign 4)
 #define PPC_TLNEI      stringify_in_c(twnei)
 #define PPC_LLARX      stringify_in_c(lwarx)
 #define PPC_STLCX      stringify_in_c(stwcx.)
index b617dac82969085a2217e9ee502e05e04ac9ca11..1399caf719aefcfffc2871976b184d967173396e 100644 (file)
@@ -1,57 +1,65 @@
 /*
- * kgdb.h: Defines and declarations for serial line source level
- *         remote debugging of the Linux kernel using gdb.
+ * include/asm-powerpc/kgdb.h
  *
+ * The PowerPC (32/64) specific defines / externs for KGDB.  Based on
+ * the previous 32bit and 64bit specific files, which had the following
+ * copyrights:
+ *
+ * PPC64 Mods (C) 2005 Frank Rowand (frowand@mvista.com)
+ * PPC Mods (C) 2004 Tom Rini (trini@mvista.com)
+ * PPC Mods (C) 2003 John Whitney (john.whitney@timesys.com)
  * PPC Mods (C) 1998 Michael Tesch (tesch@cs.wisc.edu)
  *
+ *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Author: Tom Rini <trini@kernel.crashing.org>
+ *
+ * 2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #ifdef __KERNEL__
-#ifndef _PPC_KGDB_H
-#define _PPC_KGDB_H
+#ifndef __POWERPC_KGDB_H__
+#define __POWERPC_KGDB_H__
 
 #ifndef __ASSEMBLY__
 
-/* Things specific to the gen550 backend. */
-struct uart_port;
-
-extern void gen550_progress(char *, unsigned short);
-extern void gen550_kgdb_map_scc(void);
-extern void gen550_init(int, struct uart_port *);
-
-/* Things specific to the pmac backend. */
-extern void zs_kgdb_hook(int tty_num);
-
-/* To init the kgdb engine. (called by serial hook)*/
-extern void set_debug_traps(void);
-
-/* To enter the debugger explicitly. */
-extern void breakpoint(void);
-
-/* For taking exceptions
- * these are defined in traps.c
- */
-extern int (*debugger)(struct pt_regs *regs);
-extern int (*debugger_bpt)(struct pt_regs *regs);
-extern int (*debugger_sstep)(struct pt_regs *regs);
-extern int (*debugger_iabr_match)(struct pt_regs *regs);
-extern int (*debugger_dabr_match)(struct pt_regs *regs);
-extern void (*debugger_fault_handler)(struct pt_regs *regs);
-
-/* What we bring to the party */
-int kgdb_bpt(struct pt_regs *regs);
-int kgdb_sstep(struct pt_regs *regs);
-void kgdb(struct pt_regs *regs);
-int kgdb_iabr_match(struct pt_regs *regs);
-int kgdb_dabr_match(struct pt_regs *regs);
+#define BREAK_INSTR_SIZE       4
+#define BUFMAX                 ((NUMREGBYTES * 2) + 512)
+#define OUTBUFMAX              ((NUMREGBYTES * 2) + 512)
+static inline void arch_kgdb_breakpoint(void)
+{
+       asm(".long 0x7d821008"); /* twge r2, r2 */
+}
+#define CACHE_FLUSH_IS_SAFE    1
 
+/* The number bytes of registers we have to save depends on a few
+ * things.  For 64bit we default to not including vector registers and
+ * vector state registers. */
+#ifdef CONFIG_PPC64
 /*
- * external low-level support routines (ie macserial.c)
+ * 64 bit (8 byte) registers:
+ *   32 gpr, 32 fpr, nip, msr, link, ctr
+ * 32 bit (4 byte) registers:
+ *   ccr, xer, fpscr
  */
-extern void kgdb_interruptible(int); /* control interrupts from serial */
-extern void putDebugChar(char);   /* write a single character      */
-extern char getDebugChar(void);   /* read and return a single char */
-
+#define NUMREGBYTES            ((68 * 8) + (3 * 4))
+#define NUMCRITREGBYTES                184
+#else /* CONFIG_PPC32 */
+/* On non-E500 family PPC32 we determine the size by picking the last
+ * register we need, but on E500 we skip sections so we list what we
+ * need to store, and add it up. */
+#ifndef CONFIG_E500
+#define MAXREG                 (PT_FPSCR+1)
+#else
+/* 32 GPRs (8 bytes), nip, msr, ccr, link, ctr, xer, acc (8 bytes), spefscr*/
+#define MAXREG                 ((32*2)+6+2+1)
+#endif
+#define NUMREGBYTES            (MAXREG * sizeof(int))
+/* CR/LR, R1, R2, R13-R31 inclusive. */
+#define NUMCRITREGBYTES                (23 * sizeof(int))
+#endif /* 32/64 */
 #endif /* !(__ASSEMBLY__) */
-#endif /* !(_PPC_KGDB_H) */
+#endif /* !__POWERPC_KGDB_H__ */
 #endif /* __KERNEL__ */
index 989922621e353fdfea01149dbf6c075967261510..1233d735fd289a5831e7d6a542a0912b9cffcf32 100644 (file)
@@ -80,7 +80,8 @@ struct machdep_calls {
                                     long index,
                                     long npages,
                                     unsigned long uaddr,
-                                    enum dma_data_direction direction);
+                                    enum dma_data_direction direction,
+                                    struct dma_attrs *attrs);
        void            (*tce_free)(struct iommu_table *tbl,
                                    long index,
                                    long npages);
index 73015f0139deeb94c0a81adf6b7e5007049666a3..3a96d001cb7539866ecdbd00e3e53934979f92b6 100644 (file)
@@ -295,10 +295,10 @@ extern int icache_44x_need_flush;
 #define _PAGE_PRESENT  0x00001 /* S: PTE contains a translation */
 #define _PAGE_USER     0x00002 /* S: User page (maps to UR) */
 #define _PAGE_FILE     0x00002 /* S: when !present: nonlinear file mapping */
-#define _PAGE_ACCESSED 0x00004 /* S: Page referenced */
-#define _PAGE_HWWRITE  0x00008 /* H: Dirty & RW, set in exception */
-#define _PAGE_RW       0x00010 /* S: Write permission */
-#define _PAGE_HWEXEC   0x00020 /* H: UX permission */
+#define _PAGE_RW       0x00004 /* S: Write permission (SW) */
+#define _PAGE_DIRTY    0x00008 /* S: Page dirty */
+#define _PAGE_HWEXEC   0x00010 /* H: SX permission */
+#define _PAGE_ACCESSED 0x00020 /* S: Page referenced */
 
 #define _PAGE_ENDIAN   0x00040 /* H: E bit */
 #define _PAGE_GUARDED  0x00080 /* H: G bit */
@@ -307,21 +307,14 @@ extern int icache_44x_need_flush;
 #define _PAGE_WRITETHRU        0x00400 /* H: W bit */
 
 #ifdef CONFIG_PTE_64BIT
-#define _PAGE_DIRTY    0x08000 /* S: Page dirty */
-
 /* ERPN in a PTE never gets cleared, ignore it */
 #define _PTE_NONE_MASK 0xffffffffffff0000ULL
-#else
-#define _PAGE_DIRTY    0x00800 /* S: Page dirty */
 #endif
 
 #define _PMD_PRESENT   0
 #define _PMD_PRESENT_MASK (PAGE_MASK)
 #define _PMD_BAD       (~PAGE_MASK)
 
-/* Until my rework is finished, FSL BookE still needs atomic PTE updates */
-#define PTE_ATOMIC_UPDATES     1
-
 #elif defined(CONFIG_8xx)
 /* Definitions for 8xx embedded chips. */
 #define _PAGE_PRESENT  0x0001  /* Page is valid */
index e1dc090748dff7b3774197f2fb28d0b3fffb7747..b4e91fbf5081ab79533856a12f3370d42218499a 100644 (file)
@@ -30,6 +30,7 @@
 #ifdef __KERNEL__
 
 #define PMI_TYPE_FREQ_CHANGE   0x01
+#define PMI_TYPE_POWER_BUTTON  0x02
 #define PMI_READ_TYPE          0
 #define PMI_READ_DATA0         1
 #define PMI_READ_DATA1         2
index 81ffe3b3c1ce771b29062d5111d1c23d5aa94875..f9e34c493cbbcb3764a7f584296ca5809cfa60a9 100644 (file)
@@ -337,12 +337,18 @@ enum ps3_system_bus_device_type {
        PS3_DEVICE_TYPE_LPM,
 };
 
+enum ps3_match_sub_id {
+       /* for PS3_MATCH_ID_GRAPHICS */
+       PS3_MATCH_SUB_ID_FB             = 1,
+};
+
 /**
  * struct ps3_system_bus_device - a device on the system bus
  */
 
 struct ps3_system_bus_device {
        enum ps3_match_id match_id;
+       enum ps3_match_sub_id match_sub_id;
        enum ps3_system_bus_device_type dev_type;
 
        u64 bus_id;                       /* SB */
@@ -371,6 +377,7 @@ int ps3_close_hv_device(struct ps3_system_bus_device *dev);
 
 struct ps3_system_bus_driver {
        enum ps3_match_id match_id;
+       enum ps3_match_sub_id match_sub_id;
        struct device_driver core;
        int (*probe)(struct ps3_system_bus_device *);
        int (*remove)(struct ps3_system_bus_device *);
index bbccadfee0d63c90f705554af0b88c05f109c552..c6d1ab650778fa440d6eb79fa25a1b0a3cc779aa 100644 (file)
 #define   CTRL_RUNLATCH        0x1
 #define SPRN_DABR      0x3F5   /* Data Address Breakpoint Register */
 #define   DABR_TRANSLATION     (1UL << 2)
+#define SPRN_DABR2     0x13D   /* e300 */
 #define SPRN_DABRX     0x3F7   /* Data Address Breakpoint Register Extension */
 #define   DABRX_USER   (1UL << 0)
 #define   DABRX_KERNEL (1UL << 1)
 #define SPRN_DAR       0x013   /* Data Address Register */
+#define SPRN_DBCR      0x136   /* e300 Data Breakpoint Control Reg */
 #define SPRN_DSISR     0x012   /* Data Storage Interrupt Status Register */
 #define   DSISR_NOHPTE         0x40000000      /* no translation found */
 #define   DSISR_PROTFAULT      0x08000000      /* protection fault */
 #define HID1_PS                (1<<16)         /* 750FX PLL selection */
 #define SPRN_HID2      0x3F8           /* Hardware Implementation Register 2 */
 #define SPRN_IABR      0x3F2   /* Instruction Address Breakpoint Register */
+#define SPRN_IABR2     0x3FA           /* 83xx */
+#define SPRN_IBCR      0x135           /* 83xx Insn Breakpoint Control Reg */
 #define SPRN_HID4      0x3F4           /* 970 HID4 */
 #define SPRN_HID5      0x3F6           /* 970 HID5 */
 #define SPRN_HID6      0x3F9   /* BE HID 6 */
index 1a0736f8803fa8db84de6b428ae808c95b49b835..bd0fb8495154d1684f51aa9bce6654ca6a763a99 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/sched.h>
 #include <linux/errno.h>
+#include <asm/asm-compat.h>
 #include <asm/processor.h>
 #include <asm/page.h>
 
@@ -141,12 +142,11 @@ extern long __put_user_bad(void);
                "       b 2b\n"                                 \
                ".previous\n"                                   \
                ".section __ex_table,\"a\"\n"                   \
-               "       .balign %5\n"                           \
+                       PPC_LONG_ALIGN "\n"                     \
                        PPC_LONG "1b,3b\n"                      \
                ".previous"                                     \
                : "=r" (err)                                    \
-               : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\
-                 "i"(sizeof(unsigned long)))
+               : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
 
 #ifdef __powerpc64__
 #define __put_user_asm2(x, ptr, retval)                                \
@@ -162,13 +162,12 @@ extern long __put_user_bad(void);
                "       b 3b\n"                                 \
                ".previous\n"                                   \
                ".section __ex_table,\"a\"\n"                   \
-               "       .balign %5\n"                           \
+                       PPC_LONG_ALIGN "\n"                     \
                        PPC_LONG "1b,4b\n"                      \
                        PPC_LONG "2b,4b\n"                      \
                ".previous"                                     \
                : "=r" (err)                                    \
-               : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\
-                 "i"(sizeof(unsigned long)))
+               : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
 #endif /* __powerpc64__ */
 
 #define __put_user_size(x, ptr, size, retval)                  \
@@ -226,12 +225,11 @@ extern long __get_user_bad(void);
                "       b 2b\n"                         \
                ".previous\n"                           \
                ".section __ex_table,\"a\"\n"           \
-               "       .balign %5\n"                   \
+                       PPC_LONG_ALIGN "\n"             \
                        PPC_LONG "1b,3b\n"              \
                ".previous"                             \
                : "=r" (err), "=r" (x)                  \
-               : "b" (addr), "i" (-EFAULT), "0" (err), \
-                 "i"(sizeof(unsigned long)))
+               : "b" (addr), "i" (-EFAULT), "0" (err))
 
 #ifdef __powerpc64__
 #define __get_user_asm2(x, addr, err)                  \
@@ -249,13 +247,12 @@ extern long __get_user_bad(void);
                "       b 3b\n"                         \
                ".previous\n"                           \
                ".section __ex_table,\"a\"\n"           \
-               "       .balign %5\n"                   \
+                       PPC_LONG_ALIGN "\n"             \
                        PPC_LONG "1b,4b\n"              \
                        PPC_LONG "2b,4b\n"              \
                ".previous"                             \
                : "=r" (err), "=&r" (x)                 \
-               : "b" (addr), "i" (-EFAULT), "0" (err), \
-                 "i"(sizeof(unsigned long)))
+               : "b" (addr), "i" (-EFAULT), "0" (err))
 #endif /* __powerpc64__ */
 
 #define __get_user_size(x, ptr, size, retval)                  \
index f529f70b1d82f0b011a8e30d924e1b50ed662d65..fce16abe7ee1ea77d88bdc968859b33465a91ac8 100644 (file)
@@ -156,11 +156,11 @@ struct ucc_fast_info {
 
 struct ucc_fast_private {
        struct ucc_fast_info *uf_info;
-       struct ucc_fast *uf_regs;       /* a pointer to memory map of UCC regs. */
-       u32 *p_ucce;            /* a pointer to the event register in memory. */
-       u32 *p_uccm;            /* a pointer to the mask register in memory. */
+       struct ucc_fast __iomem *uf_regs; /* a pointer to the UCC regs. */
+       u32 __iomem *p_ucce;    /* a pointer to the event register in memory. */
+       u32 __iomem *p_uccm;    /* a pointer to the mask register in memory. */
 #ifdef CONFIG_UGETH_TX_ON_DEMAND
-       u16 *p_utodr;           /* pointer to the transmit on demand register */
+       u16 __iomem *p_utodr;   /* pointer to the transmit on demand register */
 #endif
        int enabled_tx;         /* Whether channel is enabled for Tx (ENT) */
        int enabled_rx;         /* Whether channel is enabled for Rx (ENR) */
index 671223718f0af6e07fd19c5e94247bb555e7de95..6cdaf9d33b386631df559a00e93851a44880c13f 100644 (file)
@@ -1,14 +1 @@
-include include/asm-generic/Kbuild.asm
-
-header-y += apc.h
-header-y += asi.h
-header-y += bpp.h
-header-y += jsflash.h
-header-y += openpromio.h
-header-y += reg.h
-header-y += traps.h
-header-y += vfc_ioctls.h
-
-unifdef-y += fbio.h
-unifdef-y += perfctr.h
-unifdef-y += psr.h
+# dummy file to avoid breaking make headers_install
diff --git a/include/asm-sparc/agp.h b/include/asm-sparc/agp.h
new file mode 100644 (file)
index 0000000..c245687
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef AGP_H
+#define AGP_H 1
+
+/* dummy for now */
+
+#define map_page_into_agp(page)
+#define unmap_page_from_agp(page)
+#define flush_agp_cache() mb()
+
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order)                \
+       ((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order)  \
+       free_pages((unsigned long)(table), (order))
+
+#endif
diff --git a/include/asm-sparc/apb.h b/include/asm-sparc/apb.h
new file mode 100644 (file)
index 0000000..8f3b57d
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * apb.h: Advanced PCI Bridge Configuration Registers and Bits
+ *
+ * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
+ */
+
+#ifndef _SPARC64_APB_H
+#define _SPARC64_APB_H
+
+#define APB_TICK_REGISTER                      0xb0
+#define APB_INT_ACK                            0xb8
+#define APB_PRIMARY_MASTER_RETRY_LIMIT         0xc0
+#define APB_DMA_ASFR                           0xc8
+#define APB_DMA_AFAR                           0xd0
+#define APB_PIO_TARGET_RETRY_LIMIT             0xd8
+#define APB_PIO_TARGET_LATENCY_TIMER           0xd9
+#define APB_DMA_TARGET_RETRY_LIMIT             0xda
+#define APB_DMA_TARGET_LATENCY_TIMER           0xdb
+#define APB_SECONDARY_MASTER_RETRY_LIMIT       0xdc
+#define APB_SECONDARY_CONTROL                  0xdd
+#define APB_IO_ADDRESS_MAP                     0xde
+#define APB_MEM_ADDRESS_MAP                    0xdf
+
+#define APB_PCI_CONTROL_LOW                    0xe0
+#  define APB_PCI_CTL_LOW_ARB_PARK                     (1 << 21)
+#  define APB_PCI_CTL_LOW_ERRINT_EN                    (1 << 8)
+
+#define APB_PCI_CONTROL_HIGH                   0xe4
+#  define APB_PCI_CTL_HIGH_SERR                                (1 << 2)
+#  define APB_PCI_CTL_HIGH_ARBITER_EN                  (1 << 0)
+
+#define APB_PIO_ASFR                           0xe8
+#define APB_PIO_AFAR                           0xf0
+#define APB_DIAG_REGISTER                      0xf8
+
+#endif /* !(_SPARC64_APB_H) */
index 158f9b00d43ff363fd3b9f9d99fa973b9b56e6a8..74703c5ef985eb4b3c7ed726b5cdb5cd8814f93b 100644 (file)
@@ -3,7 +3,7 @@
 
 /* asi.h:  Address Space Identifier values for the sparc.
  *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
  *
  * Pioneer work for sun4m: Paul Hatchman (paul@sfe.com.au)
  * Joint edition for sun4c+sun4m: Pete A. Zaitcev <zaitcev@ipmce.su>
 
 #define ASI_M_ACTION       0x4c   /* Breakpoint Action Register (GNU/Viking) */
 
+/* V9 Architecture mandary ASIs. */
+#define ASI_N                  0x04 /* Nucleus                         */
+#define ASI_NL                 0x0c /* Nucleus, little endian          */
+#define ASI_AIUP               0x10 /* Primary, user                   */
+#define ASI_AIUS               0x11 /* Secondary, user                 */
+#define ASI_AIUPL              0x18 /* Primary, user, little endian    */
+#define ASI_AIUSL              0x19 /* Secondary, user, little endian  */
+#define ASI_P                  0x80 /* Primary, implicit               */
+#define ASI_S                  0x81 /* Secondary, implicit             */
+#define ASI_PNF                        0x82 /* Primary, no fault               */
+#define ASI_SNF                        0x83 /* Secondary, no fault             */
+#define ASI_PL                 0x88 /* Primary, implicit, l-endian     */
+#define ASI_SL                 0x89 /* Secondary, implicit, l-endian   */
+#define ASI_PNFL               0x8a /* Primary, no fault, l-endian     */
+#define ASI_SNFL               0x8b /* Secondary, no fault, l-endian   */
+
+/* SpitFire and later extended ASIs.  The "(III)" marker designates
+ * UltraSparc-III and later specific ASIs.  The "(CMT)" marker designates
+ * Chip Multi Threading specific ASIs.  "(NG)" designates Niagara specific
+ * ASIs, "(4V)" designates SUN4V specific ASIs.
+ */
+#define ASI_PHYS_USE_EC                0x14 /* PADDR, E-cachable               */
+#define ASI_PHYS_BYPASS_EC_E   0x15 /* PADDR, E-bit                    */
+#define ASI_BLK_AIUP_4V                0x16 /* (4V) Prim, user, block ld/st    */
+#define ASI_BLK_AIUS_4V                0x17 /* (4V) Sec, user, block ld/st     */
+#define ASI_PHYS_USE_EC_L      0x1c /* PADDR, E-cachable, little endian*/
+#define ASI_PHYS_BYPASS_EC_E_L 0x1d /* PADDR, E-bit, little endian     */
+#define ASI_BLK_AIUP_L_4V      0x1e /* (4V) Prim, user, block, l-endian*/
+#define ASI_BLK_AIUS_L_4V      0x1f /* (4V) Sec, user, block, l-endian */
+#define ASI_SCRATCHPAD         0x20 /* (4V) Scratch Pad Registers      */
+#define ASI_MMU                        0x21 /* (4V) MMU Context Registers      */
+#define ASI_BLK_INIT_QUAD_LDD_AIUS 0x23 /* (NG) init-store, twin load,
+                                        * secondary, user
+                                        */
+#define ASI_NUCLEUS_QUAD_LDD   0x24 /* Cachable, qword load            */
+#define ASI_QUEUE              0x25 /* (4V) Interrupt Queue Registers  */
+#define ASI_QUAD_LDD_PHYS_4V   0x26 /* (4V) Physical, qword load       */
+#define ASI_NUCLEUS_QUAD_LDD_L 0x2c /* Cachable, qword load, l-endian  */
+#define ASI_QUAD_LDD_PHYS_L_4V 0x2e /* (4V) Phys, qword load, l-endian */
+#define ASI_PCACHE_DATA_STATUS 0x30 /* (III) PCache data stat RAM diag */
+#define ASI_PCACHE_DATA                0x31 /* (III) PCache data RAM diag      */
+#define ASI_PCACHE_TAG         0x32 /* (III) PCache tag RAM diag       */
+#define ASI_PCACHE_SNOOP_TAG   0x33 /* (III) PCache snoop tag RAM diag */
+#define ASI_QUAD_LDD_PHYS      0x34 /* (III+) PADDR, qword load        */
+#define ASI_WCACHE_VALID_BITS  0x38 /* (III) WCache Valid Bits diag    */
+#define ASI_WCACHE_DATA                0x39 /* (III) WCache data RAM diag      */
+#define ASI_WCACHE_TAG         0x3a /* (III) WCache tag RAM diag       */
+#define ASI_WCACHE_SNOOP_TAG   0x3b /* (III) WCache snoop tag RAM diag */
+#define ASI_QUAD_LDD_PHYS_L    0x3c /* (III+) PADDR, qw-load, l-endian */
+#define ASI_SRAM_FAST_INIT     0x40 /* (III+) Fast SRAM init           */
+#define ASI_CORE_AVAILABLE     0x41 /* (CMT) LP Available              */
+#define ASI_CORE_ENABLE_STAT   0x41 /* (CMT) LP Enable Status          */
+#define ASI_CORE_ENABLE                0x41 /* (CMT) LP Enable RW              */
+#define ASI_XIR_STEERING       0x41 /* (CMT) XIR Steering RW           */
+#define ASI_CORE_RUNNING_RW    0x41 /* (CMT) LP Running RW             */
+#define ASI_CORE_RUNNING_W1S   0x41 /* (CMT) LP Running Write-One Set  */
+#define ASI_CORE_RUNNING_W1C   0x41 /* (CMT) LP Running Write-One Clr  */
+#define ASI_CORE_RUNNING_STAT  0x41 /* (CMT) LP Running Status         */
+#define ASI_CMT_ERROR_STEERING 0x41 /* (CMT) Error Steering RW         */
+#define ASI_DCACHE_INVALIDATE  0x42 /* (III) DCache Invalidate diag    */
+#define ASI_DCACHE_UTAG                0x43 /* (III) DCache uTag diag          */
+#define ASI_DCACHE_SNOOP_TAG   0x44 /* (III) DCache snoop tag RAM diag */
+#define ASI_LSU_CONTROL                0x45 /* Load-store control unit         */
+#define ASI_DCU_CONTROL_REG    0x45 /* (III) DCache Unit Control reg   */
+#define ASI_DCACHE_DATA                0x46 /* DCache data-ram diag access     */
+#define ASI_DCACHE_TAG         0x47 /* Dcache tag/valid ram diag access*/
+#define ASI_INTR_DISPATCH_STAT 0x48 /* IRQ vector dispatch status      */
+#define ASI_INTR_RECEIVE       0x49 /* IRQ vector receive status       */
+#define ASI_UPA_CONFIG         0x4a /* UPA config space                */
+#define ASI_JBUS_CONFIG                0x4a /* (IIIi) JBUS Config Register     */
+#define ASI_SAFARI_CONFIG      0x4a /* (III) Safari Config Register    */
+#define ASI_SAFARI_ADDRESS     0x4a /* (III) Safari Address Register   */
+#define ASI_ESTATE_ERROR_EN    0x4b /* E-cache error enable space      */
+#define ASI_AFSR               0x4c /* Async fault status register     */
+#define ASI_AFAR               0x4d /* Async fault address register    */
+#define ASI_EC_TAG_DATA                0x4e /* E-cache tag/valid ram diag acc  */
+#define ASI_IMMU               0x50 /* Insn-MMU main register space    */
+#define ASI_IMMU_TSB_8KB_PTR   0x51 /* Insn-MMU 8KB TSB pointer reg    */
+#define ASI_IMMU_TSB_64KB_PTR  0x52 /* Insn-MMU 64KB TSB pointer reg   */
+#define ASI_ITLB_DATA_IN       0x54 /* Insn-MMU TLB data in reg        */
+#define ASI_ITLB_DATA_ACCESS   0x55 /* Insn-MMU TLB data access reg    */
+#define ASI_ITLB_TAG_READ      0x56 /* Insn-MMU TLB tag read reg       */
+#define ASI_IMMU_DEMAP         0x57 /* Insn-MMU TLB demap              */
+#define ASI_DMMU               0x58 /* Data-MMU main register space    */
+#define ASI_DMMU_TSB_8KB_PTR   0x59 /* Data-MMU 8KB TSB pointer reg    */
+#define ASI_DMMU_TSB_64KB_PTR  0x5a /* Data-MMU 16KB TSB pointer reg   */
+#define ASI_DMMU_TSB_DIRECT_PTR        0x5b /* Data-MMU TSB direct pointer reg */
+#define ASI_DTLB_DATA_IN       0x5c /* Data-MMU TLB data in reg        */
+#define ASI_DTLB_DATA_ACCESS   0x5d /* Data-MMU TLB data access reg    */
+#define ASI_DTLB_TAG_READ      0x5e /* Data-MMU TLB tag read reg       */
+#define ASI_DMMU_DEMAP         0x5f /* Data-MMU TLB demap              */
+#define ASI_IIU_INST_TRAP      0x60 /* (III) Instruction Breakpoint    */
+#define ASI_INTR_ID            0x63 /* (CMT) Interrupt ID register     */
+#define ASI_CORE_ID            0x63 /* (CMT) LP ID register            */
+#define ASI_CESR_ID            0x63 /* (CMT) CESR ID register          */
+#define ASI_IC_INSTR           0x66 /* Insn cache instrucion ram diag  */
+#define ASI_IC_TAG             0x67 /* Insn cache tag/valid ram diag   */
+#define ASI_IC_STAG            0x68 /* (III) Insn cache snoop tag ram  */
+#define ASI_IC_PRE_DECODE      0x6e /* Insn cache pre-decode ram diag  */
+#define ASI_IC_NEXT_FIELD      0x6f /* Insn cache next-field ram diag  */
+#define ASI_BRPRED_ARRAY       0x6f /* (III) Branch Prediction RAM diag*/
+#define ASI_BLK_AIUP           0x70 /* Primary, user, block load/store */
+#define ASI_BLK_AIUS           0x71 /* Secondary, user, block ld/st    */
+#define ASI_MCU_CTRL_REG       0x72 /* (III) Memory controller regs    */
+#define ASI_EC_DATA            0x74 /* (III) E-cache data staging reg  */
+#define ASI_EC_CTRL            0x75 /* (III) E-cache control reg       */
+#define ASI_EC_W               0x76 /* E-cache diag write access       */
+#define ASI_UDB_ERROR_W                0x77 /* External UDB error regs W       */
+#define ASI_UDB_CONTROL_W      0x77 /* External UDB control regs W     */
+#define ASI_INTR_W             0x77 /* IRQ vector dispatch write       */
+#define ASI_INTR_DATAN_W       0x77 /* (III) Out irq vector data reg N */
+#define ASI_INTR_DISPATCH_W    0x77 /* (III) Interrupt vector dispatch */
+#define ASI_BLK_AIUPL          0x78 /* Primary, user, little, blk ld/st*/
+#define ASI_BLK_AIUSL          0x79 /* Secondary, user, little, blk ld/st*/
+#define ASI_EC_R               0x7e /* E-cache diag read access        */
+#define ASI_UDBH_ERROR_R       0x7f /* External UDB error regs rd hi   */
+#define ASI_UDBL_ERROR_R       0x7f /* External UDB error regs rd low  */
+#define ASI_UDBH_CONTROL_R     0x7f /* External UDB control regs rd hi */
+#define ASI_UDBL_CONTROL_R     0x7f /* External UDB control regs rd low*/
+#define ASI_INTR_R             0x7f /* IRQ vector dispatch read        */
+#define ASI_INTR_DATAN_R       0x7f /* (III) In irq vector data reg N  */
+#define ASI_PST8_P             0xc0 /* Primary, 8 8-bit, partial       */
+#define ASI_PST8_S             0xc1 /* Secondary, 8 8-bit, partial     */
+#define ASI_PST16_P            0xc2 /* Primary, 4 16-bit, partial      */
+#define ASI_PST16_S            0xc3 /* Secondary, 4 16-bit, partial    */
+#define ASI_PST32_P            0xc4 /* Primary, 2 32-bit, partial      */
+#define ASI_PST32_S            0xc5 /* Secondary, 2 32-bit, partial    */
+#define ASI_PST8_PL            0xc8 /* Primary, 8 8-bit, partial, L    */
+#define ASI_PST8_SL            0xc9 /* Secondary, 8 8-bit, partial, L  */
+#define ASI_PST16_PL           0xca /* Primary, 4 16-bit, partial, L   */
+#define ASI_PST16_SL           0xcb /* Secondary, 4 16-bit, partial, L */
+#define ASI_PST32_PL           0xcc /* Primary, 2 32-bit, partial, L   */
+#define ASI_PST32_SL           0xcd /* Secondary, 2 32-bit, partial, L */
+#define ASI_FL8_P              0xd0 /* Primary, 1 8-bit, fpu ld/st     */
+#define ASI_FL8_S              0xd1 /* Secondary, 1 8-bit, fpu ld/st   */
+#define ASI_FL16_P             0xd2 /* Primary, 1 16-bit, fpu ld/st    */
+#define ASI_FL16_S             0xd3 /* Secondary, 1 16-bit, fpu ld/st  */
+#define ASI_FL8_PL             0xd8 /* Primary, 1 8-bit, fpu ld/st, L  */
+#define ASI_FL8_SL             0xd9 /* Secondary, 1 8-bit, fpu ld/st, L*/
+#define ASI_FL16_PL            0xda /* Primary, 1 16-bit, fpu ld/st, L */
+#define ASI_FL16_SL            0xdb /* Secondary, 1 16-bit, fpu ld/st,L*/
+#define ASI_BLK_COMMIT_P       0xe0 /* Primary, blk store commit       */
+#define ASI_BLK_COMMIT_S       0xe1 /* Secondary, blk store commit     */
+#define ASI_BLK_INIT_QUAD_LDD_P        0xe2 /* (NG) init-store, twin load,
+                                     * primary, implicit
+                                     */
+#define ASI_BLK_P              0xf0 /* Primary, blk ld/st              */
+#define ASI_BLK_S              0xf1 /* Secondary, blk ld/st            */
+#define ASI_BLK_PL             0xf8 /* Primary, blk ld/st, little      */
+#define ASI_BLK_SL             0xf9 /* Secondary, blk ld/st, little    */
+
 #endif /* _SPARC_ASI_H */
index 5c944b5a804003f5cc2a87b7972e5c22cd18ceb7..66d8166ec1d7d768e321b7fe06414140ac7d7bf6 100644 (file)
@@ -1,165 +1,8 @@
-/* atomic.h: These still suck, but the I-cache hit rate is higher.
- *
- * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
- * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)
- * Copyright (C) 2007 Kyle McMartin (kyle@parisc-linux.org)
- *
- * Additions by Keith M Wesolowski (wesolows@foobazco.org) based
- * on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>.
- */
-
-#ifndef __ARCH_SPARC_ATOMIC__
-#define __ARCH_SPARC_ATOMIC__
-
-#include <linux/types.h>
-
-typedef struct { volatile int counter; } atomic_t;
-
-#ifdef __KERNEL__
-
-#define ATOMIC_INIT(i)  { (i) }
-
-extern int __atomic_add_return(int, atomic_t *);
-extern int atomic_cmpxchg(atomic_t *, int, int);
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-extern int atomic_add_unless(atomic_t *, int, int);
-extern void atomic_set(atomic_t *, int);
-
-#define atomic_read(v)          ((v)->counter)
-
-#define atomic_add(i, v)       ((void)__atomic_add_return( (int)(i), (v)))
-#define atomic_sub(i, v)       ((void)__atomic_add_return(-(int)(i), (v)))
-#define atomic_inc(v)          ((void)__atomic_add_return(        1, (v)))
-#define atomic_dec(v)          ((void)__atomic_add_return(       -1, (v)))
-
-#define atomic_add_return(i, v)        (__atomic_add_return( (int)(i), (v)))
-#define atomic_sub_return(i, v)        (__atomic_add_return(-(int)(i), (v)))
-#define atomic_inc_return(v)   (__atomic_add_return(        1, (v)))
-#define atomic_dec_return(v)   (__atomic_add_return(       -1, (v)))
-
-#define atomic_add_negative(a, v)      (atomic_add_return((a), (v)) < 0)
-
-/*
- * atomic_inc_and_test - increment and test
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1
- * and returns true if the result is zero, or false for all
- * other cases.
- */
-#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
-
-#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
-#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
-
-#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
-
-/* This is the old 24-bit implementation.  It's still used internally
- * by some sparc-specific code, notably the semaphore implementation.
- */
-typedef struct { volatile int counter; } atomic24_t;
-
-#ifndef CONFIG_SMP
-
-#define ATOMIC24_INIT(i)  { (i) }
-#define atomic24_read(v)          ((v)->counter)
-#define atomic24_set(v, i)        (((v)->counter) = i)
-
+#ifndef ___ASM_SPARC_ATOMIC_H
+#define ___ASM_SPARC_ATOMIC_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/atomic_64.h>
 #else
-/* We do the bulk of the actual work out of line in two common
- * routines in assembler, see arch/sparc/lib/atomic.S for the
- * "fun" details.
- *
- * For SMP the trick is you embed the spin lock byte within
- * the word, use the low byte so signedness is easily retained
- * via a quick arithmetic shift.  It looks like this:
- *
- *     ----------------------------------------
- *     | signed 24-bit counter value |  lock  |  atomic_t
- *     ----------------------------------------
- *      31                          8 7      0
- */
-
-#define ATOMIC24_INIT(i)       { ((i) << 8) }
-
-static inline int atomic24_read(const atomic24_t *v)
-{
-       int ret = v->counter;
-
-       while(ret & 0xff)
-               ret = v->counter;
-
-       return ret >> 8;
-}
-
-#define atomic24_set(v, i)     (((v)->counter) = ((i) << 8))
+#include <asm-sparc/atomic_32.h>
+#endif
 #endif
-
-static inline int __atomic24_add(int i, atomic24_t *v)
-{
-       register volatile int *ptr asm("g1");
-       register int increment asm("g2");
-       register int tmp1 asm("g3");
-       register int tmp2 asm("g4");
-       register int tmp3 asm("g7");
-
-       ptr = &v->counter;
-       increment = i;
-
-       __asm__ __volatile__(
-       "mov    %%o7, %%g4\n\t"
-       "call   ___atomic24_add\n\t"
-       " add   %%o7, 8, %%o7\n"
-       : "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
-       : "0" (increment), "r" (ptr)
-       : "memory", "cc");
-
-       return increment;
-}
-
-static inline int __atomic24_sub(int i, atomic24_t *v)
-{
-       register volatile int *ptr asm("g1");
-       register int increment asm("g2");
-       register int tmp1 asm("g3");
-       register int tmp2 asm("g4");
-       register int tmp3 asm("g7");
-
-       ptr = &v->counter;
-       increment = i;
-
-       __asm__ __volatile__(
-       "mov    %%o7, %%g4\n\t"
-       "call   ___atomic24_sub\n\t"
-       " add   %%o7, 8, %%o7\n"
-       : "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
-       : "0" (increment), "r" (ptr)
-       : "memory", "cc");
-
-       return increment;
-}
-
-#define atomic24_add(i, v) ((void)__atomic24_add((i), (v)))
-#define atomic24_sub(i, v) ((void)__atomic24_sub((i), (v)))
-
-#define atomic24_dec_return(v) __atomic24_sub(1, (v))
-#define atomic24_inc_return(v) __atomic24_add(1, (v))
-
-#define atomic24_sub_and_test(i, v) (__atomic24_sub((i), (v)) == 0)
-#define atomic24_dec_and_test(v) (__atomic24_sub(1, (v)) == 0)
-
-#define atomic24_inc(v) ((void)__atomic24_add(1, (v)))
-#define atomic24_dec(v) ((void)__atomic24_sub(1, (v)))
-
-#define atomic24_add_negative(i, v) (__atomic24_add((i), (v)) < 0)
-
-/* Atomic operations are already serializing */
-#define smp_mb__before_atomic_dec()    barrier()
-#define smp_mb__after_atomic_dec()     barrier()
-#define smp_mb__before_atomic_inc()    barrier()
-#define smp_mb__after_atomic_inc()     barrier()
-
-#endif /* !(__KERNEL__) */
-
-#include <asm-generic/atomic.h>
-#endif /* !(__ARCH_SPARC_ATOMIC__) */
diff --git a/include/asm-sparc/atomic_32.h b/include/asm-sparc/atomic_32.h
new file mode 100644 (file)
index 0000000..5c944b5
--- /dev/null
@@ -0,0 +1,165 @@
+/* atomic.h: These still suck, but the I-cache hit rate is higher.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)
+ * Copyright (C) 2007 Kyle McMartin (kyle@parisc-linux.org)
+ *
+ * Additions by Keith M Wesolowski (wesolows@foobazco.org) based
+ * on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>.
+ */
+
+#ifndef __ARCH_SPARC_ATOMIC__
+#define __ARCH_SPARC_ATOMIC__
+
+#include <linux/types.h>
+
+typedef struct { volatile int counter; } atomic_t;
+
+#ifdef __KERNEL__
+
+#define ATOMIC_INIT(i)  { (i) }
+
+extern int __atomic_add_return(int, atomic_t *);
+extern int atomic_cmpxchg(atomic_t *, int, int);
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+extern int atomic_add_unless(atomic_t *, int, int);
+extern void atomic_set(atomic_t *, int);
+
+#define atomic_read(v)          ((v)->counter)
+
+#define atomic_add(i, v)       ((void)__atomic_add_return( (int)(i), (v)))
+#define atomic_sub(i, v)       ((void)__atomic_add_return(-(int)(i), (v)))
+#define atomic_inc(v)          ((void)__atomic_add_return(        1, (v)))
+#define atomic_dec(v)          ((void)__atomic_add_return(       -1, (v)))
+
+#define atomic_add_return(i, v)        (__atomic_add_return( (int)(i), (v)))
+#define atomic_sub_return(i, v)        (__atomic_add_return(-(int)(i), (v)))
+#define atomic_inc_return(v)   (__atomic_add_return(        1, (v)))
+#define atomic_dec_return(v)   (__atomic_add_return(       -1, (v)))
+
+#define atomic_add_negative(a, v)      (atomic_add_return((a), (v)) < 0)
+
+/*
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+
+#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
+#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
+
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+/* This is the old 24-bit implementation.  It's still used internally
+ * by some sparc-specific code, notably the semaphore implementation.
+ */
+typedef struct { volatile int counter; } atomic24_t;
+
+#ifndef CONFIG_SMP
+
+#define ATOMIC24_INIT(i)  { (i) }
+#define atomic24_read(v)          ((v)->counter)
+#define atomic24_set(v, i)        (((v)->counter) = i)
+
+#else
+/* We do the bulk of the actual work out of line in two common
+ * routines in assembler, see arch/sparc/lib/atomic.S for the
+ * "fun" details.
+ *
+ * For SMP the trick is you embed the spin lock byte within
+ * the word, use the low byte so signedness is easily retained
+ * via a quick arithmetic shift.  It looks like this:
+ *
+ *     ----------------------------------------
+ *     | signed 24-bit counter value |  lock  |  atomic_t
+ *     ----------------------------------------
+ *      31                          8 7      0
+ */
+
+#define ATOMIC24_INIT(i)       { ((i) << 8) }
+
+static inline int atomic24_read(const atomic24_t *v)
+{
+       int ret = v->counter;
+
+       while(ret & 0xff)
+               ret = v->counter;
+
+       return ret >> 8;
+}
+
+#define atomic24_set(v, i)     (((v)->counter) = ((i) << 8))
+#endif
+
+static inline int __atomic24_add(int i, atomic24_t *v)
+{
+       register volatile int *ptr asm("g1");
+       register int increment asm("g2");
+       register int tmp1 asm("g3");
+       register int tmp2 asm("g4");
+       register int tmp3 asm("g7");
+
+       ptr = &v->counter;
+       increment = i;
+
+       __asm__ __volatile__(
+       "mov    %%o7, %%g4\n\t"
+       "call   ___atomic24_add\n\t"
+       " add   %%o7, 8, %%o7\n"
+       : "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
+       : "0" (increment), "r" (ptr)
+       : "memory", "cc");
+
+       return increment;
+}
+
+static inline int __atomic24_sub(int i, atomic24_t *v)
+{
+       register volatile int *ptr asm("g1");
+       register int increment asm("g2");
+       register int tmp1 asm("g3");
+       register int tmp2 asm("g4");
+       register int tmp3 asm("g7");
+
+       ptr = &v->counter;
+       increment = i;
+
+       __asm__ __volatile__(
+       "mov    %%o7, %%g4\n\t"
+       "call   ___atomic24_sub\n\t"
+       " add   %%o7, 8, %%o7\n"
+       : "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
+       : "0" (increment), "r" (ptr)
+       : "memory", "cc");
+
+       return increment;
+}
+
+#define atomic24_add(i, v) ((void)__atomic24_add((i), (v)))
+#define atomic24_sub(i, v) ((void)__atomic24_sub((i), (v)))
+
+#define atomic24_dec_return(v) __atomic24_sub(1, (v))
+#define atomic24_inc_return(v) __atomic24_add(1, (v))
+
+#define atomic24_sub_and_test(i, v) (__atomic24_sub((i), (v)) == 0)
+#define atomic24_dec_and_test(v) (__atomic24_sub(1, (v)) == 0)
+
+#define atomic24_inc(v) ((void)__atomic24_add(1, (v)))
+#define atomic24_dec(v) ((void)__atomic24_sub(1, (v)))
+
+#define atomic24_add_negative(i, v) (__atomic24_add((i), (v)) < 0)
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec()    barrier()
+#define smp_mb__after_atomic_dec()     barrier()
+#define smp_mb__before_atomic_inc()    barrier()
+#define smp_mb__after_atomic_inc()     barrier()
+
+#endif /* !(__KERNEL__) */
+
+#include <asm-generic/atomic.h>
+#endif /* !(__ARCH_SPARC_ATOMIC__) */
diff --git a/include/asm-sparc/atomic_64.h b/include/asm-sparc/atomic_64.h
new file mode 100644 (file)
index 0000000..2c71ec4
--- /dev/null
@@ -0,0 +1,128 @@
+/* atomic.h: Thankfully the V9 is at least reasonable for this
+ *           stuff.
+ *
+ * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com)
+ */
+
+#ifndef __ARCH_SPARC64_ATOMIC__
+#define __ARCH_SPARC64_ATOMIC__
+
+#include <linux/types.h>
+#include <asm/system.h>
+
+typedef struct { volatile int counter; } atomic_t;
+typedef struct { volatile __s64 counter; } atomic64_t;
+
+#define ATOMIC_INIT(i)         { (i) }
+#define ATOMIC64_INIT(i)       { (i) }
+
+#define atomic_read(v)         ((v)->counter)
+#define atomic64_read(v)       ((v)->counter)
+
+#define atomic_set(v, i)       (((v)->counter) = i)
+#define atomic64_set(v, i)     (((v)->counter) = i)
+
+extern void atomic_add(int, atomic_t *);
+extern void atomic64_add(int, atomic64_t *);
+extern void atomic_sub(int, atomic_t *);
+extern void atomic64_sub(int, atomic64_t *);
+
+extern int atomic_add_ret(int, atomic_t *);
+extern int atomic64_add_ret(int, atomic64_t *);
+extern int atomic_sub_ret(int, atomic_t *);
+extern int atomic64_sub_ret(int, atomic64_t *);
+
+#define atomic_dec_return(v) atomic_sub_ret(1, v)
+#define atomic64_dec_return(v) atomic64_sub_ret(1, v)
+
+#define atomic_inc_return(v) atomic_add_ret(1, v)
+#define atomic64_inc_return(v) atomic64_add_ret(1, v)
+
+#define atomic_sub_return(i, v) atomic_sub_ret(i, v)
+#define atomic64_sub_return(i, v) atomic64_sub_ret(i, v)
+
+#define atomic_add_return(i, v) atomic_add_ret(i, v)
+#define atomic64_add_return(i, v) atomic64_add_ret(i, v)
+
+/*
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
+
+#define atomic_sub_and_test(i, v) (atomic_sub_ret(i, v) == 0)
+#define atomic64_sub_and_test(i, v) (atomic64_sub_ret(i, v) == 0)
+
+#define atomic_dec_and_test(v) (atomic_sub_ret(1, v) == 0)
+#define atomic64_dec_and_test(v) (atomic64_sub_ret(1, v) == 0)
+
+#define atomic_inc(v) atomic_add(1, v)
+#define atomic64_inc(v) atomic64_add(1, v)
+
+#define atomic_dec(v) atomic_sub(1, v)
+#define atomic64_dec(v) atomic64_sub(1, v)
+
+#define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0)
+#define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0)
+
+#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+       int c, old;
+       c = atomic_read(v);
+       for (;;) {
+               if (unlikely(c == (u)))
+                       break;
+               old = atomic_cmpxchg((v), c, c + (a));
+               if (likely(old == c))
+                       break;
+               c = old;
+       }
+       return c != (u);
+}
+
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+#define atomic64_cmpxchg(v, o, n) \
+       ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+       long c, old;
+       c = atomic64_read(v);
+       for (;;) {
+               if (unlikely(c == (u)))
+                       break;
+               old = atomic64_cmpxchg((v), c, c + (a));
+               if (likely(old == c))
+                       break;
+               c = old;
+       }
+       return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
+/* Atomic operations are already serializing */
+#ifdef CONFIG_SMP
+#define smp_mb__before_atomic_dec()    membar_storeload_loadload();
+#define smp_mb__after_atomic_dec()     membar_storeload_storestore();
+#define smp_mb__before_atomic_inc()    membar_storeload_loadload();
+#define smp_mb__after_atomic_inc()     membar_storeload_storestore();
+#else
+#define smp_mb__before_atomic_dec()    barrier()
+#define smp_mb__after_atomic_dec()     barrier()
+#define smp_mb__before_atomic_inc()    barrier()
+#define smp_mb__after_atomic_inc()     barrier()
+#endif
+
+#include <asm-generic/atomic.h>
+#endif /* !(__ARCH_SPARC64_ATOMIC__) */
index e552b8d68450c895fb65733645da297a1246ee2d..24c6f3c0f5779c5ea9d2789ae8b91017f2ab97e3 100644 (file)
@@ -1,89 +1,8 @@
-/*
- * auxio.h:  Definitions and code for the Auxiliary I/O register.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-#ifndef _SPARC_AUXIO_H
-#define _SPARC_AUXIO_H
-
-#include <asm/system.h>
-#include <asm/vaddrs.h>
-
-/* This register is an unsigned char in IO space.  It does two things.
- * First, it is used to control the front panel LED light on machines
- * that have it (good for testing entry points to trap handlers and irq's)
- * Secondly, it controls various floppy drive parameters.
- */
-#define AUXIO_ORMEIN      0xf0    /* All writes must set these bits. */
-#define AUXIO_ORMEIN4M    0xc0    /* sun4m - All writes must set these bits. */
-#define AUXIO_FLPY_DENS   0x20    /* Floppy density, high if set. Read only. */
-#define AUXIO_FLPY_DCHG   0x10    /* A disk change occurred.  Read only. */
-#define AUXIO_EDGE_ON     0x10    /* sun4m - On means Jumper block is in. */
-#define AUXIO_FLPY_DSEL   0x08    /* Drive select/start-motor. Write only. */
-#define AUXIO_LINK_TEST   0x08    /* sun4m - On means TPE Carrier detect. */
-
-/* Set the following to one, then zero, after doing a pseudo DMA transfer. */
-#define AUXIO_FLPY_TCNT   0x04    /* Floppy terminal count. Write only. */
-
-/* Set the following to zero to eject the floppy. */
-#define AUXIO_FLPY_EJCT   0x02    /* Eject floppy disk.  Write only. */
-#define AUXIO_LED         0x01    /* On if set, off if unset. Read/Write */
-
-#ifndef __ASSEMBLY__
-
-/* 
- * NOTE: these routines are implementation dependent-- 
- * understand the hardware you are querying! 
- */
-extern void set_auxio(unsigned char bits_on, unsigned char bits_off);
-extern unsigned char get_auxio(void); /* .../asm-sparc/floppy.h */
-
-/*
- * The following routines are provided for driver-compatibility
- * with sparc64 (primarily sunlance.c)
- */
-
-#define AUXIO_LTE_ON    1
-#define AUXIO_LTE_OFF   0
-
-/* auxio_set_lte - Set Link Test Enable (TPE Link Detect)
- *
- * on - AUXIO_LTE_ON or AUXIO_LTE_OFF
- */
-#define auxio_set_lte(on) \
-do { \
-       if(on) { \
-               set_auxio(AUXIO_LINK_TEST, 0); \
-       } else { \
-               set_auxio(0, AUXIO_LINK_TEST); \
-       } \
-} while (0)
-
-#define AUXIO_LED_ON    1
-#define AUXIO_LED_OFF   0
-
-/* auxio_set_led - Set system front panel LED
- *
- * on - AUXIO_LED_ON or AUXIO_LED_OFF
- */
-#define auxio_set_led(on) \
-do { \
-       if(on) { \
-               set_auxio(AUXIO_LED, 0); \
-       } else { \
-               set_auxio(0, AUXIO_LED); \
-       } \
-} while (0)
-
-#endif /* !(__ASSEMBLY__) */
-
-
-/* AUXIO2 (Power Off Control) */
-extern __volatile__ unsigned char * auxio_power_register;
-
-#define        AUXIO_POWER_DETECT_FAILURE      32
-#define        AUXIO_POWER_CLEAR_FAILURE       2
-#define        AUXIO_POWER_OFF                 1
-
-
-#endif /* !(_SPARC_AUXIO_H) */
+#ifndef ___ASM_SPARC_AUXIO_H
+#define ___ASM_SPARC_AUXIO_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/auxio_64.h>
+#else
+#include <asm-sparc/auxio_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/auxio_32.h b/include/asm-sparc/auxio_32.h
new file mode 100644 (file)
index 0000000..4db8f23
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * auxio.h:  Definitions and code for the Auxiliary I/O register.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC_AUXIO_H
+#define _SPARC_AUXIO_H
+
+#include <asm/system.h>
+#include <asm/vaddrs.h>
+
+/* This register is an unsigned char in IO space.  It does two things.
+ * First, it is used to control the front panel LED light on machines
+ * that have it (good for testing entry points to trap handlers and irq's)
+ * Secondly, it controls various floppy drive parameters.
+ */
+#define AUXIO_ORMEIN      0xf0    /* All writes must set these bits. */
+#define AUXIO_ORMEIN4M    0xc0    /* sun4m - All writes must set these bits. */
+#define AUXIO_FLPY_DENS   0x20    /* Floppy density, high if set. Read only. */
+#define AUXIO_FLPY_DCHG   0x10    /* A disk change occurred.  Read only. */
+#define AUXIO_EDGE_ON     0x10    /* sun4m - On means Jumper block is in. */
+#define AUXIO_FLPY_DSEL   0x08    /* Drive select/start-motor. Write only. */
+#define AUXIO_LINK_TEST   0x08    /* sun4m - On means TPE Carrier detect. */
+
+/* Set the following to one, then zero, after doing a pseudo DMA transfer. */
+#define AUXIO_FLPY_TCNT   0x04    /* Floppy terminal count. Write only. */
+
+/* Set the following to zero to eject the floppy. */
+#define AUXIO_FLPY_EJCT   0x02    /* Eject floppy disk.  Write only. */
+#define AUXIO_LED         0x01    /* On if set, off if unset. Read/Write */
+
+#ifndef __ASSEMBLY__
+
+/*
+ * NOTE: these routines are implementation dependent--
+ * understand the hardware you are querying!
+ */
+extern void set_auxio(unsigned char bits_on, unsigned char bits_off);
+extern unsigned char get_auxio(void); /* .../asm-sparc/floppy.h */
+
+/*
+ * The following routines are provided for driver-compatibility
+ * with sparc64 (primarily sunlance.c)
+ */
+
+#define AUXIO_LTE_ON    1
+#define AUXIO_LTE_OFF   0
+
+/* auxio_set_lte - Set Link Test Enable (TPE Link Detect)
+ *
+ * on - AUXIO_LTE_ON or AUXIO_LTE_OFF
+ */
+#define auxio_set_lte(on) \
+do { \
+       if(on) { \
+               set_auxio(AUXIO_LINK_TEST, 0); \
+       } else { \
+               set_auxio(0, AUXIO_LINK_TEST); \
+       } \
+} while (0)
+
+#define AUXIO_LED_ON    1
+#define AUXIO_LED_OFF   0
+
+/* auxio_set_led - Set system front panel LED
+ *
+ * on - AUXIO_LED_ON or AUXIO_LED_OFF
+ */
+#define auxio_set_led(on) \
+do { \
+       if(on) { \
+               set_auxio(AUXIO_LED, 0); \
+       } else { \
+               set_auxio(0, AUXIO_LED); \
+       } \
+} while (0)
+
+#endif /* !(__ASSEMBLY__) */
+
+
+/* AUXIO2 (Power Off Control) */
+extern __volatile__ unsigned char * auxio_power_register;
+
+#define        AUXIO_POWER_DETECT_FAILURE      32
+#define        AUXIO_POWER_CLEAR_FAILURE       2
+#define        AUXIO_POWER_OFF                 1
+
+
+#endif /* !(_SPARC_AUXIO_H) */
diff --git a/include/asm-sparc/auxio_64.h b/include/asm-sparc/auxio_64.h
new file mode 100644 (file)
index 0000000..f61cd1e
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * auxio.h:  Definitions and code for the Auxiliary I/O registers.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * Refactoring for unified NCR/PCIO support 2002 Eric Brower (ebrower@usa.net)
+ */
+#ifndef _SPARC64_AUXIO_H
+#define _SPARC64_AUXIO_H
+
+/* AUXIO implementations:
+ * sbus-based NCR89C105 "Slavio"
+ *     LED/Floppy (AUX1) register
+ *     Power (AUX2) register
+ *
+ * ebus-based auxio on PCIO
+ *     LED Auxio Register
+ *     Power Auxio Register
+ *
+ * Register definitions from NCR _NCR89C105 Chip Specification_
+ *
+ * SLAVIO AUX1 @ 0x1900000
+ * -------------------------------------------------
+ * | (R) | (R) |  D  | (R) |  E  |  M  |  T  |  L  |
+ * -------------------------------------------------
+ * (R) - bit 7:6,4 are reserved and should be masked in s/w
+ *  D  - Floppy Density Sense (1=high density) R/O
+ *  E  - Link Test Enable, directly reflected on AT&T 7213 LTE pin
+ *  M  - Monitor/Mouse Mux, directly reflected on MON_MSE_MUX pin
+ *  T  - Terminal Count: sends TC pulse to 82077 floppy controller
+ *  L  - System LED on front panel (0=off, 1=on)
+ */
+#define AUXIO_AUX1_MASK                0xc0 /* Mask bits               */
+#define AUXIO_AUX1_FDENS       0x20 /* Floppy Density Sense    */
+#define AUXIO_AUX1_LTE                 0x08 /* Link Test Enable        */
+#define AUXIO_AUX1_MMUX                0x04 /* Monitor/Mouse Mux       */
+#define AUXIO_AUX1_FTCNT       0x02 /* Terminal Count,         */
+#define AUXIO_AUX1_LED         0x01 /* System LED              */
+
+/* SLAVIO AUX2 @ 0x1910000
+ * -------------------------------------------------
+ * | (R) | (R) |  D  | (R) | (R) | (R) |  C  |  F  |
+ * -------------------------------------------------
+ * (R) - bits 7:6,4:2 are reserved and should be masked in s/w
+ *  D  - Power Failure Detect (1=power fail)
+ *  C  - Clear Power Failure Detect Int (1=clear)
+ *  F  - Power Off (1=power off)
+ */
+#define AUXIO_AUX2_MASK                0xdc /* Mask Bits               */
+#define AUXIO_AUX2_PFAILDET    0x20 /* Power Fail Detect       */
+#define AUXIO_AUX2_PFAILCLR    0x02 /* Clear Pwr Fail Det Intr */
+#define AUXIO_AUX2_PWR_OFF     0x01 /* Power Off               */
+
+/* Register definitions from Sun Microsystems _PCIO_ p/n 802-7837
+ *
+ * PCIO LED Auxio @ 0x726000
+ * -------------------------------------------------
+ * |             31:1 Unused                 | LED |
+ * -------------------------------------------------
+ * Bits 31:1 unused
+ * LED - System LED on front panel (0=off, 1=on)
+ */
+#define AUXIO_PCIO_LED         0x01 /* System LED              */
+
+/* PCIO Power Auxio @ 0x724000
+ * -------------------------------------------------
+ * |             31:2 Unused           | CPO | SPO |
+ * -------------------------------------------------
+ * Bits 31:2 unused
+ * CPO - Courtesy Power Off (1=off)
+ * SPO - System Power Off   (1=off)
+ */
+#define AUXIO_PCIO_CPWR_OFF    0x02 /* Courtesy Power Off      */
+#define AUXIO_PCIO_SPWR_OFF    0x01 /* System Power Off        */
+
+#ifndef __ASSEMBLY__
+
+extern void __iomem *auxio_register;
+
+#define AUXIO_LTE_ON   1
+#define AUXIO_LTE_OFF  0
+
+/* auxio_set_lte - Set Link Test Enable (TPE Link Detect)
+ *
+ * on - AUXIO_LTE_ON or AUXIO_LTE_OFF
+ */
+extern void auxio_set_lte(int on);
+
+#define AUXIO_LED_ON   1
+#define AUXIO_LED_OFF  0
+
+/* auxio_set_led - Set system front panel LED
+ *
+ * on - AUXIO_LED_ON or AUXIO_LED_OFF
+ */
+extern void auxio_set_led(int on);
+
+#endif /* ifndef __ASSEMBLY__ */
+
+#endif /* !(_SPARC64_AUXIO_H) */
diff --git a/include/asm-sparc/backoff.h b/include/asm-sparc/backoff.h
new file mode 100644 (file)
index 0000000..fa1fdf6
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef _SPARC64_BACKOFF_H
+#define _SPARC64_BACKOFF_H
+
+#define BACKOFF_LIMIT  (4 * 1024)
+
+#ifdef CONFIG_SMP
+
+#define BACKOFF_SETUP(reg)     \
+       mov     1, reg
+
+#define BACKOFF_SPIN(reg, tmp, label)  \
+       mov     reg, tmp; \
+88:    brnz,pt tmp, 88b; \
+        sub    tmp, 1, tmp; \
+       set     BACKOFF_LIMIT, tmp; \
+       cmp     reg, tmp; \
+       bg,pn   %xcc, label; \
+        nop; \
+       ba,pt   %xcc, label; \
+        sllx   reg, 1, reg;
+
+#else
+
+#define BACKOFF_SETUP(reg)
+#define BACKOFF_SPIN(reg, tmp, label) \
+       ba,pt   %xcc, label; \
+        nop;
+
+#endif
+
+#endif /* _SPARC64_BACKOFF_H */
diff --git a/include/asm-sparc/bbc.h b/include/asm-sparc/bbc.h
new file mode 100644 (file)
index 0000000..423a858
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * bbc.h: Defines for BootBus Controller found on UltraSPARC-III
+ *        systems.
+ *
+ * Copyright (C) 2000 David S. Miller (davem@redhat.com)
+ */
+
+#ifndef _SPARC64_BBC_H
+#define _SPARC64_BBC_H
+
+/* Register sizes are indicated by "B" (Byte, 1-byte),
+ * "H" (Half-word, 2 bytes), "W" (Word, 4 bytes) or
+ * "Q" (Quad, 8 bytes) inside brackets.
+ */
+
+#define BBC_AID                0x00    /* [B] Agent ID                 */
+#define BBC_DEVP       0x01    /* [B] Device Present           */
+#define BBC_ARB                0x02    /* [B] Arbitration              */
+#define BBC_QUIESCE    0x03    /* [B] Quiesce                  */
+#define BBC_WDACTION   0x04    /* [B] Watchdog Action          */
+#define BBC_SPG                0x06    /* [B] Soft POR Gen             */
+#define BBC_SXG                0x07    /* [B] Soft XIR Gen             */
+#define BBC_PSRC       0x08    /* [W] POR Source               */
+#define BBC_XSRC       0x0c    /* [B] XIR Source               */
+#define BBC_CSC                0x0d    /* [B] Clock Synthesizers Control*/
+#define BBC_ES_CTRL    0x0e    /* [H] Energy Star Control      */
+#define BBC_ES_ACT     0x10    /* [W] E* Assert Change Time    */
+#define BBC_ES_DACT    0x14    /* [B] E* De-Assert Change Time */
+#define BBC_ES_DABT    0x15    /* [B] E* De-Assert Bypass Time */
+#define BBC_ES_ABT     0x16    /* [H] E* Assert Bypass Time    */
+#define BBC_ES_PST     0x18    /* [W] E* PLL Settle Time       */
+#define BBC_ES_FSL     0x1c    /* [W] E* Frequency Switch Latency*/
+#define BBC_EBUST      0x20    /* [Q] EBUS Timing              */
+#define BBC_JTAG_CMD   0x28    /* [W] JTAG+ Command            */
+#define BBC_JTAG_CTRL  0x2c    /* [B] JTAG+ Control            */
+#define BBC_I2C_SEL    0x2d    /* [B] I2C Selection            */
+#define BBC_I2C_0_S1   0x2e    /* [B] I2C ctrlr-0 reg S1       */
+#define BBC_I2C_0_S0   0x2f    /* [B] I2C ctrlr-0 regs S0,S0',S2,S3*/
+#define BBC_I2C_1_S1   0x30    /* [B] I2C ctrlr-1 reg S1       */
+#define BBC_I2C_1_S0   0x31    /* [B] I2C ctrlr-1 regs S0,S0',S2,S3*/
+#define BBC_KBD_BEEP   0x32    /* [B] Keyboard Beep            */
+#define BBC_KBD_BCNT   0x34    /* [W] Keyboard Beep Counter    */
+
+#define BBC_REGS_SIZE  0x40
+
+/* There is a 2K scratch ram area at offset 0x80000 but I doubt
+ * we will use it for anything.
+ */
+
+/* Agent ID register.  This register shows the Safari Agent ID
+ * for the processors.  The value returned depends upon which
+ * cpu is reading the register.
+ */
+#define BBC_AID_ID     0x07    /* Safari ID            */
+#define BBC_AID_RESV   0xf8    /* Reserved             */
+
+/* Device Present register.  One can determine which cpus are actually
+ * present in the machine by interrogating this register.
+ */
+#define BBC_DEVP_CPU0  0x01    /* Processor 0 present  */
+#define BBC_DEVP_CPU1  0x02    /* Processor 1 present  */
+#define BBC_DEVP_CPU2  0x04    /* Processor 2 present  */
+#define BBC_DEVP_CPU3  0x08    /* Processor 3 present  */
+#define BBC_DEVP_RESV  0xf0    /* Reserved             */
+
+/* Arbitration register.  This register is used to block access to
+ * the BBC from a particular cpu.
+ */
+#define BBC_ARB_CPU0   0x01    /* Enable cpu 0 BBC arbitratrion */
+#define BBC_ARB_CPU1   0x02    /* Enable cpu 1 BBC arbitratrion */
+#define BBC_ARB_CPU2   0x04    /* Enable cpu 2 BBC arbitratrion */
+#define BBC_ARB_CPU3   0x08    /* Enable cpu 3 BBC arbitratrion */
+#define BBC_ARB_RESV   0xf0    /* Reserved                      */
+
+/* Quiesce register.  Bus and BBC segments for cpus can be disabled
+ * with this register, ie. for hot plugging.
+ */
+#define BBC_QUIESCE_S02        0x01    /* Quiesce Safari segment for cpu 0 and 2 */
+#define BBC_QUIESCE_S13        0x02    /* Quiesce Safari segment for cpu 1 and 3 */
+#define BBC_QUIESCE_B02        0x04    /* Quiesce BBC segment for cpu 0 and 2    */
+#define BBC_QUIESCE_B13        0x08    /* Quiesce BBC segment for cpu 1 and 3    */
+#define BBC_QUIESCE_FD0 0x10   /* Disable Fatal_Error[0] reporting       */
+#define BBC_QUIESCE_FD1 0x20   /* Disable Fatal_Error[1] reporting       */
+#define BBC_QUIESCE_FD2 0x40   /* Disable Fatal_Error[2] reporting       */
+#define BBC_QUIESCE_FD3 0x80   /* Disable Fatal_Error[3] reporting       */
+
+/* Watchdog Action register.  When the watchdog device timer expires
+ * a line is enabled to the BBC.  The action BBC takes when this line
+ * is asserted can be controlled by this regiser.
+ */
+#define BBC_WDACTION_RST  0x01 /* When set, watchdog causes system reset.
+                                * When clear, BBC ignores watchdog signal.
+                                */
+#define BBC_WDACTION_RESV 0xfe /* Reserved */
+
+/* Soft_POR_GEN register.  The POR (Power On Reset) signal may be asserted
+ * for specific processors or all processors via this register.
+ */
+#define BBC_SPG_CPU0   0x01 /* Assert POR for processor 0      */
+#define BBC_SPG_CPU1   0x02 /* Assert POR for processor 1      */
+#define BBC_SPG_CPU2   0x04 /* Assert POR for processor 2      */
+#define BBC_SPG_CPU3   0x08 /* Assert POR for processor 3      */
+#define BBC_SPG_CPUALL 0x10 /* Reset all processors and reset
+                             * the entire system.
+                             */
+#define BBC_SPG_RESV   0xe0 /* Reserved                        */
+
+/* Soft_XIR_GEN register.  The XIR (eXternally Initiated Reset) signal
+ * may be asserted to specific processors via this register.
+ */
+#define BBC_SXG_CPU0   0x01 /* Assert XIR for processor 0      */
+#define BBC_SXG_CPU1   0x02 /* Assert XIR for processor 1      */
+#define BBC_SXG_CPU2   0x04 /* Assert XIR for processor 2      */
+#define BBC_SXG_CPU3   0x08 /* Assert XIR for processor 3      */
+#define BBC_SXG_RESV   0xf0 /* Reserved                        */
+
+/* POR Source register.  One may identify the cause of the most recent
+ * reset by reading this register.
+ */
+#define BBC_PSRC_SPG0  0x0001 /* CPU 0 reset via BBC_SPG register      */
+#define BBC_PSRC_SPG1  0x0002 /* CPU 1 reset via BBC_SPG register      */
+#define BBC_PSRC_SPG2  0x0004 /* CPU 2 reset via BBC_SPG register      */
+#define BBC_PSRC_SPG3  0x0008 /* CPU 3 reset via BBC_SPG register      */
+#define BBC_PSRC_SPGSYS        0x0010 /* System reset via BBC_SPG register     */
+#define BBC_PSRC_JTAG  0x0020 /* System reset via JTAG+                */
+#define BBC_PSRC_BUTTON        0x0040 /* System reset via push-button dongle   */
+#define BBC_PSRC_PWRUP 0x0080 /* System reset via power-up             */
+#define BBC_PSRC_FE0   0x0100 /* CPU 0 reported Fatal_Error            */
+#define BBC_PSRC_FE1   0x0200 /* CPU 1 reported Fatal_Error            */
+#define BBC_PSRC_FE2   0x0400 /* CPU 2 reported Fatal_Error            */
+#define BBC_PSRC_FE3   0x0800 /* CPU 3 reported Fatal_Error            */
+#define BBC_PSRC_FE4   0x1000 /* Schizo reported Fatal_Error           */
+#define BBC_PSRC_FE5   0x2000 /* Safari device 5 reported Fatal_Error  */
+#define BBC_PSRC_FE6   0x4000 /* CPMS reported Fatal_Error             */
+#define BBC_PSRC_SYNTH 0x8000 /* System reset when on-board clock synthesizers
+                               * were updated.
+                               */
+#define BBC_PSRC_WDT   0x10000 /* System reset via Super I/O watchdog  */
+#define BBC_PSRC_RSC   0x20000 /* System reset via RSC remote monitoring
+                               * device
+                               */
+
+/* XIR Source register.  The source of an XIR event sent to a processor may
+ * be determined via this register.
+ */
+#define BBC_XSRC_SXG0  0x01    /* CPU 0 received XIR via Soft_XIR_GEN reg */
+#define BBC_XSRC_SXG1  0x02    /* CPU 1 received XIR via Soft_XIR_GEN reg */
+#define BBC_XSRC_SXG2  0x04    /* CPU 2 received XIR via Soft_XIR_GEN reg */
+#define BBC_XSRC_SXG3  0x08    /* CPU 3 received XIR via Soft_XIR_GEN reg */
+#define BBC_XSRC_JTAG  0x10    /* All CPUs received XIR via JTAG+         */
+#define BBC_XSRC_W_OR_B        0x20    /* All CPUs received XIR either because:
+                                * a) Super I/O watchdog fired, or
+                                * b) XIR push button was activated
+                                */
+#define BBC_XSRC_RESV  0xc0    /* Reserved                                */
+
+/* Clock Synthesizers Control register.  This register provides the big-bang
+ * programming interface to the two clock synthesizers of the machine.
+ */
+#define BBC_CSC_SLOAD  0x01    /* Directly connected to S_LOAD pins    */
+#define BBC_CSC_SDATA  0x02    /* Directly connected to S_DATA pins    */
+#define BBC_CSC_SCLOCK 0x04    /* Directly connected to S_CLOCK pins   */
+#define BBC_CSC_RESV   0x78    /* Reserved                             */
+#define BBC_CSC_RST    0x80    /* Generate system reset when S_LOAD==1 */
+
+/* Energy Star Control register.  This register is used to generate the
+ * clock frequency change trigger to the main system devices (Schizo and
+ * the processors).  The transition occurs when bits in this register
+ * go from 0 to 1, only one bit must be set at once else no action
+ * occurs.  Basically the sequence of events is:
+ * a) Choose new frequency: full, 1/2 or 1/32
+ * b) Program this desired frequency into the cpus and Schizo.
+ * c) Set the same value in this register.
+ * d) 16 system clocks later, clear this register.
+ */
+#define BBC_ES_CTRL_1_1                0x01    /* Full frequency       */
+#define BBC_ES_CTRL_1_2                0x02    /* 1/2 frequency        */
+#define BBC_ES_CTRL_1_32       0x20    /* 1/32 frequency       */
+#define BBC_ES_RESV            0xdc    /* Reserved             */
+
+/* Energy Star Assert Change Time register.  This determines the number
+ * of BBC clock cycles (which is half the system frequency) between
+ * the detection of FREEZE_ACK being asserted and the assertion of
+ * the CLK_CHANGE_L[2:0] signals.
+ */
+#define BBC_ES_ACT_VAL 0xff
+
+/* Energy Star Assert Bypass Time register.  This determines the number
+ * of BBC clock cycles (which is half the system frequency) between
+ * the assertion of the CLK_CHANGE_L[2:0] signals and the assertion of
+ * the ESTAR_PLL_BYPASS signal.
+ */
+#define BBC_ES_ABT_VAL 0xffff
+
+/* Energy Star PLL Settle Time register.  This determines the number of
+ * BBC clock cycles (which is half the system frequency) between the
+ * de-assertion of CLK_CHANGE_L[2:0] and the de-assertion of the FREEZE_L
+ * signal.
+ */
+#define BBC_ES_PST_VAL 0xffffffff
+
+/* Energy Star Frequency Switch Latency register.  This is the number of
+ * BBC clocks between the de-assertion of CLK_CHANGE_L[2:0] and the first
+ * edge of the Safari clock at the new frequency.
+ */
+#define BBC_ES_FSL_VAL 0xffffffff
+
+/* Keyboard Beep control register.  This is a simple enabler for the audio
+ * beep sound.
+ */
+#define BBC_KBD_BEEP_ENABLE    0x01 /* Enable beep     */
+#define BBC_KBD_BEEP_RESV      0xfe /* Reserved        */
+
+/* Keyboard Beep Counter register.  There is a free-running counter inside
+ * the BBC which runs at half the system clock.  The bit set in this register
+ * determines when the audio sound is generated.  So for example if bit
+ * 10 is set, the audio beep will oscillate at 1/(2**12).  The keyboard beep
+ * generator automatically selects a different bit to use if the system clock
+ * is changed via Energy Star.
+ */
+#define BBC_KBD_BCNT_BITS      0x0007fc00
+#define BBC_KBC_BCNT_RESV      0xfff803ff
+
+#endif /* _SPARC64_BBC_H */
+
index 68b98a7e6454952500e54cd6728eb688813836a2..1a2949d0193fa85defd4a7a2698bf4afb372b7cf 100644 (file)
@@ -1,111 +1,8 @@
-/*
- * bitops.h: Bit string operations on the Sparc.
- *
- * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
- * Copyright 1996 Eddie C. Dost   (ecd@skynet.be)
- * Copyright 2001 Anton Blanchard (anton@samba.org)
- */
-
-#ifndef _SPARC_BITOPS_H
-#define _SPARC_BITOPS_H
-
-#include <linux/compiler.h>
-#include <asm/byteorder.h>
-
-#ifdef __KERNEL__
-
-#ifndef _LINUX_BITOPS_H
-#error only <linux/bitops.h> can be included directly
+#ifndef ___ASM_SPARC_BITOPS_H
+#define ___ASM_SPARC_BITOPS_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/bitops_64.h>
+#else
+#include <asm-sparc/bitops_32.h>
+#endif
 #endif
-
-extern unsigned long ___set_bit(unsigned long *addr, unsigned long mask);
-extern unsigned long ___clear_bit(unsigned long *addr, unsigned long mask);
-extern unsigned long ___change_bit(unsigned long *addr, unsigned long mask);
-
-/*
- * Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0'
- * is in the highest of the four bytes and bit '31' is the high bit
- * within the first byte. Sparc is BIG-Endian. Unless noted otherwise
- * all bit-ops return 0 if bit was previously clear and != 0 otherwise.
- */
-static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
-{
-       unsigned long *ADDR, mask;
-
-       ADDR = ((unsigned long *) addr) + (nr >> 5);
-       mask = 1 << (nr & 31);
-
-       return ___set_bit(ADDR, mask) != 0;
-}
-
-static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
-{
-       unsigned long *ADDR, mask;
-
-       ADDR = ((unsigned long *) addr) + (nr >> 5);
-       mask = 1 << (nr & 31);
-
-       (void) ___set_bit(ADDR, mask);
-}
-
-static inline int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
-{
-       unsigned long *ADDR, mask;
-
-       ADDR = ((unsigned long *) addr) + (nr >> 5);
-       mask = 1 << (nr & 31);
-
-       return ___clear_bit(ADDR, mask) != 0;
-}
-
-static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
-{
-       unsigned long *ADDR, mask;
-
-       ADDR = ((unsigned long *) addr) + (nr >> 5);
-       mask = 1 << (nr & 31);
-
-       (void) ___clear_bit(ADDR, mask);
-}
-
-static inline int test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
-{
-       unsigned long *ADDR, mask;
-
-       ADDR = ((unsigned long *) addr) + (nr >> 5);
-       mask = 1 << (nr & 31);
-
-       return ___change_bit(ADDR, mask) != 0;
-}
-
-static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
-{
-       unsigned long *ADDR, mask;
-
-       ADDR = ((unsigned long *) addr) + (nr >> 5);
-       mask = 1 << (nr & 31);
-
-       (void) ___change_bit(ADDR, mask);
-}
-
-#include <asm-generic/bitops/non-atomic.h>
-
-#define smp_mb__before_clear_bit()     do { } while(0)
-#define smp_mb__after_clear_bit()      do { } while(0)
-
-#include <asm-generic/bitops/ffz.h>
-#include <asm-generic/bitops/__ffs.h>
-#include <asm-generic/bitops/sched.h>
-#include <asm-generic/bitops/ffs.h>
-#include <asm-generic/bitops/fls.h>
-#include <asm-generic/bitops/fls64.h>
-#include <asm-generic/bitops/hweight.h>
-#include <asm-generic/bitops/lock.h>
-#include <asm-generic/bitops/find.h>
-#include <asm-generic/bitops/ext2-non-atomic.h>
-#include <asm-generic/bitops/ext2-atomic.h>
-#include <asm-generic/bitops/minix.h>
-
-#endif /* __KERNEL__ */
-
-#endif /* defined(_SPARC_BITOPS_H) */
diff --git a/include/asm-sparc/bitops_32.h b/include/asm-sparc/bitops_32.h
new file mode 100644 (file)
index 0000000..68b98a7
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * bitops.h: Bit string operations on the Sparc.
+ *
+ * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright 1996 Eddie C. Dost   (ecd@skynet.be)
+ * Copyright 2001 Anton Blanchard (anton@samba.org)
+ */
+
+#ifndef _SPARC_BITOPS_H
+#define _SPARC_BITOPS_H
+
+#include <linux/compiler.h>
+#include <asm/byteorder.h>
+
+#ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
+extern unsigned long ___set_bit(unsigned long *addr, unsigned long mask);
+extern unsigned long ___clear_bit(unsigned long *addr, unsigned long mask);
+extern unsigned long ___change_bit(unsigned long *addr, unsigned long mask);
+
+/*
+ * Set bit 'nr' in 32-bit quantity at address 'addr' where bit '0'
+ * is in the highest of the four bytes and bit '31' is the high bit
+ * within the first byte. Sparc is BIG-Endian. Unless noted otherwise
+ * all bit-ops return 0 if bit was previously clear and != 0 otherwise.
+ */
+static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *addr)
+{
+       unsigned long *ADDR, mask;
+
+       ADDR = ((unsigned long *) addr) + (nr >> 5);
+       mask = 1 << (nr & 31);
+
+       return ___set_bit(ADDR, mask) != 0;
+}
+
+static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
+{
+       unsigned long *ADDR, mask;
+
+       ADDR = ((unsigned long *) addr) + (nr >> 5);
+       mask = 1 << (nr & 31);
+
+       (void) ___set_bit(ADDR, mask);
+}
+
+static inline int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
+{
+       unsigned long *ADDR, mask;
+
+       ADDR = ((unsigned long *) addr) + (nr >> 5);
+       mask = 1 << (nr & 31);
+
+       return ___clear_bit(ADDR, mask) != 0;
+}
+
+static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
+{
+       unsigned long *ADDR, mask;
+
+       ADDR = ((unsigned long *) addr) + (nr >> 5);
+       mask = 1 << (nr & 31);
+
+       (void) ___clear_bit(ADDR, mask);
+}
+
+static inline int test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
+{
+       unsigned long *ADDR, mask;
+
+       ADDR = ((unsigned long *) addr) + (nr >> 5);
+       mask = 1 << (nr & 31);
+
+       return ___change_bit(ADDR, mask) != 0;
+}
+
+static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
+{
+       unsigned long *ADDR, mask;
+
+       ADDR = ((unsigned long *) addr) + (nr >> 5);
+       mask = 1 << (nr & 31);
+
+       (void) ___change_bit(ADDR, mask);
+}
+
+#include <asm-generic/bitops/non-atomic.h>
+
+#define smp_mb__before_clear_bit()     do { } while(0)
+#define smp_mb__after_clear_bit()      do { } while(0)
+
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/fls64.h>
+#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
+#include <asm-generic/bitops/find.h>
+#include <asm-generic/bitops/ext2-non-atomic.h>
+#include <asm-generic/bitops/ext2-atomic.h>
+#include <asm-generic/bitops/minix.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* defined(_SPARC_BITOPS_H) */
diff --git a/include/asm-sparc/bitops_64.h b/include/asm-sparc/bitops_64.h
new file mode 100644 (file)
index 0000000..bb87b80
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * bitops.h: Bit string operations on the V9.
+ *
+ * Copyright 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_BITOPS_H
+#define _SPARC64_BITOPS_H
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
+#include <linux/compiler.h>
+#include <asm/byteorder.h>
+
+extern int test_and_set_bit(unsigned long nr, volatile unsigned long *addr);
+extern int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr);
+extern int test_and_change_bit(unsigned long nr, volatile unsigned long *addr);
+extern void set_bit(unsigned long nr, volatile unsigned long *addr);
+extern void clear_bit(unsigned long nr, volatile unsigned long *addr);
+extern void change_bit(unsigned long nr, volatile unsigned long *addr);
+
+#include <asm-generic/bitops/non-atomic.h>
+
+#ifdef CONFIG_SMP
+#define smp_mb__before_clear_bit()     membar_storeload_loadload()
+#define smp_mb__after_clear_bit()      membar_storeload_storestore()
+#else
+#define smp_mb__before_clear_bit()     barrier()
+#define smp_mb__after_clear_bit()      barrier()
+#endif
+
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/__fls.h>
+#include <asm-generic/bitops/fls64.h>
+
+#ifdef __KERNEL__
+
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/ffs.h>
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#ifdef ULTRA_HAS_POPULATION_COUNT
+
+static inline unsigned int hweight64(unsigned long w)
+{
+       unsigned int res;
+
+       __asm__ ("popc %1,%0" : "=r" (res) : "r" (w));
+       return res;
+}
+
+static inline unsigned int hweight32(unsigned int w)
+{
+       unsigned int res;
+
+       __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff));
+       return res;
+}
+
+static inline unsigned int hweight16(unsigned int w)
+{
+       unsigned int res;
+
+       __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff));
+       return res;
+}
+
+static inline unsigned int hweight8(unsigned int w)
+{
+       unsigned int res;
+
+       __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff));
+       return res;
+}
+
+#else
+
+#include <asm-generic/bitops/hweight.h>
+
+#endif
+#include <asm-generic/bitops/lock.h>
+#endif /* __KERNEL__ */
+
+#include <asm-generic/bitops/find.h>
+
+#ifdef __KERNEL__
+
+#include <asm-generic/bitops/ext2-non-atomic.h>
+
+#define ext2_set_bit_atomic(lock,nr,addr) \
+       test_and_set_bit((nr) ^ 0x38,(unsigned long *)(addr))
+#define ext2_clear_bit_atomic(lock,nr,addr) \
+       test_and_clear_bit((nr) ^ 0x38,(unsigned long *)(addr))
+
+#include <asm-generic/bitops/minix.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* defined(_SPARC64_BITOPS_H) */
index 68ac109102715911f5ff244cfa8ee1a5cfb8d751..2b6a37957c2da803739a7e0a71779ea264f2b5d4 100644 (file)
@@ -1,85 +1,8 @@
-#ifndef _SPARC_CACHEFLUSH_H
-#define _SPARC_CACHEFLUSH_H
-
-#include <linux/mm.h>          /* Common for other includes */
-// #include <linux/kernel.h> from pgalloc.h
-// #include <linux/sched.h>  from pgalloc.h
-
-// #include <asm/page.h>
-#include <asm/btfixup.h>
-
-/*
- * Fine grained cache flushing.
- */
-#ifdef CONFIG_SMP
-
-BTFIXUPDEF_CALL(void, local_flush_cache_all, void)
-BTFIXUPDEF_CALL(void, local_flush_cache_mm, struct mm_struct *)
-BTFIXUPDEF_CALL(void, local_flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(void, local_flush_cache_page, struct vm_area_struct *, unsigned long)
-
-#define local_flush_cache_all() BTFIXUP_CALL(local_flush_cache_all)()
-#define local_flush_cache_mm(mm) BTFIXUP_CALL(local_flush_cache_mm)(mm)
-#define local_flush_cache_range(vma,start,end) BTFIXUP_CALL(local_flush_cache_range)(vma,start,end)
-#define local_flush_cache_page(vma,addr) BTFIXUP_CALL(local_flush_cache_page)(vma,addr)
-
-BTFIXUPDEF_CALL(void, local_flush_page_to_ram, unsigned long)
-BTFIXUPDEF_CALL(void, local_flush_sig_insns, struct mm_struct *, unsigned long)
-
-#define local_flush_page_to_ram(addr) BTFIXUP_CALL(local_flush_page_to_ram)(addr)
-#define local_flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(local_flush_sig_insns)(mm,insn_addr)
-
-extern void smp_flush_cache_all(void);
-extern void smp_flush_cache_mm(struct mm_struct *mm);
-extern void smp_flush_cache_range(struct vm_area_struct *vma,
-                                 unsigned long start,
-                                 unsigned long end);
-extern void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page);
-
-extern void smp_flush_page_to_ram(unsigned long page);
-extern void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
-
-#endif /* CONFIG_SMP */
-
-BTFIXUPDEF_CALL(void, flush_cache_all, void)
-BTFIXUPDEF_CALL(void, flush_cache_mm, struct mm_struct *)
-BTFIXUPDEF_CALL(void, flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(void, flush_cache_page, struct vm_area_struct *, unsigned long)
-
-#define flush_cache_all() BTFIXUP_CALL(flush_cache_all)()
-#define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
-#define flush_cache_dup_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
-#define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end)
-#define flush_cache_page(vma,addr,pfn) BTFIXUP_CALL(flush_cache_page)(vma,addr)
-#define flush_icache_range(start, end)         do { } while (0)
-#define flush_icache_page(vma, pg)             do { } while (0)
-
-#define flush_icache_user_range(vma,pg,adr,len)        do { } while (0)
-
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-       do {                                                    \
-               flush_cache_page(vma, vaddr, page_to_pfn(page));\
-               memcpy(dst, src, len);                          \
-       } while (0)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
-       do {                                                    \
-               flush_cache_page(vma, vaddr, page_to_pfn(page));\
-               memcpy(dst, src, len);                          \
-       } while (0)
-
-BTFIXUPDEF_CALL(void, __flush_page_to_ram, unsigned long)
-BTFIXUPDEF_CALL(void, flush_sig_insns, struct mm_struct *, unsigned long)
-
-#define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr)
-#define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr)
-
-extern void sparc_flush_page_to_ram(struct page *page);
-
-#define flush_dcache_page(page)                        sparc_flush_page_to_ram(page)
-#define flush_dcache_mmap_lock(mapping)                do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)      do { } while (0)
-
-#define flush_cache_vmap(start, end)           flush_cache_all()
-#define flush_cache_vunmap(start, end)         flush_cache_all()
-
-#endif /* _SPARC_CACHEFLUSH_H */
+#ifndef ___ASM_SPARC_CACHEFLUSH_H
+#define ___ASM_SPARC_CACHEFLUSH_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/cacheflush_64.h>
+#else
+#include <asm-sparc/cacheflush_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/cacheflush_32.h b/include/asm-sparc/cacheflush_32.h
new file mode 100644 (file)
index 0000000..68ac109
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef _SPARC_CACHEFLUSH_H
+#define _SPARC_CACHEFLUSH_H
+
+#include <linux/mm.h>          /* Common for other includes */
+// #include <linux/kernel.h> from pgalloc.h
+// #include <linux/sched.h>  from pgalloc.h
+
+// #include <asm/page.h>
+#include <asm/btfixup.h>
+
+/*
+ * Fine grained cache flushing.
+ */
+#ifdef CONFIG_SMP
+
+BTFIXUPDEF_CALL(void, local_flush_cache_all, void)
+BTFIXUPDEF_CALL(void, local_flush_cache_mm, struct mm_struct *)
+BTFIXUPDEF_CALL(void, local_flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
+BTFIXUPDEF_CALL(void, local_flush_cache_page, struct vm_area_struct *, unsigned long)
+
+#define local_flush_cache_all() BTFIXUP_CALL(local_flush_cache_all)()
+#define local_flush_cache_mm(mm) BTFIXUP_CALL(local_flush_cache_mm)(mm)
+#define local_flush_cache_range(vma,start,end) BTFIXUP_CALL(local_flush_cache_range)(vma,start,end)
+#define local_flush_cache_page(vma,addr) BTFIXUP_CALL(local_flush_cache_page)(vma,addr)
+
+BTFIXUPDEF_CALL(void, local_flush_page_to_ram, unsigned long)
+BTFIXUPDEF_CALL(void, local_flush_sig_insns, struct mm_struct *, unsigned long)
+
+#define local_flush_page_to_ram(addr) BTFIXUP_CALL(local_flush_page_to_ram)(addr)
+#define local_flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(local_flush_sig_insns)(mm,insn_addr)
+
+extern void smp_flush_cache_all(void);
+extern void smp_flush_cache_mm(struct mm_struct *mm);
+extern void smp_flush_cache_range(struct vm_area_struct *vma,
+                                 unsigned long start,
+                                 unsigned long end);
+extern void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page);
+
+extern void smp_flush_page_to_ram(unsigned long page);
+extern void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
+
+#endif /* CONFIG_SMP */
+
+BTFIXUPDEF_CALL(void, flush_cache_all, void)
+BTFIXUPDEF_CALL(void, flush_cache_mm, struct mm_struct *)
+BTFIXUPDEF_CALL(void, flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
+BTFIXUPDEF_CALL(void, flush_cache_page, struct vm_area_struct *, unsigned long)
+
+#define flush_cache_all() BTFIXUP_CALL(flush_cache_all)()
+#define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
+#define flush_cache_dup_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
+#define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end)
+#define flush_cache_page(vma,addr,pfn) BTFIXUP_CALL(flush_cache_page)(vma,addr)
+#define flush_icache_range(start, end)         do { } while (0)
+#define flush_icache_page(vma, pg)             do { } while (0)
+
+#define flush_icache_user_range(vma,pg,adr,len)        do { } while (0)
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+       do {                                                    \
+               flush_cache_page(vma, vaddr, page_to_pfn(page));\
+               memcpy(dst, src, len);                          \
+       } while (0)
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+       do {                                                    \
+               flush_cache_page(vma, vaddr, page_to_pfn(page));\
+               memcpy(dst, src, len);                          \
+       } while (0)
+
+BTFIXUPDEF_CALL(void, __flush_page_to_ram, unsigned long)
+BTFIXUPDEF_CALL(void, flush_sig_insns, struct mm_struct *, unsigned long)
+
+#define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr)
+#define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr)
+
+extern void sparc_flush_page_to_ram(struct page *page);
+
+#define flush_dcache_page(page)                        sparc_flush_page_to_ram(page)
+#define flush_dcache_mmap_lock(mapping)                do { } while (0)
+#define flush_dcache_mmap_unlock(mapping)      do { } while (0)
+
+#define flush_cache_vmap(start, end)           flush_cache_all()
+#define flush_cache_vunmap(start, end)         flush_cache_all()
+
+#endif /* _SPARC_CACHEFLUSH_H */
diff --git a/include/asm-sparc/cacheflush_64.h b/include/asm-sparc/cacheflush_64.h
new file mode 100644 (file)
index 0000000..c433217
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef _SPARC64_CACHEFLUSH_H
+#define _SPARC64_CACHEFLUSH_H
+
+#include <asm/page.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/mm.h>
+
+/* Cache flush operations. */
+
+/* These are the same regardless of whether this is an SMP kernel or not. */
+#define flush_cache_mm(__mm) \
+       do { if ((__mm) == current->mm) flushw_user(); } while(0)
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
+#define flush_cache_range(vma, start, end) \
+       flush_cache_mm((vma)->vm_mm)
+#define flush_cache_page(vma, page, pfn) \
+       flush_cache_mm((vma)->vm_mm)
+
+/*
+ * On spitfire, the icache doesn't snoop local stores and we don't
+ * use block commit stores (which invalidate icache lines) during
+ * module load, so we need this.
+ */
+extern void flush_icache_range(unsigned long start, unsigned long end);
+extern void __flush_icache_page(unsigned long);
+
+extern void __flush_dcache_page(void *addr, int flush_icache);
+extern void flush_dcache_page_impl(struct page *page);
+#ifdef CONFIG_SMP
+extern void smp_flush_dcache_page_impl(struct page *page, int cpu);
+extern void flush_dcache_page_all(struct mm_struct *mm, struct page *page);
+#else
+#define smp_flush_dcache_page_impl(page,cpu) flush_dcache_page_impl(page)
+#define flush_dcache_page_all(mm,page) flush_dcache_page_impl(page)
+#endif
+
+extern void __flush_dcache_range(unsigned long start, unsigned long end);
+extern void flush_dcache_page(struct page *page);
+
+#define flush_icache_page(vma, pg)     do { } while(0)
+#define flush_icache_user_range(vma,pg,adr,len)        do { } while (0)
+
+extern void flush_ptrace_access(struct vm_area_struct *, struct page *,
+                               unsigned long uaddr, void *kaddr,
+                               unsigned long len, int write);
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len)             \
+       do {                                                            \
+               flush_cache_page(vma, vaddr, page_to_pfn(page));        \
+               memcpy(dst, src, len);                                  \
+               flush_ptrace_access(vma, page, vaddr, src, len, 0);     \
+       } while (0)
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len)           \
+       do {                                                            \
+               flush_cache_page(vma, vaddr, page_to_pfn(page));        \
+               memcpy(dst, src, len);                                  \
+               flush_ptrace_access(vma, page, vaddr, dst, len, 1);     \
+       } while (0)
+
+#define flush_dcache_mmap_lock(mapping)                do { } while (0)
+#define flush_dcache_mmap_unlock(mapping)      do { } while (0)
+
+#define flush_cache_vmap(start, end)           do { } while (0)
+#define flush_cache_vunmap(start, end)         do { } while (0)
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+/* internal debugging function */
+void kernel_map_pages(struct page *page, int numpages, int enable);
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _SPARC64_CACHEFLUSH_H */
diff --git a/include/asm-sparc/chafsr.h b/include/asm-sparc/chafsr.h
new file mode 100644 (file)
index 0000000..85c69b3
--- /dev/null
@@ -0,0 +1,241 @@
+#ifndef _SPARC64_CHAFSR_H
+#define _SPARC64_CHAFSR_H
+
+/* Cheetah Asynchronous Fault Status register, ASI=0x4C VA<63:0>=0x0 */
+
+/* Comments indicate which processor variants on which the bit definition
+ * is valid.  Codes are:
+ * ch  -->     cheetah
+ * ch+ -->     cheetah plus
+ * jp  -->     jalapeno
+ */
+
+/* All bits of this register except M_SYNDROME and E_SYNDROME are
+ * read, write 1 to clear.  M_SYNDROME and E_SYNDROME are read-only.
+ */
+
+/* Software bit set by linux trap handlers to indicate that the trap was
+ * signalled at %tl >= 1.
+ */
+#define CHAFSR_TL1             (1UL << 63UL) /* n/a */
+
+/* Unmapped error from system bus for prefetch queue or
+ * store queue read operation
+ */
+#define CHPAFSR_DTO            (1UL << 59UL) /* ch+ */
+
+/* Bus error from system bus for prefetch queue or store queue
+ * read operation
+ */
+#define CHPAFSR_DBERR          (1UL << 58UL) /* ch+ */
+
+/* Hardware corrected E-cache Tag ECC error */
+#define CHPAFSR_THCE           (1UL << 57UL) /* ch+ */
+/* System interface protocol error, hw timeout caused */
+#define JPAFSR_JETO            (1UL << 57UL) /* jp */
+
+/* SW handled correctable E-cache Tag ECC error */
+#define CHPAFSR_TSCE           (1UL << 56UL) /* ch+ */
+/* Parity error on system snoop results */
+#define JPAFSR_SCE             (1UL << 56UL) /* jp */
+
+/* Uncorrectable E-cache Tag ECC error */
+#define CHPAFSR_TUE            (1UL << 55UL) /* ch+ */
+/* System interface protocol error, illegal command detected */
+#define JPAFSR_JEIC            (1UL << 55UL) /* jp */
+
+/* Uncorrectable system bus data ECC error due to prefetch
+ * or store fill request
+ */
+#define CHPAFSR_DUE            (1UL << 54UL) /* ch+ */
+/* System interface protocol error, illegal ADTYPE detected */
+#define JPAFSR_JEIT            (1UL << 54UL) /* jp */
+
+/* Multiple errors of the same type have occurred.  This bit is set when
+ * an uncorrectable error or a SW correctable error occurs and the status
+ * bit to report that error is already set.  When multiple errors of
+ * different types are indicated by setting multiple status bits.
+ *
+ * This bit is not set if multiple HW corrected errors with the same
+ * status bit occur, only uncorrectable and SW correctable ones have
+ * this behavior.
+ *
+ * This bit is not set when multiple ECC errors happen within a single
+ * 64-byte system bus transaction.  Only the first ECC error in a 16-byte
+ * subunit will be logged.  All errors in subsequent 16-byte subunits
+ * from the same 64-byte transaction are ignored.
+ */
+#define CHAFSR_ME              (1UL << 53UL) /* ch,ch+,jp */
+
+/* Privileged state error has occurred.  This is a capture of PSTATE.PRIV
+ * at the time the error is detected.
+ */
+#define CHAFSR_PRIV            (1UL << 52UL) /* ch,ch+,jp */
+
+/* The following bits 51 (CHAFSR_PERR) to 33 (CHAFSR_CE) are sticky error
+ * bits and record the most recently detected errors.  Bits accumulate
+ * errors that have been detected since the last write to clear the bit.
+ */
+
+/* System interface protocol error.  The processor asserts its' ERROR
+ * pin when this event occurs and it also logs a specific cause code
+ * into a JTAG scannable flop.
+ */
+#define CHAFSR_PERR            (1UL << 51UL) /* ch,ch+,jp */
+
+/* Internal processor error.  The processor asserts its' ERROR
+ * pin when this event occurs and it also logs a specific cause code
+ * into a JTAG scannable flop.
+ */
+#define CHAFSR_IERR            (1UL << 50UL) /* ch,ch+,jp */
+
+/* System request parity error on incoming address */
+#define CHAFSR_ISAP            (1UL << 49UL) /* ch,ch+,jp */
+
+/* HW Corrected system bus MTAG ECC error */
+#define CHAFSR_EMC             (1UL << 48UL) /* ch,ch+ */
+/* Parity error on L2 cache tag SRAM */
+#define JPAFSR_ETP             (1UL << 48UL) /* jp */
+
+/* Uncorrectable system bus MTAG ECC error */
+#define CHAFSR_EMU             (1UL << 47UL) /* ch,ch+ */
+/* Out of range memory error has occurred */
+#define JPAFSR_OM              (1UL << 47UL) /* jp */
+
+/* HW Corrected system bus data ECC error for read of interrupt vector */
+#define CHAFSR_IVC             (1UL << 46UL) /* ch,ch+ */
+/* Error due to unsupported store */
+#define JPAFSR_UMS             (1UL << 46UL) /* jp */
+
+/* Uncorrectable system bus data ECC error for read of interrupt vector */
+#define CHAFSR_IVU             (1UL << 45UL) /* ch,ch+,jp */
+
+/* Unmapped error from system bus */
+#define CHAFSR_TO              (1UL << 44UL) /* ch,ch+,jp */
+
+/* Bus error response from system bus */
+#define CHAFSR_BERR            (1UL << 43UL) /* ch,ch+,jp */
+
+/* SW Correctable E-cache ECC error for instruction fetch or data access
+ * other than block load.
+ */
+#define CHAFSR_UCC             (1UL << 42UL) /* ch,ch+,jp */
+
+/* Uncorrectable E-cache ECC error for instruction fetch or data access
+ * other than block load.
+ */
+#define CHAFSR_UCU             (1UL << 41UL) /* ch,ch+,jp */
+
+/* Copyout HW Corrected ECC error */
+#define CHAFSR_CPC             (1UL << 40UL) /* ch,ch+,jp */
+
+/* Copyout Uncorrectable ECC error */
+#define CHAFSR_CPU             (1UL << 39UL) /* ch,ch+,jp */
+
+/* HW Corrected ECC error from E-cache for writeback */
+#define CHAFSR_WDC             (1UL << 38UL) /* ch,ch+,jp */
+
+/* Uncorrectable ECC error from E-cache for writeback */
+#define CHAFSR_WDU             (1UL << 37UL) /* ch,ch+,jp */
+
+/* HW Corrected ECC error from E-cache for store merge or block load */
+#define CHAFSR_EDC             (1UL << 36UL) /* ch,ch+,jp */
+
+/* Uncorrectable ECC error from E-cache for store merge or block load */
+#define CHAFSR_EDU             (1UL << 35UL) /* ch,ch+,jp */
+
+/* Uncorrectable system bus data ECC error for read of memory or I/O */
+#define CHAFSR_UE              (1UL << 34UL) /* ch,ch+,jp */
+
+/* HW Corrected system bus data ECC error for read of memory or I/O */
+#define CHAFSR_CE              (1UL << 33UL) /* ch,ch+,jp */
+
+/* Uncorrectable ECC error from remote cache/memory */
+#define JPAFSR_RUE             (1UL << 32UL) /* jp */
+
+/* Correctable ECC error from remote cache/memory */
+#define JPAFSR_RCE             (1UL << 31UL) /* jp */
+
+/* JBUS parity error on returned read data */
+#define JPAFSR_BP              (1UL << 30UL) /* jp */
+
+/* JBUS parity error on data for writeback or block store */
+#define JPAFSR_WBP             (1UL << 29UL) /* jp */
+
+/* Foreign read to DRAM incurring correctable ECC error */
+#define JPAFSR_FRC             (1UL << 28UL) /* jp */
+
+/* Foreign read to DRAM incurring uncorrectable ECC error */
+#define JPAFSR_FRU             (1UL << 27UL) /* jp */
+
+#define CHAFSR_ERRORS          (CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \
+                                CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \
+                                CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \
+                                CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \
+                                CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE)
+#define CHPAFSR_ERRORS         (CHPAFSR_DTO | CHPAFSR_DBERR | CHPAFSR_THCE | \
+                                CHPAFSR_TSCE | CHPAFSR_TUE | CHPAFSR_DUE | \
+                                CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \
+                                CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \
+                                CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \
+                                CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \
+                                CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE)
+#define JPAFSR_ERRORS          (JPAFSR_JETO | JPAFSR_SCE | JPAFSR_JEIC | \
+                                JPAFSR_JEIT | CHAFSR_PERR | CHAFSR_IERR | \
+                                CHAFSR_ISAP | JPAFSR_ETP | JPAFSR_OM | \
+                                JPAFSR_UMS | CHAFSR_IVU | CHAFSR_TO | \
+                                CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | \
+                                CHAFSR_CPC | CHAFSR_CPU | CHAFSR_WDC | \
+                                CHAFSR_WDU | CHAFSR_EDC | CHAFSR_EDU | \
+                                CHAFSR_UE | CHAFSR_CE | JPAFSR_RUE | \
+                                JPAFSR_RCE | JPAFSR_BP | JPAFSR_WBP | \
+                                JPAFSR_FRC | JPAFSR_FRU)
+
+/* Active JBUS request signal when error occurred */
+#define JPAFSR_JBREQ           (0x7UL << 24UL) /* jp */
+#define JPAFSR_JBREQ_SHIFT     24UL
+
+/* L2 cache way information */
+#define JPAFSR_ETW             (0x3UL << 22UL) /* jp */
+#define JPAFSR_ETW_SHIFT       22UL
+
+/* System bus MTAG ECC syndrome.  This field captures the status of the
+ * first occurrence of the highest-priority error according to the M_SYND
+ * overwrite policy.  After the AFSR sticky bit, corresponding to the error
+ * for which the M_SYND is reported, is cleared, the contents of the M_SYND
+ * field will be unchanged by will be unfrozen for further error capture.
+ */
+#define CHAFSR_M_SYNDROME      (0xfUL << 16UL) /* ch,ch+,jp */
+#define CHAFSR_M_SYNDROME_SHIFT        16UL
+
+/* Agenid Id of the foreign device causing the UE/CE errors */
+#define JPAFSR_AID             (0x1fUL << 9UL) /* jp */
+#define JPAFSR_AID_SHIFT       9UL
+
+/* System bus or E-cache data ECC syndrome.  This field captures the status
+ * of the first occurrence of the highest-priority error according to the
+ * E_SYND overwrite policy.  After the AFSR sticky bit, corresponding to the
+ * error for which the E_SYND is reported, is cleare, the contents of the E_SYND
+ * field will be unchanged but will be unfrozen for further error capture.
+ */
+#define CHAFSR_E_SYNDROME      (0x1ffUL << 0UL) /* ch,ch+,jp */
+#define CHAFSR_E_SYNDROME_SHIFT        0UL
+
+/* The AFSR must be explicitly cleared by software, it is not cleared automatically
+ * by a read.  Writes to bits <51:33> with bits set will clear the corresponding
+ * bits in the AFSR.  Bits associated with disrupting traps must be cleared before
+ * interrupts are re-enabled to prevent multiple traps for the same error.  I.e.
+ * PSTATE.IE and AFSR bits control delivery of disrupting traps.
+ *
+ * Since there is only one AFAR, when multiple events have been logged by the
+ * bits in the AFSR, at most one of these events will have its status captured
+ * in the AFAR.  The highest priority of those event bits will get AFAR logging.
+ * The AFAR will be unlocked and available to capture the address of another event
+ * as soon as the one bit in AFSR that corresponds to the event logged in AFAR is
+ * cleared.  For example, if AFSR.CE is detected, then AFSR.UE (which overwrites
+ * the AFAR), and AFSR.UE is cleared by not AFSR.CE, then the AFAR will be unlocked
+ * and ready for another event, even though AFSR.CE is still set.  The same rules
+ * also apply to the M_SYNDROME and E_SYNDROME fields of the AFSR.
+ */
+
+#endif /* _SPARC64_CHAFSR_H */
index d044ddb5a3cfad9d9091bd11fb4e5d721dbbe826..4e3553d4f6e17a3eb6c07be765b1fe08b4542604 100644 (file)
@@ -1,241 +1,8 @@
-#ifndef __SPARC_CHECKSUM_H
-#define __SPARC_CHECKSUM_H
-
-/*  checksum.h:  IP/UDP/TCP checksum routines on the Sparc.
- *
- *  Copyright(C) 1995 Linus Torvalds
- *  Copyright(C) 1995 Miguel de Icaza
- *  Copyright(C) 1996 David S. Miller
- *  Copyright(C) 1996 Eddie C. Dost
- *  Copyright(C) 1997 Jakub Jelinek
- *
- * derived from:
- *     Alpha checksum c-code
- *      ix86 inline assembly
- *      RFC1071 Computing the Internet Checksum
- */
-#include <linux/in6.h>
-#include <asm/uaccess.h>
-
-/* computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-extern __wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/* the same as csum_partial, but copies from fs:src while it
- * checksums
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-extern unsigned int __csum_partial_copy_sparc_generic (const unsigned char *, unsigned char *);
-
-static inline __wsum
-csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
-{
-       register unsigned int ret asm("o0") = (unsigned int)src;
-       register char *d asm("o1") = dst;
-       register int l asm("g1") = len;
-
-       __asm__ __volatile__ (
-               "call __csum_partial_copy_sparc_generic\n\t"
-               " mov %6, %%g7\n"
-       : "=&r" (ret), "=&r" (d), "=&r" (l)
-       : "0" (ret), "1" (d), "2" (l), "r" (sum)
-       : "o2", "o3", "o4", "o5", "o7",
-         "g2", "g3", "g4", "g5", "g7",
-         "memory", "cc");
-       return (__force __wsum)ret;
-}
-
-static inline __wsum
-csum_partial_copy_from_user(const void __user *src, void *dst, int len,
-                           __wsum sum, int *err)
-  {
-       register unsigned long ret asm("o0") = (unsigned long)src;
-       register char *d asm("o1") = dst;
-       register int l asm("g1") = len;
-       register __wsum s asm("g7") = sum;
-
-       __asm__ __volatile__ (
-       ".section __ex_table,#alloc\n\t"
-       ".align 4\n\t"
-       ".word 1f,2\n\t"
-       ".previous\n"
-       "1:\n\t"
-       "call __csum_partial_copy_sparc_generic\n\t"
-       " st %8, [%%sp + 64]\n"
-       : "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
-       : "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
-       : "o2", "o3", "o4", "o5", "o7", "g2", "g3", "g4", "g5",
-         "cc", "memory");
-       return (__force __wsum)ret;
-}
-  
-static inline __wsum
-csum_partial_copy_to_user(const void *src, void __user *dst, int len,
-                         __wsum sum, int *err)
-{
-       if (!access_ok (VERIFY_WRITE, dst, len)) {
-               *err = -EFAULT;
-               return sum;
-       } else {
-               register unsigned long ret asm("o0") = (unsigned long)src;
-               register char __user *d asm("o1") = dst;
-               register int l asm("g1") = len;
-               register __wsum s asm("g7") = sum;
-
-               __asm__ __volatile__ (
-               ".section __ex_table,#alloc\n\t"
-               ".align 4\n\t"
-               ".word 1f,1\n\t"
-               ".previous\n"
-               "1:\n\t"
-               "call __csum_partial_copy_sparc_generic\n\t"
-               " st %8, [%%sp + 64]\n"
-               : "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
-               : "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
-               : "o2", "o3", "o4", "o5", "o7",
-                 "g2", "g3", "g4", "g5",
-                 "cc", "memory");
-               return (__force __wsum)ret;
-       }
-}
-
-#define HAVE_CSUM_COPY_USER
-#define csum_and_copy_to_user csum_partial_copy_to_user
-
-/* ihl is always 5 or greater, almost always is 5, and iph is word aligned
- * the majority of the time.
- */
-static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
-{
-       __sum16 sum;
-
-       /* Note: We must read %2 before we touch %0 for the first time,
-        *       because GCC can legitimately use the same register for
-        *       both operands.
-        */
-       __asm__ __volatile__("sub\t%2, 4, %%g4\n\t"
-                            "ld\t[%1 + 0x00], %0\n\t"
-                            "ld\t[%1 + 0x04], %%g2\n\t"
-                            "ld\t[%1 + 0x08], %%g3\n\t"
-                            "addcc\t%%g2, %0, %0\n\t"
-                            "addxcc\t%%g3, %0, %0\n\t"
-                            "ld\t[%1 + 0x0c], %%g2\n\t"
-                            "ld\t[%1 + 0x10], %%g3\n\t"
-                            "addxcc\t%%g2, %0, %0\n\t"
-                            "addx\t%0, %%g0, %0\n"
-                            "1:\taddcc\t%%g3, %0, %0\n\t"
-                            "add\t%1, 4, %1\n\t"
-                            "addxcc\t%0, %%g0, %0\n\t"
-                            "subcc\t%%g4, 1, %%g4\n\t"
-                            "be,a\t2f\n\t"
-                            "sll\t%0, 16, %%g2\n\t"
-                            "b\t1b\n\t"
-                            "ld\t[%1 + 0x10], %%g3\n"
-                            "2:\taddcc\t%0, %%g2, %%g2\n\t"
-                            "srl\t%%g2, 16, %0\n\t"
-                            "addx\t%0, %%g0, %0\n\t"
-                            "xnor\t%%g0, %0, %0"
-                            : "=r" (sum), "=&r" (iph)
-                            : "r" (ihl), "1" (iph)
-                            : "g2", "g3", "g4", "cc", "memory");
-       return sum;
-}
-
-/* Fold a partial checksum without adding pseudo headers. */
-static inline __sum16 csum_fold(__wsum sum)
-{
-       unsigned int tmp;
-
-       __asm__ __volatile__("addcc\t%0, %1, %1\n\t"
-                            "srl\t%1, 16, %1\n\t"
-                            "addx\t%1, %%g0, %1\n\t"
-                            "xnor\t%%g0, %1, %0"
-                            : "=&r" (sum), "=r" (tmp)
-                            : "0" (sum), "1" ((__force u32)sum<<16)
-                            : "cc");
-       return (__force __sum16)sum;
-}
-
-static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
-                                              unsigned short len,
-                                              unsigned short proto,
-                                              __wsum sum)
-{
-       __asm__ __volatile__("addcc\t%1, %0, %0\n\t"
-                            "addxcc\t%2, %0, %0\n\t"
-                            "addxcc\t%3, %0, %0\n\t"
-                            "addx\t%0, %%g0, %0\n\t"
-                            : "=r" (sum), "=r" (saddr)
-                            : "r" (daddr), "r" (proto + len), "0" (sum),
-                              "1" (saddr)
-                            : "cc");
-       return sum;
-}
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
-                                                  unsigned short len,
-                                                  unsigned short proto,
-                                                  __wsum sum)
-{
-       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
-}
-
-#define _HAVE_ARCH_IPV6_CSUM
-
-static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
-                                     const struct in6_addr *daddr,
-                                     __u32 len, unsigned short proto,
-                                     __wsum sum)
-{
-       __asm__ __volatile__ (
-               "addcc  %3, %4, %%g4\n\t"
-               "addxcc %5, %%g4, %%g4\n\t"
-               "ld     [%2 + 0x0c], %%g2\n\t"
-               "ld     [%2 + 0x08], %%g3\n\t"
-               "addxcc %%g2, %%g4, %%g4\n\t"
-               "ld     [%2 + 0x04], %%g2\n\t"
-               "addxcc %%g3, %%g4, %%g4\n\t"
-               "ld     [%2 + 0x00], %%g3\n\t"
-               "addxcc %%g2, %%g4, %%g4\n\t"
-               "ld     [%1 + 0x0c], %%g2\n\t"
-               "addxcc %%g3, %%g4, %%g4\n\t"
-               "ld     [%1 + 0x08], %%g3\n\t"
-               "addxcc %%g2, %%g4, %%g4\n\t"
-               "ld     [%1 + 0x04], %%g2\n\t"
-               "addxcc %%g3, %%g4, %%g4\n\t"
-               "ld     [%1 + 0x00], %%g3\n\t"
-               "addxcc %%g2, %%g4, %%g4\n\t"
-               "addxcc %%g3, %%g4, %0\n\t"
-               "addx   0, %0, %0\n"
-               : "=&r" (sum)
-               : "r" (saddr), "r" (daddr), 
-                 "r"(htonl(len)), "r"(htonl(proto)), "r"(sum)
-               : "g2", "g3", "g4", "cc");
-
-       return csum_fold(sum);
-}
-
-/* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */
-static inline __sum16 ip_compute_csum(const void *buff, int len)
-{
-       return csum_fold(csum_partial(buff, len, 0));
-}
-
-#endif /* !(__SPARC_CHECKSUM_H) */
+#ifndef ___ASM_SPARC_CHECKSUM_H
+#define ___ASM_SPARC_CHECKSUM_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/checksum_64.h>
+#else
+#include <asm-sparc/checksum_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/checksum_32.h b/include/asm-sparc/checksum_32.h
new file mode 100644 (file)
index 0000000..bdbda14
--- /dev/null
@@ -0,0 +1,241 @@
+#ifndef __SPARC_CHECKSUM_H
+#define __SPARC_CHECKSUM_H
+
+/*  checksum.h:  IP/UDP/TCP checksum routines on the Sparc.
+ *
+ *  Copyright(C) 1995 Linus Torvalds
+ *  Copyright(C) 1995 Miguel de Icaza
+ *  Copyright(C) 1996 David S. Miller
+ *  Copyright(C) 1996 Eddie C. Dost
+ *  Copyright(C) 1997 Jakub Jelinek
+ *
+ * derived from:
+ *     Alpha checksum c-code
+ *      ix86 inline assembly
+ *      RFC1071 Computing the Internet Checksum
+ */
+
+#include <linux/in6.h>
+#include <asm/uaccess.h>
+
+/* computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+extern __wsum csum_partial(const void *buff, int len, __wsum sum);
+
+/* the same as csum_partial, but copies from fs:src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+extern unsigned int __csum_partial_copy_sparc_generic (const unsigned char *, unsigned char *);
+
+static inline __wsum
+csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
+{
+       register unsigned int ret asm("o0") = (unsigned int)src;
+       register char *d asm("o1") = dst;
+       register int l asm("g1") = len;
+
+       __asm__ __volatile__ (
+               "call __csum_partial_copy_sparc_generic\n\t"
+               " mov %6, %%g7\n"
+       : "=&r" (ret), "=&r" (d), "=&r" (l)
+       : "0" (ret), "1" (d), "2" (l), "r" (sum)
+       : "o2", "o3", "o4", "o5", "o7",
+         "g2", "g3", "g4", "g5", "g7",
+         "memory", "cc");
+       return (__force __wsum)ret;
+}
+
+static inline __wsum
+csum_partial_copy_from_user(const void __user *src, void *dst, int len,
+                           __wsum sum, int *err)
+  {
+       register unsigned long ret asm("o0") = (unsigned long)src;
+       register char *d asm("o1") = dst;
+       register int l asm("g1") = len;
+       register __wsum s asm("g7") = sum;
+
+       __asm__ __volatile__ (
+       ".section __ex_table,#alloc\n\t"
+       ".align 4\n\t"
+       ".word 1f,2\n\t"
+       ".previous\n"
+       "1:\n\t"
+       "call __csum_partial_copy_sparc_generic\n\t"
+       " st %8, [%%sp + 64]\n"
+       : "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
+       : "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
+       : "o2", "o3", "o4", "o5", "o7", "g2", "g3", "g4", "g5",
+         "cc", "memory");
+       return (__force __wsum)ret;
+}
+
+static inline __wsum
+csum_partial_copy_to_user(const void *src, void __user *dst, int len,
+                         __wsum sum, int *err)
+{
+       if (!access_ok (VERIFY_WRITE, dst, len)) {
+               *err = -EFAULT;
+               return sum;
+       } else {
+               register unsigned long ret asm("o0") = (unsigned long)src;
+               register char __user *d asm("o1") = dst;
+               register int l asm("g1") = len;
+               register __wsum s asm("g7") = sum;
+
+               __asm__ __volatile__ (
+               ".section __ex_table,#alloc\n\t"
+               ".align 4\n\t"
+               ".word 1f,1\n\t"
+               ".previous\n"
+               "1:\n\t"
+               "call __csum_partial_copy_sparc_generic\n\t"
+               " st %8, [%%sp + 64]\n"
+               : "=&r" (ret), "=&r" (d), "=&r" (l), "=&r" (s)
+               : "0" (ret), "1" (d), "2" (l), "3" (s), "r" (err)
+               : "o2", "o3", "o4", "o5", "o7",
+                 "g2", "g3", "g4", "g5",
+                 "cc", "memory");
+               return (__force __wsum)ret;
+       }
+}
+
+#define HAVE_CSUM_COPY_USER
+#define csum_and_copy_to_user csum_partial_copy_to_user
+
+/* ihl is always 5 or greater, almost always is 5, and iph is word aligned
+ * the majority of the time.
+ */
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+       __sum16 sum;
+
+       /* Note: We must read %2 before we touch %0 for the first time,
+        *       because GCC can legitimately use the same register for
+        *       both operands.
+        */
+       __asm__ __volatile__("sub\t%2, 4, %%g4\n\t"
+                            "ld\t[%1 + 0x00], %0\n\t"
+                            "ld\t[%1 + 0x04], %%g2\n\t"
+                            "ld\t[%1 + 0x08], %%g3\n\t"
+                            "addcc\t%%g2, %0, %0\n\t"
+                            "addxcc\t%%g3, %0, %0\n\t"
+                            "ld\t[%1 + 0x0c], %%g2\n\t"
+                            "ld\t[%1 + 0x10], %%g3\n\t"
+                            "addxcc\t%%g2, %0, %0\n\t"
+                            "addx\t%0, %%g0, %0\n"
+                            "1:\taddcc\t%%g3, %0, %0\n\t"
+                            "add\t%1, 4, %1\n\t"
+                            "addxcc\t%0, %%g0, %0\n\t"
+                            "subcc\t%%g4, 1, %%g4\n\t"
+                            "be,a\t2f\n\t"
+                            "sll\t%0, 16, %%g2\n\t"
+                            "b\t1b\n\t"
+                            "ld\t[%1 + 0x10], %%g3\n"
+                            "2:\taddcc\t%0, %%g2, %%g2\n\t"
+                            "srl\t%%g2, 16, %0\n\t"
+                            "addx\t%0, %%g0, %0\n\t"
+                            "xnor\t%%g0, %0, %0"
+                            : "=r" (sum), "=&r" (iph)
+                            : "r" (ihl), "1" (iph)
+                            : "g2", "g3", "g4", "cc", "memory");
+       return sum;
+}
+
+/* Fold a partial checksum without adding pseudo headers. */
+static inline __sum16 csum_fold(__wsum sum)
+{
+       unsigned int tmp;
+
+       __asm__ __volatile__("addcc\t%0, %1, %1\n\t"
+                            "srl\t%1, 16, %1\n\t"
+                            "addx\t%1, %%g0, %1\n\t"
+                            "xnor\t%%g0, %1, %0"
+                            : "=&r" (sum), "=r" (tmp)
+                            : "0" (sum), "1" ((__force u32)sum<<16)
+                            : "cc");
+       return (__force __sum16)sum;
+}
+
+static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
+                                              unsigned short len,
+                                              unsigned short proto,
+                                              __wsum sum)
+{
+       __asm__ __volatile__("addcc\t%1, %0, %0\n\t"
+                            "addxcc\t%2, %0, %0\n\t"
+                            "addxcc\t%3, %0, %0\n\t"
+                            "addx\t%0, %%g0, %0\n\t"
+                            : "=r" (sum), "=r" (saddr)
+                            : "r" (daddr), "r" (proto + len), "0" (sum),
+                              "1" (saddr)
+                            : "cc");
+       return sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+                                                  unsigned short len,
+                                                  unsigned short proto,
+                                                  __wsum sum)
+{
+       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+
+static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+                                     const struct in6_addr *daddr,
+                                     __u32 len, unsigned short proto,
+                                     __wsum sum)
+{
+       __asm__ __volatile__ (
+               "addcc  %3, %4, %%g4\n\t"
+               "addxcc %5, %%g4, %%g4\n\t"
+               "ld     [%2 + 0x0c], %%g2\n\t"
+               "ld     [%2 + 0x08], %%g3\n\t"
+               "addxcc %%g2, %%g4, %%g4\n\t"
+               "ld     [%2 + 0x04], %%g2\n\t"
+               "addxcc %%g3, %%g4, %%g4\n\t"
+               "ld     [%2 + 0x00], %%g3\n\t"
+               "addxcc %%g2, %%g4, %%g4\n\t"
+               "ld     [%1 + 0x0c], %%g2\n\t"
+               "addxcc %%g3, %%g4, %%g4\n\t"
+               "ld     [%1 + 0x08], %%g3\n\t"
+               "addxcc %%g2, %%g4, %%g4\n\t"
+               "ld     [%1 + 0x04], %%g2\n\t"
+               "addxcc %%g3, %%g4, %%g4\n\t"
+               "ld     [%1 + 0x00], %%g3\n\t"
+               "addxcc %%g2, %%g4, %%g4\n\t"
+               "addxcc %%g3, %%g4, %0\n\t"
+               "addx   0, %0, %0\n"
+               : "=&r" (sum)
+               : "r" (saddr), "r" (daddr),
+                 "r"(htonl(len)), "r"(htonl(proto)), "r"(sum)
+               : "g2", "g3", "g4", "cc");
+
+       return csum_fold(sum);
+}
+
+/* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */
+static inline __sum16 ip_compute_csum(const void *buff, int len)
+{
+       return csum_fold(csum_partial(buff, len, 0));
+}
+
+#endif /* !(__SPARC_CHECKSUM_H) */
diff --git a/include/asm-sparc/checksum_64.h b/include/asm-sparc/checksum_64.h
new file mode 100644 (file)
index 0000000..019b961
--- /dev/null
@@ -0,0 +1,167 @@
+#ifndef __SPARC64_CHECKSUM_H
+#define __SPARC64_CHECKSUM_H
+
+/*  checksum.h:  IP/UDP/TCP checksum routines on the V9.
+ *
+ *  Copyright(C) 1995 Linus Torvalds
+ *  Copyright(C) 1995 Miguel de Icaza
+ *  Copyright(C) 1996 David S. Miller
+ *  Copyright(C) 1996 Eddie C. Dost
+ *  Copyright(C) 1997 Jakub Jelinek
+ *
+ * derived from:
+ *     Alpha checksum c-code
+ *      ix86 inline assembly
+ *      RFC1071 Computing the Internet Checksum
+ */
+
+#include <linux/in6.h>
+#include <asm/uaccess.h>
+
+/* computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+extern __wsum csum_partial(const void * buff, int len, __wsum sum);
+
+/* the same as csum_partial, but copies from user space while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern __wsum csum_partial_copy_nocheck(const void *src, void *dst,
+                                             int len, __wsum sum);
+
+extern long __csum_partial_copy_from_user(const void __user *src,
+                                         void *dst, int len,
+                                         __wsum sum);
+
+static inline __wsum
+csum_partial_copy_from_user(const void __user *src,
+                           void *dst, int len,
+                           __wsum sum, int *err)
+{
+       long ret = __csum_partial_copy_from_user(src, dst, len, sum);
+       if (ret < 0)
+               *err = -EFAULT;
+       return (__force __wsum) ret;
+}
+
+/*
+ *     Copy and checksum to user
+ */
+#define HAVE_CSUM_COPY_USER
+extern long __csum_partial_copy_to_user(const void *src,
+                                       void __user *dst, int len,
+                                         __wsum sum);
+
+static inline __wsum
+csum_and_copy_to_user(const void *src,
+                     void __user *dst, int len,
+                     __wsum sum, int *err)
+{
+       long ret = __csum_partial_copy_to_user(src, dst, len, sum);
+       if (ret < 0)
+               *err = -EFAULT;
+       return (__force __wsum) ret;
+}
+
+/* ihl is always 5 or greater, almost always is 5, and iph is word aligned
+ * the majority of the time.
+ */
+extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
+
+/* Fold a partial checksum without adding pseudo headers. */
+static inline __sum16 csum_fold(__wsum sum)
+{
+       unsigned int tmp;
+
+       __asm__ __volatile__(
+"      addcc           %0, %1, %1\n"
+"      srl             %1, 16, %1\n"
+"      addc            %1, %%g0, %1\n"
+"      xnor            %%g0, %1, %0\n"
+       : "=&r" (sum), "=r" (tmp)
+       : "0" (sum), "1" ((__force u32)sum<<16)
+       : "cc");
+       return (__force __sum16)sum;
+}
+
+static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
+                                              unsigned int len,
+                                              unsigned short proto,
+                                              __wsum sum)
+{
+       __asm__ __volatile__(
+"      addcc           %1, %0, %0\n"
+"      addccc          %2, %0, %0\n"
+"      addccc          %3, %0, %0\n"
+"      addc            %0, %%g0, %0\n"
+       : "=r" (sum), "=r" (saddr)
+       : "r" (daddr), "r" (proto + len), "0" (sum), "1" (saddr)
+       : "cc");
+       return sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+                                                  unsigned short len,
+                                                  unsigned short proto,
+                                                  __wsum sum)
+{
+       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+
+static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+                                     const struct in6_addr *daddr,
+                                     __u32 len, unsigned short proto,
+                                     __wsum sum)
+{
+       __asm__ __volatile__ (
+"      addcc           %3, %4, %%g7\n"
+"      addccc          %5, %%g7, %%g7\n"
+"      lduw            [%2 + 0x0c], %%g2\n"
+"      lduw            [%2 + 0x08], %%g3\n"
+"      addccc          %%g2, %%g7, %%g7\n"
+"      lduw            [%2 + 0x04], %%g2\n"
+"      addccc          %%g3, %%g7, %%g7\n"
+"      lduw            [%2 + 0x00], %%g3\n"
+"      addccc          %%g2, %%g7, %%g7\n"
+"      lduw            [%1 + 0x0c], %%g2\n"
+"      addccc          %%g3, %%g7, %%g7\n"
+"      lduw            [%1 + 0x08], %%g3\n"
+"      addccc          %%g2, %%g7, %%g7\n"
+"      lduw            [%1 + 0x04], %%g2\n"
+"      addccc          %%g3, %%g7, %%g7\n"
+"      lduw            [%1 + 0x00], %%g3\n"
+"      addccc          %%g2, %%g7, %%g7\n"
+"      addccc          %%g3, %%g7, %0\n"
+"      addc            0, %0, %0\n"
+       : "=&r" (sum)
+       : "r" (saddr), "r" (daddr), "r"(htonl(len)),
+         "r"(htonl(proto)), "r"(sum)
+       : "g2", "g3", "g7", "cc");
+
+       return csum_fold(sum);
+}
+
+/* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */
+static inline __sum16 ip_compute_csum(const void *buff, int len)
+{
+       return csum_fold(csum_partial(buff, len, 0));
+}
+
+#endif /* !(__SPARC64_CHECKSUM_H) */
diff --git a/include/asm-sparc/chmctrl.h b/include/asm-sparc/chmctrl.h
new file mode 100644 (file)
index 0000000..859b4a4
--- /dev/null
@@ -0,0 +1,183 @@
+#ifndef _SPARC64_CHMCTRL_H
+#define _SPARC64_CHMCTRL_H
+
+/* Cheetah memory controller programmable registers. */
+#define CHMCTRL_TCTRL1         0x00 /* Memory Timing Control I         */
+#define CHMCTRL_TCTRL2         0x08 /* Memory Timing Control II        */
+#define CHMCTRL_TCTRL3         0x38 /* Memory Timing Control III       */
+#define CHMCTRL_TCTRL4         0x40 /* Memory Timing Control IV        */
+#define CHMCTRL_DECODE1                0x10 /* Memory Address Decode I         */
+#define CHMCTRL_DECODE2                0x18 /* Memory Address Decode II        */
+#define CHMCTRL_DECODE3                0x20 /* Memory Address Decode III       */
+#define CHMCTRL_DECODE4                0x28 /* Memory Address Decode IV        */
+#define CHMCTRL_MACTRL         0x30 /* Memory Address Control          */
+
+/* Memory Timing Control I */
+#define TCTRL1_SDRAMCTL_DLY    0xf000000000000000UL
+#define TCTRL1_SDRAMCTL_DLY_SHIFT     60
+#define TCTRL1_SDRAMCLK_DLY    0x0e00000000000000UL
+#define TCTRL1_SDRAMCLK_DLY_SHIFT     57
+#define TCTRL1_R               0x0100000000000000UL
+#define TCTRL1_R_SHIFT                       56
+#define TCTRL1_AUTORFR_CYCLE   0x00fe000000000000UL
+#define TCTRL1_AUTORFR_CYCLE_SHIFT    49
+#define TCTRL1_RD_WAIT         0x0001f00000000000UL
+#define TCTRL1_RD_WAIT_SHIFT         44
+#define TCTRL1_PC_CYCLE                0x00000fc000000000UL
+#define TCTRL1_PC_CYCLE_SHIFT        38
+#define TCTRL1_WR_MORE_RAS_PW  0x0000003f00000000UL
+#define TCTRL1_WR_MORE_RAS_PW_SHIFT   32
+#define TCTRL1_RD_MORE_RAW_PW  0x00000000fc000000UL
+#define TCTRL1_RD_MORE_RAS_PW_SHIFT   26
+#define TCTRL1_ACT_WR_DLY      0x0000000003f00000UL
+#define TCTRL1_ACT_WR_DLY_SHIFT              20
+#define TCTRL1_ACT_RD_DLY      0x00000000000fc000UL
+#define TCTRL1_ACT_RD_DLY_SHIFT              14
+#define TCTRL1_BANK_PRESENT    0x0000000000003000UL
+#define TCTRL1_BANK_PRESENT_SHIFT     12
+#define TCTRL1_RFR_INT         0x0000000000000ff8UL
+#define TCTRL1_RFR_INT_SHIFT         3
+#define TCTRL1_SET_MODE_REG    0x0000000000000004UL
+#define TCTRL1_SET_MODE_REG_SHIFT     2
+#define TCTRL1_RFR_ENABLE      0x0000000000000002UL
+#define TCTRL1_RFR_ENABLE_SHIFT              1
+#define TCTRL1_PRECHG_ALL      0x0000000000000001UL
+#define TCTRL1_PRECHG_ALL_SHIFT              0
+
+/* Memory Timing Control II */
+#define TCTRL2_WR_MSEL_DLY     0xfc00000000000000UL
+#define TCTRL2_WR_MSEL_DLY_SHIFT      58
+#define TCTRL2_RD_MSEL_DLY     0x03f0000000000000UL
+#define TCTRL2_RD_MSEL_DLY_SHIFT      52
+#define TCTRL2_WRDATA_THLD     0x000c000000000000UL
+#define TCTRL2_WRDATA_THLD_SHIFT      50
+#define TCTRL2_RDWR_RD_TI_DLY  0x0003f00000000000UL
+#define TCTRL2_RDWR_RD_TI_DLY_SHIFT   44
+#define TCTRL2_AUTOPRECHG_ENBL 0x0000080000000000UL
+#define TCTRL2_AUTOPRECHG_ENBL_SHIFT  43
+#define TCTRL2_RDWR_PI_MORE_DLY        0x000007c000000000UL
+#define TCTRL2_RDWR_PI_MORE_DLY_SHIFT 38
+#define TCTRL2_RDWR_1_DLY      0x0000003f00000000UL
+#define TCTRL2_RDWR_1_DLY_SHIFT       32
+#define TCTRL2_WRWR_PI_MORE_DLY        0x00000000f8000000UL
+#define TCTRL2_WRWR_PI_MORE_DLY_SHIFT 27
+#define TCTRL2_WRWR_1_DLY      0x0000000007e00000UL
+#define TCTRL2_WRWR_1_DLY_SHIFT       21
+#define TCTRL2_RDWR_RD_PI_MORE_DLY 0x00000000001f0000UL
+#define TCTRL2_RDWR_RD_PI_MORE_DLY_SHIFT 16
+#define TCTRL2_R               0x0000000000008000UL
+#define TCTRL2_R_SHIFT               15
+#define TCTRL2_SDRAM_MODE_REG_DATA 0x0000000000007fffUL
+#define TCTRL2_SDRAM_MODE_REG_DATA_SHIFT 0
+
+/* Memory Timing Control III */
+#define TCTRL3_SDRAM_CTL_DLY   0xf000000000000000UL
+#define TCTRL3_SDRAM_CTL_DLY_SHIFT    60
+#define TCTRL3_SDRAM_CLK_DLY   0x0e00000000000000UL
+#define TCTRL3_SDRAM_CLK_DLY_SHIFT    57
+#define TCTRL3_R               0x0100000000000000UL
+#define TCTRL3_R_SHIFT               56
+#define TCTRL3_AUTO_RFR_CYCLE  0x00fe000000000000UL
+#define TCTRL3_AUTO_RFR_CYCLE_SHIFT   49
+#define TCTRL3_RD_WAIT         0x0001f00000000000UL
+#define TCTRL3_RD_WAIT_SHIFT         44
+#define TCTRL3_PC_CYCLE                0x00000fc000000000UL
+#define TCTRL3_PC_CYCLE_SHIFT        38
+#define TCTRL3_WR_MORE_RAW_PW  0x0000003f00000000UL
+#define TCTRL3_WR_MORE_RAW_PW_SHIFT   32
+#define TCTRL3_RD_MORE_RAW_PW  0x00000000fc000000UL
+#define TCTRL3_RD_MORE_RAW_PW_SHIFT   26
+#define TCTRL3_ACT_WR_DLY      0x0000000003f00000UL
+#define TCTRL3_ACT_WR_DLY_SHIFT       20
+#define TCTRL3_ACT_RD_DLY      0x00000000000fc000UL
+#define TCTRL3_ACT_RD_DLY_SHIFT       14
+#define TCTRL3_BANK_PRESENT    0x0000000000003000UL
+#define TCTRL3_BANK_PRESENT_SHIFT     12
+#define TCTRL3_RFR_INT         0x0000000000000ff8UL
+#define TCTRL3_RFR_INT_SHIFT         3
+#define TCTRL3_SET_MODE_REG    0x0000000000000004UL
+#define TCTRL3_SET_MODE_REG_SHIFT     2
+#define TCTRL3_RFR_ENABLE      0x0000000000000002UL
+#define TCTRL3_RFR_ENABLE_SHIFT       1
+#define TCTRL3_PRECHG_ALL      0x0000000000000001UL
+#define TCTRL3_PRECHG_ALL_SHIFT              0
+
+/* Memory Timing Control IV */
+#define TCTRL4_WR_MSEL_DLY     0xfc00000000000000UL
+#define TCTRL4_WR_MSEL_DLY_SHIFT      58
+#define TCTRL4_RD_MSEL_DLY     0x03f0000000000000UL
+#define TCTRL4_RD_MSEL_DLY_SHIFT      52
+#define TCTRL4_WRDATA_THLD     0x000c000000000000UL
+#define TCTRL4_WRDATA_THLD_SHIFT      50
+#define TCTRL4_RDWR_RD_RI_DLY  0x0003f00000000000UL
+#define TCTRL4_RDWR_RD_RI_DLY_SHIFT   44
+#define TCTRL4_AUTO_PRECHG_ENBL        0x0000080000000000UL
+#define TCTRL4_AUTO_PRECHG_ENBL_SHIFT 43
+#define TCTRL4_RD_WR_PI_MORE_DLY 0x000007c000000000UL
+#define TCTRL4_RD_WR_PI_MORE_DLY_SHIFT 38
+#define TCTRL4_RD_WR_TI_DLY    0x0000003f00000000UL
+#define TCTRL4_RD_WR_TI_DLY_SHIFT     32
+#define TCTRL4_WR_WR_PI_MORE_DLY 0x00000000f8000000UL
+#define TCTRL4_WR_WR_PI_MORE_DLY_SHIFT 27
+#define TCTRL4_WR_WR_TI_DLY    0x0000000007e00000UL
+#define TCTRL4_WR_WR_TI_DLY_SHIFT     21
+#define TCTRL4_RDWR_RD_PI_MORE_DLY 0x00000000001f000UL0
+#define TCTRL4_RDWR_RD_PI_MORE_DLY_SHIFT 16
+#define TCTRL4_R               0x0000000000008000UL
+#define TCTRL4_R_SHIFT               15
+#define TCTRL4_SDRAM_MODE_REG_DATA 0x0000000000007fffUL
+#define TCTRL4_SDRAM_MODE_REG_DATA_SHIFT 0
+
+/* All 4 memory address decoding registers have the
+ * same layout.
+ */
+#define MEM_DECODE_VALID       0x8000000000000000UL /* Valid */
+#define MEM_DECODE_VALID_SHIFT       63
+#define MEM_DECODE_UK          0x001ffe0000000000UL /* Upper mask */
+#define MEM_DECODE_UK_SHIFT          41
+#define MEM_DECODE_UM          0x0000001ffff00000UL /* Upper match */
+#define MEM_DECODE_UM_SHIFT          20
+#define MEM_DECODE_LK          0x000000000003c000UL /* Lower mask */
+#define MEM_DECODE_LK_SHIFT          14
+#define MEM_DECODE_LM          0x0000000000000f00UL /* Lower match */
+#define MEM_DECODE_LM_SHIFT           8
+
+#define PA_UPPER_BITS          0x000007fffc000000UL
+#define PA_UPPER_BITS_SHIFT    26
+#define PA_LOWER_BITS          0x00000000000003c0UL
+#define PA_LOWER_BITS_SHIFT    6
+
+#define MACTRL_R0                       0x8000000000000000UL
+#define MACTRL_R0_SHIFT                         63
+#define MACTRL_ADDR_LE_PW                0x7000000000000000UL
+#define MACTRL_ADDR_LE_PW_SHIFT                 60
+#define MACTRL_CMD_PW                    0x0f00000000000000UL
+#define MACTRL_CMD_PW_SHIFT             56
+#define MACTRL_HALF_MODE_WR_MSEL_DLY     0x00fc000000000000UL
+#define MACTRL_HALF_MODE_WR_MSEL_DLY_SHIFT 50
+#define MACTRL_HALF_MODE_RD_MSEL_DLY     0x0003f00000000000UL
+#define MACTRL_HALF_MODE_RD_MSEL_DLY_SHIFT 44
+#define MACTRL_HALF_MODE_SDRAM_CTL_DLY   0x00000f0000000000UL
+#define MACTRL_HALF_MODE_SDRAM_CTL_DLY_SHIFT 40
+#define MACTRL_HALF_MODE_SDRAM_CLK_DLY   0x000000e000000000UL
+#define MACTRL_HALF_MODE_SDRAM_CLK_DLY_SHIFT 37
+#define MACTRL_R1                        0x0000001000000000UL
+#define MACTRL_R1_SHIFT                      36
+#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B3 0x0000000f00000000UL
+#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B3_SHIFT 32
+#define MACTRL_ENC_INTLV_B3              0x00000000f8000000UL
+#define MACTRL_ENC_INTLV_B3_SHIFT              27
+#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B2 0x0000000007800000UL
+#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B2_SHIFT 23
+#define MACTRL_ENC_INTLV_B2              0x00000000007c0000UL
+#define MACTRL_ENC_INTLV_B2_SHIFT              18
+#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B1 0x000000000003c000UL
+#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B1_SHIFT 14
+#define MACTRL_ENC_INTLV_B1              0x0000000000003e00UL
+#define MACTRL_ENC_INTLV_B1_SHIFT               9
+#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B0 0x00000000000001e0UL
+#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B0_SHIFT  5
+#define MACTRL_ENC_INTLV_B0              0x000000000000001fUL
+#define MACTRL_ENC_INTLV_B0_SHIFT               0
+
+#endif /* _SPARC64_CHMCTRL_H */
diff --git a/include/asm-sparc/cmt.h b/include/asm-sparc/cmt.h
new file mode 100644 (file)
index 0000000..870db59
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef _SPARC64_CMT_H
+#define _SPARC64_CMT_H
+
+/* cmt.h: Chip Multi-Threading register definitions
+ *
+ * Copyright (C) 2004 David S. Miller (davem@redhat.com)
+ */
+
+/* ASI_CORE_ID - private */
+#define LP_ID          0x0000000000000010UL
+#define  LP_ID_MAX     0x00000000003f0000UL
+#define  LP_ID_ID      0x000000000000003fUL
+
+/* ASI_INTR_ID - private */
+#define LP_INTR_ID     0x0000000000000000UL
+#define  LP_INTR_ID_ID 0x00000000000003ffUL
+
+/* ASI_CESR_ID - private */
+#define CESR_ID                0x0000000000000040UL
+#define  CESR_ID_ID    0x00000000000000ffUL
+
+/* ASI_CORE_AVAILABLE - shared */
+#define LP_AVAIL       0x0000000000000000UL
+#define  LP_AVAIL_1    0x0000000000000002UL
+#define  LP_AVAIL_0    0x0000000000000001UL
+
+/* ASI_CORE_ENABLE_STATUS - shared */
+#define LP_ENAB_STAT   0x0000000000000010UL
+#define  LP_ENAB_STAT_1        0x0000000000000002UL
+#define  LP_ENAB_STAT_0        0x0000000000000001UL
+
+/* ASI_CORE_ENABLE - shared */
+#define LP_ENAB                0x0000000000000020UL
+#define  LP_ENAB_1     0x0000000000000002UL
+#define  LP_ENAB_0     0x0000000000000001UL
+
+/* ASI_CORE_RUNNING - shared */
+#define LP_RUNNING_RW  0x0000000000000050UL
+#define LP_RUNNING_W1S 0x0000000000000060UL
+#define LP_RUNNING_W1C 0x0000000000000068UL
+#define  LP_RUNNING_1  0x0000000000000002UL
+#define  LP_RUNNING_0  0x0000000000000001UL
+
+/* ASI_CORE_RUNNING_STAT - shared */
+#define LP_RUN_STAT    0x0000000000000058UL
+#define  LP_RUN_STAT_1 0x0000000000000002UL
+#define  LP_RUN_STAT_0 0x0000000000000001UL
+
+/* ASI_XIR_STEERING - shared */
+#define LP_XIR_STEER   0x0000000000000030UL
+#define  LP_XIR_STEER_1        0x0000000000000002UL
+#define  LP_XIR_STEER_0        0x0000000000000001UL
+
+/* ASI_CMT_ERROR_STEERING - shared */
+#define CMT_ER_STEER   0x0000000000000040UL
+#define  CMT_ER_STEER_1        0x0000000000000002UL
+#define  CMT_ER_STEER_0        0x0000000000000001UL
+
+#endif /* _SPARC64_CMT_H */
diff --git a/include/asm-sparc/compat.h b/include/asm-sparc/compat.h
new file mode 100644 (file)
index 0000000..f260b58
--- /dev/null
@@ -0,0 +1,243 @@
+#ifndef _ASM_SPARC64_COMPAT_H
+#define _ASM_SPARC64_COMPAT_H
+/*
+ * Architecture specific compatibility types
+ */
+#include <linux/types.h>
+
+#define COMPAT_USER_HZ 100
+
+typedef u32            compat_size_t;
+typedef s32            compat_ssize_t;
+typedef s32            compat_time_t;
+typedef s32            compat_clock_t;
+typedef s32            compat_pid_t;
+typedef u16            __compat_uid_t;
+typedef u16            __compat_gid_t;
+typedef u32            __compat_uid32_t;
+typedef u32            __compat_gid32_t;
+typedef u16            compat_mode_t;
+typedef u32            compat_ino_t;
+typedef u16            compat_dev_t;
+typedef s32            compat_off_t;
+typedef s64            compat_loff_t;
+typedef s16            compat_nlink_t;
+typedef u16            compat_ipc_pid_t;
+typedef s32            compat_daddr_t;
+typedef u32            compat_caddr_t;
+typedef __kernel_fsid_t        compat_fsid_t;
+typedef s32            compat_key_t;
+typedef s32            compat_timer_t;
+
+typedef s32            compat_int_t;
+typedef s32            compat_long_t;
+typedef s64            compat_s64;
+typedef u32            compat_uint_t;
+typedef u32            compat_ulong_t;
+typedef u64            compat_u64;
+
+struct compat_timespec {
+       compat_time_t   tv_sec;
+       s32             tv_nsec;
+};
+
+struct compat_timeval {
+       compat_time_t   tv_sec;
+       s32             tv_usec;
+};
+
+struct compat_stat {
+       compat_dev_t    st_dev;
+       compat_ino_t    st_ino;
+       compat_mode_t   st_mode;
+       compat_nlink_t  st_nlink;
+       __compat_uid_t  st_uid;
+       __compat_gid_t  st_gid;
+       compat_dev_t    st_rdev;
+       compat_off_t    st_size;
+       compat_time_t   st_atime;
+       compat_ulong_t  st_atime_nsec;
+       compat_time_t   st_mtime;
+       compat_ulong_t  st_mtime_nsec;
+       compat_time_t   st_ctime;
+       compat_ulong_t  st_ctime_nsec;
+       compat_off_t    st_blksize;
+       compat_off_t    st_blocks;
+       u32             __unused4[2];
+};
+
+struct compat_stat64 {
+       unsigned long long      st_dev;
+
+       unsigned long long      st_ino;
+
+       unsigned int    st_mode;
+       unsigned int    st_nlink;
+
+       unsigned int    st_uid;
+       unsigned int    st_gid;
+
+       unsigned long long      st_rdev;
+
+       unsigned char   __pad3[8];
+
+       long long       st_size;
+       unsigned int    st_blksize;
+
+       unsigned char   __pad4[8];
+       unsigned int    st_blocks;
+
+       unsigned int    st_atime;
+       unsigned int    st_atime_nsec;
+
+       unsigned int    st_mtime;
+       unsigned int    st_mtime_nsec;
+
+       unsigned int    st_ctime;
+       unsigned int    st_ctime_nsec;
+
+       unsigned int    __unused4;
+       unsigned int    __unused5;
+};
+
+struct compat_flock {
+       short           l_type;
+       short           l_whence;
+       compat_off_t    l_start;
+       compat_off_t    l_len;
+       compat_pid_t    l_pid;
+       short           __unused;
+};
+
+#define F_GETLK64      12
+#define F_SETLK64      13
+#define F_SETLKW64     14
+
+struct compat_flock64 {
+       short           l_type;
+       short           l_whence;
+       compat_loff_t   l_start;
+       compat_loff_t   l_len;
+       compat_pid_t    l_pid;
+       short           __unused;
+};
+
+struct compat_statfs {
+       int             f_type;
+       int             f_bsize;
+       int             f_blocks;
+       int             f_bfree;
+       int             f_bavail;
+       int             f_files;
+       int             f_ffree;
+       compat_fsid_t   f_fsid;
+       int             f_namelen;      /* SunOS ignores this field. */
+       int             f_frsize;
+       int             f_spare[5];
+};
+
+#define COMPAT_RLIM_INFINITY 0x7fffffff
+
+typedef u32            compat_old_sigset_t;
+
+#define _COMPAT_NSIG           64
+#define _COMPAT_NSIG_BPW       32
+
+typedef u32            compat_sigset_word;
+
+#define COMPAT_OFF_T_MAX       0x7fffffff
+#define COMPAT_LOFF_T_MAX      0x7fffffffffffffffL
+
+/*
+ * A pointer passed in from user mode. This should not
+ * be used for syscall parameters, just declare them
+ * as pointers because the syscall entry code will have
+ * appropriately converted them already.
+ */
+typedef        u32             compat_uptr_t;
+
+static inline void __user *compat_ptr(compat_uptr_t uptr)
+{
+       return (void __user *)(unsigned long)uptr;
+}
+
+static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+{
+       return (u32)(unsigned long)uptr;
+}
+
+static inline void __user *compat_alloc_user_space(long len)
+{
+       struct pt_regs *regs = current_thread_info()->kregs;
+       unsigned long usp = regs->u_regs[UREG_I6];
+
+       if (!(test_thread_flag(TIF_32BIT)))
+               usp += STACK_BIAS;
+       else
+               usp &= 0xffffffffUL;
+
+       usp -= len;
+       usp &= ~0x7UL;
+
+       return (void __user *) usp;
+}
+
+struct compat_ipc64_perm {
+       compat_key_t key;
+       __compat_uid32_t uid;
+       __compat_gid32_t gid;
+       __compat_uid32_t cuid;
+       __compat_gid32_t cgid;
+       unsigned short __pad1;
+       compat_mode_t mode;
+       unsigned short __pad2;
+       unsigned short seq;
+       unsigned long __unused1;        /* yes they really are 64bit pads */
+       unsigned long __unused2;
+};
+
+struct compat_semid64_ds {
+       struct compat_ipc64_perm sem_perm;
+       unsigned int    __pad1;
+       compat_time_t   sem_otime;
+       unsigned int    __pad2;
+       compat_time_t   sem_ctime;
+       u32             sem_nsems;
+       u32             __unused1;
+       u32             __unused2;
+};
+
+struct compat_msqid64_ds {
+       struct compat_ipc64_perm msg_perm;
+       unsigned int    __pad1;
+       compat_time_t   msg_stime;
+       unsigned int    __pad2;
+       compat_time_t   msg_rtime;
+       unsigned int    __pad3;
+       compat_time_t   msg_ctime;
+       unsigned int    msg_cbytes;
+       unsigned int    msg_qnum;
+       unsigned int    msg_qbytes;
+       compat_pid_t    msg_lspid;
+       compat_pid_t    msg_lrpid;
+       unsigned int    __unused1;
+       unsigned int    __unused2;
+};
+
+struct compat_shmid64_ds {
+       struct compat_ipc64_perm shm_perm;
+       unsigned int    __pad1;
+       compat_time_t   shm_atime;
+       unsigned int    __pad2;
+       compat_time_t   shm_dtime;
+       unsigned int    __pad3;
+       compat_time_t   shm_ctime;
+       compat_size_t   shm_segsz;
+       compat_pid_t    shm_cpid;
+       compat_pid_t    shm_lpid;
+       unsigned int    shm_nattch;
+       unsigned int    __unused1;
+       unsigned int    __unused2;
+};
+
+#endif /* _ASM_SPARC64_COMPAT_H */
diff --git a/include/asm-sparc/compat_signal.h b/include/asm-sparc/compat_signal.h
new file mode 100644 (file)
index 0000000..b759eab
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _COMPAT_SIGNAL_H
+#define _COMPAT_SIGNAL_H
+
+#include <linux/compat.h>
+#include <asm/signal.h>
+
+#ifdef CONFIG_COMPAT
+struct __new_sigaction32 {
+       unsigned                sa_handler;
+       unsigned int            sa_flags;
+       unsigned                sa_restorer;     /* not used by Linux/SPARC yet */
+       compat_sigset_t         sa_mask;
+};
+
+struct __old_sigaction32 {
+       unsigned                sa_handler;
+       compat_old_sigset_t     sa_mask;
+       unsigned int            sa_flags;
+       unsigned                sa_restorer;     /* not used by Linux/SPARC yet */
+};
+
+typedef struct sigaltstack32 {
+       u32                     ss_sp;
+       int                     ss_flags;
+       compat_size_t           ss_size;
+} stack_t32;
+#endif
+
+#endif /* !(_COMPAT_SIGNAL_H) */
index a2c4d51d36c4c478f81dc0ba99a05a8809690137..b76fac0c8d8feb549fcb7d43c9e18ebdb7449933 100644 (file)
@@ -1,27 +1,8 @@
-/* cpudata.h: Per-cpu parameters.
- *
- * Copyright (C) 2004 Keith M Wesolowski (wesolows@foobazco.org)
- *
- * Based on include/asm-sparc64/cpudata.h and Linux 2.4 smp.h
- * both (C) David S. Miller.
- */
-
-#ifndef _SPARC_CPUDATA_H
-#define _SPARC_CPUDATA_H
-
-#include <linux/percpu.h>
-
-typedef struct {
-       unsigned long udelay_val;
-       unsigned long clock_tick;
-       unsigned int multiplier;
-       unsigned int counter;
-       int prom_node;
-       int mid;
-       int next;
-} cpuinfo_sparc;
-
-DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
-#define cpu_data(__cpu) per_cpu(__cpu_data, (__cpu))
-
-#endif /* _SPARC_CPUDATA_H */
+#ifndef ___ASM_SPARC_CPUDATA_H
+#define ___ASM_SPARC_CPUDATA_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/cpudata_64.h>
+#else
+#include <asm-sparc/cpudata_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/cpudata_32.h b/include/asm-sparc/cpudata_32.h
new file mode 100644 (file)
index 0000000..a2c4d51
--- /dev/null
@@ -0,0 +1,27 @@
+/* cpudata.h: Per-cpu parameters.
+ *
+ * Copyright (C) 2004 Keith M Wesolowski (wesolows@foobazco.org)
+ *
+ * Based on include/asm-sparc64/cpudata.h and Linux 2.4 smp.h
+ * both (C) David S. Miller.
+ */
+
+#ifndef _SPARC_CPUDATA_H
+#define _SPARC_CPUDATA_H
+
+#include <linux/percpu.h>
+
+typedef struct {
+       unsigned long udelay_val;
+       unsigned long clock_tick;
+       unsigned int multiplier;
+       unsigned int counter;
+       int prom_node;
+       int mid;
+       int next;
+} cpuinfo_sparc;
+
+DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
+#define cpu_data(__cpu) per_cpu(__cpu_data, (__cpu))
+
+#endif /* _SPARC_CPUDATA_H */
diff --git a/include/asm-sparc/cpudata_64.h b/include/asm-sparc/cpudata_64.h
new file mode 100644 (file)
index 0000000..532975e
--- /dev/null
@@ -0,0 +1,240 @@
+/* cpudata.h: Per-cpu parameters.
+ *
+ * Copyright (C) 2003, 2005, 2006 David S. Miller (davem@davemloft.net)
+ */
+
+#ifndef _SPARC64_CPUDATA_H
+#define _SPARC64_CPUDATA_H
+
+#include <asm/hypervisor.h>
+#include <asm/asi.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/percpu.h>
+#include <linux/threads.h>
+
+typedef struct {
+       /* Dcache line 1 */
+       unsigned int    __softirq_pending; /* must be 1st, see rtrap.S */
+       unsigned int    __pad0;
+       unsigned long   clock_tick;     /* %tick's per second */
+       unsigned long   __pad;
+       unsigned int    __pad1;
+       unsigned int    __pad2;
+
+       /* Dcache line 2, rarely used */
+       unsigned int    dcache_size;
+       unsigned int    dcache_line_size;
+       unsigned int    icache_size;
+       unsigned int    icache_line_size;
+       unsigned int    ecache_size;
+       unsigned int    ecache_line_size;
+       int             core_id;
+       int             proc_id;
+} cpuinfo_sparc;
+
+DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
+#define cpu_data(__cpu)                per_cpu(__cpu_data, (__cpu))
+#define local_cpu_data()       __get_cpu_var(__cpu_data)
+
+/* Trap handling code needs to get at a few critical values upon
+ * trap entry and to process TSB misses.  These cannot be in the
+ * per_cpu() area as we really need to lock them into the TLB and
+ * thus make them part of the main kernel image.  As a result we
+ * try to make this as small as possible.
+ *
+ * This is padded out and aligned to 64-bytes to avoid false sharing
+ * on SMP.
+ */
+
+/* If you modify the size of this structure, please update
+ * TRAP_BLOCK_SZ_SHIFT below.
+ */
+struct thread_info;
+struct trap_per_cpu {
+/* D-cache line 1: Basic thread information, cpu and device mondo queues */
+       struct thread_info      *thread;
+       unsigned long           pgd_paddr;
+       unsigned long           cpu_mondo_pa;
+       unsigned long           dev_mondo_pa;
+
+/* D-cache line 2: Error Mondo Queue and kernel buffer pointers */
+       unsigned long           resum_mondo_pa;
+       unsigned long           resum_kernel_buf_pa;
+       unsigned long           nonresum_mondo_pa;
+       unsigned long           nonresum_kernel_buf_pa;
+
+/* Dcache lines 3, 4, 5, and 6: Hypervisor Fault Status */
+       struct hv_fault_status  fault_info;
+
+/* Dcache line 7: Physical addresses of CPU send mondo block and CPU list.  */
+       unsigned long           cpu_mondo_block_pa;
+       unsigned long           cpu_list_pa;
+       unsigned long           tsb_huge;
+       unsigned long           tsb_huge_temp;
+
+/* Dcache line 8: IRQ work list, and keep trap_block a power-of-2 in size.  */
+       unsigned long           irq_worklist_pa;
+       unsigned int            cpu_mondo_qmask;
+       unsigned int            dev_mondo_qmask;
+       unsigned int            resum_qmask;
+       unsigned int            nonresum_qmask;
+       void                    *hdesc;
+} __attribute__((aligned(64)));
+extern struct trap_per_cpu trap_block[NR_CPUS];
+extern void init_cur_cpu_trap(struct thread_info *);
+extern void setup_tba(void);
+extern int ncpus_probed;
+extern void __init cpu_probe(void);
+extern const struct seq_operations cpuinfo_op;
+
+extern unsigned long real_hard_smp_processor_id(void);
+
+struct cpuid_patch_entry {
+       unsigned int    addr;
+       unsigned int    cheetah_safari[4];
+       unsigned int    cheetah_jbus[4];
+       unsigned int    starfire[4];
+       unsigned int    sun4v[4];
+};
+extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end;
+
+struct sun4v_1insn_patch_entry {
+       unsigned int    addr;
+       unsigned int    insn;
+};
+extern struct sun4v_1insn_patch_entry __sun4v_1insn_patch,
+       __sun4v_1insn_patch_end;
+
+struct sun4v_2insn_patch_entry {
+       unsigned int    addr;
+       unsigned int    insns[2];
+};
+extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
+       __sun4v_2insn_patch_end;
+
+#endif /* !(__ASSEMBLY__) */
+
+#define TRAP_PER_CPU_THREAD            0x00
+#define TRAP_PER_CPU_PGD_PADDR         0x08
+#define TRAP_PER_CPU_CPU_MONDO_PA      0x10
+#define TRAP_PER_CPU_DEV_MONDO_PA      0x18
+#define TRAP_PER_CPU_RESUM_MONDO_PA    0x20
+#define TRAP_PER_CPU_RESUM_KBUF_PA     0x28
+#define TRAP_PER_CPU_NONRESUM_MONDO_PA 0x30
+#define TRAP_PER_CPU_NONRESUM_KBUF_PA  0x38
+#define TRAP_PER_CPU_FAULT_INFO                0x40
+#define TRAP_PER_CPU_CPU_MONDO_BLOCK_PA        0xc0
+#define TRAP_PER_CPU_CPU_LIST_PA       0xc8
+#define TRAP_PER_CPU_TSB_HUGE          0xd0
+#define TRAP_PER_CPU_TSB_HUGE_TEMP     0xd8
+#define TRAP_PER_CPU_IRQ_WORKLIST_PA   0xe0
+#define TRAP_PER_CPU_CPU_MONDO_QMASK   0xe8
+#define TRAP_PER_CPU_DEV_MONDO_QMASK   0xec
+#define TRAP_PER_CPU_RESUM_QMASK       0xf0
+#define TRAP_PER_CPU_NONRESUM_QMASK    0xf4
+
+#define TRAP_BLOCK_SZ_SHIFT            8
+
+#include <asm/scratchpad.h>
+
+#define __GET_CPUID(REG)                               \
+       /* Spitfire implementation (default). */        \
+661:   ldxa            [%g0] ASI_UPA_CONFIG, REG;      \
+       srlx            REG, 17, REG;                   \
+        and            REG, 0x1f, REG;                 \
+       nop;                                            \
+       .section        .cpuid_patch, "ax";             \
+       /* Instruction location. */                     \
+       .word           661b;                           \
+       /* Cheetah Safari implementation. */            \
+       ldxa            [%g0] ASI_SAFARI_CONFIG, REG;   \
+       srlx            REG, 17, REG;                   \
+       and             REG, 0x3ff, REG;                \
+       nop;                                            \
+       /* Cheetah JBUS implementation. */              \
+       ldxa            [%g0] ASI_JBUS_CONFIG, REG;     \
+       srlx            REG, 17, REG;                   \
+       and             REG, 0x1f, REG;                 \
+       nop;                                            \
+       /* Starfire implementation. */                  \
+       sethi           %hi(0x1fff40000d0 >> 9), REG;   \
+       sllx            REG, 9, REG;                    \
+       or              REG, 0xd0, REG;                 \
+       lduwa           [REG] ASI_PHYS_BYPASS_EC_E, REG;\
+       /* sun4v implementation. */                     \
+       mov             SCRATCHPAD_CPUID, REG;          \
+       ldxa            [REG] ASI_SCRATCHPAD, REG;      \
+       nop;                                            \
+       nop;                                            \
+       .previous;
+
+#ifdef CONFIG_SMP
+
+#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP)                \
+       __GET_CPUID(TMP)                        \
+       sethi   %hi(trap_block), DEST;          \
+       sllx    TMP, TRAP_BLOCK_SZ_SHIFT, TMP;  \
+       or      DEST, %lo(trap_block), DEST;    \
+       add     DEST, TMP, DEST;                \
+
+/* Clobbers TMP, current address space PGD phys address into DEST.  */
+#define TRAP_LOAD_PGD_PHYS(DEST, TMP)          \
+       TRAP_LOAD_TRAP_BLOCK(DEST, TMP)         \
+       ldx     [DEST + TRAP_PER_CPU_PGD_PADDR], DEST;
+
+/* Clobbers TMP, loads local processor's IRQ work area into DEST.  */
+#define TRAP_LOAD_IRQ_WORK_PA(DEST, TMP)       \
+       TRAP_LOAD_TRAP_BLOCK(DEST, TMP)         \
+       add     DEST, TRAP_PER_CPU_IRQ_WORKLIST_PA, DEST;
+
+/* Clobbers TMP, loads DEST with current thread info pointer.  */
+#define TRAP_LOAD_THREAD_REG(DEST, TMP)                \
+       TRAP_LOAD_TRAP_BLOCK(DEST, TMP)         \
+       ldx     [DEST + TRAP_PER_CPU_THREAD], DEST;
+
+/* Given the current thread info pointer in THR, load the per-cpu
+ * area base of the current processor into DEST.  REG1, REG2, and REG3 are
+ * clobbered.
+ *
+ * You absolutely cannot use DEST as a temporary in this code.  The
+ * reason is that traps can happen during execution, and return from
+ * trap will load the fully resolved DEST per-cpu base.  This can corrupt
+ * the calculations done by the macro mid-stream.
+ */
+#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) \
+       lduh    [THR + TI_CPU], REG1;                   \
+       sethi   %hi(__per_cpu_shift), REG3;             \
+       sethi   %hi(__per_cpu_base), REG2;              \
+       ldx     [REG3 + %lo(__per_cpu_shift)], REG3;    \
+       ldx     [REG2 + %lo(__per_cpu_base)], REG2;     \
+       sllx    REG1, REG3, REG3;                       \
+       add     REG3, REG2, DEST;
+
+#else
+
+#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP)                \
+       sethi   %hi(trap_block), DEST;          \
+       or      DEST, %lo(trap_block), DEST;    \
+
+/* Uniprocessor versions, we know the cpuid is zero.  */
+#define TRAP_LOAD_PGD_PHYS(DEST, TMP)          \
+       TRAP_LOAD_TRAP_BLOCK(DEST, TMP)         \
+       ldx     [DEST + TRAP_PER_CPU_PGD_PADDR], DEST;
+
+/* Clobbers TMP, loads local processor's IRQ work area into DEST.  */
+#define TRAP_LOAD_IRQ_WORK_PA(DEST, TMP)       \
+       TRAP_LOAD_TRAP_BLOCK(DEST, TMP)         \
+       add     DEST, TRAP_PER_CPU_IRQ_WORKLIST_PA, DEST;
+
+#define TRAP_LOAD_THREAD_REG(DEST, TMP)                \
+       TRAP_LOAD_TRAP_BLOCK(DEST, TMP)         \
+       ldx     [DEST + TRAP_PER_CPU_THREAD], DEST;
+
+/* No per-cpu areas on uniprocessor, so no need to load DEST.  */
+#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3)
+
+#endif /* !(CONFIG_SMP) */
+
+#endif /* _SPARC64_CPUDATA_H */
diff --git a/include/asm-sparc/dcr.h b/include/asm-sparc/dcr.h
new file mode 100644 (file)
index 0000000..620c9ba
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _SPARC64_DCR_H
+#define _SPARC64_DCR_H
+
+/* UltraSparc-III/III+ Dispatch Control Register, ASR 0x12 */
+#define DCR_DPE                0x0000000000001000 /* III+: D$ Parity Error Enable      */
+#define DCR_OBS                0x0000000000000fc0 /* Observability Bus Controls        */
+#define DCR_BPE                0x0000000000000020 /* Branch Predict Enable             */
+#define DCR_RPE                0x0000000000000010 /* Return Address Prediction Enable  */
+#define DCR_SI         0x0000000000000008 /* Single Instruction Disable        */
+#define DCR_IPE                0x0000000000000004 /* III+: I$ Parity Error Enable      */
+#define DCR_IFPOE      0x0000000000000002 /* IRQ FP Operation Enable           */
+#define DCR_MS         0x0000000000000001 /* Multi-Scalar dispatch             */
+
+#endif /* _SPARC64_DCR_H */
diff --git a/include/asm-sparc/dcu.h b/include/asm-sparc/dcu.h
new file mode 100644 (file)
index 0000000..0f704e1
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _SPARC64_DCU_H
+#define _SPARC64_DCU_H
+
+#include <linux/const.h>
+
+/* UltraSparc-III Data Cache Unit Control Register */
+#define DCU_CP _AC(0x0002000000000000,UL) /* Phys Cache Enable w/o mmu */
+#define DCU_CV _AC(0x0001000000000000,UL) /* Virt Cache Enable w/o mmu */
+#define DCU_ME _AC(0x0000800000000000,UL) /* NC-store Merging Enable   */
+#define DCU_RE _AC(0x0000400000000000,UL) /* RAW bypass Enable         */
+#define DCU_PE _AC(0x0000200000000000,UL) /* PCache Enable             */
+#define DCU_HPE        _AC(0x0000100000000000,UL) /* HW prefetch Enable        */
+#define DCU_SPE        _AC(0x0000080000000000,UL) /* SW prefetch Enable        */
+#define DCU_SL _AC(0x0000040000000000,UL) /* Secondary ld-steering Enab*/
+#define DCU_WE _AC(0x0000020000000000,UL) /* WCache enable             */
+#define DCU_PM _AC(0x000001fe00000000,UL) /* PA Watchpoint Byte Mask   */
+#define DCU_VM _AC(0x00000001fe000000,UL) /* VA Watchpoint Byte Mask   */
+#define DCU_PR _AC(0x0000000001000000,UL) /* PA Watchpoint Read Enable */
+#define DCU_PW _AC(0x0000000000800000,UL) /* PA Watchpoint Write Enable*/
+#define DCU_VR _AC(0x0000000000400000,UL) /* VA Watchpoint Read Enable */
+#define DCU_VW _AC(0x0000000000200000,UL) /* VA Watchpoint Write Enable*/
+#define DCU_DM _AC(0x0000000000000008,UL) /* DMMU Enable               */
+#define DCU_IM _AC(0x0000000000000004,UL) /* IMMU Enable               */
+#define DCU_DC _AC(0x0000000000000002,UL) /* Data Cache Enable         */
+#define DCU_IC _AC(0x0000000000000001,UL) /* Instruction Cache Enable  */
+
+#endif /* _SPARC64_DCU_H */
index bc9aba2bead6060744c3f995054be3bfe72e1ee7..6210a3ce97517860de53a9b1823a4eaa5b56e871 100644 (file)
@@ -1,34 +1,8 @@
-/*
- * delay.h: Linux delay routines on the Sparc.
- *
- * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu).
- */
-
-#ifndef __SPARC_DELAY_H
-#define __SPARC_DELAY_H
-
-#include <asm/cpudata.h>
-
-static inline void __delay(unsigned long loops)
-{
-       __asm__ __volatile__("cmp %0, 0\n\t"
-                            "1: bne 1b\n\t"
-                            "subcc %0, 1, %0\n" :
-                            "=&r" (loops) :
-                            "0" (loops) :
-                            "cc");
-}
-
-/* This is too messy with inline asm on the Sparc. */
-extern void __udelay(unsigned long usecs, unsigned long lpj);
-extern void __ndelay(unsigned long nsecs, unsigned long lpj);
-
-#ifdef CONFIG_SMP
-#define __udelay_val   cpu_data(smp_processor_id()).udelay_val
-#else /* SMP */
-#define __udelay_val   loops_per_jiffy
-#endif /* SMP */
-#define udelay(__usecs)        __udelay(__usecs, __udelay_val)
-#define ndelay(__nsecs)        __ndelay(__nsecs, __udelay_val)
-
-#endif /* defined(__SPARC_DELAY_H) */
+#ifndef ___ASM_SPARC_DELAY_H
+#define ___ASM_SPARC_DELAY_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/delay_64.h>
+#else
+#include <asm-sparc/delay_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/delay_32.h b/include/asm-sparc/delay_32.h
new file mode 100644 (file)
index 0000000..bc9aba2
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * delay.h: Linux delay routines on the Sparc.
+ *
+ * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu).
+ */
+
+#ifndef __SPARC_DELAY_H
+#define __SPARC_DELAY_H
+
+#include <asm/cpudata.h>
+
+static inline void __delay(unsigned long loops)
+{
+       __asm__ __volatile__("cmp %0, 0\n\t"
+                            "1: bne 1b\n\t"
+                            "subcc %0, 1, %0\n" :
+                            "=&r" (loops) :
+                            "0" (loops) :
+                            "cc");
+}
+
+/* This is too messy with inline asm on the Sparc. */
+extern void __udelay(unsigned long usecs, unsigned long lpj);
+extern void __ndelay(unsigned long nsecs, unsigned long lpj);
+
+#ifdef CONFIG_SMP
+#define __udelay_val   cpu_data(smp_processor_id()).udelay_val
+#else /* SMP */
+#define __udelay_val   loops_per_jiffy
+#endif /* SMP */
+#define udelay(__usecs)        __udelay(__usecs, __udelay_val)
+#define ndelay(__nsecs)        __ndelay(__nsecs, __udelay_val)
+
+#endif /* defined(__SPARC_DELAY_H) */
diff --git a/include/asm-sparc/delay_64.h b/include/asm-sparc/delay_64.h
new file mode 100644 (file)
index 0000000..a77aa62
--- /dev/null
@@ -0,0 +1,17 @@
+/* delay.h: Linux delay routines on sparc64.
+ *
+ * Copyright (C) 1996, 2004, 2007 David S. Miller (davem@davemloft.net).
+ */
+
+#ifndef _SPARC64_DELAY_H
+#define _SPARC64_DELAY_H
+
+#ifndef __ASSEMBLY__
+
+extern void __delay(unsigned long loops);
+extern void udelay(unsigned long usecs);
+#define mdelay(n)      udelay((n) * 1000)
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _SPARC64_DELAY_H */
diff --git a/include/asm-sparc/display7seg.h b/include/asm-sparc/display7seg.h
new file mode 100644 (file)
index 0000000..86d4a90
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *
+ * display7seg - Driver interface for the 7-segment display
+ * present on Sun Microsystems CP1400 and CP1500
+ *
+ * Copyright (c) 2000 Eric Brower <ebrower@usa.net>
+ *
+ */
+
+#ifndef __display7seg_h__
+#define __display7seg_h__
+
+#define D7S_IOC        'p'
+
+#define D7SIOCRD _IOR(D7S_IOC, 0x45, int)      /* Read device state    */
+#define D7SIOCWR _IOW(D7S_IOC, 0x46, int)      /* Write device state   */
+#define D7SIOCTM _IO (D7S_IOC, 0x47)           /* Translate mode (FLIP)*/
+
+/*
+ * ioctl flag definitions
+ *
+ * POINT       - Toggle decimal point  (0=absent 1=present)
+ * ALARM       - Toggle alarm LED              (0=green  1=red)
+ * FLIP                - Toggle inverted mode  (0=normal 1=flipped)
+ * bits 0-4    - Character displayed   (see definitions below)
+ *
+ * Display segments are defined as follows,
+ * subject to D7S_FLIP register state:
+ *
+ *    a
+ *   ---
+ * f|   |b
+ *   -g-
+ * e|   |c
+ *   ---
+ *    d
+ */
+
+#define D7S_POINT      (1 << 7)        /* Decimal point*/
+#define D7S_ALARM      (1 << 6)        /* Alarm LED    */
+#define D7S_FLIP       (1 << 5)        /* Flip display */
+
+#define D7S_0          0x00            /* Numerals 0-9 */
+#define D7S_1          0x01
+#define D7S_2          0x02
+#define D7S_3          0x03
+#define D7S_4          0x04
+#define D7S_5          0x05
+#define D7S_6          0x06
+#define D7S_7          0x07
+#define D7S_8          0x08
+#define D7S_9          0x09
+#define D7S_A          0x0A            /* Letters A-F, H, L, P */
+#define D7S_B          0x0B
+#define D7S_C          0x0C
+#define D7S_D          0x0D
+#define D7S_E          0x0E
+#define D7S_F          0x0F
+#define D7S_H          0x10
+#define D7S_E2         0x11
+#define D7S_L          0x12
+#define D7S_P          0x13
+#define D7S_SEGA       0x14            /* Individual segments */
+#define D7S_SEGB       0x15
+#define D7S_SEGC       0x16
+#define D7S_SEGD       0x17
+#define D7S_SEGE       0x18
+#define D7S_SEGF       0x19
+#define D7S_SEGG       0x1A
+#define D7S_SEGABFG 0x1B               /* Segment groupings */
+#define D7S_SEGCDEG    0x1C
+#define D7S_SEGBCEF 0x1D
+#define D7S_SEGADG     0x1E
+#define D7S_BLANK      0x1F            /* Clear all segments */
+
+#define D7S_MIN_VAL    0x0
+#define D7S_MAX_VAL    0x1F
+
+#endif /* ifndef __display7seg_h__ */
index f3a641e6b2c88645cc09852923d1804bba410546..7483504259cef140dd187a87af7025a18d689486 100644 (file)
@@ -1,11 +1,8 @@
-#ifndef _ASM_SPARC_DMA_MAPPING_H
-#define _ASM_SPARC_DMA_MAPPING_H
-
-
-#ifdef CONFIG_PCI
-#include <asm-generic/dma-mapping.h>
+#ifndef ___ASM_SPARC_DMA_MAPPING_H
+#define ___ASM_SPARC_DMA_MAPPING_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/dma-mapping_64.h>
 #else
-#include <asm-generic/dma-mapping-broken.h>
-#endif /* PCI */
-
-#endif /* _ASM_SPARC_DMA_MAPPING_H */
+#include <asm-sparc/dma-mapping_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/dma-mapping_32.h b/include/asm-sparc/dma-mapping_32.h
new file mode 100644 (file)
index 0000000..f3a641e
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _ASM_SPARC_DMA_MAPPING_H
+#define _ASM_SPARC_DMA_MAPPING_H
+
+
+#ifdef CONFIG_PCI
+#include <asm-generic/dma-mapping.h>
+#else
+#include <asm-generic/dma-mapping-broken.h>
+#endif /* PCI */
+
+#endif /* _ASM_SPARC_DMA_MAPPING_H */
diff --git a/include/asm-sparc/dma-mapping_64.h b/include/asm-sparc/dma-mapping_64.h
new file mode 100644 (file)
index 0000000..38cbec7
--- /dev/null
@@ -0,0 +1,154 @@
+#ifndef _ASM_SPARC64_DMA_MAPPING_H
+#define _ASM_SPARC64_DMA_MAPPING_H
+
+#include <linux/scatterlist.h>
+#include <linux/mm.h>
+
+#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
+
+struct dma_ops {
+       void *(*alloc_coherent)(struct device *dev, size_t size,
+                               dma_addr_t *dma_handle, gfp_t flag);
+       void (*free_coherent)(struct device *dev, size_t size,
+                             void *cpu_addr, dma_addr_t dma_handle);
+       dma_addr_t (*map_single)(struct device *dev, void *cpu_addr,
+                                size_t size,
+                                enum dma_data_direction direction);
+       void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
+                            size_t size,
+                            enum dma_data_direction direction);
+       int (*map_sg)(struct device *dev, struct scatterlist *sg, int nents,
+                     enum dma_data_direction direction);
+       void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
+                        int nhwentries,
+                        enum dma_data_direction direction);
+       void (*sync_single_for_cpu)(struct device *dev,
+                                   dma_addr_t dma_handle, size_t size,
+                                   enum dma_data_direction direction);
+       void (*sync_sg_for_cpu)(struct device *dev, struct scatterlist *sg,
+                               int nelems,
+                               enum dma_data_direction direction);
+};
+extern const struct dma_ops *dma_ops;
+
+extern int dma_supported(struct device *dev, u64 mask);
+extern int dma_set_mask(struct device *dev, u64 dma_mask);
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+                                      dma_addr_t *dma_handle, gfp_t flag)
+{
+       return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+                                    void *cpu_addr, dma_addr_t dma_handle)
+{
+       dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
+}
+
+static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
+                                       size_t size,
+                                       enum dma_data_direction direction)
+{
+       return dma_ops->map_single(dev, cpu_addr, size, direction);
+}
+
+static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
+                                   size_t size,
+                                   enum dma_data_direction direction)
+{
+       dma_ops->unmap_single(dev, dma_addr, size, direction);
+}
+
+static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
+                                     unsigned long offset, size_t size,
+                                     enum dma_data_direction direction)
+{
+       return dma_ops->map_single(dev, page_address(page) + offset,
+                                  size, direction);
+}
+
+static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
+                                 size_t size,
+                                 enum dma_data_direction direction)
+{
+       dma_ops->unmap_single(dev, dma_address, size, direction);
+}
+
+static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
+                            int nents, enum dma_data_direction direction)
+{
+       return dma_ops->map_sg(dev, sg, nents, direction);
+}
+
+static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+                               int nents, enum dma_data_direction direction)
+{
+       dma_ops->unmap_sg(dev, sg, nents, direction);
+}
+
+static inline void dma_sync_single_for_cpu(struct device *dev,
+                                          dma_addr_t dma_handle, size_t size,
+                                          enum dma_data_direction direction)
+{
+       dma_ops->sync_single_for_cpu(dev, dma_handle, size, direction);
+}
+
+static inline void dma_sync_single_for_device(struct device *dev,
+                                             dma_addr_t dma_handle,
+                                             size_t size,
+                                             enum dma_data_direction direction)
+{
+       /* No flushing needed to sync cpu writes to the device.  */
+}
+
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+                                                dma_addr_t dma_handle,
+                                                unsigned long offset,
+                                                size_t size,
+                                                enum dma_data_direction direction)
+{
+       dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction);
+}
+
+static inline void dma_sync_single_range_for_device(struct device *dev,
+                                                   dma_addr_t dma_handle,
+                                                   unsigned long offset,
+                                                   size_t size,
+                                                   enum dma_data_direction direction)
+{
+       /* No flushing needed to sync cpu writes to the device.  */
+}
+
+
+static inline void dma_sync_sg_for_cpu(struct device *dev,
+                                      struct scatterlist *sg, int nelems,
+                                      enum dma_data_direction direction)
+{
+       dma_ops->sync_sg_for_cpu(dev, sg, nelems, direction);
+}
+
+static inline void dma_sync_sg_for_device(struct device *dev,
+                                         struct scatterlist *sg, int nelems,
+                                         enum dma_data_direction direction)
+{
+       /* No flushing needed to sync cpu writes to the device.  */
+}
+
+static inline int dma_mapping_error(dma_addr_t dma_addr)
+{
+       return (dma_addr == DMA_ERROR_CODE);
+}
+
+static inline int dma_get_cache_alignment(void)
+{
+       /* no easy way to get cache size on all processors, so return
+        * the maximum possible, to be safe */
+       return (1 << INTERNODE_CACHE_SHIFT);
+}
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_is_consistent(d, h)        (1)
+
+#endif /* _ASM_SPARC64_DMA_MAPPING_H */
index 959d6c8a71ae72365f6d33e2c1921bebbe012317..8cc69bfaae2ab8459433dadaf6a10ce1e20eae65 100644 (file)
@@ -1,288 +1,8 @@
-/* include/asm-sparc/dma.h
- *
- * Copyright 1995 (C) David S. Miller (davem@davemloft.net)
- */
-
-#ifndef _ASM_SPARC_DMA_H
-#define _ASM_SPARC_DMA_H
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-#include <asm/vac-ops.h>  /* for invalidate's, etc. */
-#include <asm/sbus.h>
-#include <asm/delay.h>
-#include <asm/oplib.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <linux/spinlock.h>
-
-struct page;
-extern spinlock_t  dma_spin_lock;
-
-static inline unsigned long claim_dma_lock(void)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&dma_spin_lock, flags);
-       return flags;
-}
-
-static inline void release_dma_lock(unsigned long flags)
-{
-       spin_unlock_irqrestore(&dma_spin_lock, flags);
-}
-
-/* These are irrelevant for Sparc DMA, but we leave it in so that
- * things can compile.
- */
-#define MAX_DMA_CHANNELS 8
-#define MAX_DMA_ADDRESS  (~0UL)
-#define DMA_MODE_READ    1
-#define DMA_MODE_WRITE   2
-
-/* Useful constants */
-#define SIZE_16MB      (16*1024*1024)
-#define SIZE_64K       (64*1024)
-
-/* SBUS DMA controller reg offsets */
-#define DMA_CSR                0x00UL          /* rw  DMA control/status register    0x00   */
-#define DMA_ADDR       0x04UL          /* rw  DMA transfer address register  0x04   */
-#define DMA_COUNT      0x08UL          /* rw  DMA transfer count register    0x08   */
-#define DMA_TEST       0x0cUL          /* rw  DMA test/debug register        0x0c   */
-
-/* DVMA chip revisions */
-enum dvma_rev {
-       dvmarev0,
-       dvmaesc1,
-       dvmarev1,
-       dvmarev2,
-       dvmarev3,
-       dvmarevplus,
-       dvmahme
-};
-
-#define DMA_HASCOUNT(rev)  ((rev)==dvmaesc1)
-
-/* Linux DMA information structure, filled during probe. */
-struct sbus_dma {
-       struct sbus_dma *next;
-       struct sbus_dev *sdev;
-       void __iomem *regs;
-
-       /* Status, misc info */
-       int node;                /* Prom node for this DMA device */
-       int running;             /* Are we doing DMA now? */
-       int allocated;           /* Are we "owned" by anyone yet? */
-
-       /* Transfer information. */
-       unsigned long addr;      /* Start address of current transfer */
-       int nbytes;              /* Size of current transfer */
-       int realbytes;           /* For splitting up large transfers, etc. */
-
-       /* DMA revision */
-       enum dvma_rev revision;
-};
-
-extern struct sbus_dma *dma_chain;
-
-/* Broken hardware... */
-#ifdef CONFIG_SUN4
-/* Have to sort this out. Does rev0 work fine on sun4[cmd] without isbroken?
- * Or is rev0 present only on sun4 boxes? -jj */
-#define DMA_ISBROKEN(dma)    ((dma)->revision == dvmarev0 || (dma)->revision == dvmarev1)
+#ifndef ___ASM_SPARC_DMA_H
+#define ___ASM_SPARC_DMA_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/dma_64.h>
 #else
-#define DMA_ISBROKEN(dma)    ((dma)->revision == dvmarev1)
+#include <asm-sparc/dma_32.h>
 #endif
-#define DMA_ISESC1(dma)      ((dma)->revision == dvmaesc1)
-
-/* Main routines in dma.c */
-extern void dvma_init(struct sbus_bus *);
-
-/* Fields in the cond_reg register */
-/* First, the version identification bits */
-#define DMA_DEVICE_ID    0xf0000000        /* Device identification bits */
-#define DMA_VERS0        0x00000000        /* Sunray DMA version */
-#define DMA_ESCV1        0x40000000        /* DMA ESC Version 1 */
-#define DMA_VERS1        0x80000000        /* DMA rev 1 */
-#define DMA_VERS2        0xa0000000        /* DMA rev 2 */
-#define DMA_VERHME       0xb0000000        /* DMA hme gate array */
-#define DMA_VERSPLUS     0x90000000        /* DMA rev 1 PLUS */
-
-#define DMA_HNDL_INTR    0x00000001        /* An IRQ needs to be handled */
-#define DMA_HNDL_ERROR   0x00000002        /* We need to take an error */
-#define DMA_FIFO_ISDRAIN 0x0000000c        /* The DMA FIFO is draining */
-#define DMA_INT_ENAB     0x00000010        /* Turn on interrupts */
-#define DMA_FIFO_INV     0x00000020        /* Invalidate the FIFO */
-#define DMA_ACC_SZ_ERR   0x00000040        /* The access size was bad */
-#define DMA_FIFO_STDRAIN 0x00000040        /* DMA_VERS1 Drain the FIFO */
-#define DMA_RST_SCSI     0x00000080        /* Reset the SCSI controller */
-#define DMA_RST_ENET     DMA_RST_SCSI      /* Reset the ENET controller */
-#define DMA_RST_BPP      DMA_RST_SCSI      /* Reset the BPP controller */
-#define DMA_ST_WRITE     0x00000100        /* write from device to memory */
-#define DMA_ENABLE       0x00000200        /* Fire up DMA, handle requests */
-#define DMA_PEND_READ    0x00000400        /* DMA_VERS1/0/PLUS Pending Read */
-#define DMA_ESC_BURST    0x00000800        /* 1=16byte 0=32byte */
-#define DMA_READ_AHEAD   0x00001800        /* DMA read ahead partial longword */
-#define DMA_DSBL_RD_DRN  0x00001000        /* No EC drain on slave reads */
-#define DMA_BCNT_ENAB    0x00002000        /* If on, use the byte counter */
-#define DMA_TERM_CNTR    0x00004000        /* Terminal counter */
-#define DMA_SCSI_SBUS64  0x00008000        /* HME: Enable 64-bit SBUS mode. */
-#define DMA_CSR_DISAB    0x00010000        /* No FIFO drains during csr */
-#define DMA_SCSI_DISAB   0x00020000        /* No FIFO drains during reg */
-#define DMA_DSBL_WR_INV  0x00020000        /* No EC inval. on slave writes */
-#define DMA_ADD_ENABLE   0x00040000        /* Special ESC DVMA optimization */
-#define DMA_E_BURSTS    0x000c0000        /* ENET: SBUS r/w burst mask */
-#define DMA_E_BURST32   0x00040000        /* ENET: SBUS 32 byte r/w burst */
-#define DMA_E_BURST16   0x00000000        /* ENET: SBUS 16 byte r/w burst */
-#define DMA_BRST_SZ      0x000c0000        /* SCSI: SBUS r/w burst size */
-#define DMA_BRST64       0x00080000        /* SCSI: 64byte bursts (HME on UltraSparc only) */
-#define DMA_BRST32       0x00040000        /* SCSI/BPP: 32byte bursts */
-#define DMA_BRST16       0x00000000        /* SCSI/BPP: 16byte bursts */
-#define DMA_BRST0        0x00080000        /* SCSI: no bursts (non-HME gate arrays) */
-#define DMA_ADDR_DISAB   0x00100000        /* No FIFO drains during addr */
-#define DMA_2CLKS        0x00200000        /* Each transfer = 2 clock ticks */
-#define DMA_3CLKS        0x00400000        /* Each transfer = 3 clock ticks */
-#define DMA_EN_ENETAUI   DMA_3CLKS         /* Put lance into AUI-cable mode */
-#define DMA_CNTR_DISAB   0x00800000        /* No IRQ when DMA_TERM_CNTR set */
-#define DMA_AUTO_NADDR   0x01000000        /* Use "auto nxt addr" feature */
-#define DMA_SCSI_ON      0x02000000        /* Enable SCSI dma */
-#define DMA_BPP_ON       DMA_SCSI_ON       /* Enable BPP dma */
-#define DMA_PARITY_OFF   0x02000000        /* HME: disable parity checking */
-#define DMA_LOADED_ADDR  0x04000000        /* Address has been loaded */
-#define DMA_LOADED_NADDR 0x08000000        /* Next address has been loaded */
-#define DMA_RESET_FAS366 0x08000000        /* HME: Assert RESET to FAS366 */
-
-/* Values describing the burst-size property from the PROM */
-#define DMA_BURST1       0x01
-#define DMA_BURST2       0x02
-#define DMA_BURST4       0x04
-#define DMA_BURST8       0x08
-#define DMA_BURST16      0x10
-#define DMA_BURST32      0x20
-#define DMA_BURST64      0x40
-#define DMA_BURSTBITS    0x7f
-
-/* Determine highest possible final transfer address given a base */
-#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL))
-
-/* Yes, I hack a lot of elisp in my spare time... */
-#define DMA_ERROR_P(regs)  ((((regs)->cond_reg) & DMA_HNDL_ERROR))
-#define DMA_IRQ_P(regs)    ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR)))
-#define DMA_WRITE_P(regs)  ((((regs)->cond_reg) & DMA_ST_WRITE))
-#define DMA_OFF(regs)      ((((regs)->cond_reg) &= (~DMA_ENABLE)))
-#define DMA_INTSOFF(regs)  ((((regs)->cond_reg) &= (~DMA_INT_ENAB)))
-#define DMA_INTSON(regs)   ((((regs)->cond_reg) |= (DMA_INT_ENAB)))
-#define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV))
-#define DMA_SETSTART(regs, addr)  ((((regs)->st_addr) = (char *) addr))
-#define DMA_BEGINDMA_W(regs) \
-        ((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB))))
-#define DMA_BEGINDMA_R(regs) \
-        ((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE)))))
-
-/* For certain DMA chips, we need to disable ints upon irq entry
- * and turn them back on when we are done.  So in any ESP interrupt
- * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT
- * when leaving the handler.  You have been warned...
- */
-#define DMA_IRQ_ENTRY(dma, dregs) do { \
-        if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \
-   } while (0)
-
-#define DMA_IRQ_EXIT(dma, dregs) do { \
-       if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \
-   } while(0)
-
-#if 0  /* P3 this stuff is inline in ledma.c:init_restart_ledma() */
-/* Pause until counter runs out or BIT isn't set in the DMA condition
- * register.
- */
-static inline void sparc_dma_pause(struct sparc_dma_registers *regs,
-                                      unsigned long bit)
-{
-       int ctr = 50000;   /* Let's find some bugs ;) */
-
-       /* Busy wait until the bit is not set any more */
-       while((regs->cond_reg&bit) && (ctr>0)) {
-               ctr--;
-               __delay(5);
-       }
-
-       /* Check for bogus outcome. */
-       if(!ctr)
-               panic("DMA timeout");
-}
-
-/* Reset the friggin' thing... */
-#define DMA_RESET(dma) do { \
-       struct sparc_dma_registers *regs = dma->regs;                      \
-       /* Let the current FIFO drain itself */                            \
-       sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN));                         \
-       /* Reset the logic */                                              \
-       regs->cond_reg |= (DMA_RST_SCSI);     /* assert */                 \
-       __delay(400);                         /* let the bits set ;) */    \
-       regs->cond_reg &= ~(DMA_RST_SCSI);    /* de-assert */              \
-       sparc_dma_enable_interrupts(regs);    /* Re-enable interrupts */   \
-       /* Enable FAST transfers if available */                           \
-       if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS;            \
-       dma->running = 0;                                                  \
-} while(0)
 #endif
-
-#define for_each_dvma(dma) \
-        for((dma) = dma_chain; (dma); (dma) = (dma)->next)
-
-extern int get_dma_list(char *);
-extern int request_dma(unsigned int, __const__ char *);
-extern void free_dma(unsigned int);
-
-/* From PCI */
-
-#ifdef CONFIG_PCI
-extern int isa_dma_bridge_buggy;
-#else
-#define isa_dma_bridge_buggy   (0)
-#endif
-
-/* Routines for data transfer buffers. */
-BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long)
-BTFIXUPDEF_CALL(void,   mmu_unlockarea, char *, unsigned long)
-
-#define mmu_lockarea(vaddr,len) BTFIXUP_CALL(mmu_lockarea)(vaddr,len)
-#define mmu_unlockarea(vaddr,len) BTFIXUP_CALL(mmu_unlockarea)(vaddr,len)
-
-/* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */
-BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, char *, unsigned long, struct sbus_bus *sbus)
-BTFIXUPDEF_CALL(void,  mmu_get_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus)
-BTFIXUPDEF_CALL(void,  mmu_release_scsi_one, __u32, unsigned long, struct sbus_bus *sbus)
-BTFIXUPDEF_CALL(void,  mmu_release_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus)
-
-#define mmu_get_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_get_scsi_one)(vaddr,len,sbus)
-#define mmu_get_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_get_scsi_sgl)(sg,sz,sbus)
-#define mmu_release_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_release_scsi_one)(vaddr,len,sbus)
-#define mmu_release_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_release_scsi_sgl)(sg,sz,sbus)
-
-/*
- * mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep.
- *
- * The mmu_map_dma_area establishes two mappings in one go.
- * These mappings point to pages normally mapped at 'va' (linear address).
- * First mapping is for CPU visible address at 'a', uncached.
- * This is an alias, but it works because it is an uncached mapping.
- * Second mapping is for device visible address, or "bus" address.
- * The bus address is returned at '*pba'.
- *
- * These functions seem distinct, but are hard to split. On sun4c,
- * at least for now, 'a' is equal to bus address, and retured in *pba.
- * On sun4m, page attributes depend on the CPU type, so we have to
- * know if we are mapping RAM or I/O, so it has to be an additional argument
- * to a separate mapping function for CPU visible mappings.
- */
-BTFIXUPDEF_CALL(int,  mmu_map_dma_area, dma_addr_t *, unsigned long, unsigned long, int len)
-BTFIXUPDEF_CALL(struct page *, mmu_translate_dvma, unsigned long busa)
-BTFIXUPDEF_CALL(void,  mmu_unmap_dma_area, unsigned long busa, int len)
-
-#define mmu_map_dma_area(pba,va,a,len) BTFIXUP_CALL(mmu_map_dma_area)(pba,va,a,len)
-#define mmu_unmap_dma_area(ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(ba,len)
-#define mmu_translate_dvma(ba)     BTFIXUP_CALL(mmu_translate_dvma)(ba)
-
-#endif /* !(_ASM_SPARC_DMA_H) */
diff --git a/include/asm-sparc/dma_32.h b/include/asm-sparc/dma_32.h
new file mode 100644 (file)
index 0000000..959d6c8
--- /dev/null
@@ -0,0 +1,288 @@
+/* include/asm-sparc/dma.h
+ *
+ * Copyright 1995 (C) David S. Miller (davem@davemloft.net)
+ */
+
+#ifndef _ASM_SPARC_DMA_H
+#define _ASM_SPARC_DMA_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/vac-ops.h>  /* for invalidate's, etc. */
+#include <asm/sbus.h>
+#include <asm/delay.h>
+#include <asm/oplib.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <linux/spinlock.h>
+
+struct page;
+extern spinlock_t  dma_spin_lock;
+
+static inline unsigned long claim_dma_lock(void)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&dma_spin_lock, flags);
+       return flags;
+}
+
+static inline void release_dma_lock(unsigned long flags)
+{
+       spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+/* These are irrelevant for Sparc DMA, but we leave it in so that
+ * things can compile.
+ */
+#define MAX_DMA_CHANNELS 8
+#define MAX_DMA_ADDRESS  (~0UL)
+#define DMA_MODE_READ    1
+#define DMA_MODE_WRITE   2
+
+/* Useful constants */
+#define SIZE_16MB      (16*1024*1024)
+#define SIZE_64K       (64*1024)
+
+/* SBUS DMA controller reg offsets */
+#define DMA_CSR                0x00UL          /* rw  DMA control/status register    0x00   */
+#define DMA_ADDR       0x04UL          /* rw  DMA transfer address register  0x04   */
+#define DMA_COUNT      0x08UL          /* rw  DMA transfer count register    0x08   */
+#define DMA_TEST       0x0cUL          /* rw  DMA test/debug register        0x0c   */
+
+/* DVMA chip revisions */
+enum dvma_rev {
+       dvmarev0,
+       dvmaesc1,
+       dvmarev1,
+       dvmarev2,
+       dvmarev3,
+       dvmarevplus,
+       dvmahme
+};
+
+#define DMA_HASCOUNT(rev)  ((rev)==dvmaesc1)
+
+/* Linux DMA information structure, filled during probe. */
+struct sbus_dma {
+       struct sbus_dma *next;
+       struct sbus_dev *sdev;
+       void __iomem *regs;
+
+       /* Status, misc info */
+       int node;                /* Prom node for this DMA device */
+       int running;             /* Are we doing DMA now? */
+       int allocated;           /* Are we "owned" by anyone yet? */
+
+       /* Transfer information. */
+       unsigned long addr;      /* Start address of current transfer */
+       int nbytes;              /* Size of current transfer */
+       int realbytes;           /* For splitting up large transfers, etc. */
+
+       /* DMA revision */
+       enum dvma_rev revision;
+};
+
+extern struct sbus_dma *dma_chain;
+
+/* Broken hardware... */
+#ifdef CONFIG_SUN4
+/* Have to sort this out. Does rev0 work fine on sun4[cmd] without isbroken?
+ * Or is rev0 present only on sun4 boxes? -jj */
+#define DMA_ISBROKEN(dma)    ((dma)->revision == dvmarev0 || (dma)->revision == dvmarev1)
+#else
+#define DMA_ISBROKEN(dma)    ((dma)->revision == dvmarev1)
+#endif
+#define DMA_ISESC1(dma)      ((dma)->revision == dvmaesc1)
+
+/* Main routines in dma.c */
+extern void dvma_init(struct sbus_bus *);
+
+/* Fields in the cond_reg register */
+/* First, the version identification bits */
+#define DMA_DEVICE_ID    0xf0000000        /* Device identification bits */
+#define DMA_VERS0        0x00000000        /* Sunray DMA version */
+#define DMA_ESCV1        0x40000000        /* DMA ESC Version 1 */
+#define DMA_VERS1        0x80000000        /* DMA rev 1 */
+#define DMA_VERS2        0xa0000000        /* DMA rev 2 */
+#define DMA_VERHME       0xb0000000        /* DMA hme gate array */
+#define DMA_VERSPLUS     0x90000000        /* DMA rev 1 PLUS */
+
+#define DMA_HNDL_INTR    0x00000001        /* An IRQ needs to be handled */
+#define DMA_HNDL_ERROR   0x00000002        /* We need to take an error */
+#define DMA_FIFO_ISDRAIN 0x0000000c        /* The DMA FIFO is draining */
+#define DMA_INT_ENAB     0x00000010        /* Turn on interrupts */
+#define DMA_FIFO_INV     0x00000020        /* Invalidate the FIFO */
+#define DMA_ACC_SZ_ERR   0x00000040        /* The access size was bad */
+#define DMA_FIFO_STDRAIN 0x00000040        /* DMA_VERS1 Drain the FIFO */
+#define DMA_RST_SCSI     0x00000080        /* Reset the SCSI controller */
+#define DMA_RST_ENET     DMA_RST_SCSI      /* Reset the ENET controller */
+#define DMA_RST_BPP      DMA_RST_SCSI      /* Reset the BPP controller */
+#define DMA_ST_WRITE     0x00000100        /* write from device to memory */
+#define DMA_ENABLE       0x00000200        /* Fire up DMA, handle requests */
+#define DMA_PEND_READ    0x00000400        /* DMA_VERS1/0/PLUS Pending Read */
+#define DMA_ESC_BURST    0x00000800        /* 1=16byte 0=32byte */
+#define DMA_READ_AHEAD   0x00001800        /* DMA read ahead partial longword */
+#define DMA_DSBL_RD_DRN  0x00001000        /* No EC drain on slave reads */
+#define DMA_BCNT_ENAB    0x00002000        /* If on, use the byte counter */
+#define DMA_TERM_CNTR    0x00004000        /* Terminal counter */
+#define DMA_SCSI_SBUS64  0x00008000        /* HME: Enable 64-bit SBUS mode. */
+#define DMA_CSR_DISAB    0x00010000        /* No FIFO drains during csr */
+#define DMA_SCSI_DISAB   0x00020000        /* No FIFO drains during reg */
+#define DMA_DSBL_WR_INV  0x00020000        /* No EC inval. on slave writes */
+#define DMA_ADD_ENABLE   0x00040000        /* Special ESC DVMA optimization */
+#define DMA_E_BURSTS    0x000c0000        /* ENET: SBUS r/w burst mask */
+#define DMA_E_BURST32   0x00040000        /* ENET: SBUS 32 byte r/w burst */
+#define DMA_E_BURST16   0x00000000        /* ENET: SBUS 16 byte r/w burst */
+#define DMA_BRST_SZ      0x000c0000        /* SCSI: SBUS r/w burst size */
+#define DMA_BRST64       0x00080000        /* SCSI: 64byte bursts (HME on UltraSparc only) */
+#define DMA_BRST32       0x00040000        /* SCSI/BPP: 32byte bursts */
+#define DMA_BRST16       0x00000000        /* SCSI/BPP: 16byte bursts */
+#define DMA_BRST0        0x00080000        /* SCSI: no bursts (non-HME gate arrays) */
+#define DMA_ADDR_DISAB   0x00100000        /* No FIFO drains during addr */
+#define DMA_2CLKS        0x00200000        /* Each transfer = 2 clock ticks */
+#define DMA_3CLKS        0x00400000        /* Each transfer = 3 clock ticks */
+#define DMA_EN_ENETAUI   DMA_3CLKS         /* Put lance into AUI-cable mode */
+#define DMA_CNTR_DISAB   0x00800000        /* No IRQ when DMA_TERM_CNTR set */
+#define DMA_AUTO_NADDR   0x01000000        /* Use "auto nxt addr" feature */
+#define DMA_SCSI_ON      0x02000000        /* Enable SCSI dma */
+#define DMA_BPP_ON       DMA_SCSI_ON       /* Enable BPP dma */
+#define DMA_PARITY_OFF   0x02000000        /* HME: disable parity checking */
+#define DMA_LOADED_ADDR  0x04000000        /* Address has been loaded */
+#define DMA_LOADED_NADDR 0x08000000        /* Next address has been loaded */
+#define DMA_RESET_FAS366 0x08000000        /* HME: Assert RESET to FAS366 */
+
+/* Values describing the burst-size property from the PROM */
+#define DMA_BURST1       0x01
+#define DMA_BURST2       0x02
+#define DMA_BURST4       0x04
+#define DMA_BURST8       0x08
+#define DMA_BURST16      0x10
+#define DMA_BURST32      0x20
+#define DMA_BURST64      0x40
+#define DMA_BURSTBITS    0x7f
+
+/* Determine highest possible final transfer address given a base */
+#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL))
+
+/* Yes, I hack a lot of elisp in my spare time... */
+#define DMA_ERROR_P(regs)  ((((regs)->cond_reg) & DMA_HNDL_ERROR))
+#define DMA_IRQ_P(regs)    ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR)))
+#define DMA_WRITE_P(regs)  ((((regs)->cond_reg) & DMA_ST_WRITE))
+#define DMA_OFF(regs)      ((((regs)->cond_reg) &= (~DMA_ENABLE)))
+#define DMA_INTSOFF(regs)  ((((regs)->cond_reg) &= (~DMA_INT_ENAB)))
+#define DMA_INTSON(regs)   ((((regs)->cond_reg) |= (DMA_INT_ENAB)))
+#define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV))
+#define DMA_SETSTART(regs, addr)  ((((regs)->st_addr) = (char *) addr))
+#define DMA_BEGINDMA_W(regs) \
+        ((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB))))
+#define DMA_BEGINDMA_R(regs) \
+        ((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE)))))
+
+/* For certain DMA chips, we need to disable ints upon irq entry
+ * and turn them back on when we are done.  So in any ESP interrupt
+ * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT
+ * when leaving the handler.  You have been warned...
+ */
+#define DMA_IRQ_ENTRY(dma, dregs) do { \
+        if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \
+   } while (0)
+
+#define DMA_IRQ_EXIT(dma, dregs) do { \
+       if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \
+   } while(0)
+
+#if 0  /* P3 this stuff is inline in ledma.c:init_restart_ledma() */
+/* Pause until counter runs out or BIT isn't set in the DMA condition
+ * register.
+ */
+static inline void sparc_dma_pause(struct sparc_dma_registers *regs,
+                                      unsigned long bit)
+{
+       int ctr = 50000;   /* Let's find some bugs ;) */
+
+       /* Busy wait until the bit is not set any more */
+       while((regs->cond_reg&bit) && (ctr>0)) {
+               ctr--;
+               __delay(5);
+       }
+
+       /* Check for bogus outcome. */
+       if(!ctr)
+               panic("DMA timeout");
+}
+
+/* Reset the friggin' thing... */
+#define DMA_RESET(dma) do { \
+       struct sparc_dma_registers *regs = dma->regs;                      \
+       /* Let the current FIFO drain itself */                            \
+       sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN));                         \
+       /* Reset the logic */                                              \
+       regs->cond_reg |= (DMA_RST_SCSI);     /* assert */                 \
+       __delay(400);                         /* let the bits set ;) */    \
+       regs->cond_reg &= ~(DMA_RST_SCSI);    /* de-assert */              \
+       sparc_dma_enable_interrupts(regs);    /* Re-enable interrupts */   \
+       /* Enable FAST transfers if available */                           \
+       if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS;            \
+       dma->running = 0;                                                  \
+} while(0)
+#endif
+
+#define for_each_dvma(dma) \
+        for((dma) = dma_chain; (dma); (dma) = (dma)->next)
+
+extern int get_dma_list(char *);
+extern int request_dma(unsigned int, __const__ char *);
+extern void free_dma(unsigned int);
+
+/* From PCI */
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy   (0)
+#endif
+
+/* Routines for data transfer buffers. */
+BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long)
+BTFIXUPDEF_CALL(void,   mmu_unlockarea, char *, unsigned long)
+
+#define mmu_lockarea(vaddr,len) BTFIXUP_CALL(mmu_lockarea)(vaddr,len)
+#define mmu_unlockarea(vaddr,len) BTFIXUP_CALL(mmu_unlockarea)(vaddr,len)
+
+/* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */
+BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, char *, unsigned long, struct sbus_bus *sbus)
+BTFIXUPDEF_CALL(void,  mmu_get_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus)
+BTFIXUPDEF_CALL(void,  mmu_release_scsi_one, __u32, unsigned long, struct sbus_bus *sbus)
+BTFIXUPDEF_CALL(void,  mmu_release_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus)
+
+#define mmu_get_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_get_scsi_one)(vaddr,len,sbus)
+#define mmu_get_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_get_scsi_sgl)(sg,sz,sbus)
+#define mmu_release_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_release_scsi_one)(vaddr,len,sbus)
+#define mmu_release_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_release_scsi_sgl)(sg,sz,sbus)
+
+/*
+ * mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep.
+ *
+ * The mmu_map_dma_area establishes two mappings in one go.
+ * These mappings point to pages normally mapped at 'va' (linear address).
+ * First mapping is for CPU visible address at 'a', uncached.
+ * This is an alias, but it works because it is an uncached mapping.
+ * Second mapping is for device visible address, or "bus" address.
+ * The bus address is returned at '*pba'.
+ *
+ * These functions seem distinct, but are hard to split. On sun4c,
+ * at least for now, 'a' is equal to bus address, and retured in *pba.
+ * On sun4m, page attributes depend on the CPU type, so we have to
+ * know if we are mapping RAM or I/O, so it has to be an additional argument
+ * to a separate mapping function for CPU visible mappings.
+ */
+BTFIXUPDEF_CALL(int,  mmu_map_dma_area, dma_addr_t *, unsigned long, unsigned long, int len)
+BTFIXUPDEF_CALL(struct page *, mmu_translate_dvma, unsigned long busa)
+BTFIXUPDEF_CALL(void,  mmu_unmap_dma_area, unsigned long busa, int len)
+
+#define mmu_map_dma_area(pba,va,a,len) BTFIXUP_CALL(mmu_map_dma_area)(pba,va,a,len)
+#define mmu_unmap_dma_area(ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(ba,len)
+#define mmu_translate_dvma(ba)     BTFIXUP_CALL(mmu_translate_dvma)(ba)
+
+#endif /* !(_ASM_SPARC_DMA_H) */
diff --git a/include/asm-sparc/dma_64.h b/include/asm-sparc/dma_64.h
new file mode 100644 (file)
index 0000000..9d4c024
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * include/asm-sparc64/dma.h
+ *
+ * Copyright 1996 (C) David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _ASM_SPARC64_DMA_H
+#define _ASM_SPARC64_DMA_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+
+#include <asm/sbus.h>
+#include <asm/delay.h>
+#include <asm/oplib.h>
+
+/* These are irrelevant for Sparc DMA, but we leave it in so that
+ * things can compile.
+ */
+#define MAX_DMA_CHANNELS 8
+#define DMA_MODE_READ    1
+#define DMA_MODE_WRITE   2
+#define MAX_DMA_ADDRESS  (~0UL)
+
+/* Useful constants */
+#define SIZE_16MB      (16*1024*1024)
+#define SIZE_64K       (64*1024)
+
+/* SBUS DMA controller reg offsets */
+#define DMA_CSR                0x00UL          /* rw  DMA control/status register    0x00   */
+#define DMA_ADDR       0x04UL          /* rw  DMA transfer address register  0x04   */
+#define DMA_COUNT      0x08UL          /* rw  DMA transfer count register    0x08   */
+#define DMA_TEST       0x0cUL          /* rw  DMA test/debug register        0x0c   */
+
+/* DVMA chip revisions */
+enum dvma_rev {
+       dvmarev0,
+       dvmaesc1,
+       dvmarev1,
+       dvmarev2,
+       dvmarev3,
+       dvmarevplus,
+       dvmahme
+};
+
+#define DMA_HASCOUNT(rev)  ((rev)==dvmaesc1)
+
+/* Linux DMA information structure, filled during probe. */
+struct sbus_dma {
+       struct sbus_dma *next;
+       struct sbus_dev *sdev;
+       void __iomem *regs;
+
+       /* Status, misc info */
+       int node;                /* Prom node for this DMA device */
+       int running;             /* Are we doing DMA now? */
+       int allocated;           /* Are we "owned" by anyone yet? */
+
+       /* Transfer information. */
+       u32 addr;                /* Start address of current transfer */
+       int nbytes;              /* Size of current transfer */
+       int realbytes;           /* For splitting up large transfers, etc. */
+
+       /* DMA revision */
+       enum dvma_rev revision;
+};
+
+extern struct sbus_dma *dma_chain;
+
+/* Broken hardware... */
+#define DMA_ISBROKEN(dma)    ((dma)->revision == dvmarev1)
+#define DMA_ISESC1(dma)      ((dma)->revision == dvmaesc1)
+
+/* Main routines in dma.c */
+extern void dvma_init(struct sbus_bus *);
+
+/* Fields in the cond_reg register */
+/* First, the version identification bits */
+#define DMA_DEVICE_ID    0xf0000000        /* Device identification bits */
+#define DMA_VERS0        0x00000000        /* Sunray DMA version */
+#define DMA_ESCV1        0x40000000        /* DMA ESC Version 1 */
+#define DMA_VERS1        0x80000000        /* DMA rev 1 */
+#define DMA_VERS2        0xa0000000        /* DMA rev 2 */
+#define DMA_VERHME       0xb0000000        /* DMA hme gate array */
+#define DMA_VERSPLUS     0x90000000        /* DMA rev 1 PLUS */
+
+#define DMA_HNDL_INTR    0x00000001        /* An IRQ needs to be handled */
+#define DMA_HNDL_ERROR   0x00000002        /* We need to take an error */
+#define DMA_FIFO_ISDRAIN 0x0000000c        /* The DMA FIFO is draining */
+#define DMA_INT_ENAB     0x00000010        /* Turn on interrupts */
+#define DMA_FIFO_INV     0x00000020        /* Invalidate the FIFO */
+#define DMA_ACC_SZ_ERR   0x00000040        /* The access size was bad */
+#define DMA_FIFO_STDRAIN 0x00000040        /* DMA_VERS1 Drain the FIFO */
+#define DMA_RST_SCSI     0x00000080        /* Reset the SCSI controller */
+#define DMA_RST_ENET     DMA_RST_SCSI      /* Reset the ENET controller */
+#define DMA_ST_WRITE     0x00000100        /* write from device to memory */
+#define DMA_ENABLE       0x00000200        /* Fire up DMA, handle requests */
+#define DMA_PEND_READ    0x00000400        /* DMA_VERS1/0/PLUS Pending Read */
+#define DMA_ESC_BURST    0x00000800        /* 1=16byte 0=32byte */
+#define DMA_READ_AHEAD   0x00001800        /* DMA read ahead partial longword */
+#define DMA_DSBL_RD_DRN  0x00001000        /* No EC drain on slave reads */
+#define DMA_BCNT_ENAB    0x00002000        /* If on, use the byte counter */
+#define DMA_TERM_CNTR    0x00004000        /* Terminal counter */
+#define DMA_SCSI_SBUS64  0x00008000        /* HME: Enable 64-bit SBUS mode. */
+#define DMA_CSR_DISAB    0x00010000        /* No FIFO drains during csr */
+#define DMA_SCSI_DISAB   0x00020000        /* No FIFO drains during reg */
+#define DMA_DSBL_WR_INV  0x00020000        /* No EC inval. on slave writes */
+#define DMA_ADD_ENABLE   0x00040000        /* Special ESC DVMA optimization */
+#define DMA_E_BURSTS    0x000c0000        /* ENET: SBUS r/w burst mask */
+#define DMA_E_BURST32   0x00040000        /* ENET: SBUS 32 byte r/w burst */
+#define DMA_E_BURST16   0x00000000        /* ENET: SBUS 16 byte r/w burst */
+#define DMA_BRST_SZ      0x000c0000        /* SCSI: SBUS r/w burst size */
+#define DMA_BRST64       0x000c0000        /* SCSI: 64byte bursts (HME on UltraSparc only) */
+#define DMA_BRST32       0x00040000        /* SCSI: 32byte bursts */
+#define DMA_BRST16       0x00000000        /* SCSI: 16byte bursts */
+#define DMA_BRST0        0x00080000        /* SCSI: no bursts (non-HME gate arrays) */
+#define DMA_ADDR_DISAB   0x00100000        /* No FIFO drains during addr */
+#define DMA_2CLKS        0x00200000        /* Each transfer = 2 clock ticks */
+#define DMA_3CLKS        0x00400000        /* Each transfer = 3 clock ticks */
+#define DMA_EN_ENETAUI   DMA_3CLKS         /* Put lance into AUI-cable mode */
+#define DMA_CNTR_DISAB   0x00800000        /* No IRQ when DMA_TERM_CNTR set */
+#define DMA_AUTO_NADDR   0x01000000        /* Use "auto nxt addr" feature */
+#define DMA_SCSI_ON      0x02000000        /* Enable SCSI dma */
+#define DMA_PARITY_OFF   0x02000000        /* HME: disable parity checking */
+#define DMA_LOADED_ADDR  0x04000000        /* Address has been loaded */
+#define DMA_LOADED_NADDR 0x08000000        /* Next address has been loaded */
+#define DMA_RESET_FAS366 0x08000000        /* HME: Assert RESET to FAS366 */
+
+/* Values describing the burst-size property from the PROM */
+#define DMA_BURST1       0x01
+#define DMA_BURST2       0x02
+#define DMA_BURST4       0x04
+#define DMA_BURST8       0x08
+#define DMA_BURST16      0x10
+#define DMA_BURST32      0x20
+#define DMA_BURST64      0x40
+#define DMA_BURSTBITS    0x7f
+
+/* Determine highest possible final transfer address given a base */
+#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL))
+
+/* Yes, I hack a lot of elisp in my spare time... */
+#define DMA_ERROR_P(regs)  ((sbus_readl((regs) + DMA_CSR) & DMA_HNDL_ERROR))
+#define DMA_IRQ_P(regs)    ((sbus_readl((regs) + DMA_CSR)) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))
+#define DMA_WRITE_P(regs)  ((sbus_readl((regs) + DMA_CSR) & DMA_ST_WRITE))
+#define DMA_OFF(__regs)                \
+do {   u32 tmp = sbus_readl((__regs) + DMA_CSR); \
+       tmp &= ~DMA_ENABLE; \
+       sbus_writel(tmp, (__regs) + DMA_CSR); \
+} while(0)
+#define DMA_INTSOFF(__regs)    \
+do {   u32 tmp = sbus_readl((__regs) + DMA_CSR); \
+       tmp &= ~DMA_INT_ENAB; \
+       sbus_writel(tmp, (__regs) + DMA_CSR); \
+} while(0)
+#define DMA_INTSON(__regs)     \
+do {   u32 tmp = sbus_readl((__regs) + DMA_CSR); \
+       tmp |= DMA_INT_ENAB; \
+       sbus_writel(tmp, (__regs) + DMA_CSR); \
+} while(0)
+#define DMA_PUNTFIFO(__regs)   \
+do {   u32 tmp = sbus_readl((__regs) + DMA_CSR); \
+       tmp |= DMA_FIFO_INV; \
+       sbus_writel(tmp, (__regs) + DMA_CSR); \
+} while(0)
+#define DMA_SETSTART(__regs, __addr)   \
+       sbus_writel((u32)(__addr), (__regs) + DMA_ADDR);
+#define DMA_BEGINDMA_W(__regs) \
+do {   u32 tmp = sbus_readl((__regs) + DMA_CSR); \
+       tmp |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB); \
+       sbus_writel(tmp, (__regs) + DMA_CSR); \
+} while(0)
+#define DMA_BEGINDMA_R(__regs) \
+do {   u32 tmp = sbus_readl((__regs) + DMA_CSR); \
+       tmp |= (DMA_ENABLE|DMA_INT_ENAB); \
+       tmp &= ~DMA_ST_WRITE; \
+       sbus_writel(tmp, (__regs) + DMA_CSR); \
+} while(0)
+
+/* For certain DMA chips, we need to disable ints upon irq entry
+ * and turn them back on when we are done.  So in any ESP interrupt
+ * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT
+ * when leaving the handler.  You have been warned...
+ */
+#define DMA_IRQ_ENTRY(dma, dregs) do { \
+        if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \
+   } while (0)
+
+#define DMA_IRQ_EXIT(dma, dregs) do { \
+       if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \
+   } while(0)
+
+#define for_each_dvma(dma) \
+        for((dma) = dma_chain; (dma); (dma) = (dma)->next)
+
+/* From PCI */
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy   (0)
+#endif
+
+#endif /* !(_ASM_SPARC64_DMA_H) */
index 491f85d662df66c54c7ecc77dc3c233033432a27..a5da2d00cd1814728af538bbca535919f2086cdd 100644 (file)
@@ -1,99 +1,8 @@
-/*
- * ebus.h: PCI to Ebus pseudo driver software state.
- *
- * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) 
- *
- * Adopted for sparc by V. Roganov and G. Raiko.
- */
-
-#ifndef __SPARC_EBUS_H
-#define __SPARC_EBUS_H
-
-#ifndef _LINUX_IOPORT_H
-#include <linux/ioport.h>
+#ifndef ___ASM_SPARC_EBUS_H
+#define ___ASM_SPARC_EBUS_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/ebus_64.h>
+#else
+#include <asm-sparc/ebus_32.h>
+#endif
 #endif
-#include <asm/oplib.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
-
-struct linux_ebus_child {
-       struct linux_ebus_child         *next;
-       struct linux_ebus_device        *parent;
-       struct linux_ebus               *bus;
-       struct device_node              *prom_node;
-       struct resource                  resource[PROMREG_MAX];
-       int                              num_addrs;
-       unsigned int                     irqs[PROMINTR_MAX];
-       int                              num_irqs;
-};
-
-struct linux_ebus_device {
-       struct of_device                ofdev;
-       struct linux_ebus_device        *next;
-       struct linux_ebus_child         *children;
-       struct linux_ebus               *bus;
-       struct device_node              *prom_node;
-       struct resource                  resource[PROMREG_MAX];
-       int                              num_addrs;
-       unsigned int                     irqs[PROMINTR_MAX];
-       int                              num_irqs;
-};
-#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev)
-
-struct linux_ebus {
-       struct of_device                ofdev;
-       struct linux_ebus               *next;
-       struct linux_ebus_device        *devices;
-       struct linux_pbm_info           *parent;
-       struct pci_dev                  *self;
-       struct device_node              *prom_node;
-};
-#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev)
-
-struct linux_ebus_dma {
-       unsigned int dcsr;
-       unsigned int dacr;
-       unsigned int dbcr;
-};
-
-#define EBUS_DCSR_INT_PEND     0x00000001
-#define EBUS_DCSR_ERR_PEND     0x00000002
-#define EBUS_DCSR_DRAIN                0x00000004
-#define EBUS_DCSR_INT_EN       0x00000010
-#define EBUS_DCSR_RESET                0x00000080
-#define EBUS_DCSR_WRITE                0x00000100
-#define EBUS_DCSR_EN_DMA       0x00000200
-#define EBUS_DCSR_CYC_PEND     0x00000400
-#define EBUS_DCSR_DIAG_RD_DONE 0x00000800
-#define EBUS_DCSR_DIAG_WR_DONE 0x00001000
-#define EBUS_DCSR_EN_CNT       0x00002000
-#define EBUS_DCSR_TC           0x00004000
-#define EBUS_DCSR_DIS_CSR_DRN  0x00010000
-#define EBUS_DCSR_BURST_SZ_MASK        0x000c0000
-#define EBUS_DCSR_BURST_SZ_1   0x00080000
-#define EBUS_DCSR_BURST_SZ_4   0x00000000
-#define EBUS_DCSR_BURST_SZ_8   0x00040000
-#define EBUS_DCSR_BURST_SZ_16  0x000c0000
-#define EBUS_DCSR_DIAG_EN      0x00100000
-#define EBUS_DCSR_DIS_ERR_PEND 0x00400000
-#define EBUS_DCSR_TCI_DIS      0x00800000
-#define EBUS_DCSR_EN_NEXT      0x01000000
-#define EBUS_DCSR_DMA_ON       0x02000000
-#define EBUS_DCSR_A_LOADED     0x04000000
-#define EBUS_DCSR_NA_LOADED    0x08000000
-#define EBUS_DCSR_DEV_ID_MASK  0xf0000000
-
-extern struct linux_ebus               *ebus_chain;
-
-extern void ebus_init(void);
-
-#define for_each_ebus(bus)                                             \
-        for((bus) = ebus_chain; (bus); (bus) = (bus)->next)
-
-#define for_each_ebusdev(dev, bus)                                     \
-        for((dev) = (bus)->devices; (dev); (dev) = (dev)->next)
-
-#define for_each_edevchild(dev, child)                                 \
-        for((child) = (dev)->children; (child); (child) = (child)->next)
-
-#endif /* !(__SPARC_EBUS_H) */
diff --git a/include/asm-sparc/ebus_32.h b/include/asm-sparc/ebus_32.h
new file mode 100644 (file)
index 0000000..29cb7df
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * ebus.h: PCI to Ebus pseudo driver software state.
+ *
+ * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
+ *
+ * Adopted for sparc by V. Roganov and G. Raiko.
+ */
+
+#ifndef __SPARC_EBUS_H
+#define __SPARC_EBUS_H
+
+#ifndef _LINUX_IOPORT_H
+#include <linux/ioport.h>
+#endif
+#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
+
+struct linux_ebus_child {
+       struct linux_ebus_child         *next;
+       struct linux_ebus_device        *parent;
+       struct linux_ebus               *bus;
+       struct device_node              *prom_node;
+       struct resource                  resource[PROMREG_MAX];
+       int                              num_addrs;
+       unsigned int                     irqs[PROMINTR_MAX];
+       int                              num_irqs;
+};
+
+struct linux_ebus_device {
+       struct of_device                ofdev;
+       struct linux_ebus_device        *next;
+       struct linux_ebus_child         *children;
+       struct linux_ebus               *bus;
+       struct device_node              *prom_node;
+       struct resource                  resource[PROMREG_MAX];
+       int                              num_addrs;
+       unsigned int                     irqs[PROMINTR_MAX];
+       int                              num_irqs;
+};
+#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev)
+
+struct linux_ebus {
+       struct of_device                ofdev;
+       struct linux_ebus               *next;
+       struct linux_ebus_device        *devices;
+       struct linux_pbm_info           *parent;
+       struct pci_dev                  *self;
+       struct device_node              *prom_node;
+};
+#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev)
+
+struct linux_ebus_dma {
+       unsigned int dcsr;
+       unsigned int dacr;
+       unsigned int dbcr;
+};
+
+#define EBUS_DCSR_INT_PEND     0x00000001
+#define EBUS_DCSR_ERR_PEND     0x00000002
+#define EBUS_DCSR_DRAIN                0x00000004
+#define EBUS_DCSR_INT_EN       0x00000010
+#define EBUS_DCSR_RESET                0x00000080
+#define EBUS_DCSR_WRITE                0x00000100
+#define EBUS_DCSR_EN_DMA       0x00000200
+#define EBUS_DCSR_CYC_PEND     0x00000400
+#define EBUS_DCSR_DIAG_RD_DONE 0x00000800
+#define EBUS_DCSR_DIAG_WR_DONE 0x00001000
+#define EBUS_DCSR_EN_CNT       0x00002000
+#define EBUS_DCSR_TC           0x00004000
+#define EBUS_DCSR_DIS_CSR_DRN  0x00010000
+#define EBUS_DCSR_BURST_SZ_MASK        0x000c0000
+#define EBUS_DCSR_BURST_SZ_1   0x00080000
+#define EBUS_DCSR_BURST_SZ_4   0x00000000
+#define EBUS_DCSR_BURST_SZ_8   0x00040000
+#define EBUS_DCSR_BURST_SZ_16  0x000c0000
+#define EBUS_DCSR_DIAG_EN      0x00100000
+#define EBUS_DCSR_DIS_ERR_PEND 0x00400000
+#define EBUS_DCSR_TCI_DIS      0x00800000
+#define EBUS_DCSR_EN_NEXT      0x01000000
+#define EBUS_DCSR_DMA_ON       0x02000000
+#define EBUS_DCSR_A_LOADED     0x04000000
+#define EBUS_DCSR_NA_LOADED    0x08000000
+#define EBUS_DCSR_DEV_ID_MASK  0xf0000000
+
+extern struct linux_ebus               *ebus_chain;
+
+extern void ebus_init(void);
+
+#define for_each_ebus(bus)                                             \
+        for((bus) = ebus_chain; (bus); (bus) = (bus)->next)
+
+#define for_each_ebusdev(dev, bus)                                     \
+        for((dev) = (bus)->devices; (dev); (dev) = (dev)->next)
+
+#define for_each_edevchild(dev, child)                                 \
+        for((child) = (dev)->children; (child); (child) = (child)->next)
+
+#endif /* !(__SPARC_EBUS_H) */
diff --git a/include/asm-sparc/ebus_64.h b/include/asm-sparc/ebus_64.h
new file mode 100644 (file)
index 0000000..fcc62b9
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * ebus.h: PCI to Ebus pseudo driver software state.
+ *
+ * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
+ * Copyright (C) 1999 David S. Miller (davem@redhat.com)
+ */
+
+#ifndef __SPARC64_EBUS_H
+#define __SPARC64_EBUS_H
+
+#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
+
+struct linux_ebus_child {
+       struct linux_ebus_child         *next;
+       struct linux_ebus_device        *parent;
+       struct linux_ebus               *bus;
+       struct device_node              *prom_node;
+       struct resource                  resource[PROMREG_MAX];
+       int                              num_addrs;
+       unsigned int                     irqs[PROMINTR_MAX];
+       int                              num_irqs;
+};
+
+struct linux_ebus_device {
+       struct of_device                ofdev;
+       struct linux_ebus_device        *next;
+       struct linux_ebus_child         *children;
+       struct linux_ebus               *bus;
+       struct device_node              *prom_node;
+       struct resource                  resource[PROMREG_MAX];
+       int                              num_addrs;
+       unsigned int                     irqs[PROMINTR_MAX];
+       int                              num_irqs;
+};
+#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev)
+
+struct linux_ebus {
+       struct of_device                ofdev;
+       struct linux_ebus               *next;
+       struct linux_ebus_device        *devices;
+       struct pci_dev                  *self;
+       int                              index;
+       int                              is_rio;
+       struct device_node              *prom_node;
+};
+#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev)
+
+struct ebus_dma_info {
+       spinlock_t      lock;
+       void __iomem    *regs;
+
+       unsigned int    flags;
+#define EBUS_DMA_FLAG_USE_EBDMA_HANDLER                0x00000001
+#define EBUS_DMA_FLAG_TCI_DISABLE              0x00000002
+
+       /* These are only valid is EBUS_DMA_FLAG_USE_EBDMA_HANDLER is
+        * set.
+        */
+       void (*callback)(struct ebus_dma_info *p, int event, void *cookie);
+       void *client_cookie;
+       unsigned int    irq;
+#define EBUS_DMA_EVENT_ERROR   1
+#define EBUS_DMA_EVENT_DMA     2
+#define EBUS_DMA_EVENT_DEVICE  4
+
+       unsigned char   name[64];
+};
+
+extern int ebus_dma_register(struct ebus_dma_info *p);
+extern int ebus_dma_irq_enable(struct ebus_dma_info *p, int on);
+extern void ebus_dma_unregister(struct ebus_dma_info *p);
+extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr,
+                           size_t len);
+extern void ebus_dma_prepare(struct ebus_dma_info *p, int write);
+extern unsigned int ebus_dma_residue(struct ebus_dma_info *p);
+extern unsigned int ebus_dma_addr(struct ebus_dma_info *p);
+extern void ebus_dma_enable(struct ebus_dma_info *p, int on);
+
+extern struct linux_ebus               *ebus_chain;
+
+extern void ebus_init(void);
+
+#define for_each_ebus(bus)                                             \
+        for((bus) = ebus_chain; (bus); (bus) = (bus)->next)
+
+#define for_each_ebusdev(dev, bus)                                     \
+        for((dev) = (bus)->devices; (dev); (dev) = (dev)->next)
+
+#define for_each_edevchild(dev, child)                                 \
+        for((child) = (dev)->children; (child); (child) = (child)->next)
+
+#endif /* !(__SPARC64_EBUS_H) */
index d043f80bc2fd4b858a260c91d00e1592bc780caf..f035c45d7b5e3ee4f02fce36767775fd85083cb3 100644 (file)
@@ -1,145 +1,8 @@
-#ifndef __ASMSPARC_ELF_H
-#define __ASMSPARC_ELF_H
-
-/*
- * ELF register definitions..
- */
-
-#include <asm/ptrace.h>
-
-/*
- * Sparc section types
- */
-#define STT_REGISTER           13
-
-/*
- * Sparc ELF relocation types
- */
-#define        R_SPARC_NONE            0
-#define        R_SPARC_8               1
-#define        R_SPARC_16              2
-#define        R_SPARC_32              3
-#define        R_SPARC_DISP8           4
-#define        R_SPARC_DISP16          5
-#define        R_SPARC_DISP32          6
-#define        R_SPARC_WDISP30         7
-#define        R_SPARC_WDISP22         8
-#define        R_SPARC_HI22            9
-#define        R_SPARC_22              10
-#define        R_SPARC_13              11
-#define        R_SPARC_LO10            12
-#define        R_SPARC_GOT10           13
-#define        R_SPARC_GOT13           14
-#define        R_SPARC_GOT22           15
-#define        R_SPARC_PC10            16
-#define        R_SPARC_PC22            17
-#define        R_SPARC_WPLT30          18
-#define        R_SPARC_COPY            19
-#define        R_SPARC_GLOB_DAT        20
-#define        R_SPARC_JMP_SLOT        21
-#define        R_SPARC_RELATIVE        22
-#define        R_SPARC_UA32            23
-#define R_SPARC_PLT32          24
-#define R_SPARC_HIPLT22                25
-#define R_SPARC_LOPLT10                26
-#define R_SPARC_PCPLT32                27
-#define R_SPARC_PCPLT22                28
-#define R_SPARC_PCPLT10                29
-#define R_SPARC_10             30
-#define R_SPARC_11             31
-#define R_SPARC_64             32
-#define R_SPARC_OLO10          33
-#define R_SPARC_WDISP16                40
-#define R_SPARC_WDISP19                41
-#define R_SPARC_7              43
-#define R_SPARC_5              44
-#define R_SPARC_6              45
-
-/* Bits present in AT_HWCAP, primarily for Sparc32.  */
-
-#define HWCAP_SPARC_FLUSH       1    /* CPU supports flush instruction. */
-#define HWCAP_SPARC_STBAR       2
-#define HWCAP_SPARC_SWAP        4
-#define HWCAP_SPARC_MULDIV      8
-#define HWCAP_SPARC_V9         16
-#define HWCAP_SPARC_ULTRA3     32
-
-#define CORE_DUMP_USE_REGSET
-
-/* Format is:
- *     G0 --> G7
- *     O0 --> O7
- *     L0 --> L7
- *     I0 --> I7
- *     PSR, PC, nPC, Y, WIM, TBR
- */
-typedef unsigned long elf_greg_t;
-#define ELF_NGREG 38
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct {
-       union {
-               unsigned long   pr_regs[32];
-               double          pr_dregs[16];
-       } pr_fr;
-       unsigned long __unused;
-       unsigned long   pr_fsr;
-       unsigned char   pr_qcnt;
-       unsigned char   pr_q_entrysize;
-       unsigned char   pr_en;
-       unsigned int    pr_q[64];
-} elf_fpregset_t;
-
-#include <asm/mbus.h>
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ((x)->e_machine == EM_SPARC)
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_ARCH       EM_SPARC
-#define ELF_CLASS      ELFCLASS32
-#define ELF_DATA       ELFDATA2MSB
-
-#define USE_ELF_CORE_DUMP
-#ifndef CONFIG_SUN4
-#define ELF_EXEC_PAGESIZE      4096
+#ifndef ___ASM_SPARC_ELF_H
+#define ___ASM_SPARC_ELF_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/elf_64.h>
 #else
-#define ELF_EXEC_PAGESIZE      8192
+#include <asm-sparc/elf_32.h>
+#endif
 #endif
-
-
-/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
-   use of this is to invoke "./ld.so someprog" to test out a new version of
-   the loader.  We need to make sure that it is out of the way of the program
-   that it will "exec", and that there is sufficient room for the brk.  */
-
-#define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
-
-/* This yields a mask that user programs can use to figure out what
-   instruction set this cpu supports.  This can NOT be done in userspace
-   on Sparc.  */
-
-/* Sun4c has none of the capabilities, most sun4m's have them all.
- * XXX This is gross, set some global variable at boot time. -DaveM
- */
-#define ELF_HWCAP      ((ARCH_SUN4C_SUN4) ? 0 : \
-                        (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \
-                         HWCAP_SPARC_SWAP | \
-                         ((srmmu_modtype != Cypress && \
-                           srmmu_modtype != Cypress_vE && \
-                           srmmu_modtype != Cypress_vD) ? \
-                          HWCAP_SPARC_MULDIV : 0)))
-
-/* This yields a string that ld.so will use to load implementation
-   specific libraries for optimization.  This is more specific in
-   intent than poking at uname or /proc/cpuinfo. */
-
-#define ELF_PLATFORM   (NULL)
-
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
-
-#endif /* !(__ASMSPARC_ELF_H) */
diff --git a/include/asm-sparc/elf_32.h b/include/asm-sparc/elf_32.h
new file mode 100644 (file)
index 0000000..d043f80
--- /dev/null
@@ -0,0 +1,145 @@
+#ifndef __ASMSPARC_ELF_H
+#define __ASMSPARC_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+
+/*
+ * Sparc section types
+ */
+#define STT_REGISTER           13
+
+/*
+ * Sparc ELF relocation types
+ */
+#define        R_SPARC_NONE            0
+#define        R_SPARC_8               1
+#define        R_SPARC_16              2
+#define        R_SPARC_32              3
+#define        R_SPARC_DISP8           4
+#define        R_SPARC_DISP16          5
+#define        R_SPARC_DISP32          6
+#define        R_SPARC_WDISP30         7
+#define        R_SPARC_WDISP22         8
+#define        R_SPARC_HI22            9
+#define        R_SPARC_22              10
+#define        R_SPARC_13              11
+#define        R_SPARC_LO10            12
+#define        R_SPARC_GOT10           13
+#define        R_SPARC_GOT13           14
+#define        R_SPARC_GOT22           15
+#define        R_SPARC_PC10            16
+#define        R_SPARC_PC22            17
+#define        R_SPARC_WPLT30          18
+#define        R_SPARC_COPY            19
+#define        R_SPARC_GLOB_DAT        20
+#define        R_SPARC_JMP_SLOT        21
+#define        R_SPARC_RELATIVE        22
+#define        R_SPARC_UA32            23
+#define R_SPARC_PLT32          24
+#define R_SPARC_HIPLT22                25
+#define R_SPARC_LOPLT10                26
+#define R_SPARC_PCPLT32                27
+#define R_SPARC_PCPLT22                28
+#define R_SPARC_PCPLT10                29
+#define R_SPARC_10             30
+#define R_SPARC_11             31
+#define R_SPARC_64             32
+#define R_SPARC_OLO10          33
+#define R_SPARC_WDISP16                40
+#define R_SPARC_WDISP19                41
+#define R_SPARC_7              43
+#define R_SPARC_5              44
+#define R_SPARC_6              45
+
+/* Bits present in AT_HWCAP, primarily for Sparc32.  */
+
+#define HWCAP_SPARC_FLUSH       1    /* CPU supports flush instruction. */
+#define HWCAP_SPARC_STBAR       2
+#define HWCAP_SPARC_SWAP        4
+#define HWCAP_SPARC_MULDIV      8
+#define HWCAP_SPARC_V9         16
+#define HWCAP_SPARC_ULTRA3     32
+
+#define CORE_DUMP_USE_REGSET
+
+/* Format is:
+ *     G0 --> G7
+ *     O0 --> O7
+ *     L0 --> L7
+ *     I0 --> I7
+ *     PSR, PC, nPC, Y, WIM, TBR
+ */
+typedef unsigned long elf_greg_t;
+#define ELF_NGREG 38
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct {
+       union {
+               unsigned long   pr_regs[32];
+               double          pr_dregs[16];
+       } pr_fr;
+       unsigned long __unused;
+       unsigned long   pr_fsr;
+       unsigned char   pr_qcnt;
+       unsigned char   pr_q_entrysize;
+       unsigned char   pr_en;
+       unsigned int    pr_q[64];
+} elf_fpregset_t;
+
+#include <asm/mbus.h>
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_SPARC)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_ARCH       EM_SPARC
+#define ELF_CLASS      ELFCLASS32
+#define ELF_DATA       ELFDATA2MSB
+
+#define USE_ELF_CORE_DUMP
+#ifndef CONFIG_SUN4
+#define ELF_EXEC_PAGESIZE      4096
+#else
+#define ELF_EXEC_PAGESIZE      8192
+#endif
+
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  This can NOT be done in userspace
+   on Sparc.  */
+
+/* Sun4c has none of the capabilities, most sun4m's have them all.
+ * XXX This is gross, set some global variable at boot time. -DaveM
+ */
+#define ELF_HWCAP      ((ARCH_SUN4C_SUN4) ? 0 : \
+                        (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \
+                         HWCAP_SPARC_SWAP | \
+                         ((srmmu_modtype != Cypress && \
+                           srmmu_modtype != Cypress_vE && \
+                           srmmu_modtype != Cypress_vD) ? \
+                          HWCAP_SPARC_MULDIV : 0)))
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo. */
+
+#define ELF_PLATFORM   (NULL)
+
+#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+
+#endif /* !(__ASMSPARC_ELF_H) */
diff --git a/include/asm-sparc/elf_64.h b/include/asm-sparc/elf_64.h
new file mode 100644 (file)
index 0000000..0818a13
--- /dev/null
@@ -0,0 +1,217 @@
+#ifndef __ASM_SPARC64_ELF_H
+#define __ASM_SPARC64_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/spitfire.h>
+
+/*
+ * Sparc section types
+ */
+#define STT_REGISTER           13
+
+/*
+ * Sparc ELF relocation types
+ */
+#define        R_SPARC_NONE            0
+#define        R_SPARC_8               1
+#define        R_SPARC_16              2
+#define        R_SPARC_32              3
+#define        R_SPARC_DISP8           4
+#define        R_SPARC_DISP16          5
+#define        R_SPARC_DISP32          6
+#define        R_SPARC_WDISP30         7
+#define        R_SPARC_WDISP22         8
+#define        R_SPARC_HI22            9
+#define        R_SPARC_22              10
+#define        R_SPARC_13              11
+#define        R_SPARC_LO10            12
+#define        R_SPARC_GOT10           13
+#define        R_SPARC_GOT13           14
+#define        R_SPARC_GOT22           15
+#define        R_SPARC_PC10            16
+#define        R_SPARC_PC22            17
+#define        R_SPARC_WPLT30          18
+#define        R_SPARC_COPY            19
+#define        R_SPARC_GLOB_DAT        20
+#define        R_SPARC_JMP_SLOT        21
+#define        R_SPARC_RELATIVE        22
+#define        R_SPARC_UA32            23
+#define R_SPARC_PLT32          24
+#define R_SPARC_HIPLT22                25
+#define R_SPARC_LOPLT10                26
+#define R_SPARC_PCPLT32                27
+#define R_SPARC_PCPLT22                28
+#define R_SPARC_PCPLT10                29
+#define R_SPARC_10             30
+#define R_SPARC_11             31
+#define R_SPARC_64             32
+#define R_SPARC_OLO10          33
+#define R_SPARC_WDISP16                40
+#define R_SPARC_WDISP19                41
+#define R_SPARC_7              43
+#define R_SPARC_5              44
+#define R_SPARC_6              45
+
+/* Bits present in AT_HWCAP, primarily for Sparc32.  */
+
+#define HWCAP_SPARC_FLUSH       1    /* CPU supports flush instruction. */
+#define HWCAP_SPARC_STBAR       2
+#define HWCAP_SPARC_SWAP        4
+#define HWCAP_SPARC_MULDIV      8
+#define HWCAP_SPARC_V9         16
+#define HWCAP_SPARC_ULTRA3     32
+#define HWCAP_SPARC_BLKINIT    64
+#define HWCAP_SPARC_N2         128
+
+#define CORE_DUMP_USE_REGSET
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_ARCH               EM_SPARCV9
+#define ELF_CLASS              ELFCLASS64
+#define ELF_DATA               ELFDATA2MSB
+
+/* Format of 64-bit elf_gregset_t is:
+ *     G0 --> G7
+ *     O0 --> O7
+ *     L0 --> L7
+ *     I0 --> I7
+ *     TSTATE
+ *     TPC
+ *     TNPC
+ *     Y
+ */
+typedef unsigned long elf_greg_t;
+#define ELF_NGREG 36
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct {
+       unsigned long   pr_regs[32];
+       unsigned long   pr_fsr;
+       unsigned long   pr_gsr;
+       unsigned long   pr_fprs;
+} elf_fpregset_t;
+
+/* Format of 32-bit elf_gregset_t is:
+ *     G0 --> G7
+ *     O0 --> O7
+ *     L0 --> L7
+ *     I0 --> I7
+ *     PSR, PC, nPC, Y, WIM, TBR
+ */
+typedef unsigned int compat_elf_greg_t;
+#define COMPAT_ELF_NGREG 38
+typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
+
+typedef struct {
+       union {
+               unsigned int    pr_regs[32];
+               unsigned long   pr_dregs[16];
+       } pr_fr;
+       unsigned int __unused;
+       unsigned int    pr_fsr;
+       unsigned char   pr_qcnt;
+       unsigned char   pr_q_entrysize;
+       unsigned char   pr_en;
+       unsigned int    pr_q[64];
+} compat_elf_fpregset_t;
+
+/* UltraSparc extensions.  Still unused, but will be eventually.  */
+typedef struct {
+       unsigned int pr_type;
+       unsigned int pr_align;
+       union {
+               struct {
+                       union {
+                               unsigned int    pr_regs[32];
+                               unsigned long   pr_dregs[16];
+                               long double     pr_qregs[8];
+                       } pr_xfr;
+               } pr_v8p;
+               unsigned int    pr_xfsr;
+               unsigned int    pr_fprs;
+               unsigned int    pr_xg[8];
+               unsigned int    pr_xo[8];
+               unsigned long   pr_tstate;
+               unsigned int    pr_filler[8];
+       } pr_un;
+} elf_xregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x)              ((x)->e_machine == ELF_ARCH)
+#define compat_elf_check_arch(x)       ((x)->e_machine == EM_SPARC || \
+                                        (x)->e_machine == EM_SPARC32PLUS)
+#define compat_start_thread            start_thread32
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE      PAGE_SIZE
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE                0x0000010000000000UL
+#define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
+
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  */
+
+/* On Ultra, we support all of the v8 capabilities. */
+static inline unsigned int sparc64_elf_hwcap(void)
+{
+       unsigned int cap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR |
+                           HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV |
+                           HWCAP_SPARC_V9);
+
+       if (tlb_type == cheetah || tlb_type == cheetah_plus)
+               cap |= HWCAP_SPARC_ULTRA3;
+       else if (tlb_type == hypervisor) {
+               if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 ||
+                   sun4v_chip_type == SUN4V_CHIP_NIAGARA2)
+                       cap |= HWCAP_SPARC_BLKINIT;
+               if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2)
+                       cap |= HWCAP_SPARC_N2;
+       }
+
+       return cap;
+}
+
+#define ELF_HWCAP      sparc64_elf_hwcap();
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.  */
+
+#define ELF_PLATFORM   (NULL)
+
+#define SET_PERSONALITY(ex, ibcs2)                     \
+do {   unsigned long new_flags = current_thread_info()->flags; \
+       new_flags &= _TIF_32BIT;                        \
+       if ((ex).e_ident[EI_CLASS] == ELFCLASS32)       \
+               new_flags |= _TIF_32BIT;                \
+       else                                            \
+               new_flags &= ~_TIF_32BIT;               \
+       if ((current_thread_info()->flags & _TIF_32BIT) \
+           != new_flags)                               \
+               set_thread_flag(TIF_ABI_PENDING);       \
+       else                                            \
+               clear_thread_flag(TIF_ABI_PENDING);     \
+       /* flush_thread will update pgd cache */        \
+       if (ibcs2)                                      \
+               set_personality(PER_SVR4);              \
+       else if (current->personality != PER_LINUX32)   \
+               set_personality(PER_LINUX);             \
+} while (0)
+
+#endif /* !(__ASM_SPARC64_ELF_H) */
diff --git a/include/asm-sparc/envctrl.h b/include/asm-sparc/envctrl.h
new file mode 100644 (file)
index 0000000..624fa7e
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ *
+ * envctrl.h: Definitions for access to the i2c environment
+ *            monitoring on Ultrasparc systems.
+ *
+ * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
+ * Copyright (C) 2000  Vinh Truong  (vinh.truong@eng.sun.com)
+ * VT - Add all ioctl commands and environment status definitions
+ * VT - Add application note
+ */
+#ifndef _SPARC64_ENVCTRL_H
+#define _SPARC64_ENVCTRL_H 1
+
+#include <linux/ioctl.h>
+
+/* Application note:
+ *
+ * The driver supports 4 operations: open(), close(), ioctl(), read()
+ * The device name is /dev/envctrl.
+ * Below is sample usage:
+ *
+ *     fd = open("/dev/envtrl", O_RDONLY);
+ *     if (ioctl(fd, ENVCTRL_READ_SHUTDOWN_TEMPERATURE, 0) < 0)
+ *             printf("error\n");
+ *     ret = read(fd, buf, 10);
+ *     close(fd);
+ *
+ * Notice in the case of cpu voltage and temperature, the default is
+ * cpu0.  If we need to know the info of cpu1, cpu2, cpu3, we need to
+ * pass in cpu number in ioctl() last parameter.  For example, to
+ * get the voltage of cpu2:
+ *
+ *     ioctlbuf[0] = 2;
+ *     if (ioctl(fd, ENVCTRL_READ_CPU_VOLTAGE, ioctlbuf) < 0)
+ *             printf("error\n");
+ *     ret = read(fd, buf, 10);
+ *
+ * All the return values are in ascii.  So check read return value
+ * and do appropriate conversions in your application.
+ */
+
+/* IOCTL commands */
+
+/* Note: these commands reflect possible monitor features.
+ * Some boards choose to support some of the features only.
+ */
+#define ENVCTRL_RD_CPU_TEMPERATURE     _IOR('p', 0x40, int)
+#define ENVCTRL_RD_CPU_VOLTAGE         _IOR('p', 0x41, int)
+#define ENVCTRL_RD_FAN_STATUS          _IOR('p', 0x42, int)
+#define ENVCTRL_RD_WARNING_TEMPERATURE _IOR('p', 0x43, int)
+#define ENVCTRL_RD_SHUTDOWN_TEMPERATURE        _IOR('p', 0x44, int)
+#define ENVCTRL_RD_VOLTAGE_STATUS      _IOR('p', 0x45, int)
+#define ENVCTRL_RD_SCSI_TEMPERATURE    _IOR('p', 0x46, int)
+#define ENVCTRL_RD_ETHERNET_TEMPERATURE        _IOR('p', 0x47, int)
+#define ENVCTRL_RD_MTHRBD_TEMPERATURE  _IOR('p', 0x48, int)
+
+#define ENVCTRL_RD_GLOBALADDRESS       _IOR('p', 0x49, int)
+
+/* Read return values for a voltage status request. */
+#define ENVCTRL_VOLTAGE_POWERSUPPLY_GOOD       0x01
+#define ENVCTRL_VOLTAGE_BAD                    0x02
+#define ENVCTRL_POWERSUPPLY_BAD                        0x03
+#define ENVCTRL_VOLTAGE_POWERSUPPLY_BAD                0x04
+
+/* Read return values for a fan status request.
+ * A failure match means either the fan fails or
+ * the fan is not connected.  Some boards have optional
+ * connectors to connect extra fans.
+ *
+ * There are maximum 8 monitor fans.  Some are cpu fans
+ * some are system fans.  The mask below only indicates
+ * fan by order number.
+ * Below is a sample application:
+ *
+ *     if (ioctl(fd, ENVCTRL_READ_FAN_STATUS, 0) < 0) {
+ *             printf("ioctl fan failed\n");
+ *     }
+ *     if (read(fd, rslt, 1) <= 0) {
+ *             printf("error or fan not monitored\n");
+ *     } else {
+ *             if (rslt[0] == ENVCTRL_ALL_FANS_GOOD) {
+ *                     printf("all fans good\n");
+ *     } else if (rslt[0] == ENVCTRL_ALL_FANS_BAD) {
+ *             printf("all fans bad\n");
+ *     } else {
+ *             if (rslt[0] & ENVCTRL_FAN0_FAILURE_MASK) {
+ *                     printf("fan 0 failed or not connected\n");
+ *     }
+ *     ......
+ */
+
+#define ENVCTRL_ALL_FANS_GOOD                  0x00
+#define ENVCTRL_FAN0_FAILURE_MASK              0x01
+#define ENVCTRL_FAN1_FAILURE_MASK              0x02
+#define ENVCTRL_FAN2_FAILURE_MASK              0x04
+#define ENVCTRL_FAN3_FAILURE_MASK              0x08
+#define ENVCTRL_FAN4_FAILURE_MASK              0x10
+#define ENVCTRL_FAN5_FAILURE_MASK              0x20
+#define ENVCTRL_FAN6_FAILURE_MASK              0x40
+#define ENVCTRL_FAN7_FAILURE_MASK              0x80
+#define ENVCTRL_ALL_FANS_BAD                   0xFF
+
+#endif /* !(_SPARC64_ENVCTRL_H) */
diff --git a/include/asm-sparc/estate.h b/include/asm-sparc/estate.h
new file mode 100644 (file)
index 0000000..520c085
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef _SPARC64_ESTATE_H
+#define _SPARC64_ESTATE_H
+
+/* UltraSPARC-III E-cache Error Enable */
+#define ESTATE_ERROR_FMT       0x0000000000040000 /* Force MTAG ECC            */
+#define ESTATE_ERROR_FMESS     0x000000000003c000 /* Forced MTAG ECC val       */
+#define ESTATE_ERROR_FMD       0x0000000000002000 /* Force DATA ECC            */
+#define ESTATE_ERROR_FDECC     0x0000000000001ff0 /* Forced DATA ECC val       */
+#define ESTATE_ERROR_UCEEN     0x0000000000000008 /* See below                 */
+#define ESTATE_ERROR_NCEEN     0x0000000000000002 /* See below                 */
+#define ESTATE_ERROR_CEEN      0x0000000000000001 /* See below                 */
+
+/* UCEEN enables the fast_ECC_error trap for: 1) software correctable E-cache
+ * errors 2) uncorrectable E-cache errors.  Such events only occur on reads
+ * of the E-cache by the local processor for: 1) data loads 2) instruction
+ * fetches 3) atomic operations.  Such events _cannot_ occur for: 1) merge
+ * 2) writeback 2) copyout.  The AFSR bits associated with these traps are
+ * UCC and UCU.
+ */
+
+/* NCEEN enables instruction_access_error, data_access_error, and ECC_error traps
+ * for uncorrectable ECC errors and system errors.
+ *
+ * Uncorrectable system bus data error or MTAG ECC error, system bus TimeOUT,
+ * or system bus BusERR:
+ * 1) As the result of an instruction fetch, will generate instruction_access_error
+ * 2) As the result of a load etc. will generate data_access_error.
+ * 3) As the result of store merge completion, writeback, or copyout will
+ *    generate a disrupting ECC_error trap.
+ * 4) As the result of such errors on instruction vector fetch can generate any
+ *    of the 3 trap types.
+ *
+ * The AFSR bits associated with these traps are EMU, EDU, WDU, CPU, IVU, UE,
+ * BERR, and TO.
+ */
+
+/* CEEN enables the ECC_error trap for hardware corrected ECC errors.  System bus
+ * reads resulting in a hardware corrected data or MTAG ECC error will generate an
+ * ECC_error disrupting trap with this bit enabled.
+ *
+ * This same trap will also be generated when a hardware corrected ECC error results
+ * during store merge, writeback, and copyout operations.
+ */
+
+/* In general, if the trap enable bits above are disabled the AFSR bits will still
+ * log the events even though the trap will not be generated by the processor.
+ */
+
+#endif /* _SPARC64_ESTATE_H */
index c2b27e7a7cad1767532ab97ae494d81c4da35a1a..b9215a0907d3f429352edd0298dbc12dffbb8dca 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef __LINUX_FBIO_H
 #define __LINUX_FBIO_H
 
+#include <linux/compiler.h>
+#include <linux/types.h>
+
 /* Constants used for fbio SunOS compatibility */
 /* (C) 1996 Miguel de Icaza */
 
@@ -38,6 +41,9 @@
 #define FBTYPE_PCI_IGA1682     23
 #define FBTYPE_P9100COLOR      24
 
+#define FBTYPE_PCI_GENERIC     1000
+#define FBTYPE_PCI_MACH64      1001
+
 /* fbio ioctls */
 /* Returned by FBIOGTYPE */
 struct  fbtype {
@@ -97,8 +103,8 @@ struct fbcursor {
         struct fbcurpos hot;    /* cursor hot spot */
         struct fbcmap cmap;     /* color map info */
         struct fbcurpos size;   /* cursor bit map size */
-        char *image;            /* cursor image bits */
-        char *mask;             /* cursor mask bits */
+        char __user *image;     /* cursor image bits */
+        char __user *mask;      /* cursor mask bits */
 };
 
 /* set/get cursor attributes/shape */
@@ -294,4 +300,31 @@ struct fb_clut32 {
 #define LEO_LD_GBL_MAP         0x01009000
 #define LEO_UNK2_MAP           0x0100a000
 
+#ifdef __KERNEL__
+struct  fbcmap32 {
+       int             index;          /* first element (0 origin) */
+       int             count;
+       u32             red;
+       u32             green;
+       u32             blue;
+};
+
+#define FBIOPUTCMAP32  _IOW('F', 3, struct fbcmap32)
+#define FBIOGETCMAP32  _IOW('F', 4, struct fbcmap32)
+
+struct fbcursor32 {
+       short set;              /* what to set, choose from the list above */
+       short enable;           /* cursor on/off */
+       struct fbcurpos pos;    /* cursor position */
+       struct fbcurpos hot;    /* cursor hot spot */
+       struct fbcmap32 cmap;   /* color map info */
+       struct fbcurpos size;   /* cursor bit map size */
+       u32     image;          /* cursor image bits */
+       u32     mask;           /* cursor mask bits */
+};
+
+#define FBIOSCURSOR32  _IOW('F', 24, struct fbcursor32)
+#define FBIOGCURSOR32  _IOW('F', 25, struct fbcursor32)
+#endif
+
 #endif /* __LINUX_FBIO_H */
index 07bd2d80257fa83134346a20280bdeb3186bb753..d4d9c9d852c3d6324621689995fe637c51cdaa94 100644 (file)
 #define O_EXCL         0x0800  /* not fcntl */
 #define O_SYNC         0x2000
 #define O_NONBLOCK     0x4000
+#if defined(__sparc__) && defined(__arch64__)
+#define O_NDELAY       0x0004
+#else
 #define O_NDELAY       (0x0004 | O_NONBLOCK)
+#endif
 #define O_NOCTTY       0x8000  /* not fcntl */
 #define O_LARGEFILE    0x40000
 #define O_DIRECT        0x100000 /* direct disk access hint */
diff --git a/include/asm-sparc/fhc.h b/include/asm-sparc/fhc.h
new file mode 100644 (file)
index 0000000..788cbc4
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * fhc.h: Structures for central/fhc pseudo driver on Sunfire/Starfire/Wildfire.
+ *
+ * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com)
+ */
+
+#ifndef _SPARC64_FHC_H
+#define _SPARC64_FHC_H
+
+#include <linux/timer.h>
+
+#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/upa.h>
+
+struct linux_fhc;
+
+/* Clock board register offsets. */
+#define CLOCK_CTRL     0x00UL  /* Main control */
+#define CLOCK_STAT1    0x10UL  /* Status one */
+#define CLOCK_STAT2    0x20UL  /* Status two */
+#define CLOCK_PWRSTAT  0x30UL  /* Power status */
+#define CLOCK_PWRPRES  0x40UL  /* Power presence */
+#define CLOCK_TEMP     0x50UL  /* Temperature */
+#define CLOCK_IRQDIAG  0x60UL  /* IRQ diagnostics */
+#define CLOCK_PWRSTAT2 0x70UL  /* Power status two */
+
+#define CLOCK_CTRL_LLED                0x04    /* Left LED, 0 == on */
+#define CLOCK_CTRL_MLED                0x02    /* Mid LED, 1 == on */
+#define CLOCK_CTRL_RLED                0x01    /* RIght LED, 1 == on */
+
+struct linux_central {
+       struct linux_fhc                *child;
+       unsigned long                   cfreg;
+       unsigned long                   clkregs;
+       unsigned long                   clkver;
+       int                             slots;
+       struct device_node              *prom_node;
+
+       struct linux_prom_ranges        central_ranges[PROMREG_MAX];
+       int                             num_central_ranges;
+};
+
+/* Firehose controller register offsets */
+struct fhc_regs {
+       unsigned long                   pregs;  /* FHC internal regs */
+#define FHC_PREGS_ID   0x00UL  /* FHC ID */
+#define  FHC_ID_VERS           0xf0000000 /* Version of this FHC               */
+#define  FHC_ID_PARTID         0x0ffff000 /* Part ID code (0x0f9f == FHC)      */
+#define  FHC_ID_MANUF          0x0000007e /* Manufacturer (0x3e == SUN's JEDEC)*/
+#define  FHC_ID_RESV           0x00000001 /* Read as one                       */
+#define FHC_PREGS_RCS  0x10UL  /* FHC Reset Control/Status Register */
+#define  FHC_RCS_POR           0x80000000 /* Last reset was a power cycle      */
+#define  FHC_RCS_SPOR          0x40000000 /* Last reset was sw power on reset  */
+#define  FHC_RCS_SXIR          0x20000000 /* Last reset was sw XIR reset       */
+#define  FHC_RCS_BPOR          0x10000000 /* Last reset was due to POR button  */
+#define  FHC_RCS_BXIR          0x08000000 /* Last reset was due to XIR button  */
+#define  FHC_RCS_WEVENT                0x04000000 /* CPU reset was due to wakeup event */
+#define  FHC_RCS_CFATAL                0x02000000 /* Centerplane Fatal Error signalled */
+#define  FHC_RCS_FENAB         0x01000000 /* Fatal errors elicit system reset  */
+#define FHC_PREGS_CTRL 0x20UL  /* FHC Control Register */
+#define  FHC_CONTROL_ICS       0x00100000 /* Ignore Centerplane Signals        */
+#define  FHC_CONTROL_FRST      0x00080000 /* Fatal Error Reset Enable          */
+#define  FHC_CONTROL_LFAT      0x00040000 /* AC/DC signalled a local error     */
+#define  FHC_CONTROL_SLINE     0x00010000 /* Firmware Synchronization Line     */
+#define  FHC_CONTROL_DCD       0x00008000 /* DC-->DC Converter Disable         */
+#define  FHC_CONTROL_POFF      0x00004000 /* AC/DC Controller PLL Disable      */
+#define  FHC_CONTROL_FOFF      0x00002000 /* FHC Controller PLL Disable        */
+#define  FHC_CONTROL_AOFF      0x00001000 /* CPU A SRAM/SBD Low Power Mode     */
+#define  FHC_CONTROL_BOFF      0x00000800 /* CPU B SRAM/SBD Low Power Mode     */
+#define  FHC_CONTROL_PSOFF     0x00000400 /* Turns off this FHC's power supply */
+#define  FHC_CONTROL_IXIST     0x00000200 /* 0=FHC tells clock board it exists */
+#define  FHC_CONTROL_XMSTR     0x00000100 /* 1=Causes this FHC to be XIR master*/
+#define  FHC_CONTROL_LLED      0x00000040 /* 0=Left LED ON                     */
+#define  FHC_CONTROL_MLED      0x00000020 /* 1=Middle LED ON                   */
+#define  FHC_CONTROL_RLED      0x00000010 /* 1=Right LED                       */
+#define  FHC_CONTROL_BPINS     0x00000003 /* Spare Bidirectional Pins          */
+#define FHC_PREGS_BSR  0x30UL  /* FHC Board Status Register */
+#define  FHC_BSR_DA64          0x00040000 /* Port A: 0=128bit 1=64bit data path */
+#define  FHC_BSR_DB64          0x00020000 /* Port B: 0=128bit 1=64bit data path */
+#define  FHC_BSR_BID           0x0001e000 /* Board ID                           */
+#define  FHC_BSR_SA            0x00001c00 /* Port A UPA Speed (from the pins)   */
+#define  FHC_BSR_SB            0x00000380 /* Port B UPA Speed (from the pins)   */
+#define  FHC_BSR_NDIAG         0x00000040 /* Not in Diag Mode                   */
+#define  FHC_BSR_NTBED         0x00000020 /* Not in TestBED Mode                */
+#define  FHC_BSR_NIA           0x0000001c /* Jumper, bit 18 in PROM space       */
+#define  FHC_BSR_SI            0x00000001 /* Spare input pin value              */
+#define FHC_PREGS_ECC  0x40UL  /* FHC ECC Control Register (16 bits) */
+#define FHC_PREGS_JCTRL        0xf0UL  /* FHC JTAG Control Register */
+#define  FHC_JTAG_CTRL_MENAB   0x80000000 /* Indicates this is JTAG Master      */
+#define  FHC_JTAG_CTRL_MNONE   0x40000000 /* Indicates no JTAG Master present   */
+#define FHC_PREGS_JCMD 0x100UL /* FHC JTAG Command Register */
+       unsigned long                   ireg;   /* FHC IGN reg */
+#define FHC_IREG_IGN   0x00UL  /* This FHC's IGN */
+       unsigned long                   ffregs; /* FHC fanfail regs */
+#define FHC_FFREGS_IMAP        0x00UL  /* FHC Fanfail IMAP */
+#define FHC_FFREGS_ICLR        0x10UL  /* FHC Fanfail ICLR */
+       unsigned long                   sregs;  /* FHC system regs */
+#define FHC_SREGS_IMAP 0x00UL  /* FHC System IMAP */
+#define FHC_SREGS_ICLR 0x10UL  /* FHC System ICLR */
+       unsigned long                   uregs;  /* FHC uart regs */
+#define FHC_UREGS_IMAP 0x00UL  /* FHC Uart IMAP */
+#define FHC_UREGS_ICLR 0x10UL  /* FHC Uart ICLR */
+       unsigned long                   tregs;  /* FHC TOD regs */
+#define FHC_TREGS_IMAP 0x00UL  /* FHC TOD IMAP */
+#define FHC_TREGS_ICLR 0x10UL  /* FHC TOD ICLR */
+};
+
+struct linux_fhc {
+       struct linux_fhc                *next;
+       struct linux_central            *parent;        /* NULL if not central FHC */
+       struct fhc_regs                 fhc_regs;
+       int                             board;
+       int                             jtag_master;
+       struct device_node              *prom_node;
+
+       struct linux_prom_ranges        fhc_ranges[PROMREG_MAX];
+       int                             num_fhc_ranges;
+};
+
+#endif /* !(_SPARC64_FHC_H) */
index d3978e068e2bbb9be764d6150ad7a30a16d12ffe..6c628ba15a8d62ceaccb1e0124457435c478b445 100644 (file)
@@ -1,388 +1,8 @@
-/* asm-sparc/floppy.h: Sparc specific parts of the Floppy driver.
- *
- * Copyright (C) 1995 David S. Miller (davem@davemloft.net)
- */
-
-#ifndef __ASM_SPARC_FLOPPY_H
-#define __ASM_SPARC_FLOPPY_H
-
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/idprom.h>
-#include <asm/machines.h>
-#include <asm/oplib.h>
-#include <asm/auxio.h>
-#include <asm/irq.h>
-
-/* We don't need no stinkin' I/O port allocation crap. */
-#undef release_region
-#undef request_region
-#define release_region(X, Y)   do { } while(0)
-#define request_region(X, Y, Z)        (1)
-
-/* References:
- * 1) Netbsd Sun floppy driver.
- * 2) NCR 82077 controller manual
- * 3) Intel 82077 controller manual
- */
-struct sun_flpy_controller {
-       volatile unsigned char status_82072;  /* Main Status reg. */
-#define dcr_82072              status_82072   /* Digital Control reg. */
-#define status1_82077          status_82072   /* Auxiliary Status reg. 1 */
-
-       volatile unsigned char data_82072;    /* Data fifo. */
-#define status2_82077          data_82072     /* Auxiliary Status reg. 2 */
-
-       volatile unsigned char dor_82077;     /* Digital Output reg. */
-       volatile unsigned char tapectl_82077; /* What the? Tape control reg? */
-
-       volatile unsigned char status_82077;  /* Main Status Register. */
-#define drs_82077              status_82077   /* Digital Rate Select reg. */
-
-       volatile unsigned char data_82077;    /* Data fifo. */
-       volatile unsigned char ___unused;
-       volatile unsigned char dir_82077;     /* Digital Input reg. */
-#define dcr_82077              dir_82077      /* Config Control reg. */
-};
-
-/* You'll only ever find one controller on a SparcStation anyways. */
-static struct sun_flpy_controller *sun_fdc = NULL;
-extern volatile unsigned char *fdc_status;
-
-struct sun_floppy_ops {
-       unsigned char (*fd_inb)(int port);
-       void (*fd_outb)(unsigned char value, int port);
-};
-
-static struct sun_floppy_ops sun_fdops;
-
-#define fd_inb(port)              sun_fdops.fd_inb(port)
-#define fd_outb(value,port)       sun_fdops.fd_outb(value,port)
-#define fd_enable_dma()           sun_fd_enable_dma()
-#define fd_disable_dma()          sun_fd_disable_dma()
-#define fd_request_dma()          (0) /* nothing... */
-#define fd_free_dma()             /* nothing... */
-#define fd_clear_dma_ff()         /* nothing... */
-#define fd_set_dma_mode(mode)     sun_fd_set_dma_mode(mode)
-#define fd_set_dma_addr(addr)     sun_fd_set_dma_addr(addr)
-#define fd_set_dma_count(count)   sun_fd_set_dma_count(count)
-#define fd_enable_irq()           /* nothing... */
-#define fd_disable_irq()          /* nothing... */
-#define fd_cacheflush(addr, size) /* nothing... */
-#define fd_request_irq()          sun_fd_request_irq()
-#define fd_free_irq()             /* nothing... */
-#if 0  /* P3: added by Alain, these cause a MMU corruption. 19960524 XXX */
-#define fd_dma_mem_alloc(size)    ((unsigned long) vmalloc(size))
-#define fd_dma_mem_free(addr,size) (vfree((void *)(addr)))
+#ifndef ___ASM_SPARC_FLOPPY_H
+#define ___ASM_SPARC_FLOPPY_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/floppy_64.h>
+#else
+#include <asm-sparc/floppy_32.h>
+#endif
 #endif
-
-/* XXX This isn't really correct. XXX */
-#define get_dma_residue(x)        (0)
-
-#define FLOPPY0_TYPE  4
-#define FLOPPY1_TYPE  0
-
-/* Super paranoid... */
-#undef HAVE_DISABLE_HLT
-
-/* Here is where we catch the floppy driver trying to initialize,
- * therefore this is where we call the PROM device tree probing
- * routine etc. on the Sparc.
- */
-#define FDC1                      sun_floppy_init()
-
-#define N_FDC    1
-#define N_DRIVE  8
-
-/* No 64k boundary crossing problems on the Sparc. */
-#define CROSS_64KB(a,s) (0)
-
-/* Routines unique to each controller type on a Sun. */
-static void sun_set_dor(unsigned char value, int fdc_82077)
-{
-       if (sparc_cpu_model == sun4c) {
-               unsigned int bits = 0;
-               if (value & 0x10)
-                       bits |= AUXIO_FLPY_DSEL;
-               if ((value & 0x80) == 0)
-                       bits |= AUXIO_FLPY_EJCT;
-               set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT));
-       }
-       if (fdc_82077) {
-               sun_fdc->dor_82077 = value;
-       }
-}
-
-static unsigned char sun_read_dir(void)
-{
-       if (sparc_cpu_model == sun4c)
-               return (get_auxio() & AUXIO_FLPY_DCHG) ? 0x80 : 0;
-       else
-               return sun_fdc->dir_82077;
-}
-
-static unsigned char sun_82072_fd_inb(int port)
-{
-       udelay(5);
-       switch(port & 7) {
-       default:
-               printk("floppy: Asked to read unknown port %d\n", port);
-               panic("floppy: Port bolixed.");
-       case 4: /* FD_STATUS */
-               return sun_fdc->status_82072 & ~STATUS_DMA;
-       case 5: /* FD_DATA */
-               return sun_fdc->data_82072;
-       case 7: /* FD_DIR */
-               return sun_read_dir();
-       };
-       panic("sun_82072_fd_inb: How did I get here?");
-}
-
-static void sun_82072_fd_outb(unsigned char value, int port)
-{
-       udelay(5);
-       switch(port & 7) {
-       default:
-               printk("floppy: Asked to write to unknown port %d\n", port);
-               panic("floppy: Port bolixed.");
-       case 2: /* FD_DOR */
-               sun_set_dor(value, 0);
-               break;
-       case 5: /* FD_DATA */
-               sun_fdc->data_82072 = value;
-               break;
-       case 7: /* FD_DCR */
-               sun_fdc->dcr_82072 = value;
-               break;
-       case 4: /* FD_STATUS */
-               sun_fdc->status_82072 = value;
-               break;
-       };
-       return;
-}
-
-static unsigned char sun_82077_fd_inb(int port)
-{
-       udelay(5);
-       switch(port & 7) {
-       default:
-               printk("floppy: Asked to read unknown port %d\n", port);
-               panic("floppy: Port bolixed.");
-       case 0: /* FD_STATUS_0 */
-               return sun_fdc->status1_82077;
-       case 1: /* FD_STATUS_1 */
-               return sun_fdc->status2_82077;
-       case 2: /* FD_DOR */
-               return sun_fdc->dor_82077;
-       case 3: /* FD_TDR */
-               return sun_fdc->tapectl_82077;
-       case 4: /* FD_STATUS */
-               return sun_fdc->status_82077 & ~STATUS_DMA;
-       case 5: /* FD_DATA */
-               return sun_fdc->data_82077;
-       case 7: /* FD_DIR */
-               return sun_read_dir();
-       };
-       panic("sun_82077_fd_inb: How did I get here?");
-}
-
-static void sun_82077_fd_outb(unsigned char value, int port)
-{
-       udelay(5);
-       switch(port & 7) {
-       default:
-               printk("floppy: Asked to write to unknown port %d\n", port);
-               panic("floppy: Port bolixed.");
-       case 2: /* FD_DOR */
-               sun_set_dor(value, 1);
-               break;
-       case 5: /* FD_DATA */
-               sun_fdc->data_82077 = value;
-               break;
-       case 7: /* FD_DCR */
-               sun_fdc->dcr_82077 = value;
-               break;
-       case 4: /* FD_STATUS */
-               sun_fdc->status_82077 = value;
-               break;
-       case 3: /* FD_TDR */
-               sun_fdc->tapectl_82077 = value;
-               break;
-       };
-       return;
-}
-
-/* For pseudo-dma (Sun floppy drives have no real DMA available to
- * them so we must eat the data fifo bytes directly ourselves) we have
- * three state variables.  doing_pdma tells our inline low-level
- * assembly floppy interrupt entry point whether it should sit and eat
- * bytes from the fifo or just transfer control up to the higher level
- * floppy interrupt c-code.  I tried very hard but I could not get the
- * pseudo-dma to work in c-code without getting many overruns and
- * underruns.  If non-zero, doing_pdma encodes the direction of
- * the transfer for debugging.  1=read 2=write
- */
-extern char *pdma_vaddr;
-extern unsigned long pdma_size;
-extern volatile int doing_pdma;
-
-/* This is software state */
-extern char *pdma_base;
-extern unsigned long pdma_areasize;
-
-/* Common routines to all controller types on the Sparc. */
-static inline void virtual_dma_init(void)
-{
-       /* nothing... */
-}
-
-static inline void sun_fd_disable_dma(void)
-{
-       doing_pdma = 0;
-       if (pdma_base) {
-               mmu_unlockarea(pdma_base, pdma_areasize);
-               pdma_base = NULL;
-       }
-}
-
-static inline void sun_fd_set_dma_mode(int mode)
-{
-       switch(mode) {
-       case DMA_MODE_READ:
-               doing_pdma = 1;
-               break;
-       case DMA_MODE_WRITE:
-               doing_pdma = 2;
-               break;
-       default:
-               printk("Unknown dma mode %d\n", mode);
-               panic("floppy: Giving up...");
-       }
-}
-
-static inline void sun_fd_set_dma_addr(char *buffer)
-{
-       pdma_vaddr = buffer;
-}
-
-static inline void sun_fd_set_dma_count(int length)
-{
-       pdma_size = length;
-}
-
-static inline void sun_fd_enable_dma(void)
-{
-       pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
-       pdma_base = pdma_vaddr;
-       pdma_areasize = pdma_size;
-}
-
-/* Our low-level entry point in arch/sparc/kernel/entry.S */
-extern int sparc_floppy_request_irq(int irq, unsigned long flags,
-                                   irq_handler_t irq_handler);
-
-static int sun_fd_request_irq(void)
-{
-       static int once = 0;
-       int error;
-
-       if(!once) {
-               once = 1;
-               error = sparc_floppy_request_irq(FLOPPY_IRQ,
-                                                IRQF_DISABLED,
-                                                floppy_interrupt);
-               return ((error == 0) ? 0 : -1);
-       } else return 0;
-}
-
-static struct linux_prom_registers fd_regs[2];
-
-static int sun_floppy_init(void)
-{
-       char state[128];
-       int tnode, fd_node, num_regs;
-       struct resource r;
-
-       use_virtual_dma = 1;
-       
-       FLOPPY_IRQ = 11;
-       /* Forget it if we aren't on a machine that could possibly
-        * ever have a floppy drive.
-        */
-       if((sparc_cpu_model != sun4c && sparc_cpu_model != sun4m) ||
-          ((idprom->id_machtype == (SM_SUN4C | SM_4C_SLC)) ||
-           (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC)))) {
-               /* We certainly don't have a floppy controller. */
-               goto no_sun_fdc;
-       }
-       /* Well, try to find one. */
-       tnode = prom_getchild(prom_root_node);
-       fd_node = prom_searchsiblings(tnode, "obio");
-       if(fd_node != 0) {
-               tnode = prom_getchild(fd_node);
-               fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo");
-       } else {
-               fd_node = prom_searchsiblings(tnode, "fd");
-       }
-       if(fd_node == 0) {
-               goto no_sun_fdc;
-       }
-
-       /* The sun4m lets us know if the controller is actually usable. */
-       if(sparc_cpu_model == sun4m &&
-          prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) {
-               if(!strcmp(state, "disabled")) {
-                       goto no_sun_fdc;
-               }
-       }
-       num_regs = prom_getproperty(fd_node, "reg", (char *) fd_regs, sizeof(fd_regs));
-       num_regs = (num_regs / sizeof(fd_regs[0]));
-       prom_apply_obio_ranges(fd_regs, num_regs);
-       memset(&r, 0, sizeof(r));
-       r.flags = fd_regs[0].which_io;
-       r.start = fd_regs[0].phys_addr;
-       sun_fdc = (struct sun_flpy_controller *)
-           sbus_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");
-
-       /* Last minute sanity check... */
-       if(sun_fdc->status_82072 == 0xff) {
-               sun_fdc = NULL;
-               goto no_sun_fdc;
-       }
-
-       sun_fdops.fd_inb = sun_82077_fd_inb;
-       sun_fdops.fd_outb = sun_82077_fd_outb;
-       fdc_status = &sun_fdc->status_82077;
-
-       if (sun_fdc->dor_82077 == 0x80) {
-               sun_fdc->dor_82077 = 0x02;
-               if (sun_fdc->dor_82077 == 0x80) {
-                       sun_fdops.fd_inb = sun_82072_fd_inb;
-                       sun_fdops.fd_outb = sun_82072_fd_outb;
-                       fdc_status = &sun_fdc->status_82072;
-               }
-       }
-
-       /* Success... */
-       allowed_drive_mask = 0x01;
-       return (int) sun_fdc;
-
-no_sun_fdc:
-       return -1;
-}
-
-static int sparc_eject(void)
-{
-       set_dor(0x00, 0xff, 0x90);
-       udelay(500);
-       set_dor(0x00, 0x6f, 0x00);
-       udelay(500);
-       return 0;
-}
-
-#define fd_eject(drive) sparc_eject()
-
-#define EXTRA_FLOPPY_PARAMS
-
-#endif /* !(__ASM_SPARC_FLOPPY_H) */
diff --git a/include/asm-sparc/floppy_32.h b/include/asm-sparc/floppy_32.h
new file mode 100644 (file)
index 0000000..acdd06e
--- /dev/null
@@ -0,0 +1,388 @@
+/* asm-sparc/floppy.h: Sparc specific parts of the Floppy driver.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@davemloft.net)
+ */
+
+#ifndef __ASM_SPARC_FLOPPY_H
+#define __ASM_SPARC_FLOPPY_H
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/idprom.h>
+#include <asm/machines.h>
+#include <asm/oplib.h>
+#include <asm/auxio.h>
+#include <asm/irq.h>
+
+/* We don't need no stinkin' I/O port allocation crap. */
+#undef release_region
+#undef request_region
+#define release_region(X, Y)   do { } while(0)
+#define request_region(X, Y, Z)        (1)
+
+/* References:
+ * 1) Netbsd Sun floppy driver.
+ * 2) NCR 82077 controller manual
+ * 3) Intel 82077 controller manual
+ */
+struct sun_flpy_controller {
+       volatile unsigned char status_82072;  /* Main Status reg. */
+#define dcr_82072              status_82072   /* Digital Control reg. */
+#define status1_82077          status_82072   /* Auxiliary Status reg. 1 */
+
+       volatile unsigned char data_82072;    /* Data fifo. */
+#define status2_82077          data_82072     /* Auxiliary Status reg. 2 */
+
+       volatile unsigned char dor_82077;     /* Digital Output reg. */
+       volatile unsigned char tapectl_82077; /* What the? Tape control reg? */
+
+       volatile unsigned char status_82077;  /* Main Status Register. */
+#define drs_82077              status_82077   /* Digital Rate Select reg. */
+
+       volatile unsigned char data_82077;    /* Data fifo. */
+       volatile unsigned char ___unused;
+       volatile unsigned char dir_82077;     /* Digital Input reg. */
+#define dcr_82077              dir_82077      /* Config Control reg. */
+};
+
+/* You'll only ever find one controller on a SparcStation anyways. */
+static struct sun_flpy_controller *sun_fdc = NULL;
+extern volatile unsigned char *fdc_status;
+
+struct sun_floppy_ops {
+       unsigned char (*fd_inb)(int port);
+       void (*fd_outb)(unsigned char value, int port);
+};
+
+static struct sun_floppy_ops sun_fdops;
+
+#define fd_inb(port)              sun_fdops.fd_inb(port)
+#define fd_outb(value,port)       sun_fdops.fd_outb(value,port)
+#define fd_enable_dma()           sun_fd_enable_dma()
+#define fd_disable_dma()          sun_fd_disable_dma()
+#define fd_request_dma()          (0) /* nothing... */
+#define fd_free_dma()             /* nothing... */
+#define fd_clear_dma_ff()         /* nothing... */
+#define fd_set_dma_mode(mode)     sun_fd_set_dma_mode(mode)
+#define fd_set_dma_addr(addr)     sun_fd_set_dma_addr(addr)
+#define fd_set_dma_count(count)   sun_fd_set_dma_count(count)
+#define fd_enable_irq()           /* nothing... */
+#define fd_disable_irq()          /* nothing... */
+#define fd_cacheflush(addr, size) /* nothing... */
+#define fd_request_irq()          sun_fd_request_irq()
+#define fd_free_irq()             /* nothing... */
+#if 0  /* P3: added by Alain, these cause a MMU corruption. 19960524 XXX */
+#define fd_dma_mem_alloc(size)    ((unsigned long) vmalloc(size))
+#define fd_dma_mem_free(addr,size) (vfree((void *)(addr)))
+#endif
+
+/* XXX This isn't really correct. XXX */
+#define get_dma_residue(x)        (0)
+
+#define FLOPPY0_TYPE  4
+#define FLOPPY1_TYPE  0
+
+/* Super paranoid... */
+#undef HAVE_DISABLE_HLT
+
+/* Here is where we catch the floppy driver trying to initialize,
+ * therefore this is where we call the PROM device tree probing
+ * routine etc. on the Sparc.
+ */
+#define FDC1                      sun_floppy_init()
+
+#define N_FDC    1
+#define N_DRIVE  8
+
+/* No 64k boundary crossing problems on the Sparc. */
+#define CROSS_64KB(a,s) (0)
+
+/* Routines unique to each controller type on a Sun. */
+static void sun_set_dor(unsigned char value, int fdc_82077)
+{
+       if (sparc_cpu_model == sun4c) {
+               unsigned int bits = 0;
+               if (value & 0x10)
+                       bits |= AUXIO_FLPY_DSEL;
+               if ((value & 0x80) == 0)
+                       bits |= AUXIO_FLPY_EJCT;
+               set_auxio(bits, (~bits) & (AUXIO_FLPY_DSEL|AUXIO_FLPY_EJCT));
+       }
+       if (fdc_82077) {
+               sun_fdc->dor_82077 = value;
+       }
+}
+
+static unsigned char sun_read_dir(void)
+{
+       if (sparc_cpu_model == sun4c)
+               return (get_auxio() & AUXIO_FLPY_DCHG) ? 0x80 : 0;
+       else
+               return sun_fdc->dir_82077;
+}
+
+static unsigned char sun_82072_fd_inb(int port)
+{
+       udelay(5);
+       switch(port & 7) {
+       default:
+               printk("floppy: Asked to read unknown port %d\n", port);
+               panic("floppy: Port bolixed.");
+       case 4: /* FD_STATUS */
+               return sun_fdc->status_82072 & ~STATUS_DMA;
+       case 5: /* FD_DATA */
+               return sun_fdc->data_82072;
+       case 7: /* FD_DIR */
+               return sun_read_dir();
+       };
+       panic("sun_82072_fd_inb: How did I get here?");
+}
+
+static void sun_82072_fd_outb(unsigned char value, int port)
+{
+       udelay(5);
+       switch(port & 7) {
+       default:
+               printk("floppy: Asked to write to unknown port %d\n", port);
+               panic("floppy: Port bolixed.");
+       case 2: /* FD_DOR */
+               sun_set_dor(value, 0);
+               break;
+       case 5: /* FD_DATA */
+               sun_fdc->data_82072 = value;
+               break;
+       case 7: /* FD_DCR */
+               sun_fdc->dcr_82072 = value;
+               break;
+       case 4: /* FD_STATUS */
+               sun_fdc->status_82072 = value;
+               break;
+       };
+       return;
+}
+
+static unsigned char sun_82077_fd_inb(int port)
+{
+       udelay(5);
+       switch(port & 7) {
+       default:
+               printk("floppy: Asked to read unknown port %d\n", port);
+               panic("floppy: Port bolixed.");
+       case 0: /* FD_STATUS_0 */
+               return sun_fdc->status1_82077;
+       case 1: /* FD_STATUS_1 */
+               return sun_fdc->status2_82077;
+       case 2: /* FD_DOR */
+               return sun_fdc->dor_82077;
+       case 3: /* FD_TDR */
+               return sun_fdc->tapectl_82077;
+       case 4: /* FD_STATUS */
+               return sun_fdc->status_82077 & ~STATUS_DMA;
+       case 5: /* FD_DATA */
+               return sun_fdc->data_82077;
+       case 7: /* FD_DIR */
+               return sun_read_dir();
+       };
+       panic("sun_82077_fd_inb: How did I get here?");
+}
+
+static void sun_82077_fd_outb(unsigned char value, int port)
+{
+       udelay(5);
+       switch(port & 7) {
+       default:
+               printk("floppy: Asked to write to unknown port %d\n", port);
+               panic("floppy: Port bolixed.");
+       case 2: /* FD_DOR */
+               sun_set_dor(value, 1);
+               break;
+       case 5: /* FD_DATA */
+               sun_fdc->data_82077 = value;
+               break;
+       case 7: /* FD_DCR */
+               sun_fdc->dcr_82077 = value;
+               break;
+       case 4: /* FD_STATUS */
+               sun_fdc->status_82077 = value;
+               break;
+       case 3: /* FD_TDR */
+               sun_fdc->tapectl_82077 = value;
+               break;
+       };
+       return;
+}
+
+/* For pseudo-dma (Sun floppy drives have no real DMA available to
+ * them so we must eat the data fifo bytes directly ourselves) we have
+ * three state variables.  doing_pdma tells our inline low-level
+ * assembly floppy interrupt entry point whether it should sit and eat
+ * bytes from the fifo or just transfer control up to the higher level
+ * floppy interrupt c-code.  I tried very hard but I could not get the
+ * pseudo-dma to work in c-code without getting many overruns and
+ * underruns.  If non-zero, doing_pdma encodes the direction of
+ * the transfer for debugging.  1=read 2=write
+ */
+extern char *pdma_vaddr;
+extern unsigned long pdma_size;
+extern volatile int doing_pdma;
+
+/* This is software state */
+extern char *pdma_base;
+extern unsigned long pdma_areasize;
+
+/* Common routines to all controller types on the Sparc. */
+static inline void virtual_dma_init(void)
+{
+       /* nothing... */
+}
+
+static inline void sun_fd_disable_dma(void)
+{
+       doing_pdma = 0;
+       if (pdma_base) {
+               mmu_unlockarea(pdma_base, pdma_areasize);
+               pdma_base = NULL;
+       }
+}
+
+static inline void sun_fd_set_dma_mode(int mode)
+{
+       switch(mode) {
+       case DMA_MODE_READ:
+               doing_pdma = 1;
+               break;
+       case DMA_MODE_WRITE:
+               doing_pdma = 2;
+               break;
+       default:
+               printk("Unknown dma mode %d\n", mode);
+               panic("floppy: Giving up...");
+       }
+}
+
+static inline void sun_fd_set_dma_addr(char *buffer)
+{
+       pdma_vaddr = buffer;
+}
+
+static inline void sun_fd_set_dma_count(int length)
+{
+       pdma_size = length;
+}
+
+static inline void sun_fd_enable_dma(void)
+{
+       pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
+       pdma_base = pdma_vaddr;
+       pdma_areasize = pdma_size;
+}
+
+/* Our low-level entry point in arch/sparc/kernel/entry.S */
+extern int sparc_floppy_request_irq(int irq, unsigned long flags,
+                                   irq_handler_t irq_handler);
+
+static int sun_fd_request_irq(void)
+{
+       static int once = 0;
+       int error;
+
+       if(!once) {
+               once = 1;
+               error = sparc_floppy_request_irq(FLOPPY_IRQ,
+                                                IRQF_DISABLED,
+                                                floppy_interrupt);
+               return ((error == 0) ? 0 : -1);
+       } else return 0;
+}
+
+static struct linux_prom_registers fd_regs[2];
+
+static int sun_floppy_init(void)
+{
+       char state[128];
+       int tnode, fd_node, num_regs;
+       struct resource r;
+
+       use_virtual_dma = 1;
+
+       FLOPPY_IRQ = 11;
+       /* Forget it if we aren't on a machine that could possibly
+        * ever have a floppy drive.
+        */
+       if((sparc_cpu_model != sun4c && sparc_cpu_model != sun4m) ||
+          ((idprom->id_machtype == (SM_SUN4C | SM_4C_SLC)) ||
+           (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC)))) {
+               /* We certainly don't have a floppy controller. */
+               goto no_sun_fdc;
+       }
+       /* Well, try to find one. */
+       tnode = prom_getchild(prom_root_node);
+       fd_node = prom_searchsiblings(tnode, "obio");
+       if(fd_node != 0) {
+               tnode = prom_getchild(fd_node);
+               fd_node = prom_searchsiblings(tnode, "SUNW,fdtwo");
+       } else {
+               fd_node = prom_searchsiblings(tnode, "fd");
+       }
+       if(fd_node == 0) {
+               goto no_sun_fdc;
+       }
+
+       /* The sun4m lets us know if the controller is actually usable. */
+       if(sparc_cpu_model == sun4m &&
+          prom_getproperty(fd_node, "status", state, sizeof(state)) != -1) {
+               if(!strcmp(state, "disabled")) {
+                       goto no_sun_fdc;
+               }
+       }
+       num_regs = prom_getproperty(fd_node, "reg", (char *) fd_regs, sizeof(fd_regs));
+       num_regs = (num_regs / sizeof(fd_regs[0]));
+       prom_apply_obio_ranges(fd_regs, num_regs);
+       memset(&r, 0, sizeof(r));
+       r.flags = fd_regs[0].which_io;
+       r.start = fd_regs[0].phys_addr;
+       sun_fdc = (struct sun_flpy_controller *)
+           sbus_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");
+
+       /* Last minute sanity check... */
+       if(sun_fdc->status_82072 == 0xff) {
+               sun_fdc = NULL;
+               goto no_sun_fdc;
+       }
+
+       sun_fdops.fd_inb = sun_82077_fd_inb;
+       sun_fdops.fd_outb = sun_82077_fd_outb;
+       fdc_status = &sun_fdc->status_82077;
+
+       if (sun_fdc->dor_82077 == 0x80) {
+               sun_fdc->dor_82077 = 0x02;
+               if (sun_fdc->dor_82077 == 0x80) {
+                       sun_fdops.fd_inb = sun_82072_fd_inb;
+                       sun_fdops.fd_outb = sun_82072_fd_outb;
+                       fdc_status = &sun_fdc->status_82072;
+               }
+       }
+
+       /* Success... */
+       allowed_drive_mask = 0x01;
+       return (int) sun_fdc;
+
+no_sun_fdc:
+       return -1;
+}
+
+static int sparc_eject(void)
+{
+       set_dor(0x00, 0xff, 0x90);
+       udelay(500);
+       set_dor(0x00, 0x6f, 0x00);
+       udelay(500);
+       return 0;
+}
+
+#define fd_eject(drive) sparc_eject()
+
+#define EXTRA_FLOPPY_PARAMS
+
+#endif /* !(__ASM_SPARC_FLOPPY_H) */
diff --git a/include/asm-sparc/floppy_64.h b/include/asm-sparc/floppy_64.h
new file mode 100644 (file)
index 0000000..c39db10
--- /dev/null
@@ -0,0 +1,782 @@
+/* floppy.h: Sparc specific parts of the Floppy driver.
+ *
+ * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ *
+ * Ultra/PCI support added: Sep 1997  Eddie C. Dost  (ecd@skynet.be)
+ */
+
+#ifndef __ASM_SPARC64_FLOPPY_H
+#define __ASM_SPARC64_FLOPPY_H
+
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/idprom.h>
+#include <asm/oplib.h>
+#include <asm/auxio.h>
+#include <asm/sbus.h>
+#include <asm/irq.h>
+
+
+/*
+ * Define this to enable exchanging drive 0 and 1 if only drive 1 is
+ * probed on PCI machines.
+ */
+#undef PCI_FDC_SWAP_DRIVES
+
+
+/* References:
+ * 1) Netbsd Sun floppy driver.
+ * 2) NCR 82077 controller manual
+ * 3) Intel 82077 controller manual
+ */
+struct sun_flpy_controller {
+       volatile unsigned char status1_82077; /* Auxiliary Status reg. 1 */
+       volatile unsigned char status2_82077; /* Auxiliary Status reg. 2 */
+       volatile unsigned char dor_82077;     /* Digital Output reg. */
+       volatile unsigned char tapectl_82077; /* Tape Control reg */
+       volatile unsigned char status_82077;  /* Main Status Register. */
+#define drs_82077              status_82077   /* Digital Rate Select reg. */
+       volatile unsigned char data_82077;    /* Data fifo. */
+       volatile unsigned char ___unused;
+       volatile unsigned char dir_82077;     /* Digital Input reg. */
+#define dcr_82077              dir_82077      /* Config Control reg. */
+};
+
+/* 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 sbus_dev *floppy_sdev = NULL;
+
+struct sun_floppy_ops {
+       unsigned char   (*fd_inb) (unsigned long port);
+       void            (*fd_outb) (unsigned char value, unsigned long port);
+       void            (*fd_enable_dma) (void);
+       void            (*fd_disable_dma) (void);
+       void            (*fd_set_dma_mode) (int);
+       void            (*fd_set_dma_addr) (char *);
+       void            (*fd_set_dma_count) (int);
+       unsigned int    (*get_dma_residue) (void);
+       int             (*fd_request_irq) (void);
+       void            (*fd_free_irq) (void);
+       int             (*fd_eject) (int);
+};
+
+static struct sun_floppy_ops sun_fdops;
+
+#define fd_inb(port)              sun_fdops.fd_inb(port)
+#define fd_outb(value,port)       sun_fdops.fd_outb(value,port)
+#define fd_enable_dma()           sun_fdops.fd_enable_dma()
+#define fd_disable_dma()          sun_fdops.fd_disable_dma()
+#define fd_request_dma()          (0) /* nothing... */
+#define fd_free_dma()             /* nothing... */
+#define fd_clear_dma_ff()         /* nothing... */
+#define fd_set_dma_mode(mode)     sun_fdops.fd_set_dma_mode(mode)
+#define fd_set_dma_addr(addr)     sun_fdops.fd_set_dma_addr(addr)
+#define fd_set_dma_count(count)   sun_fdops.fd_set_dma_count(count)
+#define get_dma_residue(x)        sun_fdops.get_dma_residue()
+#define fd_cacheflush(addr, size) /* nothing... */
+#define fd_request_irq()          sun_fdops.fd_request_irq()
+#define fd_free_irq()             sun_fdops.fd_free_irq()
+#define fd_eject(drive)           sun_fdops.fd_eject(drive)
+
+/* Super paranoid... */
+#undef HAVE_DISABLE_HLT
+
+static int sun_floppy_types[2] = { 0, 0 };
+
+/* Here is where we catch the floppy driver trying to initialize,
+ * therefore this is where we call the PROM device tree probing
+ * routine etc. on the Sparc.
+ */
+#define FLOPPY0_TYPE           sun_floppy_init()
+#define FLOPPY1_TYPE           sun_floppy_types[1]
+
+#define FDC1                   ((unsigned long)sun_fdc)
+
+#define N_FDC    1
+#define N_DRIVE  8
+
+/* No 64k boundary crossing problems on the Sparc. */
+#define CROSS_64KB(a,s) (0)
+
+static unsigned char sun_82077_fd_inb(unsigned long port)
+{
+       udelay(5);
+       switch(port & 7) {
+       default:
+               printk("floppy: Asked to read unknown port %lx\n", port);
+               panic("floppy: Port bolixed.");
+       case 4: /* FD_STATUS */
+               return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA;
+       case 5: /* FD_DATA */
+               return sbus_readb(&sun_fdc->data_82077);
+       case 7: /* FD_DIR */
+               /* XXX: Is DCL on 0x80 in sun4m? */
+               return sbus_readb(&sun_fdc->dir_82077);
+       };
+       panic("sun_82072_fd_inb: How did I get here?");
+}
+
+static void sun_82077_fd_outb(unsigned char value, unsigned long port)
+{
+       udelay(5);
+       switch(port & 7) {
+       default:
+               printk("floppy: Asked to write to unknown port %lx\n", port);
+               panic("floppy: Port bolixed.");
+       case 2: /* FD_DOR */
+               /* Happily, the 82077 has a real DOR register. */
+               sbus_writeb(value, &sun_fdc->dor_82077);
+               break;
+       case 5: /* FD_DATA */
+               sbus_writeb(value, &sun_fdc->data_82077);
+               break;
+       case 7: /* FD_DCR */
+               sbus_writeb(value, &sun_fdc->dcr_82077);
+               break;
+       case 4: /* FD_STATUS */
+               sbus_writeb(value, &sun_fdc->status_82077);
+               break;
+       };
+       return;
+}
+
+/* For pseudo-dma (Sun floppy drives have no real DMA available to
+ * them so we must eat the data fifo bytes directly ourselves) we have
+ * three state variables.  doing_pdma tells our inline low-level
+ * assembly floppy interrupt entry point whether it should sit and eat
+ * bytes from the fifo or just transfer control up to the higher level
+ * floppy interrupt c-code.  I tried very hard but I could not get the
+ * pseudo-dma to work in c-code without getting many overruns and
+ * underruns.  If non-zero, doing_pdma encodes the direction of
+ * the transfer for debugging.  1=read 2=write
+ */
+unsigned char *pdma_vaddr;
+unsigned long pdma_size;
+volatile int doing_pdma = 0;
+
+/* This is software state */
+char *pdma_base = NULL;
+unsigned long pdma_areasize;
+
+/* Common routines to all controller types on the Sparc. */
+static void sun_fd_disable_dma(void)
+{
+       doing_pdma = 0;
+       if (pdma_base) {
+               mmu_unlockarea(pdma_base, pdma_areasize);
+               pdma_base = NULL;
+       }
+}
+
+static void sun_fd_set_dma_mode(int mode)
+{
+       switch(mode) {
+       case DMA_MODE_READ:
+               doing_pdma = 1;
+               break;
+       case DMA_MODE_WRITE:
+               doing_pdma = 2;
+               break;
+       default:
+               printk("Unknown dma mode %d\n", mode);
+               panic("floppy: Giving up...");
+       }
+}
+
+static void sun_fd_set_dma_addr(char *buffer)
+{
+       pdma_vaddr = buffer;
+}
+
+static void sun_fd_set_dma_count(int length)
+{
+       pdma_size = length;
+}
+
+static void sun_fd_enable_dma(void)
+{
+       pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
+       pdma_base = pdma_vaddr;
+       pdma_areasize = pdma_size;
+}
+
+irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie)
+{
+       if (likely(doing_pdma)) {
+               void __iomem *stat = (void __iomem *) fdc_status;
+               unsigned char *vaddr = pdma_vaddr;
+               unsigned long size = pdma_size;
+               u8 val;
+
+               while (size) {
+                       val = readb(stat);
+                       if (unlikely(!(val & 0x80))) {
+                               pdma_vaddr = vaddr;
+                               pdma_size = size;
+                               return IRQ_HANDLED;
+                       }
+                       if (unlikely(!(val & 0x20))) {
+                               pdma_vaddr = vaddr;
+                               pdma_size = size;
+                               doing_pdma = 0;
+                               goto main_interrupt;
+                       }
+                       if (val & 0x40) {
+                               /* read */
+                               *vaddr++ = readb(stat + 1);
+                       } else {
+                               unsigned char data = *vaddr++;
+
+                               /* write */
+                               writeb(data, stat + 1);
+                       }
+                       size--;
+               }
+
+               pdma_vaddr = vaddr;
+               pdma_size = size;
+
+               /* Send Terminal Count pulse to floppy controller. */
+               val = readb(auxio_register);
+               val |= AUXIO_AUX1_FTCNT;
+               writeb(val, auxio_register);
+               val &= ~AUXIO_AUX1_FTCNT;
+               writeb(val, auxio_register);
+
+               doing_pdma = 0;
+       }
+
+main_interrupt:
+       return floppy_interrupt(irq, dev_cookie);
+}
+
+static int sun_fd_request_irq(void)
+{
+       static int once = 0;
+       int error;
+
+       if(!once) {
+               once = 1;
+
+               error = request_irq(FLOPPY_IRQ, sparc_floppy_irq,
+                                   IRQF_DISABLED, "floppy", NULL);
+
+               return ((error == 0) ? 0 : -1);
+       }
+       return 0;
+}
+
+static void sun_fd_free_irq(void)
+{
+}
+
+static unsigned int sun_get_dma_residue(void)
+{
+       /* XXX This isn't really correct. XXX */
+       return 0;
+}
+
+static int sun_fd_eject(int drive)
+{
+       set_dor(0x00, 0xff, 0x90);
+       udelay(500);
+       set_dor(0x00, 0x6f, 0x00);
+       udelay(500);
+       return 0;
+}
+
+#ifdef CONFIG_PCI
+#include <asm/ebus.h>
+#include <asm/ns87303.h>
+
+static struct ebus_dma_info sun_pci_fd_ebus_dma;
+static struct pci_dev *sun_pci_ebus_dev;
+static int sun_pci_broken_drive = -1;
+
+struct sun_pci_dma_op {
+       unsigned int    addr;
+       int             len;
+       int             direction;
+       char            *buf;
+};
+static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
+static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
+
+extern irqreturn_t floppy_interrupt(int irq, void *dev_id);
+
+static unsigned char sun_pci_fd_inb(unsigned long port)
+{
+       udelay(5);
+       return inb(port);
+}
+
+static void sun_pci_fd_outb(unsigned char val, unsigned long port)
+{
+       udelay(5);
+       outb(val, port);
+}
+
+static void sun_pci_fd_broken_outb(unsigned char val, unsigned long port)
+{
+       udelay(5);
+       /*
+        * XXX: Due to SUN's broken floppy connector on AX and AXi
+        *      we need to turn on MOTOR_0 also, if the floppy is
+        *      jumpered to DS1 (like most PC floppies are). I hope
+        *      this does not hurt correct hardware like the AXmp.
+        *      (Eddie, Sep 12 1998).
+        */
+       if (port == ((unsigned long)sun_fdc) + 2) {
+               if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) {
+                       val |= 0x10;
+               }
+       }
+       outb(val, port);
+}
+
+#ifdef PCI_FDC_SWAP_DRIVES
+static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port)
+{
+       udelay(5);
+       /*
+        * XXX: Due to SUN's broken floppy connector on AX and AXi
+        *      we need to turn on MOTOR_0 also, if the floppy is
+        *      jumpered to DS1 (like most PC floppies are). I hope
+        *      this does not hurt correct hardware like the AXmp.
+        *      (Eddie, Sep 12 1998).
+        */
+       if (port == ((unsigned long)sun_fdc) + 2) {
+               if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) {
+                       val &= ~(0x03);
+                       val |= 0x21;
+               }
+       }
+       outb(val, port);
+}
+#endif /* PCI_FDC_SWAP_DRIVES */
+
+static void sun_pci_fd_enable_dma(void)
+{
+       BUG_ON((NULL == sun_pci_dma_pending.buf)        ||
+           (0    == sun_pci_dma_pending.len)   ||
+           (0    == sun_pci_dma_pending.direction));
+
+       sun_pci_dma_current.buf = sun_pci_dma_pending.buf;
+       sun_pci_dma_current.len = sun_pci_dma_pending.len;
+       sun_pci_dma_current.direction = sun_pci_dma_pending.direction;
+
+       sun_pci_dma_pending.buf  = NULL;
+       sun_pci_dma_pending.len  = 0;
+       sun_pci_dma_pending.direction = 0;
+       sun_pci_dma_pending.addr = -1U;
+
+       sun_pci_dma_current.addr =
+               pci_map_single(sun_pci_ebus_dev,
+                              sun_pci_dma_current.buf,
+                              sun_pci_dma_current.len,
+                              sun_pci_dma_current.direction);
+
+       ebus_dma_enable(&sun_pci_fd_ebus_dma, 1);
+
+       if (ebus_dma_request(&sun_pci_fd_ebus_dma,
+                            sun_pci_dma_current.addr,
+                            sun_pci_dma_current.len))
+               BUG();
+}
+
+static void sun_pci_fd_disable_dma(void)
+{
+       ebus_dma_enable(&sun_pci_fd_ebus_dma, 0);
+       if (sun_pci_dma_current.addr != -1U)
+               pci_unmap_single(sun_pci_ebus_dev,
+                                sun_pci_dma_current.addr,
+                                sun_pci_dma_current.len,
+                                sun_pci_dma_current.direction);
+       sun_pci_dma_current.addr = -1U;
+}
+
+static void sun_pci_fd_set_dma_mode(int mode)
+{
+       if (mode == DMA_MODE_WRITE)
+               sun_pci_dma_pending.direction = PCI_DMA_TODEVICE;
+       else
+               sun_pci_dma_pending.direction = PCI_DMA_FROMDEVICE;
+
+       ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE);
+}
+
+static void sun_pci_fd_set_dma_count(int length)
+{
+       sun_pci_dma_pending.len = length;
+}
+
+static void sun_pci_fd_set_dma_addr(char *buffer)
+{
+       sun_pci_dma_pending.buf = buffer;
+}
+
+static unsigned int sun_pci_get_dma_residue(void)
+{
+       return ebus_dma_residue(&sun_pci_fd_ebus_dma);
+}
+
+static int sun_pci_fd_request_irq(void)
+{
+       return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1);
+}
+
+static void sun_pci_fd_free_irq(void)
+{
+       ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0);
+}
+
+static int sun_pci_fd_eject(int drive)
+{
+       return -EINVAL;
+}
+
+void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie)
+{
+       floppy_interrupt(0, NULL);
+}
+
+/*
+ * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI,
+ * even if this is configured using DS1, thus looks like /dev/fd1 with
+ * the cabling used in Ultras.
+ */
+#define DOR    (port + 2)
+#define MSR    (port + 4)
+#define FIFO   (port + 5)
+
+static void sun_pci_fd_out_byte(unsigned long port, unsigned char val,
+                               unsigned long reg)
+{
+       unsigned char status;
+       int timeout = 1000;
+
+       while (!((status = inb(MSR)) & 0x80) && --timeout)
+               udelay(100);
+       outb(val, reg);
+}
+
+static unsigned char sun_pci_fd_sensei(unsigned long port)
+{
+       unsigned char result[2] = { 0x70, 0x00 };
+       unsigned char status;
+       int i = 0;
+
+       sun_pci_fd_out_byte(port, 0x08, FIFO);
+       do {
+               int timeout = 1000;
+
+               while (!((status = inb(MSR)) & 0x80) && --timeout)
+                       udelay(100);
+
+               if (!timeout)
+                       break;
+
+               if ((status & 0xf0) == 0xd0)
+                       result[i++] = inb(FIFO);
+               else
+                       break;
+       } while (i < 2);
+
+       return result[0];
+}
+
+static void sun_pci_fd_reset(unsigned long port)
+{
+       unsigned char mask = 0x00;
+       unsigned char status;
+       int timeout = 10000;
+
+       outb(0x80, MSR);
+       do {
+               status = sun_pci_fd_sensei(port);
+               if ((status & 0xc0) == 0xc0)
+                       mask |= 1 << (status & 0x03);
+               else
+                       udelay(100);
+       } while ((mask != 0x0f) && --timeout);
+}
+
+static int sun_pci_fd_test_drive(unsigned long port, int drive)
+{
+       unsigned char status, data;
+       int timeout = 1000;
+       int ready;
+
+       sun_pci_fd_reset(port);
+
+       data = (0x10 << drive) | 0x0c | drive;
+       sun_pci_fd_out_byte(port, data, DOR);
+
+       sun_pci_fd_out_byte(port, 0x07, FIFO);
+       sun_pci_fd_out_byte(port, drive & 0x03, FIFO);
+
+       do {
+               udelay(100);
+               status = sun_pci_fd_sensei(port);
+       } while (((status & 0xc0) == 0x80) && --timeout);
+
+       if (!timeout)
+               ready = 0;
+       else
+               ready = (status & 0x10) ? 0 : 1;
+
+       sun_pci_fd_reset(port);
+       return ready;
+}
+#undef FIFO
+#undef MSR
+#undef DOR
+
+#endif /* CONFIG_PCI */
+
+#ifdef CONFIG_PCI
+static int __init ebus_fdthree_p(struct linux_ebus_device *edev)
+{
+       if (!strcmp(edev->prom_node->name, "fdthree"))
+               return 1;
+       if (!strcmp(edev->prom_node->name, "floppy")) {
+               const char *compat;
+
+               compat = of_get_property(edev->prom_node,
+                                        "compatible", NULL);
+               if (compat && !strcmp(compat, "fdthree"))
+                       return 1;
+       }
+       return 0;
+}
+#endif
+
+static unsigned long __init sun_floppy_init(void)
+{
+       char state[128];
+       struct sbus_bus *bus;
+       struct sbus_dev *sdev = NULL;
+       static int initialized = 0;
+
+       if (initialized)
+               return sun_floppy_types[0];
+       initialized = 1;
+
+       for_all_sbusdev (sdev, bus) {
+               if (!strcmp(sdev->prom_name, "SUNW,fdtwo"))
+                       break;
+       }
+       if(sdev) {
+               floppy_sdev = sdev;
+               FLOPPY_IRQ = sdev->irqs[0];
+       } else {
+#ifdef CONFIG_PCI
+               struct linux_ebus *ebus;
+               struct linux_ebus_device *edev = NULL;
+               unsigned long config = 0;
+               void __iomem *auxio_reg;
+               const char *state_prop;
+
+               for_each_ebus(ebus) {
+                       for_each_ebusdev(edev, ebus) {
+                               if (ebus_fdthree_p(edev))
+                                       goto ebus_done;
+                       }
+               }
+       ebus_done:
+               if (!edev)
+                       return 0;
+
+               state_prop = of_get_property(edev->prom_node, "status", NULL);
+               if (state_prop && !strncmp(state_prop, "disabled", 8))
+                       return 0;
+
+               FLOPPY_IRQ = edev->irqs[0];
+
+               /* Make sure the high density bit is set, some systems
+                * (most notably Ultra5/Ultra10) come up with it clear.
+                */
+               auxio_reg = (void __iomem *) edev->resource[2].start;
+               writel(readl(auxio_reg)|0x2, auxio_reg);
+
+               sun_pci_ebus_dev = ebus->self;
+
+               spin_lock_init(&sun_pci_fd_ebus_dma.lock);
+
+               /* XXX ioremap */
+               sun_pci_fd_ebus_dma.regs = (void __iomem *)
+                       edev->resource[1].start;
+               if (!sun_pci_fd_ebus_dma.regs)
+                       return 0;
+
+               sun_pci_fd_ebus_dma.flags = (EBUS_DMA_FLAG_USE_EBDMA_HANDLER |
+                                            EBUS_DMA_FLAG_TCI_DISABLE);
+               sun_pci_fd_ebus_dma.callback = sun_pci_fd_dma_callback;
+               sun_pci_fd_ebus_dma.client_cookie = NULL;
+               sun_pci_fd_ebus_dma.irq = FLOPPY_IRQ;
+               strcpy(sun_pci_fd_ebus_dma.name, "floppy");
+               if (ebus_dma_register(&sun_pci_fd_ebus_dma))
+                       return 0;
+
+               /* XXX ioremap */
+               sun_fdc = (struct sun_flpy_controller *)edev->resource[0].start;
+
+               sun_fdops.fd_inb = sun_pci_fd_inb;
+               sun_fdops.fd_outb = sun_pci_fd_outb;
+
+               can_use_virtual_dma = use_virtual_dma = 0;
+               sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma;
+               sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma;
+               sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode;
+               sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr;
+               sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;
+               sun_fdops.get_dma_residue = sun_pci_get_dma_residue;
+
+               sun_fdops.fd_request_irq = sun_pci_fd_request_irq;
+               sun_fdops.fd_free_irq = sun_pci_fd_free_irq;
+
+               sun_fdops.fd_eject = sun_pci_fd_eject;
+
+               fdc_status = (unsigned long) &sun_fdc->status_82077;
+
+               /*
+                * XXX: Find out on which machines this is really needed.
+                */
+               if (1) {
+                       sun_pci_broken_drive = 1;
+                       sun_fdops.fd_outb = sun_pci_fd_broken_outb;
+               }
+
+               allowed_drive_mask = 0;
+               if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0))
+                       sun_floppy_types[0] = 4;
+               if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1))
+                       sun_floppy_types[1] = 4;
+
+               /*
+                * Find NS87303 SuperIO config registers (through ecpp).
+                */
+               for_each_ebus(ebus) {
+                       for_each_ebusdev(edev, ebus) {
+                               if (!strcmp(edev->prom_node->name, "ecpp")) {
+                                       config = edev->resource[1].start;
+                                       goto config_done;
+                               }
+                       }
+               }
+       config_done:
+
+               /*
+                * Sanity check, is this really the NS87303?
+                */
+               switch (config & 0x3ff) {
+               case 0x02e:
+               case 0x15c:
+               case 0x26e:
+               case 0x398:
+                       break;
+               default:
+                       config = 0;
+               }
+
+               if (!config)
+                       return sun_floppy_types[0];
+
+               /* Enable PC-AT mode. */
+               ns87303_modify(config, ASC, 0, 0xc0);
+
+#ifdef PCI_FDC_SWAP_DRIVES
+               /*
+                * If only Floppy 1 is present, swap drives.
+                */
+               if (!sun_floppy_types[0] && sun_floppy_types[1]) {
+                       /*
+                        * Set the drive exchange bit in FCR on NS87303,
+                        * make sure other bits are sane before doing so.
+                        */
+                       ns87303_modify(config, FER, FER_EDM, 0);
+                       ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);
+                       ns87303_modify(config, FCR, 0, FCR_LDE);
+
+                       config = sun_floppy_types[0];
+                       sun_floppy_types[0] = sun_floppy_types[1];
+                       sun_floppy_types[1] = config;
+
+                       if (sun_pci_broken_drive != -1) {
+                               sun_pci_broken_drive = 1 - sun_pci_broken_drive;
+                               sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb;
+                       }
+               }
+#endif /* PCI_FDC_SWAP_DRIVES */
+
+               return sun_floppy_types[0];
+#else
+               return 0;
+#endif
+       }
+       prom_getproperty(sdev->prom_node, "status", state, sizeof(state));
+       if(!strncmp(state, "disabled", 8))
+               return 0;
+
+       /*
+        * We cannot do sbus_ioremap here: it does request_region,
+        * which the generic floppy driver tries to do once again.
+        * But we must use the sdev resource values as they have
+        * had parent ranges applied.
+        */
+       sun_fdc = (struct sun_flpy_controller *)
+               (sdev->resource[0].start +
+                ((sdev->resource[0].flags & 0x1ffUL) << 32UL));
+
+       /* Last minute sanity check... */
+       if(sbus_readb(&sun_fdc->status1_82077) == 0xff) {
+               sun_fdc = (struct sun_flpy_controller *)-1;
+               return 0;
+       }
+
+        sun_fdops.fd_inb = sun_82077_fd_inb;
+        sun_fdops.fd_outb = sun_82077_fd_outb;
+
+       can_use_virtual_dma = use_virtual_dma = 1;
+       sun_fdops.fd_enable_dma = sun_fd_enable_dma;
+       sun_fdops.fd_disable_dma = sun_fd_disable_dma;
+       sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
+       sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
+       sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
+       sun_fdops.get_dma_residue = sun_get_dma_residue;
+
+       sun_fdops.fd_request_irq = sun_fd_request_irq;
+       sun_fdops.fd_free_irq = sun_fd_free_irq;
+
+       sun_fdops.fd_eject = sun_fd_eject;
+
+        fdc_status = (unsigned long) &sun_fdc->status_82077;
+
+       /* Success... */
+       allowed_drive_mask = 0x01;
+       sun_floppy_types[0] = 4;
+       sun_floppy_types[1] = 0;
+
+       return sun_floppy_types[0];
+}
+
+#define EXTRA_FLOPPY_PARAMS
+
+static DEFINE_SPINLOCK(dma_spin_lock);
+
+#define claim_dma_lock() \
+({     unsigned long flags; \
+       spin_lock_irqsave(&dma_spin_lock, flags); \
+       flags; \
+})
+
+#define release_dma_lock(__flags) \
+       spin_unlock_irqrestore(&dma_spin_lock, __flags);
+
+#endif /* !(__ASM_SPARC64_FLOPPY_H) */
diff --git a/include/asm-sparc/fpumacro.h b/include/asm-sparc/fpumacro.h
new file mode 100644 (file)
index 0000000..cc463fe
--- /dev/null
@@ -0,0 +1,33 @@
+/* fpumacro.h: FPU related macros.
+ *
+ * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_FPUMACRO_H
+#define _SPARC64_FPUMACRO_H
+
+#include <asm/asi.h>
+#include <asm/visasm.h>
+
+struct fpustate {
+       u32     regs[64];
+};
+
+#define FPUSTATE (struct fpustate *)(current_thread_info()->fpregs)
+
+static inline unsigned long fprs_read(void)
+{
+       unsigned long retval;
+
+       __asm__ __volatile__("rd %%fprs, %0" : "=r" (retval));
+
+       return retval;
+}
+
+static inline void fprs_write(unsigned long val)
+{
+       __asm__ __volatile__("wr %0, 0x0, %%fprs" : : "r" (val));
+}
+
+#endif /* !(_SPARC64_FPUMACRO_H) */
index 6a332a9f099c2eafbf78ee5f79056a349d41a775..c6a9f038c531b22defd2ba117c975a14c660f747 100644 (file)
@@ -1,6 +1,8 @@
-#ifndef _ASM_FUTEX_H
-#define _ASM_FUTEX_H
-
-#include <asm-generic/futex.h>
-
+#ifndef ___ASM_SPARC_FUTEX_H
+#define ___ASM_SPARC_FUTEX_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/futex_64.h>
+#else
+#include <asm-sparc/futex_32.h>
+#endif
 #endif
diff --git a/include/asm-sparc/futex_32.h b/include/asm-sparc/futex_32.h
new file mode 100644 (file)
index 0000000..6a332a9
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _ASM_FUTEX_H
+#define _ASM_FUTEX_H
+
+#include <asm-generic/futex.h>
+
+#endif
diff --git a/include/asm-sparc/futex_64.h b/include/asm-sparc/futex_64.h
new file mode 100644 (file)
index 0000000..d837893
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef _SPARC64_FUTEX_H
+#define _SPARC64_FUTEX_H
+
+#include <linux/futex.h>
+#include <linux/uaccess.h>
+#include <asm/errno.h>
+#include <asm/system.h>
+
+#define __futex_cas_op(insn, ret, oldval, uaddr, oparg)        \
+       __asm__ __volatile__(                           \
+       "\n1:   lduwa   [%3] %%asi, %2\n"               \
+       "       " insn "\n"                             \
+       "2:     casa    [%3] %%asi, %2, %1\n"           \
+       "       cmp     %2, %1\n"                       \
+       "       bne,pn  %%icc, 1b\n"                    \
+       "        mov    0, %0\n"                        \
+       "3:\n"                                          \
+       "       .section .fixup,#alloc,#execinstr\n"    \
+       "       .align  4\n"                            \
+       "4:     sethi   %%hi(3b), %0\n"                 \
+       "       jmpl    %0 + %%lo(3b), %%g0\n"          \
+       "        mov    %5, %0\n"                       \
+       "       .previous\n"                            \
+       "       .section __ex_table,\"a\"\n"            \
+       "       .align  4\n"                            \
+       "       .word   1b, 4b\n"                       \
+       "       .word   2b, 4b\n"                       \
+       "       .previous\n"                            \
+       : "=&r" (ret), "=&r" (oldval), "=&r" (tem)      \
+       : "r" (uaddr), "r" (oparg), "i" (-EFAULT)       \
+       : "memory")
+
+static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
+{
+       int op = (encoded_op >> 28) & 7;
+       int cmp = (encoded_op >> 24) & 15;
+       int oparg = (encoded_op << 8) >> 20;
+       int cmparg = (encoded_op << 20) >> 20;
+       int oldval = 0, ret, tem;
+
+       if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(int))))
+               return -EFAULT;
+       if (unlikely((((unsigned long) uaddr) & 0x3UL)))
+               return -EINVAL;
+
+       if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+               oparg = 1 << oparg;
+
+       pagefault_disable();
+
+       switch (op) {
+       case FUTEX_OP_SET:
+               __futex_cas_op("mov\t%4, %1", ret, oldval, uaddr, oparg);
+               break;
+       case FUTEX_OP_ADD:
+               __futex_cas_op("add\t%2, %4, %1", ret, oldval, uaddr, oparg);
+               break;
+       case FUTEX_OP_OR:
+               __futex_cas_op("or\t%2, %4, %1", ret, oldval, uaddr, oparg);
+               break;
+       case FUTEX_OP_ANDN:
+               __futex_cas_op("and\t%2, %4, %1", ret, oldval, uaddr, oparg);
+               break;
+       case FUTEX_OP_XOR:
+               __futex_cas_op("xor\t%2, %4, %1", ret, oldval, uaddr, oparg);
+               break;
+       default:
+               ret = -ENOSYS;
+       }
+
+       pagefault_enable();
+
+       if (!ret) {
+               switch (cmp) {
+               case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
+               case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
+               case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
+               case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
+               case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
+               case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
+               default: ret = -ENOSYS;
+               }
+       }
+       return ret;
+}
+
+static inline int
+futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
+{
+       __asm__ __volatile__(
+       "\n1:   casa    [%3] %%asi, %2, %0\n"
+       "2:\n"
+       "       .section .fixup,#alloc,#execinstr\n"
+       "       .align  4\n"
+       "3:     sethi   %%hi(2b), %0\n"
+       "       jmpl    %0 + %%lo(2b), %%g0\n"
+       "        mov    %4, %0\n"
+       "       .previous\n"
+       "       .section __ex_table,\"a\"\n"
+       "       .align  4\n"
+       "       .word   1b, 3b\n"
+       "       .previous\n"
+       : "=r" (newval)
+       : "0" (newval), "r" (oldval), "r" (uaddr), "i" (-EFAULT)
+       : "memory");
+
+       return newval;
+}
+
+#endif /* !(_SPARC64_FUTEX_H) */
index 4f63ed8df55191517f819cacd3ec54f886a19941..15647877310031815fdbcfc2bada8d5de6c856f2 100644 (file)
@@ -1,23 +1,8 @@
-/* hardirq.h: 32-bit Sparc hard IRQ support.
- *
- * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1998-2000 Anton Blanchard (anton@samba.org)
- */
-
-#ifndef __SPARC_HARDIRQ_H
-#define __SPARC_HARDIRQ_H
-
-#include <linux/threads.h>
-#include <linux/spinlock.h>
-#include <linux/cache.h>
-
-/* entry.S is sensitive to the offsets of these fields */ /* XXX P3 Is it? */
-typedef struct {
-       unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
-
-#define HARDIRQ_BITS    8
-
-#endif /* __SPARC_HARDIRQ_H */
+#ifndef ___ASM_SPARC_HARDIRQ_H
+#define ___ASM_SPARC_HARDIRQ_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/hardirq_64.h>
+#else
+#include <asm-sparc/hardirq_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/hardirq_32.h b/include/asm-sparc/hardirq_32.h
new file mode 100644 (file)
index 0000000..4f63ed8
--- /dev/null
@@ -0,0 +1,23 @@
+/* hardirq.h: 32-bit Sparc hard IRQ support.
+ *
+ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1998-2000 Anton Blanchard (anton@samba.org)
+ */
+
+#ifndef __SPARC_HARDIRQ_H
+#define __SPARC_HARDIRQ_H
+
+#include <linux/threads.h>
+#include <linux/spinlock.h>
+#include <linux/cache.h>
+
+/* entry.S is sensitive to the offsets of these fields */ /* XXX P3 Is it? */
+typedef struct {
+       unsigned int __softirq_pending;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+#define HARDIRQ_BITS    8
+
+#endif /* __SPARC_HARDIRQ_H */
diff --git a/include/asm-sparc/hardirq_64.h b/include/asm-sparc/hardirq_64.h
new file mode 100644 (file)
index 0000000..7c29fd1
--- /dev/null
@@ -0,0 +1,19 @@
+/* hardirq.h: 64-bit Sparc hard IRQ support.
+ *
+ * Copyright (C) 1997, 1998, 2005 David S. Miller (davem@davemloft.net)
+ */
+
+#ifndef __SPARC64_HARDIRQ_H
+#define __SPARC64_HARDIRQ_H
+
+#include <asm/cpudata.h>
+
+#define __ARCH_IRQ_STAT
+#define local_softirq_pending() \
+       (local_cpu_data().__softirq_pending)
+
+void ack_bad_irq(unsigned int irq);
+
+#define HARDIRQ_BITS   8
+
+#endif /* !(__SPARC64_HARDIRQ_H) */
index 7c35491a8b53d387ac477305fbed04092e68ee76..14652abdea31c42cf97a6a3dc93df7bcb19804ca 100644 (file)
@@ -1,102 +1,8 @@
-#ifndef __SPARC_HEAD_H
-#define __SPARC_HEAD_H
-
-#define KERNBASE        0xf0000000  /* First address the kernel will eventually be */
-#define LOAD_ADDR       0x4000      /* prom jumps to us here unless this is elf /boot */
-#define SUN4C_SEGSZ     (1 << 18)
-#define SRMMU_L1_KBASE_OFFSET ((KERNBASE>>24)<<2)  /* Used in boot remapping. */
-#define INTS_ENAB        0x01           /* entry.S uses this. */
-
-#define SUN4_PROM_VECTOR 0xFFE81000     /* SUN4 PROM needs to be hardwired */
-
-#define WRITE_PAUSE      nop; nop; nop; /* Have to do this after %wim/%psr chg */
-#define NOP_INSN         0x01000000     /* Used to patch sparc_save_state */
-
-/* Here are some trap goodies */
-
-/* Generic trap entry. */
-#define TRAP_ENTRY(type, label) \
-       rd %psr, %l0; b label; rd %wim, %l3; nop;
-
-/* Data/text faults. Defaults to sun4c version at boot time. */
-#define SPARC_TFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 1, %l7;
-#define SPARC_DFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 0, %l7;
-#define SRMMU_TFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 1, %l7;
-#define SRMMU_DFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 0, %l7;
-
-/* This is for traps we should NEVER get. */
-#define BAD_TRAP(num) \
-        rd %psr, %l0; mov num, %l7; b bad_trap_handler; rd %wim, %l3;
-
-/* This is for traps when we want just skip the instruction which caused it */
-#define SKIP_TRAP(type, name) \
-       jmpl %l2, %g0; rett %l2 + 4; nop; nop;
-
-/* Notice that for the system calls we pull a trick.  We load up a
- * different pointer to the system call vector table in %l7, but call
- * the same generic system call low-level entry point.  The trap table
- * entry sequences are also HyperSparc pipeline friendly ;-)
- */
-
-/* Software trap for Linux system calls. */
-#define LINUX_SYSCALL_TRAP \
-        sethi %hi(sys_call_table), %l7; \
-        or %l7, %lo(sys_call_table), %l7; \
-        b linux_sparc_syscall; \
-        rd %psr, %l0;
-
-#define BREAKPOINT_TRAP \
-       b breakpoint_trap; \
-       rd %psr,%l0; \
-       nop; \
-       nop;
-
-#ifdef CONFIG_KGDB
-#define KGDB_TRAP(num) \
-       b kgdb_trap_low; \
-       rd %psr,%l0; \
-       nop; \
-       nop;
+#ifndef ___ASM_SPARC_HEAD_H
+#define ___ASM_SPARC_HEAD_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/head_64.h>
 #else
-#define KGDB_TRAP(num) \
-       BAD_TRAP(num)
+#include <asm-sparc/head_32.h>
+#endif
 #endif
-
-/* The Get Condition Codes software trap for userland. */
-#define GETCC_TRAP \
-        b getcc_trap_handler; mov %psr, %l0; nop; nop;
-
-/* The Set Condition Codes software trap for userland. */
-#define SETCC_TRAP \
-        b setcc_trap_handler; mov %psr, %l0; nop; nop;
-
-/* The Get PSR software trap for userland. */
-#define GETPSR_TRAP \
-       mov %psr, %i0; jmp %l2; rett %l2 + 4; nop;
-
-/* This is for hard interrupts from level 1-14, 15 is non-maskable (nmi) and
- * gets handled with another macro.
- */
-#define TRAP_ENTRY_INTERRUPT(int_level) \
-        mov int_level, %l7; rd %psr, %l0; b real_irq_entry; rd %wim, %l3;
-
-/* NMI's (Non Maskable Interrupts) are special, you can't keep them
- * from coming in, and basically if you get one, the shows over. ;(
- * On the sun4c they are usually asynchronous memory errors, on the
- * the sun4m they could be either due to mem errors or a software
- * initiated interrupt from the prom/kern on an SMP box saying "I
- * command you to do CPU tricks, read your mailbox for more info."
- */
-#define NMI_TRAP \
-        rd %wim, %l3; b linux_trap_nmi_sun4c; mov %psr, %l0; nop;
-
-/* Window overflows/underflows are special and we need to try to be as
- * efficient as possible here....
- */
-#define WINDOW_SPILL \
-        rd %psr, %l0; rd %wim, %l3; b spill_window_entry; andcc %l0, PSR_PS, %g0;
-
-#define WINDOW_FILL \
-        rd %psr, %l0; rd %wim, %l3; b fill_window_entry; andcc %l0, PSR_PS, %g0;
-
-#endif /* __SPARC_HEAD_H */
diff --git a/include/asm-sparc/head_32.h b/include/asm-sparc/head_32.h
new file mode 100644 (file)
index 0000000..7c35491
--- /dev/null
@@ -0,0 +1,102 @@
+#ifndef __SPARC_HEAD_H
+#define __SPARC_HEAD_H
+
+#define KERNBASE        0xf0000000  /* First address the kernel will eventually be */
+#define LOAD_ADDR       0x4000      /* prom jumps to us here unless this is elf /boot */
+#define SUN4C_SEGSZ     (1 << 18)
+#define SRMMU_L1_KBASE_OFFSET ((KERNBASE>>24)<<2)  /* Used in boot remapping. */
+#define INTS_ENAB        0x01           /* entry.S uses this. */
+
+#define SUN4_PROM_VECTOR 0xFFE81000     /* SUN4 PROM needs to be hardwired */
+
+#define WRITE_PAUSE      nop; nop; nop; /* Have to do this after %wim/%psr chg */
+#define NOP_INSN         0x01000000     /* Used to patch sparc_save_state */
+
+/* Here are some trap goodies */
+
+/* Generic trap entry. */
+#define TRAP_ENTRY(type, label) \
+       rd %psr, %l0; b label; rd %wim, %l3; nop;
+
+/* Data/text faults. Defaults to sun4c version at boot time. */
+#define SPARC_TFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 1, %l7;
+#define SPARC_DFAULT rd %psr, %l0; rd %wim, %l3; b sun4c_fault; mov 0, %l7;
+#define SRMMU_TFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 1, %l7;
+#define SRMMU_DFAULT rd %psr, %l0; rd %wim, %l3; b srmmu_fault; mov 0, %l7;
+
+/* This is for traps we should NEVER get. */
+#define BAD_TRAP(num) \
+        rd %psr, %l0; mov num, %l7; b bad_trap_handler; rd %wim, %l3;
+
+/* This is for traps when we want just skip the instruction which caused it */
+#define SKIP_TRAP(type, name) \
+       jmpl %l2, %g0; rett %l2 + 4; nop; nop;
+
+/* Notice that for the system calls we pull a trick.  We load up a
+ * different pointer to the system call vector table in %l7, but call
+ * the same generic system call low-level entry point.  The trap table
+ * entry sequences are also HyperSparc pipeline friendly ;-)
+ */
+
+/* Software trap for Linux system calls. */
+#define LINUX_SYSCALL_TRAP \
+        sethi %hi(sys_call_table), %l7; \
+        or %l7, %lo(sys_call_table), %l7; \
+        b linux_sparc_syscall; \
+        rd %psr, %l0;
+
+#define BREAKPOINT_TRAP \
+       b breakpoint_trap; \
+       rd %psr,%l0; \
+       nop; \
+       nop;
+
+#ifdef CONFIG_KGDB
+#define KGDB_TRAP(num) \
+       b kgdb_trap_low; \
+       rd %psr,%l0; \
+       nop; \
+       nop;
+#else
+#define KGDB_TRAP(num) \
+       BAD_TRAP(num)
+#endif
+
+/* The Get Condition Codes software trap for userland. */
+#define GETCC_TRAP \
+        b getcc_trap_handler; mov %psr, %l0; nop; nop;
+
+/* The Set Condition Codes software trap for userland. */
+#define SETCC_TRAP \
+        b setcc_trap_handler; mov %psr, %l0; nop; nop;
+
+/* The Get PSR software trap for userland. */
+#define GETPSR_TRAP \
+       mov %psr, %i0; jmp %l2; rett %l2 + 4; nop;
+
+/* This is for hard interrupts from level 1-14, 15 is non-maskable (nmi) and
+ * gets handled with another macro.
+ */
+#define TRAP_ENTRY_INTERRUPT(int_level) \
+        mov int_level, %l7; rd %psr, %l0; b real_irq_entry; rd %wim, %l3;
+
+/* NMI's (Non Maskable Interrupts) are special, you can't keep them
+ * from coming in, and basically if you get one, the shows over. ;(
+ * On the sun4c they are usually asynchronous memory errors, on the
+ * the sun4m they could be either due to mem errors or a software
+ * initiated interrupt from the prom/kern on an SMP box saying "I
+ * command you to do CPU tricks, read your mailbox for more info."
+ */
+#define NMI_TRAP \
+        rd %wim, %l3; b linux_trap_nmi_sun4c; mov %psr, %l0; nop;
+
+/* Window overflows/underflows are special and we need to try to be as
+ * efficient as possible here....
+ */
+#define WINDOW_SPILL \
+        rd %psr, %l0; rd %wim, %l3; b spill_window_entry; andcc %l0, PSR_PS, %g0;
+
+#define WINDOW_FILL \
+        rd %psr, %l0; rd %wim, %l3; b fill_window_entry; andcc %l0, PSR_PS, %g0;
+
+#endif /* __SPARC_HEAD_H */
diff --git a/include/asm-sparc/head_64.h b/include/asm-sparc/head_64.h
new file mode 100644 (file)
index 0000000..10e9dab
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef _SPARC64_HEAD_H
+#define _SPARC64_HEAD_H
+
+#include <asm/pstate.h>
+
+       /* wrpr %g0, val, %gl */
+#define SET_GL(val)    \
+       .word   0xa1902000 | val
+
+       /* rdpr %gl, %gN */
+#define GET_GL_GLOBAL(N)       \
+       .word   0x81540000 | (N << 25)
+
+#define KERNBASE       0x400000
+
+#define        PTREGS_OFF      (STACK_BIAS + STACKFRAME_SZ)
+
+#define __CHEETAH_ID   0x003e0014
+#define __JALAPENO_ID  0x003e0016
+#define __SERRANO_ID   0x003e0022
+
+#define CHEETAH_MANUF          0x003e
+#define CHEETAH_IMPL           0x0014 /* Ultra-III   */
+#define CHEETAH_PLUS_IMPL      0x0015 /* Ultra-III+  */
+#define JALAPENO_IMPL          0x0016 /* Ultra-IIIi  */
+#define JAGUAR_IMPL            0x0018 /* Ultra-IV    */
+#define PANTHER_IMPL           0x0019 /* Ultra-IV+   */
+#define SERRANO_IMPL           0x0022 /* Ultra-IIIi+ */
+
+#define BRANCH_IF_SUN4V(tmp1,label)            \
+       sethi   %hi(is_sun4v), %tmp1;           \
+       lduw    [%tmp1 + %lo(is_sun4v)], %tmp1; \
+       brnz,pn %tmp1, label;                   \
+        nop
+
+#define BRANCH_IF_CHEETAH_BASE(tmp1,tmp2,label)        \
+       rdpr    %ver, %tmp1;                    \
+       sethi   %hi(__CHEETAH_ID), %tmp2;       \
+       srlx    %tmp1, 32, %tmp1;               \
+       or      %tmp2, %lo(__CHEETAH_ID), %tmp2;\
+       cmp     %tmp1, %tmp2;                   \
+       be,pn   %icc, label;                    \
+        nop;
+
+#define BRANCH_IF_JALAPENO(tmp1,tmp2,label)    \
+       rdpr    %ver, %tmp1;                    \
+       sethi   %hi(__JALAPENO_ID), %tmp2;      \
+       srlx    %tmp1, 32, %tmp1;               \
+       or      %tmp2, %lo(__JALAPENO_ID), %tmp2;\
+       cmp     %tmp1, %tmp2;                   \
+       be,pn   %icc, label;                    \
+        nop;
+
+#define BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(tmp1,tmp2,label)    \
+       rdpr    %ver, %tmp1;                    \
+       srlx    %tmp1, (32 + 16), %tmp2;        \
+       cmp     %tmp2, CHEETAH_MANUF;           \
+       bne,pt  %xcc, 99f;                      \
+        sllx   %tmp1, 16, %tmp1;               \
+       srlx    %tmp1, (32 + 16), %tmp2;        \
+       cmp     %tmp2, CHEETAH_PLUS_IMPL;       \
+       bgeu,pt %xcc, label;                    \
+99:     nop;
+
+#define BRANCH_IF_ANY_CHEETAH(tmp1,tmp2,label) \
+       rdpr    %ver, %tmp1;                    \
+       srlx    %tmp1, (32 + 16), %tmp2;        \
+       cmp     %tmp2, CHEETAH_MANUF;           \
+       bne,pt  %xcc, 99f;                      \
+        sllx   %tmp1, 16, %tmp1;               \
+       srlx    %tmp1, (32 + 16), %tmp2;        \
+       cmp     %tmp2, CHEETAH_IMPL;            \
+       bgeu,pt %xcc, label;                    \
+99:     nop;
+
+#endif /* !(_SPARC64_HEAD_H) */
diff --git a/include/asm-sparc/hugetlb.h b/include/asm-sparc/hugetlb.h
new file mode 100644 (file)
index 0000000..412af58
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef _ASM_SPARC64_HUGETLB_H
+#define _ASM_SPARC64_HUGETLB_H
+
+#include <asm/page.h>
+
+
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+                    pte_t *ptep, pte_t pte);
+
+pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+                             pte_t *ptep);
+
+void hugetlb_prefault_arch_hook(struct mm_struct *mm);
+
+static inline int is_hugepage_only_range(struct mm_struct *mm,
+                                        unsigned long addr,
+                                        unsigned long len) {
+       return 0;
+}
+
+/*
+ * If the arch doesn't supply something else, assume that hugepage
+ * size aligned regions are ok without further preparation.
+ */
+static inline int prepare_hugepage_range(unsigned long addr, unsigned long len)
+{
+       if (len & ~HPAGE_MASK)
+               return -EINVAL;
+       if (addr & ~HPAGE_MASK)
+               return -EINVAL;
+       return 0;
+}
+
+static inline void hugetlb_free_pgd_range(struct mmu_gather **tlb,
+                                         unsigned long addr, unsigned long end,
+                                         unsigned long floor,
+                                         unsigned long ceiling)
+{
+       free_pgd_range(tlb, addr, end, floor, ceiling);
+}
+
+static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
+                                        unsigned long addr, pte_t *ptep)
+{
+}
+
+static inline int huge_pte_none(pte_t pte)
+{
+       return pte_none(pte);
+}
+
+static inline pte_t huge_pte_wrprotect(pte_t pte)
+{
+       return pte_wrprotect(pte);
+}
+
+static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+                                          unsigned long addr, pte_t *ptep)
+{
+       ptep_set_wrprotect(mm, addr, ptep);
+}
+
+static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+                                            unsigned long addr, pte_t *ptep,
+                                            pte_t pte, int dirty)
+{
+       return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+}
+
+static inline pte_t huge_ptep_get(pte_t *ptep)
+{
+       return *ptep;
+}
+
+static inline int arch_prepare_hugepage(struct page *page)
+{
+       return 0;
+}
+
+static inline void arch_release_hugepage(struct page *page)
+{
+}
+
+#endif /* _ASM_SPARC64_HUGETLB_H */
diff --git a/include/asm-sparc/hvtramp.h b/include/asm-sparc/hvtramp.h
new file mode 100644 (file)
index 0000000..b2b9b94
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _SPARC64_HVTRAP_H
+#define _SPARC64_HVTRAP_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+struct hvtramp_mapping {
+       __u64           vaddr;
+       __u64           tte;
+};
+
+struct hvtramp_descr {
+       __u32                   cpu;
+       __u32                   num_mappings;
+       __u64                   fault_info_va;
+       __u64                   fault_info_pa;
+       __u64                   thread_reg;
+       struct hvtramp_mapping  maps[1];
+};
+
+extern void hv_cpu_startup(unsigned long hvdescr_pa);
+
+#endif
+
+#define HVTRAMP_DESCR_CPU              0x00
+#define HVTRAMP_DESCR_NUM_MAPPINGS     0x04
+#define HVTRAMP_DESCR_FAULT_INFO_VA    0x08
+#define HVTRAMP_DESCR_FAULT_INFO_PA    0x10
+#define HVTRAMP_DESCR_THREAD_REG       0x18
+#define HVTRAMP_DESCR_MAPS             0x20
+
+#define HVTRAMP_MAPPING_VADDR          0x00
+#define HVTRAMP_MAPPING_TTE            0x08
+#define HVTRAMP_MAPPING_SIZE           0x10
+
+#endif /* _SPARC64_HVTRAP_H */
diff --git a/include/asm-sparc/hypervisor.h b/include/asm-sparc/hypervisor.h
new file mode 100644 (file)
index 0000000..109ae24
--- /dev/null
@@ -0,0 +1,2949 @@
+#ifndef _SPARC64_HYPERVISOR_H
+#define _SPARC64_HYPERVISOR_H
+
+/* Sun4v hypervisor interfaces and defines.
+ *
+ * Hypervisor calls are made via traps to software traps number 0x80
+ * and above.  Registers %o0 to %o5 serve as argument, status, and
+ * return value registers.
+ *
+ * There are two kinds of these traps.  First there are the normal
+ * "fast traps" which use software trap 0x80 and encode the function
+ * to invoke by number in register %o5.  Argument and return value
+ * handling is as follows:
+ *
+ * -----------------------------------------------
+ * |  %o5  | function number |     undefined     |
+ * |  %o0  |   argument 0    |   return status   |
+ * |  %o1  |   argument 1    |   return value 1  |
+ * |  %o2  |   argument 2    |   return value 2  |
+ * |  %o3  |   argument 3    |   return value 3  |
+ * |  %o4  |   argument 4    |   return value 4  |
+ * -----------------------------------------------
+ *
+ * The second type are "hyper-fast traps" which encode the function
+ * number in the software trap number itself.  So these use trap
+ * numbers > 0x80.  The register usage for hyper-fast traps is as
+ * follows:
+ *
+ * -----------------------------------------------
+ * |  %o0  |   argument 0    |   return status   |
+ * |  %o1  |   argument 1    |   return value 1  |
+ * |  %o2  |   argument 2    |   return value 2  |
+ * |  %o3  |   argument 3    |   return value 3  |
+ * |  %o4  |   argument 4    |   return value 4  |
+ * -----------------------------------------------
+ *
+ * Registers providing explicit arguments to the hypervisor calls
+ * are volatile across the call.  Upon return their values are
+ * undefined unless explicitly specified as containing a particular
+ * return value by the specific call.  The return status is always
+ * returned in register %o0, zero indicates a successful execution of
+ * the hypervisor call and other values indicate an error status as
+ * defined below.  So, for example, if a hyper-fast trap takes
+ * arguments 0, 1, and 2, then %o0, %o1, and %o2 are volatile across
+ * the call and %o3, %o4, and %o5 would be preserved.
+ *
+ * If the hypervisor trap is invalid, or the fast trap function number
+ * is invalid, HV_EBADTRAP will be returned in %o0.  Also, all 64-bits
+ * of the argument and return values are significant.
+ */
+
+/* Trap numbers.  */
+#define HV_FAST_TRAP           0x80
+#define HV_MMU_MAP_ADDR_TRAP   0x83
+#define HV_MMU_UNMAP_ADDR_TRAP 0x84
+#define HV_TTRACE_ADDENTRY_TRAP        0x85
+#define HV_CORE_TRAP           0xff
+
+/* Error codes.  */
+#define HV_EOK                         0  /* Successful return            */
+#define HV_ENOCPU                      1  /* Invalid CPU id               */
+#define HV_ENORADDR                    2  /* Invalid real address         */
+#define HV_ENOINTR                     3  /* Invalid interrupt id         */
+#define HV_EBADPGSZ                    4  /* Invalid pagesize encoding    */
+#define HV_EBADTSB                     5  /* Invalid TSB description      */
+#define HV_EINVAL                      6  /* Invalid argument             */
+#define HV_EBADTRAP                    7  /* Invalid function number      */
+#define HV_EBADALIGN                   8  /* Invalid address alignment    */
+#define HV_EWOULDBLOCK                 9  /* Cannot complete w/o blocking */
+#define HV_ENOACCESS                   10 /* No access to resource        */
+#define HV_EIO                         11 /* I/O error                    */
+#define HV_ECPUERROR                   12 /* CPU in error state           */
+#define HV_ENOTSUPPORTED               13 /* Function not supported       */
+#define HV_ENOMAP                      14 /* No mapping found             */
+#define HV_ETOOMANY                    15 /* Too many items specified     */
+#define HV_ECHANNEL                    16 /* Invalid LDC channel          */
+#define HV_EBUSY                       17 /* Resource busy                */
+
+/* mach_exit()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MACH_EXIT
+ * ARG0:       exit code
+ * ERRORS:     This service does not return.
+ *
+ * Stop all CPUs in the virtual domain and place them into the stopped
+ * state.  The 64-bit exit code may be passed to a service entity as
+ * the domain's exit status.  On systems without a service entity, the
+ * domain will undergo a reset, and the boot firmware will be
+ * reloaded.
+ *
+ * This function will never return to the guest that invokes it.
+ *
+ * Note: By convention an exit code of zero denotes a successful exit by
+ *       the guest code.  A non-zero exit code denotes a guest specific
+ *       error indication.
+ *
+ */
+#define HV_FAST_MACH_EXIT              0x00
+
+#ifndef __ASSEMBLY__
+extern void sun4v_mach_exit(unsigned long exit_code);
+#endif
+
+/* Domain services.  */
+
+/* mach_desc()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MACH_DESC
+ * ARG0:       buffer
+ * ARG1:       length
+ * RET0:       status
+ * RET1:       length
+ * ERRORS:     HV_EBADALIGN    Buffer is badly aligned
+ *             HV_ENORADDR     Buffer is to an illegal real address.
+ *             HV_EINVAL       Buffer length is too small for complete
+ *                             machine description.
+ *
+ * Copy the most current machine description into the buffer indicated
+ * by the real address in ARG0.  The buffer provided must be 16 byte
+ * aligned.  Upon success or HV_EINVAL, this service returns the
+ * actual size of the machine description in the RET1 return value.
+ *
+ * Note: A method of determining the appropriate buffer size for the
+ *       machine description is to first call this service with a buffer
+ *       length of 0 bytes.
+ */
+#define HV_FAST_MACH_DESC              0x01
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mach_desc(unsigned long buffer_pa,
+                                    unsigned long buf_len,
+                                    unsigned long *real_buf_len);
+#endif
+
+/* mach_sir()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MACH_SIR
+ * ERRORS:     This service does not return.
+ *
+ * Perform a software initiated reset of the virtual machine domain.
+ * All CPUs are captured as soon as possible, all hardware devices are
+ * returned to the entry default state, and the domain is restarted at
+ * the SIR (trap type 0x04) real trap table (RTBA) entry point on one
+ * of the CPUs.  The single CPU restarted is selected as determined by
+ * platform specific policy.  Memory is preserved across this
+ * operation.
+ */
+#define HV_FAST_MACH_SIR               0x02
+
+#ifndef __ASSEMBLY__
+extern void sun4v_mach_sir(void);
+#endif
+
+/* mach_set_watchdog()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MACH_SET_WATCHDOG
+ * ARG0:       timeout in milliseconds
+ * RET0:       status
+ * RET1:       time remaining in milliseconds
+ *
+ * A guest uses this API to set a watchdog timer.  Once the gues has set
+ * the timer, it must call the timer service again either to disable or
+ * postpone the expiration.  If the timer expires before being reset or
+ * disabled, then the hypervisor take a platform specific action leading
+ * to guest termination within a bounded time period.  The platform action
+ * may include recovery actions such as reporting the expiration to a
+ * Service Processor, and/or automatically restarting the gues.
+ *
+ * The 'timeout' parameter is specified in milliseconds, however the
+ * implementated granularity is given by the 'watchdog-resolution'
+ * property in the 'platform' node of the guest's machine description.
+ * The largest allowed timeout value is specified by the
+ * 'watchdog-max-timeout' property of the 'platform' node.
+ *
+ * If the 'timeout' argument is not zero, the watchdog timer is set to
+ * expire after a minimum of 'timeout' milliseconds.
+ *
+ * If the 'timeout' argument is zero, the watchdog timer is disabled.
+ *
+ * If the 'timeout' value exceeds the value of the 'max-watchdog-timeout'
+ * property, the hypervisor leaves the watchdog timer state unchanged,
+ * and returns a status of EINVAL.
+ *
+ * The 'time remaining' return value is valid regardless of whether the
+ * return status is EOK or EINVAL.  A non-zero return value indicates the
+ * number of milliseconds that were remaining until the timer was to expire.
+ * If less than one millisecond remains, the return value is '1'.  If the
+ * watchdog timer was disabled at the time of the call, the return value is
+ * zero.
+ *
+ * If the hypervisor cannot support the exact timeout value requested, but
+ * can support a larger timeout value, the hypervisor may round the actual
+ * timeout to a value larger than the requested timeout, consequently the
+ * 'time remaining' return value may be larger than the previously requested
+ * timeout value.
+ *
+ * Any guest OS debugger should be aware that the watchdog service may be in
+ * use.  Consequently, it is recommended that the watchdog service is
+ * disabled upon debugger entry (e.g. reaching a breakpoint), and then
+ * re-enabled upon returning to normal execution.  The API has been designed
+ * with this in mind, and the 'time remaining' result of the disable call may
+ * be used directly as the timeout argument of the re-enable call.
+ */
+#define HV_FAST_MACH_SET_WATCHDOG      0x05
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mach_set_watchdog(unsigned long timeout,
+                                            unsigned long *orig_timeout);
+#endif
+
+/* CPU services.
+ *
+ * CPUs represent devices that can execute software threads.  A single
+ * chip that contains multiple cores or strands is represented as
+ * multiple CPUs with unique CPU identifiers.  CPUs are exported to
+ * OBP via the machine description (and to the OS via the OBP device
+ * tree).  CPUs are always in one of three states: stopped, running,
+ * or error.
+ *
+ * A CPU ID is a pre-assigned 16-bit value that uniquely identifies a
+ * CPU within a logical domain.  Operations that are to be performed
+ * on multiple CPUs specify them via a CPU list.  A CPU list is an
+ * array in real memory, of which each 16-bit word is a CPU ID.  CPU
+ * lists are passed through the API as two arguments.  The first is
+ * the number of entries (16-bit words) in the CPU list, and the
+ * second is the (real address) pointer to the CPU ID list.
+ */
+
+/* cpu_start()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CPU_START
+ * ARG0:       CPU ID
+ * ARG1:       PC
+ * ARG2:       RTBA
+ * ARG3:       target ARG0
+ * RET0:       status
+ * ERRORS:     ENOCPU          Invalid CPU ID
+ *             EINVAL          Target CPU ID is not in the stopped state
+ *             ENORADDR        Invalid PC or RTBA real address
+ *             EBADALIGN       Unaligned PC or unaligned RTBA
+ *             EWOULDBLOCK     Starting resources are not available
+ *
+ * Start CPU with given CPU ID with PC in %pc and with a real trap
+ * base address value of RTBA.  The indicated CPU must be in the
+ * stopped state.  The supplied RTBA must be aligned on a 256 byte
+ * boundary.  On successful completion, the specified CPU will be in
+ * the running state and will be supplied with "target ARG0" in %o0
+ * and RTBA in %tba.
+ */
+#define HV_FAST_CPU_START              0x10
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_cpu_start(unsigned long cpuid,
+                                    unsigned long pc,
+                                    unsigned long rtba,
+                                    unsigned long arg0);
+#endif
+
+/* cpu_stop()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CPU_STOP
+ * ARG0:       CPU ID
+ * RET0:       status
+ * ERRORS:     ENOCPU          Invalid CPU ID
+ *             EINVAL          Target CPU ID is the current cpu
+ *             EINVAL          Target CPU ID is not in the running state
+ *             EWOULDBLOCK     Stopping resources are not available
+ *             ENOTSUPPORTED   Not supported on this platform
+ *
+ * The specified CPU is stopped.  The indicated CPU must be in the
+ * running state.  On completion, it will be in the stopped state.  It
+ * is not legal to stop the current CPU.
+ *
+ * Note: As this service cannot be used to stop the current cpu, this service
+ *       may not be used to stop the last running CPU in a domain.  To stop
+ *       and exit a running domain, a guest must use the mach_exit() service.
+ */
+#define HV_FAST_CPU_STOP               0x11
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_cpu_stop(unsigned long cpuid);
+#endif
+
+/* cpu_yield()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CPU_YIELD
+ * RET0:       status
+ * ERRORS:     No possible error.
+ *
+ * Suspend execution on the current CPU.  Execution will resume when
+ * an interrupt (device, %stick_compare, or cross-call) is targeted to
+ * the CPU.  On some CPUs, this API may be used by the hypervisor to
+ * save power by disabling hardware strands.
+ */
+#define HV_FAST_CPU_YIELD              0x12
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_cpu_yield(void);
+#endif
+
+/* cpu_qconf()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CPU_QCONF
+ * ARG0:       queue
+ * ARG1:       base real address
+ * ARG2:       number of entries
+ * RET0:       status
+ * ERRORS:     ENORADDR        Invalid base real address
+ *             EINVAL          Invalid queue or number of entries is less
+ *                             than 2 or too large.
+ *             EBADALIGN       Base real address is not correctly aligned
+ *                             for size.
+ *
+ * Configure the given queue to be placed at the given base real
+ * address, with the given number of entries.  The number of entries
+ * must be a power of 2.  The base real address must be aligned
+ * exactly to match the queue size.  Each queue entry is 64 bytes
+ * long, so for example a 32 entry queue must be aligned on a 2048
+ * byte real address boundary.
+ *
+ * The specified queue is unconfigured if the number of entries is given
+ * as zero.
+ *
+ * For the current version of this API service, the argument queue is defined
+ * as follows:
+ *
+ *     queue           description
+ *     -----           -------------------------
+ *     0x3c            cpu mondo queue
+ *     0x3d            device mondo queue
+ *     0x3e            resumable error queue
+ *     0x3f            non-resumable error queue
+ *
+ * Note: The maximum number of entries for each queue for a specific cpu may
+ *       be determined from the machine description.
+ */
+#define HV_FAST_CPU_QCONF              0x14
+#define  HV_CPU_QUEUE_CPU_MONDO                 0x3c
+#define  HV_CPU_QUEUE_DEVICE_MONDO      0x3d
+#define  HV_CPU_QUEUE_RES_ERROR                 0x3e
+#define  HV_CPU_QUEUE_NONRES_ERROR      0x3f
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_cpu_qconf(unsigned long type,
+                                    unsigned long queue_paddr,
+                                    unsigned long num_queue_entries);
+#endif
+
+/* cpu_qinfo()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CPU_QINFO
+ * ARG0:       queue
+ * RET0:       status
+ * RET1:       base real address
+ * RET1:       number of entries
+ * ERRORS:     EINVAL          Invalid queue
+ *
+ * Return the configuration info for the given queue.  The base real
+ * address and number of entries of the defined queue are returned.
+ * The queue argument values are the same as for cpu_qconf() above.
+ *
+ * If the specified queue is a valid queue number, but no queue has
+ * been defined, the number of entries will be set to zero and the
+ * base real address returned is undefined.
+ */
+#define HV_FAST_CPU_QINFO              0x15
+
+/* cpu_mondo_send()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CPU_MONDO_SEND
+ * ARG0-1:     CPU list
+ * ARG2:       data real address
+ * RET0:       status
+ * ERRORS:     EBADALIGN       Mondo data is not 64-byte aligned or CPU list
+ *                             is not 2-byte aligned.
+ *             ENORADDR        Invalid data mondo address, or invalid cpu list
+ *                             address.
+ *             ENOCPU          Invalid cpu in CPU list
+ *             EWOULDBLOCK     Some or all of the listed CPUs did not receive
+ *                             the mondo
+ *             ECPUERROR       One or more of the listed CPUs are in error
+ *                             state, use HV_FAST_CPU_STATE to see which ones
+ *             EINVAL          CPU list includes caller's CPU ID
+ *
+ * Send a mondo interrupt to the CPUs in the given CPU list with the
+ * 64-bytes at the given data real address.  The data must be 64-byte
+ * aligned.  The mondo data will be delivered to the cpu_mondo queues
+ * of the recipient CPUs.
+ *
+ * In all cases, error or not, the CPUs in the CPU list to which the
+ * mondo has been successfully delivered will be indicated by having
+ * their entry in CPU list updated with the value 0xffff.
+ */
+#define HV_FAST_CPU_MONDO_SEND         0x42
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_cpu_mondo_send(unsigned long cpu_count, unsigned long cpu_list_pa, unsigned long mondo_block_pa);
+#endif
+
+/* cpu_myid()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CPU_MYID
+ * RET0:       status
+ * RET1:       CPU ID
+ * ERRORS:     No errors defined.
+ *
+ * Return the hypervisor ID handle for the current CPU.  Use by a
+ * virtual CPU to discover it's own identity.
+ */
+#define HV_FAST_CPU_MYID               0x16
+
+/* cpu_state()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CPU_STATE
+ * ARG0:       CPU ID
+ * RET0:       status
+ * RET1:       state
+ * ERRORS:     ENOCPU          Invalid CPU ID
+ *
+ * Retrieve the current state of the CPU with the given CPU ID.
+ */
+#define HV_FAST_CPU_STATE              0x17
+#define  HV_CPU_STATE_STOPPED           0x01
+#define  HV_CPU_STATE_RUNNING           0x02
+#define  HV_CPU_STATE_ERROR             0x03
+
+#ifndef __ASSEMBLY__
+extern long sun4v_cpu_state(unsigned long cpuid);
+#endif
+
+/* cpu_set_rtba()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CPU_SET_RTBA
+ * ARG0:       RTBA
+ * RET0:       status
+ * RET1:       previous RTBA
+ * ERRORS:     ENORADDR        Invalid RTBA real address
+ *             EBADALIGN       RTBA is incorrectly aligned for a trap table
+ *
+ * Set the real trap base address of the local cpu to the given RTBA.
+ * The supplied RTBA must be aligned on a 256 byte boundary.  Upon
+ * success the previous value of the RTBA is returned in RET1.
+ *
+ * Note: This service does not affect %tba
+ */
+#define HV_FAST_CPU_SET_RTBA           0x18
+
+/* cpu_set_rtba()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CPU_GET_RTBA
+ * RET0:       status
+ * RET1:       previous RTBA
+ * ERRORS:     No possible error.
+ *
+ * Returns the current value of RTBA in RET1.
+ */
+#define HV_FAST_CPU_GET_RTBA           0x19
+
+/* MMU services.
+ *
+ * Layout of a TSB description for mmu_tsb_ctx{,non}0() calls.
+ */
+#ifndef __ASSEMBLY__
+struct hv_tsb_descr {
+       unsigned short          pgsz_idx;
+       unsigned short          assoc;
+       unsigned int            num_ttes;       /* in TTEs */
+       unsigned int            ctx_idx;
+       unsigned int            pgsz_mask;
+       unsigned long           tsb_base;
+       unsigned long           resv;
+};
+#endif
+#define HV_TSB_DESCR_PGSZ_IDX_OFFSET   0x00
+#define HV_TSB_DESCR_ASSOC_OFFSET      0x02
+#define HV_TSB_DESCR_NUM_TTES_OFFSET   0x04
+#define HV_TSB_DESCR_CTX_IDX_OFFSET    0x08
+#define HV_TSB_DESCR_PGSZ_MASK_OFFSET  0x0c
+#define HV_TSB_DESCR_TSB_BASE_OFFSET   0x10
+#define HV_TSB_DESCR_RESV_OFFSET       0x18
+
+/* Page size bitmask.  */
+#define HV_PGSZ_MASK_8K                        (1 << 0)
+#define HV_PGSZ_MASK_64K               (1 << 1)
+#define HV_PGSZ_MASK_512K              (1 << 2)
+#define HV_PGSZ_MASK_4MB               (1 << 3)
+#define HV_PGSZ_MASK_32MB              (1 << 4)
+#define HV_PGSZ_MASK_256MB             (1 << 5)
+#define HV_PGSZ_MASK_2GB               (1 << 6)
+#define HV_PGSZ_MASK_16GB              (1 << 7)
+
+/* Page size index.  The value given in the TSB descriptor must correspond
+ * to the smallest page size specified in the pgsz_mask page size bitmask.
+ */
+#define HV_PGSZ_IDX_8K                 0
+#define HV_PGSZ_IDX_64K                        1
+#define HV_PGSZ_IDX_512K               2
+#define HV_PGSZ_IDX_4MB                        3
+#define HV_PGSZ_IDX_32MB               4
+#define HV_PGSZ_IDX_256MB              5
+#define HV_PGSZ_IDX_2GB                        6
+#define HV_PGSZ_IDX_16GB               7
+
+/* MMU fault status area.
+ *
+ * MMU related faults have their status and fault address information
+ * placed into a memory region made available by privileged code.  Each
+ * virtual processor must make a mmu_fault_area_conf() call to tell the
+ * hypervisor where that processor's fault status should be stored.
+ *
+ * The fault status block is a multiple of 64-bytes and must be aligned
+ * on a 64-byte boundary.
+ */
+#ifndef __ASSEMBLY__
+struct hv_fault_status {
+       unsigned long           i_fault_type;
+       unsigned long           i_fault_addr;
+       unsigned long           i_fault_ctx;
+       unsigned long           i_reserved[5];
+       unsigned long           d_fault_type;
+       unsigned long           d_fault_addr;
+       unsigned long           d_fault_ctx;
+       unsigned long           d_reserved[5];
+};
+#endif
+#define HV_FAULT_I_TYPE_OFFSET 0x00
+#define HV_FAULT_I_ADDR_OFFSET 0x08
+#define HV_FAULT_I_CTX_OFFSET  0x10
+#define HV_FAULT_D_TYPE_OFFSET 0x40
+#define HV_FAULT_D_ADDR_OFFSET 0x48
+#define HV_FAULT_D_CTX_OFFSET  0x50
+
+#define HV_FAULT_TYPE_FAST_MISS        1
+#define HV_FAULT_TYPE_FAST_PROT        2
+#define HV_FAULT_TYPE_MMU_MISS 3
+#define HV_FAULT_TYPE_INV_RA   4
+#define HV_FAULT_TYPE_PRIV_VIOL        5
+#define HV_FAULT_TYPE_PROT_VIOL        6
+#define HV_FAULT_TYPE_NFO      7
+#define HV_FAULT_TYPE_NFO_SEFF 8
+#define HV_FAULT_TYPE_INV_VA   9
+#define HV_FAULT_TYPE_INV_ASI  10
+#define HV_FAULT_TYPE_NC_ATOMIC        11
+#define HV_FAULT_TYPE_PRIV_ACT 12
+#define HV_FAULT_TYPE_RESV1    13
+#define HV_FAULT_TYPE_UNALIGNED        14
+#define HV_FAULT_TYPE_INV_PGSZ 15
+/* Values 16 --> -2 are reserved.  */
+#define HV_FAULT_TYPE_MULTIPLE -1
+
+/* Flags argument for mmu_{map,unmap}_addr(), mmu_demap_{page,context,all}(),
+ * and mmu_{map,unmap}_perm_addr().
+ */
+#define HV_MMU_DMMU                    0x01
+#define HV_MMU_IMMU                    0x02
+#define HV_MMU_ALL                     (HV_MMU_DMMU | HV_MMU_IMMU)
+
+/* mmu_map_addr()
+ * TRAP:       HV_MMU_MAP_ADDR_TRAP
+ * ARG0:       virtual address
+ * ARG1:       mmu context
+ * ARG2:       TTE
+ * ARG3:       flags (HV_MMU_{IMMU,DMMU})
+ * ERRORS:     EINVAL          Invalid virtual address, mmu context, or flags
+ *             EBADPGSZ        Invalid page size value
+ *             ENORADDR        Invalid real address in TTE
+ *
+ * Create a non-permanent mapping using the given TTE, virtual
+ * address, and mmu context.  The flags argument determines which
+ * (data, or instruction, or both) TLB the mapping gets loaded into.
+ *
+ * The behavior is undefined if the valid bit is clear in the TTE.
+ *
+ * Note: This API call is for privileged code to specify temporary translation
+ *       mappings without the need to create and manage a TSB.
+ */
+
+/* mmu_unmap_addr()
+ * TRAP:       HV_MMU_UNMAP_ADDR_TRAP
+ * ARG0:       virtual address
+ * ARG1:       mmu context
+ * ARG2:       flags (HV_MMU_{IMMU,DMMU})
+ * ERRORS:     EINVAL          Invalid virtual address, mmu context, or flags
+ *
+ * Demaps the given virtual address in the given mmu context on this
+ * CPU.  This function is intended to be used to demap pages mapped
+ * with mmu_map_addr.  This service is equivalent to invoking
+ * mmu_demap_page() with only the current CPU in the CPU list. The
+ * flags argument determines which (data, or instruction, or both) TLB
+ * the mapping gets unmapped from.
+ *
+ * Attempting to perform an unmap operation for a previously defined
+ * permanent mapping will have undefined results.
+ */
+
+/* mmu_tsb_ctx0()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMU_TSB_CTX0
+ * ARG0:       number of TSB descriptions
+ * ARG1:       TSB descriptions pointer
+ * RET0:       status
+ * ERRORS:     ENORADDR                Invalid TSB descriptions pointer or
+ *                                     TSB base within a descriptor
+ *             EBADALIGN               TSB descriptions pointer is not aligned
+ *                                     to an 8-byte boundary, or TSB base
+ *                                     within a descriptor is not aligned for
+ *                                     the given TSB size
+ *             EBADPGSZ                Invalid page size in a TSB descriptor
+ *             EBADTSB                 Invalid associativity or size in a TSB
+ *                                     descriptor
+ *             EINVAL                  Invalid number of TSB descriptions, or
+ *                                     invalid context index in a TSB
+ *                                     descriptor, or index page size not
+ *                                     equal to smallest page size in page
+ *                                     size bitmask field.
+ *
+ * Configures the TSBs for the current CPU for virtual addresses with
+ * context zero.  The TSB descriptions pointer is a pointer to an
+ * array of the given number of TSB descriptions.
+ *
+ * Note: The maximum number of TSBs available to a virtual CPU is given by the
+ *       mmu-max-#tsbs property of the cpu's corresponding "cpu" node in the
+ *       machine description.
+ */
+#define HV_FAST_MMU_TSB_CTX0           0x20
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mmu_tsb_ctx0(unsigned long num_descriptions,
+                                       unsigned long tsb_desc_ra);
+#endif
+
+/* mmu_tsb_ctxnon0()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMU_TSB_CTXNON0
+ * ARG0:       number of TSB descriptions
+ * ARG1:       TSB descriptions pointer
+ * RET0:       status
+ * ERRORS:     Same as for mmu_tsb_ctx0() above.
+ *
+ * Configures the TSBs for the current CPU for virtual addresses with
+ * non-zero contexts.  The TSB descriptions pointer is a pointer to an
+ * array of the given number of TSB descriptions.
+ *
+ * Note: A maximum of 16 TSBs may be specified in the TSB description list.
+ */
+#define HV_FAST_MMU_TSB_CTXNON0                0x21
+
+/* mmu_demap_page()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMU_DEMAP_PAGE
+ * ARG0:       reserved, must be zero
+ * ARG1:       reserved, must be zero
+ * ARG2:       virtual address
+ * ARG3:       mmu context
+ * ARG4:       flags (HV_MMU_{IMMU,DMMU})
+ * RET0:       status
+ * ERRORS:     EINVAL                  Invalid virutal address, context, or
+ *                                     flags value
+ *             ENOTSUPPORTED           ARG0 or ARG1 is non-zero
+ *
+ * Demaps any page mapping of the given virtual address in the given
+ * mmu context for the current virtual CPU.  Any virtually tagged
+ * caches are guaranteed to be kept consistent.  The flags argument
+ * determines which TLB (instruction, or data, or both) participate in
+ * the operation.
+ *
+ * ARG0 and ARG1 are both reserved and must be set to zero.
+ */
+#define HV_FAST_MMU_DEMAP_PAGE         0x22
+
+/* mmu_demap_ctx()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMU_DEMAP_CTX
+ * ARG0:       reserved, must be zero
+ * ARG1:       reserved, must be zero
+ * ARG2:       mmu context
+ * ARG3:       flags (HV_MMU_{IMMU,DMMU})
+ * RET0:       status
+ * ERRORS:     EINVAL                  Invalid context or flags value
+ *             ENOTSUPPORTED           ARG0 or ARG1 is non-zero
+ *
+ * Demaps all non-permanent virtual page mappings previously specified
+ * for the given context for the current virtual CPU.  Any virtual
+ * tagged caches are guaranteed to be kept consistent.  The flags
+ * argument determines which TLB (instruction, or data, or both)
+ * participate in the operation.
+ *
+ * ARG0 and ARG1 are both reserved and must be set to zero.
+ */
+#define HV_FAST_MMU_DEMAP_CTX          0x23
+
+/* mmu_demap_all()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMU_DEMAP_ALL
+ * ARG0:       reserved, must be zero
+ * ARG1:       reserved, must be zero
+ * ARG2:       flags (HV_MMU_{IMMU,DMMU})
+ * RET0:       status
+ * ERRORS:     EINVAL                  Invalid flags value
+ *             ENOTSUPPORTED           ARG0 or ARG1 is non-zero
+ *
+ * Demaps all non-permanent virtual page mappings previously specified
+ * for the current virtual CPU.  Any virtual tagged caches are
+ * guaranteed to be kept consistent.  The flags argument determines
+ * which TLB (instruction, or data, or both) participate in the
+ * operation.
+ *
+ * ARG0 and ARG1 are both reserved and must be set to zero.
+ */
+#define HV_FAST_MMU_DEMAP_ALL          0x24
+
+#ifndef __ASSEMBLY__
+extern void sun4v_mmu_demap_all(void);
+#endif
+
+/* mmu_map_perm_addr()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMU_MAP_PERM_ADDR
+ * ARG0:       virtual address
+ * ARG1:       reserved, must be zero
+ * ARG2:       TTE
+ * ARG3:       flags (HV_MMU_{IMMU,DMMU})
+ * RET0:       status
+ * ERRORS:     EINVAL                  Invalid virutal address or flags value
+ *             EBADPGSZ                Invalid page size value
+ *             ENORADDR                Invalid real address in TTE
+ *             ETOOMANY                Too many mappings (max of 8 reached)
+ *
+ * Create a permanent mapping using the given TTE and virtual address
+ * for context 0 on the calling virtual CPU.  A maximum of 8 such
+ * permanent mappings may be specified by privileged code.  Mappings
+ * may be removed with mmu_unmap_perm_addr().
+ *
+ * The behavior is undefined if a TTE with the valid bit clear is given.
+ *
+ * Note: This call is used to specify address space mappings for which
+ *       privileged code does not expect to receive misses.  For example,
+ *       this mechanism can be used to map kernel nucleus code and data.
+ */
+#define HV_FAST_MMU_MAP_PERM_ADDR      0x25
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mmu_map_perm_addr(unsigned long vaddr,
+                                            unsigned long set_to_zero,
+                                            unsigned long tte,
+                                            unsigned long flags);
+#endif
+
+/* mmu_fault_area_conf()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMU_FAULT_AREA_CONF
+ * ARG0:       real address
+ * RET0:       status
+ * RET1:       previous mmu fault area real address
+ * ERRORS:     ENORADDR                Invalid real address
+ *             EBADALIGN               Invalid alignment for fault area
+ *
+ * Configure the MMU fault status area for the calling CPU.  A 64-byte
+ * aligned real address specifies where MMU fault status information
+ * is placed.  The return value is the previously specified area, or 0
+ * for the first invocation.  Specifying a fault area at real address
+ * 0 is not allowed.
+ */
+#define HV_FAST_MMU_FAULT_AREA_CONF    0x26
+
+/* mmu_enable()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMU_ENABLE
+ * ARG0:       enable flag
+ * ARG1:       return target address
+ * RET0:       status
+ * ERRORS:     ENORADDR                Invalid real address when disabling
+ *                                     translation.
+ *             EBADALIGN               The return target address is not
+ *                                     aligned to an instruction.
+ *             EINVAL                  The enable flag request the current
+ *                                     operating mode (e.g. disable if already
+ *                                     disabled)
+ *
+ * Enable or disable virtual address translation for the calling CPU
+ * within the virtual machine domain.  If the enable flag is zero,
+ * translation is disabled, any non-zero value will enable
+ * translation.
+ *
+ * When this function returns, the newly selected translation mode
+ * will be active.  If the mmu is being enabled, then the return
+ * target address is a virtual address else it is a real address.
+ *
+ * Upon successful completion, control will be returned to the given
+ * return target address (ie. the cpu will jump to that address).  On
+ * failure, the previous mmu mode remains and the trap simply returns
+ * as normal with the appropriate error code in RET0.
+ */
+#define HV_FAST_MMU_ENABLE             0x27
+
+/* mmu_unmap_perm_addr()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMU_UNMAP_PERM_ADDR
+ * ARG0:       virtual address
+ * ARG1:       reserved, must be zero
+ * ARG2:       flags (HV_MMU_{IMMU,DMMU})
+ * RET0:       status
+ * ERRORS:     EINVAL                  Invalid virutal address or flags value
+ *             ENOMAP                  Specified mapping was not found
+ *
+ * Demaps any permanent page mapping (established via
+ * mmu_map_perm_addr()) at the given virtual address for context 0 on
+ * the current virtual CPU.  Any virtual tagged caches are guaranteed
+ * to be kept consistent.
+ */
+#define HV_FAST_MMU_UNMAP_PERM_ADDR    0x28
+
+/* mmu_tsb_ctx0_info()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMU_TSB_CTX0_INFO
+ * ARG0:       max TSBs
+ * ARG1:       buffer pointer
+ * RET0:       status
+ * RET1:       number of TSBs
+ * ERRORS:     EINVAL                  Supplied buffer is too small
+ *             EBADALIGN               The buffer pointer is badly aligned
+ *             ENORADDR                Invalid real address for buffer pointer
+ *
+ * Return the TSB configuration as previous defined by mmu_tsb_ctx0()
+ * into the provided buffer.  The size of the buffer is given in ARG1
+ * in terms of the number of TSB description entries.
+ *
+ * Upon return, RET1 always contains the number of TSB descriptions
+ * previously configured.  If zero TSBs were configured, EOK is
+ * returned with RET1 containing 0.
+ */
+#define HV_FAST_MMU_TSB_CTX0_INFO      0x29
+
+/* mmu_tsb_ctxnon0_info()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMU_TSB_CTXNON0_INFO
+ * ARG0:       max TSBs
+ * ARG1:       buffer pointer
+ * RET0:       status
+ * RET1:       number of TSBs
+ * ERRORS:     EINVAL                  Supplied buffer is too small
+ *             EBADALIGN               The buffer pointer is badly aligned
+ *             ENORADDR                Invalid real address for buffer pointer
+ *
+ * Return the TSB configuration as previous defined by
+ * mmu_tsb_ctxnon0() into the provided buffer.  The size of the buffer
+ * is given in ARG1 in terms of the number of TSB description entries.
+ *
+ * Upon return, RET1 always contains the number of TSB descriptions
+ * previously configured.  If zero TSBs were configured, EOK is
+ * returned with RET1 containing 0.
+ */
+#define HV_FAST_MMU_TSB_CTXNON0_INFO   0x2a
+
+/* mmu_fault_area_info()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMU_FAULT_AREA_INFO
+ * RET0:       status
+ * RET1:       fault area real address
+ * ERRORS:     No errors defined.
+ *
+ * Return the currently defined MMU fault status area for the current
+ * CPU.  The real address of the fault status area is returned in
+ * RET1, or 0 is returned in RET1 if no fault status area is defined.
+ *
+ * Note: mmu_fault_area_conf() may be called with the return value (RET1)
+ *       from this service if there is a need to save and restore the fault
+ *      area for a cpu.
+ */
+#define HV_FAST_MMU_FAULT_AREA_INFO    0x2b
+
+/* Cache and Memory services. */
+
+/* mem_scrub()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MEM_SCRUB
+ * ARG0:       real address
+ * ARG1:       length
+ * RET0:       status
+ * RET1:       length scrubbed
+ * ERRORS:     ENORADDR        Invalid real address
+ *             EBADALIGN       Start address or length are not correctly
+ *                             aligned
+ *             EINVAL          Length is zero
+ *
+ * Zero the memory contents in the range real address to real address
+ * plus length minus 1.  Also, valid ECC will be generated for that
+ * memory address range.  Scrubbing is started at the given real
+ * address, but may not scrub the entire given length.  The actual
+ * length scrubbed will be returned in RET1.
+ *
+ * The real address and length must be aligned on an 8K boundary, or
+ * contain the start address and length from a sun4v error report.
+ *
+ * Note: There are two uses for this function.  The first use is to block clear
+ *       and initialize memory and the second is to scrub an u ncorrectable
+ *       error reported via a resumable or non-resumable trap.  The second
+ *       use requires the arguments to be equal to the real address and length
+ *       provided in a sun4v memory error report.
+ */
+#define HV_FAST_MEM_SCRUB              0x31
+
+/* mem_sync()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MEM_SYNC
+ * ARG0:       real address
+ * ARG1:       length
+ * RET0:       status
+ * RET1:       length synced
+ * ERRORS:     ENORADDR        Invalid real address
+ *             EBADALIGN       Start address or length are not correctly
+ *                             aligned
+ *             EINVAL          Length is zero
+ *
+ * Force the next access within the real address to real address plus
+ * length minus 1 to be fetches from main system memory.  Less than
+ * the given length may be synced, the actual amount synced is
+ * returned in RET1.  The real address and length must be aligned on
+ * an 8K boundary.
+ */
+#define HV_FAST_MEM_SYNC               0x32
+
+/* Time of day services.
+ *
+ * The hypervisor maintains the time of day on a per-domain basis.
+ * Changing the time of day in one domain does not affect the time of
+ * day on any other domain.
+ *
+ * Time is described by a single unsigned 64-bit word which is the
+ * number of seconds since the UNIX Epoch (00:00:00 UTC, January 1,
+ * 1970).
+ */
+
+/* tod_get()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_TOD_GET
+ * RET0:       status
+ * RET1:       TOD
+ * ERRORS:     EWOULDBLOCK     TOD resource is temporarily unavailable
+ *             ENOTSUPPORTED   If TOD not supported on this platform
+ *
+ * Return the current time of day.  May block if TOD access is
+ * temporarily not possible.
+ */
+#define HV_FAST_TOD_GET                        0x50
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_tod_get(unsigned long *time);
+#endif
+
+/* tod_set()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_TOD_SET
+ * ARG0:       TOD
+ * RET0:       status
+ * ERRORS:     EWOULDBLOCK     TOD resource is temporarily unavailable
+ *             ENOTSUPPORTED   If TOD not supported on this platform
+ *
+ * The current time of day is set to the value specified in ARG0.  May
+ * block if TOD access is temporarily not possible.
+ */
+#define HV_FAST_TOD_SET                        0x51
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_tod_set(unsigned long time);
+#endif
+
+/* Console services */
+
+/* con_getchar()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CONS_GETCHAR
+ * RET0:       status
+ * RET1:       character
+ * ERRORS:     EWOULDBLOCK     No character available.
+ *
+ * Returns a character from the console device.  If no character is
+ * available then an EWOULDBLOCK error is returned.  If a character is
+ * available, then the returned status is EOK and the character value
+ * is in RET1.
+ *
+ * A virtual BREAK is represented by the 64-bit value -1.
+ *
+ * A virtual HUP signal is represented by the 64-bit value -2.
+ */
+#define HV_FAST_CONS_GETCHAR           0x60
+
+/* con_putchar()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CONS_PUTCHAR
+ * ARG0:       character
+ * RET0:       status
+ * ERRORS:     EINVAL          Illegal character
+ *             EWOULDBLOCK     Output buffer currently full, would block
+ *
+ * Send a character to the console device.  Only character values
+ * between 0 and 255 may be used.  Values outside this range are
+ * invalid except for the 64-bit value -1 which is used to send a
+ * virtual BREAK.
+ */
+#define HV_FAST_CONS_PUTCHAR           0x61
+
+/* con_read()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CONS_READ
+ * ARG0:       buffer real address
+ * ARG1:       buffer size in bytes
+ * RET0:       status
+ * RET1:       bytes read or BREAK or HUP
+ * ERRORS:     EWOULDBLOCK     No character available.
+ *
+ * Reads characters into a buffer from the console device.  If no
+ * character is available then an EWOULDBLOCK error is returned.
+ * If a character is available, then the returned status is EOK
+ * and the number of bytes read into the given buffer is provided
+ * in RET1.
+ *
+ * A virtual BREAK is represented by the 64-bit RET1 value -1.
+ *
+ * A virtual HUP signal is represented by the 64-bit RET1 value -2.
+ *
+ * If BREAK or HUP are indicated, no bytes were read into buffer.
+ */
+#define HV_FAST_CONS_READ              0x62
+
+/* con_write()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_CONS_WRITE
+ * ARG0:       buffer real address
+ * ARG1:       buffer size in bytes
+ * RET0:       status
+ * RET1:       bytes written
+ * ERRORS:     EWOULDBLOCK     Output buffer currently full, would block
+ *
+ * Send a characters in buffer to the console device.  Breaks must be
+ * sent using con_putchar().
+ */
+#define HV_FAST_CONS_WRITE             0x63
+
+#ifndef __ASSEMBLY__
+extern long sun4v_con_getchar(long *status);
+extern long sun4v_con_putchar(long c);
+extern long sun4v_con_read(unsigned long buffer,
+                          unsigned long size,
+                          unsigned long *bytes_read);
+extern unsigned long sun4v_con_write(unsigned long buffer,
+                                    unsigned long size,
+                                    unsigned long *bytes_written);
+#endif
+
+/* mach_set_soft_state()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MACH_SET_SOFT_STATE
+ * ARG0:       software state
+ * ARG1:       software state description pointer
+ * RET0:       status
+ * ERRORS:     EINVAL          software state not valid or software state
+ *                             description is not NULL terminated
+ *             ENORADDR        software state description pointer is not a
+ *                             valid real address
+ *             EBADALIGNED     software state description is not correctly
+ *                             aligned
+ *
+ * This allows the guest to report it's soft state to the hypervisor.  There
+ * are two primary components to this state.  The first part states whether
+ * the guest software is running or not.  The second containts optional
+ * details specific to the software.
+ *
+ * The software state argument is defined below in HV_SOFT_STATE_*, and
+ * indicates whether the guest is operating normally or in a transitional
+ * state.
+ *
+ * The software state description argument is a real address of a data buffer
+ * of size 32-bytes aligned on a 32-byte boundary.  It is treated as a NULL
+ * terminated 7-bit ASCII string of up to 31 characters not including the
+ * NULL termination.
+ */
+#define HV_FAST_MACH_SET_SOFT_STATE    0x70
+#define  HV_SOFT_STATE_NORMAL           0x01
+#define  HV_SOFT_STATE_TRANSITION       0x02
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mach_set_soft_state(unsigned long soft_state,
+                                              unsigned long msg_string_ra);
+#endif
+
+/* mach_get_soft_state()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MACH_GET_SOFT_STATE
+ * ARG0:       software state description pointer
+ * RET0:       status
+ * RET1:       software state
+ * ERRORS:     ENORADDR        software state description pointer is not a
+ *                             valid real address
+ *             EBADALIGNED     software state description is not correctly
+ *                             aligned
+ *
+ * Retrieve the current value of the guest's software state.  The rules
+ * for the software state pointer are the same as for mach_set_soft_state()
+ * above.
+ */
+#define HV_FAST_MACH_GET_SOFT_STATE    0x71
+
+/* svc_send()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_SVC_SEND
+ * ARG0:       service ID
+ * ARG1:       buffer real address
+ * ARG2:       buffer size
+ * RET0:       STATUS
+ * RET1:       sent_bytes
+ *
+ * Be careful, all output registers are clobbered by this operation,
+ * so for example it is not possible to save away a value in %o4
+ * across the trap.
+ */
+#define HV_FAST_SVC_SEND               0x80
+
+/* svc_recv()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_SVC_RECV
+ * ARG0:       service ID
+ * ARG1:       buffer real address
+ * ARG2:       buffer size
+ * RET0:       STATUS
+ * RET1:       recv_bytes
+ *
+ * Be careful, all output registers are clobbered by this operation,
+ * so for example it is not possible to save away a value in %o4
+ * across the trap.
+ */
+#define HV_FAST_SVC_RECV               0x81
+
+/* svc_getstatus()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_SVC_GETSTATUS
+ * ARG0:       service ID
+ * RET0:       STATUS
+ * RET1:       status bits
+ */
+#define HV_FAST_SVC_GETSTATUS          0x82
+
+/* svc_setstatus()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_SVC_SETSTATUS
+ * ARG0:       service ID
+ * ARG1:       bits to set
+ * RET0:       STATUS
+ */
+#define HV_FAST_SVC_SETSTATUS          0x83
+
+/* svc_clrstatus()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_SVC_CLRSTATUS
+ * ARG0:       service ID
+ * ARG1:       bits to clear
+ * RET0:       STATUS
+ */
+#define HV_FAST_SVC_CLRSTATUS          0x84
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_svc_send(unsigned long svc_id,
+                                   unsigned long buffer,
+                                   unsigned long buffer_size,
+                                   unsigned long *sent_bytes);
+extern unsigned long sun4v_svc_recv(unsigned long svc_id,
+                                   unsigned long buffer,
+                                   unsigned long buffer_size,
+                                   unsigned long *recv_bytes);
+extern unsigned long sun4v_svc_getstatus(unsigned long svc_id,
+                                        unsigned long *status_bits);
+extern unsigned long sun4v_svc_setstatus(unsigned long svc_id,
+                                        unsigned long status_bits);
+extern unsigned long sun4v_svc_clrstatus(unsigned long svc_id,
+                                        unsigned long status_bits);
+#endif
+
+/* Trap trace services.
+ *
+ * The hypervisor provides a trap tracing capability for privileged
+ * code running on each virtual CPU.  Privileged code provides a
+ * round-robin trap trace queue within which the hypervisor writes
+ * 64-byte entries detailing hyperprivileged traps taken n behalf of
+ * privileged code.  This is provided as a debugging capability for
+ * privileged code.
+ *
+ * The trap trace control structure is 64-bytes long and placed at the
+ * start (offset 0) of the trap trace buffer, and is described as
+ * follows:
+ */
+#ifndef __ASSEMBLY__
+struct hv_trap_trace_control {
+       unsigned long           head_offset;
+       unsigned long           tail_offset;
+       unsigned long           __reserved[0x30 / sizeof(unsigned long)];
+};
+#endif
+#define HV_TRAP_TRACE_CTRL_HEAD_OFFSET 0x00
+#define HV_TRAP_TRACE_CTRL_TAIL_OFFSET 0x08
+
+/* The head offset is the offset of the most recently completed entry
+ * in the trap-trace buffer.  The tail offset is the offset of the
+ * next entry to be written.  The control structure is owned and
+ * modified by the hypervisor.  A guest may not modify the control
+ * structure contents.  Attempts to do so will result in undefined
+ * behavior for the guest.
+ *
+ * Each trap trace buffer entry is layed out as follows:
+ */
+#ifndef __ASSEMBLY__
+struct hv_trap_trace_entry {
+       unsigned char   type;           /* Hypervisor or guest entry?   */
+       unsigned char   hpstate;        /* Hyper-privileged state       */
+       unsigned char   tl;             /* Trap level                   */
+       unsigned char   gl;             /* Global register level        */
+       unsigned short  tt;             /* Trap type                    */
+       unsigned short  tag;            /* Extended trap identifier     */
+       unsigned long   tstate;         /* Trap state                   */
+       unsigned long   tick;           /* Tick                         */
+       unsigned long   tpc;            /* Trap PC                      */
+       unsigned long   f1;             /* Entry specific               */
+       unsigned long   f2;             /* Entry specific               */
+       unsigned long   f3;             /* Entry specific               */
+       unsigned long   f4;             /* Entry specific               */
+};
+#endif
+#define HV_TRAP_TRACE_ENTRY_TYPE       0x00
+#define HV_TRAP_TRACE_ENTRY_HPSTATE    0x01
+#define HV_TRAP_TRACE_ENTRY_TL         0x02
+#define HV_TRAP_TRACE_ENTRY_GL         0x03
+#define HV_TRAP_TRACE_ENTRY_TT         0x04
+#define HV_TRAP_TRACE_ENTRY_TAG                0x06
+#define HV_TRAP_TRACE_ENTRY_TSTATE     0x08
+#define HV_TRAP_TRACE_ENTRY_TICK       0x10
+#define HV_TRAP_TRACE_ENTRY_TPC                0x18
+#define HV_TRAP_TRACE_ENTRY_F1         0x20
+#define HV_TRAP_TRACE_ENTRY_F2         0x28
+#define HV_TRAP_TRACE_ENTRY_F3         0x30
+#define HV_TRAP_TRACE_ENTRY_F4         0x38
+
+/* The type field is encoded as follows.  */
+#define HV_TRAP_TYPE_UNDEF             0x00 /* Entry content undefined     */
+#define HV_TRAP_TYPE_HV                        0x01 /* Hypervisor trap entry       */
+#define HV_TRAP_TYPE_GUEST             0xff /* Added via ttrace_addentry() */
+
+/* ttrace_buf_conf()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_TTRACE_BUF_CONF
+ * ARG0:       real address
+ * ARG1:       number of entries
+ * RET0:       status
+ * RET1:       number of entries
+ * ERRORS:     ENORADDR        Invalid real address
+ *             EINVAL          Size is too small
+ *             EBADALIGN       Real address not aligned on 64-byte boundary
+ *
+ * Requests hypervisor trap tracing and declares a virtual CPU's trap
+ * trace buffer to the hypervisor.  The real address supplies the real
+ * base address of the trap trace queue and must be 64-byte aligned.
+ * Specifying a value of 0 for the number of entries disables trap
+ * tracing for the calling virtual CPU.  The buffer allocated must be
+ * sized for a power of two number of 64-byte trap trace entries plus
+ * an initial 64-byte control structure.
+ *
+ * This may be invoked any number of times so that a virtual CPU may
+ * relocate a trap trace buffer or create "snapshots" of information.
+ *
+ * If the real address is illegal or badly aligned, then trap tracing
+ * is disabled and an error is returned.
+ *
+ * Upon failure with EINVAL, this service call returns in RET1 the
+ * minimum number of buffer entries required.  Upon other failures
+ * RET1 is undefined.
+ */
+#define HV_FAST_TTRACE_BUF_CONF                0x90
+
+/* ttrace_buf_info()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_TTRACE_BUF_INFO
+ * RET0:       status
+ * RET1:       real address
+ * RET2:       size
+ * ERRORS:     None defined.
+ *
+ * Returns the size and location of the previously declared trap-trace
+ * buffer.  In the event that no buffer was previously defined, or the
+ * buffer is disabled, this call will return a size of zero bytes.
+ */
+#define HV_FAST_TTRACE_BUF_INFO                0x91
+
+/* ttrace_enable()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_TTRACE_ENABLE
+ * ARG0:       enable
+ * RET0:       status
+ * RET1:       previous enable state
+ * ERRORS:     EINVAL          No trap trace buffer currently defined
+ *
+ * Enable or disable trap tracing, and return the previous enabled
+ * state in RET1.  Future systems may define various flags for the
+ * enable argument (ARG0), for the moment a guest should pass
+ * "(uint64_t) -1" to enable, and "(uint64_t) 0" to disable all
+ * tracing - which will ensure future compatability.
+ */
+#define HV_FAST_TTRACE_ENABLE          0x92
+
+/* ttrace_freeze()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_TTRACE_FREEZE
+ * ARG0:       freeze
+ * RET0:       status
+ * RET1:       previous freeze state
+ * ERRORS:     EINVAL          No trap trace buffer currently defined
+ *
+ * Freeze or unfreeze trap tracing, returning the previous freeze
+ * state in RET1.  A guest should pass a non-zero value to freeze and
+ * a zero value to unfreeze all tracing.  The returned previous state
+ * is 0 for not frozen and 1 for frozen.
+ */
+#define HV_FAST_TTRACE_FREEZE          0x93
+
+/* ttrace_addentry()
+ * TRAP:       HV_TTRACE_ADDENTRY_TRAP
+ * ARG0:       tag (16-bits)
+ * ARG1:       data word 0
+ * ARG2:       data word 1
+ * ARG3:       data word 2
+ * ARG4:       data word 3
+ * RET0:       status
+ * ERRORS:     EINVAL          No trap trace buffer currently defined
+ *
+ * Add an entry to the trap trace buffer.  Upon return only ARG0/RET0
+ * is modified - none of the other registers holding arguments are
+ * volatile across this hypervisor service.
+ */
+
+/* Core dump services.
+ *
+ * Since the hypervisor viraulizes and thus obscures a lot of the
+ * physical machine layout and state, traditional OS crash dumps can
+ * be difficult to diagnose especially when the problem is a
+ * configuration error of some sort.
+ *
+ * The dump services provide an opaque buffer into which the
+ * hypervisor can place it's internal state in order to assist in
+ * debugging such situations.  The contents are opaque and extremely
+ * platform and hypervisor implementation specific.  The guest, during
+ * a core dump, requests that the hypervisor update any information in
+ * the dump buffer in preparation to being dumped as part of the
+ * domain's memory image.
+ */
+
+/* dump_buf_update()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_DUMP_BUF_UPDATE
+ * ARG0:       real address
+ * ARG1:       size
+ * RET0:       status
+ * RET1:       required size of dump buffer
+ * ERRORS:     ENORADDR        Invalid real address
+ *             EBADALIGN       Real address is not aligned on a 64-byte
+ *                             boundary
+ *             EINVAL          Size is non-zero but less than minimum size
+ *                             required
+ *             ENOTSUPPORTED   Operation not supported on current logical
+ *                             domain
+ *
+ * Declare a domain dump buffer to the hypervisor.  The real address
+ * provided for the domain dump buffer must be 64-byte aligned.  The
+ * size specifies the size of the dump buffer and may be larger than
+ * the minimum size specified in the machine description.  The
+ * hypervisor will fill the dump buffer with opaque data.
+ *
+ * Note: A guest may elect to include dump buffer contents as part of a crash
+ *       dump to assist with debugging.  This function may be called any number
+ *       of times so that a guest may relocate a dump buffer, or create
+ *       "snapshots" of any dump-buffer information.  Each call to
+ *       dump_buf_update() atomically declares the new dump buffer to the
+ *       hypervisor.
+ *
+ * A specified size of 0 unconfigures the dump buffer.  If the real
+ * address is illegal or badly aligned, then any currently active dump
+ * buffer is disabled and an error is returned.
+ *
+ * In the event that the call fails with EINVAL, RET1 contains the
+ * minimum size requires by the hypervisor for a valid dump buffer.
+ */
+#define HV_FAST_DUMP_BUF_UPDATE                0x94
+
+/* dump_buf_info()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_DUMP_BUF_INFO
+ * RET0:       status
+ * RET1:       real address of current dump buffer
+ * RET2:       size of current dump buffer
+ * ERRORS:     No errors defined.
+ *
+ * Return the currently configures dump buffer description.  A
+ * returned size of 0 bytes indicates an undefined dump buffer.  In
+ * this case the return address in RET1 is undefined.
+ */
+#define HV_FAST_DUMP_BUF_INFO          0x95
+
+/* Device interrupt services.
+ *
+ * Device interrupts are allocated to system bus bridges by the hypervisor,
+ * and described to OBP in the machine description.  OBP then describes
+ * these interrupts to the OS via properties in the device tree.
+ *
+ * Terminology:
+ *
+ *     cpuid           Unique opaque value which represents a target cpu.
+ *
+ *     devhandle       Device handle.  It uniquely identifies a device, and
+ *                     consistes of the lower 28-bits of the hi-cell of the
+ *                     first entry of the device's "reg" property in the
+ *                     OBP device tree.
+ *
+ *     devino          Device interrupt number.  Specifies the relative
+ *                     interrupt number within the device.  The unique
+ *                     combination of devhandle and devino are used to
+ *                     identify a specific device interrupt.
+ *
+ *                     Note: The devino value is the same as the values in the
+ *                           "interrupts" property or "interrupt-map" property
+ *                           in the OBP device tree for that device.
+ *
+ *     sysino          System interrupt number.  A 64-bit unsigned interger
+ *                     representing a unique interrupt within a virtual
+ *                     machine.
+ *
+ *     intr_state      A flag representing the interrupt state for a given
+ *                     sysino.  The state values are defined below.
+ *
+ *     intr_enabled    A flag representing the 'enabled' state for a given
+ *                     sysino.  The enable values are defined below.
+ */
+
+#define HV_INTR_STATE_IDLE             0 /* Nothing pending */
+#define HV_INTR_STATE_RECEIVED         1 /* Interrupt received by hardware */
+#define HV_INTR_STATE_DELIVERED                2 /* Interrupt delivered to queue */
+
+#define HV_INTR_DISABLED               0 /* sysino not enabled */
+#define HV_INTR_ENABLED                        1 /* sysino enabled */
+
+/* intr_devino_to_sysino()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_INTR_DEVINO2SYSINO
+ * ARG0:       devhandle
+ * ARG1:       devino
+ * RET0:       status
+ * RET1:       sysino
+ * ERRORS:     EINVAL          Invalid devhandle/devino
+ *
+ * Converts a device specific interrupt number of the given
+ * devhandle/devino into a system specific ino (sysino).
+ */
+#define HV_FAST_INTR_DEVINO2SYSINO     0xa0
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_devino_to_sysino(unsigned long devhandle,
+                                           unsigned long devino);
+#endif
+
+/* intr_getenabled()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_INTR_GETENABLED
+ * ARG0:       sysino
+ * RET0:       status
+ * RET1:       intr_enabled (HV_INTR_{DISABLED,ENABLED})
+ * ERRORS:     EINVAL          Invalid sysino
+ *
+ * Returns interrupt enabled state in RET1 for the interrupt defined
+ * by the given sysino.
+ */
+#define HV_FAST_INTR_GETENABLED                0xa1
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_intr_getenabled(unsigned long sysino);
+#endif
+
+/* intr_setenabled()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_INTR_SETENABLED
+ * ARG0:       sysino
+ * ARG1:       intr_enabled (HV_INTR_{DISABLED,ENABLED})
+ * RET0:       status
+ * ERRORS:     EINVAL          Invalid sysino or intr_enabled value
+ *
+ * Set the 'enabled' state of the interrupt sysino.
+ */
+#define HV_FAST_INTR_SETENABLED                0xa2
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_intr_setenabled(unsigned long sysino, unsigned long intr_enabled);
+#endif
+
+/* intr_getstate()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_INTR_GETSTATE
+ * ARG0:       sysino
+ * RET0:       status
+ * RET1:       intr_state (HV_INTR_STATE_*)
+ * ERRORS:     EINVAL          Invalid sysino
+ *
+ * Returns current state of the interrupt defined by the given sysino.
+ */
+#define HV_FAST_INTR_GETSTATE          0xa3
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_intr_getstate(unsigned long sysino);
+#endif
+
+/* intr_setstate()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_INTR_SETSTATE
+ * ARG0:       sysino
+ * ARG1:       intr_state (HV_INTR_STATE_*)
+ * RET0:       status
+ * ERRORS:     EINVAL          Invalid sysino or intr_state value
+ *
+ * Sets the current state of the interrupt described by the given sysino
+ * value.
+ *
+ * Note: Setting the state to HV_INTR_STATE_IDLE clears any pending
+ *       interrupt for sysino.
+ */
+#define HV_FAST_INTR_SETSTATE          0xa4
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_intr_setstate(unsigned long sysino, unsigned long intr_state);
+#endif
+
+/* intr_gettarget()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_INTR_GETTARGET
+ * ARG0:       sysino
+ * RET0:       status
+ * RET1:       cpuid
+ * ERRORS:     EINVAL          Invalid sysino
+ *
+ * Returns CPU that is the current target of the interrupt defined by
+ * the given sysino.  The CPU value returned is undefined if the target
+ * has not been set via intr_settarget().
+ */
+#define HV_FAST_INTR_GETTARGET         0xa5
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_intr_gettarget(unsigned long sysino);
+#endif
+
+/* intr_settarget()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_INTR_SETTARGET
+ * ARG0:       sysino
+ * ARG1:       cpuid
+ * RET0:       status
+ * ERRORS:     EINVAL          Invalid sysino
+ *             ENOCPU          Invalid cpuid
+ *
+ * Set the target CPU for the interrupt defined by the given sysino.
+ */
+#define HV_FAST_INTR_SETTARGET         0xa6
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_intr_settarget(unsigned long sysino, unsigned long cpuid);
+#endif
+
+/* vintr_get_cookie()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_GET_COOKIE
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * RET0:       status
+ * RET1:       cookie
+ */
+#define HV_FAST_VINTR_GET_COOKIE       0xa7
+
+/* vintr_set_cookie()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_SET_COOKIE
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * ARG2:       cookie
+ * RET0:       status
+ */
+#define HV_FAST_VINTR_SET_COOKIE       0xa8
+
+/* vintr_get_valid()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_GET_VALID
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * RET0:       status
+ * RET1:       valid state
+ */
+#define HV_FAST_VINTR_GET_VALID                0xa9
+
+/* vintr_set_valid()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_SET_VALID
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * ARG2:       valid state
+ * RET0:       status
+ */
+#define HV_FAST_VINTR_SET_VALID                0xaa
+
+/* vintr_get_state()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_GET_STATE
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * RET0:       status
+ * RET1:       state
+ */
+#define HV_FAST_VINTR_GET_STATE                0xab
+
+/* vintr_set_state()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_SET_STATE
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * ARG2:       state
+ * RET0:       status
+ */
+#define HV_FAST_VINTR_SET_STATE                0xac
+
+/* vintr_get_target()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_GET_TARGET
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * RET0:       status
+ * RET1:       cpuid
+ */
+#define HV_FAST_VINTR_GET_TARGET       0xad
+
+/* vintr_set_target()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_VINTR_SET_TARGET
+ * ARG0:       device handle
+ * ARG1:       device ino
+ * ARG2:       cpuid
+ * RET0:       status
+ */
+#define HV_FAST_VINTR_SET_TARGET       0xae
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_vintr_get_cookie(unsigned long dev_handle,
+                                           unsigned long dev_ino,
+                                           unsigned long *cookie);
+extern unsigned long sun4v_vintr_set_cookie(unsigned long dev_handle,
+                                           unsigned long dev_ino,
+                                           unsigned long cookie);
+extern unsigned long sun4v_vintr_get_valid(unsigned long dev_handle,
+                                          unsigned long dev_ino,
+                                          unsigned long *valid);
+extern unsigned long sun4v_vintr_set_valid(unsigned long dev_handle,
+                                          unsigned long dev_ino,
+                                          unsigned long valid);
+extern unsigned long sun4v_vintr_get_state(unsigned long dev_handle,
+                                          unsigned long dev_ino,
+                                          unsigned long *state);
+extern unsigned long sun4v_vintr_set_state(unsigned long dev_handle,
+                                          unsigned long dev_ino,
+                                          unsigned long state);
+extern unsigned long sun4v_vintr_get_target(unsigned long dev_handle,
+                                           unsigned long dev_ino,
+                                           unsigned long *cpuid);
+extern unsigned long sun4v_vintr_set_target(unsigned long dev_handle,
+                                           unsigned long dev_ino,
+                                           unsigned long cpuid);
+#endif
+
+/* PCI IO services.
+ *
+ * See the terminology descriptions in the device interrupt services
+ * section above as those apply here too.  Here are terminology
+ * definitions specific to these PCI IO services:
+ *
+ *     tsbnum          TSB number.  Indentifies which io-tsb is used.
+ *                     For this version of the specification, tsbnum
+ *                     must be zero.
+ *
+ *     tsbindex        TSB index.  Identifies which entry in the TSB
+ *                     is used.  The first entry is zero.
+ *
+ *     tsbid           A 64-bit aligned data structure which contains
+ *                     a tsbnum and a tsbindex.  Bits 63:32 contain the
+ *                     tsbnum and bits 31:00 contain the tsbindex.
+ *
+ *                     Use the HV_PCI_TSBID() macro to construct such
+ *                     values.
+ *
+ *     io_attributes   IO attributes for IOMMU mappings.  One of more
+ *                     of the attritbute bits are stores in a 64-bit
+ *                     value.  The values are defined below.
+ *
+ *     r_addr          64-bit real address
+ *
+ *     pci_device      PCI device address.  A PCI device address identifies
+ *                     a specific device on a specific PCI bus segment.
+ *                     A PCI device address ia a 32-bit unsigned integer
+ *                     with the following format:
+ *
+ *                             00000000.bbbbbbbb.dddddfff.00000000
+ *
+ *                     Use the HV_PCI_DEVICE_BUILD() macro to construct
+ *                     such values.
+ *
+ *     pci_config_offset
+ *                     PCI configureation space offset.  For conventional
+ *                     PCI a value between 0 and 255.  For extended
+ *                     configuration space, a value between 0 and 4095.
+ *
+ *                     Note: For PCI configuration space accesses, the offset
+ *                           must be aligned to the access size.
+ *
+ *     error_flag      A return value which specifies if the action succeeded
+ *                     or failed.  0 means no error, non-0 means some error
+ *                     occurred while performing the service.
+ *
+ *     io_sync_direction
+ *                     Direction definition for pci_dma_sync(), defined
+ *                     below in HV_PCI_SYNC_*.
+ *
+ *     io_page_list    A list of io_page_addresses, an io_page_address is
+ *                     a real address.
+ *
+ *     io_page_list_p  A pointer to an io_page_list.
+ *
+ *     "size based byte swap" - Some functions do size based byte swapping
+ *                              which allows sw to access pointers and
+ *                              counters in native form when the processor
+ *                              operates in a different endianness than the
+ *                              IO bus.  Size-based byte swapping converts a
+ *                              multi-byte field between big-endian and
+ *                              little-endian format.
+ */
+
+#define HV_PCI_MAP_ATTR_READ           0x01
+#define HV_PCI_MAP_ATTR_WRITE          0x02
+
+#define HV_PCI_DEVICE_BUILD(b,d,f)     \
+       ((((b) & 0xff) << 16) | \
+        (((d) & 0x1f) << 11) | \
+        (((f) & 0x07) <<  8))
+
+#define HV_PCI_TSBID(__tsb_num, __tsb_index) \
+       ((((u64)(__tsb_num)) << 32UL) | ((u64)(__tsb_index)))
+
+#define HV_PCI_SYNC_FOR_DEVICE         0x01
+#define HV_PCI_SYNC_FOR_CPU            0x02
+
+/* pci_iommu_map()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_IOMMU_MAP
+ * ARG0:       devhandle
+ * ARG1:       tsbid
+ * ARG2:       #ttes
+ * ARG3:       io_attributes
+ * ARG4:       io_page_list_p
+ * RET0:       status
+ * RET1:       #ttes mapped
+ * ERRORS:     EINVAL          Invalid devhandle/tsbnum/tsbindex/io_attributes
+ *             EBADALIGN       Improperly aligned real address
+ *             ENORADDR        Invalid real address
+ *
+ * Create IOMMU mappings in the sun4v device defined by the given
+ * devhandle.  The mappings are created in the TSB defined by the
+ * tsbnum component of the given tsbid.  The first mapping is created
+ * in the TSB i ndex defined by the tsbindex component of the given tsbid.
+ * The call creates up to #ttes mappings, the first one at tsbnum, tsbindex,
+ * the second at tsbnum, tsbindex + 1, etc.
+ *
+ * All mappings are created with the attributes defined by the io_attributes
+ * argument.  The page mapping addresses are described in the io_page_list
+ * defined by the given io_page_list_p, which is a pointer to the io_page_list.
+ * The first entry in the io_page_list is the address for the first iotte, the
+ * 2nd for the 2nd iotte, and so on.
+ *
+ * Each io_page_address in the io_page_list must be appropriately aligned.
+ * #ttes must be greater than zero.  For this version of the spec, the tsbnum
+ * component of the given tsbid must be zero.
+ *
+ * Returns the actual number of mappings creates, which may be less than
+ * or equal to the argument #ttes.  If the function returns a value which
+ * is less than the #ttes, the caller may continus to call the function with
+ * an updated tsbid, #ttes, io_page_list_p arguments until all pages are
+ * mapped.
+ *
+ * Note: This function does not imply an iotte cache flush.  The guest must
+ *       demap an entry before re-mapping it.
+ */
+#define HV_FAST_PCI_IOMMU_MAP          0xb0
+
+/* pci_iommu_demap()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_IOMMU_DEMAP
+ * ARG0:       devhandle
+ * ARG1:       tsbid
+ * ARG2:       #ttes
+ * RET0:       status
+ * RET1:       #ttes demapped
+ * ERRORS:     EINVAL          Invalid devhandle/tsbnum/tsbindex
+ *
+ * Demap and flush IOMMU mappings in the device defined by the given
+ * devhandle.  Demaps up to #ttes entries in the TSB defined by the tsbnum
+ * component of the given tsbid, starting at the TSB index defined by the
+ * tsbindex component of the given tsbid.
+ *
+ * For this version of the spec, the tsbnum of the given tsbid must be zero.
+ * #ttes must be greater than zero.
+ *
+ * Returns the actual number of ttes demapped, which may be less than or equal
+ * to the argument #ttes.  If #ttes demapped is less than #ttes, the caller
+ * may continue to call this function with updated tsbid and #ttes arguments
+ * until all pages are demapped.
+ *
+ * Note: Entries do not have to be mapped to be demapped.  A demap of an
+ *       unmapped page will flush the entry from the tte cache.
+ */
+#define HV_FAST_PCI_IOMMU_DEMAP                0xb1
+
+/* pci_iommu_getmap()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_IOMMU_GETMAP
+ * ARG0:       devhandle
+ * ARG1:       tsbid
+ * RET0:       status
+ * RET1:       io_attributes
+ * RET2:       real address
+ * ERRORS:     EINVAL          Invalid devhandle/tsbnum/tsbindex
+ *             ENOMAP          Mapping is not valid, no translation exists
+ *
+ * Read and return the mapping in the device described by the given devhandle
+ * and tsbid.  If successful, the io_attributes shall be returned in RET1
+ * and the page address of the mapping shall be returned in RET2.
+ *
+ * For this version of the spec, the tsbnum component of the given tsbid
+ * must be zero.
+ */
+#define HV_FAST_PCI_IOMMU_GETMAP       0xb2
+
+/* pci_iommu_getbypass()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_IOMMU_GETBYPASS
+ * ARG0:       devhandle
+ * ARG1:       real address
+ * ARG2:       io_attributes
+ * RET0:       status
+ * RET1:       io_addr
+ * ERRORS:     EINVAL          Invalid devhandle/io_attributes
+ *             ENORADDR        Invalid real address
+ *             ENOTSUPPORTED   Function not supported in this implementation.
+ *
+ * Create a "special" mapping in the device described by the given devhandle,
+ * for the given real address and attributes.  Return the IO address in RET1
+ * if successful.
+ */
+#define HV_FAST_PCI_IOMMU_GETBYPASS    0xb3
+
+/* pci_config_get()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_CONFIG_GET
+ * ARG0:       devhandle
+ * ARG1:       pci_device
+ * ARG2:       pci_config_offset
+ * ARG3:       size
+ * RET0:       status
+ * RET1:       error_flag
+ * RET2:       data
+ * ERRORS:     EINVAL          Invalid devhandle/pci_device/offset/size
+ *             EBADALIGN       pci_config_offset not size aligned
+ *             ENOACCESS       Access to this offset is not permitted
+ *
+ * Read PCI configuration space for the adapter described by the given
+ * devhandle.  Read size (1, 2, or 4) bytes of data from the given
+ * pci_device, at pci_config_offset from the beginning of the device's
+ * configuration space.  If there was no error, RET1 is set to zero and
+ * RET2 is set to the data read.  Insignificant bits in RET2 are not
+ * guarenteed to have any specific value and therefore must be ignored.
+ *
+ * The data returned in RET2 is size based byte swapped.
+ *
+ * If an error occurs during the read, set RET1 to a non-zero value.  The
+ * given pci_config_offset must be 'size' aligned.
+ */
+#define HV_FAST_PCI_CONFIG_GET         0xb4
+
+/* pci_config_put()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_CONFIG_PUT
+ * ARG0:       devhandle
+ * ARG1:       pci_device
+ * ARG2:       pci_config_offset
+ * ARG3:       size
+ * ARG4:       data
+ * RET0:       status
+ * RET1:       error_flag
+ * ERRORS:     EINVAL          Invalid devhandle/pci_device/offset/size
+ *             EBADALIGN       pci_config_offset not size aligned
+ *             ENOACCESS       Access to this offset is not permitted
+ *
+ * Write PCI configuration space for the adapter described by the given
+ * devhandle.  Write size (1, 2, or 4) bytes of data in a single operation,
+ * at pci_config_offset from the beginning of the device's configuration
+ * space.  The data argument contains the data to be written to configuration
+ * space.  Prior to writing, the data is size based byte swapped.
+ *
+ * If an error occurs during the write access, do not generate an error
+ * report, do set RET1 to a non-zero value.  Otherwise RET1 is zero.
+ * The given pci_config_offset must be 'size' aligned.
+ *
+ * This function is permitted to read from offset zero in the configuration
+ * space described by the given pci_device if necessary to ensure that the
+ * write access to config space completes.
+ */
+#define HV_FAST_PCI_CONFIG_PUT         0xb5
+
+/* pci_peek()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_PEEK
+ * ARG0:       devhandle
+ * ARG1:       real address
+ * ARG2:       size
+ * RET0:       status
+ * RET1:       error_flag
+ * RET2:       data
+ * ERRORS:     EINVAL          Invalid devhandle or size
+ *             EBADALIGN       Improperly aligned real address
+ *             ENORADDR        Bad real address
+ *             ENOACCESS       Guest access prohibited
+ *
+ * Attempt to read the IO address given by the given devhandle, real address,
+ * and size.  Size must be 1, 2, 4, or 8.  The read is performed as a single
+ * access operation using the given size.  If an error occurs when reading
+ * from the given location, do not generate an error report, but return a
+ * non-zero value in RET1.  If the read was successful, return zero in RET1
+ * and return the actual data read in RET2.  The data returned is size based
+ * byte swapped.
+ *
+ * Non-significant bits in RET2 are not guarenteed to have any specific value
+ * and therefore must be ignored.  If RET1 is returned as non-zero, the data
+ * value is not guarenteed to have any specific value and should be ignored.
+ *
+ * The caller must have permission to read from the given devhandle, real
+ * address, which must be an IO address.  The argument real address must be a
+ * size aligned address.
+ *
+ * The hypervisor implementation of this function must block access to any
+ * IO address that the guest does not have explicit permission to access.
+ */
+#define HV_FAST_PCI_PEEK               0xb6
+
+/* pci_poke()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_POKE
+ * ARG0:       devhandle
+ * ARG1:       real address
+ * ARG2:       size
+ * ARG3:       data
+ * ARG4:       pci_device
+ * RET0:       status
+ * RET1:       error_flag
+ * ERRORS:     EINVAL          Invalid devhandle, size, or pci_device
+ *             EBADALIGN       Improperly aligned real address
+ *             ENORADDR        Bad real address
+ *             ENOACCESS       Guest access prohibited
+ *             ENOTSUPPORTED   Function is not supported by implementation
+ *
+ * Attempt to write data to the IO address given by the given devhandle,
+ * real address, and size.  Size must be 1, 2, 4, or 8.  The write is
+ * performed as a single access operation using the given size. Prior to
+ * writing the data is size based swapped.
+ *
+ * If an error occurs when writing to the given location, do not generate an
+ * error report, but return a non-zero value in RET1.  If the write was
+ * successful, return zero in RET1.
+ *
+ * pci_device describes the configuration address of the device being
+ * written to.  The implementation may safely read from offset 0 with
+ * the configuration space of the device described by devhandle and
+ * pci_device in order to guarantee that the write portion of the operation
+ * completes
+ *
+ * Any error that occurs due to the read shall be reported using the normal
+ * error reporting mechanisms .. the read error is not suppressed.
+ *
+ * The caller must have permission to write to the given devhandle, real
+ * address, which must be an IO address.  The argument real address must be a
+ * size aligned address.  The caller must have permission to read from
+ * the given devhandle, pci_device cofiguration space offset 0.
+ *
+ * The hypervisor implementation of this function must block access to any
+ * IO address that the guest does not have explicit permission to access.
+ */
+#define HV_FAST_PCI_POKE               0xb7
+
+/* pci_dma_sync()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_DMA_SYNC
+ * ARG0:       devhandle
+ * ARG1:       real address
+ * ARG2:       size
+ * ARG3:       io_sync_direction
+ * RET0:       status
+ * RET1:       #synced
+ * ERRORS:     EINVAL          Invalid devhandle or io_sync_direction
+ *             ENORADDR        Bad real address
+ *
+ * Synchronize a memory region described by the given real address and size,
+ * for the device defined by the given devhandle using the direction(s)
+ * defined by the given io_sync_direction.  The argument size is the size of
+ * the memory region in bytes.
+ *
+ * Return the actual number of bytes synchronized in the return value #synced,
+ * which may be less than or equal to the argument size.  If the return
+ * value #synced is less than size, the caller must continue to call this
+ * function with updated real address and size arguments until the entire
+ * memory region is synchronized.
+ */
+#define HV_FAST_PCI_DMA_SYNC           0xb8
+
+/* PCI MSI services.  */
+
+#define HV_MSITYPE_MSI32               0x00
+#define HV_MSITYPE_MSI64               0x01
+
+#define HV_MSIQSTATE_IDLE              0x00
+#define HV_MSIQSTATE_ERROR             0x01
+
+#define HV_MSIQ_INVALID                        0x00
+#define HV_MSIQ_VALID                  0x01
+
+#define HV_MSISTATE_IDLE               0x00
+#define HV_MSISTATE_DELIVERED          0x01
+
+#define HV_MSIVALID_INVALID            0x00
+#define HV_MSIVALID_VALID              0x01
+
+#define HV_PCIE_MSGTYPE_PME_MSG                0x18
+#define HV_PCIE_MSGTYPE_PME_ACK_MSG    0x1b
+#define HV_PCIE_MSGTYPE_CORR_MSG       0x30
+#define HV_PCIE_MSGTYPE_NONFATAL_MSG   0x31
+#define HV_PCIE_MSGTYPE_FATAL_MSG      0x33
+
+#define HV_MSG_INVALID                 0x00
+#define HV_MSG_VALID                   0x01
+
+/* pci_msiq_conf()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSIQ_CONF
+ * ARG0:       devhandle
+ * ARG1:       msiqid
+ * ARG2:       real address
+ * ARG3:       number of entries
+ * RET0:       status
+ * ERRORS:     EINVAL          Invalid devhandle, msiqid or nentries
+ *             EBADALIGN       Improperly aligned real address
+ *             ENORADDR        Bad real address
+ *
+ * Configure the MSI queue given by the devhandle and msiqid arguments,
+ * and to be placed at the given real address and be of the given
+ * number of entries.  The real address must be aligned exactly to match
+ * the queue size.  Each queue entry is 64-bytes long, so f.e. a 32 entry
+ * queue must be aligned on a 2048 byte real address boundary.  The MSI-EQ
+ * Head and Tail are initialized so that the MSI-EQ is 'empty'.
+ *
+ * Implementation Note: Certain implementations have fixed sized queues.  In
+ *                      that case, number of entries must contain the correct
+ *                      value.
+ */
+#define HV_FAST_PCI_MSIQ_CONF          0xc0
+
+/* pci_msiq_info()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSIQ_INFO
+ * ARG0:       devhandle
+ * ARG1:       msiqid
+ * RET0:       status
+ * RET1:       real address
+ * RET2:       number of entries
+ * ERRORS:     EINVAL          Invalid devhandle or msiqid
+ *
+ * Return the configuration information for the MSI queue described
+ * by the given devhandle and msiqid.  The base address of the queue
+ * is returned in ARG1 and the number of entries is returned in ARG2.
+ * If the queue is unconfigured, the real address is undefined and the
+ * number of entries will be returned as zero.
+ */
+#define HV_FAST_PCI_MSIQ_INFO          0xc1
+
+/* pci_msiq_getvalid()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSIQ_GETVALID
+ * ARG0:       devhandle
+ * ARG1:       msiqid
+ * RET0:       status
+ * RET1:       msiqvalid       (HV_MSIQ_VALID or HV_MSIQ_INVALID)
+ * ERRORS:     EINVAL          Invalid devhandle or msiqid
+ *
+ * Get the valid state of the MSI-EQ described by the given devhandle and
+ * msiqid.
+ */
+#define HV_FAST_PCI_MSIQ_GETVALID      0xc2
+
+/* pci_msiq_setvalid()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSIQ_SETVALID
+ * ARG0:       devhandle
+ * ARG1:       msiqid
+ * ARG2:       msiqvalid       (HV_MSIQ_VALID or HV_MSIQ_INVALID)
+ * RET0:       status
+ * ERRORS:     EINVAL          Invalid devhandle or msiqid or msiqvalid
+ *                             value or MSI EQ is uninitialized
+ *
+ * Set the valid state of the MSI-EQ described by the given devhandle and
+ * msiqid to the given msiqvalid.
+ */
+#define HV_FAST_PCI_MSIQ_SETVALID      0xc3
+
+/* pci_msiq_getstate()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSIQ_GETSTATE
+ * ARG0:       devhandle
+ * ARG1:       msiqid
+ * RET0:       status
+ * RET1:       msiqstate       (HV_MSIQSTATE_IDLE or HV_MSIQSTATE_ERROR)
+ * ERRORS:     EINVAL          Invalid devhandle or msiqid
+ *
+ * Get the state of the MSI-EQ described by the given devhandle and
+ * msiqid.
+ */
+#define HV_FAST_PCI_MSIQ_GETSTATE      0xc4
+
+/* pci_msiq_getvalid()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSIQ_GETVALID
+ * ARG0:       devhandle
+ * ARG1:       msiqid
+ * ARG2:       msiqstate       (HV_MSIQSTATE_IDLE or HV_MSIQSTATE_ERROR)
+ * RET0:       status
+ * ERRORS:     EINVAL          Invalid devhandle or msiqid or msiqstate
+ *                             value or MSI EQ is uninitialized
+ *
+ * Set the state of the MSI-EQ described by the given devhandle and
+ * msiqid to the given msiqvalid.
+ */
+#define HV_FAST_PCI_MSIQ_SETSTATE      0xc5
+
+/* pci_msiq_gethead()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSIQ_GETHEAD
+ * ARG0:       devhandle
+ * ARG1:       msiqid
+ * RET0:       status
+ * RET1:       msiqhead
+ * ERRORS:     EINVAL          Invalid devhandle or msiqid
+ *
+ * Get the current MSI EQ queue head for the MSI-EQ described by the
+ * given devhandle and msiqid.
+ */
+#define HV_FAST_PCI_MSIQ_GETHEAD       0xc6
+
+/* pci_msiq_sethead()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSIQ_SETHEAD
+ * ARG0:       devhandle
+ * ARG1:       msiqid
+ * ARG2:       msiqhead
+ * RET0:       status
+ * ERRORS:     EINVAL          Invalid devhandle or msiqid or msiqhead,
+ *                             or MSI EQ is uninitialized
+ *
+ * Set the current MSI EQ queue head for the MSI-EQ described by the
+ * given devhandle and msiqid.
+ */
+#define HV_FAST_PCI_MSIQ_SETHEAD       0xc7
+
+/* pci_msiq_gettail()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSIQ_GETTAIL
+ * ARG0:       devhandle
+ * ARG1:       msiqid
+ * RET0:       status
+ * RET1:       msiqtail
+ * ERRORS:     EINVAL          Invalid devhandle or msiqid
+ *
+ * Get the current MSI EQ queue tail for the MSI-EQ described by the
+ * given devhandle and msiqid.
+ */
+#define HV_FAST_PCI_MSIQ_GETTAIL       0xc8
+
+/* pci_msi_getvalid()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSI_GETVALID
+ * ARG0:       devhandle
+ * ARG1:       msinum
+ * RET0:       status
+ * RET1:       msivalidstate
+ * ERRORS:     EINVAL          Invalid devhandle or msinum
+ *
+ * Get the current valid/enabled state for the MSI defined by the
+ * given devhandle and msinum.
+ */
+#define HV_FAST_PCI_MSI_GETVALID       0xc9
+
+/* pci_msi_setvalid()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSI_SETVALID
+ * ARG0:       devhandle
+ * ARG1:       msinum
+ * ARG2:       msivalidstate
+ * RET0:       status
+ * ERRORS:     EINVAL          Invalid devhandle or msinum or msivalidstate
+ *
+ * Set the current valid/enabled state for the MSI defined by the
+ * given devhandle and msinum.
+ */
+#define HV_FAST_PCI_MSI_SETVALID       0xca
+
+/* pci_msi_getmsiq()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSI_GETMSIQ
+ * ARG0:       devhandle
+ * ARG1:       msinum
+ * RET0:       status
+ * RET1:       msiqid
+ * ERRORS:     EINVAL          Invalid devhandle or msinum or MSI is unbound
+ *
+ * Get the MSI EQ that the MSI defined by the given devhandle and
+ * msinum is bound to.
+ */
+#define HV_FAST_PCI_MSI_GETMSIQ                0xcb
+
+/* pci_msi_setmsiq()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSI_SETMSIQ
+ * ARG0:       devhandle
+ * ARG1:       msinum
+ * ARG2:       msitype
+ * ARG3:       msiqid
+ * RET0:       status
+ * ERRORS:     EINVAL          Invalid devhandle or msinum or msiqid
+ *
+ * Set the MSI EQ that the MSI defined by the given devhandle and
+ * msinum is bound to.
+ */
+#define HV_FAST_PCI_MSI_SETMSIQ                0xcc
+
+/* pci_msi_getstate()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSI_GETSTATE
+ * ARG0:       devhandle
+ * ARG1:       msinum
+ * RET0:       status
+ * RET1:       msistate
+ * ERRORS:     EINVAL          Invalid devhandle or msinum
+ *
+ * Get the state of the MSI defined by the given devhandle and msinum.
+ * If not initialized, return HV_MSISTATE_IDLE.
+ */
+#define HV_FAST_PCI_MSI_GETSTATE       0xcd
+
+/* pci_msi_setstate()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSI_SETSTATE
+ * ARG0:       devhandle
+ * ARG1:       msinum
+ * ARG2:       msistate
+ * RET0:       status
+ * ERRORS:     EINVAL          Invalid devhandle or msinum or msistate
+ *
+ * Set the state of the MSI defined by the given devhandle and msinum.
+ */
+#define HV_FAST_PCI_MSI_SETSTATE       0xce
+
+/* pci_msg_getmsiq()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSG_GETMSIQ
+ * ARG0:       devhandle
+ * ARG1:       msgtype
+ * RET0:       status
+ * RET1:       msiqid
+ * ERRORS:     EINVAL          Invalid devhandle or msgtype
+ *
+ * Get the MSI EQ of the MSG defined by the given devhandle and msgtype.
+ */
+#define HV_FAST_PCI_MSG_GETMSIQ                0xd0
+
+/* pci_msg_setmsiq()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSG_SETMSIQ
+ * ARG0:       devhandle
+ * ARG1:       msgtype
+ * ARG2:       msiqid
+ * RET0:       status
+ * ERRORS:     EINVAL          Invalid devhandle, msgtype, or msiqid
+ *
+ * Set the MSI EQ of the MSG defined by the given devhandle and msgtype.
+ */
+#define HV_FAST_PCI_MSG_SETMSIQ                0xd1
+
+/* pci_msg_getvalid()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSG_GETVALID
+ * ARG0:       devhandle
+ * ARG1:       msgtype
+ * RET0:       status
+ * RET1:       msgvalidstate
+ * ERRORS:     EINVAL          Invalid devhandle or msgtype
+ *
+ * Get the valid/enabled state of the MSG defined by the given
+ * devhandle and msgtype.
+ */
+#define HV_FAST_PCI_MSG_GETVALID       0xd2
+
+/* pci_msg_setvalid()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_PCI_MSG_SETVALID
+ * ARG0:       devhandle
+ * ARG1:       msgtype
+ * ARG2:       msgvalidstate
+ * RET0:       status
+ * ERRORS:     EINVAL          Invalid devhandle or msgtype or msgvalidstate
+ *
+ * Set the valid/enabled state of the MSG defined by the given
+ * devhandle and msgtype.
+ */
+#define HV_FAST_PCI_MSG_SETVALID       0xd3
+
+/* Logical Domain Channel services.  */
+
+#define LDC_CHANNEL_DOWN               0
+#define LDC_CHANNEL_UP                 1
+#define LDC_CHANNEL_RESETTING          2
+
+/* ldc_tx_qconf()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_TX_QCONF
+ * ARG0:       channel ID
+ * ARG1:       real address base of queue
+ * ARG2:       num entries in queue
+ * RET0:       status
+ *
+ * Configure transmit queue for the LDC endpoint specified by the
+ * given channel ID, to be placed at the given real address, and
+ * be of the given num entries.  Num entries must be a power of two.
+ * The real address base of the queue must be aligned on the queue
+ * size.  Each queue entry is 64-bytes, so for example, a 32 entry
+ * queue must be aligned on a 2048 byte real address boundary.
+ *
+ * Upon configuration of a valid transmit queue the head and tail
+ * pointers are set to a hypervisor specific identical value indicating
+ * that the queue initially is empty.
+ *
+ * The endpoint's transmit queue is un-configured if num entries is zero.
+ *
+ * The maximum number of entries for each queue for a specific cpu may be
+ * determined from the machine description.  A transmit queue may be
+ * specified even in the event that the LDC is down (peer endpoint has no
+ * receive queue specified).  Transmission will begin as soon as the peer
+ * endpoint defines a receive queue.
+ *
+ * It is recommended that a guest wait for a transmit queue to empty prior
+ * to reconfiguring it, or un-configuring it.  Re or un-configuring of a
+ * non-empty transmit queue behaves exactly as defined above, however it
+ * is undefined as to how many of the pending entries in the original queue
+ * will be delivered prior to the re-configuration taking effect.
+ * Furthermore, as the queue configuration causes a reset of the head and
+ * tail pointers there is no way for a guest to determine how many entries
+ * have been sent after the configuration operation.
+ */
+#define HV_FAST_LDC_TX_QCONF           0xe0
+
+/* ldc_tx_qinfo()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_TX_QINFO
+ * ARG0:       channel ID
+ * RET0:       status
+ * RET1:       real address base of queue
+ * RET2:       num entries in queue
+ *
+ * Return the configuration info for the transmit queue of LDC endpoint
+ * defined by the given channel ID.  The real address is the currently
+ * defined real address base of the defined queue, and num entries is the
+ * size of the queue in terms of number of entries.
+ *
+ * If the specified channel ID is a valid endpoint number, but no transmit
+ * queue has been defined this service will return success, but with num
+ * entries set to zero and the real address will have an undefined value.
+ */
+#define HV_FAST_LDC_TX_QINFO           0xe1
+
+/* ldc_tx_get_state()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_TX_GET_STATE
+ * ARG0:       channel ID
+ * RET0:       status
+ * RET1:       head offset
+ * RET2:       tail offset
+ * RET3:       channel state
+ *
+ * Return the transmit state, and the head and tail queue pointers, for
+ * the transmit queue of the LDC endpoint defined by the given channel ID.
+ * The head and tail values are the byte offset of the head and tail
+ * positions of the transmit queue for the specified endpoint.
+ */
+#define HV_FAST_LDC_TX_GET_STATE       0xe2
+
+/* ldc_tx_set_qtail()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_TX_SET_QTAIL
+ * ARG0:       channel ID
+ * ARG1:       tail offset
+ * RET0:       status
+ *
+ * Update the tail pointer for the transmit queue associated with the LDC
+ * endpoint defined by the given channel ID.  The tail offset specified
+ * must be aligned on a 64 byte boundary, and calculated so as to increase
+ * the number of pending entries on the transmit queue.  Any attempt to
+ * decrease the number of pending transmit queue entires is considered
+ * an invalid tail offset and will result in an EINVAL error.
+ *
+ * Since the tail of the transmit queue may not be moved backwards, the
+ * transmit queue may be flushed by configuring a new transmit queue,
+ * whereupon the hypervisor will configure the initial transmit head and
+ * tail pointers to be equal.
+ */
+#define HV_FAST_LDC_TX_SET_QTAIL       0xe3
+
+/* ldc_rx_qconf()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_RX_QCONF
+ * ARG0:       channel ID
+ * ARG1:       real address base of queue
+ * ARG2:       num entries in queue
+ * RET0:       status
+ *
+ * Configure receive queue for the LDC endpoint specified by the
+ * given channel ID, to be placed at the given real address, and
+ * be of the given num entries.  Num entries must be a power of two.
+ * The real address base of the queue must be aligned on the queue
+ * size.  Each queue entry is 64-bytes, so for example, a 32 entry
+ * queue must be aligned on a 2048 byte real address boundary.
+ *
+ * The endpoint's transmit queue is un-configured if num entries is zero.
+ *
+ * If a valid receive queue is specified for a local endpoint the LDC is
+ * in the up state for the purpose of transmission to this endpoint.
+ *
+ * The maximum number of entries for each queue for a specific cpu may be
+ * determined from the machine description.
+ *
+ * As receive queue configuration causes a reset of the queue's head and
+ * tail pointers there is no way for a gues to determine how many entries
+ * have been received between a preceeding ldc_get_rx_state() API call
+ * and the completion of the configuration operation.  It should be noted
+ * that datagram delivery is not guarenteed via domain channels anyway,
+ * and therefore any higher protocol should be resilient to datagram
+ * loss if necessary.  However, to overcome this specific race potential
+ * it is recommended, for example, that a higher level protocol be employed
+ * to ensure either retransmission, or ensure that no datagrams are pending
+ * on the peer endpoint's transmit queue prior to the configuration process.
+ */
+#define HV_FAST_LDC_RX_QCONF           0xe4
+
+/* ldc_rx_qinfo()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_RX_QINFO
+ * ARG0:       channel ID
+ * RET0:       status
+ * RET1:       real address base of queue
+ * RET2:       num entries in queue
+ *
+ * Return the configuration info for the receive queue of LDC endpoint
+ * defined by the given channel ID.  The real address is the currently
+ * defined real address base of the defined queue, and num entries is the
+ * size of the queue in terms of number of entries.
+ *
+ * If the specified channel ID is a valid endpoint number, but no receive
+ * queue has been defined this service will return success, but with num
+ * entries set to zero and the real address will have an undefined value.
+ */
+#define HV_FAST_LDC_RX_QINFO           0xe5
+
+/* ldc_rx_get_state()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_RX_GET_STATE
+ * ARG0:       channel ID
+ * RET0:       status
+ * RET1:       head offset
+ * RET2:       tail offset
+ * RET3:       channel state
+ *
+ * Return the receive state, and the head and tail queue pointers, for
+ * the receive queue of the LDC endpoint defined by the given channel ID.
+ * The head and tail values are the byte offset of the head and tail
+ * positions of the receive queue for the specified endpoint.
+ */
+#define HV_FAST_LDC_RX_GET_STATE       0xe6
+
+/* ldc_rx_set_qhead()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_RX_SET_QHEAD
+ * ARG0:       channel ID
+ * ARG1:       head offset
+ * RET0:       status
+ *
+ * Update the head pointer for the receive queue associated with the LDC
+ * endpoint defined by the given channel ID.  The head offset specified
+ * must be aligned on a 64 byte boundary, and calculated so as to decrease
+ * the number of pending entries on the receive queue.  Any attempt to
+ * increase the number of pending receive queue entires is considered
+ * an invalid head offset and will result in an EINVAL error.
+ *
+ * The receive queue may be flushed by setting the head offset equal
+ * to the current tail offset.
+ */
+#define HV_FAST_LDC_RX_SET_QHEAD       0xe7
+
+/* LDC Map Table Entry.  Each slot is defined by a translation table
+ * entry, as specified by the LDC_MTE_* bits below, and a 64-bit
+ * hypervisor invalidation cookie.
+ */
+#define LDC_MTE_PADDR  0x0fffffffffffe000 /* pa[55:13]          */
+#define LDC_MTE_COPY_W 0x0000000000000400 /* copy write access  */
+#define LDC_MTE_COPY_R 0x0000000000000200 /* copy read access   */
+#define LDC_MTE_IOMMU_W        0x0000000000000100 /* IOMMU write access */
+#define LDC_MTE_IOMMU_R        0x0000000000000080 /* IOMMU read access  */
+#define LDC_MTE_EXEC   0x0000000000000040 /* execute            */
+#define LDC_MTE_WRITE  0x0000000000000020 /* read               */
+#define LDC_MTE_READ   0x0000000000000010 /* write              */
+#define LDC_MTE_SZALL  0x000000000000000f /* page size bits     */
+#define LDC_MTE_SZ16GB 0x0000000000000007 /* 16GB page          */
+#define LDC_MTE_SZ2GB  0x0000000000000006 /* 2GB page           */
+#define LDC_MTE_SZ256MB        0x0000000000000005 /* 256MB page         */
+#define LDC_MTE_SZ32MB 0x0000000000000004 /* 32MB page          */
+#define LDC_MTE_SZ4MB  0x0000000000000003 /* 4MB page           */
+#define LDC_MTE_SZ512K 0x0000000000000002 /* 512K page          */
+#define LDC_MTE_SZ64K  0x0000000000000001 /* 64K page           */
+#define LDC_MTE_SZ8K   0x0000000000000000 /* 8K page            */
+
+#ifndef __ASSEMBLY__
+struct ldc_mtable_entry {
+       unsigned long   mte;
+       unsigned long   cookie;
+};
+#endif
+
+/* ldc_set_map_table()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_SET_MAP_TABLE
+ * ARG0:       channel ID
+ * ARG1:       table real address
+ * ARG2:       num entries
+ * RET0:       status
+ *
+ * Register the MTE table at the given table real address, with the
+ * specified num entries, for the LDC indicated by the given channel
+ * ID.
+ */
+#define HV_FAST_LDC_SET_MAP_TABLE      0xea
+
+/* ldc_get_map_table()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_GET_MAP_TABLE
+ * ARG0:       channel ID
+ * RET0:       status
+ * RET1:       table real address
+ * RET2:       num entries
+ *
+ * Return the configuration of the current mapping table registered
+ * for the given channel ID.
+ */
+#define HV_FAST_LDC_GET_MAP_TABLE      0xeb
+
+#define LDC_COPY_IN    0
+#define LDC_COPY_OUT   1
+
+/* ldc_copy()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_COPY
+ * ARG0:       channel ID
+ * ARG1:       LDC_COPY_* direction code
+ * ARG2:       target real address
+ * ARG3:       local real address
+ * ARG4:       length in bytes
+ * RET0:       status
+ * RET1:       actual length in bytes
+ */
+#define HV_FAST_LDC_COPY               0xec
+
+#define LDC_MEM_READ   1
+#define LDC_MEM_WRITE  2
+#define LDC_MEM_EXEC   4
+
+/* ldc_mapin()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_MAPIN
+ * ARG0:       channel ID
+ * ARG1:       cookie
+ * RET0:       status
+ * RET1:       real address
+ * RET2:       LDC_MEM_* permissions
+ */
+#define HV_FAST_LDC_MAPIN              0xed
+
+/* ldc_unmap()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_UNMAP
+ * ARG0:       real address
+ * RET0:       status
+ */
+#define HV_FAST_LDC_UNMAP              0xee
+
+/* ldc_revoke()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_LDC_REVOKE
+ * ARG0:       channel ID
+ * ARG1:       cookie
+ * ARG2:       ldc_mtable_entry cookie
+ * RET0:       status
+ */
+#define HV_FAST_LDC_REVOKE             0xef
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_ldc_tx_qconf(unsigned long channel,
+                                       unsigned long ra,
+                                       unsigned long num_entries);
+extern unsigned long sun4v_ldc_tx_qinfo(unsigned long channel,
+                                       unsigned long *ra,
+                                       unsigned long *num_entries);
+extern unsigned long sun4v_ldc_tx_get_state(unsigned long channel,
+                                           unsigned long *head_off,
+                                           unsigned long *tail_off,
+                                           unsigned long *chan_state);
+extern unsigned long sun4v_ldc_tx_set_qtail(unsigned long channel,
+                                           unsigned long tail_off);
+extern unsigned long sun4v_ldc_rx_qconf(unsigned long channel,
+                                       unsigned long ra,
+                                       unsigned long num_entries);
+extern unsigned long sun4v_ldc_rx_qinfo(unsigned long channel,
+                                       unsigned long *ra,
+                                       unsigned long *num_entries);
+extern unsigned long sun4v_ldc_rx_get_state(unsigned long channel,
+                                           unsigned long *head_off,
+                                           unsigned long *tail_off,
+                                           unsigned long *chan_state);
+extern unsigned long sun4v_ldc_rx_set_qhead(unsigned long channel,
+                                           unsigned long head_off);
+extern unsigned long sun4v_ldc_set_map_table(unsigned long channel,
+                                            unsigned long ra,
+                                            unsigned long num_entries);
+extern unsigned long sun4v_ldc_get_map_table(unsigned long channel,
+                                            unsigned long *ra,
+                                            unsigned long *num_entries);
+extern unsigned long sun4v_ldc_copy(unsigned long channel,
+                                   unsigned long dir_code,
+                                   unsigned long tgt_raddr,
+                                   unsigned long lcl_raddr,
+                                   unsigned long len,
+                                   unsigned long *actual_len);
+extern unsigned long sun4v_ldc_mapin(unsigned long channel,
+                                    unsigned long cookie,
+                                    unsigned long *ra,
+                                    unsigned long *perm);
+extern unsigned long sun4v_ldc_unmap(unsigned long ra);
+extern unsigned long sun4v_ldc_revoke(unsigned long channel,
+                                     unsigned long cookie,
+                                     unsigned long mte_cookie);
+#endif
+
+/* Performance counter services.  */
+
+#define HV_PERF_JBUS_PERF_CTRL_REG     0x00
+#define HV_PERF_JBUS_PERF_CNT_REG      0x01
+#define HV_PERF_DRAM_PERF_CTRL_REG_0   0x02
+#define HV_PERF_DRAM_PERF_CNT_REG_0    0x03
+#define HV_PERF_DRAM_PERF_CTRL_REG_1   0x04
+#define HV_PERF_DRAM_PERF_CNT_REG_1    0x05
+#define HV_PERF_DRAM_PERF_CTRL_REG_2   0x06
+#define HV_PERF_DRAM_PERF_CNT_REG_2    0x07
+#define HV_PERF_DRAM_PERF_CTRL_REG_3   0x08
+#define HV_PERF_DRAM_PERF_CNT_REG_3    0x09
+
+/* get_perfreg()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_GET_PERFREG
+ * ARG0:       performance reg number
+ * RET0:       status
+ * RET1:       performance reg value
+ * ERRORS:     EINVAL          Invalid performance register number
+ *             ENOACCESS       No access allowed to performance counters
+ *
+ * Read the value of the given DRAM/JBUS performance counter/control register.
+ */
+#define HV_FAST_GET_PERFREG            0x100
+
+/* set_perfreg()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_SET_PERFREG
+ * ARG0:       performance reg number
+ * ARG1:       performance reg value
+ * RET0:       status
+ * ERRORS:     EINVAL          Invalid performance register number
+ *             ENOACCESS       No access allowed to performance counters
+ *
+ * Write the given performance reg value to the given DRAM/JBUS
+ * performance counter/control register.
+ */
+#define HV_FAST_SET_PERFREG            0x101
+
+/* MMU statistics services.
+ *
+ * The hypervisor maintains MMU statistics and privileged code provides
+ * a buffer where these statistics can be collected.  It is continually
+ * updated once configured.  The layout is as follows:
+ */
+#ifndef __ASSEMBLY__
+struct hv_mmu_statistics {
+       unsigned long immu_tsb_hits_ctx0_8k_tte;
+       unsigned long immu_tsb_ticks_ctx0_8k_tte;
+       unsigned long immu_tsb_hits_ctx0_64k_tte;
+       unsigned long immu_tsb_ticks_ctx0_64k_tte;
+       unsigned long __reserved1[2];
+       unsigned long immu_tsb_hits_ctx0_4mb_tte;
+       unsigned long immu_tsb_ticks_ctx0_4mb_tte;
+       unsigned long __reserved2[2];
+       unsigned long immu_tsb_hits_ctx0_256mb_tte;
+       unsigned long immu_tsb_ticks_ctx0_256mb_tte;
+       unsigned long __reserved3[4];
+       unsigned long immu_tsb_hits_ctxnon0_8k_tte;
+       unsigned long immu_tsb_ticks_ctxnon0_8k_tte;
+       unsigned long immu_tsb_hits_ctxnon0_64k_tte;
+       unsigned long immu_tsb_ticks_ctxnon0_64k_tte;
+       unsigned long __reserved4[2];
+       unsigned long immu_tsb_hits_ctxnon0_4mb_tte;
+       unsigned long immu_tsb_ticks_ctxnon0_4mb_tte;
+       unsigned long __reserved5[2];
+       unsigned long immu_tsb_hits_ctxnon0_256mb_tte;
+       unsigned long immu_tsb_ticks_ctxnon0_256mb_tte;
+       unsigned long __reserved6[4];
+       unsigned long dmmu_tsb_hits_ctx0_8k_tte;
+       unsigned long dmmu_tsb_ticks_ctx0_8k_tte;
+       unsigned long dmmu_tsb_hits_ctx0_64k_tte;
+       unsigned long dmmu_tsb_ticks_ctx0_64k_tte;
+       unsigned long __reserved7[2];
+       unsigned long dmmu_tsb_hits_ctx0_4mb_tte;
+       unsigned long dmmu_tsb_ticks_ctx0_4mb_tte;
+       unsigned long __reserved8[2];
+       unsigned long dmmu_tsb_hits_ctx0_256mb_tte;
+       unsigned long dmmu_tsb_ticks_ctx0_256mb_tte;
+       unsigned long __reserved9[4];
+       unsigned long dmmu_tsb_hits_ctxnon0_8k_tte;
+       unsigned long dmmu_tsb_ticks_ctxnon0_8k_tte;
+       unsigned long dmmu_tsb_hits_ctxnon0_64k_tte;
+       unsigned long dmmu_tsb_ticks_ctxnon0_64k_tte;
+       unsigned long __reserved10[2];
+       unsigned long dmmu_tsb_hits_ctxnon0_4mb_tte;
+       unsigned long dmmu_tsb_ticks_ctxnon0_4mb_tte;
+       unsigned long __reserved11[2];
+       unsigned long dmmu_tsb_hits_ctxnon0_256mb_tte;
+       unsigned long dmmu_tsb_ticks_ctxnon0_256mb_tte;
+       unsigned long __reserved12[4];
+};
+#endif
+
+/* mmustat_conf()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMUSTAT_CONF
+ * ARG0:       real address
+ * RET0:       status
+ * RET1:       real address
+ * ERRORS:     ENORADDR        Invalid real address
+ *             EBADALIGN       Real address not aligned on 64-byte boundary
+ *             EBADTRAP        API not supported on this processor
+ *
+ * Enable MMU statistic gathering using the buffer at the given real
+ * address on the current virtual CPU.  The new buffer real address
+ * is given in ARG1, and the previously specified buffer real address
+ * is returned in RET1, or is returned as zero for the first invocation.
+ *
+ * If the passed in real address argument is zero, this will disable
+ * MMU statistic collection on the current virtual CPU.  If an error is
+ * returned then no statistics are collected.
+ *
+ * The buffer contents should be initialized to all zeros before being
+ * given to the hypervisor or else the statistics will be meaningless.
+ */
+#define HV_FAST_MMUSTAT_CONF           0x102
+
+/* mmustat_info()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_MMUSTAT_INFO
+ * RET0:       status
+ * RET1:       real address
+ * ERRORS:     EBADTRAP        API not supported on this processor
+ *
+ * Return the current state and real address of the currently configured
+ * MMU statistics buffer on the current virtual CPU.
+ */
+#define HV_FAST_MMUSTAT_INFO           0x103
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mmustat_conf(unsigned long ra, unsigned long *orig_ra);
+extern unsigned long sun4v_mmustat_info(unsigned long *ra);
+#endif
+
+/* NCS crypto services  */
+
+/* ncs_request() sub-function numbers */
+#define HV_NCS_QCONF                   0x01
+#define HV_NCS_QTAIL_UPDATE            0x02
+
+#ifndef __ASSEMBLY__
+struct hv_ncs_queue_entry {
+       /* MAU Control Register */
+       unsigned long   mau_control;
+#define MAU_CONTROL_INV_PARITY 0x0000000000002000
+#define MAU_CONTROL_STRAND     0x0000000000001800
+#define MAU_CONTROL_BUSY       0x0000000000000400
+#define MAU_CONTROL_INT                0x0000000000000200
+#define MAU_CONTROL_OP         0x00000000000001c0
+#define MAU_CONTROL_OP_SHIFT   6
+#define MAU_OP_LOAD_MA_MEMORY  0x0
+#define MAU_OP_STORE_MA_MEMORY 0x1
+#define MAU_OP_MODULAR_MULT    0x2
+#define MAU_OP_MODULAR_REDUCE  0x3
+#define MAU_OP_MODULAR_EXP_LOOP        0x4
+#define MAU_CONTROL_LEN                0x000000000000003f
+#define MAU_CONTROL_LEN_SHIFT  0
+
+       /* Real address of bytes to load or store bytes
+        * into/out-of the MAU.
+        */
+       unsigned long   mau_mpa;
+
+       /* Modular Arithmetic MA Offset Register.  */
+       unsigned long   mau_ma;
+
+       /* Modular Arithmetic N Prime Register.  */
+       unsigned long   mau_np;
+};
+
+struct hv_ncs_qconf_arg {
+       unsigned long   mid;      /* MAU ID, 1 per core on Niagara */
+       unsigned long   base;     /* Real address base of queue */
+       unsigned long   end;      /* Real address end of queue */
+       unsigned long   num_ents; /* Number of entries in queue */
+};
+
+struct hv_ncs_qtail_update_arg {
+       unsigned long   mid;      /* MAU ID, 1 per core on Niagara */
+       unsigned long   tail;     /* New tail index to use */
+       unsigned long   syncflag; /* only SYNCFLAG_SYNC is implemented */
+#define HV_NCS_SYNCFLAG_SYNC   0x00
+#define HV_NCS_SYNCFLAG_ASYNC  0x01
+};
+#endif
+
+/* ncs_request()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_FAST_NCS_REQUEST
+ * ARG0:       NCS sub-function
+ * ARG1:       sub-function argument real address
+ * ARG2:       size in bytes of sub-function argument
+ * RET0:       status
+ *
+ * The MAU chip of the Niagara processor is not directly accessible
+ * to privileged code, instead it is programmed indirectly via this
+ * hypervisor API.
+ *
+ * The interfaces defines a queue of MAU operations to perform.
+ * Privileged code registers a queue with the hypervisor by invoking
+ * this HVAPI with the HV_NCS_QCONF sub-function, which defines the
+ * base, end, and number of entries of the queue.  Each queue entry
+ * contains a MAU register struct block.
+ *
+ * The privileged code then proceeds to add entries to the queue and
+ * then invoke the HV_NCS_QTAIL_UPDATE sub-function.  Since only
+ * synchronous operations are supported by the current hypervisor,
+ * HV_NCS_QTAIL_UPDATE will run all the pending queue entries to
+ * completion and return HV_EOK, or return an error code.
+ *
+ * The real address of the sub-function argument must be aligned on at
+ * least an 8-byte boundary.
+ *
+ * The tail argument of HV_NCS_QTAIL_UPDATE is an index, not a byte
+ * offset, into the queue and must be less than or equal the 'num_ents'
+ * argument given in the HV_NCS_QCONF call.
+ */
+#define HV_FAST_NCS_REQUEST            0x110
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_ncs_request(unsigned long request,
+                                      unsigned long arg_ra,
+                                      unsigned long arg_size);
+#endif
+
+#define HV_FAST_FIRE_GET_PERFREG       0x120
+#define HV_FAST_FIRE_SET_PERFREG       0x121
+
+/* Function numbers for HV_CORE_TRAP.  */
+#define HV_CORE_SET_VER                        0x00
+#define HV_CORE_PUTCHAR                        0x01
+#define HV_CORE_EXIT                   0x02
+#define HV_CORE_GET_VER                        0x03
+
+/* Hypervisor API groups for use with HV_CORE_SET_VER and
+ * HV_CORE_GET_VER.
+ */
+#define HV_GRP_SUN4V                   0x0000
+#define HV_GRP_CORE                    0x0001
+#define HV_GRP_INTR                    0x0002
+#define HV_GRP_SOFT_STATE              0x0003
+#define HV_GRP_PCI                     0x0100
+#define HV_GRP_LDOM                    0x0101
+#define HV_GRP_SVC_CHAN                        0x0102
+#define HV_GRP_NCS                     0x0103
+#define HV_GRP_RNG                     0x0104
+#define HV_GRP_NIAG_PERF               0x0200
+#define HV_GRP_FIRE_PERF               0x0201
+#define HV_GRP_N2_CPU                  0x0202
+#define HV_GRP_NIU                     0x0204
+#define HV_GRP_VF_CPU                  0x0205
+#define HV_GRP_DIAG                    0x0300
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_get_version(unsigned long group,
+                                      unsigned long *major,
+                                      unsigned long *minor);
+extern unsigned long sun4v_set_version(unsigned long group,
+                                      unsigned long major,
+                                      unsigned long minor,
+                                      unsigned long *actual_minor);
+
+extern int sun4v_hvapi_register(unsigned long group, unsigned long major,
+                               unsigned long *minor);
+extern void sun4v_hvapi_unregister(unsigned long group);
+extern int sun4v_hvapi_get(unsigned long group,
+                          unsigned long *major,
+                          unsigned long *minor);
+extern void sun4v_hvapi_init(void);
+#endif
+
+#endif /* !(_SPARC64_HYPERVISOR_H) */
index afd1736ed4804d85c0b4099f764d613e4b45a69b..879fcec72dc12e0bdd2726b19b6d77aba1d489b1 100644 (file)
 
 #ifdef __KERNEL__
 
-#include <asm/pgtable.h>
 #include <asm/io.h>
+#ifdef CONFIG_SPARC64
+#include <asm/pgalloc.h>
+#include <asm/spitfire.h>
+#include <asm/cacheflush.h>
+#include <asm/page.h>
+#else
+#include <asm/pgtable.h>
 #include <asm/psr.h>
+#endif
 
 #undef  MAX_HWIFS
 #define MAX_HWIFS      2
 #define __ide_mm_outsw __ide_outsw
 #define __ide_mm_outsl __ide_outsl
 
-static inline void __ide_insw(unsigned long port,
-                                 void *dst,
-                                 unsigned long count)
+static inline void __ide_insw(void __iomem *port, void *dst, u32 count)
 {
-       volatile unsigned short *data_port;
-       /* unsigned long end = (unsigned long)dst + (count << 1); */ /* P3 */
+#if defined(CONFIG_SPARC64) && defined(DCACHE_ALIASING_POSSIBLE)
+       unsigned long end = (unsigned long)dst + (count << 1);
+#endif
        u16 *ps = dst;
        u32 *pi;
 
-       data_port = (volatile unsigned short *)port;
-
        if(((unsigned long)ps) & 0x2) {
-               *ps++ = *data_port;
+               *ps++ = __raw_readw(port);
                count--;
        }
        pi = (u32 *)ps;
        while(count >= 2) {
                u32 w;
 
-               w  = (*data_port) << 16;
-               w |= (*data_port);
+               w  = __raw_readw(port) << 16;
+               w |= __raw_readw(port);
                *pi++ = w;
                count -= 2;
        }
        ps = (u16 *)pi;
        if(count)
-               *ps++ = *data_port;
+               *ps++ = __raw_readw(port);
 
-       /* __flush_dcache_range((unsigned long)dst, end); */ /* P3 see hme */
+#if defined(CONFIG_SPARC64) && defined(DCACHE_ALIASING_POSSIBLE)
+       __flush_dcache_range((unsigned long)dst, end);
+#endif
 }
 
-static inline void __ide_outsw(unsigned long port,
-                                  const void *src,
-                                  unsigned long count)
+static inline void __ide_outsw(void __iomem *port, const void *src, u32 count)
 {
-       volatile unsigned short *data_port;
-       /* unsigned long end = (unsigned long)src + (count << 1); */
+#if defined(CONFIG_SPARC64) && defined(DCACHE_ALIASING_POSSIBLE)
+       unsigned long end = (unsigned long)src + (count << 1);
+#endif
        const u16 *ps = src;
        const u32 *pi;
 
-       data_port = (volatile unsigned short *)port;
-
        if(((unsigned long)src) & 0x2) {
-               *data_port = *ps++;
+               __raw_writew(*ps++, port);
                count--;
        }
        pi = (const u32 *)ps;
@@ -79,15 +82,17 @@ static inline void __ide_outsw(unsigned long port,
                u32 w;
 
                w = *pi++;
-               *data_port = (w >> 16);
-               *data_port = w;
+               __raw_writew((w >> 16), port);
+               __raw_writew(w, port);
                count -= 2;
        }
        ps = (const u16 *)pi;
        if(count)
-               *data_port = *ps;
+               __raw_writew(*ps, port);
 
-       /* __flush_dcache_range((unsigned long)src, end); */ /* P3 see hme */
+#if defined(CONFIG_SPARC64) && defined(DCACHE_ALIASING_POSSIBLE)
+       __flush_dcache_range((unsigned long)src, end);
+#endif
 }
 
 #endif /* __KERNEL__ */
index 41adb417a4e5185f04b782e00a74417cea22ee94..6976aa2439c649c2028d615d0316e828355ec74a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * idprom.h: Macros and defines for idprom routines
  *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
  */
 
 #ifndef _SPARC_IDPROM_H
diff --git a/include/asm-sparc/intr_queue.h b/include/asm-sparc/intr_queue.h
new file mode 100644 (file)
index 0000000..206077d
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef _SPARC64_INTR_QUEUE_H
+#define _SPARC64_INTR_QUEUE_H
+
+/* Sun4v interrupt queue registers, accessed via ASI_QUEUE.  */
+
+#define INTRQ_CPU_MONDO_HEAD     0x3c0 /* CPU mondo head                 */
+#define INTRQ_CPU_MONDO_TAIL     0x3c8 /* CPU mondo tail                 */
+#define INTRQ_DEVICE_MONDO_HEAD          0x3d0 /* Device mondo head              */
+#define INTRQ_DEVICE_MONDO_TAIL          0x3d8 /* Device mondo tail              */
+#define INTRQ_RESUM_MONDO_HEAD   0x3e0 /* Resumable error mondo head     */
+#define INTRQ_RESUM_MONDO_TAIL   0x3e8 /* Resumable error mondo tail     */
+#define INTRQ_NONRESUM_MONDO_HEAD 0x3f0 /* Non-resumable error mondo head */
+#define INTRQ_NONRESUM_MONDO_TAIL 0x3f8 /* Non-resumable error mondo head */
+
+#endif /* !(_SPARC64_INTR_QUEUE_H) */
index 3a3e7bdb06b39ec05a3b113a03415df3dd94f6a8..fc9024d3dfc30f5fdd7990c581abc33e19acc93b 100644 (file)
@@ -1,325 +1,8 @@
-#ifndef __SPARC_IO_H
-#define __SPARC_IO_H
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/ioport.h>  /* struct resource */
-
-#include <asm/page.h>      /* IO address mapping routines need this */
-#include <asm/system.h>
-
-#define page_to_phys(page)     (((page) - mem_map) << PAGE_SHIFT)
-
-static inline u32 flip_dword (u32 l)
-{
-       return ((l&0xff)<<24) | (((l>>8)&0xff)<<16) | (((l>>16)&0xff)<<8)| ((l>>24)&0xff);
-}
-
-static inline u16 flip_word (u16 w)
-{
-       return ((w&0xff) << 8) | ((w>>8)&0xff);
-}
-
-#define mmiowb()
-
-/*
- * Memory mapped I/O to PCI
- */
-
-static inline u8 __raw_readb(const volatile void __iomem *addr)
-{
-       return *(__force volatile u8 *)addr;
-}
-
-static inline u16 __raw_readw(const volatile void __iomem *addr)
-{
-       return *(__force volatile u16 *)addr;
-}
-
-static inline u32 __raw_readl(const volatile void __iomem *addr)
-{
-       return *(__force volatile u32 *)addr;
-}
-
-static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
-{
-       *(__force volatile u8 *)addr = b;
-}
-
-static inline void __raw_writew(u16 w, volatile void __iomem *addr)
-{
-       *(__force volatile u16 *)addr = w;
-}
-
-static inline void __raw_writel(u32 l, volatile void __iomem *addr)
-{
-       *(__force volatile u32 *)addr = l;
-}
-
-static inline u8 __readb(const volatile void __iomem *addr)
-{
-       return *(__force volatile u8 *)addr;
-}
-
-static inline u16 __readw(const volatile void __iomem *addr)
-{
-       return flip_word(*(__force volatile u16 *)addr);
-}
-
-static inline u32 __readl(const volatile void __iomem *addr)
-{
-       return flip_dword(*(__force volatile u32 *)addr);
-}
-
-static inline void __writeb(u8 b, volatile void __iomem *addr)
-{
-       *(__force volatile u8 *)addr = b;
-}
-
-static inline void __writew(u16 w, volatile void __iomem *addr)
-{
-       *(__force volatile u16 *)addr = flip_word(w);
-}
-
-static inline void __writel(u32 l, volatile void __iomem *addr)
-{
-       *(__force volatile u32 *)addr = flip_dword(l);
-}
-
-#define readb(__addr)          __readb(__addr)
-#define readw(__addr)          __readw(__addr)
-#define readl(__addr)          __readl(__addr)
-#define readb_relaxed(__addr)  readb(__addr)
-#define readw_relaxed(__addr)  readw(__addr)
-#define readl_relaxed(__addr)  readl(__addr)
-
-#define writeb(__b, __addr)    __writeb((__b),(__addr))
-#define writew(__w, __addr)    __writew((__w),(__addr))
-#define writel(__l, __addr)    __writel((__l),(__addr))
-
-/*
- * I/O space operations
- *
- * Arrangement on a Sun is somewhat complicated.
- *
- * First of all, we want to use standard Linux drivers
- * for keyboard, PC serial, etc. These drivers think
- * they access I/O space and use inb/outb.
- * On the other hand, EBus bridge accepts PCI *memory*
- * cycles and converts them into ISA *I/O* cycles.
- * Ergo, we want inb & outb to generate PCI memory cycles.
- *
- * If we want to issue PCI *I/O* cycles, we do this
- * with a low 64K fixed window in PCIC. This window gets
- * mapped somewhere into virtual kernel space and we
- * can use inb/outb again.
- */
-#define inb_local(__addr)      __readb((void __iomem *)(unsigned long)(__addr))
-#define inb(__addr)            __readb((void __iomem *)(unsigned long)(__addr))
-#define inw(__addr)            __readw((void __iomem *)(unsigned long)(__addr))
-#define inl(__addr)            __readl((void __iomem *)(unsigned long)(__addr))
-
-#define outb_local(__b, __addr)        __writeb(__b, (void __iomem *)(unsigned long)(__addr))
-#define outb(__b, __addr)      __writeb(__b, (void __iomem *)(unsigned long)(__addr))
-#define outw(__w, __addr)      __writew(__w, (void __iomem *)(unsigned long)(__addr))
-#define outl(__l, __addr)      __writel(__l, (void __iomem *)(unsigned long)(__addr))
-
-#define inb_p(__addr)          inb(__addr)
-#define outb_p(__b, __addr)    outb(__b, __addr)
-#define inw_p(__addr)          inw(__addr)
-#define outw_p(__w, __addr)    outw(__w, __addr)
-#define inl_p(__addr)          inl(__addr)
-#define outl_p(__l, __addr)    outl(__l, __addr)
-
-void outsb(unsigned long addr, const void *src, unsigned long cnt);
-void outsw(unsigned long addr, const void *src, unsigned long cnt);
-void outsl(unsigned long addr, const void *src, unsigned long cnt);
-void insb(unsigned long addr, void *dst, unsigned long count);
-void insw(unsigned long addr, void *dst, unsigned long count);
-void insl(unsigned long addr, void *dst, unsigned long count);
-
-#define IO_SPACE_LIMIT 0xffffffff
-
-/*
- * SBus accessors.
- *
- * SBus has only one, memory mapped, I/O space.
- * We do not need to flip bytes for SBus of course.
- */
-static inline u8 _sbus_readb(const volatile void __iomem *addr)
-{
-       return *(__force volatile u8 *)addr;
-}
-
-static inline u16 _sbus_readw(const volatile void __iomem *addr)
-{
-       return *(__force volatile u16 *)addr;
-}
-
-static inline u32 _sbus_readl(const volatile void __iomem *addr)
-{
-       return *(__force volatile u32 *)addr;
-}
-
-static inline void _sbus_writeb(u8 b, volatile void __iomem *addr)
-{
-       *(__force volatile u8 *)addr = b;
-}
-
-static inline void _sbus_writew(u16 w, volatile void __iomem *addr)
-{
-       *(__force volatile u16 *)addr = w;
-}
-
-static inline void _sbus_writel(u32 l, volatile void __iomem *addr)
-{
-       *(__force volatile u32 *)addr = l;
-}
-
-/*
- * The only reason for #define's is to hide casts to unsigned long.
- */
-#define sbus_readb(__addr)             _sbus_readb(__addr)
-#define sbus_readw(__addr)             _sbus_readw(__addr)
-#define sbus_readl(__addr)             _sbus_readl(__addr)
-#define sbus_writeb(__b, __addr)       _sbus_writeb(__b, __addr)
-#define sbus_writew(__w, __addr)       _sbus_writew(__w, __addr)
-#define sbus_writel(__l, __addr)       _sbus_writel(__l, __addr)
-
-static inline void sbus_memset_io(volatile void __iomem *__dst, int c, __kernel_size_t n)
-{
-       while(n--) {
-               sbus_writeb(c, __dst);
-               __dst++;
-       }
-}
-
-static inline void
-_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
-{
-       volatile void __iomem *d = dst;
-
-       while (n--) {
-               writeb(c, d);
-               d++;
-       }
-}
-
-#define memset_io(d,c,sz)      _memset_io(d,c,sz)
-
-static inline void
-_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
-{
-       char *d = dst;
-
-       while (n--) {
-               char tmp = readb(src);
-               *d++ = tmp;
-               src++;
-       }
-}
-
-#define memcpy_fromio(d,s,sz)  _memcpy_fromio(d,s,sz)
-
-static inline void 
-_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
-{
-       const char *s = src;
-       volatile void __iomem *d = dst;
-
-       while (n--) {
-               char tmp = *s++;
-               writeb(tmp, d);
-               d++;
-       }
-}
-
-#define memcpy_toio(d,s,sz)    _memcpy_toio(d,s,sz)
-
-#ifdef __KERNEL__
-
-/*
- * Bus number may be embedded in the higher bits of the physical address.
- * This is why we have no bus number argument to ioremap().
- */
-extern void __iomem *ioremap(unsigned long offset, unsigned long size);
-#define ioremap_nocache(X,Y)   ioremap((X),(Y))
-extern void iounmap(volatile void __iomem *addr);
-
-#define ioread8(X)                     readb(X)
-#define ioread16(X)                    readw(X)
-#define ioread32(X)                    readl(X)
-#define iowrite8(val,X)                        writeb(val,X)
-#define iowrite16(val,X)               writew(val,X)
-#define iowrite32(val,X)               writel(val,X)
-
-static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
-{
-       insb((unsigned long __force)port, buf, count);
-}
-static inline void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
-{
-       insw((unsigned long __force)port, buf, count);
-}
-
-static inline void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
-{
-       insl((unsigned long __force)port, buf, count);
-}
-
-static inline void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
-{
-       outsb((unsigned long __force)port, buf, count);
-}
-
-static inline void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
-{
-       outsw((unsigned long __force)port, buf, count);
-}
-
-static inline void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
-{
-       outsl((unsigned long __force)port, buf, count);
-}
-
-/* Create a virtual mapping cookie for an IO port range */
-extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
-extern void ioport_unmap(void __iomem *);
-
-/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
-struct pci_dev;
-extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
-extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
-
-/*
- * Bus number may be in res->flags... somewhere.
- */
-extern void __iomem *sbus_ioremap(struct resource *res, unsigned long offset,
-    unsigned long size, char *name);
-extern void sbus_iounmap(volatile void __iomem *vaddr, unsigned long size);
-
-
-/*
- * At the moment, we do not use CMOS_READ anywhere outside of rtc.c,
- * so rtc_port is static in it. This should not change unless a new
- * hardware pops up.
- */
-#define RTC_PORT(x)   (rtc_port + (x))
-#define RTC_ALWAYS_BCD  0
-
+#ifndef ___ASM_SPARC_IO_H
+#define ___ASM_SPARC_IO_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/io_64.h>
+#else
+#include <asm-sparc/io_32.h>
+#endif
 #endif
-
-#define __ARCH_HAS_NO_PAGE_ZERO_MAPPED         1
-
-/*
- * Convert a physical pointer to a virtual kernel pointer for /dev/mem
- * access
- */
-#define xlate_dev_mem_ptr(p)   __va(p)
-
-/*
- * Convert a virtual cached pointer to an uncached pointer
- */
-#define xlate_dev_kmem_ptr(p)  p
-
-#endif /* !(__SPARC_IO_H) */
diff --git a/include/asm-sparc/io_32.h b/include/asm-sparc/io_32.h
new file mode 100644 (file)
index 0000000..10d7da4
--- /dev/null
@@ -0,0 +1,326 @@
+#ifndef __SPARC_IO_H
+#define __SPARC_IO_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/ioport.h>  /* struct resource */
+
+#include <asm/page.h>      /* IO address mapping routines need this */
+#include <asm/system.h>
+
+#define page_to_phys(page)     (((page) - mem_map) << PAGE_SHIFT)
+
+static inline u32 flip_dword (u32 l)
+{
+       return ((l&0xff)<<24) | (((l>>8)&0xff)<<16) | (((l>>16)&0xff)<<8)| ((l>>24)&0xff);
+}
+
+static inline u16 flip_word (u16 w)
+{
+       return ((w&0xff) << 8) | ((w>>8)&0xff);
+}
+
+#define mmiowb()
+
+/*
+ * Memory mapped I/O to PCI
+ */
+
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+       return *(__force volatile u8 *)addr;
+}
+
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+       return *(__force volatile u16 *)addr;
+}
+
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+       return *(__force volatile u32 *)addr;
+}
+
+static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
+{
+       *(__force volatile u8 *)addr = b;
+}
+
+static inline void __raw_writew(u16 w, volatile void __iomem *addr)
+{
+       *(__force volatile u16 *)addr = w;
+}
+
+static inline void __raw_writel(u32 l, volatile void __iomem *addr)
+{
+       *(__force volatile u32 *)addr = l;
+}
+
+static inline u8 __readb(const volatile void __iomem *addr)
+{
+       return *(__force volatile u8 *)addr;
+}
+
+static inline u16 __readw(const volatile void __iomem *addr)
+{
+       return flip_word(*(__force volatile u16 *)addr);
+}
+
+static inline u32 __readl(const volatile void __iomem *addr)
+{
+       return flip_dword(*(__force volatile u32 *)addr);
+}
+
+static inline void __writeb(u8 b, volatile void __iomem *addr)
+{
+       *(__force volatile u8 *)addr = b;
+}
+
+static inline void __writew(u16 w, volatile void __iomem *addr)
+{
+       *(__force volatile u16 *)addr = flip_word(w);
+}
+
+static inline void __writel(u32 l, volatile void __iomem *addr)
+{
+       *(__force volatile u32 *)addr = flip_dword(l);
+}
+
+#define readb(__addr)          __readb(__addr)
+#define readw(__addr)          __readw(__addr)
+#define readl(__addr)          __readl(__addr)
+#define readb_relaxed(__addr)  readb(__addr)
+#define readw_relaxed(__addr)  readw(__addr)
+#define readl_relaxed(__addr)  readl(__addr)
+
+#define writeb(__b, __addr)    __writeb((__b),(__addr))
+#define writew(__w, __addr)    __writew((__w),(__addr))
+#define writel(__l, __addr)    __writel((__l),(__addr))
+
+/*
+ * I/O space operations
+ *
+ * Arrangement on a Sun is somewhat complicated.
+ *
+ * First of all, we want to use standard Linux drivers
+ * for keyboard, PC serial, etc. These drivers think
+ * they access I/O space and use inb/outb.
+ * On the other hand, EBus bridge accepts PCI *memory*
+ * cycles and converts them into ISA *I/O* cycles.
+ * Ergo, we want inb & outb to generate PCI memory cycles.
+ *
+ * If we want to issue PCI *I/O* cycles, we do this
+ * with a low 64K fixed window in PCIC. This window gets
+ * mapped somewhere into virtual kernel space and we
+ * can use inb/outb again.
+ */
+#define inb_local(__addr)      __readb((void __iomem *)(unsigned long)(__addr))
+#define inb(__addr)            __readb((void __iomem *)(unsigned long)(__addr))
+#define inw(__addr)            __readw((void __iomem *)(unsigned long)(__addr))
+#define inl(__addr)            __readl((void __iomem *)(unsigned long)(__addr))
+
+#define outb_local(__b, __addr)        __writeb(__b, (void __iomem *)(unsigned long)(__addr))
+#define outb(__b, __addr)      __writeb(__b, (void __iomem *)(unsigned long)(__addr))
+#define outw(__w, __addr)      __writew(__w, (void __iomem *)(unsigned long)(__addr))
+#define outl(__l, __addr)      __writel(__l, (void __iomem *)(unsigned long)(__addr))
+
+#define inb_p(__addr)          inb(__addr)
+#define outb_p(__b, __addr)    outb(__b, __addr)
+#define inw_p(__addr)          inw(__addr)
+#define outw_p(__w, __addr)    outw(__w, __addr)
+#define inl_p(__addr)          inl(__addr)
+#define outl_p(__l, __addr)    outl(__l, __addr)
+
+void outsb(unsigned long addr, const void *src, unsigned long cnt);
+void outsw(unsigned long addr, const void *src, unsigned long cnt);
+void outsl(unsigned long addr, const void *src, unsigned long cnt);
+void insb(unsigned long addr, void *dst, unsigned long count);
+void insw(unsigned long addr, void *dst, unsigned long count);
+void insl(unsigned long addr, void *dst, unsigned long count);
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * SBus accessors.
+ *
+ * SBus has only one, memory mapped, I/O space.
+ * We do not need to flip bytes for SBus of course.
+ */
+static inline u8 _sbus_readb(const volatile void __iomem *addr)
+{
+       return *(__force volatile u8 *)addr;
+}
+
+static inline u16 _sbus_readw(const volatile void __iomem *addr)
+{
+       return *(__force volatile u16 *)addr;
+}
+
+static inline u32 _sbus_readl(const volatile void __iomem *addr)
+{
+       return *(__force volatile u32 *)addr;
+}
+
+static inline void _sbus_writeb(u8 b, volatile void __iomem *addr)
+{
+       *(__force volatile u8 *)addr = b;
+}
+
+static inline void _sbus_writew(u16 w, volatile void __iomem *addr)
+{
+       *(__force volatile u16 *)addr = w;
+}
+
+static inline void _sbus_writel(u32 l, volatile void __iomem *addr)
+{
+       *(__force volatile u32 *)addr = l;
+}
+
+/*
+ * The only reason for #define's is to hide casts to unsigned long.
+ */
+#define sbus_readb(__addr)             _sbus_readb(__addr)
+#define sbus_readw(__addr)             _sbus_readw(__addr)
+#define sbus_readl(__addr)             _sbus_readl(__addr)
+#define sbus_writeb(__b, __addr)       _sbus_writeb(__b, __addr)
+#define sbus_writew(__w, __addr)       _sbus_writew(__w, __addr)
+#define sbus_writel(__l, __addr)       _sbus_writel(__l, __addr)
+
+static inline void sbus_memset_io(volatile void __iomem *__dst, int c, __kernel_size_t n)
+{
+       while(n--) {
+               sbus_writeb(c, __dst);
+               __dst++;
+       }
+}
+
+static inline void
+_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
+{
+       volatile void __iomem *d = dst;
+
+       while (n--) {
+               writeb(c, d);
+               d++;
+       }
+}
+
+#define memset_io(d,c,sz)      _memset_io(d,c,sz)
+
+static inline void
+_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
+{
+       char *d = dst;
+
+       while (n--) {
+               char tmp = readb(src);
+               *d++ = tmp;
+               src++;
+       }
+}
+
+#define memcpy_fromio(d,s,sz)  _memcpy_fromio(d,s,sz)
+
+static inline void
+_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
+{
+       const char *s = src;
+       volatile void __iomem *d = dst;
+
+       while (n--) {
+               char tmp = *s++;
+               writeb(tmp, d);
+               d++;
+       }
+}
+
+#define memcpy_toio(d,s,sz)    _memcpy_toio(d,s,sz)
+
+#ifdef __KERNEL__
+
+/*
+ * Bus number may be embedded in the higher bits of the physical address.
+ * This is why we have no bus number argument to ioremap().
+ */
+extern void __iomem *ioremap(unsigned long offset, unsigned long size);
+#define ioremap_nocache(X,Y)   ioremap((X),(Y))
+#define ioremap_wc(X,Y)                ioremap((X),(Y))
+extern void iounmap(volatile void __iomem *addr);
+
+#define ioread8(X)                     readb(X)
+#define ioread16(X)                    readw(X)
+#define ioread32(X)                    readl(X)
+#define iowrite8(val,X)                        writeb(val,X)
+#define iowrite16(val,X)               writew(val,X)
+#define iowrite32(val,X)               writel(val,X)
+
+static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
+{
+       insb((unsigned long __force)port, buf, count);
+}
+static inline void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
+{
+       insw((unsigned long __force)port, buf, count);
+}
+
+static inline void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
+{
+       insl((unsigned long __force)port, buf, count);
+}
+
+static inline void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
+{
+       outsb((unsigned long __force)port, buf, count);
+}
+
+static inline void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
+{
+       outsw((unsigned long __force)port, buf, count);
+}
+
+static inline void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
+{
+       outsl((unsigned long __force)port, buf, count);
+}
+
+/* Create a virtual mapping cookie for an IO port range */
+extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
+extern void ioport_unmap(void __iomem *);
+
+/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
+struct pci_dev;
+extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
+
+/*
+ * Bus number may be in res->flags... somewhere.
+ */
+extern void __iomem *sbus_ioremap(struct resource *res, unsigned long offset,
+    unsigned long size, char *name);
+extern void sbus_iounmap(volatile void __iomem *vaddr, unsigned long size);
+
+
+/*
+ * At the moment, we do not use CMOS_READ anywhere outside of rtc.c,
+ * so rtc_port is static in it. This should not change unless a new
+ * hardware pops up.
+ */
+#define RTC_PORT(x)   (rtc_port + (x))
+#define RTC_ALWAYS_BCD  0
+
+#endif
+
+#define __ARCH_HAS_NO_PAGE_ZERO_MAPPED         1
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p)   __va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p)  p
+
+#endif /* !(__SPARC_IO_H) */
diff --git a/include/asm-sparc/io_64.h b/include/asm-sparc/io_64.h
new file mode 100644 (file)
index 0000000..0bff078
--- /dev/null
@@ -0,0 +1,511 @@
+#ifndef __SPARC64_IO_H
+#define __SPARC64_IO_H
+
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+#include <asm/page.h>      /* IO address mapping routines need this */
+#include <asm/system.h>
+#include <asm/asi.h>
+
+/* PC crapola... */
+#define __SLOW_DOWN_IO do { } while (0)
+#define SLOW_DOWN_IO   do { } while (0)
+
+/* BIO layer definitions. */
+extern unsigned long kern_base, kern_size;
+#define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
+
+static inline u8 _inb(unsigned long addr)
+{
+       u8 ret;
+
+       __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_inb */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+
+       return ret;
+}
+
+static inline u16 _inw(unsigned long addr)
+{
+       u16 ret;
+
+       __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_inw */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+
+       return ret;
+}
+
+static inline u32 _inl(unsigned long addr)
+{
+       u32 ret;
+
+       __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_inl */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+
+       return ret;
+}
+
+static inline void _outb(u8 b, unsigned long addr)
+{
+       __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */"
+                            : /* no outputs */
+                            : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+}
+
+static inline void _outw(u16 w, unsigned long addr)
+{
+       __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */"
+                            : /* no outputs */
+                            : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+}
+
+static inline void _outl(u32 l, unsigned long addr)
+{
+       __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */"
+                            : /* no outputs */
+                            : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+}
+
+#define inb(__addr)            (_inb((unsigned long)(__addr)))
+#define inw(__addr)            (_inw((unsigned long)(__addr)))
+#define inl(__addr)            (_inl((unsigned long)(__addr)))
+#define outb(__b, __addr)      (_outb((u8)(__b), (unsigned long)(__addr)))
+#define outw(__w, __addr)      (_outw((u16)(__w), (unsigned long)(__addr)))
+#define outl(__l, __addr)      (_outl((u32)(__l), (unsigned long)(__addr)))
+
+#define inb_p(__addr)          inb(__addr)
+#define outb_p(__b, __addr)    outb(__b, __addr)
+#define inw_p(__addr)          inw(__addr)
+#define outw_p(__w, __addr)    outw(__w, __addr)
+#define inl_p(__addr)          inl(__addr)
+#define outl_p(__l, __addr)    outl(__l, __addr)
+
+extern void outsb(unsigned long, const void *, unsigned long);
+extern void outsw(unsigned long, const void *, unsigned long);
+extern void outsl(unsigned long, const void *, unsigned long);
+extern void insb(unsigned long, void *, unsigned long);
+extern void insw(unsigned long, void *, unsigned long);
+extern void insl(unsigned long, void *, unsigned long);
+
+static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
+{
+       insb((unsigned long __force)port, buf, count);
+}
+static inline void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
+{
+       insw((unsigned long __force)port, buf, count);
+}
+
+static inline void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
+{
+       insl((unsigned long __force)port, buf, count);
+}
+
+static inline void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
+{
+       outsb((unsigned long __force)port, buf, count);
+}
+
+static inline void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
+{
+       outsw((unsigned long __force)port, buf, count);
+}
+
+static inline void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
+{
+       outsl((unsigned long __force)port, buf, count);
+}
+
+/* Memory functions, same as I/O accesses on Ultra. */
+static inline u8 _readb(const volatile void __iomem *addr)
+{      u8 ret;
+
+       __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+       return ret;
+}
+
+static inline u16 _readw(const volatile void __iomem *addr)
+{      u16 ret;
+
+       __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+
+       return ret;
+}
+
+static inline u32 _readl(const volatile void __iomem *addr)
+{      u32 ret;
+
+       __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+
+       return ret;
+}
+
+static inline u64 _readq(const volatile void __iomem *addr)
+{      u64 ret;
+
+       __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_readq */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+
+       return ret;
+}
+
+static inline void _writeb(u8 b, volatile void __iomem *addr)
+{
+       __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */"
+                            : /* no outputs */
+                            : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+}
+
+static inline void _writew(u16 w, volatile void __iomem *addr)
+{
+       __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */"
+                            : /* no outputs */
+                            : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+}
+
+static inline void _writel(u32 l, volatile void __iomem *addr)
+{
+       __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */"
+                            : /* no outputs */
+                            : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+}
+
+static inline void _writeq(u64 q, volatile void __iomem *addr)
+{
+       __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_writeq */"
+                            : /* no outputs */
+                            : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
+                            : "memory");
+}
+
+#define readb(__addr)          _readb(__addr)
+#define readw(__addr)          _readw(__addr)
+#define readl(__addr)          _readl(__addr)
+#define readq(__addr)          _readq(__addr)
+#define readb_relaxed(__addr)  _readb(__addr)
+#define readw_relaxed(__addr)  _readw(__addr)
+#define readl_relaxed(__addr)  _readl(__addr)
+#define readq_relaxed(__addr)  _readq(__addr)
+#define writeb(__b, __addr)    _writeb(__b, __addr)
+#define writew(__w, __addr)    _writew(__w, __addr)
+#define writel(__l, __addr)    _writel(__l, __addr)
+#define writeq(__q, __addr)    _writeq(__q, __addr)
+
+/* Now versions without byte-swapping. */
+static inline u8 _raw_readb(unsigned long addr)
+{
+       u8 ret;
+
+       __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+
+       return ret;
+}
+
+static inline u16 _raw_readw(unsigned long addr)
+{
+       u16 ret;
+
+       __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+
+       return ret;
+}
+
+static inline u32 _raw_readl(unsigned long addr)
+{
+       u32 ret;
+
+       __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+
+       return ret;
+}
+
+static inline u64 _raw_readq(unsigned long addr)
+{
+       u64 ret;
+
+       __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_raw_readq */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+
+       return ret;
+}
+
+static inline void _raw_writeb(u8 b, unsigned long addr)
+{
+       __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */"
+                            : /* no outputs */
+                            : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+}
+
+static inline void _raw_writew(u16 w, unsigned long addr)
+{
+       __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */"
+                            : /* no outputs */
+                            : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+}
+
+static inline void _raw_writel(u32 l, unsigned long addr)
+{
+       __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */"
+                            : /* no outputs */
+                            : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+}
+
+static inline void _raw_writeq(u64 q, unsigned long addr)
+{
+       __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */"
+                            : /* no outputs */
+                            : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+}
+
+#define __raw_readb(__addr)            (_raw_readb((unsigned long)(__addr)))
+#define __raw_readw(__addr)            (_raw_readw((unsigned long)(__addr)))
+#define __raw_readl(__addr)            (_raw_readl((unsigned long)(__addr)))
+#define __raw_readq(__addr)            (_raw_readq((unsigned long)(__addr)))
+#define __raw_writeb(__b, __addr)      (_raw_writeb((u8)(__b), (unsigned long)(__addr)))
+#define __raw_writew(__w, __addr)      (_raw_writew((u16)(__w), (unsigned long)(__addr)))
+#define __raw_writel(__l, __addr)      (_raw_writel((u32)(__l), (unsigned long)(__addr)))
+#define __raw_writeq(__q, __addr)      (_raw_writeq((u64)(__q), (unsigned long)(__addr)))
+
+/* Valid I/O Space regions are anywhere, because each PCI bus supported
+ * can live in an arbitrary area of the physical address range.
+ */
+#define IO_SPACE_LIMIT 0xffffffffffffffffUL
+
+/* Now, SBUS variants, only difference from PCI is that we do
+ * not use little-endian ASIs.
+ */
+static inline u8 _sbus_readb(const volatile void __iomem *addr)
+{
+       u8 ret;
+
+       __asm__ __volatile__("lduba\t[%1] %2, %0\t/* sbus_readb */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
+                            : "memory");
+
+       return ret;
+}
+
+static inline u16 _sbus_readw(const volatile void __iomem *addr)
+{
+       u16 ret;
+
+       __asm__ __volatile__("lduha\t[%1] %2, %0\t/* sbus_readw */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
+                            : "memory");
+
+       return ret;
+}
+
+static inline u32 _sbus_readl(const volatile void __iomem *addr)
+{
+       u32 ret;
+
+       __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* sbus_readl */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
+                            : "memory");
+
+       return ret;
+}
+
+static inline u64 _sbus_readq(const volatile void __iomem *addr)
+{
+       u64 ret;
+
+       __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* sbus_readq */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
+                            : "memory");
+
+       return ret;
+}
+
+static inline void _sbus_writeb(u8 b, volatile void __iomem *addr)
+{
+       __asm__ __volatile__("stba\t%r0, [%1] %2\t/* sbus_writeb */"
+                            : /* no outputs */
+                            : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
+                            : "memory");
+}
+
+static inline void _sbus_writew(u16 w, volatile void __iomem *addr)
+{
+       __asm__ __volatile__("stha\t%r0, [%1] %2\t/* sbus_writew */"
+                            : /* no outputs */
+                            : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
+                            : "memory");
+}
+
+static inline void _sbus_writel(u32 l, volatile void __iomem *addr)
+{
+       __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* sbus_writel */"
+                            : /* no outputs */
+                            : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
+                            : "memory");
+}
+
+static inline void _sbus_writeq(u64 l, volatile void __iomem *addr)
+{
+       __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* sbus_writeq */"
+                            : /* no outputs */
+                            : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
+                            : "memory");
+}
+
+#define sbus_readb(__addr)             _sbus_readb(__addr)
+#define sbus_readw(__addr)             _sbus_readw(__addr)
+#define sbus_readl(__addr)             _sbus_readl(__addr)
+#define sbus_readq(__addr)             _sbus_readq(__addr)
+#define sbus_writeb(__b, __addr)       _sbus_writeb(__b, __addr)
+#define sbus_writew(__w, __addr)       _sbus_writew(__w, __addr)
+#define sbus_writel(__l, __addr)       _sbus_writel(__l, __addr)
+#define sbus_writeq(__l, __addr)       _sbus_writeq(__l, __addr)
+
+static inline void _sbus_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
+{
+       while(n--) {
+               sbus_writeb(c, dst);
+               dst++;
+       }
+}
+
+#define sbus_memset_io(d,c,sz) _sbus_memset_io(d,c,sz)
+
+static inline void
+_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
+{
+       volatile void __iomem *d = dst;
+
+       while (n--) {
+               writeb(c, d);
+               d++;
+       }
+}
+
+#define memset_io(d,c,sz)      _memset_io(d,c,sz)
+
+static inline void
+_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
+{
+       char *d = dst;
+
+       while (n--) {
+               char tmp = readb(src);
+               *d++ = tmp;
+               src++;
+       }
+}
+
+#define memcpy_fromio(d,s,sz)  _memcpy_fromio(d,s,sz)
+
+static inline void
+_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
+{
+       const char *s = src;
+       volatile void __iomem *d = dst;
+
+       while (n--) {
+               char tmp = *s++;
+               writeb(tmp, d);
+               d++;
+       }
+}
+
+#define memcpy_toio(d,s,sz)    _memcpy_toio(d,s,sz)
+
+#define mmiowb()
+
+#ifdef __KERNEL__
+
+/* On sparc64 we have the whole physical IO address space accessible
+ * using physically addressed loads and stores, so this does nothing.
+ */
+static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+{
+       return (void __iomem *)offset;
+}
+
+#define ioremap_nocache(X,Y)           ioremap((X),(Y))
+#define ioremap_wc(X,Y)                        ioremap((X),(Y))
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+}
+
+#define ioread8(X)                     readb(X)
+#define ioread16(X)                    readw(X)
+#define ioread32(X)                    readl(X)
+#define iowrite8(val,X)                        writeb(val,X)
+#define iowrite16(val,X)               writew(val,X)
+#define iowrite32(val,X)               writel(val,X)
+
+/* Create a virtual mapping cookie for an IO port range */
+extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
+extern void ioport_unmap(void __iomem *);
+
+/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
+struct pci_dev;
+extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
+
+/* Similarly for SBUS. */
+#define sbus_ioremap(__res, __offset, __size, __name) \
+({     unsigned long __ret; \
+       __ret  = (__res)->start + (((__res)->flags & 0x1ffUL) << 32UL); \
+       __ret += (unsigned long) (__offset); \
+       if (! request_region((__ret), (__size), (__name))) \
+               __ret = 0UL; \
+       (void __iomem *) __ret; \
+})
+
+#define sbus_iounmap(__addr, __size)   \
+       release_region((unsigned long)(__addr), (__size))
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p)   __va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p)  p
+
+#endif
+
+#endif /* !(__SPARC64_IO_H) */
index 3f4d0087b6a3c1a3d39e432d0d74f851caedc354..1fe6855c5c1896dccae71b86d359db3dd826e5be 100644 (file)
@@ -22,7 +22,7 @@
 
 /* Note that all the ioctls that are not available in Linux have a 
  * double underscore on the front to: a) avoid some programs to
- * thing we support some ioctls under Linux (autoconfiguration stuff)
+ * think we support some ioctls under Linux (autoconfiguration stuff)
  */
 /* Little t */
 #define TIOCGETD       _IOR('t', 0, int)
 #define TIOCSERGETLSR   0x5459 /* Get line status register */
 #define TIOCSERGETMULTI 0x545A /* Get multiport config  */
 #define TIOCSERSETMULTI 0x545B /* Set multiport config */
-#define TIOCMIWAIT     0x545C /* Wait input */
+#define TIOCMIWAIT     0x545C /* Wait for change on serial input line(s) */
 #define TIOCGICOUNT    0x545D /* Read serial port inline interrupt counts */
 
 /* Kernel definitions */
index 70c589c05a109627e9c70adf1b50e104513f436c..91b072b0d7a083b1dfa272b7622ecf25d9859974 100644 (file)
@@ -1,121 +1,8 @@
-/* iommu.h: Definitions for the sun4m IOMMU.
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-#ifndef _SPARC_IOMMU_H
-#define _SPARC_IOMMU_H
-
-#include <asm/page.h>
-#include <asm/bitext.h>
-
-/* The iommu handles all virtual to physical address translations
- * that occur between the SBUS and physical memory.  Access by
- * the cpu to IO registers and similar go over the mbus so are
- * translated by the on chip SRMMU.  The iommu and the srmmu do
- * not need to have the same translations at all, in fact most
- * of the time the translations they handle are a disjunct set.
- * Basically the iommu handles all dvma sbus activity.
- */
-
-/* The IOMMU registers occupy three pages in IO space. */
-struct iommu_regs {
-       /* First page */
-       volatile unsigned long control;    /* IOMMU control */
-       volatile unsigned long base;       /* Physical base of iopte page table */
-       volatile unsigned long _unused1[3];
-       volatile unsigned long tlbflush;   /* write only */
-       volatile unsigned long pageflush;  /* write only */
-       volatile unsigned long _unused2[1017];
-       /* Second page */
-       volatile unsigned long afsr;       /* Async-fault status register */
-       volatile unsigned long afar;       /* Async-fault physical address */
-       volatile unsigned long _unused3[2];
-       volatile unsigned long sbuscfg0;   /* SBUS configuration registers, per-slot */
-       volatile unsigned long sbuscfg1;
-       volatile unsigned long sbuscfg2;
-       volatile unsigned long sbuscfg3;
-       volatile unsigned long mfsr;       /* Memory-fault status register */
-       volatile unsigned long mfar;       /* Memory-fault physical address */
-       volatile unsigned long _unused4[1014];
-       /* Third page */
-       volatile unsigned long mid;        /* IOMMU module-id */
-};
-
-#define IOMMU_CTRL_IMPL     0xf0000000 /* Implementation */
-#define IOMMU_CTRL_VERS     0x0f000000 /* Version */
-#define IOMMU_CTRL_RNGE     0x0000001c /* Mapping RANGE */
-#define IOMMU_RNGE_16MB     0x00000000 /* 0xff000000 -> 0xffffffff */
-#define IOMMU_RNGE_32MB     0x00000004 /* 0xfe000000 -> 0xffffffff */
-#define IOMMU_RNGE_64MB     0x00000008 /* 0xfc000000 -> 0xffffffff */
-#define IOMMU_RNGE_128MB    0x0000000c /* 0xf8000000 -> 0xffffffff */
-#define IOMMU_RNGE_256MB    0x00000010 /* 0xf0000000 -> 0xffffffff */
-#define IOMMU_RNGE_512MB    0x00000014 /* 0xe0000000 -> 0xffffffff */
-#define IOMMU_RNGE_1GB      0x00000018 /* 0xc0000000 -> 0xffffffff */
-#define IOMMU_RNGE_2GB      0x0000001c /* 0x80000000 -> 0xffffffff */
-#define IOMMU_CTRL_ENAB     0x00000001 /* IOMMU Enable */
-
-#define IOMMU_AFSR_ERR      0x80000000 /* LE, TO, or BE asserted */
-#define IOMMU_AFSR_LE       0x40000000 /* SBUS reports error after transaction */
-#define IOMMU_AFSR_TO       0x20000000 /* Write access took more than 12.8 us. */
-#define IOMMU_AFSR_BE       0x10000000 /* Write access received error acknowledge */
-#define IOMMU_AFSR_SIZE     0x0e000000 /* Size of transaction causing error */
-#define IOMMU_AFSR_S        0x01000000 /* Sparc was in supervisor mode */
-#define IOMMU_AFSR_RESV     0x00f00000 /* Reserver, forced to 0x8 by hardware */
-#define IOMMU_AFSR_ME       0x00080000 /* Multiple errors occurred */
-#define IOMMU_AFSR_RD       0x00040000 /* A read operation was in progress */
-#define IOMMU_AFSR_FAV      0x00020000 /* IOMMU afar has valid contents */
-
-#define IOMMU_SBCFG_SAB30   0x00010000 /* Phys-address bit 30 when bypass enabled */
-#define IOMMU_SBCFG_BA16    0x00000004 /* Slave supports 16 byte bursts */
-#define IOMMU_SBCFG_BA8     0x00000002 /* Slave supports 8 byte bursts */
-#define IOMMU_SBCFG_BYPASS  0x00000001 /* Bypass IOMMU, treat all addresses
-                                         produced by this device as pure
-                                         physical. */
-
-#define IOMMU_MFSR_ERR      0x80000000 /* One or more of PERR1 or PERR0 */
-#define IOMMU_MFSR_S        0x01000000 /* Sparc was in supervisor mode */
-#define IOMMU_MFSR_CPU      0x00800000 /* CPU transaction caused parity error */
-#define IOMMU_MFSR_ME       0x00080000 /* Multiple parity errors occurred */
-#define IOMMU_MFSR_PERR     0x00006000 /* high bit indicates parity error occurred
-                                         on the even word of the access, low bit
-                                         indicated odd word caused the parity error */
-#define IOMMU_MFSR_BM       0x00001000 /* Error occurred while in boot mode */
-#define IOMMU_MFSR_C        0x00000800 /* Address causing error was marked cacheable */
-#define IOMMU_MFSR_RTYP     0x000000f0 /* Memory request transaction type */
-
-#define IOMMU_MID_SBAE      0x001f0000 /* SBus arbitration enable */
-#define IOMMU_MID_SE        0x00100000 /* Enables SCSI/ETHERNET arbitration */
-#define IOMMU_MID_SB3       0x00080000 /* Enable SBUS device 3 arbitration */
-#define IOMMU_MID_SB2       0x00040000 /* Enable SBUS device 2 arbitration */
-#define IOMMU_MID_SB1       0x00020000 /* Enable SBUS device 1 arbitration */
-#define IOMMU_MID_SB0       0x00010000 /* Enable SBUS device 0 arbitration */
-#define IOMMU_MID_MID       0x0000000f /* Module-id, hardcoded to 0x8 */
-
-/* The format of an iopte in the page tables */
-#define IOPTE_PAGE          0x07ffff00 /* Physical page number (PA[30:12]) */
-#define IOPTE_CACHE         0x00000080 /* Cached (in vme IOCACHE or Viking/MXCC) */
-#define IOPTE_WRITE         0x00000004 /* Writeable */
-#define IOPTE_VALID         0x00000002 /* IOPTE is valid */
-#define IOPTE_WAZ           0x00000001 /* Write as zeros */
-
-struct iommu_struct {
-       struct iommu_regs *regs;
-       iopte_t *page_table;
-       /* For convenience */
-       unsigned long start; /* First managed virtual address */
-       unsigned long end;   /* Last managed virtual address */
-
-       struct bit_map usemap;
-};
-
-static inline void iommu_invalidate(struct iommu_regs *regs)
-{
-       regs->tlbflush = 0;
-}
-
-static inline void iommu_invalidate_page(struct iommu_regs *regs, unsigned long ba)
-{
-       regs->pageflush = (ba & PAGE_MASK);
-}
-
-#endif /* !(_SPARC_IOMMU_H) */
+#ifndef ___ASM_SPARC_IOMMU_H
+#define ___ASM_SPARC_IOMMU_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/iommu_64.h>
+#else
+#include <asm-sparc/iommu_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/iommu_32.h b/include/asm-sparc/iommu_32.h
new file mode 100644 (file)
index 0000000..70c589c
--- /dev/null
@@ -0,0 +1,121 @@
+/* iommu.h: Definitions for the sun4m IOMMU.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC_IOMMU_H
+#define _SPARC_IOMMU_H
+
+#include <asm/page.h>
+#include <asm/bitext.h>
+
+/* The iommu handles all virtual to physical address translations
+ * that occur between the SBUS and physical memory.  Access by
+ * the cpu to IO registers and similar go over the mbus so are
+ * translated by the on chip SRMMU.  The iommu and the srmmu do
+ * not need to have the same translations at all, in fact most
+ * of the time the translations they handle are a disjunct set.
+ * Basically the iommu handles all dvma sbus activity.
+ */
+
+/* The IOMMU registers occupy three pages in IO space. */
+struct iommu_regs {
+       /* First page */
+       volatile unsigned long control;    /* IOMMU control */
+       volatile unsigned long base;       /* Physical base of iopte page table */
+       volatile unsigned long _unused1[3];
+       volatile unsigned long tlbflush;   /* write only */
+       volatile unsigned long pageflush;  /* write only */
+       volatile unsigned long _unused2[1017];
+       /* Second page */
+       volatile unsigned long afsr;       /* Async-fault status register */
+       volatile unsigned long afar;       /* Async-fault physical address */
+       volatile unsigned long _unused3[2];
+       volatile unsigned long sbuscfg0;   /* SBUS configuration registers, per-slot */
+       volatile unsigned long sbuscfg1;
+       volatile unsigned long sbuscfg2;
+       volatile unsigned long sbuscfg3;
+       volatile unsigned long mfsr;       /* Memory-fault status register */
+       volatile unsigned long mfar;       /* Memory-fault physical address */
+       volatile unsigned long _unused4[1014];
+       /* Third page */
+       volatile unsigned long mid;        /* IOMMU module-id */
+};
+
+#define IOMMU_CTRL_IMPL     0xf0000000 /* Implementation */
+#define IOMMU_CTRL_VERS     0x0f000000 /* Version */
+#define IOMMU_CTRL_RNGE     0x0000001c /* Mapping RANGE */
+#define IOMMU_RNGE_16MB     0x00000000 /* 0xff000000 -> 0xffffffff */
+#define IOMMU_RNGE_32MB     0x00000004 /* 0xfe000000 -> 0xffffffff */
+#define IOMMU_RNGE_64MB     0x00000008 /* 0xfc000000 -> 0xffffffff */
+#define IOMMU_RNGE_128MB    0x0000000c /* 0xf8000000 -> 0xffffffff */
+#define IOMMU_RNGE_256MB    0x00000010 /* 0xf0000000 -> 0xffffffff */
+#define IOMMU_RNGE_512MB    0x00000014 /* 0xe0000000 -> 0xffffffff */
+#define IOMMU_RNGE_1GB      0x00000018 /* 0xc0000000 -> 0xffffffff */
+#define IOMMU_RNGE_2GB      0x0000001c /* 0x80000000 -> 0xffffffff */
+#define IOMMU_CTRL_ENAB     0x00000001 /* IOMMU Enable */
+
+#define IOMMU_AFSR_ERR      0x80000000 /* LE, TO, or BE asserted */
+#define IOMMU_AFSR_LE       0x40000000 /* SBUS reports error after transaction */
+#define IOMMU_AFSR_TO       0x20000000 /* Write access took more than 12.8 us. */
+#define IOMMU_AFSR_BE       0x10000000 /* Write access received error acknowledge */
+#define IOMMU_AFSR_SIZE     0x0e000000 /* Size of transaction causing error */
+#define IOMMU_AFSR_S        0x01000000 /* Sparc was in supervisor mode */
+#define IOMMU_AFSR_RESV     0x00f00000 /* Reserver, forced to 0x8 by hardware */
+#define IOMMU_AFSR_ME       0x00080000 /* Multiple errors occurred */
+#define IOMMU_AFSR_RD       0x00040000 /* A read operation was in progress */
+#define IOMMU_AFSR_FAV      0x00020000 /* IOMMU afar has valid contents */
+
+#define IOMMU_SBCFG_SAB30   0x00010000 /* Phys-address bit 30 when bypass enabled */
+#define IOMMU_SBCFG_BA16    0x00000004 /* Slave supports 16 byte bursts */
+#define IOMMU_SBCFG_BA8     0x00000002 /* Slave supports 8 byte bursts */
+#define IOMMU_SBCFG_BYPASS  0x00000001 /* Bypass IOMMU, treat all addresses
+                                         produced by this device as pure
+                                         physical. */
+
+#define IOMMU_MFSR_ERR      0x80000000 /* One or more of PERR1 or PERR0 */
+#define IOMMU_MFSR_S        0x01000000 /* Sparc was in supervisor mode */
+#define IOMMU_MFSR_CPU      0x00800000 /* CPU transaction caused parity error */
+#define IOMMU_MFSR_ME       0x00080000 /* Multiple parity errors occurred */
+#define IOMMU_MFSR_PERR     0x00006000 /* high bit indicates parity error occurred
+                                         on the even word of the access, low bit
+                                         indicated odd word caused the parity error */
+#define IOMMU_MFSR_BM       0x00001000 /* Error occurred while in boot mode */
+#define IOMMU_MFSR_C        0x00000800 /* Address causing error was marked cacheable */
+#define IOMMU_MFSR_RTYP     0x000000f0 /* Memory request transaction type */
+
+#define IOMMU_MID_SBAE      0x001f0000 /* SBus arbitration enable */
+#define IOMMU_MID_SE        0x00100000 /* Enables SCSI/ETHERNET arbitration */
+#define IOMMU_MID_SB3       0x00080000 /* Enable SBUS device 3 arbitration */
+#define IOMMU_MID_SB2       0x00040000 /* Enable SBUS device 2 arbitration */
+#define IOMMU_MID_SB1       0x00020000 /* Enable SBUS device 1 arbitration */
+#define IOMMU_MID_SB0       0x00010000 /* Enable SBUS device 0 arbitration */
+#define IOMMU_MID_MID       0x0000000f /* Module-id, hardcoded to 0x8 */
+
+/* The format of an iopte in the page tables */
+#define IOPTE_PAGE          0x07ffff00 /* Physical page number (PA[30:12]) */
+#define IOPTE_CACHE         0x00000080 /* Cached (in vme IOCACHE or Viking/MXCC) */
+#define IOPTE_WRITE         0x00000004 /* Writeable */
+#define IOPTE_VALID         0x00000002 /* IOPTE is valid */
+#define IOPTE_WAZ           0x00000001 /* Write as zeros */
+
+struct iommu_struct {
+       struct iommu_regs *regs;
+       iopte_t *page_table;
+       /* For convenience */
+       unsigned long start; /* First managed virtual address */
+       unsigned long end;   /* Last managed virtual address */
+
+       struct bit_map usemap;
+};
+
+static inline void iommu_invalidate(struct iommu_regs *regs)
+{
+       regs->tlbflush = 0;
+}
+
+static inline void iommu_invalidate_page(struct iommu_regs *regs, unsigned long ba)
+{
+       regs->pageflush = (ba & PAGE_MASK);
+}
+
+#endif /* !(_SPARC_IOMMU_H) */
diff --git a/include/asm-sparc/iommu_64.h b/include/asm-sparc/iommu_64.h
new file mode 100644 (file)
index 0000000..d7b9afc
--- /dev/null
@@ -0,0 +1,62 @@
+/* iommu.h: Definitions for the sun5 IOMMU.
+ *
+ * Copyright (C) 1996, 1999, 2007 David S. Miller (davem@davemloft.net)
+ */
+#ifndef _SPARC64_IOMMU_H
+#define _SPARC64_IOMMU_H
+
+/* The format of an iopte in the page tables. */
+#define IOPTE_VALID   0x8000000000000000UL
+#define IOPTE_64K     0x2000000000000000UL
+#define IOPTE_STBUF   0x1000000000000000UL
+#define IOPTE_INTRA   0x0800000000000000UL
+#define IOPTE_CONTEXT 0x07ff800000000000UL
+#define IOPTE_PAGE    0x00007fffffffe000UL
+#define IOPTE_CACHE   0x0000000000000010UL
+#define IOPTE_WRITE   0x0000000000000002UL
+
+#define IOMMU_NUM_CTXS 4096
+
+struct iommu_arena {
+       unsigned long   *map;
+       unsigned int    hint;
+       unsigned int    limit;
+};
+
+struct iommu {
+       spinlock_t              lock;
+       struct iommu_arena      arena;
+       void                    (*flush_all)(struct iommu *);
+       iopte_t                 *page_table;
+       u32                     page_table_map_base;
+       unsigned long           iommu_control;
+       unsigned long           iommu_tsbbase;
+       unsigned long           iommu_flush;
+       unsigned long           iommu_flushinv;
+       unsigned long           iommu_tags;
+       unsigned long           iommu_ctxflush;
+       unsigned long           write_complete_reg;
+       unsigned long           dummy_page;
+       unsigned long           dummy_page_pa;
+       unsigned long           ctx_lowest_free;
+       DECLARE_BITMAP(ctx_bitmap, IOMMU_NUM_CTXS);
+       u32                     dma_addr_mask;
+};
+
+struct strbuf {
+       int                     strbuf_enabled;
+       unsigned long           strbuf_control;
+       unsigned long           strbuf_pflush;
+       unsigned long           strbuf_fsync;
+       unsigned long           strbuf_ctxflush;
+       unsigned long           strbuf_ctxmatch_base;
+       unsigned long           strbuf_flushflag_pa;
+       volatile unsigned long *strbuf_flushflag;
+       volatile unsigned long  __flushflag_buf[(64+(64-1)) / sizeof(long)];
+};
+
+extern int iommu_table_init(struct iommu *iommu, int tsbsize,
+                           u32 dma_offset, u32 dma_addr_mask,
+                           int numa_node);
+
+#endif /* !(_SPARC64_IOMMU_H) */
index 9bef02d04e4b303fd5ac08929114fcd1b937288a..037605d986e25f7c527468c67ee33330c2bce9a1 100644 (file)
@@ -1,31 +1,8 @@
-#ifndef _SPARC_IPCBUF_H
-#define _SPARC_IPCBUF_H
-
-/* 
- * The ipc64_perm structure for sparc architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 32-bit mode
- * - 32-bit seq
- * - 2 miscellaneous 64-bit values (so that this structure matches
- *                                 sparc64 ipc64_perm)
- */
-
-struct ipc64_perm
-{
-       __kernel_key_t          key;
-       __kernel_uid32_t        uid;
-       __kernel_gid32_t        gid;
-       __kernel_uid32_t        cuid;
-       __kernel_gid32_t        cgid;
-       unsigned short          __pad1;
-       __kernel_mode_t         mode;
-       unsigned short          __pad2;
-       unsigned short          seq;
-       unsigned long long      __unused1;
-       unsigned long long      __unused2;
-};
-
-#endif /* _SPARC_IPCBUF_H */
+#ifndef ___ASM_SPARC_IPCBUF_H
+#define ___ASM_SPARC_IPCBUF_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/ipcbuf_64.h>
+#else
+#include <asm-sparc/ipcbuf_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/ipcbuf_32.h b/include/asm-sparc/ipcbuf_32.h
new file mode 100644 (file)
index 0000000..6387209
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef _SPARC_IPCBUF_H
+#define _SPARC_IPCBUF_H
+
+/*
+ * The ipc64_perm structure for sparc architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode
+ * - 32-bit seq
+ * - 2 miscellaneous 64-bit values (so that this structure matches
+ *                                 sparc64 ipc64_perm)
+ */
+
+struct ipc64_perm
+{
+       __kernel_key_t          key;
+       __kernel_uid32_t        uid;
+       __kernel_gid32_t        gid;
+       __kernel_uid32_t        cuid;
+       __kernel_gid32_t        cgid;
+       unsigned short          __pad1;
+       __kernel_mode_t         mode;
+       unsigned short          __pad2;
+       unsigned short          seq;
+       unsigned long long      __unused1;
+       unsigned long long      __unused2;
+};
+
+#endif /* _SPARC_IPCBUF_H */
diff --git a/include/asm-sparc/ipcbuf_64.h b/include/asm-sparc/ipcbuf_64.h
new file mode 100644 (file)
index 0000000..a44b855
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _SPARC64_IPCBUF_H
+#define _SPARC64_IPCBUF_H
+
+/*
+ * The ipc64_perm structure for sparc64 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit seq
+ * - 2 miscellaneous 64-bit values
+ */
+
+struct ipc64_perm
+{
+       __kernel_key_t  key;
+       __kernel_uid_t  uid;
+       __kernel_gid_t  gid;
+       __kernel_uid_t  cuid;
+       __kernel_gid_t  cgid;
+       __kernel_mode_t mode;
+       unsigned short  __pad1;
+       unsigned short  seq;
+       unsigned long   __unused1;
+       unsigned long   __unused2;
+};
+
+#endif /* _SPARC64_IPCBUF_H */
index fe205cc444b889619e82612ac3ba7ed00302035a..7af6bb4aa09c8043c68f42fb7ae1a620afc61d57 100644 (file)
@@ -1,15 +1,8 @@
-/* irq.h: IRQ registers on the Sparc.
- *
- * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
- */
-
-#ifndef _SPARC_IRQ_H
-#define _SPARC_IRQ_H
-
-#include <linux/interrupt.h>
-
-#define NR_IRQS    16
-
-#define irq_canonicalize(irq)  (irq)
-
+#ifndef ___ASM_SPARC_IRQ_H
+#define ___ASM_SPARC_IRQ_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/irq_64.h>
+#else
+#include <asm-sparc/irq_32.h>
+#endif
 #endif
diff --git a/include/asm-sparc/irq_32.h b/include/asm-sparc/irq_32.h
new file mode 100644 (file)
index 0000000..fe205cc
--- /dev/null
@@ -0,0 +1,15 @@
+/* irq.h: IRQ registers on the Sparc.
+ *
+ * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
+ */
+
+#ifndef _SPARC_IRQ_H
+#define _SPARC_IRQ_H
+
+#include <linux/interrupt.h>
+
+#define NR_IRQS    16
+
+#define irq_canonicalize(irq)  (irq)
+
+#endif
diff --git a/include/asm-sparc/irq_64.h b/include/asm-sparc/irq_64.h
new file mode 100644 (file)
index 0000000..0bb9bf5
--- /dev/null
@@ -0,0 +1,93 @@
+/* irq.h: IRQ registers on the 64-bit Sparc.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
+ */
+
+#ifndef _SPARC64_IRQ_H
+#define _SPARC64_IRQ_H
+
+#include <linux/linkage.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <asm/pil.h>
+#include <asm/ptrace.h>
+
+/* IMAP/ICLR register defines */
+#define IMAP_VALID             0x80000000UL    /* IRQ Enabled          */
+#define IMAP_TID_UPA           0x7c000000UL    /* UPA TargetID         */
+#define IMAP_TID_JBUS          0x7c000000UL    /* JBUS TargetID        */
+#define IMAP_TID_SHIFT         26
+#define IMAP_AID_SAFARI                0x7c000000UL    /* Safari AgentID       */
+#define IMAP_AID_SHIFT         26
+#define IMAP_NID_SAFARI                0x03e00000UL    /* Safari NodeID        */
+#define IMAP_NID_SHIFT         21
+#define IMAP_IGN               0x000007c0UL    /* IRQ Group Number     */
+#define IMAP_INO               0x0000003fUL    /* IRQ Number           */
+#define IMAP_INR               0x000007ffUL    /* Full interrupt number*/
+
+#define ICLR_IDLE              0x00000000UL    /* Idle state           */
+#define ICLR_TRANSMIT          0x00000001UL    /* Transmit state       */
+#define ICLR_PENDING           0x00000003UL    /* Pending state        */
+
+/* The largest number of unique interrupt sources we support.
+ * If this needs to ever be larger than 255, you need to change
+ * the type of ino_bucket->virt_irq as appropriate.
+ *
+ * ino_bucket->virt_irq allocation is made during {sun4v_,}build_irq().
+ */
+#define NR_IRQS    255
+
+extern void irq_install_pre_handler(int virt_irq,
+                                   void (*func)(unsigned int, void *, void *),
+                                   void *arg1, void *arg2);
+#define irq_canonicalize(irq)  (irq)
+extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap);
+extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino);
+extern unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino);
+extern unsigned int sun4v_build_msi(u32 devhandle, unsigned int *virt_irq_p,
+                                   unsigned int msi_devino_start,
+                                   unsigned int msi_devino_end);
+extern void sun4v_destroy_msi(unsigned int virt_irq);
+extern unsigned int sun4u_build_msi(u32 portid, unsigned int *virt_irq_p,
+                                   unsigned int msi_devino_start,
+                                   unsigned int msi_devino_end,
+                                   unsigned long imap_base,
+                                   unsigned long iclr_base);
+extern void sun4u_destroy_msi(unsigned int virt_irq);
+extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);
+
+extern unsigned char virt_irq_alloc(unsigned int dev_handle,
+                                   unsigned int dev_ino);
+#ifdef CONFIG_PCI_MSI
+extern void virt_irq_free(unsigned int virt_irq);
+#endif
+
+extern void __init init_IRQ(void);
+extern void fixup_irqs(void);
+
+static inline void set_softint(unsigned long bits)
+{
+       __asm__ __volatile__("wr        %0, 0x0, %%set_softint"
+                            : /* No outputs */
+                            : "r" (bits));
+}
+
+static inline void clear_softint(unsigned long bits)
+{
+       __asm__ __volatile__("wr        %0, 0x0, %%clear_softint"
+                            : /* No outputs */
+                            : "r" (bits));
+}
+
+static inline unsigned long get_softint(void)
+{
+       unsigned long retval;
+
+       __asm__ __volatile__("rd        %%softint, %0"
+                            : "=r" (retval));
+       return retval;
+}
+
+#endif
index db398fb328263051be401e0e0aabb97fcdf2a77f..c6402b187e23cca383976e3beacc6bafd8968919 100644 (file)
@@ -1,39 +1,8 @@
-/*
- * include/asm-sparc/irqflags.h
- *
- * IRQ flags handling
- *
- * This file gets included from lowlevel asm headers too, to provide
- * wrapped versions of the local_irq_*() APIs, based on the
- * raw_local_irq_*() functions from the lowlevel headers.
- */
-#ifndef _ASM_IRQFLAGS_H
-#define _ASM_IRQFLAGS_H
-
-#ifndef __ASSEMBLY__
-
-extern void raw_local_irq_restore(unsigned long);
-extern unsigned long __raw_local_irq_save(void);
-extern void raw_local_irq_enable(void);
-
-static inline unsigned long getipl(void)
-{
-        unsigned long retval;
-
-        __asm__ __volatile__("rd        %%psr, %0" : "=r" (retval));
-        return retval;
-}
-
-#define raw_local_save_flags(flags) ((flags) = getipl())
-#define raw_local_irq_save(flags)   ((flags) = __raw_local_irq_save())
-#define raw_local_irq_disable()     ((void) __raw_local_irq_save())
-#define raw_irqs_disabled()         ((getipl() & PSR_PIL) != 0)
-
-static inline int raw_irqs_disabled_flags(unsigned long flags)
-{
-        return ((flags & PSR_PIL) != 0);
-}
-
-#endif /* (__ASSEMBLY__) */
-
-#endif /* !(_ASM_IRQFLAGS_H) */
+#ifndef ___ASM_SPARC_IRQFLAGS_H
+#define ___ASM_SPARC_IRQFLAGS_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/irqflags_64.h>
+#else
+#include <asm-sparc/irqflags_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/irqflags_32.h b/include/asm-sparc/irqflags_32.h
new file mode 100644 (file)
index 0000000..db398fb
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * include/asm-sparc/irqflags.h
+ *
+ * IRQ flags handling
+ *
+ * This file gets included from lowlevel asm headers too, to provide
+ * wrapped versions of the local_irq_*() APIs, based on the
+ * raw_local_irq_*() functions from the lowlevel headers.
+ */
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+#ifndef __ASSEMBLY__
+
+extern void raw_local_irq_restore(unsigned long);
+extern unsigned long __raw_local_irq_save(void);
+extern void raw_local_irq_enable(void);
+
+static inline unsigned long getipl(void)
+{
+        unsigned long retval;
+
+        __asm__ __volatile__("rd        %%psr, %0" : "=r" (retval));
+        return retval;
+}
+
+#define raw_local_save_flags(flags) ((flags) = getipl())
+#define raw_local_irq_save(flags)   ((flags) = __raw_local_irq_save())
+#define raw_local_irq_disable()     ((void) __raw_local_irq_save())
+#define raw_irqs_disabled()         ((getipl() & PSR_PIL) != 0)
+
+static inline int raw_irqs_disabled_flags(unsigned long flags)
+{
+        return ((flags & PSR_PIL) != 0);
+}
+
+#endif /* (__ASSEMBLY__) */
+
+#endif /* !(_ASM_IRQFLAGS_H) */
diff --git a/include/asm-sparc/irqflags_64.h b/include/asm-sparc/irqflags_64.h
new file mode 100644 (file)
index 0000000..024fc54
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * include/asm-sparc64/irqflags.h
+ *
+ * IRQ flags handling
+ *
+ * This file gets included from lowlevel asm headers too, to provide
+ * wrapped versions of the local_irq_*() APIs, based on the
+ * raw_local_irq_*() functions from the lowlevel headers.
+ */
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+#ifndef __ASSEMBLY__
+
+static inline unsigned long __raw_local_save_flags(void)
+{
+       unsigned long flags;
+
+       __asm__ __volatile__(
+               "rdpr   %%pil, %0"
+               : "=r" (flags)
+       );
+
+       return flags;
+}
+
+#define raw_local_save_flags(flags) \
+               do { (flags) = __raw_local_save_flags(); } while (0)
+
+static inline void raw_local_irq_restore(unsigned long flags)
+{
+       __asm__ __volatile__(
+               "wrpr   %0, %%pil"
+               : /* no output */
+               : "r" (flags)
+               : "memory"
+       );
+}
+
+static inline void raw_local_irq_disable(void)
+{
+       __asm__ __volatile__(
+               "wrpr   15, %%pil"
+               : /* no outputs */
+               : /* no inputs */
+               : "memory"
+       );
+}
+
+static inline void raw_local_irq_enable(void)
+{
+       __asm__ __volatile__(
+               "wrpr   0, %%pil"
+               : /* no outputs */
+               : /* no inputs */
+               : "memory"
+       );
+}
+
+static inline int raw_irqs_disabled_flags(unsigned long flags)
+{
+       return (flags > 0);
+}
+
+static inline int raw_irqs_disabled(void)
+{
+       unsigned long flags = __raw_local_save_flags();
+
+       return raw_irqs_disabled_flags(flags);
+}
+
+/*
+ * For spinlocks, etc:
+ */
+static inline unsigned long __raw_local_irq_save(void)
+{
+       unsigned long flags = __raw_local_save_flags();
+
+       raw_local_irq_disable();
+
+       return flags;
+}
+
+#define raw_local_irq_save(flags) \
+               do { (flags) = __raw_local_irq_save(); } while (0)
+
+#endif /* (__ASSEMBLY__) */
+
+#endif /* !(_ASM_IRQFLAGS_H) */
index f69fe7d84b3c046a01c0f6740c0c3b72d1eb3374..fe07d00d0534424d0d295341f60ba59cd72e3510 100644 (file)
@@ -1,73 +1,8 @@
-/*
- * kdebug.h:  Defines and definitions for debugging the Linux kernel
- *            under various kernel debuggers.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-#ifndef _SPARC_KDEBUG_H
-#define _SPARC_KDEBUG_H
-
-#include <asm/openprom.h>
-#include <asm/vaddrs.h>
-
-/* Breakpoints are enter through trap table entry 126.  So in sparc assembly
- * if you want to drop into the debugger you do:
- *
- * t DEBUG_BP_TRAP
- */
-
-#define DEBUG_BP_TRAP     126
-
-#ifndef __ASSEMBLY__
-/* The debug vector is passed in %o1 at boot time.  It is a pointer to
- * a structure in the debuggers address space.  Here is its format.
- */
-
-typedef unsigned int (*debugger_funct)(void);
-
-struct kernel_debug {
-       /* First the entry point into the debugger.  You jump here
-        * to give control over to the debugger.
-        */
-       unsigned long kdebug_entry;
-       unsigned long kdebug_trapme;   /* Figure out later... */
-       /* The following is the number of pages that the debugger has
-        * taken from to total pool.
-        */
-       unsigned long *kdebug_stolen_pages;
-       /* Ok, after you remap yourself and/or change the trap table
-        * from what you were left with at boot time you have to call
-        * this synchronization function so the debugger can check out
-        * what you have done.
-        */
-       debugger_funct teach_debugger;
-}; /* I think that is it... */
-
-extern struct kernel_debug *linux_dbvec;
-
-/* Use this macro in C-code to enter the debugger. */
-static inline void sp_enter_debugger(void)
-{
-       __asm__ __volatile__("jmpl %0, %%o7\n\t"
-                            "nop\n\t" : :
-                            "r" (linux_dbvec) : "o7", "memory");
-}
-
-#define SP_ENTER_DEBUGGER do { \
-            if((linux_dbvec!=0) && ((*(short *)linux_dbvec)!=-1)) \
-              sp_enter_debugger(); \
-                      } while(0)
-
-enum die_val {
-       DIE_UNUSED,
-};
-
-#endif /* !(__ASSEMBLY__) */
-
-/* Some nice offset defines for assembler code. */
-#define KDEBUG_ENTRY_OFF    0x0
-#define KDEBUG_DUNNO_OFF    0x4
-#define KDEBUG_DUNNO2_OFF   0x8
-#define KDEBUG_TEACH_OFF    0xc
-
-#endif /* !(_SPARC_KDEBUG_H) */
+#ifndef ___ASM_SPARC_KDEBUG_H
+#define ___ASM_SPARC_KDEBUG_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/kdebug_64.h>
+#else
+#include <asm-sparc/kdebug_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/kdebug_32.h b/include/asm-sparc/kdebug_32.h
new file mode 100644 (file)
index 0000000..f69fe7d
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * kdebug.h:  Defines and definitions for debugging the Linux kernel
+ *            under various kernel debuggers.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC_KDEBUG_H
+#define _SPARC_KDEBUG_H
+
+#include <asm/openprom.h>
+#include <asm/vaddrs.h>
+
+/* Breakpoints are enter through trap table entry 126.  So in sparc assembly
+ * if you want to drop into the debugger you do:
+ *
+ * t DEBUG_BP_TRAP
+ */
+
+#define DEBUG_BP_TRAP     126
+
+#ifndef __ASSEMBLY__
+/* The debug vector is passed in %o1 at boot time.  It is a pointer to
+ * a structure in the debuggers address space.  Here is its format.
+ */
+
+typedef unsigned int (*debugger_funct)(void);
+
+struct kernel_debug {
+       /* First the entry point into the debugger.  You jump here
+        * to give control over to the debugger.
+        */
+       unsigned long kdebug_entry;
+       unsigned long kdebug_trapme;   /* Figure out later... */
+       /* The following is the number of pages that the debugger has
+        * taken from to total pool.
+        */
+       unsigned long *kdebug_stolen_pages;
+       /* Ok, after you remap yourself and/or change the trap table
+        * from what you were left with at boot time you have to call
+        * this synchronization function so the debugger can check out
+        * what you have done.
+        */
+       debugger_funct teach_debugger;
+}; /* I think that is it... */
+
+extern struct kernel_debug *linux_dbvec;
+
+/* Use this macro in C-code to enter the debugger. */
+static inline void sp_enter_debugger(void)
+{
+       __asm__ __volatile__("jmpl %0, %%o7\n\t"
+                            "nop\n\t" : :
+                            "r" (linux_dbvec) : "o7", "memory");
+}
+
+#define SP_ENTER_DEBUGGER do { \
+            if((linux_dbvec!=0) && ((*(short *)linux_dbvec)!=-1)) \
+              sp_enter_debugger(); \
+                      } while(0)
+
+enum die_val {
+       DIE_UNUSED,
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+/* Some nice offset defines for assembler code. */
+#define KDEBUG_ENTRY_OFF    0x0
+#define KDEBUG_DUNNO_OFF    0x4
+#define KDEBUG_DUNNO2_OFF   0x8
+#define KDEBUG_TEACH_OFF    0xc
+
+#endif /* !(_SPARC_KDEBUG_H) */
diff --git a/include/asm-sparc/kdebug_64.h b/include/asm-sparc/kdebug_64.h
new file mode 100644 (file)
index 0000000..f905b77
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _SPARC64_KDEBUG_H
+#define _SPARC64_KDEBUG_H
+
+struct pt_regs;
+
+extern void bad_trap(struct pt_regs *, long);
+
+/* Grossly misnamed. */
+enum die_val {
+       DIE_OOPS = 1,
+       DIE_DEBUG,      /* ta 0x70 */
+       DIE_DEBUG_2,    /* ta 0x71 */
+       DIE_DIE,
+       DIE_TRAP,
+       DIE_TRAP_TL1,
+       DIE_CALL,
+};
+
+#endif
index e215f7104974fb76957d66695185f9e925edc519..602f5e034f7a48afd0d85af3f72e2fbfd382d9d4 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef _ASM_KMAP_TYPES_H
 #define _ASM_KMAP_TYPES_H
 
+/* Dummy header just to define km_type.  None of this
+ * is actually used on sparc.  -DaveM
+ */
+
 enum km_type {
        KM_BOUNCE_READ,
        KM_SKB_SUNRPC_DATA,
diff --git a/include/asm-sparc/kprobes.h b/include/asm-sparc/kprobes.h
new file mode 100644 (file)
index 0000000..5879d71
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef _SPARC64_KPROBES_H
+#define _SPARC64_KPROBES_H
+
+#include <linux/types.h>
+#include <linux/percpu.h>
+
+typedef u32 kprobe_opcode_t;
+
+#define BREAKPOINT_INSTRUCTION   0x91d02070 /* ta 0x70 */
+#define BREAKPOINT_INSTRUCTION_2 0x91d02071 /* ta 0x71 */
+#define MAX_INSN_SIZE 2
+
+#define kretprobe_blacklist_size 0
+
+#define arch_remove_kprobe(p)  do {} while (0)
+
+#define flush_insn_slot(p)             \
+do {   flushi(&(p)->ainsn.insn[0]);    \
+       flushi(&(p)->ainsn.insn[1]);    \
+} while (0)
+
+void kretprobe_trampoline(void);
+
+/* Architecture specific copy of original instruction*/
+struct arch_specific_insn {
+       /* copy of the original instruction */
+       kprobe_opcode_t insn[MAX_INSN_SIZE];
+};
+
+struct prev_kprobe {
+       struct kprobe *kp;
+       unsigned long status;
+       unsigned long orig_tnpc;
+       unsigned long orig_tstate_pil;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+       unsigned long kprobe_status;
+       unsigned long kprobe_orig_tnpc;
+       unsigned long kprobe_orig_tstate_pil;
+       struct pt_regs jprobe_saved_regs;
+       struct prev_kprobe prev_kprobe;
+};
+
+extern int kprobe_exceptions_notify(struct notifier_block *self,
+                                   unsigned long val, void *data);
+extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
+#endif /* _SPARC64_KPROBES_H */
diff --git a/include/asm-sparc/ldc.h b/include/asm-sparc/ldc.h
new file mode 100644 (file)
index 0000000..bdb524a
--- /dev/null
@@ -0,0 +1,138 @@
+#ifndef _SPARC64_LDC_H
+#define _SPARC64_LDC_H
+
+#include <asm/hypervisor.h>
+
+extern int ldom_domaining_enabled;
+extern void ldom_set_var(const char *var, const char *value);
+extern void ldom_reboot(const char *boot_command);
+extern void ldom_power_off(void);
+
+/* The event handler will be evoked when link state changes
+ * or data becomes available on the receive side.
+ *
+ * For non-RAW links, if the LDC_EVENT_RESET event arrives the
+ * driver should reset all of it's internal state and reinvoke
+ * ldc_connect() to try and bring the link up again.
+ *
+ * For RAW links, ldc_connect() is not used.  Instead the driver
+ * just waits for the LDC_EVENT_UP event.
+ */
+struct ldc_channel_config {
+       void (*event)(void *arg, int event);
+
+       u32                     mtu;
+       unsigned int            rx_irq;
+       unsigned int            tx_irq;
+       u8                      mode;
+#define LDC_MODE_RAW           0x00
+#define LDC_MODE_UNRELIABLE    0x01
+#define LDC_MODE_RESERVED      0x02
+#define LDC_MODE_STREAM                0x03
+
+       u8                      debug;
+#define LDC_DEBUG_HS           0x01
+#define LDC_DEBUG_STATE                0x02
+#define LDC_DEBUG_RX           0x04
+#define LDC_DEBUG_TX           0x08
+#define LDC_DEBUG_DATA         0x10
+};
+
+#define LDC_EVENT_RESET                0x01
+#define LDC_EVENT_UP           0x02
+#define LDC_EVENT_DATA_READY   0x04
+
+#define LDC_STATE_INVALID      0x00
+#define LDC_STATE_INIT         0x01
+#define LDC_STATE_BOUND                0x02
+#define LDC_STATE_READY                0x03
+#define LDC_STATE_CONNECTED    0x04
+
+struct ldc_channel;
+
+/* Allocate state for a channel.  */
+extern struct ldc_channel *ldc_alloc(unsigned long id,
+                                    const struct ldc_channel_config *cfgp,
+                                    void *event_arg);
+
+/* Shut down and free state for a channel.  */
+extern void ldc_free(struct ldc_channel *lp);
+
+/* Register TX and RX queues of the link with the hypervisor.  */
+extern int ldc_bind(struct ldc_channel *lp, const char *name);
+
+/* For non-RAW protocols we need to complete a handshake before
+ * communication can proceed.  ldc_connect() does that, if the
+ * handshake completes successfully, an LDC_EVENT_UP event will
+ * be sent up to the driver.
+ */
+extern int ldc_connect(struct ldc_channel *lp);
+extern int ldc_disconnect(struct ldc_channel *lp);
+
+extern int ldc_state(struct ldc_channel *lp);
+
+/* Read and write operations.  Only valid when the link is up.  */
+extern int ldc_write(struct ldc_channel *lp, const void *buf,
+                    unsigned int size);
+extern int ldc_read(struct ldc_channel *lp, void *buf, unsigned int size);
+
+#define LDC_MAP_SHADOW 0x01
+#define LDC_MAP_DIRECT 0x02
+#define LDC_MAP_IO     0x04
+#define LDC_MAP_R      0x08
+#define LDC_MAP_W      0x10
+#define LDC_MAP_X      0x20
+#define LDC_MAP_RW     (LDC_MAP_R | LDC_MAP_W)
+#define LDC_MAP_RWX    (LDC_MAP_R | LDC_MAP_W | LDC_MAP_X)
+#define LDC_MAP_ALL    0x03f
+
+struct ldc_trans_cookie {
+       u64                     cookie_addr;
+       u64                     cookie_size;
+};
+
+struct scatterlist;
+extern int ldc_map_sg(struct ldc_channel *lp,
+                     struct scatterlist *sg, int num_sg,
+                     struct ldc_trans_cookie *cookies, int ncookies,
+                     unsigned int map_perm);
+
+extern int ldc_map_single(struct ldc_channel *lp,
+                         void *buf, unsigned int len,
+                         struct ldc_trans_cookie *cookies, int ncookies,
+                         unsigned int map_perm);
+
+extern void ldc_unmap(struct ldc_channel *lp, struct ldc_trans_cookie *cookies,
+                     int ncookies);
+
+extern int ldc_copy(struct ldc_channel *lp, int copy_dir,
+                   void *buf, unsigned int len, unsigned long offset,
+                   struct ldc_trans_cookie *cookies, int ncookies);
+
+static inline int ldc_get_dring_entry(struct ldc_channel *lp,
+                                     void *buf, unsigned int len,
+                                     unsigned long offset,
+                                     struct ldc_trans_cookie *cookies,
+                                     int ncookies)
+{
+       return ldc_copy(lp, LDC_COPY_IN, buf, len, offset, cookies, ncookies);
+}
+
+static inline int ldc_put_dring_entry(struct ldc_channel *lp,
+                                     void *buf, unsigned int len,
+                                     unsigned long offset,
+                                     struct ldc_trans_cookie *cookies,
+                                     int ncookies)
+{
+       return ldc_copy(lp, LDC_COPY_OUT, buf, len, offset, cookies, ncookies);
+}
+
+extern void *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len,
+                                struct ldc_trans_cookie *cookies,
+                                int *ncookies, unsigned int map_perm);
+
+extern void ldc_free_exp_dring(struct ldc_channel *lp, void *buf,
+                              unsigned int len,
+                              struct ldc_trans_cookie *cookies, int ncookies);
+
+#endif /* _SPARC64_LDC_H */
diff --git a/include/asm-sparc/lmb.h b/include/asm-sparc/lmb.h
new file mode 100644 (file)
index 0000000..6a352cb
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _SPARC64_LMB_H
+#define _SPARC64_LMB_H
+
+#include <asm/oplib.h>
+
+#define LMB_DBG(fmt...) prom_printf(fmt)
+
+#define LMB_REAL_LIMIT 0
+
+#endif /* !(_SPARC64_LMB_H) */
diff --git a/include/asm-sparc/lsu.h b/include/asm-sparc/lsu.h
new file mode 100644 (file)
index 0000000..7190f8d
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _SPARC64_LSU_H
+#define _SPARC64_LSU_H
+
+#include <linux/const.h>
+
+/* LSU Control Register */
+#define LSU_CONTROL_PM _AC(0x000001fe00000000,UL) /* Phys-watchpoint byte mask*/
+#define LSU_CONTROL_VM _AC(0x00000001fe000000,UL) /* Virt-watchpoint byte mask*/
+#define LSU_CONTROL_PR _AC(0x0000000001000000,UL) /* Phys-rd watchpoint enable*/
+#define LSU_CONTROL_PW _AC(0x0000000000800000,UL) /* Phys-wr watchpoint enable*/
+#define LSU_CONTROL_VR _AC(0x0000000000400000,UL) /* Virt-rd watchpoint enable*/
+#define LSU_CONTROL_VW _AC(0x0000000000200000,UL) /* Virt-wr watchpoint enable*/
+#define LSU_CONTROL_FM _AC(0x00000000000ffff0,UL) /* Parity mask enables.     */
+#define LSU_CONTROL_DM _AC(0x0000000000000008,UL) /* Data MMU enable.         */
+#define LSU_CONTROL_IM _AC(0x0000000000000004,UL) /* Instruction MMU enable.  */
+#define LSU_CONTROL_DC _AC(0x0000000000000002,UL) /* Data cache enable.       */
+#define LSU_CONTROL_IC _AC(0x0000000000000001,UL) /* Instruction cache enable.*/
+
+#endif /* !(_SPARC64_LSU_H) */
index d6c6bf836206fa584bc8e8ce10405c6e08c04d6e..c28c2f2487940436f97b45073683fa4ab57cc8b4 100644 (file)
@@ -17,8 +17,6 @@ struct Sun_Machine_Models {
  */
 #define NUM_SUN_MACHINES   15
 
-extern struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES];
-
 /* The machine type in the idprom area looks like this:
  *
  * ---------------
index bb5ae614b166fa4a80e1dfa006d19fe494331e4f..69f07a022ee6c3d21078e3dc34bd72612c4e8949 100644 (file)
@@ -43,8 +43,6 @@ extern unsigned int viking_rev, swift_rev, cypress_rev;
 #define HWBUG_SUPERSCALAR_BAD        0x00000080
 #define HWBUG_PACINIT_BITROT         0x00000100
 
-extern unsigned int hwbug_bitmask;
-
 /* First the module type values. To find out which you have, just load
  * the mmu control register from ASI_M_MMUREG alternate address space and
  * shift the value right 28 bits.
index fa7eac9265825e7cd7ccb1f38ec1a64015df967a..9ab65c21e9e43233b2c9c925438bf4c8f1cceba7 100644 (file)
@@ -1,29 +1,8 @@
-/*
- * Machine dependent access functions for RTC registers.
- */
-#ifndef __ASM_SPARC_MC146818RTC_H
-#define __ASM_SPARC_MC146818RTC_H
-
-#include <asm/io.h>
-
-#ifndef RTC_PORT
-#define RTC_PORT(x)    (0x70 + (x))
-#define RTC_ALWAYS_BCD 1       /* RTC operates in binary mode */
+#ifndef ___ASM_SPARC_MC146818RTC_H
+#define ___ASM_SPARC_MC146818RTC_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/mc146818rtc_64.h>
+#else
+#include <asm-sparc/mc146818rtc_32.h>
+#endif
 #endif
-
-/*
- * The yet supported machines all access the RTC index register via
- * an ISA port access but the way to access the date register differs ...
- */
-#define CMOS_READ(addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-inb_p(RTC_PORT(1)); \
-})
-#define CMOS_WRITE(val, addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-outb_p((val),RTC_PORT(1)); \
-})
-
-#define RTC_IRQ 8
-
-#endif /* __ASM_SPARC_MC146818RTC_H */
diff --git a/include/asm-sparc/mc146818rtc_32.h b/include/asm-sparc/mc146818rtc_32.h
new file mode 100644 (file)
index 0000000..fa7eac9
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef __ASM_SPARC_MC146818RTC_H
+#define __ASM_SPARC_MC146818RTC_H
+
+#include <asm/io.h>
+
+#ifndef RTC_PORT
+#define RTC_PORT(x)    (0x70 + (x))
+#define RTC_ALWAYS_BCD 1       /* RTC operates in binary mode */
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#define RTC_IRQ 8
+
+#endif /* __ASM_SPARC_MC146818RTC_H */
diff --git a/include/asm-sparc/mc146818rtc_64.h b/include/asm-sparc/mc146818rtc_64.h
new file mode 100644 (file)
index 0000000..e9c0fcc
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef __ASM_SPARC64_MC146818RTC_H
+#define __ASM_SPARC64_MC146818RTC_H
+
+#include <asm/io.h>
+
+#ifndef RTC_PORT
+#ifdef CONFIG_PCI
+extern unsigned long ds1287_regs;
+#else
+#define ds1287_regs (0UL)
+#endif
+#define RTC_PORT(x)    (ds1287_regs + (x))
+#define RTC_ALWAYS_BCD 0
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#define RTC_IRQ 8
+
+#endif /* __ASM_SPARC64_MC146818RTC_H */
diff --git a/include/asm-sparc/mdesc.h b/include/asm-sparc/mdesc.h
new file mode 100644 (file)
index 0000000..1acc727
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef _SPARC64_MDESC_H
+#define _SPARC64_MDESC_H
+
+#include <linux/types.h>
+#include <linux/cpumask.h>
+#include <asm/prom.h>
+
+struct mdesc_handle;
+
+/* Machine description operations are to be surrounded by grab and
+ * release calls.  The mdesc_handle returned from the grab is
+ * the first argument to all of the operational calls that work
+ * on mdescs.
+ */
+extern struct mdesc_handle *mdesc_grab(void);
+extern void mdesc_release(struct mdesc_handle *);
+
+#define MDESC_NODE_NULL                (~(u64)0)
+
+extern u64 mdesc_node_by_name(struct mdesc_handle *handle,
+                             u64 from_node, const char *name);
+#define mdesc_for_each_node_by_name(__hdl, __node, __name) \
+       for (__node = mdesc_node_by_name(__hdl, MDESC_NODE_NULL, __name); \
+            (__node) != MDESC_NODE_NULL; \
+            __node = mdesc_node_by_name(__hdl, __node, __name))
+
+/* Access to property values returned from mdesc_get_property() are
+ * only valid inside of a mdesc_grab()/mdesc_release() sequence.
+ * Once mdesc_release() is called, the memory backed up by these
+ * pointers may reference freed up memory.
+ *
+ * Therefore callers must make copies of any property values
+ * they need.
+ *
+ * These same rules apply to mdesc_node_name().
+ */
+extern const void *mdesc_get_property(struct mdesc_handle *handle,
+                                     u64 node, const char *name, int *lenp);
+extern const char *mdesc_node_name(struct mdesc_handle *hp, u64 node);
+
+/* MD arc iteration, the standard sequence is:
+ *
+ *     unsigned long arc;
+ *     mdesc_for_each_arc(arc, handle, node, MDESC_ARC_TYPE_{FWD,BACK}) {
+ *             unsigned long target = mdesc_arc_target(handle, arc);
+ *             ...
+ *     }
+ */
+
+#define MDESC_ARC_TYPE_FWD     "fwd"
+#define MDESC_ARC_TYPE_BACK    "back"
+
+extern u64 mdesc_next_arc(struct mdesc_handle *handle, u64 from,
+                         const char *arc_type);
+#define mdesc_for_each_arc(__arc, __hdl, __node, __type) \
+       for (__arc = mdesc_next_arc(__hdl, __node, __type); \
+            (__arc) != MDESC_NODE_NULL; \
+            __arc = mdesc_next_arc(__hdl, __arc, __type))
+
+extern u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc);
+
+extern void mdesc_update(void);
+
+struct mdesc_notifier_client {
+       void (*add)(struct mdesc_handle *handle, u64 node);
+       void (*remove)(struct mdesc_handle *handle, u64 node);
+
+       const char                      *node_name;
+       struct mdesc_notifier_client    *next;
+};
+
+extern void mdesc_register_notifier(struct mdesc_notifier_client *client);
+
+extern void mdesc_fill_in_cpu_data(cpumask_t mask);
+
+extern void sun4v_mdesc_init(void);
+
+#endif
index ccd36d26615a7c12abc6ec328e2295152038f833..ee66bf6dcbd6b1deefbc8a2b90dc5f65d2385827 100644 (file)
@@ -1,7 +1,8 @@
-#ifndef __MMU_H
-#define __MMU_H
-
-/* Default "unsigned long" context */
-typedef unsigned long mm_context_t;
-
+#ifndef ___ASM_SPARC_MMU_H
+#define ___ASM_SPARC_MMU_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/mmu_64.h>
+#else
+#include <asm-sparc/mmu_32.h>
+#endif
 #endif
diff --git a/include/asm-sparc/mmu_32.h b/include/asm-sparc/mmu_32.h
new file mode 100644 (file)
index 0000000..ccd36d2
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __MMU_H
+#define __MMU_H
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
+
+#endif
diff --git a/include/asm-sparc/mmu_64.h b/include/asm-sparc/mmu_64.h
new file mode 100644 (file)
index 0000000..9067dc5
--- /dev/null
@@ -0,0 +1,123 @@
+#ifndef __MMU_H
+#define __MMU_H
+
+#include <linux/const.h>
+#include <asm/page.h>
+#include <asm/hypervisor.h>
+
+#define CTX_NR_BITS            13
+
+#define TAG_CONTEXT_BITS       ((_AC(1,UL) << CTX_NR_BITS) - _AC(1,UL))
+
+/* UltraSPARC-III+ and later have a feature whereby you can
+ * select what page size the various Data-TLB instances in the
+ * chip.  In order to gracefully support this, we put the version
+ * field in a spot outside of the areas of the context register
+ * where this parameter is specified.
+ */
+#define CTX_VERSION_SHIFT      22
+#define CTX_VERSION_MASK       ((~0UL) << CTX_VERSION_SHIFT)
+
+#define CTX_PGSZ_8KB           _AC(0x0,UL)
+#define CTX_PGSZ_64KB          _AC(0x1,UL)
+#define CTX_PGSZ_512KB         _AC(0x2,UL)
+#define CTX_PGSZ_4MB           _AC(0x3,UL)
+#define CTX_PGSZ_BITS          _AC(0x7,UL)
+#define CTX_PGSZ0_NUC_SHIFT    61
+#define CTX_PGSZ1_NUC_SHIFT    58
+#define CTX_PGSZ0_SHIFT                16
+#define CTX_PGSZ1_SHIFT                19
+#define CTX_PGSZ_MASK          ((CTX_PGSZ_BITS << CTX_PGSZ0_SHIFT) | \
+                                (CTX_PGSZ_BITS << CTX_PGSZ1_SHIFT))
+
+#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
+#define CTX_PGSZ_BASE  CTX_PGSZ_8KB
+#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
+#define CTX_PGSZ_BASE  CTX_PGSZ_64KB
+#else
+#error No page size specified in kernel configuration
+#endif
+
+#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
+#define CTX_PGSZ_HUGE          CTX_PGSZ_4MB
+#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
+#define CTX_PGSZ_HUGE          CTX_PGSZ_512KB
+#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
+#define CTX_PGSZ_HUGE          CTX_PGSZ_64KB
+#endif
+
+#define CTX_PGSZ_KERN  CTX_PGSZ_4MB
+
+/* Thus, when running on UltraSPARC-III+ and later, we use the following
+ * PRIMARY_CONTEXT register values for the kernel context.
+ */
+#define CTX_CHEETAH_PLUS_NUC \
+       ((CTX_PGSZ_KERN << CTX_PGSZ0_NUC_SHIFT) | \
+        (CTX_PGSZ_BASE << CTX_PGSZ1_NUC_SHIFT))
+
+#define CTX_CHEETAH_PLUS_CTX0 \
+       ((CTX_PGSZ_KERN << CTX_PGSZ0_SHIFT) | \
+        (CTX_PGSZ_BASE << CTX_PGSZ1_SHIFT))
+
+/* If you want "the TLB context number" use CTX_NR_MASK.  If you
+ * want "the bits I program into the context registers" use
+ * CTX_HW_MASK.
+ */
+#define CTX_NR_MASK            TAG_CONTEXT_BITS
+#define CTX_HW_MASK            (CTX_NR_MASK | CTX_PGSZ_MASK)
+
+#define CTX_FIRST_VERSION      ((_AC(1,UL) << CTX_VERSION_SHIFT) + _AC(1,UL))
+#define CTX_VALID(__ctx)       \
+        (!(((__ctx.sparc64_ctx_val) ^ tlb_context_cache) & CTX_VERSION_MASK))
+#define CTX_HWBITS(__ctx)      ((__ctx.sparc64_ctx_val) & CTX_HW_MASK)
+#define CTX_NRBITS(__ctx)      ((__ctx.sparc64_ctx_val) & CTX_NR_MASK)
+
+#ifndef __ASSEMBLY__
+
+#define TSB_ENTRY_ALIGNMENT    16
+
+struct tsb {
+       unsigned long tag;
+       unsigned long pte;
+} __attribute__((aligned(TSB_ENTRY_ALIGNMENT)));
+
+extern void __tsb_insert(unsigned long ent, unsigned long tag, unsigned long pte);
+extern void tsb_flush(unsigned long ent, unsigned long tag);
+extern void tsb_init(struct tsb *tsb, unsigned long size);
+
+struct tsb_config {
+       struct tsb              *tsb;
+       unsigned long           tsb_rss_limit;
+       unsigned long           tsb_nentries;
+       unsigned long           tsb_reg_val;
+       unsigned long           tsb_map_vaddr;
+       unsigned long           tsb_map_pte;
+};
+
+#define MM_TSB_BASE    0
+
+#ifdef CONFIG_HUGETLB_PAGE
+#define MM_TSB_HUGE    1
+#define MM_NUM_TSBS    2
+#else
+#define MM_NUM_TSBS    1
+#endif
+
+typedef struct {
+       spinlock_t              lock;
+       unsigned long           sparc64_ctx_val;
+       unsigned long           huge_pte_count;
+       struct tsb_config       tsb_block[MM_NUM_TSBS];
+       struct hv_tsb_descr     tsb_descr[MM_NUM_TSBS];
+} mm_context_t;
+
+#endif /* !__ASSEMBLY__ */
+
+#define TSB_CONFIG_TSB         0x00
+#define TSB_CONFIG_RSS_LIMIT   0x08
+#define TSB_CONFIG_NENTRIES    0x10
+#define TSB_CONFIG_REG_VAL     0x18
+#define TSB_CONFIG_MAP_VADDR   0x20
+#define TSB_CONFIG_MAP_PTE     0x28
+
+#endif /* __MMU_H */
index 671a997b9e6961d4f543347b46266773c5abf622..e14efb9532ff235c4f5f6e769197a8f557584953 100644 (file)
@@ -1,42 +1,8 @@
-#ifndef __SPARC_MMU_CONTEXT_H
-#define __SPARC_MMU_CONTEXT_H
-
-#include <asm/btfixup.h>
-
-#ifndef __ASSEMBLY__
-
-#include <asm-generic/mm_hooks.h>
-
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-{
-}
-
-/*
- * Initialize a new mmu context.  This is invoked when a new
- * address space instance (unique or shared) is instantiated.
- */
-#define init_new_context(tsk, mm) (((mm)->context = NO_CONTEXT), 0)
-
-/*
- * Destroy a dead context.  This occurs when mmput drops the
- * mm_users count to zero, the mmaps have been released, and
- * all the page tables have been flushed.  Our job is to destroy
- * any remaining processor-specific state.
- */
-BTFIXUPDEF_CALL(void, destroy_context, struct mm_struct *)
-
-#define destroy_context(mm) BTFIXUP_CALL(destroy_context)(mm)
-
-/* Switch the current MM context. */
-BTFIXUPDEF_CALL(void, switch_mm, struct mm_struct *, struct mm_struct *, struct task_struct *)
-
-#define switch_mm(old_mm, mm, tsk) BTFIXUP_CALL(switch_mm)(old_mm, mm, tsk)
-
-#define deactivate_mm(tsk,mm)  do { } while (0)
-
-/* Activate a new MM instance for the current task. */
-#define activate_mm(active_mm, mm) switch_mm((active_mm), (mm), NULL)
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(__SPARC_MMU_CONTEXT_H) */
+#ifndef ___ASM_SPARC_MMU_CONTEXT_H
+#define ___ASM_SPARC_MMU_CONTEXT_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/mmu_context_64.h>
+#else
+#include <asm-sparc/mmu_context_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/mmu_context_32.h b/include/asm-sparc/mmu_context_32.h
new file mode 100644 (file)
index 0000000..671a997
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef __SPARC_MMU_CONTEXT_H
+#define __SPARC_MMU_CONTEXT_H
+
+#include <asm/btfixup.h>
+
+#ifndef __ASSEMBLY__
+
+#include <asm-generic/mm_hooks.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+/*
+ * Initialize a new mmu context.  This is invoked when a new
+ * address space instance (unique or shared) is instantiated.
+ */
+#define init_new_context(tsk, mm) (((mm)->context = NO_CONTEXT), 0)
+
+/*
+ * Destroy a dead context.  This occurs when mmput drops the
+ * mm_users count to zero, the mmaps have been released, and
+ * all the page tables have been flushed.  Our job is to destroy
+ * any remaining processor-specific state.
+ */
+BTFIXUPDEF_CALL(void, destroy_context, struct mm_struct *)
+
+#define destroy_context(mm) BTFIXUP_CALL(destroy_context)(mm)
+
+/* Switch the current MM context. */
+BTFIXUPDEF_CALL(void, switch_mm, struct mm_struct *, struct mm_struct *, struct task_struct *)
+
+#define switch_mm(old_mm, mm, tsk) BTFIXUP_CALL(switch_mm)(old_mm, mm, tsk)
+
+#define deactivate_mm(tsk,mm)  do { } while (0)
+
+/* Activate a new MM instance for the current task. */
+#define activate_mm(active_mm, mm) switch_mm((active_mm), (mm), NULL)
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__SPARC_MMU_CONTEXT_H) */
diff --git a/include/asm-sparc/mmu_context_64.h b/include/asm-sparc/mmu_context_64.h
new file mode 100644 (file)
index 0000000..5693ab4
--- /dev/null
@@ -0,0 +1,155 @@
+#ifndef __SPARC64_MMU_CONTEXT_H
+#define __SPARC64_MMU_CONTEXT_H
+
+/* Derived heavily from Linus's Alpha/AXP ASN code... */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/spinlock.h>
+#include <asm/system.h>
+#include <asm/spitfire.h>
+#include <asm-generic/mm_hooks.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+extern spinlock_t ctx_alloc_lock;
+extern unsigned long tlb_context_cache;
+extern unsigned long mmu_context_bmap[];
+
+extern void get_new_mmu_context(struct mm_struct *mm);
+#ifdef CONFIG_SMP
+extern void smp_new_mmu_context_version(void);
+#else
+#define smp_new_mmu_context_version() do { } while (0)
+#endif
+
+extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+extern void destroy_context(struct mm_struct *mm);
+
+extern void __tsb_context_switch(unsigned long pgd_pa,
+                                struct tsb_config *tsb_base,
+                                struct tsb_config *tsb_huge,
+                                unsigned long tsb_descr_pa);
+
+static inline void tsb_context_switch(struct mm_struct *mm)
+{
+       __tsb_context_switch(__pa(mm->pgd),
+                            &mm->context.tsb_block[0],
+#ifdef CONFIG_HUGETLB_PAGE
+                            (mm->context.tsb_block[1].tsb ?
+                             &mm->context.tsb_block[1] :
+                             NULL)
+#else
+                            NULL
+#endif
+                            , __pa(&mm->context.tsb_descr[0]));
+}
+
+extern void tsb_grow(struct mm_struct *mm, unsigned long tsb_index, unsigned long mm_rss);
+#ifdef CONFIG_SMP
+extern void smp_tsb_sync(struct mm_struct *mm);
+#else
+#define smp_tsb_sync(__mm) do { } while (0)
+#endif
+
+/* Set MMU context in the actual hardware. */
+#define load_secondary_context(__mm) \
+       __asm__ __volatile__( \
+       "\n661: stxa            %0, [%1] %2\n" \
+       "       .section        .sun4v_1insn_patch, \"ax\"\n" \
+       "       .word           661b\n" \
+       "       stxa            %0, [%1] %3\n" \
+       "       .previous\n" \
+       "       flush           %%g6\n" \
+       : /* No outputs */ \
+       : "r" (CTX_HWBITS((__mm)->context)), \
+         "r" (SECONDARY_CONTEXT), "i" (ASI_DMMU), "i" (ASI_MMU))
+
+extern void __flush_tlb_mm(unsigned long, unsigned long);
+
+/* Switch the current MM context.  Interrupts are disabled.  */
+static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk)
+{
+       unsigned long ctx_valid, flags;
+       int cpu;
+
+       if (unlikely(mm == &init_mm))
+               return;
+
+       spin_lock_irqsave(&mm->context.lock, flags);
+       ctx_valid = CTX_VALID(mm->context);
+       if (!ctx_valid)
+               get_new_mmu_context(mm);
+
+       /* We have to be extremely careful here or else we will miss
+        * a TSB grow if we switch back and forth between a kernel
+        * thread and an address space which has it's TSB size increased
+        * on another processor.
+        *
+        * It is possible to play some games in order to optimize the
+        * switch, but the safest thing to do is to unconditionally
+        * perform the secondary context load and the TSB context switch.
+        *
+        * For reference the bad case is, for address space "A":
+        *
+        *              CPU 0                   CPU 1
+        *      run address space A
+        *      set cpu0's bits in cpu_vm_mask
+        *      switch to kernel thread, borrow
+        *      address space A via entry_lazy_tlb
+        *                                      run address space A
+        *                                      set cpu1's bit in cpu_vm_mask
+        *                                      flush_tlb_pending()
+        *                                      reset cpu_vm_mask to just cpu1
+        *                                      TSB grow
+        *      run address space A
+        *      context was valid, so skip
+        *      TSB context switch
+        *
+        * At that point cpu0 continues to use a stale TSB, the one from
+        * before the TSB grow performed on cpu1.  cpu1 did not cross-call
+        * cpu0 to update it's TSB because at that point the cpu_vm_mask
+        * only had cpu1 set in it.
+        */
+       load_secondary_context(mm);
+       tsb_context_switch(mm);
+
+       /* Any time a processor runs a context on an address space
+        * for the first time, we must flush that context out of the
+        * local TLB.
+        */
+       cpu = smp_processor_id();
+       if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) {
+               cpu_set(cpu, mm->cpu_vm_mask);
+               __flush_tlb_mm(CTX_HWBITS(mm->context),
+                              SECONDARY_CONTEXT);
+       }
+       spin_unlock_irqrestore(&mm->context.lock, flags);
+}
+
+#define deactivate_mm(tsk,mm)  do { } while (0)
+
+/* Activate a new MM instance for the current task. */
+static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm)
+{
+       unsigned long flags;
+       int cpu;
+
+       spin_lock_irqsave(&mm->context.lock, flags);
+       if (!CTX_VALID(mm->context))
+               get_new_mmu_context(mm);
+       cpu = smp_processor_id();
+       if (!cpu_isset(cpu, mm->cpu_vm_mask))
+               cpu_set(cpu, mm->cpu_vm_mask);
+
+       load_secondary_context(mm);
+       __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT);
+       tsb_context_switch(mm);
+       spin_unlock_irqrestore(&mm->context.lock, flags);
+}
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__SPARC64_MMU_CONTEXT_H) */
diff --git a/include/asm-sparc/mmzone.h b/include/asm-sparc/mmzone.h
new file mode 100644 (file)
index 0000000..ebf5986
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _SPARC64_MMZONE_H
+#define _SPARC64_MMZONE_H
+
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+
+extern struct pglist_data *node_data[];
+
+#define NODE_DATA(nid)         (node_data[nid])
+#define node_start_pfn(nid)    (NODE_DATA(nid)->node_start_pfn)
+#define node_end_pfn(nid)      (NODE_DATA(nid)->node_end_pfn)
+
+extern int numa_cpu_lookup_table[];
+extern cpumask_t numa_cpumask_lookup_table[];
+
+#endif /* CONFIG_NEED_MULTIPLE_NODES */
+
+#endif /* _SPARC64_MMZONE_H */
index cbd9e67b0c0bd42d47f1744e6adec9f23e709aea..516138fe681a53117f673b942ba1b293a203ccee 100644 (file)
@@ -1,7 +1,8 @@
-#ifndef _ASM_SPARC_MODULE_H
-#define _ASM_SPARC_MODULE_H
-struct mod_arch_specific { };
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-#endif /* _ASM_SPARC_MODULE_H */
+#ifndef ___ASM_SPARC_MODULE_H
+#define ___ASM_SPARC_MODULE_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/module_64.h>
+#else
+#include <asm-sparc/module_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/module_32.h b/include/asm-sparc/module_32.h
new file mode 100644 (file)
index 0000000..cbd9e67
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _ASM_SPARC_MODULE_H
+#define _ASM_SPARC_MODULE_H
+struct mod_arch_specific { };
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+#endif /* _ASM_SPARC_MODULE_H */
diff --git a/include/asm-sparc/module_64.h b/include/asm-sparc/module_64.h
new file mode 100644 (file)
index 0000000..3d77ba4
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _ASM_SPARC64_MODULE_H
+#define _ASM_SPARC64_MODULE_H
+struct mod_arch_specific { };
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym Elf64_Sym
+#define Elf_Ehdr Elf64_Ehdr
+#endif /* _ASM_SPARC64_MODULE_H */
index 29aad11b8f00972a861f14e889e80a564e0c67f4..5b9f7fec7ee74cb1b6bb2d72bb952d5268ef8b82 100644 (file)
@@ -1,173 +1,8 @@
-/*
- * mostek.h:  Describes the various Mostek time of day clock registers.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
- * Added intersil code 05/25/98 Chris Davis (cdavis@cois.on.ca)
- */
-
-#ifndef _SPARC_MOSTEK_H
-#define _SPARC_MOSTEK_H
-
-#include <asm/idprom.h>
-#include <asm/io.h>
-
-/*       M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ)
- *
- *                             Data
- * Address                                                 Function
- *        Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0
- *   7ff  -     -     -     -    -     -     -     -       Year 00-99
- *   7fe  0     0     0     -    -     -     -     -      Month 01-12
- *   7fd  0     0     -     -    -     -     -     -       Date 01-31
- *   7fc  0     FT    0     0    0     -     -     -        Day 01-07
- *   7fb  KS    0     -     -    -     -     -     -      Hours 00-23
- *   7fa  0     -     -     -    -     -     -     -    Minutes 00-59
- *   7f9  ST    -     -     -    -     -     -     -    Seconds 00-59
- *   7f8  W     R     S     -    -     -     -     -    Control
- *
- *   * ST is STOP BIT
- *   * W is WRITE BIT
- *   * R is READ BIT
- *   * S is SIGN BIT
- *   * FT is FREQ TEST BIT
- *   * KS is KICK START BIT
- */
-
-/* The Mostek 48t02 real time clock and NVRAM chip. The registers
- * other than the control register are in binary coded decimal. Some
- * control bits also live outside the control register.
- */
-#define mostek_read(_addr)             readb(_addr)
-#define mostek_write(_addr,_val)       writeb(_val, _addr)
-#define MOSTEK_EEPROM          0x0000UL
-#define MOSTEK_IDPROM          0x07d8UL
-#define MOSTEK_CREG            0x07f8UL
-#define MOSTEK_SEC             0x07f9UL
-#define MOSTEK_MIN             0x07faUL
-#define MOSTEK_HOUR            0x07fbUL
-#define MOSTEK_DOW             0x07fcUL
-#define MOSTEK_DOM             0x07fdUL
-#define MOSTEK_MONTH           0x07feUL
-#define MOSTEK_YEAR            0x07ffUL
-
-struct mostek48t02 {
-       volatile char eeprom[2008];     /* This is the eeprom, don't touch! */
-       struct idprom idprom;           /* The idprom lives here. */
-       volatile unsigned char creg;    /* Control register */
-       volatile unsigned char sec;     /* Seconds (0-59) */
-       volatile unsigned char min;     /* Minutes (0-59) */
-       volatile unsigned char hour;    /* Hour (0-23) */
-       volatile unsigned char dow;     /* Day of the week (1-7) */
-       volatile unsigned char dom;     /* Day of the month (1-31) */
-       volatile unsigned char month;   /* Month of year (1-12) */
-       volatile unsigned char year;    /* Year (0-99) */
-};
-
-extern spinlock_t mostek_lock;
-extern void __iomem *mstk48t02_regs;
-
-/* Control register values. */
-#define        MSTK_CREG_WRITE 0x80    /* Must set this before placing values. */
-#define        MSTK_CREG_READ  0x40    /* Stop updates to allow a clean read. */
-#define        MSTK_CREG_SIGN  0x20    /* Slow/speed clock in calibration mode. */
-
-/* Control bits that live in the other registers. */
-#define        MSTK_STOP       0x80    /* Stop the clock oscillator. (sec) */
-#define        MSTK_KICK_START 0x80    /* Kick start the clock chip. (hour) */
-#define MSTK_FREQ_TEST 0x40    /* Frequency test mode. (day) */
-
-#define MSTK_YEAR_ZERO       1968   /* If year reg has zero, it is 1968. */
-#define MSTK_CVT_YEAR(yr)  ((yr) + MSTK_YEAR_ZERO)
-
-/* Masks that define how much space each value takes up. */
-#define        MSTK_SEC_MASK   0x7f
-#define        MSTK_MIN_MASK   0x7f
-#define        MSTK_HOUR_MASK  0x3f
-#define        MSTK_DOW_MASK   0x07
-#define        MSTK_DOM_MASK   0x3f
-#define        MSTK_MONTH_MASK 0x1f
-#define        MSTK_YEAR_MASK  0xffU
-
-/* Binary coded decimal conversion macros. */
-#define MSTK_REGVAL_TO_DECIMAL(x)  (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
-#define MSTK_DECIMAL_TO_REGVAL(x)  ((((x) / 0x0A) << 0x04) + ((x) % 0x0A))
-
-/* Generic register set and get macros for internal use. */
-#define MSTK_GET(regs,var,mask) (MSTK_REGVAL_TO_DECIMAL(((struct mostek48t02 *)regs)->var & MSTK_ ## mask ## _MASK))
-#define MSTK_SET(regs,var,value,mask) do { ((struct mostek48t02 *)regs)->var &= ~(MSTK_ ## mask ## _MASK); ((struct mostek48t02 *)regs)->var |= MSTK_DECIMAL_TO_REGVAL(value) & (MSTK_ ## mask ## _MASK); } while (0)
-
-/* Macros to make register access easier on our fingers. These give you
- * the decimal value of the register requested if applicable. You pass
- * the a pointer to a 'struct mostek48t02'.
- */
-#define        MSTK_REG_CREG(regs)     (((struct mostek48t02 *)regs)->creg)
-#define        MSTK_REG_SEC(regs)      MSTK_GET(regs,sec,SEC)
-#define        MSTK_REG_MIN(regs)      MSTK_GET(regs,min,MIN)
-#define        MSTK_REG_HOUR(regs)     MSTK_GET(regs,hour,HOUR)
-#define        MSTK_REG_DOW(regs)      MSTK_GET(regs,dow,DOW)
-#define        MSTK_REG_DOM(regs)      MSTK_GET(regs,dom,DOM)
-#define        MSTK_REG_MONTH(regs)    MSTK_GET(regs,month,MONTH)
-#define        MSTK_REG_YEAR(regs)     MSTK_GET(regs,year,YEAR)
-
-#define        MSTK_SET_REG_SEC(regs,value)    MSTK_SET(regs,sec,value,SEC)
-#define        MSTK_SET_REG_MIN(regs,value)    MSTK_SET(regs,min,value,MIN)
-#define        MSTK_SET_REG_HOUR(regs,value)   MSTK_SET(regs,hour,value,HOUR)
-#define        MSTK_SET_REG_DOW(regs,value)    MSTK_SET(regs,dow,value,DOW)
-#define        MSTK_SET_REG_DOM(regs,value)    MSTK_SET(regs,dom,value,DOM)
-#define        MSTK_SET_REG_MONTH(regs,value)  MSTK_SET(regs,month,value,MONTH)
-#define        MSTK_SET_REG_YEAR(regs,value)   MSTK_SET(regs,year,value,YEAR)
-
-
-/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the
- * same (basically) layout of the 48t02 chip except for the extra
- * NVRAM on board (8 KB against the 48t02's 2 KB).
- */
-struct mostek48t08 {
-       char offset[6*1024];         /* Magic things may be here, who knows? */
-       struct mostek48t02 regs;     /* Here is what we are interested in.   */
-};
-
-extern enum sparc_clock_type sp_clock_typ;
-
-#ifdef CONFIG_SUN4
-enum sparc_clock_type {        MSTK48T02, MSTK48T08, \
-INTERSIL, MSTK_INVALID };
+#ifndef ___ASM_SPARC_MOSTEK_H
+#define ___ASM_SPARC_MOSTEK_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/mostek_64.h>
 #else
-enum sparc_clock_type {        MSTK48T02, MSTK48T08, \
-MSTK_INVALID };
+#include <asm-sparc/mostek_32.h>
 #endif
-
-#ifdef CONFIG_SUN4
-/* intersil on a sun 4/260 code  data from harris doc */
-struct intersil_dt {
-        volatile unsigned char int_csec;
-        volatile unsigned char int_hour;
-        volatile unsigned char int_min;
-        volatile unsigned char int_sec;
-        volatile unsigned char int_month;
-        volatile unsigned char int_day;
-        volatile unsigned char int_year;
-        volatile unsigned char int_dow;
-};
-
-struct intersil {
-       struct intersil_dt clk;
-       struct intersil_dt cmp;
-       volatile unsigned char int_intr_reg;
-       volatile unsigned char int_cmd_reg;
-};
-
-#define INTERSIL_STOP        0x0
-#define INTERSIL_START       0x8
-#define INTERSIL_INTR_DISABLE   0x0
-#define INTERSIL_INTR_ENABLE   0x10
-#define INTERSIL_32K           0x0
-#define INTERSIL_NORMAL                0x0
-#define INTERSIL_24H           0x4 
-#define INTERSIL_INT_100HZ     0x2
-
-/* end of intersil info */
 #endif
-
-#endif /* !(_SPARC_MOSTEK_H) */
diff --git a/include/asm-sparc/mostek_32.h b/include/asm-sparc/mostek_32.h
new file mode 100644 (file)
index 0000000..a99590c
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * mostek.h:  Describes the various Mostek time of day clock registers.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
+ * Added intersil code 05/25/98 Chris Davis (cdavis@cois.on.ca)
+ */
+
+#ifndef _SPARC_MOSTEK_H
+#define _SPARC_MOSTEK_H
+
+#include <asm/idprom.h>
+#include <asm/io.h>
+
+/*       M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ)
+ *
+ *                             Data
+ * Address                                                 Function
+ *        Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0
+ *   7ff  -     -     -     -    -     -     -     -       Year 00-99
+ *   7fe  0     0     0     -    -     -     -     -      Month 01-12
+ *   7fd  0     0     -     -    -     -     -     -       Date 01-31
+ *   7fc  0     FT    0     0    0     -     -     -        Day 01-07
+ *   7fb  KS    0     -     -    -     -     -     -      Hours 00-23
+ *   7fa  0     -     -     -    -     -     -     -    Minutes 00-59
+ *   7f9  ST    -     -     -    -     -     -     -    Seconds 00-59
+ *   7f8  W     R     S     -    -     -     -     -    Control
+ *
+ *   * ST is STOP BIT
+ *   * W is WRITE BIT
+ *   * R is READ BIT
+ *   * S is SIGN BIT
+ *   * FT is FREQ TEST BIT
+ *   * KS is KICK START BIT
+ */
+
+/* The Mostek 48t02 real time clock and NVRAM chip. The registers
+ * other than the control register are in binary coded decimal. Some
+ * control bits also live outside the control register.
+ */
+#define mostek_read(_addr)             readb(_addr)
+#define mostek_write(_addr,_val)       writeb(_val, _addr)
+#define MOSTEK_EEPROM          0x0000UL
+#define MOSTEK_IDPROM          0x07d8UL
+#define MOSTEK_CREG            0x07f8UL
+#define MOSTEK_SEC             0x07f9UL
+#define MOSTEK_MIN             0x07faUL
+#define MOSTEK_HOUR            0x07fbUL
+#define MOSTEK_DOW             0x07fcUL
+#define MOSTEK_DOM             0x07fdUL
+#define MOSTEK_MONTH           0x07feUL
+#define MOSTEK_YEAR            0x07ffUL
+
+struct mostek48t02 {
+       volatile char eeprom[2008];     /* This is the eeprom, don't touch! */
+       struct idprom idprom;           /* The idprom lives here. */
+       volatile unsigned char creg;    /* Control register */
+       volatile unsigned char sec;     /* Seconds (0-59) */
+       volatile unsigned char min;     /* Minutes (0-59) */
+       volatile unsigned char hour;    /* Hour (0-23) */
+       volatile unsigned char dow;     /* Day of the week (1-7) */
+       volatile unsigned char dom;     /* Day of the month (1-31) */
+       volatile unsigned char month;   /* Month of year (1-12) */
+       volatile unsigned char year;    /* Year (0-99) */
+};
+
+extern spinlock_t mostek_lock;
+extern void __iomem *mstk48t02_regs;
+
+/* Control register values. */
+#define        MSTK_CREG_WRITE 0x80    /* Must set this before placing values. */
+#define        MSTK_CREG_READ  0x40    /* Stop updates to allow a clean read. */
+#define        MSTK_CREG_SIGN  0x20    /* Slow/speed clock in calibration mode. */
+
+/* Control bits that live in the other registers. */
+#define        MSTK_STOP       0x80    /* Stop the clock oscillator. (sec) */
+#define        MSTK_KICK_START 0x80    /* Kick start the clock chip. (hour) */
+#define MSTK_FREQ_TEST 0x40    /* Frequency test mode. (day) */
+
+#define MSTK_YEAR_ZERO       1968   /* If year reg has zero, it is 1968. */
+#define MSTK_CVT_YEAR(yr)  ((yr) + MSTK_YEAR_ZERO)
+
+/* Masks that define how much space each value takes up. */
+#define        MSTK_SEC_MASK   0x7f
+#define        MSTK_MIN_MASK   0x7f
+#define        MSTK_HOUR_MASK  0x3f
+#define        MSTK_DOW_MASK   0x07
+#define        MSTK_DOM_MASK   0x3f
+#define        MSTK_MONTH_MASK 0x1f
+#define        MSTK_YEAR_MASK  0xffU
+
+/* Binary coded decimal conversion macros. */
+#define MSTK_REGVAL_TO_DECIMAL(x)  (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
+#define MSTK_DECIMAL_TO_REGVAL(x)  ((((x) / 0x0A) << 0x04) + ((x) % 0x0A))
+
+/* Generic register set and get macros for internal use. */
+#define MSTK_GET(regs,var,mask) (MSTK_REGVAL_TO_DECIMAL(((struct mostek48t02 *)regs)->var & MSTK_ ## mask ## _MASK))
+#define MSTK_SET(regs,var,value,mask) do { ((struct mostek48t02 *)regs)->var &= ~(MSTK_ ## mask ## _MASK); ((struct mostek48t02 *)regs)->var |= MSTK_DECIMAL_TO_REGVAL(value) & (MSTK_ ## mask ## _MASK); } while (0)
+
+/* Macros to make register access easier on our fingers. These give you
+ * the decimal value of the register requested if applicable. You pass
+ * the a pointer to a 'struct mostek48t02'.
+ */
+#define        MSTK_REG_CREG(regs)     (((struct mostek48t02 *)regs)->creg)
+#define        MSTK_REG_SEC(regs)      MSTK_GET(regs,sec,SEC)
+#define        MSTK_REG_MIN(regs)      MSTK_GET(regs,min,MIN)
+#define        MSTK_REG_HOUR(regs)     MSTK_GET(regs,hour,HOUR)
+#define        MSTK_REG_DOW(regs)      MSTK_GET(regs,dow,DOW)
+#define        MSTK_REG_DOM(regs)      MSTK_GET(regs,dom,DOM)
+#define        MSTK_REG_MONTH(regs)    MSTK_GET(regs,month,MONTH)
+#define        MSTK_REG_YEAR(regs)     MSTK_GET(regs,year,YEAR)
+
+#define        MSTK_SET_REG_SEC(regs,value)    MSTK_SET(regs,sec,value,SEC)
+#define        MSTK_SET_REG_MIN(regs,value)    MSTK_SET(regs,min,value,MIN)
+#define        MSTK_SET_REG_HOUR(regs,value)   MSTK_SET(regs,hour,value,HOUR)
+#define        MSTK_SET_REG_DOW(regs,value)    MSTK_SET(regs,dow,value,DOW)
+#define        MSTK_SET_REG_DOM(regs,value)    MSTK_SET(regs,dom,value,DOM)
+#define        MSTK_SET_REG_MONTH(regs,value)  MSTK_SET(regs,month,value,MONTH)
+#define        MSTK_SET_REG_YEAR(regs,value)   MSTK_SET(regs,year,value,YEAR)
+
+
+/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the
+ * same (basically) layout of the 48t02 chip except for the extra
+ * NVRAM on board (8 KB against the 48t02's 2 KB).
+ */
+struct mostek48t08 {
+       char offset[6*1024];         /* Magic things may be here, who knows? */
+       struct mostek48t02 regs;     /* Here is what we are interested in.   */
+};
+
+#ifdef CONFIG_SUN4
+enum sparc_clock_type {        MSTK48T02, MSTK48T08, \
+INTERSIL, MSTK_INVALID };
+#else
+enum sparc_clock_type {        MSTK48T02, MSTK48T08, \
+MSTK_INVALID };
+#endif
+
+#ifdef CONFIG_SUN4
+/* intersil on a sun 4/260 code  data from harris doc */
+struct intersil_dt {
+        volatile unsigned char int_csec;
+        volatile unsigned char int_hour;
+        volatile unsigned char int_min;
+        volatile unsigned char int_sec;
+        volatile unsigned char int_month;
+        volatile unsigned char int_day;
+        volatile unsigned char int_year;
+        volatile unsigned char int_dow;
+};
+
+struct intersil {
+       struct intersil_dt clk;
+       struct intersil_dt cmp;
+       volatile unsigned char int_intr_reg;
+       volatile unsigned char int_cmd_reg;
+};
+
+#define INTERSIL_STOP        0x0
+#define INTERSIL_START       0x8
+#define INTERSIL_INTR_DISABLE   0x0
+#define INTERSIL_INTR_ENABLE   0x10
+#define INTERSIL_32K           0x0
+#define INTERSIL_NORMAL                0x0
+#define INTERSIL_24H           0x4
+#define INTERSIL_INT_100HZ     0x2
+
+/* end of intersil info */
+#endif
+
+#endif /* !(_SPARC_MOSTEK_H) */
diff --git a/include/asm-sparc/mostek_64.h b/include/asm-sparc/mostek_64.h
new file mode 100644 (file)
index 0000000..c5652de
--- /dev/null
@@ -0,0 +1,143 @@
+/* mostek.h:  Describes the various Mostek time of day clock registers.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
+ */
+
+#ifndef _SPARC64_MOSTEK_H
+#define _SPARC64_MOSTEK_H
+
+#include <asm/idprom.h>
+
+/*       M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ)
+ *
+ *                             Data
+ * Address                                                 Function
+ *        Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0
+ *   7ff  -     -     -     -    -     -     -     -       Year 00-99
+ *   7fe  0     0     0     -    -     -     -     -      Month 01-12
+ *   7fd  0     0     -     -    -     -     -     -       Date 01-31
+ *   7fc  0     FT    0     0    0     -     -     -        Day 01-07
+ *   7fb  KS    0     -     -    -     -     -     -      Hours 00-23
+ *   7fa  0     -     -     -    -     -     -     -    Minutes 00-59
+ *   7f9  ST    -     -     -    -     -     -     -    Seconds 00-59
+ *   7f8  W     R     S     -    -     -     -     -    Control
+ *
+ *   * ST is STOP BIT
+ *   * W is WRITE BIT
+ *   * R is READ BIT
+ *   * S is SIGN BIT
+ *   * FT is FREQ TEST BIT
+ *   * KS is KICK START BIT
+ */
+
+/* The Mostek 48t02 real time clock and NVRAM chip. The registers
+ * other than the control register are in binary coded decimal. Some
+ * control bits also live outside the control register.
+ *
+ * We now deal with physical addresses for I/O to the chip. -DaveM
+ */
+static inline u8 mostek_read(void __iomem *addr)
+{
+       u8 ret;
+
+       __asm__ __volatile__("lduba     [%1] %2, %0"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+       return ret;
+}
+
+static inline void mostek_write(void __iomem *addr, u8 val)
+{
+       __asm__ __volatile__("stba      %0, [%1] %2"
+                            : /* no outputs */
+                            : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+}
+
+#define MOSTEK_EEPROM          0x0000UL
+#define MOSTEK_IDPROM          0x07d8UL
+#define MOSTEK_CREG            0x07f8UL
+#define MOSTEK_SEC             0x07f9UL
+#define MOSTEK_MIN             0x07faUL
+#define MOSTEK_HOUR            0x07fbUL
+#define MOSTEK_DOW             0x07fcUL
+#define MOSTEK_DOM             0x07fdUL
+#define MOSTEK_MONTH           0x07feUL
+#define MOSTEK_YEAR            0x07ffUL
+
+extern spinlock_t mostek_lock;
+extern void __iomem *mstk48t02_regs;
+
+/* Control register values. */
+#define        MSTK_CREG_WRITE 0x80    /* Must set this before placing values. */
+#define        MSTK_CREG_READ  0x40    /* Stop updates to allow a clean read. */
+#define        MSTK_CREG_SIGN  0x20    /* Slow/speed clock in calibration mode. */
+
+/* Control bits that live in the other registers. */
+#define        MSTK_STOP       0x80    /* Stop the clock oscillator. (sec) */
+#define        MSTK_KICK_START 0x80    /* Kick start the clock chip. (hour) */
+#define MSTK_FREQ_TEST 0x40    /* Frequency test mode. (day) */
+
+#define MSTK_YEAR_ZERO       1968   /* If year reg has zero, it is 1968. */
+#define MSTK_CVT_YEAR(yr)  ((yr) + MSTK_YEAR_ZERO)
+
+/* Masks that define how much space each value takes up. */
+#define        MSTK_SEC_MASK   0x7f
+#define        MSTK_MIN_MASK   0x7f
+#define        MSTK_HOUR_MASK  0x3f
+#define        MSTK_DOW_MASK   0x07
+#define        MSTK_DOM_MASK   0x3f
+#define        MSTK_MONTH_MASK 0x1f
+#define        MSTK_YEAR_MASK  0xffU
+
+/* Binary coded decimal conversion macros. */
+#define MSTK_REGVAL_TO_DECIMAL(x)  (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
+#define MSTK_DECIMAL_TO_REGVAL(x)  ((((x) / 0x0A) << 0x04) + ((x) % 0x0A))
+
+/* Generic register set and get macros for internal use. */
+#define MSTK_GET(regs,name)    \
+       (MSTK_REGVAL_TO_DECIMAL(mostek_read(regs + MOSTEK_ ## name) & MSTK_ ## name ## _MASK))
+#define MSTK_SET(regs,name,value) \
+do {   u8 __val = mostek_read(regs + MOSTEK_ ## name); \
+       __val &= ~(MSTK_ ## name ## _MASK); \
+       __val |= (MSTK_DECIMAL_TO_REGVAL(value) & \
+                 (MSTK_ ## name ## _MASK)); \
+       mostek_write(regs + MOSTEK_ ## name, __val); \
+} while(0)
+
+/* Macros to make register access easier on our fingers. These give you
+ * the decimal value of the register requested if applicable. You pass
+ * the a pointer to a 'struct mostek48t02'.
+ */
+#define        MSTK_REG_CREG(regs)     (mostek_read((regs) + MOSTEK_CREG))
+#define        MSTK_REG_SEC(regs)      MSTK_GET(regs,SEC)
+#define        MSTK_REG_MIN(regs)      MSTK_GET(regs,MIN)
+#define        MSTK_REG_HOUR(regs)     MSTK_GET(regs,HOUR)
+#define        MSTK_REG_DOW(regs)      MSTK_GET(regs,DOW)
+#define        MSTK_REG_DOM(regs)      MSTK_GET(regs,DOM)
+#define        MSTK_REG_MONTH(regs)    MSTK_GET(regs,MONTH)
+#define        MSTK_REG_YEAR(regs)     MSTK_GET(regs,YEAR)
+
+#define        MSTK_SET_REG_SEC(regs,value)    MSTK_SET(regs,SEC,value)
+#define        MSTK_SET_REG_MIN(regs,value)    MSTK_SET(regs,MIN,value)
+#define        MSTK_SET_REG_HOUR(regs,value)   MSTK_SET(regs,HOUR,value)
+#define        MSTK_SET_REG_DOW(regs,value)    MSTK_SET(regs,DOW,value)
+#define        MSTK_SET_REG_DOM(regs,value)    MSTK_SET(regs,DOM,value)
+#define        MSTK_SET_REG_MONTH(regs,value)  MSTK_SET(regs,MONTH,value)
+#define        MSTK_SET_REG_YEAR(regs,value)   MSTK_SET(regs,YEAR,value)
+
+
+/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the
+ * same (basically) layout of the 48t02 chip except for the extra
+ * NVRAM on board (8 KB against the 48t02's 2 KB).
+ */
+#define MOSTEK_48T08_OFFSET    0x0000UL        /* Lower NVRAM portions */
+#define MOSTEK_48T08_48T02     0x1800UL        /* Offset to 48T02 chip */
+
+/* SUN5 systems usually have 48t59 model clock chipsets.  But we keep the older
+ * clock chip definitions around just in case.
+ */
+#define MOSTEK_48T59_OFFSET    0x0000UL        /* Lower NVRAM portions */
+#define MOSTEK_48T59_48T02     0x1800UL        /* Offset to 48T02 chip */
+
+#endif /* !(_SPARC64_MOSTEK_H) */
index 8cec9ad0b8257f23bbaed6d6ed8602a2442fcb07..efc7cbe9788fa3fc30be20880efc0a315d0d76c4 100644 (file)
@@ -1,7 +1,7 @@
-#ifndef _SPARC64_MSGBUF_H
-#define _SPARC64_MSGBUF_H
+#ifndef _SPARC_MSGBUF_H
+#define _SPARC_MSGBUF_H
 
-/* 
+/*
  * The msqid64_ds structure for sparc64 architecture.
  * Note extra padding because this structure is passed back and forth
  * between kernel and user space.
  * - 2 miscellaneous 32-bit values
  */
 
+#if defined(__sparc__) && defined(__arch64__)
+# define PADDING(x)
+#else
+# define PADDING(x) unsigned int x;
+#endif
+
+
 struct msqid64_ds {
        struct ipc64_perm msg_perm;
-       unsigned int   __pad1;
+       PADDING(__pad1)
        __kernel_time_t msg_stime;      /* last msgsnd time */
-       unsigned int   __pad2;
+       PADDING(__pad2)
        __kernel_time_t msg_rtime;      /* last msgrcv time */
-       unsigned int   __pad3;
+       PADDING(__pad3)
        __kernel_time_t msg_ctime;      /* last change time */
        unsigned long  msg_cbytes;      /* current number of bytes on queue */
        unsigned long  msg_qnum;        /* number of messages in queue */
@@ -27,5 +34,5 @@ struct msqid64_ds {
        unsigned long  __unused1;
        unsigned long  __unused2;
 };
-
-#endif /* _SPARC64_MSGBUF_H */
+#undef PADDING
+#endif /* _SPARC_MSGBUF_H */
index 0646102fb020a0d7f6a4d8974280e56ead4ec720..eff944b8e321a732ba4b55b0caf2641378a332cb 100644 (file)
@@ -1,13 +1,8 @@
-/*
- * linux/include/asm-sparc/namei.h
- *
- * Routines to handle famous /usr/gnemul/s*.
- * Included from linux/fs/namei.c
- */
-
-#ifndef __SPARC_NAMEI_H
-#define __SPARC_NAMEI_H
-
-#define __emul_prefix() NULL
-
-#endif /* __SPARC_NAMEI_H */
+#ifndef ___ASM_SPARC_NAMEI_H
+#define ___ASM_SPARC_NAMEI_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/namei_64.h>
+#else
+#include <asm-sparc/namei_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/namei_32.h b/include/asm-sparc/namei_32.h
new file mode 100644 (file)
index 0000000..0646102
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * linux/include/asm-sparc/namei.h
+ *
+ * Routines to handle famous /usr/gnemul/s*.
+ * Included from linux/fs/namei.c
+ */
+
+#ifndef __SPARC_NAMEI_H
+#define __SPARC_NAMEI_H
+
+#define __emul_prefix() NULL
+
+#endif /* __SPARC_NAMEI_H */
diff --git a/include/asm-sparc/namei_64.h b/include/asm-sparc/namei_64.h
new file mode 100644 (file)
index 0000000..cbc1b4c
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * linux/include/asm-sparc64/namei.h
+ *
+ * Routines to handle famous /usr/gnemul/s*.
+ * Included from linux/fs/namei.c
+ */
+
+#ifndef __SPARC64_NAMEI_H
+#define __SPARC64_NAMEI_H
+
+#define __emul_prefix() NULL
+
+#endif /* __SPARC64_NAMEI_H */
diff --git a/include/asm-sparc/ns87303.h b/include/asm-sparc/ns87303.h
new file mode 100644 (file)
index 0000000..686defe
--- /dev/null
@@ -0,0 +1,118 @@
+/* ns87303.h: Configuration Register Description for the
+ *            National Semiconductor PC87303 (SuperIO).
+ *
+ * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
+ */
+
+#ifndef _SPARC_NS87303_H
+#define _SPARC_NS87303_H 1
+
+/*
+ * Control Register Index Values
+ */
+#define FER    0x00
+#define FAR    0x01
+#define PTR    0x02
+#define FCR    0x03
+#define PCR    0x04
+#define KRR    0x05
+#define PMC    0x06
+#define TUP    0x07
+#define SID    0x08
+#define ASC    0x09
+#define CS0CF0 0x0a
+#define CS0CF1 0x0b
+#define CS1CF0 0x0c
+#define CS1CF1 0x0d
+
+/* Function Enable Register (FER) bits */
+#define FER_EDM                0x10    /* Encoded Drive and Motor pin information   */
+
+/* Function Address Register (FAR) bits */
+#define FAR_LPT_MASK   0x03
+#define FAR_LPTB       0x00
+#define FAR_LPTA       0x01
+#define FAR_LPTC       0x02
+
+/* Power and Test Register (PTR) bits */
+#define PTR_LPTB_IRQ7  0x08
+#define PTR_LEVEL_IRQ  0x80    /* When not ECP/EPP: Use level IRQ           */
+#define PTR_LPT_REG_DIR        0x80    /* When ECP/EPP: LPT CTR controlls direction */
+                               /*               of the parallel port        */
+
+/* Function Control Register (FCR) bits */
+#define FCR_LDE                0x10    /* Logical Drive Exchange                    */
+#define FCR_ZWS_ENA    0x20    /* Enable short host read/write in ECP/EPP   */
+
+/* Printer Control Register (PCR) bits */
+#define PCR_EPP_ENABLE 0x01
+#define PCR_EPP_IEEE   0x02    /* Enable EPP Version 1.9 (IEEE 1284)        */
+#define PCR_ECP_ENABLE 0x04
+#define PCR_ECP_CLK_ENA        0x08    /* If 0 ECP Clock is stopped on Power down   */
+#define PCR_IRQ_POLAR  0x20    /* If 0 IRQ is level high or negative pulse, */
+                               /* if 1 polarity is inverted                 */
+#define PCR_IRQ_ODRAIN 0x40    /* If 1, IRQ is open drain                   */
+
+/* Tape UARTs and Parallel Port Config Register (TUP) bits */
+#define TUP_EPP_TIMO   0x02    /* Enable EPP timeout IRQ                    */
+
+/* Advanced SuperIO Config Register (ASC) bits */
+#define ASC_LPT_IRQ7   0x01    /* Always use IRQ7 for LPT                  */
+#define ASC_DRV2_SEL   0x02    /* Logical Drive Exchange controlled by TDR  */
+
+#define FER_RESERVED   0x00
+#define FAR_RESERVED   0x00
+#define PTR_RESERVED   0x73
+#define FCR_RESERVED   0xc4
+#define PCR_RESERVED   0x10
+#define KRR_RESERVED   0x00
+#define PMC_RESERVED   0x98
+#define TUP_RESERVED   0xfb
+#define SIP_RESERVED   0x00
+#define ASC_RESERVED   0x18
+#define CS0CF0_RESERVED        0x00
+#define CS0CF1_RESERVED        0x08
+#define CS1CF0_RESERVED        0x00
+#define CS1CF1_RESERVED        0x08
+
+#ifdef __KERNEL__
+
+#include <linux/spinlock.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+
+extern spinlock_t ns87303_lock;
+
+static inline int ns87303_modify(unsigned long port, unsigned int index,
+                                    unsigned char clr, unsigned char set)
+{
+       static unsigned char reserved[] = {
+               FER_RESERVED, FAR_RESERVED, PTR_RESERVED, FCR_RESERVED,
+               PCR_RESERVED, KRR_RESERVED, PMC_RESERVED, TUP_RESERVED,
+               SIP_RESERVED, ASC_RESERVED, CS0CF0_RESERVED, CS0CF1_RESERVED,
+               CS1CF0_RESERVED, CS1CF1_RESERVED
+       };
+       unsigned long flags;
+       unsigned char value;
+
+       if (index > 0x0d)
+               return -EINVAL;
+
+       spin_lock_irqsave(&ns87303_lock, flags);
+
+       outb(index, port);
+       value = inb(port + 1);
+       value &= ~(reserved[index] | clr);
+       value |= set;
+       outb(value, port + 1);
+       outb(value, port + 1);
+
+       spin_unlock_irqrestore(&ns87303_lock, flags);
+
+       return 0;
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* !(_SPARC_NS87303_H) */
index 38334351c36b04685861015c7a997676bd224b3a..851eb84d737ef61a3eb9ea9fe2c1bcc459373acf 100644 (file)
@@ -1,24 +1,8 @@
-#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-sparc/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.
- *
- */
-
-/* This is just here during the transition */
-#include <linux/of_platform.h>
-
-extern struct bus_type ebus_bus_type;
-extern struct bus_type sbus_bus_type;
-
-#define of_bus_type    of_platform_bus_type    /* for compatibility */
-
-#endif /* _ASM_SPARC_OF_PLATFORM_H */
+#ifndef ___ASM_SPARC_OF_PLATFORM_H
+#define ___ASM_SPARC_OF_PLATFORM_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/of_platform_64.h>
+#else
+#include <asm-sparc/of_platform_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/of_platform_32.h b/include/asm-sparc/of_platform_32.h
new file mode 100644 (file)
index 0000000..3833435
--- /dev/null
@@ -0,0 +1,24 @@
+#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-sparc/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.
+ *
+ */
+
+/* This is just here during the transition */
+#include <linux/of_platform.h>
+
+extern struct bus_type ebus_bus_type;
+extern struct bus_type sbus_bus_type;
+
+#define of_bus_type    of_platform_bus_type    /* for compatibility */
+
+#endif /* _ASM_SPARC_OF_PLATFORM_H */
diff --git a/include/asm-sparc/of_platform_64.h b/include/asm-sparc/of_platform_64.h
new file mode 100644 (file)
index 0000000..78aa032
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _ASM_SPARC64_OF_PLATFORM_H
+#define _ASM_SPARC64_OF_PLATFORM_H
+/*
+ *    Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
+ *                      <benh@kernel.crashing.org>
+ *    Modified for Sparc by merging parts of asm-sparc/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.
+ *
+ */
+
+/* This is just here during the transition */
+#include <linux/of_platform.h>
+
+extern struct bus_type isa_bus_type;
+extern struct bus_type ebus_bus_type;
+extern struct bus_type sbus_bus_type;
+
+#define of_bus_type    of_platform_bus_type    /* for compatibility */
+
+#endif /* _ASM_SPARC64_OF_PLATFORM_H */
index ed4b6bc2b1020682479b60a35eef21e94c0ba0b3..8c349f0619946939cbcef609a403db678620e495 100644 (file)
@@ -1,257 +1,8 @@
-#ifndef __SPARC_OPENPROM_H
-#define __SPARC_OPENPROM_H
-
-/* openprom.h:  Prom structures and defines for access to the OPENBOOT
- *              prom routines and data areas.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <asm/vaddrs.h>
-
-/* Empirical constants... */
-#define        LINUX_OPPROM_MAGIC      0x10010407
-
-#ifndef __ASSEMBLY__
-/* V0 prom device operations. */
-struct linux_dev_v0_funcs {
-       int (*v0_devopen)(char *device_str);
-       int (*v0_devclose)(int dev_desc);
-       int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
-       int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
-       int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf);
-       int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf);
-       int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
-       int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
-       int (*v0_seekdev)(int dev_desc, long logical_offst, int from);
-};
-
-/* V2 and later prom device operations. */
-struct linux_dev_v2_funcs {
-       int (*v2_inst2pkg)(int d);      /* Convert ihandle to phandle */
-       char * (*v2_dumb_mem_alloc)(char *va, unsigned sz);
-       void (*v2_dumb_mem_free)(char *va, unsigned sz);
-
-       /* To map devices into virtual I/O space. */
-       char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz);
-       void (*v2_dumb_munmap)(char *virta, unsigned size);
-
-       int (*v2_dev_open)(char *devpath);
-       void (*v2_dev_close)(int d);
-       int (*v2_dev_read)(int d, char *buf, int nbytes);
-       int (*v2_dev_write)(int d, char *buf, int nbytes);
-       int (*v2_dev_seek)(int d, int hi, int lo);
-
-       /* Never issued (multistage load support) */
-       void (*v2_wheee2)(void);
-       void (*v2_wheee3)(void);
-};
-
-struct linux_mlist_v0 {
-       struct linux_mlist_v0 *theres_more;
-       char *start_adr;
-       unsigned num_bytes;
-};
-
-struct linux_mem_v0 {
-       struct linux_mlist_v0 **v0_totphys;
-       struct linux_mlist_v0 **v0_prommap;
-       struct linux_mlist_v0 **v0_available; /* What we can use */
-};
-
-/* Arguments sent to the kernel from the boot prompt. */
-struct linux_arguments_v0 {
-       char *argv[8];
-       char args[100];
-       char boot_dev[2];
-       int boot_dev_ctrl;
-       int boot_dev_unit;
-       int dev_partition;
-       char *kernel_file_name;
-       void *aieee1;           /* XXX */
-};
-
-/* V2 and up boot things. */
-struct linux_bootargs_v2 {
-       char **bootpath;
-       char **bootargs;
-       int *fd_stdin;
-       int *fd_stdout;
-};
-
-/* The top level PROM vector. */
-struct linux_romvec {
-       /* Version numbers. */
-       unsigned int pv_magic_cookie;
-       unsigned int pv_romvers;
-       unsigned int pv_plugin_revision;
-       unsigned int pv_printrev;
-
-       /* Version 0 memory descriptors. */
-       struct linux_mem_v0 pv_v0mem;
-
-       /* Node operations. */
-       struct linux_nodeops *pv_nodeops;
-
-       char **pv_bootstr;
-       struct linux_dev_v0_funcs pv_v0devops;
-
-       char *pv_stdin;
-       char *pv_stdout;
-#define        PROMDEV_KBD     0               /* input from keyboard */
-#define        PROMDEV_SCREEN  0               /* output to screen */
-#define        PROMDEV_TTYA    1               /* in/out to ttya */
-#define        PROMDEV_TTYB    2               /* in/out to ttyb */
-
-       /* Blocking getchar/putchar.  NOT REENTRANT! (grr) */
-       int (*pv_getchar)(void);
-       void (*pv_putchar)(int ch);
-
-       /* Non-blocking variants. */
-       int (*pv_nbgetchar)(void);
-       int (*pv_nbputchar)(int ch);
-
-       void (*pv_putstr)(char *str, int len);
-
-       /* Miscellany. */
-       void (*pv_reboot)(char *bootstr);
-       void (*pv_printf)(__const__ char *fmt, ...);
-       void (*pv_abort)(void);
-       __volatile__ int *pv_ticks;
-       void (*pv_halt)(void);
-       void (**pv_synchook)(void);
-
-       /* Evaluate a forth string, not different proto for V0 and V2->up. */
-       union {
-               void (*v0_eval)(int len, char *str);
-               void (*v2_eval)(char *str);
-       } pv_fortheval;
-
-       struct linux_arguments_v0 **pv_v0bootargs;
-
-       /* Get ether address. */
-       unsigned int (*pv_enaddr)(int d, char *enaddr);
-
-       struct linux_bootargs_v2 pv_v2bootargs;
-       struct linux_dev_v2_funcs pv_v2devops;
-
-       int filler[15];
-
-       /* This one is sun4c/sun4 only. */
-       void (*pv_setctxt)(int ctxt, char *va, int pmeg);
-
-       /* Prom version 3 Multiprocessor routines. This stuff is crazy.
-        * No joke. Calling these when there is only one cpu probably
-        * crashes the machine, have to test this. :-)
-        */
-
-       /* v3_cpustart() will start the cpu 'whichcpu' in mmu-context
-        * 'thiscontext' executing at address 'prog_counter'
-        */
-       int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr,
-                          int thiscontext, char *prog_counter);
-
-       /* v3_cpustop() will cause cpu 'whichcpu' to stop executing
-        * until a resume cpu call is made.
-        */
-       int (*v3_cpustop)(unsigned int whichcpu);
-
-       /* v3_cpuidle() will idle cpu 'whichcpu' until a stop or
-        * resume cpu call is made.
-        */
-       int (*v3_cpuidle)(unsigned int whichcpu);
-
-       /* v3_cpuresume() will resume processor 'whichcpu' executing
-        * starting with whatever 'pc' and 'npc' were left at the
-        * last 'idle' or 'stop' call.
-        */
-       int (*v3_cpuresume)(unsigned int whichcpu);
-};
-
-/* Routines for traversing the prom device tree. */
-struct linux_nodeops {
-       int (*no_nextnode)(int node);
-       int (*no_child)(int node);
-       int (*no_proplen)(int node, char *name);
-       int (*no_getprop)(int node, char *name, char *val);
-       int (*no_setprop)(int node, char *name, char *val, int len);
-       char * (*no_nextprop)(int node, char *name);
-};
-
-/* More fun PROM structures for device probing. */
-#define PROMREG_MAX     16
-#define PROMVADDR_MAX   16
-#define PROMINTR_MAX    15
-
-struct linux_prom_registers {
-       unsigned int which_io;         /* is this in OBIO space? */
-       unsigned int phys_addr;        /* The physical address of this register */
-       unsigned int reg_size;         /* How many bytes does this register take up? */
-};
-
-struct linux_prom_irqs {
-       int pri;    /* IRQ priority */
-       int vector; /* This is foobar, what does it do? */
-};
-
-/* Element of the "ranges" vector */
-struct linux_prom_ranges {
-       unsigned int ot_child_space;
-       unsigned int ot_child_base;             /* Bus feels this */
-       unsigned int ot_parent_space;
-       unsigned int ot_parent_base;            /* CPU looks from here */
-       unsigned int or_size;
-};
-
-/* Ranges and reg properties are a bit different for PCI. */
-struct linux_prom_pci_registers {
-       /* 
-        * We don't know what information this field contain.
-        * We guess, PCI device function is in bits 15:8
-        * So, ...
-        */
-       unsigned int which_io;  /* Let it be which_io */
-
-       unsigned int phys_hi;
-       unsigned int phys_lo;
-
-       unsigned int size_hi;
-       unsigned int size_lo;
-};
-
-struct linux_prom_pci_ranges {
-       unsigned int child_phys_hi;     /* Only certain bits are encoded here. */
-       unsigned int child_phys_mid;
-       unsigned int child_phys_lo;
-
-       unsigned int parent_phys_hi;
-       unsigned int parent_phys_lo;
-
-       unsigned int size_hi;
-       unsigned int size_lo;
-};
-
-struct linux_prom_pci_assigned_addresses {
-       unsigned int which_io;
-
-       unsigned int phys_hi;
-       unsigned int phys_lo;
-
-       unsigned int size_hi;
-       unsigned int size_lo;
-};
-
-struct linux_prom_ebus_ranges {
-       unsigned int child_phys_hi;
-       unsigned int child_phys_lo;
-
-       unsigned int parent_phys_hi;
-       unsigned int parent_phys_mid;
-       unsigned int parent_phys_lo;
-
-       unsigned int size;
-};
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(__SPARC_OPENPROM_H) */
+#ifndef ___ASM_SPARC_OPENPROM_H
+#define ___ASM_SPARC_OPENPROM_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/openprom_64.h>
+#else
+#include <asm-sparc/openprom_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/openprom_32.h b/include/asm-sparc/openprom_32.h
new file mode 100644 (file)
index 0000000..8b1649f
--- /dev/null
@@ -0,0 +1,255 @@
+#ifndef __SPARC_OPENPROM_H
+#define __SPARC_OPENPROM_H
+
+/* openprom.h:  Prom structures and defines for access to the OPENBOOT
+ *              prom routines and data areas.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/* Empirical constants... */
+#define        LINUX_OPPROM_MAGIC      0x10010407
+
+#ifndef __ASSEMBLY__
+/* V0 prom device operations. */
+struct linux_dev_v0_funcs {
+       int (*v0_devopen)(char *device_str);
+       int (*v0_devclose)(int dev_desc);
+       int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
+       int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
+       int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf);
+       int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf);
+       int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
+       int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
+       int (*v0_seekdev)(int dev_desc, long logical_offst, int from);
+};
+
+/* V2 and later prom device operations. */
+struct linux_dev_v2_funcs {
+       int (*v2_inst2pkg)(int d);      /* Convert ihandle to phandle */
+       char * (*v2_dumb_mem_alloc)(char *va, unsigned sz);
+       void (*v2_dumb_mem_free)(char *va, unsigned sz);
+
+       /* To map devices into virtual I/O space. */
+       char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz);
+       void (*v2_dumb_munmap)(char *virta, unsigned size);
+
+       int (*v2_dev_open)(char *devpath);
+       void (*v2_dev_close)(int d);
+       int (*v2_dev_read)(int d, char *buf, int nbytes);
+       int (*v2_dev_write)(int d, char *buf, int nbytes);
+       int (*v2_dev_seek)(int d, int hi, int lo);
+
+       /* Never issued (multistage load support) */
+       void (*v2_wheee2)(void);
+       void (*v2_wheee3)(void);
+};
+
+struct linux_mlist_v0 {
+       struct linux_mlist_v0 *theres_more;
+       char *start_adr;
+       unsigned num_bytes;
+};
+
+struct linux_mem_v0 {
+       struct linux_mlist_v0 **v0_totphys;
+       struct linux_mlist_v0 **v0_prommap;
+       struct linux_mlist_v0 **v0_available; /* What we can use */
+};
+
+/* Arguments sent to the kernel from the boot prompt. */
+struct linux_arguments_v0 {
+       char *argv[8];
+       char args[100];
+       char boot_dev[2];
+       int boot_dev_ctrl;
+       int boot_dev_unit;
+       int dev_partition;
+       char *kernel_file_name;
+       void *aieee1;           /* XXX */
+};
+
+/* V2 and up boot things. */
+struct linux_bootargs_v2 {
+       char **bootpath;
+       char **bootargs;
+       int *fd_stdin;
+       int *fd_stdout;
+};
+
+/* The top level PROM vector. */
+struct linux_romvec {
+       /* Version numbers. */
+       unsigned int pv_magic_cookie;
+       unsigned int pv_romvers;
+       unsigned int pv_plugin_revision;
+       unsigned int pv_printrev;
+
+       /* Version 0 memory descriptors. */
+       struct linux_mem_v0 pv_v0mem;
+
+       /* Node operations. */
+       struct linux_nodeops *pv_nodeops;
+
+       char **pv_bootstr;
+       struct linux_dev_v0_funcs pv_v0devops;
+
+       char *pv_stdin;
+       char *pv_stdout;
+#define        PROMDEV_KBD     0               /* input from keyboard */
+#define        PROMDEV_SCREEN  0               /* output to screen */
+#define        PROMDEV_TTYA    1               /* in/out to ttya */
+#define        PROMDEV_TTYB    2               /* in/out to ttyb */
+
+       /* Blocking getchar/putchar.  NOT REENTRANT! (grr) */
+       int (*pv_getchar)(void);
+       void (*pv_putchar)(int ch);
+
+       /* Non-blocking variants. */
+       int (*pv_nbgetchar)(void);
+       int (*pv_nbputchar)(int ch);
+
+       void (*pv_putstr)(char *str, int len);
+
+       /* Miscellany. */
+       void (*pv_reboot)(char *bootstr);
+       void (*pv_printf)(__const__ char *fmt, ...);
+       void (*pv_abort)(void);
+       __volatile__ int *pv_ticks;
+       void (*pv_halt)(void);
+       void (**pv_synchook)(void);
+
+       /* Evaluate a forth string, not different proto for V0 and V2->up. */
+       union {
+               void (*v0_eval)(int len, char *str);
+               void (*v2_eval)(char *str);
+       } pv_fortheval;
+
+       struct linux_arguments_v0 **pv_v0bootargs;
+
+       /* Get ether address. */
+       unsigned int (*pv_enaddr)(int d, char *enaddr);
+
+       struct linux_bootargs_v2 pv_v2bootargs;
+       struct linux_dev_v2_funcs pv_v2devops;
+
+       int filler[15];
+
+       /* This one is sun4c/sun4 only. */
+       void (*pv_setctxt)(int ctxt, char *va, int pmeg);
+
+       /* Prom version 3 Multiprocessor routines. This stuff is crazy.
+        * No joke. Calling these when there is only one cpu probably
+        * crashes the machine, have to test this. :-)
+        */
+
+       /* v3_cpustart() will start the cpu 'whichcpu' in mmu-context
+        * 'thiscontext' executing at address 'prog_counter'
+        */
+       int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr,
+                          int thiscontext, char *prog_counter);
+
+       /* v3_cpustop() will cause cpu 'whichcpu' to stop executing
+        * until a resume cpu call is made.
+        */
+       int (*v3_cpustop)(unsigned int whichcpu);
+
+       /* v3_cpuidle() will idle cpu 'whichcpu' until a stop or
+        * resume cpu call is made.
+        */
+       int (*v3_cpuidle)(unsigned int whichcpu);
+
+       /* v3_cpuresume() will resume processor 'whichcpu' executing
+        * starting with whatever 'pc' and 'npc' were left at the
+        * last 'idle' or 'stop' call.
+        */
+       int (*v3_cpuresume)(unsigned int whichcpu);
+};
+
+/* Routines for traversing the prom device tree. */
+struct linux_nodeops {
+       int (*no_nextnode)(int node);
+       int (*no_child)(int node);
+       int (*no_proplen)(int node, char *name);
+       int (*no_getprop)(int node, char *name, char *val);
+       int (*no_setprop)(int node, char *name, char *val, int len);
+       char * (*no_nextprop)(int node, char *name);
+};
+
+/* More fun PROM structures for device probing. */
+#define PROMREG_MAX     16
+#define PROMVADDR_MAX   16
+#define PROMINTR_MAX    15
+
+struct linux_prom_registers {
+       unsigned int which_io;         /* is this in OBIO space? */
+       unsigned int phys_addr;        /* The physical address of this register */
+       unsigned int reg_size;         /* How many bytes does this register take up? */
+};
+
+struct linux_prom_irqs {
+       int pri;    /* IRQ priority */
+       int vector; /* This is foobar, what does it do? */
+};
+
+/* Element of the "ranges" vector */
+struct linux_prom_ranges {
+       unsigned int ot_child_space;
+       unsigned int ot_child_base;             /* Bus feels this */
+       unsigned int ot_parent_space;
+       unsigned int ot_parent_base;            /* CPU looks from here */
+       unsigned int or_size;
+};
+
+/* Ranges and reg properties are a bit different for PCI. */
+struct linux_prom_pci_registers {
+       /*
+        * We don't know what information this field contain.
+        * We guess, PCI device function is in bits 15:8
+        * So, ...
+        */
+       unsigned int which_io;  /* Let it be which_io */
+
+       unsigned int phys_hi;
+       unsigned int phys_lo;
+
+       unsigned int size_hi;
+       unsigned int size_lo;
+};
+
+struct linux_prom_pci_ranges {
+       unsigned int child_phys_hi;     /* Only certain bits are encoded here. */
+       unsigned int child_phys_mid;
+       unsigned int child_phys_lo;
+
+       unsigned int parent_phys_hi;
+       unsigned int parent_phys_lo;
+
+       unsigned int size_hi;
+       unsigned int size_lo;
+};
+
+struct linux_prom_pci_assigned_addresses {
+       unsigned int which_io;
+
+       unsigned int phys_hi;
+       unsigned int phys_lo;
+
+       unsigned int size_hi;
+       unsigned int size_lo;
+};
+
+struct linux_prom_ebus_ranges {
+       unsigned int child_phys_hi;
+       unsigned int child_phys_lo;
+
+       unsigned int parent_phys_hi;
+       unsigned int parent_phys_mid;
+       unsigned int parent_phys_lo;
+
+       unsigned int size;
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__SPARC_OPENPROM_H) */
diff --git a/include/asm-sparc/openprom_64.h b/include/asm-sparc/openprom_64.h
new file mode 100644 (file)
index 0000000..b69e4a8
--- /dev/null
@@ -0,0 +1,280 @@
+#ifndef __SPARC64_OPENPROM_H
+#define __SPARC64_OPENPROM_H
+
+/* openprom.h:  Prom structures and defines for access to the OPENBOOT
+ *              prom routines and data areas.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __ASSEMBLY__
+/* V0 prom device operations. */
+struct linux_dev_v0_funcs {
+       int (*v0_devopen)(char *device_str);
+       int (*v0_devclose)(int dev_desc);
+       int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
+       int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
+       int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf);
+       int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf);
+       int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
+       int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
+       int (*v0_seekdev)(int dev_desc, long logical_offst, int from);
+};
+
+/* V2 and later prom device operations. */
+struct linux_dev_v2_funcs {
+       int (*v2_inst2pkg)(int d);      /* Convert ihandle to phandle */
+       char * (*v2_dumb_mem_alloc)(char *va, unsigned sz);
+       void (*v2_dumb_mem_free)(char *va, unsigned sz);
+
+       /* To map devices into virtual I/O space. */
+       char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz);
+       void (*v2_dumb_munmap)(char *virta, unsigned size);
+
+       int (*v2_dev_open)(char *devpath);
+       void (*v2_dev_close)(int d);
+       int (*v2_dev_read)(int d, char *buf, int nbytes);
+       int (*v2_dev_write)(int d, char *buf, int nbytes);
+       int (*v2_dev_seek)(int d, int hi, int lo);
+
+       /* Never issued (multistage load support) */
+       void (*v2_wheee2)(void);
+       void (*v2_wheee3)(void);
+};
+
+struct linux_mlist_v0 {
+       struct linux_mlist_v0 *theres_more;
+       unsigned start_adr;
+       unsigned num_bytes;
+};
+
+struct linux_mem_v0 {
+       struct linux_mlist_v0 **v0_totphys;
+       struct linux_mlist_v0 **v0_prommap;
+       struct linux_mlist_v0 **v0_available; /* What we can use */
+};
+
+/* Arguments sent to the kernel from the boot prompt. */
+struct linux_arguments_v0 {
+       char *argv[8];
+       char args[100];
+       char boot_dev[2];
+       int boot_dev_ctrl;
+       int boot_dev_unit;
+       int dev_partition;
+       char *kernel_file_name;
+       void *aieee1;           /* XXX */
+};
+
+/* V2 and up boot things. */
+struct linux_bootargs_v2 {
+       char **bootpath;
+       char **bootargs;
+       int *fd_stdin;
+       int *fd_stdout;
+};
+
+/* The top level PROM vector. */
+struct linux_romvec {
+       /* Version numbers. */
+       unsigned int pv_magic_cookie;
+       unsigned int pv_romvers;
+       unsigned int pv_plugin_revision;
+       unsigned int pv_printrev;
+
+       /* Version 0 memory descriptors. */
+       struct linux_mem_v0 pv_v0mem;
+
+       /* Node operations. */
+       struct linux_nodeops *pv_nodeops;
+
+       char **pv_bootstr;
+       struct linux_dev_v0_funcs pv_v0devops;
+
+       char *pv_stdin;
+       char *pv_stdout;
+#define        PROMDEV_KBD     0               /* input from keyboard */
+#define        PROMDEV_SCREEN  0               /* output to screen */
+#define        PROMDEV_TTYA    1               /* in/out to ttya */
+#define        PROMDEV_TTYB    2               /* in/out to ttyb */
+
+       /* Blocking getchar/putchar.  NOT REENTRANT! (grr) */
+       int (*pv_getchar)(void);
+       void (*pv_putchar)(int ch);
+
+       /* Non-blocking variants. */
+       int (*pv_nbgetchar)(void);
+       int (*pv_nbputchar)(int ch);
+
+       void (*pv_putstr)(char *str, int len);
+
+       /* Miscellany. */
+       void (*pv_reboot)(char *bootstr);
+       void (*pv_printf)(__const__ char *fmt, ...);
+       void (*pv_abort)(void);
+       __volatile__ int *pv_ticks;
+       void (*pv_halt)(void);
+       void (**pv_synchook)(void);
+
+       /* Evaluate a forth string, not different proto for V0 and V2->up. */
+       union {
+               void (*v0_eval)(int len, char *str);
+               void (*v2_eval)(char *str);
+       } pv_fortheval;
+
+       struct linux_arguments_v0 **pv_v0bootargs;
+
+       /* Get ether address. */
+       unsigned int (*pv_enaddr)(int d, char *enaddr);
+
+       struct linux_bootargs_v2 pv_v2bootargs;
+       struct linux_dev_v2_funcs pv_v2devops;
+
+       int filler[15];
+
+       /* This one is sun4c/sun4 only. */
+       void (*pv_setctxt)(int ctxt, char *va, int pmeg);
+
+       /* Prom version 3 Multiprocessor routines. This stuff is crazy.
+        * No joke. Calling these when there is only one cpu probably
+        * crashes the machine, have to test this. :-)
+        */
+
+       /* v3_cpustart() will start the cpu 'whichcpu' in mmu-context
+        * 'thiscontext' executing at address 'prog_counter'
+        */
+       int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr,
+                          int thiscontext, char *prog_counter);
+
+       /* v3_cpustop() will cause cpu 'whichcpu' to stop executing
+        * until a resume cpu call is made.
+        */
+       int (*v3_cpustop)(unsigned int whichcpu);
+
+       /* v3_cpuidle() will idle cpu 'whichcpu' until a stop or
+        * resume cpu call is made.
+        */
+       int (*v3_cpuidle)(unsigned int whichcpu);
+
+       /* v3_cpuresume() will resume processor 'whichcpu' executing
+        * starting with whatever 'pc' and 'npc' were left at the
+        * last 'idle' or 'stop' call.
+        */
+       int (*v3_cpuresume)(unsigned int whichcpu);
+};
+
+/* Routines for traversing the prom device tree. */
+struct linux_nodeops {
+       int (*no_nextnode)(int node);
+       int (*no_child)(int node);
+       int (*no_proplen)(int node, char *name);
+       int (*no_getprop)(int node, char *name, char *val);
+       int (*no_setprop)(int node, char *name, char *val, int len);
+       char * (*no_nextprop)(int node, char *name);
+};
+
+/* More fun PROM structures for device probing. */
+#define PROMREG_MAX     24
+#define PROMVADDR_MAX   16
+#define PROMINTR_MAX    32
+
+struct linux_prom_registers {
+       unsigned which_io;      /* hi part of physical address                  */
+       unsigned phys_addr;     /* The physical address of this register        */
+       int reg_size;           /* How many bytes does this register take up?   */
+};
+
+struct linux_prom64_registers {
+       unsigned long phys_addr;
+       unsigned long reg_size;
+};
+
+struct linux_prom_irqs {
+       int pri;    /* IRQ priority */
+       int vector; /* This is foobar, what does it do? */
+};
+
+/* Element of the "ranges" vector */
+struct linux_prom_ranges {
+       unsigned int ot_child_space;
+       unsigned int ot_child_base;             /* Bus feels this */
+       unsigned int ot_parent_space;
+       unsigned int ot_parent_base;            /* CPU looks from here */
+       unsigned int or_size;
+};
+
+struct linux_prom64_ranges {
+       unsigned long ot_child_base;            /* Bus feels this */
+       unsigned long ot_parent_base;           /* CPU looks from here */
+       unsigned long or_size;
+};
+
+/* Ranges and reg properties are a bit different for PCI. */
+struct linux_prom_pci_registers {
+       unsigned int phys_hi;
+       unsigned int phys_mid;
+       unsigned int phys_lo;
+
+       unsigned int size_hi;
+       unsigned int size_lo;
+};
+
+struct linux_prom_pci_ranges {
+       unsigned int child_phys_hi;     /* Only certain bits are encoded here. */
+       unsigned int child_phys_mid;
+       unsigned int child_phys_lo;
+
+       unsigned int parent_phys_hi;
+       unsigned int parent_phys_lo;
+
+       unsigned int size_hi;
+       unsigned int size_lo;
+};
+
+struct linux_prom_pci_intmap {
+       unsigned int phys_hi;
+       unsigned int phys_mid;
+       unsigned int phys_lo;
+
+       unsigned int interrupt;
+
+       int          cnode;
+       unsigned int cinterrupt;
+};
+
+struct linux_prom_pci_intmask {
+       unsigned int phys_hi;
+       unsigned int phys_mid;
+       unsigned int phys_lo;
+       unsigned int interrupt;
+};
+
+struct linux_prom_ebus_ranges {
+       unsigned int child_phys_hi;
+       unsigned int child_phys_lo;
+
+       unsigned int parent_phys_hi;
+       unsigned int parent_phys_mid;
+       unsigned int parent_phys_lo;
+
+       unsigned int size;
+};
+
+struct linux_prom_ebus_intmap {
+       unsigned int phys_hi;
+       unsigned int phys_lo;
+
+       unsigned int interrupt;
+
+       int          cnode;
+       unsigned int cinterrupt;
+};
+
+struct linux_prom_ebus_intmask {
+       unsigned int phys_hi;
+       unsigned int phys_lo;
+       unsigned int interrupt;
+};
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__SPARC64_OPENPROM_H) */
index 61c3ca6a8ac3965eece1dea85da99b8b8bad0bbc..e88d7c04a292279013e44b15a83843752d4dffa0 100644 (file)
@@ -1,273 +1,8 @@
-/*
- * oplib.h:  Describes the interface and available routines in the
- *           Linux Prom library.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef __SPARC_OPLIB_H
-#define __SPARC_OPLIB_H
-
-#include <asm/openprom.h>
-#include <linux/spinlock.h>
-#include <linux/compiler.h>
-
-/* The master romvec pointer... */
-extern struct linux_romvec *romvec;
-
-/* Enumeration to describe the prom major version we have detected. */
-enum prom_major_version {
-       PROM_V0,      /* Original sun4c V0 prom */
-       PROM_V2,      /* sun4c and early sun4m V2 prom */
-       PROM_V3,      /* sun4m and later, up to sun4d/sun4e machines V3 */
-       PROM_P1275,   /* IEEE compliant ISA based Sun PROM, only sun4u */
-        PROM_AP1000,  /* actually no prom at all */
-       PROM_SUN4,    /* Old sun4 proms are totally different, but we'll shoehorn it to make it fit */
-};
-
-extern enum prom_major_version prom_vers;
-/* Revision, and firmware revision. */
-extern unsigned int prom_rev, prom_prev;
-
-/* Root node of the prom device tree, this stays constant after
- * initialization is complete.
- */
-extern int prom_root_node;
-
-/* Pointer to prom structure containing the device tree traversal
- * and usage utility functions.  Only prom-lib should use these,
- * users use the interface defined by the library only!
- */
-extern struct linux_nodeops *prom_nodeops;
-
-/* The functions... */
-
-/* You must call prom_init() before using any of the library services,
- * preferably as early as possible.  Pass it the romvec pointer.
- */
-extern void prom_init(struct linux_romvec *rom_ptr);
-
-/* Boot argument acquisition, returns the boot command line string. */
-extern char *prom_getbootargs(void);
-
-/* Device utilities. */
-
-/* Map and unmap devices in IO space at virtual addresses. Note that the
- * virtual address you pass is a request and the prom may put your mappings
- * somewhere else, so check your return value as that is where your new
- * mappings really are!
- *
- * Another note, these are only available on V2 or higher proms!
- */
-extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes);
-extern void prom_unmapio(char *virt_addr, unsigned int num_bytes);
-
-/* Device operations. */
-
-/* Open the device described by the passed string.  Note, that the format
- * of the string is different on V0 vs. V2->higher proms.  The caller must
- * know what he/she is doing!  Returns the device descriptor, an int.
- */
-extern int prom_devopen(char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
-                     unsigned int seek_lowval);
-
-/* Miscellaneous routines, don't really fit in any category per se. */
-
-/* Reboot the machine with the command line passed. */
-extern void prom_reboot(char *boot_command);
-
-/* Evaluate the forth string passed. */
-extern void prom_feval(char *forth_string);
-
-/* Enter the prom, with possibility of continuation with the 'go'
- * command in newer proms.
- */
-extern void prom_cmdline(void);
-
-/* Enter the prom, with no chance of continuation for the stand-alone
- * which calls this.
- */
-extern void prom_halt(void) __attribute__ ((noreturn));
-
-/* Set the PROM 'sync' callback function to the passed function pointer.
- * When the user gives the 'sync' command at the prom prompt while the
- * kernel is still active, the prom will call this routine.
- *
- * XXX The arguments are different on V0 vs. V2->higher proms, grrr! XXX
- */
-typedef void (*sync_func_t)(void);
-extern void prom_setsync(sync_func_t func_ptr);
-
-/* Acquire the IDPROM of the root node in the prom device tree.  This
- * gets passed a buffer where you would like it stuffed.  The return value
- * is the format type of this idprom or 0xff on error.
- */
-extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
-
-/* Get the prom major version. */
-extern int prom_version(void);
-
-/* Get the prom plugin revision. */
-extern int prom_getrev(void);
-
-/* Get the prom firmware revision. */
-extern int prom_getprev(void);
-
-/* Character operations to/from the console.... */
-
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
-/* Blocking get character from console. */
-extern char prom_getchar(void);
-
-/* Blocking put character to console. */
-extern void prom_putchar(char character);
-
-/* Prom's internal routines, don't use in kernel/boot code. */
-extern void prom_printf(char *fmt, ...);
-extern void prom_write(const char *buf, unsigned int len);
-
-/* Multiprocessor operations... */
-
-/* Start the CPU with the given device tree node, context table, and context
- * at the passed program counter.
- */
-extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
-                        int context, char *program_counter);
-
-/* Stop the CPU with the passed device tree node. */
-extern int prom_stopcpu(int cpunode);
-
-/* Idle the CPU with the passed device tree node. */
-extern int prom_idlecpu(int cpunode);
-
-/* Re-Start the CPU with the passed device tree node. */
-extern int prom_restartcpu(int cpunode);
-
-/* PROM memory allocation facilities... */
-
-/* Allocated at possibly the given virtual address a chunk of the
- * indicated size.
- */
-extern char *prom_alloc(char *virt_hint, unsigned int size);
-
-/* Free a previously allocated chunk. */
-extern void prom_free(char *virt_addr, unsigned int size);
-
-/* Sun4/sun4c specific memory-management startup hook. */
-
-/* Map the passed segment in the given context at the passed
- * virtual address.
- */
-extern void prom_putsegment(int context, unsigned long virt_addr,
-                           int physical_segment);
-
-
-/* PROM device tree traversal functions... */
-
-#ifdef PROMLIB_INTERNAL
-
-/* Internal version of prom_getchild. */
-extern int __prom_getchild(int parent_node);
-
-/* Internal version of prom_getsibling. */
-extern int __prom_getsibling(int node);
-
+#ifndef ___ASM_SPARC_OPLIB_H
+#define ___ASM_SPARC_OPLIB_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/oplib_64.h>
+#else
+#include <asm-sparc/oplib_32.h>
+#endif
 #endif
-
-
-/* Get the child node of the given node, or zero if no child exists. */
-extern int prom_getchild(int parent_node);
-
-/* Get the next sibling node of the given node, or zero if no further
- * siblings exist.
- */
-extern int prom_getsibling(int node);
-
-/* Get the length, at the passed node, of the given property type.
- * Returns -1 on error (ie. no such property at this node).
- */
-extern int prom_getproplen(int thisnode, char *property);
-
-/* Fetch the requested property using the given buffer.  Returns
- * the number of bytes the prom put into your buffer or -1 on error.
- */
-extern int __must_check prom_getproperty(int thisnode, char *property,
-                                        char *prop_buffer, int propbuf_size);
-
-/* Acquire an integer property. */
-extern int prom_getint(int node, char *property);
-
-/* Acquire an integer property, with a default value. */
-extern int prom_getintdefault(int node, char *property, int defval);
-
-/* Acquire a boolean property, 0=FALSE 1=TRUE. */
-extern int prom_getbool(int node, char *prop);
-
-/* Acquire a string property, null string on error. */
-extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
-
-/* Does the passed node have the given "name"? YES=1 NO=0 */
-extern int prom_nodematch(int thisnode, char *name);
-
-/* Search all siblings starting at the passed node for "name" matching
- * the given string.  Returns the node on success, zero on failure.
- */
-extern int prom_searchsiblings(int node_start, char *name);
-
-/* Return the first property type, as a string, for the given node.
- * Returns a null string on error.
- */
-extern char *prom_firstprop(int node, char *buffer);
-
-/* Returns the next property after the passed property for the given
- * node.  Returns null string on failure.
- */
-extern char *prom_nextprop(int node, char *prev_property, char *buffer);
-
-/* Returns phandle of the path specified */
-extern int prom_finddevice(char *name);
-
-/* Returns 1 if the specified node has given property. */
-extern int prom_node_has_property(int node, char *property);
-
-/* Set the indicated property at the given node with the passed value.
- * Returns the number of bytes of your value that the prom took.
- */
-extern int prom_setprop(int node, char *prop_name, char *prop_value,
-                       int value_size);
-                       
-extern int prom_pathtoinode(char *path);
-extern int prom_inst2pkg(int);
-
-/* Dorking with Bus ranges... */
-
-/* Apply promlib probes OBIO ranges to registers. */
-extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs);
-
-/* Apply ranges of any prom node (and optionally parent node as well) to registers. */
-extern void prom_apply_generic_ranges(int node, int parent, 
-                                     struct linux_prom_registers *sbusregs, int nregs);
-
-/* CPU probing helpers.  */
-int cpu_find_by_instance(int instance, int *prom_node, int *mid);
-int cpu_find_by_mid(int mid, int *prom_node);
-int cpu_get_hwmid(int prom_node);
-
-extern spinlock_t prom_lock;
-
-#endif /* !(__SPARC_OPLIB_H) */
diff --git a/include/asm-sparc/oplib_32.h b/include/asm-sparc/oplib_32.h
new file mode 100644 (file)
index 0000000..b2631da
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * oplib.h:  Describes the interface and available routines in the
+ *           Linux Prom library.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __SPARC_OPLIB_H
+#define __SPARC_OPLIB_H
+
+#include <asm/openprom.h>
+#include <linux/spinlock.h>
+#include <linux/compiler.h>
+
+/* The master romvec pointer... */
+extern struct linux_romvec *romvec;
+
+/* Enumeration to describe the prom major version we have detected. */
+enum prom_major_version {
+       PROM_V0,      /* Original sun4c V0 prom */
+       PROM_V2,      /* sun4c and early sun4m V2 prom */
+       PROM_V3,      /* sun4m and later, up to sun4d/sun4e machines V3 */
+       PROM_P1275,   /* IEEE compliant ISA based Sun PROM, only sun4u */
+       PROM_SUN4,    /* Old sun4 proms are totally different, but we'll shoehorn it to make it fit */
+};
+
+extern enum prom_major_version prom_vers;
+/* Revision, and firmware revision. */
+extern unsigned int prom_rev, prom_prev;
+
+/* Root node of the prom device tree, this stays constant after
+ * initialization is complete.
+ */
+extern int prom_root_node;
+
+/* Pointer to prom structure containing the device tree traversal
+ * and usage utility functions.  Only prom-lib should use these,
+ * users use the interface defined by the library only!
+ */
+extern struct linux_nodeops *prom_nodeops;
+
+/* The functions... */
+
+/* You must call prom_init() before using any of the library services,
+ * preferably as early as possible.  Pass it the romvec pointer.
+ */
+extern void prom_init(struct linux_romvec *rom_ptr);
+
+/* Boot argument acquisition, returns the boot command line string. */
+extern char *prom_getbootargs(void);
+
+/* Device utilities. */
+
+/* Map and unmap devices in IO space at virtual addresses. Note that the
+ * virtual address you pass is a request and the prom may put your mappings
+ * somewhere else, so check your return value as that is where your new
+ * mappings really are!
+ *
+ * Another note, these are only available on V2 or higher proms!
+ */
+extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes);
+extern void prom_unmapio(char *virt_addr, unsigned int num_bytes);
+
+/* Device operations. */
+
+/* Open the device described by the passed string.  Note, that the format
+ * of the string is different on V0 vs. V2->higher proms.  The caller must
+ * know what he/she is doing!  Returns the device descriptor, an int.
+ */
+extern int prom_devopen(char *device_string);
+
+/* Close a previously opened device described by the passed integer
+ * descriptor.
+ */
+extern int prom_devclose(int device_handle);
+
+/* Do a seek operation on the device described by the passed integer
+ * descriptor.
+ */
+extern void prom_seek(int device_handle, unsigned int seek_hival,
+                     unsigned int seek_lowval);
+
+/* Miscellaneous routines, don't really fit in any category per se. */
+
+/* Reboot the machine with the command line passed. */
+extern void prom_reboot(char *boot_command);
+
+/* Evaluate the forth string passed. */
+extern void prom_feval(char *forth_string);
+
+/* Enter the prom, with possibility of continuation with the 'go'
+ * command in newer proms.
+ */
+extern void prom_cmdline(void);
+
+/* Enter the prom, with no chance of continuation for the stand-alone
+ * which calls this.
+ */
+extern void prom_halt(void) __attribute__ ((noreturn));
+
+/* Set the PROM 'sync' callback function to the passed function pointer.
+ * When the user gives the 'sync' command at the prom prompt while the
+ * kernel is still active, the prom will call this routine.
+ *
+ * XXX The arguments are different on V0 vs. V2->higher proms, grrr! XXX
+ */
+typedef void (*sync_func_t)(void);
+extern void prom_setsync(sync_func_t func_ptr);
+
+/* Acquire the IDPROM of the root node in the prom device tree.  This
+ * gets passed a buffer where you would like it stuffed.  The return value
+ * is the format type of this idprom or 0xff on error.
+ */
+extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
+
+/* Get the prom major version. */
+extern int prom_version(void);
+
+/* Get the prom plugin revision. */
+extern int prom_getrev(void);
+
+/* Get the prom firmware revision. */
+extern int prom_getprev(void);
+
+/* Character operations to/from the console.... */
+
+/* Non-blocking get character from console. */
+extern int prom_nbgetchar(void);
+
+/* Non-blocking put character to console. */
+extern int prom_nbputchar(char character);
+
+/* Blocking get character from console. */
+extern char prom_getchar(void);
+
+/* Blocking put character to console. */
+extern void prom_putchar(char character);
+
+/* Prom's internal routines, don't use in kernel/boot code. */
+extern void prom_printf(char *fmt, ...);
+extern void prom_write(const char *buf, unsigned int len);
+
+/* Multiprocessor operations... */
+
+/* Start the CPU with the given device tree node, context table, and context
+ * at the passed program counter.
+ */
+extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
+                        int context, char *program_counter);
+
+/* Stop the CPU with the passed device tree node. */
+extern int prom_stopcpu(int cpunode);
+
+/* Idle the CPU with the passed device tree node. */
+extern int prom_idlecpu(int cpunode);
+
+/* Re-Start the CPU with the passed device tree node. */
+extern int prom_restartcpu(int cpunode);
+
+/* PROM memory allocation facilities... */
+
+/* Allocated at possibly the given virtual address a chunk of the
+ * indicated size.
+ */
+extern char *prom_alloc(char *virt_hint, unsigned int size);
+
+/* Free a previously allocated chunk. */
+extern void prom_free(char *virt_addr, unsigned int size);
+
+/* Sun4/sun4c specific memory-management startup hook. */
+
+/* Map the passed segment in the given context at the passed
+ * virtual address.
+ */
+extern void prom_putsegment(int context, unsigned long virt_addr,
+                           int physical_segment);
+
+
+/* PROM device tree traversal functions... */
+
+#ifdef PROMLIB_INTERNAL
+
+/* Internal version of prom_getchild. */
+extern int __prom_getchild(int parent_node);
+
+/* Internal version of prom_getsibling. */
+extern int __prom_getsibling(int node);
+
+#endif
+
+
+/* Get the child node of the given node, or zero if no child exists. */
+extern int prom_getchild(int parent_node);
+
+/* Get the next sibling node of the given node, or zero if no further
+ * siblings exist.
+ */
+extern int prom_getsibling(int node);
+
+/* Get the length, at the passed node, of the given property type.
+ * Returns -1 on error (ie. no such property at this node).
+ */
+extern int prom_getproplen(int thisnode, char *property);
+
+/* Fetch the requested property using the given buffer.  Returns
+ * the number of bytes the prom put into your buffer or -1 on error.
+ */
+extern int __must_check prom_getproperty(int thisnode, char *property,
+                                        char *prop_buffer, int propbuf_size);
+
+/* Acquire an integer property. */
+extern int prom_getint(int node, char *property);
+
+/* Acquire an integer property, with a default value. */
+extern int prom_getintdefault(int node, char *property, int defval);
+
+/* Acquire a boolean property, 0=FALSE 1=TRUE. */
+extern int prom_getbool(int node, char *prop);
+
+/* Acquire a string property, null string on error. */
+extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
+
+/* Does the passed node have the given "name"? YES=1 NO=0 */
+extern int prom_nodematch(int thisnode, char *name);
+
+/* Search all siblings starting at the passed node for "name" matching
+ * the given string.  Returns the node on success, zero on failure.
+ */
+extern int prom_searchsiblings(int node_start, char *name);
+
+/* Return the first property type, as a string, for the given node.
+ * Returns a null string on error.
+ */
+extern char *prom_firstprop(int node, char *buffer);
+
+/* Returns the next property after the passed property for the given
+ * node.  Returns null string on failure.
+ */
+extern char *prom_nextprop(int node, char *prev_property, char *buffer);
+
+/* Returns phandle of the path specified */
+extern int prom_finddevice(char *name);
+
+/* Returns 1 if the specified node has given property. */
+extern int prom_node_has_property(int node, char *property);
+
+/* Set the indicated property at the given node with the passed value.
+ * Returns the number of bytes of your value that the prom took.
+ */
+extern int prom_setprop(int node, char *prop_name, char *prop_value,
+                       int value_size);
+
+extern int prom_pathtoinode(char *path);
+extern int prom_inst2pkg(int);
+
+/* Dorking with Bus ranges... */
+
+/* Apply promlib probes OBIO ranges to registers. */
+extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs);
+
+/* Apply ranges of any prom node (and optionally parent node as well) to registers. */
+extern void prom_apply_generic_ranges(int node, int parent,
+                                     struct linux_prom_registers *sbusregs, int nregs);
+
+/* CPU probing helpers.  */
+int cpu_find_by_instance(int instance, int *prom_node, int *mid);
+int cpu_find_by_mid(int mid, int *prom_node);
+int cpu_get_hwmid(int prom_node);
+
+extern spinlock_t prom_lock;
+
+#endif /* !(__SPARC_OPLIB_H) */
diff --git a/include/asm-sparc/oplib_64.h b/include/asm-sparc/oplib_64.h
new file mode 100644 (file)
index 0000000..6d2c2ca
--- /dev/null
@@ -0,0 +1,322 @@
+/* oplib.h:  Describes the interface and available routines in the
+ *           Linux Prom library.
+ *
+ * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#ifndef __SPARC64_OPLIB_H
+#define __SPARC64_OPLIB_H
+
+#include <asm/openprom.h>
+
+/* OBP version string. */
+extern char prom_version[];
+
+/* Root node of the prom device tree, this stays constant after
+ * initialization is complete.
+ */
+extern int prom_root_node;
+
+/* PROM stdin and stdout */
+extern int prom_stdin, prom_stdout;
+
+/* /chosen node of the prom device tree, this stays constant after
+ * initialization is complete.
+ */
+extern int prom_chosen_node;
+
+/* Helper values and strings in arch/sparc64/kernel/head.S */
+extern const char prom_peer_name[];
+extern const char prom_compatible_name[];
+extern const char prom_root_compatible[];
+extern const char prom_cpu_compatible[];
+extern const char prom_finddev_name[];
+extern const char prom_chosen_path[];
+extern const char prom_cpu_path[];
+extern const char prom_getprop_name[];
+extern const char prom_mmu_name[];
+extern const char prom_callmethod_name[];
+extern const char prom_translate_name[];
+extern const char prom_map_name[];
+extern const char prom_unmap_name[];
+extern int prom_mmu_ihandle_cache;
+extern unsigned int prom_boot_mapped_pc;
+extern unsigned int prom_boot_mapping_mode;
+extern unsigned long prom_boot_mapping_phys_high, prom_boot_mapping_phys_low;
+
+struct linux_mlist_p1275 {
+       struct linux_mlist_p1275 *theres_more;
+       unsigned long start_adr;
+       unsigned long num_bytes;
+};
+
+struct linux_mem_p1275 {
+       struct linux_mlist_p1275 **p1275_totphys;
+       struct linux_mlist_p1275 **p1275_prommap;
+       struct linux_mlist_p1275 **p1275_available; /* What we can use */
+};
+
+/* The functions... */
+
+/* You must call prom_init() before using any of the library services,
+ * preferably as early as possible.  Pass it the romvec pointer.
+ */
+extern void prom_init(void *cif_handler, void *cif_stack);
+
+/* Boot argument acquisition, returns the boot command line string. */
+extern char *prom_getbootargs(void);
+
+/* Device utilities. */
+
+/* Device operations. */
+
+/* Open the device described by the passed string.  Note, that the format
+ * of the string is different on V0 vs. V2->higher proms.  The caller must
+ * know what he/she is doing!  Returns the device descriptor, an int.
+ */
+extern int prom_devopen(const char *device_string);
+
+/* Close a previously opened device described by the passed integer
+ * descriptor.
+ */
+extern int prom_devclose(int device_handle);
+
+/* Do a seek operation on the device described by the passed integer
+ * descriptor.
+ */
+extern void prom_seek(int device_handle, unsigned int seek_hival,
+                     unsigned int seek_lowval);
+
+/* Miscellaneous routines, don't really fit in any category per se. */
+
+/* Reboot the machine with the command line passed. */
+extern void prom_reboot(const char *boot_command);
+
+/* Evaluate the forth string passed. */
+extern void prom_feval(const char *forth_string);
+
+/* Enter the prom, with possibility of continuation with the 'go'
+ * command in newer proms.
+ */
+extern void prom_cmdline(void);
+
+/* Enter the prom, with no chance of continuation for the stand-alone
+ * which calls this.
+ */
+extern void prom_halt(void) __attribute__ ((noreturn));
+
+/* Halt and power-off the machine. */
+extern void prom_halt_power_off(void) __attribute__ ((noreturn));
+
+/* Set the PROM 'sync' callback function to the passed function pointer.
+ * When the user gives the 'sync' command at the prom prompt while the
+ * kernel is still active, the prom will call this routine.
+ *
+ */
+typedef int (*callback_func_t)(long *cmd);
+extern void prom_setcallback(callback_func_t func_ptr);
+
+/* Acquire the IDPROM of the root node in the prom device tree.  This
+ * gets passed a buffer where you would like it stuffed.  The return value
+ * is the format type of this idprom or 0xff on error.
+ */
+extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
+
+/* Character operations to/from the console.... */
+
+/* Non-blocking get character from console. */
+extern int prom_nbgetchar(void);
+
+/* Non-blocking put character to console. */
+extern int prom_nbputchar(char character);
+
+/* Blocking get character from console. */
+extern char prom_getchar(void);
+
+/* Blocking put character to console. */
+extern void prom_putchar(char character);
+
+/* Prom's internal routines, don't use in kernel/boot code. */
+extern void prom_printf(const char *fmt, ...);
+extern void prom_write(const char *buf, unsigned int len);
+
+/* Multiprocessor operations... */
+#ifdef CONFIG_SMP
+/* Start the CPU with the given device tree node at the passed program
+ * counter with the given arg passed in via register %o0.
+ */
+extern void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg);
+
+/* Start the CPU with the given cpu ID at the passed program
+ * counter with the given arg passed in via register %o0.
+ */
+extern void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg);
+
+/* Stop the CPU with the given cpu ID.  */
+extern void prom_stopcpu_cpuid(int cpuid);
+
+/* Stop the current CPU. */
+extern void prom_stopself(void);
+
+/* Idle the current CPU. */
+extern void prom_idleself(void);
+
+/* Resume the CPU with the passed device tree node. */
+extern void prom_resumecpu(int cpunode);
+#endif
+
+/* Power management interfaces. */
+
+/* Put the current CPU to sleep. */
+extern void prom_sleepself(void);
+
+/* Put the entire system to sleep. */
+extern int prom_sleepsystem(void);
+
+/* Initiate a wakeup event. */
+extern int prom_wakeupsystem(void);
+
+/* MMU and memory related OBP interfaces. */
+
+/* Get unique string identifying SIMM at given physical address. */
+extern int prom_getunumber(int syndrome_code,
+                          unsigned long phys_addr,
+                          char *buf, int buflen);
+
+/* Retain physical memory to the caller across soft resets. */
+extern unsigned long prom_retain(const char *name,
+                                unsigned long pa_low, unsigned long pa_high,
+                                long size, long align);
+
+/* Load explicit I/D TLB entries into the calling processor. */
+extern long prom_itlb_load(unsigned long index,
+                          unsigned long tte_data,
+                          unsigned long vaddr);
+
+extern long prom_dtlb_load(unsigned long index,
+                          unsigned long tte_data,
+                          unsigned long vaddr);
+
+/* Map/Unmap client program address ranges.  First the format of
+ * the mapping mode argument.
+ */
+#define PROM_MAP_WRITE 0x0001 /* Writable */
+#define PROM_MAP_READ  0x0002 /* Readable - sw */
+#define PROM_MAP_EXEC  0x0004 /* Executable - sw */
+#define PROM_MAP_LOCKED        0x0010 /* Locked, use i/dtlb load calls for this instead */
+#define PROM_MAP_CACHED        0x0020 /* Cacheable in both L1 and L2 caches */
+#define PROM_MAP_SE    0x0040 /* Side-Effects */
+#define PROM_MAP_GLOB  0x0080 /* Global */
+#define PROM_MAP_IE    0x0100 /* Invert-Endianness */
+#define PROM_MAP_DEFAULT (PROM_MAP_WRITE | PROM_MAP_READ | PROM_MAP_EXEC | PROM_MAP_CACHED)
+
+extern int prom_map(int mode, unsigned long size,
+                   unsigned long vaddr, unsigned long paddr);
+extern void prom_unmap(unsigned long size, unsigned long vaddr);
+
+
+/* PROM device tree traversal functions... */
+
+#ifdef PROMLIB_INTERNAL
+
+/* Internal version of prom_getchild. */
+extern int __prom_getchild(int parent_node);
+
+/* Internal version of prom_getsibling. */
+extern int __prom_getsibling(int node);
+
+#endif
+
+/* Get the child node of the given node, or zero if no child exists. */
+extern int prom_getchild(int parent_node);
+
+/* Get the next sibling node of the given node, or zero if no further
+ * siblings exist.
+ */
+extern int prom_getsibling(int node);
+
+/* Get the length, at the passed node, of the given property type.
+ * Returns -1 on error (ie. no such property at this node).
+ */
+extern int prom_getproplen(int thisnode, const char *property);
+
+/* Fetch the requested property using the given buffer.  Returns
+ * the number of bytes the prom put into your buffer or -1 on error.
+ */
+extern int prom_getproperty(int thisnode, const char *property,
+                           char *prop_buffer, int propbuf_size);
+
+/* Acquire an integer property. */
+extern int prom_getint(int node, const char *property);
+
+/* Acquire an integer property, with a default value. */
+extern int prom_getintdefault(int node, const char *property, int defval);
+
+/* Acquire a boolean property, 0=FALSE 1=TRUE. */
+extern int prom_getbool(int node, const char *prop);
+
+/* Acquire a string property, null string on error. */
+extern void prom_getstring(int node, const char *prop, char *buf, int bufsize);
+
+/* Does the passed node have the given "name"? YES=1 NO=0 */
+extern int prom_nodematch(int thisnode, const char *name);
+
+/* Search all siblings starting at the passed node for "name" matching
+ * the given string.  Returns the node on success, zero on failure.
+ */
+extern int prom_searchsiblings(int node_start, const char *name);
+
+/* Return the first property type, as a string, for the given node.
+ * Returns a null string on error. Buffer should be at least 32B long.
+ */
+extern char *prom_firstprop(int node, char *buffer);
+
+/* Returns the next property after the passed property for the given
+ * node.  Returns null string on failure. Buffer should be at least 32B long.
+ */
+extern char *prom_nextprop(int node, const char *prev_property, char *buffer);
+
+/* Returns 1 if the specified node has given property. */
+extern int prom_node_has_property(int node, const char *property);
+
+/* Returns phandle of the path specified */
+extern int prom_finddevice(const char *name);
+
+/* Set the indicated property at the given node with the passed value.
+ * Returns the number of bytes of your value that the prom took.
+ */
+extern int prom_setprop(int node, const char *prop_name, char *prop_value,
+                       int value_size);
+
+extern int prom_pathtoinode(const char *path);
+extern int prom_inst2pkg(int);
+extern int prom_service_exists(const char *service_name);
+extern void prom_sun4v_guest_soft_state(void);
+
+extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
+
+/* Client interface level routines. */
+extern long p1275_cmd(const char *, long, ...);
+
+#if 0
+#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x))
+#else
+#define P1275_SIZE(x) x
+#endif
+
+/* We support at most 16 input and 1 output argument */
+#define P1275_ARG_NUMBER               0
+#define P1275_ARG_IN_STRING            1
+#define P1275_ARG_OUT_BUF              2
+#define P1275_ARG_OUT_32B              3
+#define P1275_ARG_IN_FUNCTION          4
+#define P1275_ARG_IN_BUF               5
+#define P1275_ARG_IN_64B               6
+
+#define P1275_IN(x) ((x) & 0xf)
+#define P1275_OUT(x) (((x) << 4) & 0xf0)
+#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o))
+#define P1275_ARG(n,x) ((x) << ((n)*3 + 8))
+
+#endif /* !(__SPARC64_OPLIB_H) */
index 6aa9e4c910cfcbd8f497a005b58edf1c653cb83c..f32f49fcf75c71f4cf37f4b0123dc833a1a19f7c 100644 (file)
@@ -1,165 +1,8 @@
-/*
- * page.h:  Various defines and such for MMU operations on the Sparc for
- *          the Linux kernel.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef _SPARC_PAGE_H
-#define _SPARC_PAGE_H
-
-#ifdef CONFIG_SUN4
-#define PAGE_SHIFT   13
+#ifndef ___ASM_SPARC_PAGE_H
+#define ___ASM_SPARC_PAGE_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/page_64.h>
 #else
-#define PAGE_SHIFT   12
+#include <asm-sparc/page_32.h>
 #endif
-#ifndef __ASSEMBLY__
-/* I have my suspicions... -DaveM */
-#define PAGE_SIZE    (1UL << PAGE_SHIFT)
-#else
-#define PAGE_SIZE    (1 << PAGE_SHIFT)
-#endif
-#define PAGE_MASK    (~(PAGE_SIZE-1))
-
-#include <asm/btfixup.h>
-
-#ifndef __ASSEMBLY__
-
-#define clear_page(page)        memset((void *)(page), 0, PAGE_SIZE)
-#define copy_page(to,from)     memcpy((void *)(to), (void *)(from), PAGE_SIZE)
-#define clear_user_page(addr, vaddr, page)     \
-       do {    clear_page(addr);               \
-               sparc_flush_page_to_ram(page);  \
-       } while (0)
-#define copy_user_page(to, from, vaddr, page)  \
-       do {    copy_page(to, from);            \
-               sparc_flush_page_to_ram(page);  \
-       } while (0)
-
-/* The following structure is used to hold the physical
- * memory configuration of the machine.  This is filled in
- * prom_meminit() and is later used by mem_init() to set up
- * mem_map[].  We statically allocate SPARC_PHYS_BANKS+1 of
- * these structs, this is arbitrary.  The entry after the
- * last valid one has num_bytes==0.
- */
-struct sparc_phys_banks {
-  unsigned long base_addr;
-  unsigned long num_bytes;
-};
-
-#define SPARC_PHYS_BANKS 32
-
-extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1];
-
-/* Cache alias structure.  Entry is valid if context != -1. */
-struct cache_palias {
-       unsigned long vaddr;
-       int context;
-};
-
-extern struct cache_palias *sparc_aliases;
-
-/* passing structs on the Sparc slow us down tremendously... */
-
-/* #define STRICT_MM_TYPECHECKS */
-
-#ifdef STRICT_MM_TYPECHECKS
-/*
- * These are used to make use of C type-checking..
- */
-typedef struct { unsigned long pte; } pte_t;
-typedef struct { unsigned long iopte; } iopte_t;
-typedef struct { unsigned long pmdv[16]; } pmd_t;
-typedef struct { unsigned long pgd; } pgd_t;
-typedef struct { unsigned long ctxd; } ctxd_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
-typedef struct { unsigned long iopgprot; } iopgprot_t;
-
-#define pte_val(x)     ((x).pte)
-#define iopte_val(x)   ((x).iopte)
-#define pmd_val(x)      ((x).pmdv[0])
-#define pgd_val(x)     ((x).pgd)
-#define ctxd_val(x)    ((x).ctxd)
-#define pgprot_val(x)  ((x).pgprot)
-#define iopgprot_val(x)        ((x).iopgprot)
-
-#define __pte(x)       ((pte_t) { (x) } )
-#define __iopte(x)     ((iopte_t) { (x) } )
-/* #define __pmd(x)        ((pmd_t) { (x) } ) */ /* XXX procedure with loop */
-#define __pgd(x)       ((pgd_t) { (x) } )
-#define __ctxd(x)      ((ctxd_t) { (x) } )
-#define __pgprot(x)    ((pgprot_t) { (x) } )
-#define __iopgprot(x)  ((iopgprot_t) { (x) } )
-
-#else
-/*
- * .. while these make it easier on the compiler
- */
-typedef unsigned long pte_t;
-typedef unsigned long iopte_t;
-typedef struct { unsigned long pmdv[16]; } pmd_t;
-typedef unsigned long pgd_t;
-typedef unsigned long ctxd_t;
-typedef unsigned long pgprot_t;
-typedef unsigned long iopgprot_t;
-
-#define pte_val(x)     (x)
-#define iopte_val(x)   (x)
-#define pmd_val(x)      ((x).pmdv[0])
-#define pgd_val(x)     (x)
-#define ctxd_val(x)    (x)
-#define pgprot_val(x)  (x)
-#define iopgprot_val(x)        (x)
-
-#define __pte(x)       (x)
-#define __iopte(x)     (x)
-/* #define __pmd(x)        (x) */ /* XXX later */
-#define __pgd(x)       (x)
-#define __ctxd(x)      (x)
-#define __pgprot(x)    (x)
-#define __iopgprot(x)  (x)
-
-#endif
-
-typedef struct page *pgtable_t;
-
-extern unsigned long sparc_unmapped_base;
-
-BTFIXUPDEF_SETHI(sparc_unmapped_base)
-
-#define TASK_UNMAPPED_BASE     BTFIXUP_SETHI(sparc_unmapped_base)
-
-#else /* !(__ASSEMBLY__) */
-
-#define __pgprot(x)    (x)
-
-#endif /* !(__ASSEMBLY__) */
-
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr)  (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
-#define PAGE_OFFSET    0xf0000000
-#ifndef __ASSEMBLY__
-extern unsigned long phys_base;
-extern unsigned long pfn_base;
 #endif
-#define __pa(x)                        ((unsigned long)(x) - PAGE_OFFSET + phys_base)
-#define __va(x)                        ((void *)((unsigned long) (x) - phys_base + PAGE_OFFSET))
-
-#define virt_to_phys           __pa
-#define phys_to_virt           __va
-
-#define ARCH_PFN_OFFSET                (pfn_base)
-#define virt_to_page(kaddr)    (mem_map + ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT)))
-
-#define pfn_valid(pfn)         (((pfn) >= (pfn_base)) && (((pfn)-(pfn_base)) < max_mapnr))
-#define virt_addr_valid(kaddr) ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT) < max_mapnr)
-
-#define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
-                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-#include <asm-generic/memory_model.h>
-#include <asm-generic/page.h>
-
-#endif /* _SPARC_PAGE_H */
diff --git a/include/asm-sparc/page_32.h b/include/asm-sparc/page_32.h
new file mode 100644 (file)
index 0000000..14de518
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * page.h:  Various defines and such for MMU operations on the Sparc for
+ *          the Linux kernel.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_PAGE_H
+#define _SPARC_PAGE_H
+
+#ifdef CONFIG_SUN4
+#define PAGE_SHIFT   13
+#else
+#define PAGE_SHIFT   12
+#endif
+#ifndef __ASSEMBLY__
+/* I have my suspicions... -DaveM */
+#define PAGE_SIZE    (1UL << PAGE_SHIFT)
+#else
+#define PAGE_SIZE    (1 << PAGE_SHIFT)
+#endif
+#define PAGE_MASK    (~(PAGE_SIZE-1))
+
+#include <asm/btfixup.h>
+
+#ifndef __ASSEMBLY__
+
+#define clear_page(page)        memset((void *)(page), 0, PAGE_SIZE)
+#define copy_page(to,from)     memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+#define clear_user_page(addr, vaddr, page)     \
+       do {    clear_page(addr);               \
+               sparc_flush_page_to_ram(page);  \
+       } while (0)
+#define copy_user_page(to, from, vaddr, page)  \
+       do {    copy_page(to, from);            \
+               sparc_flush_page_to_ram(page);  \
+       } while (0)
+
+/* The following structure is used to hold the physical
+ * memory configuration of the machine.  This is filled in
+ * prom_meminit() and is later used by mem_init() to set up
+ * mem_map[].  We statically allocate SPARC_PHYS_BANKS+1 of
+ * these structs, this is arbitrary.  The entry after the
+ * last valid one has num_bytes==0.
+ */
+struct sparc_phys_banks {
+  unsigned long base_addr;
+  unsigned long num_bytes;
+};
+
+#define SPARC_PHYS_BANKS 32
+
+extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1];
+
+/* Cache alias structure.  Entry is valid if context != -1. */
+struct cache_palias {
+       unsigned long vaddr;
+       int context;
+};
+
+/* passing structs on the Sparc slow us down tremendously... */
+
+/* #define STRICT_MM_TYPECHECKS */
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long iopte; } iopte_t;
+typedef struct { unsigned long pmdv[16]; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long ctxd; } ctxd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct { unsigned long iopgprot; } iopgprot_t;
+
+#define pte_val(x)     ((x).pte)
+#define iopte_val(x)   ((x).iopte)
+#define pmd_val(x)      ((x).pmdv[0])
+#define pgd_val(x)     ((x).pgd)
+#define ctxd_val(x)    ((x).ctxd)
+#define pgprot_val(x)  ((x).pgprot)
+#define iopgprot_val(x)        ((x).iopgprot)
+
+#define __pte(x)       ((pte_t) { (x) } )
+#define __iopte(x)     ((iopte_t) { (x) } )
+/* #define __pmd(x)        ((pmd_t) { (x) } ) */ /* XXX procedure with loop */
+#define __pgd(x)       ((pgd_t) { (x) } )
+#define __ctxd(x)      ((ctxd_t) { (x) } )
+#define __pgprot(x)    ((pgprot_t) { (x) } )
+#define __iopgprot(x)  ((iopgprot_t) { (x) } )
+
+#else
+/*
+ * .. while these make it easier on the compiler
+ */
+typedef unsigned long pte_t;
+typedef unsigned long iopte_t;
+typedef struct { unsigned long pmdv[16]; } pmd_t;
+typedef unsigned long pgd_t;
+typedef unsigned long ctxd_t;
+typedef unsigned long pgprot_t;
+typedef unsigned long iopgprot_t;
+
+#define pte_val(x)     (x)
+#define iopte_val(x)   (x)
+#define pmd_val(x)      ((x).pmdv[0])
+#define pgd_val(x)     (x)
+#define ctxd_val(x)    (x)
+#define pgprot_val(x)  (x)
+#define iopgprot_val(x)        (x)
+
+#define __pte(x)       (x)
+#define __iopte(x)     (x)
+/* #define __pmd(x)        (x) */ /* XXX later */
+#define __pgd(x)       (x)
+#define __ctxd(x)      (x)
+#define __pgprot(x)    (x)
+#define __iopgprot(x)  (x)
+
+#endif
+
+typedef struct page *pgtable_t;
+
+extern unsigned long sparc_unmapped_base;
+
+BTFIXUPDEF_SETHI(sparc_unmapped_base)
+
+#define TASK_UNMAPPED_BASE     BTFIXUP_SETHI(sparc_unmapped_base)
+
+#else /* !(__ASSEMBLY__) */
+
+#define __pgprot(x)    (x)
+
+#endif /* !(__ASSEMBLY__) */
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)  (((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+#define PAGE_OFFSET    0xf0000000
+#ifndef __ASSEMBLY__
+extern unsigned long phys_base;
+extern unsigned long pfn_base;
+#endif
+#define __pa(x)                        ((unsigned long)(x) - PAGE_OFFSET + phys_base)
+#define __va(x)                        ((void *)((unsigned long) (x) - phys_base + PAGE_OFFSET))
+
+#define virt_to_phys           __pa
+#define phys_to_virt           __va
+
+#define ARCH_PFN_OFFSET                (pfn_base)
+#define virt_to_page(kaddr)    (mem_map + ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT)))
+
+#define pfn_valid(pfn)         (((pfn) >= (pfn_base)) && (((pfn)-(pfn_base)) < max_mapnr))
+#define virt_addr_valid(kaddr) ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT) < max_mapnr)
+
+#define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
+                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/page.h>
+
+#endif /* _SPARC_PAGE_H */
diff --git a/include/asm-sparc/page_64.h b/include/asm-sparc/page_64.h
new file mode 100644 (file)
index 0000000..a8a2bba
--- /dev/null
@@ -0,0 +1,138 @@
+#ifndef _SPARC64_PAGE_H
+#define _SPARC64_PAGE_H
+
+#include <linux/const.h>
+
+#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
+#define PAGE_SHIFT   13
+#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
+#define PAGE_SHIFT   16
+#else
+#error No page size specified in kernel configuration
+#endif
+
+#define PAGE_SIZE    (_AC(1,UL) << PAGE_SHIFT)
+#define PAGE_MASK    (~(PAGE_SIZE-1))
+
+/* Flushing for D-cache alias handling is only needed if
+ * the page size is smaller than 16K.
+ */
+#if PAGE_SHIFT < 14
+#define DCACHE_ALIASING_POSSIBLE
+#endif
+
+#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
+#define HPAGE_SHIFT            22
+#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
+#define HPAGE_SHIFT            19
+#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
+#define HPAGE_SHIFT            16
+#endif
+
+#ifdef CONFIG_HUGETLB_PAGE
+#define HPAGE_SIZE             (_AC(1,UL) << HPAGE_SHIFT)
+#define HPAGE_MASK             (~(HPAGE_SIZE - 1UL))
+#define HUGETLB_PAGE_ORDER     (HPAGE_SHIFT - PAGE_SHIFT)
+#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+#endif
+
+#ifndef __ASSEMBLY__
+
+extern void _clear_page(void *page);
+#define clear_page(X)  _clear_page((void *)(X))
+struct page;
+extern void clear_user_page(void *addr, unsigned long vaddr, struct page *page);
+#define copy_page(X,Y) memcpy((void *)(X), (void *)(Y), PAGE_SIZE)
+extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *topage);
+
+/* Unlike sparc32, sparc64's parameter passing API is more
+ * sane in that structures which as small enough are passed
+ * in registers instead of on the stack.  Thus, setting
+ * STRICT_MM_TYPECHECKS does not generate worse code so
+ * let's enable it to get the type checking.
+ */
+
+#define STRICT_MM_TYPECHECKS
+
+#ifdef STRICT_MM_TYPECHECKS
+/* These are used to make use of C type-checking.. */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long iopte; } iopte_t;
+typedef struct { unsigned int pmd; } pmd_t;
+typedef struct { unsigned int pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)     ((x).pte)
+#define iopte_val(x)   ((x).iopte)
+#define pmd_val(x)      ((x).pmd)
+#define pgd_val(x)     ((x).pgd)
+#define pgprot_val(x)  ((x).pgprot)
+
+#define __pte(x)       ((pte_t) { (x) } )
+#define __iopte(x)     ((iopte_t) { (x) } )
+#define __pmd(x)        ((pmd_t) { (x) } )
+#define __pgd(x)       ((pgd_t) { (x) } )
+#define __pgprot(x)    ((pgprot_t) { (x) } )
+
+#else
+/* .. while these make it easier on the compiler */
+typedef unsigned long pte_t;
+typedef unsigned long iopte_t;
+typedef unsigned int pmd_t;
+typedef unsigned int pgd_t;
+typedef unsigned long pgprot_t;
+
+#define pte_val(x)     (x)
+#define iopte_val(x)   (x)
+#define pmd_val(x)      (x)
+#define pgd_val(x)     (x)
+#define pgprot_val(x)  (x)
+
+#define __pte(x)       (x)
+#define __iopte(x)     (x)
+#define __pmd(x)        (x)
+#define __pgd(x)       (x)
+#define __pgprot(x)    (x)
+
+#endif /* (STRICT_MM_TYPECHECKS) */
+
+typedef struct page *pgtable_t;
+
+#define TASK_UNMAPPED_BASE     (test_thread_flag(TIF_32BIT) ? \
+                                (_AC(0x0000000070000000,UL)) : \
+                                (_AC(0xfffff80000000000,UL) + (1UL << 32UL)))
+
+#include <asm-generic/memory_model.h>
+
+#endif /* !(__ASSEMBLY__) */
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+/* We used to stick this into a hard-coded global register (%g4)
+ * but that does not make sense anymore.
+ */
+#define PAGE_OFFSET            _AC(0xFFFFF80000000000,UL)
+
+#ifndef __ASSEMBLY__
+
+#define __pa(x)                        ((unsigned long)(x) - PAGE_OFFSET)
+#define __va(x)                        ((void *)((unsigned long) (x) + PAGE_OFFSET))
+
+#define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
+
+#define virt_to_page(kaddr)    pfn_to_page(__pa(kaddr)>>PAGE_SHIFT)
+
+#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+
+#define virt_to_phys __pa
+#define phys_to_virt __va
+
+#endif /* !(__ASSEMBLY__) */
+
+#define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
+                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#include <asm-generic/page.h>
+
+#endif /* _SPARC64_PAGE_H */
diff --git a/include/asm-sparc/parport.h b/include/asm-sparc/parport.h
new file mode 100644 (file)
index 0000000..7818b25
--- /dev/null
@@ -0,0 +1,246 @@
+/* parport.h: sparc64 specific parport initialization and dma.
+ *
+ * Copyright (C) 1999  Eddie C. Dost  (ecd@skynet.be)
+ */
+
+#ifndef _ASM_SPARC64_PARPORT_H
+#define _ASM_SPARC64_PARPORT_H 1
+
+#include <asm/ebus.h>
+#include <asm/ns87303.h>
+#include <asm/of_device.h>
+#include <asm/prom.h>
+
+#define PARPORT_PC_MAX_PORTS   PARPORT_MAX
+
+/*
+ * While sparc64 doesn't have an ISA DMA API, we provide something that looks
+ * close enough to make parport_pc happy
+ */
+#define HAS_DMA
+
+static DEFINE_SPINLOCK(dma_spin_lock);
+
+#define claim_dma_lock() \
+({     unsigned long flags; \
+       spin_lock_irqsave(&dma_spin_lock, flags); \
+       flags; \
+})
+
+#define release_dma_lock(__flags) \
+       spin_unlock_irqrestore(&dma_spin_lock, __flags);
+
+static struct sparc_ebus_info {
+       struct ebus_dma_info info;
+       unsigned int addr;
+       unsigned int count;
+       int lock;
+
+       struct parport *port;
+} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS];
+
+static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS);
+
+static inline int request_dma(unsigned int dmanr, const char *device_id)
+{
+       if (dmanr >= PARPORT_PC_MAX_PORTS)
+               return -EINVAL;
+       if (xchg(&sparc_ebus_dmas[dmanr].lock, 1) != 0)
+               return -EBUSY;
+       return 0;
+}
+
+static inline void free_dma(unsigned int dmanr)
+{
+       if (dmanr >= PARPORT_PC_MAX_PORTS) {
+               printk(KERN_WARNING "Trying to free DMA%d\n", dmanr);
+               return;
+       }
+       if (xchg(&sparc_ebus_dmas[dmanr].lock, 0) == 0) {
+               printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr);
+               return;
+       }
+}
+
+static inline void enable_dma(unsigned int dmanr)
+{
+       ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);
+
+       if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info,
+                            sparc_ebus_dmas[dmanr].addr,
+                            sparc_ebus_dmas[dmanr].count))
+               BUG();
+}
+
+static inline void disable_dma(unsigned int dmanr)
+{
+       ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0);
+}
+
+static inline void clear_dma_ff(unsigned int dmanr)
+{
+       /* nothing */
+}
+
+static inline void set_dma_mode(unsigned int dmanr, char mode)
+{
+       ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE));
+}
+
+static inline void set_dma_addr(unsigned int dmanr, unsigned int addr)
+{
+       sparc_ebus_dmas[dmanr].addr = addr;
+}
+
+static inline void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+       sparc_ebus_dmas[dmanr].count = count;
+}
+
+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)
+{
+       unsigned long base = op->resource[0].start;
+       unsigned long config = op->resource[1].start;
+       unsigned long d_base = op->resource[2].start;
+       unsigned long d_len;
+       struct device_node *parent;
+       struct parport *p;
+       int slot, err;
+
+       parent = op->node->parent;
+       if (!strcmp(parent->name, "dma")) {
+               p = parport_pc_probe_port(base, base + 0x400,
+                                         op->irqs[0], PARPORT_DMA_NOFIFO,
+                                         op->dev.parent->parent);
+               if (!p)
+                       return -ENOMEM;
+               dev_set_drvdata(&op->dev, p);
+               return 0;
+       }
+
+       for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) {
+               if (!test_and_set_bit(slot, dma_slot_map))
+                       break;
+       }
+       err = -ENODEV;
+       if (slot >= PARPORT_PC_MAX_PORTS)
+               goto out_err;
+
+       spin_lock_init(&sparc_ebus_dmas[slot].info.lock);
+
+       d_len = (op->resource[2].end - d_base) + 1UL;
+       sparc_ebus_dmas[slot].info.regs =
+               of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA");
+
+       if (!sparc_ebus_dmas[slot].info.regs)
+               goto out_clear_map;
+
+       sparc_ebus_dmas[slot].info.flags = 0;
+       sparc_ebus_dmas[slot].info.callback = NULL;
+       sparc_ebus_dmas[slot].info.client_cookie = NULL;
+       sparc_ebus_dmas[slot].info.irq = 0xdeadbeef;
+       strcpy(sparc_ebus_dmas[slot].info.name, "parport");
+       if (ebus_dma_register(&sparc_ebus_dmas[slot].info))
+               goto out_unmap_regs;
+
+       ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1);
+
+       /* Configure IRQ to Push Pull, Level Low */
+       /* Enable ECP, set bit 2 of the CTR first */
+       outb(0x04, base + 0x02);
+       ns87303_modify(config, PCR,
+                      PCR_EPP_ENABLE |
+                      PCR_IRQ_ODRAIN,
+                      PCR_ECP_ENABLE |
+                      PCR_ECP_CLK_ENA |
+                      PCR_IRQ_POLAR);
+
+       /* CTR bit 5 controls direction of port */
+       ns87303_modify(config, PTR,
+                      0, PTR_LPT_REG_DIR);
+
+       p = parport_pc_probe_port(base, base + 0x400,
+                                 op->irqs[0],
+                                 slot,
+                                 op->dev.parent);
+       err = -ENOMEM;
+       if (!p)
+               goto out_disable_irq;
+
+       dev_set_drvdata(&op->dev, p);
+
+       return 0;
+
+out_disable_irq:
+       ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
+       ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
+
+out_unmap_regs:
+       of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len);
+
+out_clear_map:
+       clear_bit(slot, dma_slot_map);
+
+out_err:
+       return err;
+}
+
+static int __devexit ecpp_remove(struct of_device *op)
+{
+       struct parport *p = dev_get_drvdata(&op->dev);
+       int slot = p->dma;
+
+       parport_pc_unregister_port(p);
+
+       if (slot != PARPORT_DMA_NOFIFO) {
+               unsigned long d_base = op->resource[2].start;
+               unsigned long d_len;
+
+               d_len = (op->resource[2].end - d_base) + 1UL;
+
+               ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
+               ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
+               of_iounmap(&op->resource[2],
+                          sparc_ebus_dmas[slot].info.regs,
+                          d_len);
+               clear_bit(slot, dma_slot_map);
+       }
+
+       return 0;
+}
+
+static struct of_device_id ecpp_match[] = {
+       {
+               .name = "ecpp",
+       },
+       {
+               .name = "parallel",
+               .compatible = "ecpp",
+       },
+       {
+               .name = "parallel",
+               .compatible = "ns87317-ecpp",
+       },
+       {},
+};
+
+static struct of_platform_driver ecpp_driver = {
+       .name                   = "ecpp",
+       .match_table            = ecpp_match,
+       .probe                  = ecpp_probe,
+       .remove                 = __devexit_p(ecpp_remove),
+};
+
+static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
+{
+       of_register_driver(&ecpp_driver, &of_bus_type);
+
+       return 0;
+}
+
+#endif /* !(_ASM_SPARC64_PARPORT_H */
index b93b6c79e08f6d48692f1539ced9fb7dbfeb8629..b807d52a48091164b0010be6bd4466863508ed8c 100644 (file)
@@ -1,170 +1,8 @@
-#ifndef __SPARC_PCI_H
-#define __SPARC_PCI_H
-
-#ifdef __KERNEL__
-
-/* Can be used to override the logic in pci_scan_bus for skipping
- * already-configured bus numbers - to be used for buggy BIOSes
- * or architectures with incomplete PCI setup by the loader.
- */
-#define pcibios_assign_all_busses()    0
-#define pcibios_scan_all_fns(a, b)     0
-
-#define PCIBIOS_MIN_IO         0UL
-#define PCIBIOS_MIN_MEM                0UL
-
-#define PCI_IRQ_NONE           0xffffffff
-
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-       /* No special bus mastering setup handling */
-}
-
-static inline void pcibios_penalize_isa_irq(int irq, int active)
-{
-       /* We don't do dynamic PCI IRQ allocation */
-}
-
-/* Dynamic DMA mapping stuff.
- */
-#define PCI_DMA_BUS_IS_PHYS    (0)
-
-#include <asm/scatterlist.h>
-
-struct pci_dev;
-
-/* Allocate and map kernel buffer using consistent mode DMA for a device.
- * hwdev should be valid struct pci_dev pointer for PCI devices.
- */
-extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle);
-
-/* Free and unmap a consistent DMA buffer.
- * cpu_addr is what was returned from pci_alloc_consistent,
- * size must be the same as what as passed into pci_alloc_consistent,
- * and likewise dma_addr must be the same as what *dma_addrp was set to.
- *
- * References to the memory and mappings assosciated with cpu_addr/dma_addr
- * past this call are illegal.
- */
-extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle);
-
-/* Map a single buffer of the indicated size for DMA in streaming mode.
- * The 32-bit bus address to use is returned.
- *
- * Once the device is given the dma address, the device owns this memory
- * until either pci_unmap_single or pci_dma_sync_single_for_cpu is performed.
- */
-extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction);
-
-/* Unmap a single streaming mode DMA translation.  The dma_addr and size
- * must match what was provided for in a previous pci_map_single call.  All
- * other usages are undefined.
- *
- * After this call, reads by the cpu to the buffer are guaranteed to see
- * whatever the device wrote there.
- */
-extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction);
-
-/* pci_unmap_{single,page} is not a nop, thus... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)      \
-       dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)                \
-       __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME)                 \
-       ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)                \
-       (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME)                   \
-       ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL)          \
-       (((PTR)->LEN_NAME) = (VAL))
-
-/*
- * Same as above, only with pages instead of mapped addresses.
- */
-extern dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
-                       unsigned long offset, size_t size, int direction);
-extern void pci_unmap_page(struct pci_dev *hwdev,
-                       dma_addr_t dma_address, size_t size, int direction);
-
-/* Map a set of buffers described by scatterlist in streaming
- * mode for DMA.  This is the scather-gather version of the
- * above pci_map_single interface.  Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length.  They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- *       DMA address/length pairs than there are SG table elements.
- *       (for example via virtual mapping capabilities)
- *       The routine returns the number of addr/length pairs actually
- *       used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are
- * the same here.
- */
-extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction);
-
-/* Unmap a set of streaming mode DMA translations.
- * Again, cpu read rules concerning calls here are the same as for
- * pci_unmap_single() above.
- */
-extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nhwents, int direction);
-
-/* Make physical memory consistent for a single
- * streaming mode DMA translation after a transfer.
- *
- * If you perform a pci_map_single() but wish to interrogate the
- * buffer using the cpu, yet do not wish to teardown the PCI dma
- * mapping, you must call this function before doing so.  At the
- * next point you give the PCI dma address back to the card, you
- * must first perform a pci_dma_sync_for_device, and then the device
- * again owns the buffer.
- */
-extern void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction);
-extern void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction);
-
-/* Make physical memory consistent for a set of streaming
- * mode DMA translations after a transfer.
- *
- * The same as pci_dma_sync_single_* but for a scatter-gather list,
- * same rules and usage.
- */
-extern void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction);
-extern void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction);
-
-/* Return whether the given PCI device DMA address mask can
- * be supported properly.  For example, if your device can
- * only drive the low 24-bits during PCI bus mastering, then
- * you would pass 0x00ffffff as the mask to this function.
- */
-static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
-{
-       return 1;
-}
-
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
-                                       enum pci_dma_burst_strategy *strat,
-                                       unsigned long *strategy_parameter)
-{
-       *strat = PCI_DMA_BURST_INFINITY;
-       *strategy_parameter = ~0UL;
-}
+#ifndef ___ASM_SPARC_PCI_H
+#define ___ASM_SPARC_PCI_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/pci_64.h>
+#else
+#include <asm-sparc/pci_32.h>
+#endif
 #endif
-
-#define PCI_DMA_ERROR_CODE      (~(dma_addr_t)0x0)
-
-static inline int pci_dma_mapping_error(dma_addr_t dma_addr)
-{
-        return (dma_addr == PCI_DMA_ERROR_CODE);
-}
-
-struct device_node;
-extern struct device_node *pci_device_to_OF_node(struct pci_dev *pdev);
-
-#endif /* __KERNEL__ */
-
-/* generic pci stuff */
-#include <asm-generic/pci.h>
-
-#endif /* __SPARC_PCI_H */
diff --git a/include/asm-sparc/pci_32.h b/include/asm-sparc/pci_32.h
new file mode 100644 (file)
index 0000000..b93b6c7
--- /dev/null
@@ -0,0 +1,170 @@
+#ifndef __SPARC_PCI_H
+#define __SPARC_PCI_H
+
+#ifdef __KERNEL__
+
+/* Can be used to override the logic in pci_scan_bus for skipping
+ * already-configured bus numbers - to be used for buggy BIOSes
+ * or architectures with incomplete PCI setup by the loader.
+ */
+#define pcibios_assign_all_busses()    0
+#define pcibios_scan_all_fns(a, b)     0
+
+#define PCIBIOS_MIN_IO         0UL
+#define PCIBIOS_MIN_MEM                0UL
+
+#define PCI_IRQ_NONE           0xffffffff
+
+static inline void pcibios_set_master(struct pci_dev *dev)
+{
+       /* No special bus mastering setup handling */
+}
+
+static inline void pcibios_penalize_isa_irq(int irq, int active)
+{
+       /* We don't do dynamic PCI IRQ allocation */
+}
+
+/* Dynamic DMA mapping stuff.
+ */
+#define PCI_DMA_BUS_IS_PHYS    (0)
+
+#include <asm/scatterlist.h>
+
+struct pci_dev;
+
+/* Allocate and map kernel buffer using consistent mode DMA for a device.
+ * hwdev should be valid struct pci_dev pointer for PCI devices.
+ */
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle);
+
+/* Free and unmap a consistent DMA buffer.
+ * cpu_addr is what was returned from pci_alloc_consistent,
+ * size must be the same as what as passed into pci_alloc_consistent,
+ * and likewise dma_addr must be the same as what *dma_addrp was set to.
+ *
+ * References to the memory and mappings assosciated with cpu_addr/dma_addr
+ * past this call are illegal.
+ */
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle);
+
+/* Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single_for_cpu is performed.
+ */
+extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction);
+
+/* Unmap a single streaming mode DMA translation.  The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call.  All
+ * other usages are undefined.
+ *
+ * After this call, reads by the cpu to the buffer are guaranteed to see
+ * whatever the device wrote there.
+ */
+extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction);
+
+/* pci_unmap_{single,page} is not a nop, thus... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)      \
+       dma_addr_t ADDR_NAME;
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)                \
+       __u32 LEN_NAME;
+#define pci_unmap_addr(PTR, ADDR_NAME)                 \
+       ((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)                \
+       (((PTR)->ADDR_NAME) = (VAL))
+#define pci_unmap_len(PTR, LEN_NAME)                   \
+       ((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)          \
+       (((PTR)->LEN_NAME) = (VAL))
+
+/*
+ * Same as above, only with pages instead of mapped addresses.
+ */
+extern dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
+                       unsigned long offset, size_t size, int direction);
+extern void pci_unmap_page(struct pci_dev *hwdev,
+                       dma_addr_t dma_address, size_t size, int direction);
+
+/* Map a set of buffers described by scatterlist in streaming
+ * mode for DMA.  This is the scather-gather version of the
+ * above pci_map_single interface.  Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length.  They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ *       DMA address/length pairs than there are SG table elements.
+ *       (for example via virtual mapping capabilities)
+ *       The routine returns the number of addr/length pairs actually
+ *       used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction);
+
+/* Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nhwents, int direction);
+
+/* Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so.  At the
+ * next point you give the PCI dma address back to the card, you
+ * must first perform a pci_dma_sync_for_device, and then the device
+ * again owns the buffer.
+ */
+extern void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction);
+extern void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction);
+
+/* Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single_* but for a scatter-gather list,
+ * same rules and usage.
+ */
+extern void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction);
+extern void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction);
+
+/* Return whether the given PCI device DMA address mask can
+ * be supported properly.  For example, if your device can
+ * only drive the low 24-bits during PCI bus mastering, then
+ * you would pass 0x00ffffff as the mask to this function.
+ */
+static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
+{
+       return 1;
+}
+
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+                                       enum pci_dma_burst_strategy *strat,
+                                       unsigned long *strategy_parameter)
+{
+       *strat = PCI_DMA_BURST_INFINITY;
+       *strategy_parameter = ~0UL;
+}
+#endif
+
+#define PCI_DMA_ERROR_CODE      (~(dma_addr_t)0x0)
+
+static inline int pci_dma_mapping_error(dma_addr_t dma_addr)
+{
+        return (dma_addr == PCI_DMA_ERROR_CODE);
+}
+
+struct device_node;
+extern struct device_node *pci_device_to_OF_node(struct pci_dev *pdev);
+
+#endif /* __KERNEL__ */
+
+/* generic pci stuff */
+#include <asm-generic/pci.h>
+
+#endif /* __SPARC_PCI_H */
diff --git a/include/asm-sparc/pci_64.h b/include/asm-sparc/pci_64.h
new file mode 100644 (file)
index 0000000..f59f257
--- /dev/null
@@ -0,0 +1,209 @@
+#ifndef __SPARC64_PCI_H
+#define __SPARC64_PCI_H
+
+#ifdef __KERNEL__
+
+#include <linux/dma-mapping.h>
+
+/* Can be used to override the logic in pci_scan_bus for skipping
+ * already-configured bus numbers - to be used for buggy BIOSes
+ * or architectures with incomplete PCI setup by the loader.
+ */
+#define pcibios_assign_all_busses()    0
+#define pcibios_scan_all_fns(a, b)     0
+
+#define PCIBIOS_MIN_IO         0UL
+#define PCIBIOS_MIN_MEM                0UL
+
+#define PCI_IRQ_NONE           0xffffffff
+
+#define PCI_CACHE_LINE_BYTES   64
+
+static inline void pcibios_set_master(struct pci_dev *dev)
+{
+       /* No special bus mastering setup handling */
+}
+
+static inline void pcibios_penalize_isa_irq(int irq, int active)
+{
+       /* We don't do dynamic PCI IRQ allocation */
+}
+
+/* The PCI address space does not equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS    (0)
+
+static inline void *pci_alloc_consistent(struct pci_dev *pdev, size_t size,
+                                        dma_addr_t *dma_handle)
+{
+       return dma_alloc_coherent(&pdev->dev, size, dma_handle, GFP_ATOMIC);
+}
+
+static inline void pci_free_consistent(struct pci_dev *pdev, size_t size,
+                                      void *vaddr, dma_addr_t dma_handle)
+{
+       return dma_free_coherent(&pdev->dev, size, vaddr, dma_handle);
+}
+
+static inline dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr,
+                                       size_t size, int direction)
+{
+       return dma_map_single(&pdev->dev, ptr, size,
+                             (enum dma_data_direction) direction);
+}
+
+static inline void pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr,
+                                   size_t size, int direction)
+{
+       dma_unmap_single(&pdev->dev, dma_addr, size,
+                        (enum dma_data_direction) direction);
+}
+
+#define pci_map_page(dev, page, off, size, dir) \
+       pci_map_single(dev, (page_address(page) + (off)), size, dir)
+#define pci_unmap_page(dev,addr,sz,dir) \
+       pci_unmap_single(dev,addr,sz,dir)
+
+/* pci_unmap_{single,page} is not a nop, thus... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)      \
+       dma_addr_t ADDR_NAME;
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)                \
+       __u32 LEN_NAME;
+#define pci_unmap_addr(PTR, ADDR_NAME)                 \
+       ((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)                \
+       (((PTR)->ADDR_NAME) = (VAL))
+#define pci_unmap_len(PTR, LEN_NAME)                   \
+       ((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)          \
+       (((PTR)->LEN_NAME) = (VAL))
+
+static inline int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg,
+                            int nents, int direction)
+{
+       return dma_map_sg(&pdev->dev, sg, nents,
+                         (enum dma_data_direction) direction);
+}
+
+static inline void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg,
+                               int nents, int direction)
+{
+       dma_unmap_sg(&pdev->dev, sg, nents,
+                    (enum dma_data_direction) direction);
+}
+
+static inline void pci_dma_sync_single_for_cpu(struct pci_dev *pdev,
+                                              dma_addr_t dma_handle,
+                                              size_t size, int direction)
+{
+       dma_sync_single_for_cpu(&pdev->dev, dma_handle, size,
+                               (enum dma_data_direction) direction);
+}
+
+static inline void pci_dma_sync_single_for_device(struct pci_dev *pdev,
+                                                 dma_addr_t dma_handle,
+                                                 size_t size, int direction)
+{
+       /* No flushing needed to sync cpu writes to the device.  */
+}
+
+static inline void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev,
+                                          struct scatterlist *sg,
+                                          int nents, int direction)
+{
+       dma_sync_sg_for_cpu(&pdev->dev, sg, nents,
+                           (enum dma_data_direction) direction);
+}
+
+static inline void pci_dma_sync_sg_for_device(struct pci_dev *pdev,
+                                             struct scatterlist *sg,
+                                             int nelems, int direction)
+{
+       /* No flushing needed to sync cpu writes to the device.  */
+}
+
+/* Return whether the given PCI device DMA address mask can
+ * be supported properly.  For example, if your device can
+ * only drive the low 24-bits during PCI bus mastering, then
+ * you would pass 0x00ffffff as the mask to this function.
+ */
+extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
+
+/* PCI IOMMU mapping bypass support. */
+
+/* PCI 64-bit addressing works for all slots on all controller
+ * types on sparc64.  However, it requires that the device
+ * can drive enough of the 64 bits.
+ */
+#define PCI64_REQUIRED_MASK    (~(dma64_addr_t)0)
+#define PCI64_ADDR_BASE                0xfffc000000000000UL
+
+static inline int pci_dma_mapping_error(dma_addr_t dma_addr)
+{
+       return dma_mapping_error(dma_addr);
+}
+
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+                                       enum pci_dma_burst_strategy *strat,
+                                       unsigned long *strategy_parameter)
+{
+       unsigned long cacheline_size;
+       u8 byte;
+
+       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
+       if (byte == 0)
+               cacheline_size = 1024;
+       else
+               cacheline_size = (int) byte * 4;
+
+       *strat = PCI_DMA_BURST_BOUNDARY;
+       *strategy_parameter = cacheline_size;
+}
+#endif
+
+/* Return the index of the PCI controller for device PDEV. */
+
+extern int pci_domain_nr(struct pci_bus *bus);
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+       return 1;
+}
+
+/* Platform support for /proc/bus/pci/X/Y mmap()s. */
+
+#define HAVE_PCI_MMAP
+#define HAVE_ARCH_PCI_GET_UNMAPPED_AREA
+#define get_pci_unmapped_area get_fb_unmapped_area
+
+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+                              enum pci_mmap_state mmap_state,
+                              int write_combine);
+
+extern void
+pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+                       struct resource *res);
+
+extern void
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                       struct pci_bus_region *region);
+
+extern struct resource *pcibios_select_root(struct pci_dev *, struct resource *);
+
+static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
+{
+       return PCI_IRQ_NONE;
+}
+
+struct device_node;
+extern struct device_node *pci_device_to_OF_node(struct pci_dev *pdev);
+
+#define HAVE_ARCH_PCI_RESOURCE_TO_USER
+extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
+                                const struct resource *rsrc,
+                                resource_size_t *start, resource_size_t *end);
+#endif /* __KERNEL__ */
+
+#endif /* __SPARC64_PCI_H */
index 06066a7aaec31b19ba83bd2231b1b26f67ed2a5c..d98ed6cf2e36cdc31541e80bdcb9abd8d9f44a86 100644 (file)
@@ -1,6 +1,8 @@
-#ifndef __ARCH_SPARC_PERCPU__
-#define __ARCH_SPARC_PERCPU__
-
-#include <asm-generic/percpu.h>
-
-#endif /* __ARCH_SPARC_PERCPU__ */
+#ifndef ___ASM_SPARC_PERCPU_H
+#define ___ASM_SPARC_PERCPU_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/percpu_64.h>
+#else
+#include <asm-sparc/percpu_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/percpu_32.h b/include/asm-sparc/percpu_32.h
new file mode 100644 (file)
index 0000000..06066a7
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __ARCH_SPARC_PERCPU__
+#define __ARCH_SPARC_PERCPU__
+
+#include <asm-generic/percpu.h>
+
+#endif /* __ARCH_SPARC_PERCPU__ */
diff --git a/include/asm-sparc/percpu_64.h b/include/asm-sparc/percpu_64.h
new file mode 100644 (file)
index 0000000..bee6459
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef __ARCH_SPARC64_PERCPU__
+#define __ARCH_SPARC64_PERCPU__
+
+#include <linux/compiler.h>
+
+register unsigned long __local_per_cpu_offset asm("g5");
+
+#ifdef CONFIG_SMP
+
+extern void real_setup_per_cpu_areas(void);
+
+extern unsigned long __per_cpu_base;
+extern unsigned long __per_cpu_shift;
+#define __per_cpu_offset(__cpu) \
+       (__per_cpu_base + ((unsigned long)(__cpu) << __per_cpu_shift))
+#define per_cpu_offset(x) (__per_cpu_offset(x))
+
+#define __my_cpu_offset __local_per_cpu_offset
+
+#else /* ! SMP */
+
+#define real_setup_per_cpu_areas()             do { } while (0)
+
+#endif /* SMP */
+
+#include <asm-generic/percpu.h>
+
+#endif /* __ARCH_SPARC64_PERCPU__ */
index 681582d2696911ce7262bfa821dc1dbff5f41d94..7fa02b53d392cef4e9c48a82decdbc639c9b97ae 100644 (file)
@@ -1,68 +1,8 @@
-#ifndef _SPARC_PGALLOC_H
-#define _SPARC_PGALLOC_H
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/page.h>
-#include <asm/btfixup.h>
-
-struct page;
-
-extern struct pgtable_cache_struct {
-       unsigned long *pgd_cache;
-       unsigned long *pte_cache;
-       unsigned long pgtable_cache_sz;
-       unsigned long pgd_cache_sz;
-} pgt_quicklists;
-#define pgd_quicklist           (pgt_quicklists.pgd_cache)
-#define pmd_quicklist           ((unsigned long *)0)
-#define pte_quicklist           (pgt_quicklists.pte_cache)
-#define pgtable_cache_size      (pgt_quicklists.pgtable_cache_sz)
-#define pgd_cache_size         (pgt_quicklists.pgd_cache_sz)
-
-extern void check_pgt_cache(void);
-BTFIXUPDEF_CALL(void,   do_check_pgt_cache, int, int)
-#define do_check_pgt_cache(low,high) BTFIXUP_CALL(do_check_pgt_cache)(low,high)
-
-BTFIXUPDEF_CALL(pgd_t *, get_pgd_fast, void)
-#define get_pgd_fast()         BTFIXUP_CALL(get_pgd_fast)()
-
-BTFIXUPDEF_CALL(void, free_pgd_fast, pgd_t *)
-#define free_pgd_fast(pgd)     BTFIXUP_CALL(free_pgd_fast)(pgd)
-
-#define pgd_free(mm, pgd)      free_pgd_fast(pgd)
-#define pgd_alloc(mm)  get_pgd_fast()
-
-BTFIXUPDEF_CALL(void, pgd_set, pgd_t *, pmd_t *)
-#define pgd_set(pgdp,pmdp) BTFIXUP_CALL(pgd_set)(pgdp,pmdp)
-#define pgd_populate(MM, PGD, PMD)      pgd_set(PGD, PMD)
-
-BTFIXUPDEF_CALL(pmd_t *, pmd_alloc_one, struct mm_struct *, unsigned long)
-#define pmd_alloc_one(mm, address)     BTFIXUP_CALL(pmd_alloc_one)(mm, address)
-
-BTFIXUPDEF_CALL(void, free_pmd_fast, pmd_t *)
-#define free_pmd_fast(pmd)     BTFIXUP_CALL(free_pmd_fast)(pmd)
-
-#define pmd_free(mm, pmd)      free_pmd_fast(pmd)
-#define __pmd_free_tlb(tlb, pmd) pmd_free((tlb)->mm, pmd)
-
-BTFIXUPDEF_CALL(void, pmd_populate, pmd_t *, struct page *)
-#define pmd_populate(MM, PMD, PTE)        BTFIXUP_CALL(pmd_populate)(PMD, PTE)
-#define pmd_pgtable(pmd) pmd_page(pmd)
-BTFIXUPDEF_CALL(void, pmd_set, pmd_t *, pte_t *)
-#define pmd_populate_kernel(MM, PMD, PTE) BTFIXUP_CALL(pmd_set)(PMD, PTE)
-
-BTFIXUPDEF_CALL(pgtable_t , pte_alloc_one, struct mm_struct *, unsigned long)
-#define pte_alloc_one(mm, address)     BTFIXUP_CALL(pte_alloc_one)(mm, address)
-BTFIXUPDEF_CALL(pte_t *, pte_alloc_one_kernel, struct mm_struct *, unsigned long)
-#define pte_alloc_one_kernel(mm, addr) BTFIXUP_CALL(pte_alloc_one_kernel)(mm, addr)
-
-BTFIXUPDEF_CALL(void, free_pte_fast, pte_t *)
-#define pte_free_kernel(mm, pte)       BTFIXUP_CALL(free_pte_fast)(pte)
-
-BTFIXUPDEF_CALL(void, pte_free, pgtable_t )
-#define pte_free(mm, pte)      BTFIXUP_CALL(pte_free)(pte)
-#define __pte_free_tlb(tlb, pte)       pte_free((tlb)->mm, pte)
-
-#endif /* _SPARC_PGALLOC_H */
+#ifndef ___ASM_SPARC_PGALLOC_H
+#define ___ASM_SPARC_PGALLOC_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/pgalloc_64.h>
+#else
+#include <asm-sparc/pgalloc_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/pgalloc_32.h b/include/asm-sparc/pgalloc_32.h
new file mode 100644 (file)
index 0000000..681582d
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef _SPARC_PGALLOC_H
+#define _SPARC_PGALLOC_H
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/page.h>
+#include <asm/btfixup.h>
+
+struct page;
+
+extern struct pgtable_cache_struct {
+       unsigned long *pgd_cache;
+       unsigned long *pte_cache;
+       unsigned long pgtable_cache_sz;
+       unsigned long pgd_cache_sz;
+} pgt_quicklists;
+#define pgd_quicklist           (pgt_quicklists.pgd_cache)
+#define pmd_quicklist           ((unsigned long *)0)
+#define pte_quicklist           (pgt_quicklists.pte_cache)
+#define pgtable_cache_size      (pgt_quicklists.pgtable_cache_sz)
+#define pgd_cache_size         (pgt_quicklists.pgd_cache_sz)
+
+extern void check_pgt_cache(void);
+BTFIXUPDEF_CALL(void,   do_check_pgt_cache, int, int)
+#define do_check_pgt_cache(low,high) BTFIXUP_CALL(do_check_pgt_cache)(low,high)
+
+BTFIXUPDEF_CALL(pgd_t *, get_pgd_fast, void)
+#define get_pgd_fast()         BTFIXUP_CALL(get_pgd_fast)()
+
+BTFIXUPDEF_CALL(void, free_pgd_fast, pgd_t *)
+#define free_pgd_fast(pgd)     BTFIXUP_CALL(free_pgd_fast)(pgd)
+
+#define pgd_free(mm, pgd)      free_pgd_fast(pgd)
+#define pgd_alloc(mm)  get_pgd_fast()
+
+BTFIXUPDEF_CALL(void, pgd_set, pgd_t *, pmd_t *)
+#define pgd_set(pgdp,pmdp) BTFIXUP_CALL(pgd_set)(pgdp,pmdp)
+#define pgd_populate(MM, PGD, PMD)      pgd_set(PGD, PMD)
+
+BTFIXUPDEF_CALL(pmd_t *, pmd_alloc_one, struct mm_struct *, unsigned long)
+#define pmd_alloc_one(mm, address)     BTFIXUP_CALL(pmd_alloc_one)(mm, address)
+
+BTFIXUPDEF_CALL(void, free_pmd_fast, pmd_t *)
+#define free_pmd_fast(pmd)     BTFIXUP_CALL(free_pmd_fast)(pmd)
+
+#define pmd_free(mm, pmd)      free_pmd_fast(pmd)
+#define __pmd_free_tlb(tlb, pmd) pmd_free((tlb)->mm, pmd)
+
+BTFIXUPDEF_CALL(void, pmd_populate, pmd_t *, struct page *)
+#define pmd_populate(MM, PMD, PTE)        BTFIXUP_CALL(pmd_populate)(PMD, PTE)
+#define pmd_pgtable(pmd) pmd_page(pmd)
+BTFIXUPDEF_CALL(void, pmd_set, pmd_t *, pte_t *)
+#define pmd_populate_kernel(MM, PMD, PTE) BTFIXUP_CALL(pmd_set)(PMD, PTE)
+
+BTFIXUPDEF_CALL(pgtable_t , pte_alloc_one, struct mm_struct *, unsigned long)
+#define pte_alloc_one(mm, address)     BTFIXUP_CALL(pte_alloc_one)(mm, address)
+BTFIXUPDEF_CALL(pte_t *, pte_alloc_one_kernel, struct mm_struct *, unsigned long)
+#define pte_alloc_one_kernel(mm, addr) BTFIXUP_CALL(pte_alloc_one_kernel)(mm, addr)
+
+BTFIXUPDEF_CALL(void, free_pte_fast, pte_t *)
+#define pte_free_kernel(mm, pte)       BTFIXUP_CALL(free_pte_fast)(pte)
+
+BTFIXUPDEF_CALL(void, pte_free, pgtable_t )
+#define pte_free(mm, pte)      BTFIXUP_CALL(pte_free)(pte)
+#define __pte_free_tlb(tlb, pte)       pte_free((tlb)->mm, pte)
+
+#endif /* _SPARC_PGALLOC_H */
diff --git a/include/asm-sparc/pgalloc_64.h b/include/asm-sparc/pgalloc_64.h
new file mode 100644 (file)
index 0000000..5bdfa2c
--- /dev/null
@@ -0,0 +1,81 @@
+#ifndef _SPARC64_PGALLOC_H
+#define _SPARC64_PGALLOC_H
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/quicklist.h>
+
+#include <asm/spitfire.h>
+#include <asm/cpudata.h>
+#include <asm/cacheflush.h>
+#include <asm/page.h>
+
+/* Page table allocation/freeing. */
+
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+       return quicklist_alloc(0, GFP_KERNEL, NULL);
+}
+
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+       quicklist_free(0, NULL, pgd);
+}
+
+#define pud_populate(MM, PUD, PMD)     pud_set(PUD, PMD)
+
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+       return quicklist_alloc(0, GFP_KERNEL, NULL);
+}
+
+static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
+{
+       quicklist_free(0, NULL, pmd);
+}
+
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+                                         unsigned long address)
+{
+       return quicklist_alloc(0, GFP_KERNEL, NULL);
+}
+
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
+                                       unsigned long address)
+{
+       struct page *page;
+       void *pg;
+
+       pg = quicklist_alloc(0, GFP_KERNEL, NULL);
+       if (!pg)
+               return NULL;
+       page = virt_to_page(pg);
+       pgtable_page_ctor(page);
+       return page;
+}
+
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+       quicklist_free(0, NULL, pte);
+}
+
+static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
+{
+       pgtable_page_dtor(ptepage);
+       quicklist_free_page(0, NULL, ptepage);
+}
+
+
+#define pmd_populate_kernel(MM, PMD, PTE)      pmd_set(PMD, PTE)
+#define pmd_populate(MM,PMD,PTE_PAGE)          \
+       pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE))
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+static inline void check_pgt_cache(void)
+{
+       quicklist_trim(0, NULL, 25, 16);
+}
+
+#endif /* _SPARC64_PGALLOC_H */
index 60512296b2ca9468b04b174d61a867cf9c954680..63cdef53bc52ef78ef6521cfe19205be61001d1e 100644 (file)
@@ -1,475 +1,8 @@
-#ifndef _SPARC_PGTABLE_H
-#define _SPARC_PGTABLE_H
-
-/*  asm-sparc/pgtable.h:  Defines and functions used to work
- *                        with Sparc page tables.
- *
- *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- *  Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#include <asm-generic/4level-fixup.h>
-
-#include <linux/spinlock.h>
-#include <linux/swap.h>
-#include <asm/types.h>
-#ifdef CONFIG_SUN4
-#include <asm/pgtsun4.h>
+#ifndef ___ASM_SPARC_PGTABLE_H
+#define ___ASM_SPARC_PGTABLE_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/pgtable_64.h>
 #else
-#include <asm/pgtsun4c.h>
+#include <asm-sparc/pgtable_32.h>
 #endif
-#include <asm/pgtsrmmu.h>
-#include <asm/vac-ops.h>
-#include <asm/oplib.h>
-#include <asm/btfixup.h>
-#include <asm/system.h>
-
-#ifndef __ASSEMBLY__
-
-struct vm_area_struct;
-struct page;
-
-extern void load_mmu(void);
-extern unsigned long calc_highpages(void);
-
-BTFIXUPDEF_SIMM13(pgdir_shift)
-BTFIXUPDEF_SETHI(pgdir_size)
-BTFIXUPDEF_SETHI(pgdir_mask)
-
-BTFIXUPDEF_SIMM13(ptrs_per_pmd)
-BTFIXUPDEF_SIMM13(ptrs_per_pgd)
-BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
-
-#define pte_ERROR(e)   __builtin_trap()
-#define pmd_ERROR(e)   __builtin_trap()
-#define pgd_ERROR(e)   __builtin_trap()
-
-BTFIXUPDEF_INT(page_none)
-BTFIXUPDEF_INT(page_copy)
-BTFIXUPDEF_INT(page_readonly)
-BTFIXUPDEF_INT(page_kernel)
-
-#define PMD_SHIFT              SUN4C_PMD_SHIFT
-#define PMD_SIZE               (1UL << PMD_SHIFT)
-#define PMD_MASK               (~(PMD_SIZE-1))
-#define PMD_ALIGN(__addr)      (((__addr) + ~PMD_MASK) & PMD_MASK)
-#define PGDIR_SHIFT            BTFIXUP_SIMM13(pgdir_shift)
-#define PGDIR_SIZE             BTFIXUP_SETHI(pgdir_size)
-#define PGDIR_MASK             BTFIXUP_SETHI(pgdir_mask)
-#define PTRS_PER_PTE           1024
-#define PTRS_PER_PMD           BTFIXUP_SIMM13(ptrs_per_pmd)
-#define PTRS_PER_PGD           BTFIXUP_SIMM13(ptrs_per_pgd)
-#define USER_PTRS_PER_PGD      BTFIXUP_SIMM13(user_ptrs_per_pgd)
-#define FIRST_USER_ADDRESS     0
-#define PTE_SIZE               (PTRS_PER_PTE*4)
-
-#define PAGE_NONE      __pgprot(BTFIXUP_INT(page_none))
-extern pgprot_t PAGE_SHARED;
-#define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
-#define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
-
-extern unsigned long page_kernel;
-
-#ifdef MODULE
-#define PAGE_KERNEL    page_kernel
-#else
-#define PAGE_KERNEL    __pgprot(BTFIXUP_INT(page_kernel))
 #endif
-
-/* Top-level page directory */
-extern pgd_t swapper_pg_dir[1024];
-
-extern void paging_init(void);
-
-/* Page table for 0-4MB for everybody, on the Sparc this
- * holds the same as on the i386.
- */
-extern pte_t pg0[1024];
-extern pte_t pg1[1024];
-extern pte_t pg2[1024];
-extern pte_t pg3[1024];
-
-extern unsigned long ptr_in_current_pgd;
-
-/* Here is a trick, since mmap.c need the initializer elements for
- * protection_map[] to be constant at compile time, I set the following
- * to all zeros.  I set it to the real values after I link in the
- * appropriate MMU page table routines at boot time.
- */
-#define __P000  __pgprot(0)
-#define __P001  __pgprot(0)
-#define __P010  __pgprot(0)
-#define __P011  __pgprot(0)
-#define __P100  __pgprot(0)
-#define __P101  __pgprot(0)
-#define __P110  __pgprot(0)
-#define __P111  __pgprot(0)
-
-#define __S000 __pgprot(0)
-#define __S001 __pgprot(0)
-#define __S010 __pgprot(0)
-#define __S011 __pgprot(0)
-#define __S100 __pgprot(0)
-#define __S101 __pgprot(0)
-#define __S110 __pgprot(0)
-#define __S111 __pgprot(0)
-
-extern int num_contexts;
-
-/* First physical page can be anywhere, the following is needed so that
- * va-->pa and vice versa conversions work properly without performance
- * hit for all __pa()/__va() operations.
- */
-extern unsigned long phys_base;
-extern unsigned long pfn_base;
-
-/*
- * BAD_PAGETABLE is used when we need a bogus page-table, while
- * BAD_PAGE is used for a bogus page.
- *
- * ZERO_PAGE is a global shared page that is always zero: used
- * for zero-mapped memory areas etc..
- */
-extern pte_t * __bad_pagetable(void);
-extern pte_t __bad_page(void);
-extern unsigned long empty_zero_page;
-
-#define BAD_PAGETABLE __bad_pagetable()
-#define BAD_PAGE __bad_page()
-#define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page))
-
-/*
- */
-BTFIXUPDEF_CALL_CONST(struct page *, pmd_page, pmd_t)
-BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page_vaddr, pgd_t)
-
-#define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd)
-#define pgd_page_vaddr(pgd) BTFIXUP_CALL(pgd_page_vaddr)(pgd)
-
-BTFIXUPDEF_SETHI(none_mask)
-BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t)
-BTFIXUPDEF_CALL(void, pte_clear, pte_t *)
-
-static inline int pte_none(pte_t pte)
-{
-       return !(pte_val(pte) & ~BTFIXUP_SETHI(none_mask));
-}
-
-#define pte_present(pte) BTFIXUP_CALL(pte_present)(pte)
-#define pte_clear(mm,addr,pte) BTFIXUP_CALL(pte_clear)(pte)
-
-BTFIXUPDEF_CALL_CONST(int, pmd_bad, pmd_t)
-BTFIXUPDEF_CALL_CONST(int, pmd_present, pmd_t)
-BTFIXUPDEF_CALL(void, pmd_clear, pmd_t *)
-
-static inline int pmd_none(pmd_t pmd)
-{
-       return !(pmd_val(pmd) & ~BTFIXUP_SETHI(none_mask));
-}
-
-#define pmd_bad(pmd) BTFIXUP_CALL(pmd_bad)(pmd)
-#define pmd_present(pmd) BTFIXUP_CALL(pmd_present)(pmd)
-#define pmd_clear(pmd) BTFIXUP_CALL(pmd_clear)(pmd)
-
-BTFIXUPDEF_CALL_CONST(int, pgd_none, pgd_t)
-BTFIXUPDEF_CALL_CONST(int, pgd_bad, pgd_t)
-BTFIXUPDEF_CALL_CONST(int, pgd_present, pgd_t)
-BTFIXUPDEF_CALL(void, pgd_clear, pgd_t *)
-
-#define pgd_none(pgd) BTFIXUP_CALL(pgd_none)(pgd)
-#define pgd_bad(pgd) BTFIXUP_CALL(pgd_bad)(pgd)
-#define pgd_present(pgd) BTFIXUP_CALL(pgd_present)(pgd)
-#define pgd_clear(pgd) BTFIXUP_CALL(pgd_clear)(pgd)
-
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-BTFIXUPDEF_HALF(pte_writei)
-BTFIXUPDEF_HALF(pte_dirtyi)
-BTFIXUPDEF_HALF(pte_youngi)
-
-static int pte_write(pte_t pte) __attribute_const__;
-static inline int pte_write(pte_t pte)
-{
-       return pte_val(pte) & BTFIXUP_HALF(pte_writei);
-}
-
-static int pte_dirty(pte_t pte) __attribute_const__;
-static inline int pte_dirty(pte_t pte)
-{
-       return pte_val(pte) & BTFIXUP_HALF(pte_dirtyi);
-}
-
-static int pte_young(pte_t pte) __attribute_const__;
-static inline int pte_young(pte_t pte)
-{
-       return pte_val(pte) & BTFIXUP_HALF(pte_youngi);
-}
-
-/*
- * The following only work if pte_present() is not true.
- */
-BTFIXUPDEF_HALF(pte_filei)
-
-static int pte_file(pte_t pte) __attribute_const__;
-static inline int pte_file(pte_t pte)
-{
-       return pte_val(pte) & BTFIXUP_HALF(pte_filei);
-}
-
-static inline int pte_special(pte_t pte)
-{
-       return 0;
-}
-
-/*
- */
-BTFIXUPDEF_HALF(pte_wrprotecti)
-BTFIXUPDEF_HALF(pte_mkcleani)
-BTFIXUPDEF_HALF(pte_mkoldi)
-
-static pte_t pte_wrprotect(pte_t pte) __attribute_const__;
-static inline pte_t pte_wrprotect(pte_t pte)
-{
-       return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_wrprotecti));
-}
-
-static pte_t pte_mkclean(pte_t pte) __attribute_const__;
-static inline pte_t pte_mkclean(pte_t pte)
-{
-       return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkcleani));
-}
-
-static pte_t pte_mkold(pte_t pte) __attribute_const__;
-static inline pte_t pte_mkold(pte_t pte)
-{
-       return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkoldi));
-}
-
-BTFIXUPDEF_CALL_CONST(pte_t, pte_mkwrite, pte_t)
-BTFIXUPDEF_CALL_CONST(pte_t, pte_mkdirty, pte_t)
-BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung, pte_t)
-
-#define pte_mkwrite(pte) BTFIXUP_CALL(pte_mkwrite)(pte)
-#define pte_mkdirty(pte) BTFIXUP_CALL(pte_mkdirty)(pte)
-#define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte)
-
-#define pte_mkspecial(pte)    (pte)
-
-#define pfn_pte(pfn, prot)             mk_pte(pfn_to_page(pfn), prot)
-
-BTFIXUPDEF_CALL(unsigned long,  pte_pfn, pte_t)
-#define pte_pfn(pte) BTFIXUP_CALL(pte_pfn)(pte)
-#define pte_page(pte)  pfn_to_page(pte_pfn(pte))
-
-/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- */
-BTFIXUPDEF_CALL_CONST(pte_t, mk_pte, struct page *, pgprot_t)
-
-BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_phys, unsigned long, pgprot_t)
-BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int)
-BTFIXUPDEF_CALL_CONST(pgprot_t, pgprot_noncached, pgprot_t)
-
-#define mk_pte(page,pgprot) BTFIXUP_CALL(mk_pte)(page,pgprot)
-#define mk_pte_phys(page,pgprot) BTFIXUP_CALL(mk_pte_phys)(page,pgprot)
-#define mk_pte_io(page,pgprot,space) BTFIXUP_CALL(mk_pte_io)(page,pgprot,space)
-
-#define pgprot_noncached(pgprot) BTFIXUP_CALL(pgprot_noncached)(pgprot)
-
-BTFIXUPDEF_INT(pte_modify_mask)
-
-static pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__;
-static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-{
-       return __pte((pte_val(pte) & BTFIXUP_INT(pte_modify_mask)) |
-               pgprot_val(newprot));
-}
-
-#define pgd_index(address) ((address) >> PGDIR_SHIFT)
-
-/* to find an entry in a page-table-directory */
-#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
-
-/* to find an entry in a kernel page-table-directory */
-#define pgd_offset_k(address) pgd_offset(&init_mm, address)
-
-/* Find an entry in the second-level page table.. */
-BTFIXUPDEF_CALL(pmd_t *, pmd_offset, pgd_t *, unsigned long)
-#define pmd_offset(dir,addr) BTFIXUP_CALL(pmd_offset)(dir,addr)
-
-/* Find an entry in the third-level page table.. */ 
-BTFIXUPDEF_CALL(pte_t *, pte_offset_kernel, pmd_t *, unsigned long)
-#define pte_offset_kernel(dir,addr) BTFIXUP_CALL(pte_offset_kernel)(dir,addr)
-
-/*
- * This shortcut works on sun4m (and sun4d) because the nocache area is static,
- * and sun4c is guaranteed to have no highmem anyway.
- */
-#define pte_offset_map(d, a)           pte_offset_kernel(d,a)
-#define pte_offset_map_nested(d, a)    pte_offset_kernel(d,a)
-
-#define pte_unmap(pte)         do{}while(0)
-#define pte_unmap_nested(pte)  do{}while(0)
-
-/* Certain architectures need to do special things when pte's
- * within a page table are directly modified.  Thus, the following
- * hook is made available.
- */
-
-BTFIXUPDEF_CALL(void, set_pte, pte_t *, pte_t)
-
-#define set_pte(ptep,pteval) BTFIXUP_CALL(set_pte)(ptep,pteval)
-#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
-
-struct seq_file;
-BTFIXUPDEF_CALL(void, mmu_info, struct seq_file *)
-
-#define mmu_info(p) BTFIXUP_CALL(mmu_info)(p)
-
-/* Fault handler stuff... */
-#define FAULT_CODE_PROT     0x1
-#define FAULT_CODE_WRITE    0x2
-#define FAULT_CODE_USER     0x4
-
-BTFIXUPDEF_CALL(void, update_mmu_cache, struct vm_area_struct *, unsigned long, pte_t)
-
-#define update_mmu_cache(vma,addr,pte) BTFIXUP_CALL(update_mmu_cache)(vma,addr,pte)
-
-BTFIXUPDEF_CALL(void, sparc_mapiorange, unsigned int, unsigned long,
-    unsigned long, unsigned int)
-BTFIXUPDEF_CALL(void, sparc_unmapiorange, unsigned long, unsigned int)
-#define sparc_mapiorange(bus,pa,va,len) BTFIXUP_CALL(sparc_mapiorange)(bus,pa,va,len)
-#define sparc_unmapiorange(va,len) BTFIXUP_CALL(sparc_unmapiorange)(va,len)
-
-extern int invalid_segment;
-
-/* Encode and de-code a swap entry */
-BTFIXUPDEF_CALL(unsigned long, __swp_type, swp_entry_t)
-BTFIXUPDEF_CALL(unsigned long, __swp_offset, swp_entry_t)
-BTFIXUPDEF_CALL(swp_entry_t, __swp_entry, unsigned long, unsigned long)
-
-#define __swp_type(__x)                        BTFIXUP_CALL(__swp_type)(__x)
-#define __swp_offset(__x)              BTFIXUP_CALL(__swp_offset)(__x)
-#define __swp_entry(__type,__off)      BTFIXUP_CALL(__swp_entry)(__type,__off)
-
-#define __pte_to_swp_entry(pte)                ((swp_entry_t) { pte_val(pte) })
-#define __swp_entry_to_pte(x)          ((pte_t) { (x).val })
-
-/* file-offset-in-pte helpers */
-BTFIXUPDEF_CALL(unsigned long, pte_to_pgoff, pte_t pte);
-BTFIXUPDEF_CALL(pte_t, pgoff_to_pte, unsigned long pgoff);
-
-#define pte_to_pgoff(pte) BTFIXUP_CALL(pte_to_pgoff)(pte)
-#define pgoff_to_pte(off) BTFIXUP_CALL(pgoff_to_pte)(off)
-
-/*
- * This is made a constant because mm/fremap.c required a constant.
- * Note that layout of these bits is different between sun4c.c and srmmu.c.
- */
-#define PTE_FILE_MAX_BITS 24
-
-/*
- */
-struct ctx_list {
-       struct ctx_list *next;
-       struct ctx_list *prev;
-       unsigned int ctx_number;
-       struct mm_struct *ctx_mm;
-};
-
-extern struct ctx_list *ctx_list_pool;  /* Dynamically allocated */
-extern struct ctx_list ctx_free;        /* Head of free list */
-extern struct ctx_list ctx_used;        /* Head of used contexts list */
-
-#define NO_CONTEXT     -1
-
-static inline void remove_from_ctx_list(struct ctx_list *entry)
-{
-       entry->next->prev = entry->prev;
-       entry->prev->next = entry->next;
-}
-
-static inline void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry)
-{
-       entry->next = head;
-       (entry->prev = head->prev)->next = entry;
-       head->prev = entry;
-}
-#define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry)
-#define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry)
-
-static inline unsigned long
-__get_phys (unsigned long addr)
-{
-       switch (sparc_cpu_model){
-       case sun4:
-       case sun4c:
-               return sun4c_get_pte (addr) << PAGE_SHIFT;
-       case sun4m:
-       case sun4d:
-               return ((srmmu_get_pte (addr) & 0xffffff00) << 4);
-       default:
-               return 0;
-       }
-}
-
-static inline int
-__get_iospace (unsigned long addr)
-{
-       switch (sparc_cpu_model){
-       case sun4:
-       case sun4c:
-               return -1; /* Don't check iospace on sun4c */
-       case sun4m:
-       case sun4d:
-               return (srmmu_get_pte (addr) >> 28);
-       default:
-               return -1;
-       }
-}
-
-extern unsigned long *sparc_valid_addr_bitmap;
-
-/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
-#define kern_addr_valid(addr) \
-       (test_bit(__pa((unsigned long)(addr))>>20, sparc_valid_addr_bitmap))
-
-extern int io_remap_pfn_range(struct vm_area_struct *vma,
-                             unsigned long from, unsigned long pfn,
-                             unsigned long size, pgprot_t prot);
-
-/*
- * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
- * its high 4 bits.  These macros/functions put it there or get it from there.
- */
-#define MK_IOSPACE_PFN(space, pfn)     (pfn | (space << (BITS_PER_LONG - 4)))
-#define GET_IOSPACE(pfn)               (pfn >> (BITS_PER_LONG - 4))
-#define GET_PFN(pfn)                   (pfn & 0x0fffffffUL)
-
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-({                                                                       \
-       int __changed = !pte_same(*(__ptep), __entry);                    \
-       if (__changed) {                                                  \
-               set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry); \
-               flush_tlb_page(__vma, __address);                         \
-       }                                                                 \
-       (sparc_cpu_model == sun4c) || __changed;                          \
-})
-
-#include <asm-generic/pgtable.h>
-
-#endif /* !(__ASSEMBLY__) */
-
-/* We provide our own get_unmapped_area to cope with VA holes for userland */
-#define HAVE_ARCH_UNMAPPED_AREA
-
-/*
- * No page table caches to initialise
- */
-#define pgtable_cache_init()   do { } while (0)
-
-#endif /* !(_SPARC_PGTABLE_H) */
diff --git a/include/asm-sparc/pgtable_32.h b/include/asm-sparc/pgtable_32.h
new file mode 100644 (file)
index 0000000..781bd46
--- /dev/null
@@ -0,0 +1,480 @@
+#ifndef _SPARC_PGTABLE_H
+#define _SPARC_PGTABLE_H
+
+/*  asm-sparc/pgtable.h:  Defines and functions used to work
+ *                        with Sparc page tables.
+ *
+ *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *  Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#ifndef __ASSEMBLY__
+#include <asm-generic/4level-fixup.h>
+
+#include <linux/spinlock.h>
+#include <linux/swap.h>
+#include <asm/types.h>
+#ifdef CONFIG_SUN4
+#include <asm/pgtsun4.h>
+#else
+#include <asm/pgtsun4c.h>
+#endif
+#include <asm/pgtsrmmu.h>
+#include <asm/vac-ops.h>
+#include <asm/oplib.h>
+#include <asm/btfixup.h>
+#include <asm/system.h>
+
+
+struct vm_area_struct;
+struct page;
+
+extern void load_mmu(void);
+extern unsigned long calc_highpages(void);
+
+BTFIXUPDEF_SIMM13(pgdir_shift)
+BTFIXUPDEF_SETHI(pgdir_size)
+BTFIXUPDEF_SETHI(pgdir_mask)
+
+BTFIXUPDEF_SIMM13(ptrs_per_pmd)
+BTFIXUPDEF_SIMM13(ptrs_per_pgd)
+BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
+
+#define pte_ERROR(e)   __builtin_trap()
+#define pmd_ERROR(e)   __builtin_trap()
+#define pgd_ERROR(e)   __builtin_trap()
+
+BTFIXUPDEF_INT(page_none)
+BTFIXUPDEF_INT(page_copy)
+BTFIXUPDEF_INT(page_readonly)
+BTFIXUPDEF_INT(page_kernel)
+
+#define PMD_SHIFT              SUN4C_PMD_SHIFT
+#define PMD_SIZE               (1UL << PMD_SHIFT)
+#define PMD_MASK               (~(PMD_SIZE-1))
+#define PMD_ALIGN(__addr)      (((__addr) + ~PMD_MASK) & PMD_MASK)
+#define PGDIR_SHIFT            BTFIXUP_SIMM13(pgdir_shift)
+#define PGDIR_SIZE             BTFIXUP_SETHI(pgdir_size)
+#define PGDIR_MASK             BTFIXUP_SETHI(pgdir_mask)
+#define PTRS_PER_PTE           1024
+#define PTRS_PER_PMD           BTFIXUP_SIMM13(ptrs_per_pmd)
+#define PTRS_PER_PGD           BTFIXUP_SIMM13(ptrs_per_pgd)
+#define USER_PTRS_PER_PGD      BTFIXUP_SIMM13(user_ptrs_per_pgd)
+#define FIRST_USER_ADDRESS     0
+#define PTE_SIZE               (PTRS_PER_PTE*4)
+
+#define PAGE_NONE      __pgprot(BTFIXUP_INT(page_none))
+extern pgprot_t PAGE_SHARED;
+#define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
+#define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
+
+extern unsigned long page_kernel;
+
+#ifdef MODULE
+#define PAGE_KERNEL    page_kernel
+#else
+#define PAGE_KERNEL    __pgprot(BTFIXUP_INT(page_kernel))
+#endif
+
+/* Top-level page directory */
+extern pgd_t swapper_pg_dir[1024];
+
+extern void paging_init(void);
+
+/* Page table for 0-4MB for everybody, on the Sparc this
+ * holds the same as on the i386.
+ */
+extern pte_t pg0[1024];
+extern pte_t pg1[1024];
+extern pte_t pg2[1024];
+extern pte_t pg3[1024];
+
+extern unsigned long ptr_in_current_pgd;
+
+/* Here is a trick, since mmap.c need the initializer elements for
+ * protection_map[] to be constant at compile time, I set the following
+ * to all zeros.  I set it to the real values after I link in the
+ * appropriate MMU page table routines at boot time.
+ */
+#define __P000  __pgprot(0)
+#define __P001  __pgprot(0)
+#define __P010  __pgprot(0)
+#define __P011  __pgprot(0)
+#define __P100  __pgprot(0)
+#define __P101  __pgprot(0)
+#define __P110  __pgprot(0)
+#define __P111  __pgprot(0)
+
+#define __S000 __pgprot(0)
+#define __S001 __pgprot(0)
+#define __S010 __pgprot(0)
+#define __S011 __pgprot(0)
+#define __S100 __pgprot(0)
+#define __S101 __pgprot(0)
+#define __S110 __pgprot(0)
+#define __S111 __pgprot(0)
+
+extern int num_contexts;
+
+/* First physical page can be anywhere, the following is needed so that
+ * va-->pa and vice versa conversions work properly without performance
+ * hit for all __pa()/__va() operations.
+ */
+extern unsigned long phys_base;
+extern unsigned long pfn_base;
+
+/*
+ * BAD_PAGETABLE is used when we need a bogus page-table, while
+ * BAD_PAGE is used for a bogus page.
+ *
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern pte_t * __bad_pagetable(void);
+extern pte_t __bad_page(void);
+extern unsigned long empty_zero_page;
+
+#define BAD_PAGETABLE __bad_pagetable()
+#define BAD_PAGE __bad_page()
+#define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page))
+
+/*
+ */
+BTFIXUPDEF_CALL_CONST(struct page *, pmd_page, pmd_t)
+BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page_vaddr, pgd_t)
+
+#define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd)
+#define pgd_page_vaddr(pgd) BTFIXUP_CALL(pgd_page_vaddr)(pgd)
+
+BTFIXUPDEF_SETHI(none_mask)
+BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t)
+BTFIXUPDEF_CALL(void, pte_clear, pte_t *)
+
+static inline int pte_none(pte_t pte)
+{
+       return !(pte_val(pte) & ~BTFIXUP_SETHI(none_mask));
+}
+
+#define pte_present(pte) BTFIXUP_CALL(pte_present)(pte)
+#define pte_clear(mm,addr,pte) BTFIXUP_CALL(pte_clear)(pte)
+
+BTFIXUPDEF_CALL_CONST(int, pmd_bad, pmd_t)
+BTFIXUPDEF_CALL_CONST(int, pmd_present, pmd_t)
+BTFIXUPDEF_CALL(void, pmd_clear, pmd_t *)
+
+static inline int pmd_none(pmd_t pmd)
+{
+       return !(pmd_val(pmd) & ~BTFIXUP_SETHI(none_mask));
+}
+
+#define pmd_bad(pmd) BTFIXUP_CALL(pmd_bad)(pmd)
+#define pmd_present(pmd) BTFIXUP_CALL(pmd_present)(pmd)
+#define pmd_clear(pmd) BTFIXUP_CALL(pmd_clear)(pmd)
+
+BTFIXUPDEF_CALL_CONST(int, pgd_none, pgd_t)
+BTFIXUPDEF_CALL_CONST(int, pgd_bad, pgd_t)
+BTFIXUPDEF_CALL_CONST(int, pgd_present, pgd_t)
+BTFIXUPDEF_CALL(void, pgd_clear, pgd_t *)
+
+#define pgd_none(pgd) BTFIXUP_CALL(pgd_none)(pgd)
+#define pgd_bad(pgd) BTFIXUP_CALL(pgd_bad)(pgd)
+#define pgd_present(pgd) BTFIXUP_CALL(pgd_present)(pgd)
+#define pgd_clear(pgd) BTFIXUP_CALL(pgd_clear)(pgd)
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+BTFIXUPDEF_HALF(pte_writei)
+BTFIXUPDEF_HALF(pte_dirtyi)
+BTFIXUPDEF_HALF(pte_youngi)
+
+static int pte_write(pte_t pte) __attribute_const__;
+static inline int pte_write(pte_t pte)
+{
+       return pte_val(pte) & BTFIXUP_HALF(pte_writei);
+}
+
+static int pte_dirty(pte_t pte) __attribute_const__;
+static inline int pte_dirty(pte_t pte)
+{
+       return pte_val(pte) & BTFIXUP_HALF(pte_dirtyi);
+}
+
+static int pte_young(pte_t pte) __attribute_const__;
+static inline int pte_young(pte_t pte)
+{
+       return pte_val(pte) & BTFIXUP_HALF(pte_youngi);
+}
+
+/*
+ * The following only work if pte_present() is not true.
+ */
+BTFIXUPDEF_HALF(pte_filei)
+
+static int pte_file(pte_t pte) __attribute_const__;
+static inline int pte_file(pte_t pte)
+{
+       return pte_val(pte) & BTFIXUP_HALF(pte_filei);
+}
+
+static inline int pte_special(pte_t pte)
+{
+       return 0;
+}
+
+/*
+ */
+BTFIXUPDEF_HALF(pte_wrprotecti)
+BTFIXUPDEF_HALF(pte_mkcleani)
+BTFIXUPDEF_HALF(pte_mkoldi)
+
+static pte_t pte_wrprotect(pte_t pte) __attribute_const__;
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+       return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_wrprotecti));
+}
+
+static pte_t pte_mkclean(pte_t pte) __attribute_const__;
+static inline pte_t pte_mkclean(pte_t pte)
+{
+       return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkcleani));
+}
+
+static pte_t pte_mkold(pte_t pte) __attribute_const__;
+static inline pte_t pte_mkold(pte_t pte)
+{
+       return __pte(pte_val(pte) & ~BTFIXUP_HALF(pte_mkoldi));
+}
+
+BTFIXUPDEF_CALL_CONST(pte_t, pte_mkwrite, pte_t)
+BTFIXUPDEF_CALL_CONST(pte_t, pte_mkdirty, pte_t)
+BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung, pte_t)
+
+#define pte_mkwrite(pte) BTFIXUP_CALL(pte_mkwrite)(pte)
+#define pte_mkdirty(pte) BTFIXUP_CALL(pte_mkdirty)(pte)
+#define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte)
+
+#define pte_mkspecial(pte)    (pte)
+
+#define pfn_pte(pfn, prot)             mk_pte(pfn_to_page(pfn), prot)
+
+BTFIXUPDEF_CALL(unsigned long,  pte_pfn, pte_t)
+#define pte_pfn(pte) BTFIXUP_CALL(pte_pfn)(pte)
+#define pte_page(pte)  pfn_to_page(pte_pfn(pte))
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+BTFIXUPDEF_CALL_CONST(pte_t, mk_pte, struct page *, pgprot_t)
+
+BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_phys, unsigned long, pgprot_t)
+BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int)
+BTFIXUPDEF_CALL_CONST(pgprot_t, pgprot_noncached, pgprot_t)
+
+#define mk_pte(page,pgprot) BTFIXUP_CALL(mk_pte)(page,pgprot)
+#define mk_pte_phys(page,pgprot) BTFIXUP_CALL(mk_pte_phys)(page,pgprot)
+#define mk_pte_io(page,pgprot,space) BTFIXUP_CALL(mk_pte_io)(page,pgprot,space)
+
+#define pgprot_noncached(pgprot) BTFIXUP_CALL(pgprot_noncached)(pgprot)
+
+BTFIXUPDEF_INT(pte_modify_mask)
+
+static pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__;
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+       return __pte((pte_val(pte) & BTFIXUP_INT(pte_modify_mask)) |
+               pgprot_val(newprot));
+}
+
+#define pgd_index(address) ((address) >> PGDIR_SHIFT)
+
+/* to find an entry in a page-table-directory */
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/* Find an entry in the second-level page table.. */
+BTFIXUPDEF_CALL(pmd_t *, pmd_offset, pgd_t *, unsigned long)
+#define pmd_offset(dir,addr) BTFIXUP_CALL(pmd_offset)(dir,addr)
+
+/* Find an entry in the third-level page table.. */
+BTFIXUPDEF_CALL(pte_t *, pte_offset_kernel, pmd_t *, unsigned long)
+#define pte_offset_kernel(dir,addr) BTFIXUP_CALL(pte_offset_kernel)(dir,addr)
+
+/*
+ * This shortcut works on sun4m (and sun4d) because the nocache area is static,
+ * and sun4c is guaranteed to have no highmem anyway.
+ */
+#define pte_offset_map(d, a)           pte_offset_kernel(d,a)
+#define pte_offset_map_nested(d, a)    pte_offset_kernel(d,a)
+
+#define pte_unmap(pte)         do{}while(0)
+#define pte_unmap_nested(pte)  do{}while(0)
+
+/* Certain architectures need to do special things when pte's
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+
+BTFIXUPDEF_CALL(void, set_pte, pte_t *, pte_t)
+
+#define set_pte(ptep,pteval) BTFIXUP_CALL(set_pte)(ptep,pteval)
+#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
+
+struct seq_file;
+BTFIXUPDEF_CALL(void, mmu_info, struct seq_file *)
+
+#define mmu_info(p) BTFIXUP_CALL(mmu_info)(p)
+
+/* Fault handler stuff... */
+#define FAULT_CODE_PROT     0x1
+#define FAULT_CODE_WRITE    0x2
+#define FAULT_CODE_USER     0x4
+
+BTFIXUPDEF_CALL(void, update_mmu_cache, struct vm_area_struct *, unsigned long, pte_t)
+
+#define update_mmu_cache(vma,addr,pte) BTFIXUP_CALL(update_mmu_cache)(vma,addr,pte)
+
+BTFIXUPDEF_CALL(void, sparc_mapiorange, unsigned int, unsigned long,
+    unsigned long, unsigned int)
+BTFIXUPDEF_CALL(void, sparc_unmapiorange, unsigned long, unsigned int)
+#define sparc_mapiorange(bus,pa,va,len) BTFIXUP_CALL(sparc_mapiorange)(bus,pa,va,len)
+#define sparc_unmapiorange(va,len) BTFIXUP_CALL(sparc_unmapiorange)(va,len)
+
+extern int invalid_segment;
+
+/* Encode and de-code a swap entry */
+BTFIXUPDEF_CALL(unsigned long, __swp_type, swp_entry_t)
+BTFIXUPDEF_CALL(unsigned long, __swp_offset, swp_entry_t)
+BTFIXUPDEF_CALL(swp_entry_t, __swp_entry, unsigned long, unsigned long)
+
+#define __swp_type(__x)                        BTFIXUP_CALL(__swp_type)(__x)
+#define __swp_offset(__x)              BTFIXUP_CALL(__swp_offset)(__x)
+#define __swp_entry(__type,__off)      BTFIXUP_CALL(__swp_entry)(__type,__off)
+
+#define __pte_to_swp_entry(pte)                ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)          ((pte_t) { (x).val })
+
+/* file-offset-in-pte helpers */
+BTFIXUPDEF_CALL(unsigned long, pte_to_pgoff, pte_t pte);
+BTFIXUPDEF_CALL(pte_t, pgoff_to_pte, unsigned long pgoff);
+
+#define pte_to_pgoff(pte) BTFIXUP_CALL(pte_to_pgoff)(pte)
+#define pgoff_to_pte(off) BTFIXUP_CALL(pgoff_to_pte)(off)
+
+/*
+ * This is made a constant because mm/fremap.c required a constant.
+ * Note that layout of these bits is different between sun4c.c and srmmu.c.
+ */
+#define PTE_FILE_MAX_BITS 24
+
+/*
+ */
+struct ctx_list {
+       struct ctx_list *next;
+       struct ctx_list *prev;
+       unsigned int ctx_number;
+       struct mm_struct *ctx_mm;
+};
+
+extern struct ctx_list *ctx_list_pool;  /* Dynamically allocated */
+extern struct ctx_list ctx_free;        /* Head of free list */
+extern struct ctx_list ctx_used;        /* Head of used contexts list */
+
+#define NO_CONTEXT     -1
+
+static inline void remove_from_ctx_list(struct ctx_list *entry)
+{
+       entry->next->prev = entry->prev;
+       entry->prev->next = entry->next;
+}
+
+static inline void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry)
+{
+       entry->next = head;
+       (entry->prev = head->prev)->next = entry;
+       head->prev = entry;
+}
+#define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry)
+#define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry)
+
+static inline unsigned long
+__get_phys (unsigned long addr)
+{
+       switch (sparc_cpu_model){
+       case sun4:
+       case sun4c:
+               return sun4c_get_pte (addr) << PAGE_SHIFT;
+       case sun4m:
+       case sun4d:
+               return ((srmmu_get_pte (addr) & 0xffffff00) << 4);
+       default:
+               return 0;
+       }
+}
+
+static inline int
+__get_iospace (unsigned long addr)
+{
+       switch (sparc_cpu_model){
+       case sun4:
+       case sun4c:
+               return -1; /* Don't check iospace on sun4c */
+       case sun4m:
+       case sun4d:
+               return (srmmu_get_pte (addr) >> 28);
+       default:
+               return -1;
+       }
+}
+
+extern unsigned long *sparc_valid_addr_bitmap;
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define kern_addr_valid(addr) \
+       (test_bit(__pa((unsigned long)(addr))>>20, sparc_valid_addr_bitmap))
+
+extern int io_remap_pfn_range(struct vm_area_struct *vma,
+                             unsigned long from, unsigned long pfn,
+                             unsigned long size, pgprot_t prot);
+
+/*
+ * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
+ * its high 4 bits.  These macros/functions put it there or get it from there.
+ */
+#define MK_IOSPACE_PFN(space, pfn)     (pfn | (space << (BITS_PER_LONG - 4)))
+#define GET_IOSPACE(pfn)               (pfn >> (BITS_PER_LONG - 4))
+#define GET_PFN(pfn)                   (pfn & 0x0fffffffUL)
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
+({                                                                       \
+       int __changed = !pte_same(*(__ptep), __entry);                    \
+       if (__changed) {                                                  \
+               set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry); \
+               flush_tlb_page(__vma, __address);                         \
+       }                                                                 \
+       (sparc_cpu_model == sun4c) || __changed;                          \
+})
+
+#include <asm-generic/pgtable.h>
+
+#endif /* !(__ASSEMBLY__) */
+
+#define VMALLOC_START           0xfe600000
+/* XXX Alter this when I get around to fixing sun4c - Anton */
+#define VMALLOC_END             0xffc00000
+
+
+/* We provide our own get_unmapped_area to cope with VA holes for userland */
+#define HAVE_ARCH_UNMAPPED_AREA
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()   do { } while (0)
+
+#endif /* !(_SPARC_PGTABLE_H) */
diff --git a/include/asm-sparc/pgtable_64.h b/include/asm-sparc/pgtable_64.h
new file mode 100644 (file)
index 0000000..bb9ec2c
--- /dev/null
@@ -0,0 +1,775 @@
+/*
+ * pgtable.h: SpitFire page table operations.
+ *
+ * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#ifndef _SPARC64_PGTABLE_H
+#define _SPARC64_PGTABLE_H
+
+/* This file contains the functions and defines necessary to modify and use
+ * the SpitFire page tables.
+ */
+
+#include <asm-generic/pgtable-nopud.h>
+
+#include <linux/compiler.h>
+#include <linux/const.h>
+#include <asm/types.h>
+#include <asm/spitfire.h>
+#include <asm/asi.h>
+#include <asm/system.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+
+/* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB).
+ * The page copy blockops can use 0x6000000 to 0x8000000.
+ * The TSB is mapped in the 0x8000000 to 0xa000000 range.
+ * The PROM resides in an area spanning 0xf0000000 to 0x100000000.
+ * The vmalloc area spans 0x100000000 to 0x200000000.
+ * Since modules need to be in the lowest 32-bits of the address space,
+ * we place them right before the OBP area from 0x10000000 to 0xf0000000.
+ * There is a single static kernel PMD which maps from 0x0 to address
+ * 0x400000000.
+ */
+#define        TLBTEMP_BASE            _AC(0x0000000006000000,UL)
+#define        TSBMAP_BASE             _AC(0x0000000008000000,UL)
+#define MODULES_VADDR          _AC(0x0000000010000000,UL)
+#define MODULES_LEN            _AC(0x00000000e0000000,UL)
+#define MODULES_END            _AC(0x00000000f0000000,UL)
+#define LOW_OBP_ADDRESS                _AC(0x00000000f0000000,UL)
+#define HI_OBP_ADDRESS         _AC(0x0000000100000000,UL)
+#define VMALLOC_START          _AC(0x0000000100000000,UL)
+#define VMALLOC_END            _AC(0x0000000200000000,UL)
+#define VMEMMAP_BASE           _AC(0x0000000200000000,UL)
+
+#define vmemmap                        ((struct page *)VMEMMAP_BASE)
+
+/* XXX All of this needs to be rethought so we can take advantage
+ * XXX cheetah's full 64-bit virtual address space, ie. no more hole
+ * XXX in the middle like on spitfire. -DaveM
+ */
+/*
+ * Given a virtual address, the lowest PAGE_SHIFT bits determine offset
+ * into the page; the next higher PAGE_SHIFT-3 bits determine the pte#
+ * in the proper pagetable (the -3 is from the 8 byte ptes, and each page
+ * table is a single page long). The next higher PMD_BITS determine pmd#
+ * in the proper pmdtable (where we must have PMD_BITS <= (PAGE_SHIFT-2)
+ * since the pmd entries are 4 bytes, and each pmd page is a single page
+ * long). Finally, the higher few bits determine pgde#.
+ */
+
+/* PMD_SHIFT determines the size of the area a second-level page
+ * table can map
+ */
+#define PMD_SHIFT      (PAGE_SHIFT + (PAGE_SHIFT-3))
+#define PMD_SIZE       (_AC(1,UL) << PMD_SHIFT)
+#define PMD_MASK       (~(PMD_SIZE-1))
+#define PMD_BITS       (PAGE_SHIFT - 2)
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define PGDIR_SHIFT    (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS)
+#define PGDIR_SIZE     (_AC(1,UL) << PGDIR_SHIFT)
+#define PGDIR_MASK     (~(PGDIR_SIZE-1))
+#define PGDIR_BITS     (PAGE_SHIFT - 2)
+
+#ifndef __ASSEMBLY__
+
+#include <linux/sched.h>
+
+/* Entries per page directory level. */
+#define PTRS_PER_PTE   (1UL << (PAGE_SHIFT-3))
+#define PTRS_PER_PMD   (1UL << PMD_BITS)
+#define PTRS_PER_PGD   (1UL << PGDIR_BITS)
+
+/* Kernel has a separate 44bit address space. */
+#define FIRST_USER_ADDRESS     0
+
+#define pte_ERROR(e)   __builtin_trap()
+#define pmd_ERROR(e)   __builtin_trap()
+#define pgd_ERROR(e)   __builtin_trap()
+
+#endif /* !(__ASSEMBLY__) */
+
+/* PTE bits which are the same in SUN4U and SUN4V format.  */
+#define _PAGE_VALID      _AC(0x8000000000000000,UL) /* Valid TTE            */
+#define _PAGE_R                  _AC(0x8000000000000000,UL) /* Keep ref bit uptodate*/
+
+/* SUN4U pte bits... */
+#define _PAGE_SZ4MB_4U   _AC(0x6000000000000000,UL) /* 4MB Page             */
+#define _PAGE_SZ512K_4U          _AC(0x4000000000000000,UL) /* 512K Page            */
+#define _PAGE_SZ64K_4U   _AC(0x2000000000000000,UL) /* 64K Page             */
+#define _PAGE_SZ8K_4U    _AC(0x0000000000000000,UL) /* 8K Page              */
+#define _PAGE_NFO_4U     _AC(0x1000000000000000,UL) /* No Fault Only        */
+#define _PAGE_IE_4U      _AC(0x0800000000000000,UL) /* Invert Endianness    */
+#define _PAGE_SOFT2_4U   _AC(0x07FC000000000000,UL) /* Software bits, set 2 */
+#define _PAGE_RES1_4U    _AC(0x0002000000000000,UL) /* Reserved             */
+#define _PAGE_SZ32MB_4U          _AC(0x0001000000000000,UL) /* (Panther) 32MB page  */
+#define _PAGE_SZ256MB_4U  _AC(0x2001000000000000,UL) /* (Panther) 256MB page */
+#define _PAGE_SZALL_4U   _AC(0x6001000000000000,UL) /* All pgsz bits        */
+#define _PAGE_SN_4U      _AC(0x0000800000000000,UL) /* (Cheetah) Snoop      */
+#define _PAGE_RES2_4U    _AC(0x0000780000000000,UL) /* Reserved             */
+#define _PAGE_PADDR_4U   _AC(0x000007FFFFFFE000,UL) /* (Cheetah) pa[42:13]  */
+#define _PAGE_SOFT_4U    _AC(0x0000000000001F80,UL) /* Software bits:       */
+#define _PAGE_EXEC_4U    _AC(0x0000000000001000,UL) /* Executable SW bit    */
+#define _PAGE_MODIFIED_4U _AC(0x0000000000000800,UL) /* Modified (dirty)     */
+#define _PAGE_FILE_4U    _AC(0x0000000000000800,UL) /* Pagecache page       */
+#define _PAGE_ACCESSED_4U _AC(0x0000000000000400,UL) /* Accessed (ref'd)     */
+#define _PAGE_READ_4U    _AC(0x0000000000000200,UL) /* Readable SW Bit      */
+#define _PAGE_WRITE_4U   _AC(0x0000000000000100,UL) /* Writable SW Bit      */
+#define _PAGE_PRESENT_4U  _AC(0x0000000000000080,UL) /* Present              */
+#define _PAGE_L_4U       _AC(0x0000000000000040,UL) /* Locked TTE           */
+#define _PAGE_CP_4U      _AC(0x0000000000000020,UL) /* Cacheable in P-Cache */
+#define _PAGE_CV_4U      _AC(0x0000000000000010,UL) /* Cacheable in V-Cache */
+#define _PAGE_E_4U       _AC(0x0000000000000008,UL) /* side-Effect          */
+#define _PAGE_P_4U       _AC(0x0000000000000004,UL) /* Privileged Page      */
+#define _PAGE_W_4U       _AC(0x0000000000000002,UL) /* Writable             */
+
+/* SUN4V pte bits... */
+#define _PAGE_NFO_4V     _AC(0x4000000000000000,UL) /* No Fault Only        */
+#define _PAGE_SOFT2_4V   _AC(0x3F00000000000000,UL) /* Software bits, set 2 */
+#define _PAGE_MODIFIED_4V _AC(0x2000000000000000,UL) /* Modified (dirty)     */
+#define _PAGE_ACCESSED_4V _AC(0x1000000000000000,UL) /* Accessed (ref'd)     */
+#define _PAGE_READ_4V    _AC(0x0800000000000000,UL) /* Readable SW Bit      */
+#define _PAGE_WRITE_4V   _AC(0x0400000000000000,UL) /* Writable SW Bit      */
+#define _PAGE_PADDR_4V   _AC(0x00FFFFFFFFFFE000,UL) /* paddr[55:13]         */
+#define _PAGE_IE_4V      _AC(0x0000000000001000,UL) /* Invert Endianness    */
+#define _PAGE_E_4V       _AC(0x0000000000000800,UL) /* side-Effect          */
+#define _PAGE_CP_4V      _AC(0x0000000000000400,UL) /* Cacheable in P-Cache */
+#define _PAGE_CV_4V      _AC(0x0000000000000200,UL) /* Cacheable in V-Cache */
+#define _PAGE_P_4V       _AC(0x0000000000000100,UL) /* Privileged Page      */
+#define _PAGE_EXEC_4V    _AC(0x0000000000000080,UL) /* Executable Page      */
+#define _PAGE_W_4V       _AC(0x0000000000000040,UL) /* Writable             */
+#define _PAGE_SOFT_4V    _AC(0x0000000000000030,UL) /* Software bits        */
+#define _PAGE_FILE_4V    _AC(0x0000000000000020,UL) /* Pagecache page       */
+#define _PAGE_PRESENT_4V  _AC(0x0000000000000010,UL) /* Present              */
+#define _PAGE_RESV_4V    _AC(0x0000000000000008,UL) /* Reserved             */
+#define _PAGE_SZ16GB_4V          _AC(0x0000000000000007,UL) /* 16GB Page            */
+#define _PAGE_SZ2GB_4V   _AC(0x0000000000000006,UL) /* 2GB Page             */
+#define _PAGE_SZ256MB_4V  _AC(0x0000000000000005,UL) /* 256MB Page           */
+#define _PAGE_SZ32MB_4V          _AC(0x0000000000000004,UL) /* 32MB Page            */
+#define _PAGE_SZ4MB_4V   _AC(0x0000000000000003,UL) /* 4MB Page             */
+#define _PAGE_SZ512K_4V          _AC(0x0000000000000002,UL) /* 512K Page            */
+#define _PAGE_SZ64K_4V   _AC(0x0000000000000001,UL) /* 64K Page             */
+#define _PAGE_SZ8K_4V    _AC(0x0000000000000000,UL) /* 8K Page              */
+#define _PAGE_SZALL_4V   _AC(0x0000000000000007,UL) /* All pgsz bits        */
+
+#if PAGE_SHIFT == 13
+#define _PAGE_SZBITS_4U        _PAGE_SZ8K_4U
+#define _PAGE_SZBITS_4V        _PAGE_SZ8K_4V
+#elif PAGE_SHIFT == 16
+#define _PAGE_SZBITS_4U        _PAGE_SZ64K_4U
+#define _PAGE_SZBITS_4V        _PAGE_SZ64K_4V
+#else
+#error Wrong PAGE_SHIFT specified
+#endif
+
+#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
+#define _PAGE_SZHUGE_4U        _PAGE_SZ4MB_4U
+#define _PAGE_SZHUGE_4V        _PAGE_SZ4MB_4V
+#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
+#define _PAGE_SZHUGE_4U        _PAGE_SZ512K_4U
+#define _PAGE_SZHUGE_4V        _PAGE_SZ512K_4V
+#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
+#define _PAGE_SZHUGE_4U        _PAGE_SZ64K_4U
+#define _PAGE_SZHUGE_4V        _PAGE_SZ64K_4V
+#endif
+
+/* These are actually filled in at boot time by sun4{u,v}_pgprot_init() */
+#define __P000 __pgprot(0)
+#define __P001 __pgprot(0)
+#define __P010 __pgprot(0)
+#define __P011 __pgprot(0)
+#define __P100 __pgprot(0)
+#define __P101 __pgprot(0)
+#define __P110 __pgprot(0)
+#define __P111 __pgprot(0)
+
+#define __S000 __pgprot(0)
+#define __S001 __pgprot(0)
+#define __S010 __pgprot(0)
+#define __S011 __pgprot(0)
+#define __S100 __pgprot(0)
+#define __S101 __pgprot(0)
+#define __S110 __pgprot(0)
+#define __S111 __pgprot(0)
+
+#ifndef __ASSEMBLY__
+
+extern pte_t mk_pte_io(unsigned long, pgprot_t, int, unsigned long);
+
+extern unsigned long pte_sz_bits(unsigned long size);
+
+extern pgprot_t PAGE_KERNEL;
+extern pgprot_t PAGE_KERNEL_LOCKED;
+extern pgprot_t PAGE_COPY;
+extern pgprot_t PAGE_SHARED;
+
+/* XXX This uglyness is for the atyfb driver's sparc mmap() support. XXX */
+extern unsigned long _PAGE_IE;
+extern unsigned long _PAGE_E;
+extern unsigned long _PAGE_CACHE;
+
+extern unsigned long pg_iobits;
+extern unsigned long _PAGE_ALL_SZ_BITS;
+extern unsigned long _PAGE_SZBITS;
+
+extern struct page *mem_map_zero;
+#define ZERO_PAGE(vaddr)       (mem_map_zero)
+
+/* PFNs are real physical page numbers.  However, mem_map only begins to record
+ * per-page information starting at pfn_base.  This is to handle systems where
+ * the first physical page in the machine is at some huge physical address,
+ * such as 4GB.   This is common on a partitioned E10000, for example.
+ */
+static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
+{
+       unsigned long paddr = pfn << PAGE_SHIFT;
+       unsigned long sz_bits;
+
+       sz_bits = 0UL;
+       if (_PAGE_SZBITS_4U != 0UL || _PAGE_SZBITS_4V != 0UL) {
+               __asm__ __volatile__(
+               "\n661: sethi           %%uhi(%1), %0\n"
+               "       sllx            %0, 32, %0\n"
+               "       .section        .sun4v_2insn_patch, \"ax\"\n"
+               "       .word           661b\n"
+               "       mov             %2, %0\n"
+               "       nop\n"
+               "       .previous\n"
+               : "=r" (sz_bits)
+               : "i" (_PAGE_SZBITS_4U), "i" (_PAGE_SZBITS_4V));
+       }
+       return __pte(paddr | sz_bits | pgprot_val(prot));
+}
+#define mk_pte(page, pgprot)   pfn_pte(page_to_pfn(page), (pgprot))
+
+/* This one can be done with two shifts.  */
+static inline unsigned long pte_pfn(pte_t pte)
+{
+       unsigned long ret;
+
+       __asm__ __volatile__(
+       "\n661: sllx            %1, %2, %0\n"
+       "       srlx            %0, %3, %0\n"
+       "       .section        .sun4v_2insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       sllx            %1, %4, %0\n"
+       "       srlx            %0, %5, %0\n"
+       "       .previous\n"
+       : "=r" (ret)
+       : "r" (pte_val(pte)),
+         "i" (21), "i" (21 + PAGE_SHIFT),
+         "i" (8), "i" (8 + PAGE_SHIFT));
+
+       return ret;
+}
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
+{
+       unsigned long mask, tmp;
+
+       /* SUN4U: 0x600307ffffffecb8 (negated == 0x9ffcf80000001347)
+        * SUN4V: 0x30ffffffffffee17 (negated == 0xcf000000000011e8)
+        *
+        * Even if we use negation tricks the result is still a 6
+        * instruction sequence, so don't try to play fancy and just
+        * do the most straightforward implementation.
+        *
+        * Note: We encode this into 3 sun4v 2-insn patch sequences.
+        */
+
+       __asm__ __volatile__(
+       "\n661: sethi           %%uhi(%2), %1\n"
+       "       sethi           %%hi(%2), %0\n"
+       "\n662: or              %1, %%ulo(%2), %1\n"
+       "       or              %0, %%lo(%2), %0\n"
+       "\n663: sllx            %1, 32, %1\n"
+       "       or              %0, %1, %0\n"
+       "       .section        .sun4v_2insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       sethi           %%uhi(%3), %1\n"
+       "       sethi           %%hi(%3), %0\n"
+       "       .word           662b\n"
+       "       or              %1, %%ulo(%3), %1\n"
+       "       or              %0, %%lo(%3), %0\n"
+       "       .word           663b\n"
+       "       sllx            %1, 32, %1\n"
+       "       or              %0, %1, %0\n"
+       "       .previous\n"
+       : "=r" (mask), "=r" (tmp)
+       : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
+              _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U |
+              _PAGE_SZBITS_4U),
+         "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
+              _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V |
+              _PAGE_SZBITS_4V));
+
+       return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
+}
+
+static inline pte_t pgoff_to_pte(unsigned long off)
+{
+       off <<= PAGE_SHIFT;
+
+       __asm__ __volatile__(
+       "\n661: or              %0, %2, %0\n"
+       "       .section        .sun4v_1insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       or              %0, %3, %0\n"
+       "       .previous\n"
+       : "=r" (off)
+       : "0" (off), "i" (_PAGE_FILE_4U), "i" (_PAGE_FILE_4V));
+
+       return __pte(off);
+}
+
+static inline pgprot_t pgprot_noncached(pgprot_t prot)
+{
+       unsigned long val = pgprot_val(prot);
+
+       __asm__ __volatile__(
+       "\n661: andn            %0, %2, %0\n"
+       "       or              %0, %3, %0\n"
+       "       .section        .sun4v_2insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       andn            %0, %4, %0\n"
+       "       or              %0, %5, %0\n"
+       "       .previous\n"
+       : "=r" (val)
+       : "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U),
+                    "i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V));
+
+       return __pgprot(val);
+}
+/* Various pieces of code check for platform support by ifdef testing
+ * on "pgprot_noncached".  That's broken and should be fixed, but for
+ * now...
+ */
+#define pgprot_noncached pgprot_noncached
+
+#ifdef CONFIG_HUGETLB_PAGE
+static inline pte_t pte_mkhuge(pte_t pte)
+{
+       unsigned long mask;
+
+       __asm__ __volatile__(
+       "\n661: sethi           %%uhi(%1), %0\n"
+       "       sllx            %0, 32, %0\n"
+       "       .section        .sun4v_2insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       mov             %2, %0\n"
+       "       nop\n"
+       "       .previous\n"
+       : "=r" (mask)
+       : "i" (_PAGE_SZHUGE_4U), "i" (_PAGE_SZHUGE_4V));
+
+       return __pte(pte_val(pte) | mask);
+}
+#endif
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+       unsigned long val = pte_val(pte), tmp;
+
+       __asm__ __volatile__(
+       "\n661: or              %0, %3, %0\n"
+       "       nop\n"
+       "\n662: nop\n"
+       "       nop\n"
+       "       .section        .sun4v_2insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       sethi           %%uhi(%4), %1\n"
+       "       sllx            %1, 32, %1\n"
+       "       .word           662b\n"
+       "       or              %1, %%lo(%4), %1\n"
+       "       or              %0, %1, %0\n"
+       "       .previous\n"
+       : "=r" (val), "=r" (tmp)
+       : "0" (val), "i" (_PAGE_MODIFIED_4U | _PAGE_W_4U),
+         "i" (_PAGE_MODIFIED_4V | _PAGE_W_4V));
+
+       return __pte(val);
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+       unsigned long val = pte_val(pte), tmp;
+
+       __asm__ __volatile__(
+       "\n661: andn            %0, %3, %0\n"
+       "       nop\n"
+       "\n662: nop\n"
+       "       nop\n"
+       "       .section        .sun4v_2insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       sethi           %%uhi(%4), %1\n"
+       "       sllx            %1, 32, %1\n"
+       "       .word           662b\n"
+       "       or              %1, %%lo(%4), %1\n"
+       "       andn            %0, %1, %0\n"
+       "       .previous\n"
+       : "=r" (val), "=r" (tmp)
+       : "0" (val), "i" (_PAGE_MODIFIED_4U | _PAGE_W_4U),
+         "i" (_PAGE_MODIFIED_4V | _PAGE_W_4V));
+
+       return __pte(val);
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+       unsigned long val = pte_val(pte), mask;
+
+       __asm__ __volatile__(
+       "\n661: mov             %1, %0\n"
+       "       nop\n"
+       "       .section        .sun4v_2insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       sethi           %%uhi(%2), %0\n"
+       "       sllx            %0, 32, %0\n"
+       "       .previous\n"
+       : "=r" (mask)
+       : "i" (_PAGE_WRITE_4U), "i" (_PAGE_WRITE_4V));
+
+       return __pte(val | mask);
+}
+
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+       unsigned long val = pte_val(pte), tmp;
+
+       __asm__ __volatile__(
+       "\n661: andn            %0, %3, %0\n"
+       "       nop\n"
+       "\n662: nop\n"
+       "       nop\n"
+       "       .section        .sun4v_2insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       sethi           %%uhi(%4), %1\n"
+       "       sllx            %1, 32, %1\n"
+       "       .word           662b\n"
+       "       or              %1, %%lo(%4), %1\n"
+       "       andn            %0, %1, %0\n"
+       "       .previous\n"
+       : "=r" (val), "=r" (tmp)
+       : "0" (val), "i" (_PAGE_WRITE_4U | _PAGE_W_4U),
+         "i" (_PAGE_WRITE_4V | _PAGE_W_4V));
+
+       return __pte(val);
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+       unsigned long mask;
+
+       __asm__ __volatile__(
+       "\n661: mov             %1, %0\n"
+       "       nop\n"
+       "       .section        .sun4v_2insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       sethi           %%uhi(%2), %0\n"
+       "       sllx            %0, 32, %0\n"
+       "       .previous\n"
+       : "=r" (mask)
+       : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V));
+
+       mask |= _PAGE_R;
+
+       return __pte(pte_val(pte) & ~mask);
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+       unsigned long mask;
+
+       __asm__ __volatile__(
+       "\n661: mov             %1, %0\n"
+       "       nop\n"
+       "       .section        .sun4v_2insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       sethi           %%uhi(%2), %0\n"
+       "       sllx            %0, 32, %0\n"
+       "       .previous\n"
+       : "=r" (mask)
+       : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V));
+
+       mask |= _PAGE_R;
+
+       return __pte(pte_val(pte) | mask);
+}
+
+static inline pte_t pte_mkspecial(pte_t pte)
+{
+       return pte;
+}
+
+static inline unsigned long pte_young(pte_t pte)
+{
+       unsigned long mask;
+
+       __asm__ __volatile__(
+       "\n661: mov             %1, %0\n"
+       "       nop\n"
+       "       .section        .sun4v_2insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       sethi           %%uhi(%2), %0\n"
+       "       sllx            %0, 32, %0\n"
+       "       .previous\n"
+       : "=r" (mask)
+       : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V));
+
+       return (pte_val(pte) & mask);
+}
+
+static inline unsigned long pte_dirty(pte_t pte)
+{
+       unsigned long mask;
+
+       __asm__ __volatile__(
+       "\n661: mov             %1, %0\n"
+       "       nop\n"
+       "       .section        .sun4v_2insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       sethi           %%uhi(%2), %0\n"
+       "       sllx            %0, 32, %0\n"
+       "       .previous\n"
+       : "=r" (mask)
+       : "i" (_PAGE_MODIFIED_4U), "i" (_PAGE_MODIFIED_4V));
+
+       return (pte_val(pte) & mask);
+}
+
+static inline unsigned long pte_write(pte_t pte)
+{
+       unsigned long mask;
+
+       __asm__ __volatile__(
+       "\n661: mov             %1, %0\n"
+       "       nop\n"
+       "       .section        .sun4v_2insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       sethi           %%uhi(%2), %0\n"
+       "       sllx            %0, 32, %0\n"
+       "       .previous\n"
+       : "=r" (mask)
+       : "i" (_PAGE_WRITE_4U), "i" (_PAGE_WRITE_4V));
+
+       return (pte_val(pte) & mask);
+}
+
+static inline unsigned long pte_exec(pte_t pte)
+{
+       unsigned long mask;
+
+       __asm__ __volatile__(
+       "\n661: sethi           %%hi(%1), %0\n"
+       "       .section        .sun4v_1insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       mov             %2, %0\n"
+       "       .previous\n"
+       : "=r" (mask)
+       : "i" (_PAGE_EXEC_4U), "i" (_PAGE_EXEC_4V));
+
+       return (pte_val(pte) & mask);
+}
+
+static inline unsigned long pte_file(pte_t pte)
+{
+       unsigned long val = pte_val(pte);
+
+       __asm__ __volatile__(
+       "\n661: and             %0, %2, %0\n"
+       "       .section        .sun4v_1insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       and             %0, %3, %0\n"
+       "       .previous\n"
+       : "=r" (val)
+       : "0" (val), "i" (_PAGE_FILE_4U), "i" (_PAGE_FILE_4V));
+
+       return val;
+}
+
+static inline unsigned long pte_present(pte_t pte)
+{
+       unsigned long val = pte_val(pte);
+
+       __asm__ __volatile__(
+       "\n661: and             %0, %2, %0\n"
+       "       .section        .sun4v_1insn_patch, \"ax\"\n"
+       "       .word           661b\n"
+       "       and             %0, %3, %0\n"
+       "       .previous\n"
+       : "=r" (val)
+       : "0" (val), "i" (_PAGE_PRESENT_4U), "i" (_PAGE_PRESENT_4V));
+
+       return val;
+}
+
+static inline int pte_special(pte_t pte)
+{
+       return 0;
+}
+
+#define pmd_set(pmdp, ptep)    \
+       (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL))
+#define pud_set(pudp, pmdp)    \
+       (pud_val(*(pudp)) = (__pa((unsigned long) (pmdp)) >> 11UL))
+#define __pmd_page(pmd)                \
+       ((unsigned long) __va((((unsigned long)pmd_val(pmd))<<11UL)))
+#define pmd_page(pmd)                  virt_to_page((void *)__pmd_page(pmd))
+#define pud_page_vaddr(pud)            \
+       ((unsigned long) __va((((unsigned long)pud_val(pud))<<11UL)))
+#define pud_page(pud)                  virt_to_page((void *)pud_page_vaddr(pud))
+#define pmd_none(pmd)                  (!pmd_val(pmd))
+#define pmd_bad(pmd)                   (0)
+#define pmd_present(pmd)               (pmd_val(pmd) != 0U)
+#define pmd_clear(pmdp)                        (pmd_val(*(pmdp)) = 0U)
+#define pud_none(pud)                  (!pud_val(pud))
+#define pud_bad(pud)                   (0)
+#define pud_present(pud)               (pud_val(pud) != 0U)
+#define pud_clear(pudp)                        (pud_val(*(pudp)) = 0U)
+
+/* Same in both SUN4V and SUN4U.  */
+#define pte_none(pte)                  (!pte_val(pte))
+
+/* to find an entry in a page-table-directory. */
+#define pgd_index(address)     (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
+#define pgd_offset(mm, address)        ((mm)->pgd + pgd_index(address))
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/* Find an entry in the second-level page table.. */
+#define pmd_offset(pudp, address)      \
+       ((pmd_t *) pud_page_vaddr(*(pudp)) + \
+        (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)))
+
+/* Find an entry in the third-level page table.. */
+#define pte_index(dir, address)        \
+       ((pte_t *) __pmd_page(*(dir)) + \
+        ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
+#define pte_offset_kernel              pte_index
+#define pte_offset_map                 pte_index
+#define pte_offset_map_nested          pte_index
+#define pte_unmap(pte)                 do { } while (0)
+#define pte_unmap_nested(pte)          do { } while (0)
+
+/* Actual page table PTE updates.  */
+extern void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig);
+
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
+{
+       pte_t orig = *ptep;
+
+       *ptep = pte;
+
+       /* It is more efficient to let flush_tlb_kernel_range()
+        * handle init_mm tlb flushes.
+        *
+        * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
+        *             and SUN4V pte layout, so this inline test is fine.
+        */
+       if (likely(mm != &init_mm) && (pte_val(orig) & _PAGE_VALID))
+               tlb_batch_add(mm, addr, ptep, orig);
+}
+
+#define pte_clear(mm,addr,ptep)                \
+       set_pte_at((mm), (addr), (ptep), __pte(0UL))
+
+#ifdef DCACHE_ALIASING_POSSIBLE
+#define __HAVE_ARCH_MOVE_PTE
+#define move_pte(pte, prot, old_addr, new_addr)                                \
+({                                                                     \
+       pte_t newpte = (pte);                                           \
+       if (tlb_type != hypervisor && pte_present(pte)) {               \
+               unsigned long this_pfn = pte_pfn(pte);                  \
+                                                                       \
+               if (pfn_valid(this_pfn) &&                              \
+                   (((old_addr) ^ (new_addr)) & (1 << 13)))            \
+                       flush_dcache_page_all(current->mm,              \
+                                             pfn_to_page(this_pfn));   \
+       }                                                               \
+       newpte;                                                         \
+})
+#endif
+
+extern pgd_t swapper_pg_dir[2048];
+extern pmd_t swapper_low_pmd_dir[2048];
+
+extern void paging_init(void);
+extern unsigned long find_ecache_flush_span(unsigned long size);
+
+/* These do nothing with the way I have things setup. */
+#define mmu_lockarea(vaddr, len)               (vaddr)
+#define mmu_unlockarea(vaddr, len)             do { } while(0)
+
+struct vm_area_struct;
+extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
+
+/* Encode and de-code a swap entry */
+#define __swp_type(entry)      (((entry).val >> PAGE_SHIFT) & 0xffUL)
+#define __swp_offset(entry)    ((entry).val >> (PAGE_SHIFT + 8UL))
+#define __swp_entry(type, offset)      \
+       ( (swp_entry_t) \
+         { \
+               (((long)(type) << PAGE_SHIFT) | \
+                 ((long)(offset) << (PAGE_SHIFT + 8UL))) \
+         } )
+#define __pte_to_swp_entry(pte)                ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)          ((pte_t) { (x).val })
+
+/* File offset in PTE support. */
+extern unsigned long pte_file(pte_t);
+#define pte_to_pgoff(pte)      (pte_val(pte) >> PAGE_SHIFT)
+extern pte_t pgoff_to_pte(unsigned long);
+#define PTE_FILE_MAX_BITS      (64UL - PAGE_SHIFT - 1UL)
+
+extern unsigned long *sparc64_valid_addr_bitmap;
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define kern_addr_valid(addr)  \
+       (test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap))
+
+extern int page_in_phys_avail(unsigned long paddr);
+
+extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
+                              unsigned long pfn,
+                              unsigned long size, pgprot_t prot);
+
+/*
+ * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
+ * its high 4 bits.  These macros/functions put it there or get it from there.
+ */
+#define MK_IOSPACE_PFN(space, pfn)     (pfn | (space << (BITS_PER_LONG - 4)))
+#define GET_IOSPACE(pfn)               (pfn >> (BITS_PER_LONG - 4))
+#define GET_PFN(pfn)                   (pfn & 0x0fffffffffffffffUL)
+
+#include <asm-generic/pgtable.h>
+
+/* We provide our own get_unmapped_area to cope with VA holes and
+ * SHM area cache aliasing for userland.
+ */
+#define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+
+/* We provide a special get_unmapped_area for framebuffer mmaps to try and use
+ * the largest alignment possible such that larget PTEs can be used.
+ */
+extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long,
+                                         unsigned long, unsigned long,
+                                         unsigned long);
+#define HAVE_ARCH_FB_UNMAPPED_AREA
+
+extern void pgtable_cache_init(void);
+extern void sun4v_register_fault_status(void);
+extern void sun4v_ktsb_register(void);
+extern void __init cheetah_ecache_flush_init(void);
+extern void sun4v_patch_tlb_handlers(void);
+
+extern unsigned long cmdline_memory_size;
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_SPARC64_PGTABLE_H) */
diff --git a/include/asm-sparc/pil.h b/include/asm-sparc/pil.h
new file mode 100644 (file)
index 0000000..71819bb
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _SPARC64_PIL_H
+#define _SPARC64_PIL_H
+
+/* To avoid some locking problems, we hard allocate certain PILs
+ * for SMP cross call messages that must do a etrap/rtrap.
+ *
+ * A local_irq_disable() does not block the cross call delivery, so
+ * when SMP locking is an issue we reschedule the event into a PIL
+ * interrupt which is blocked by local_irq_disable().
+ *
+ * In fact any XCALL which has to etrap/rtrap has a problem because
+ * it is difficult to prevent rtrap from running BH's, and that would
+ * need to be done if the XCALL arrived while %pil==15.
+ */
+#define PIL_SMP_CALL_FUNC      1
+#define PIL_SMP_RECEIVE_SIGNAL 2
+#define PIL_SMP_CAPTURE                3
+#define PIL_SMP_CTX_NEW_VERSION        4
+#define PIL_DEVICE_IRQ         5
+#define PIL_SMP_CALL_FUNC_SNGL 6
+
+#endif /* !(_SPARC64_PIL_H) */
index dcc07eb5e181b8394143ab9396a4a3576967753a..58c820d75e8335db5ab20f7bf375d6f2706fe802 100644 (file)
@@ -1,118 +1,8 @@
-#ifndef __ARCH_SPARC_POSIX_TYPES_H
-#define __ARCH_SPARC_POSIX_TYPES_H
-
-/*
- * This file is generally used by user-level software, so you need to
- * be a little careful about namespace pollution etc.  Also, we cannot
- * assume GCC is being used.
- */
-
-typedef unsigned int           __kernel_size_t;
-typedef int                    __kernel_ssize_t;
-typedef long int               __kernel_ptrdiff_t;
-typedef long                   __kernel_time_t;
-typedef long                  __kernel_suseconds_t;
-typedef long                   __kernel_clock_t;
-typedef int                    __kernel_pid_t;
-typedef unsigned short         __kernel_ipc_pid_t;
-typedef unsigned short         __kernel_uid_t;
-typedef unsigned short         __kernel_gid_t;
-typedef unsigned long          __kernel_ino_t;
-typedef unsigned short         __kernel_mode_t;
-typedef unsigned short         __kernel_umode_t;
-typedef short                  __kernel_nlink_t;
-typedef long                   __kernel_daddr_t;
-typedef long                   __kernel_off_t;
-typedef char *                 __kernel_caddr_t;
-typedef unsigned short        __kernel_uid16_t;
-typedef unsigned short        __kernel_gid16_t;
-typedef unsigned int          __kernel_uid32_t;
-typedef unsigned int          __kernel_gid32_t;
-typedef unsigned short        __kernel_old_uid_t;
-typedef unsigned short        __kernel_old_gid_t;
-typedef unsigned short        __kernel_old_dev_t;
-typedef int                    __kernel_clockid_t;
-typedef int                    __kernel_timer_t;
-
-#ifdef __GNUC__
-typedef long long      __kernel_loff_t;
+#ifndef ___ASM_SPARC_POSIX_TYPES_H
+#define ___ASM_SPARC_POSIX_TYPES_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/posix_types_64.h>
+#else
+#include <asm-sparc/posix_types_32.h>
+#endif
 #endif
-
-typedef struct {
-       int     val[2];
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__)
-
-#undef __FD_SET
-static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-       unsigned long _tmp = fd / __NFDBITS;
-       unsigned long _rem = fd % __NFDBITS;
-       fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-       unsigned long _tmp = fd / __NFDBITS;
-       unsigned long _rem = fd % __NFDBITS;
-       fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static inline int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
-{ 
-       unsigned long _tmp = fd / __NFDBITS;
-       unsigned long _rem = fd % __NFDBITS;
-       return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant cases (8 or 32 longs,
- * for 256 and 1024-bit fd_sets respectively)
- */
-#undef __FD_ZERO
-static inline void __FD_ZERO(__kernel_fd_set *p)
-{
-       unsigned long *tmp = p->fds_bits;
-       int i;
-
-       if (__builtin_constant_p(__FDSET_LONGS)) {
-               switch (__FDSET_LONGS) {
-                       case 32:
-                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-                         tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
-                         tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
-                         tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0;
-                         tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0;
-                         tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0;
-                         tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0;
-                         return;
-                       case 16:
-                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-                         tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
-                         tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
-                         return;
-                       case 8:
-                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-                         return;
-                       case 4:
-                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-                         return;
-               }
-       }
-       i = __FDSET_LONGS;
-       while (i) {
-               i--;
-               *tmp = 0;
-               tmp++;
-       }
-}
-
-#endif /* defined(__KERNEL__) */
-
-#endif /* !(__ARCH_SPARC_POSIX_TYPES_H) */
diff --git a/include/asm-sparc/posix_types_32.h b/include/asm-sparc/posix_types_32.h
new file mode 100644 (file)
index 0000000..6bb6eb1
--- /dev/null
@@ -0,0 +1,118 @@
+#ifndef __ARCH_SPARC_POSIX_TYPES_H
+#define __ARCH_SPARC_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned int           __kernel_size_t;
+typedef int                    __kernel_ssize_t;
+typedef long int               __kernel_ptrdiff_t;
+typedef long                   __kernel_time_t;
+typedef long                  __kernel_suseconds_t;
+typedef long                   __kernel_clock_t;
+typedef int                    __kernel_pid_t;
+typedef unsigned short         __kernel_ipc_pid_t;
+typedef unsigned short         __kernel_uid_t;
+typedef unsigned short         __kernel_gid_t;
+typedef unsigned long          __kernel_ino_t;
+typedef unsigned short         __kernel_mode_t;
+typedef unsigned short         __kernel_umode_t;
+typedef short                  __kernel_nlink_t;
+typedef long                   __kernel_daddr_t;
+typedef long                   __kernel_off_t;
+typedef char *                 __kernel_caddr_t;
+typedef unsigned short        __kernel_uid16_t;
+typedef unsigned short        __kernel_gid16_t;
+typedef unsigned int          __kernel_uid32_t;
+typedef unsigned int          __kernel_gid32_t;
+typedef unsigned short        __kernel_old_uid_t;
+typedef unsigned short        __kernel_old_gid_t;
+typedef unsigned short        __kernel_old_dev_t;
+typedef int                    __kernel_clockid_t;
+typedef int                    __kernel_timer_t;
+
+#ifdef __GNUC__
+typedef long long      __kernel_loff_t;
+#endif
+
+typedef struct {
+       int     val[2];
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__)
+
+#undef __FD_SET
+static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+}
+
+#undef __FD_CLR
+static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+}
+
+#undef __FD_ISSET
+static inline int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
+{
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant cases (8 or 32 longs,
+ * for 256 and 1024-bit fd_sets respectively)
+ */
+#undef __FD_ZERO
+static inline void __FD_ZERO(__kernel_fd_set *p)
+{
+       unsigned long *tmp = p->fds_bits;
+       int i;
+
+       if (__builtin_constant_p(__FDSET_LONGS)) {
+               switch (__FDSET_LONGS) {
+                       case 32:
+                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+                         tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
+                         tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
+                         tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0;
+                         tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0;
+                         tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0;
+                         tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0;
+                         return;
+                       case 16:
+                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+                         tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
+                         tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
+                         return;
+                       case 8:
+                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+                         return;
+                       case 4:
+                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+                         return;
+               }
+       }
+       i = __FDSET_LONGS;
+       while (i) {
+               i--;
+               *tmp = 0;
+               tmp++;
+       }
+}
+
+#endif /* defined(__KERNEL__) */
+
+#endif /* !(__ARCH_SPARC_POSIX_TYPES_H) */
diff --git a/include/asm-sparc/posix_types_64.h b/include/asm-sparc/posix_types_64.h
new file mode 100644 (file)
index 0000000..ba8f932
--- /dev/null
@@ -0,0 +1,122 @@
+#ifndef __ARCH_SPARC64_POSIX_TYPES_H
+#define __ARCH_SPARC64_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long          __kernel_size_t;
+typedef long                   __kernel_ssize_t;
+typedef long                   __kernel_ptrdiff_t;
+typedef long                   __kernel_time_t;
+typedef long                   __kernel_clock_t;
+typedef int                    __kernel_pid_t;
+typedef int                    __kernel_ipc_pid_t;
+typedef unsigned int           __kernel_uid_t;
+typedef unsigned int           __kernel_gid_t;
+typedef unsigned long          __kernel_ino_t;
+typedef unsigned int           __kernel_mode_t;
+typedef unsigned short         __kernel_umode_t;
+typedef unsigned int           __kernel_nlink_t;
+typedef int                    __kernel_daddr_t;
+typedef long                   __kernel_off_t;
+typedef char *                 __kernel_caddr_t;
+typedef unsigned short        __kernel_uid16_t;
+typedef unsigned short        __kernel_gid16_t;
+typedef int                    __kernel_clockid_t;
+typedef int                    __kernel_timer_t;
+
+typedef unsigned short                __kernel_old_uid_t;
+typedef unsigned short         __kernel_old_gid_t;
+typedef __kernel_uid_t        __kernel_uid32_t;
+typedef __kernel_gid_t        __kernel_gid32_t;
+
+typedef unsigned int          __kernel_old_dev_t;
+
+/* Note this piece of asymmetry from the v9 ABI.  */
+typedef int                   __kernel_suseconds_t;
+
+#ifdef __GNUC__
+typedef long long              __kernel_loff_t;
+#endif
+
+typedef struct {
+       int     val[2];
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__)
+
+#undef __FD_SET
+static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+}
+
+#undef __FD_CLR
+static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+}
+
+#undef __FD_ISSET
+static inline int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
+{
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant cases (8 or 32 longs,
+ * for 256 and 1024-bit fd_sets respectively)
+ */
+#undef __FD_ZERO
+static inline void __FD_ZERO(__kernel_fd_set *p)
+{
+       unsigned long *tmp = p->fds_bits;
+       int i;
+
+       if (__builtin_constant_p(__FDSET_LONGS)) {
+               switch (__FDSET_LONGS) {
+                       case 32:
+                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+                         tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
+                         tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
+                         tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0;
+                         tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0;
+                         tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0;
+                         tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0;
+                         return;
+                       case 16:
+                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+                         tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
+                         tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
+                         return;
+                       case 8:
+                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+                         return;
+                       case 4:
+                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+                         return;
+               }
+       }
+       i = __FDSET_LONGS;
+       while (i) {
+               i--;
+               *tmp = 0;
+               tmp++;
+       }
+}
+
+#endif /* defined(__KERNEL__) */
+
+#endif /* !(__ARCH_SPARC64_POSIX_TYPES_H) */
index 8898efbbbe07c8e57cb66c791a82410ed417bac6..11a66bb02eaa01b1dc520e05dfef5adfd2193823 100644 (file)
@@ -1,128 +1,8 @@
-/* include/asm-sparc/processor.h
- *
- * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef __ASM_SPARC_PROCESSOR_H
-#define __ASM_SPARC_PROCESSOR_H
-
-/*
- * Sparc32 implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ void *pc; __asm__("sethi %%hi(1f), %0; or %0, %%lo(1f), %0;\n1:" : "=r" (pc)); pc; })
-
-#include <asm/psr.h>
-#include <asm/ptrace.h>
-#include <asm/head.h>
-#include <asm/signal.h>
-#include <asm/btfixup.h>
-#include <asm/page.h>
-
-/*
- * The sparc has no problems with write protection
- */
-#define wp_works_ok 1
-#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
-
-/* Whee, this is STACK_TOP + PAGE_SIZE and the lowest kernel address too... 
- * That one page is used to protect kernel from intruders, so that
- * we can make our access_ok test faster
- */
-#define TASK_SIZE      PAGE_OFFSET
-#ifdef __KERNEL__
-#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
-#define STACK_TOP_MAX  STACK_TOP
-#endif /* __KERNEL__ */
-
-struct task_struct;
-
-#ifdef __KERNEL__
-struct fpq {
-       unsigned long *insn_addr;
-       unsigned long insn;
-};
+#ifndef ___ASM_SPARC_PROCESSOR_H
+#define ___ASM_SPARC_PROCESSOR_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/processor_64.h>
+#else
+#include <asm-sparc/processor_32.h>
 #endif
-
-typedef struct {
-       int seg;
-} mm_segment_t;
-
-/* The Sparc processor specific thread struct. */
-struct thread_struct {
-       struct pt_regs *kregs;
-       unsigned int _pad1;
-
-       /* Special child fork kpsr/kwim values. */
-       unsigned long fork_kpsr __attribute__ ((aligned (8)));
-       unsigned long fork_kwim;
-
-       /* Floating point regs */
-       unsigned long   float_regs[32] __attribute__ ((aligned (8)));
-       unsigned long   fsr;
-       unsigned long   fpqdepth;
-       struct fpq      fpqueue[16];
-       unsigned long flags;
-       mm_segment_t current_ds;
-};
-
-#define SPARC_FLAG_KTHREAD      0x1    /* task is a kernel thread */
-#define SPARC_FLAG_UNALIGNED    0x2    /* is allowed to do unaligned accesses */
-
-#define INIT_THREAD  { \
-       .flags = SPARC_FLAG_KTHREAD, \
-       .current_ds = KERNEL_DS, \
-}
-
-/* Return saved PC of a blocked thread. */
-extern unsigned long thread_saved_pc(struct task_struct *t);
-
-/* Do necessary setup to start up a newly executed thread. */
-static inline void start_thread(struct pt_regs * regs, unsigned long pc,
-                                   unsigned long sp)
-{
-       register unsigned long zero asm("g1");
-
-       regs->psr = (regs->psr & (PSR_CWP)) | PSR_S;
-       regs->pc = ((pc & (~3)) - 4);
-       regs->npc = regs->pc + 4;
-       regs->y = 0;
-       zero = 0;
-       __asm__ __volatile__("std\t%%g0, [%0 + %3 + 0x00]\n\t"
-                            "std\t%%g0, [%0 + %3 + 0x08]\n\t"
-                            "std\t%%g0, [%0 + %3 + 0x10]\n\t"
-                            "std\t%%g0, [%0 + %3 + 0x18]\n\t"
-                            "std\t%%g0, [%0 + %3 + 0x20]\n\t"
-                            "std\t%%g0, [%0 + %3 + 0x28]\n\t"
-                            "std\t%%g0, [%0 + %3 + 0x30]\n\t"
-                            "st\t%1, [%0 + %3 + 0x38]\n\t"
-                            "st\t%%g0, [%0 + %3 + 0x3c]"
-                            : /* no outputs */
-                            : "r" (regs),
-                              "r" (sp - sizeof(struct reg_window)),
-                              "r" (zero),
-                              "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))
-                            : "memory");
-}
-
-/* Free all resources held by a thread. */
-#define release_thread(tsk)            do { } while(0)
-extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk)   do { } while (0)
-
-extern unsigned long get_wchan(struct task_struct *);
-
-#define KSTK_EIP(tsk)  ((tsk)->thread.kregs->pc)
-#define KSTK_ESP(tsk)  ((tsk)->thread.kregs->u_regs[UREG_FP])
-
-#ifdef __KERNEL__
-
-extern struct task_struct *last_task_used_math;
-
-#define cpu_relax()    barrier()
-
 #endif
-
-#endif /* __ASM_SPARC_PROCESSOR_H */
diff --git a/include/asm-sparc/processor_32.h b/include/asm-sparc/processor_32.h
new file mode 100644 (file)
index 0000000..562c0d6
--- /dev/null
@@ -0,0 +1,128 @@
+/* include/asm-sparc/processor.h
+ *
+ * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __ASM_SPARC_PROCESSOR_H
+#define __ASM_SPARC_PROCESSOR_H
+
+/*
+ * Sparc32 implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ void *pc; __asm__("sethi %%hi(1f), %0; or %0, %%lo(1f), %0;\n1:" : "=r" (pc)); pc; })
+
+#include <asm/psr.h>
+#include <asm/ptrace.h>
+#include <asm/head.h>
+#include <asm/signal.h>
+#include <asm/btfixup.h>
+#include <asm/page.h>
+
+/*
+ * The sparc has no problems with write protection
+ */
+#define wp_works_ok 1
+#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
+
+/* Whee, this is STACK_TOP + PAGE_SIZE and the lowest kernel address too...
+ * That one page is used to protect kernel from intruders, so that
+ * we can make our access_ok test faster
+ */
+#define TASK_SIZE      PAGE_OFFSET
+#ifdef __KERNEL__
+#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
+#define STACK_TOP_MAX  STACK_TOP
+#endif /* __KERNEL__ */
+
+struct task_struct;
+
+#ifdef __KERNEL__
+struct fpq {
+       unsigned long *insn_addr;
+       unsigned long insn;
+};
+#endif
+
+typedef struct {
+       int seg;
+} mm_segment_t;
+
+/* The Sparc processor specific thread struct. */
+struct thread_struct {
+       struct pt_regs *kregs;
+       unsigned int _pad1;
+
+       /* Special child fork kpsr/kwim values. */
+       unsigned long fork_kpsr __attribute__ ((aligned (8)));
+       unsigned long fork_kwim;
+
+       /* Floating point regs */
+       unsigned long   float_regs[32] __attribute__ ((aligned (8)));
+       unsigned long   fsr;
+       unsigned long   fpqdepth;
+       struct fpq      fpqueue[16];
+       unsigned long flags;
+       mm_segment_t current_ds;
+};
+
+#define SPARC_FLAG_KTHREAD      0x1    /* task is a kernel thread */
+#define SPARC_FLAG_UNALIGNED    0x2    /* is allowed to do unaligned accesses */
+
+#define INIT_THREAD  { \
+       .flags = SPARC_FLAG_KTHREAD, \
+       .current_ds = KERNEL_DS, \
+}
+
+/* Return saved PC of a blocked thread. */
+extern unsigned long thread_saved_pc(struct task_struct *t);
+
+/* Do necessary setup to start up a newly executed thread. */
+static inline void start_thread(struct pt_regs * regs, unsigned long pc,
+                                   unsigned long sp)
+{
+       register unsigned long zero asm("g1");
+
+       regs->psr = (regs->psr & (PSR_CWP)) | PSR_S;
+       regs->pc = ((pc & (~3)) - 4);
+       regs->npc = regs->pc + 4;
+       regs->y = 0;
+       zero = 0;
+       __asm__ __volatile__("std\t%%g0, [%0 + %3 + 0x00]\n\t"
+                            "std\t%%g0, [%0 + %3 + 0x08]\n\t"
+                            "std\t%%g0, [%0 + %3 + 0x10]\n\t"
+                            "std\t%%g0, [%0 + %3 + 0x18]\n\t"
+                            "std\t%%g0, [%0 + %3 + 0x20]\n\t"
+                            "std\t%%g0, [%0 + %3 + 0x28]\n\t"
+                            "std\t%%g0, [%0 + %3 + 0x30]\n\t"
+                            "st\t%1, [%0 + %3 + 0x38]\n\t"
+                            "st\t%%g0, [%0 + %3 + 0x3c]"
+                            : /* no outputs */
+                            : "r" (regs),
+                              "r" (sp - sizeof(struct reg_window)),
+                              "r" (zero),
+                              "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))
+                            : "memory");
+}
+
+/* Free all resources held by a thread. */
+#define release_thread(tsk)            do { } while(0)
+extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk)   do { } while (0)
+
+extern unsigned long get_wchan(struct task_struct *);
+
+#define KSTK_EIP(tsk)  ((tsk)->thread.kregs->pc)
+#define KSTK_ESP(tsk)  ((tsk)->thread.kregs->u_regs[UREG_FP])
+
+#ifdef __KERNEL__
+
+extern struct task_struct *last_task_used_math;
+
+#define cpu_relax()    barrier()
+
+#endif
+
+#endif /* __ASM_SPARC_PROCESSOR_H */
diff --git a/include/asm-sparc/processor_64.h b/include/asm-sparc/processor_64.h
new file mode 100644 (file)
index 0000000..70d4280
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * include/asm-sparc64/processor.h
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __ASM_SPARC64_PROCESSOR_H
+#define __ASM_SPARC64_PROCESSOR_H
+
+/*
+ * Sparc64 implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ void *pc; __asm__("rd %%pc, %0" : "=r" (pc)); pc; })
+
+#include <asm/asi.h>
+#include <asm/pstate.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+
+/* The sparc has no problems with write protection */
+#define wp_works_ok 1
+#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
+
+/*
+ * User lives in his very own context, and cannot reference us. Note
+ * that TASK_SIZE is a misnomer, it really gives maximum user virtual
+ * address that the kernel will allocate out.
+ *
+ * XXX No longer using virtual page tables, kill this upper limit...
+ */
+#define VA_BITS                44
+#ifndef __ASSEMBLY__
+#define VPTE_SIZE      (1UL << (VA_BITS - PAGE_SHIFT + 3))
+#else
+#define VPTE_SIZE      (1 << (VA_BITS - PAGE_SHIFT + 3))
+#endif
+
+#define TASK_SIZE      ((unsigned long)-VPTE_SIZE)
+#define TASK_SIZE_OF(tsk) \
+       (test_tsk_thread_flag(tsk,TIF_32BIT) ? \
+        (1UL << 32UL) : TASK_SIZE)
+#ifdef __KERNEL__
+
+#define STACK_TOP32    ((1UL << 32UL) - PAGE_SIZE)
+#define STACK_TOP64    (0x0000080000000000UL - (1UL << 32UL))
+
+#define STACK_TOP      (test_thread_flag(TIF_32BIT) ? \
+                        STACK_TOP32 : STACK_TOP64)
+
+#define STACK_TOP_MAX  STACK_TOP64
+
+#endif
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+       unsigned char seg;
+} mm_segment_t;
+
+/* The Sparc processor specific thread struct. */
+/* XXX This should die, everything can go into thread_info now. */
+struct thread_struct {
+#ifdef CONFIG_DEBUG_SPINLOCK
+       /* How many spinlocks held by this thread.
+        * Used with spin lock debugging to catch tasks
+        * sleeping illegally with locks held.
+        */
+       int smp_lock_count;
+       unsigned int smp_lock_pc;
+#else
+       int dummy; /* f'in gcc bug... */
+#endif
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+#ifndef CONFIG_DEBUG_SPINLOCK
+#define INIT_THREAD  {                 \
+       0,                              \
+}
+#else /* CONFIG_DEBUG_SPINLOCK */
+#define INIT_THREAD  {                                 \
+/* smp_lock_count, smp_lock_pc, */                     \
+   0,             0,                                   \
+}
+#endif /* !(CONFIG_DEBUG_SPINLOCK) */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+/* Return saved PC of a blocked thread. */
+struct task_struct;
+extern unsigned long thread_saved_pc(struct task_struct *);
+
+/* On Uniprocessor, even in RMO processes see TSO semantics */
+#ifdef CONFIG_SMP
+#define TSTATE_INITIAL_MM      TSTATE_TSO
+#else
+#define TSTATE_INITIAL_MM      TSTATE_RMO
+#endif
+
+/* Do necessary setup to start up a newly executed thread. */
+#define start_thread(regs, pc, sp) \
+do { \
+       unsigned long __asi = ASI_PNF; \
+       regs->tstate = (regs->tstate & (TSTATE_CWP)) | (TSTATE_INITIAL_MM|TSTATE_IE) | (__asi << 24UL); \
+       regs->tpc = ((pc & (~3)) - 4); \
+       regs->tnpc = regs->tpc + 4; \
+       regs->y = 0; \
+       set_thread_wstate(1 << 3); \
+       if (current_thread_info()->utraps) { \
+               if (*(current_thread_info()->utraps) < 2) \
+                       kfree(current_thread_info()->utraps); \
+               else \
+                       (*(current_thread_info()->utraps))--; \
+               current_thread_info()->utraps = NULL; \
+       } \
+       __asm__ __volatile__( \
+       "stx            %%g0, [%0 + %2 + 0x00]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x08]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x10]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x18]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x20]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x28]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x30]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x38]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x40]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x48]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x50]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x58]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x60]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x68]\n\t" \
+       "stx            %1,   [%0 + %2 + 0x70]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x78]\n\t" \
+       "wrpr           %%g0, (1 << 3), %%wstate\n\t" \
+       : \
+       : "r" (regs), "r" (sp - sizeof(struct reg_window) - STACK_BIAS), \
+         "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \
+} while (0)
+
+#define start_thread32(regs, pc, sp) \
+do { \
+       unsigned long __asi = ASI_PNF; \
+       pc &= 0x00000000ffffffffUL; \
+       sp &= 0x00000000ffffffffUL; \
+       regs->tstate = (regs->tstate & (TSTATE_CWP))|(TSTATE_INITIAL_MM|TSTATE_IE|TSTATE_AM) | (__asi << 24UL); \
+       regs->tpc = ((pc & (~3)) - 4); \
+       regs->tnpc = regs->tpc + 4; \
+       regs->y = 0; \
+       set_thread_wstate(2 << 3); \
+       if (current_thread_info()->utraps) { \
+               if (*(current_thread_info()->utraps) < 2) \
+                       kfree(current_thread_info()->utraps); \
+               else \
+                       (*(current_thread_info()->utraps))--; \
+               current_thread_info()->utraps = NULL; \
+       } \
+       __asm__ __volatile__( \
+       "stx            %%g0, [%0 + %2 + 0x00]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x08]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x10]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x18]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x20]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x28]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x30]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x38]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x40]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x48]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x50]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x58]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x60]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x68]\n\t" \
+       "stx            %1,   [%0 + %2 + 0x70]\n\t" \
+       "stx            %%g0, [%0 + %2 + 0x78]\n\t" \
+       "wrpr           %%g0, (2 << 3), %%wstate\n\t" \
+       : \
+       : "r" (regs), "r" (sp - sizeof(struct reg_window32)), \
+         "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \
+} while (0)
+
+/* Free all resources held by a thread. */
+#define release_thread(tsk)            do { } while (0)
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk)   do { } while (0)
+
+extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+extern unsigned long get_wchan(struct task_struct *task);
+
+#define task_pt_regs(tsk) (task_thread_info(tsk)->kregs)
+#define KSTK_EIP(tsk)  (task_pt_regs(tsk)->tpc)
+#define KSTK_ESP(tsk)  (task_pt_regs(tsk)->u_regs[UREG_FP])
+
+#define cpu_relax()    barrier()
+
+/* Prefetch support.  This is tuned for UltraSPARC-III and later.
+ * UltraSPARC-I will treat these as nops, and UltraSPARC-II has
+ * a shallower prefetch queue than later chips.
+ */
+#define ARCH_HAS_PREFETCH
+#define ARCH_HAS_PREFETCHW
+#define ARCH_HAS_SPINLOCK_PREFETCH
+
+static inline void prefetch(const void *x)
+{
+       /* We do not use the read prefetch mnemonic because that
+        * prefetches into the prefetch-cache which only is accessible
+        * by floating point operations in UltraSPARC-III and later.
+        * By contrast, "#one_write" prefetches into the L2 cache
+        * in shared state.
+        */
+       __asm__ __volatile__("prefetch [%0], #one_write"
+                            : /* no outputs */
+                            : "r" (x));
+}
+
+static inline void prefetchw(const void *x)
+{
+       /* The most optimal prefetch to use for writes is
+        * "#n_writes".  This brings the cacheline into the
+        * L2 cache in "owned" state.
+        */
+       __asm__ __volatile__("prefetch [%0], #n_writes"
+                            : /* no outputs */
+                            : "r" (x));
+}
+
+#define spin_lock_prefetch(x)  prefetchw(x)
+
+#define HAVE_ARCH_PICK_MMAP_LAYOUT
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__ASM_SPARC64_PROCESSOR_H) */
diff --git a/include/asm-sparc/psrcompat.h b/include/asm-sparc/psrcompat.h
new file mode 100644 (file)
index 0000000..44b6327
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _SPARC64_PSRCOMPAT_H
+#define _SPARC64_PSRCOMPAT_H
+
+#include <asm/pstate.h>
+
+/* Old 32-bit PSR fields for the compatibility conversion code. */
+#define PSR_CWP     0x0000001f         /* current window pointer     */
+#define PSR_ET      0x00000020         /* enable traps field         */
+#define PSR_PS      0x00000040         /* previous privilege level   */
+#define PSR_S       0x00000080         /* current privilege level    */
+#define PSR_PIL     0x00000f00         /* processor interrupt level  */
+#define PSR_EF      0x00001000         /* enable floating point      */
+#define PSR_EC      0x00002000         /* enable co-processor        */
+#define PSR_SYSCALL 0x00004000         /* inside of a syscall        */
+#define PSR_LE      0x00008000         /* SuperSparcII little-endian */
+#define PSR_ICC     0x00f00000         /* integer condition codes    */
+#define PSR_C       0x00100000         /* carry bit                  */
+#define PSR_V       0x00200000         /* overflow bit               */
+#define PSR_Z       0x00400000         /* zero bit                   */
+#define PSR_N       0x00800000         /* negative bit               */
+#define PSR_VERS    0x0f000000         /* cpu-version field          */
+#define PSR_IMPL    0xf0000000         /* cpu-implementation field   */
+
+#define PSR_V8PLUS  0xff000000         /* fake impl/ver, meaning a 64bit CPU is present */
+#define PSR_XCC            0x000f0000         /* if PSR_V8PLUS, this is %xcc */
+
+static inline unsigned int tstate_to_psr(unsigned long tstate)
+{
+       return ((tstate & TSTATE_CWP)                   |
+               PSR_S                                   |
+               ((tstate & TSTATE_ICC) >> 12)           |
+               ((tstate & TSTATE_XCC) >> 20)           |
+               ((tstate & TSTATE_SYSCALL) ? PSR_SYSCALL : 0) |
+               PSR_V8PLUS);
+}
+
+static inline unsigned long psr_to_tstate_icc(unsigned int psr)
+{
+       unsigned long tstate = ((unsigned long)(psr & PSR_ICC)) << 12;
+       if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS)
+               tstate |= ((unsigned long)(psr & PSR_XCC)) << 20;
+       return tstate;
+}
+
+#endif /* !(_SPARC64_PSRCOMPAT_H) */
diff --git a/include/asm-sparc/pstate.h b/include/asm-sparc/pstate.h
new file mode 100644 (file)
index 0000000..a26a537
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef _SPARC64_PSTATE_H
+#define _SPARC64_PSTATE_H
+
+#include <linux/const.h>
+
+/* The V9 PSTATE Register (with SpitFire extensions).
+ *
+ * -----------------------------------------------------------------------
+ * | Resv | IG | MG | CLE | TLE |  MM  | RED | PEF | AM | PRIV | IE | AG |
+ * -----------------------------------------------------------------------
+ *  63  12  11   10    9     8    7   6   5     4     3     2     1    0
+ */
+#define PSTATE_IG   _AC(0x0000000000000800,UL) /* Interrupt Globals.   */
+#define PSTATE_MG   _AC(0x0000000000000400,UL) /* MMU Globals.         */
+#define PSTATE_CLE  _AC(0x0000000000000200,UL) /* Current Little Endian.*/
+#define PSTATE_TLE  _AC(0x0000000000000100,UL) /* Trap Little Endian.  */
+#define PSTATE_MM   _AC(0x00000000000000c0,UL) /* Memory Model.                */
+#define PSTATE_TSO  _AC(0x0000000000000000,UL) /* MM: TotalStoreOrder  */
+#define PSTATE_PSO  _AC(0x0000000000000040,UL) /* MM: PartialStoreOrder        */
+#define PSTATE_RMO  _AC(0x0000000000000080,UL) /* MM: RelaxedMemoryOrder*/
+#define PSTATE_RED  _AC(0x0000000000000020,UL) /* Reset Error Debug.   */
+#define PSTATE_PEF  _AC(0x0000000000000010,UL) /* Floating Point Enable.*/
+#define PSTATE_AM   _AC(0x0000000000000008,UL) /* Address Mask.                */
+#define PSTATE_PRIV _AC(0x0000000000000004,UL) /* Privilege.           */
+#define PSTATE_IE   _AC(0x0000000000000002,UL) /* Interrupt Enable.    */
+#define PSTATE_AG   _AC(0x0000000000000001,UL) /* Alternate Globals.   */
+
+/* The V9 TSTATE Register (with SpitFire and Linux extensions).
+ *
+ * ---------------------------------------------------------------------
+ * |  Resv |  GL  |  CCR  |  ASI  |  %pil  |  PSTATE  |  Resv  |  CWP  |
+ * ---------------------------------------------------------------------
+ *  63   43 42  40 39   32 31   24 23    20 19       8 7      5 4     0
+ */
+#define TSTATE_GL      _AC(0x0000070000000000,UL) /* Global reg level  */
+#define TSTATE_CCR     _AC(0x000000ff00000000,UL) /* Condition Codes.  */
+#define TSTATE_XCC     _AC(0x000000f000000000,UL) /* Condition Codes.  */
+#define TSTATE_XNEG    _AC(0x0000008000000000,UL) /* %xcc Negative.    */
+#define TSTATE_XZERO   _AC(0x0000004000000000,UL) /* %xcc Zero.        */
+#define TSTATE_XOVFL   _AC(0x0000002000000000,UL) /* %xcc Overflow.    */
+#define TSTATE_XCARRY  _AC(0x0000001000000000,UL) /* %xcc Carry.       */
+#define TSTATE_ICC     _AC(0x0000000f00000000,UL) /* Condition Codes.  */
+#define TSTATE_INEG    _AC(0x0000000800000000,UL) /* %icc Negative.    */
+#define TSTATE_IZERO   _AC(0x0000000400000000,UL) /* %icc Zero.        */
+#define TSTATE_IOVFL   _AC(0x0000000200000000,UL) /* %icc Overflow.    */
+#define TSTATE_ICARRY  _AC(0x0000000100000000,UL) /* %icc Carry.       */
+#define TSTATE_ASI     _AC(0x00000000ff000000,UL) /* AddrSpace ID.     */
+#define TSTATE_PIL     _AC(0x0000000000f00000,UL) /* %pil (Linux traps)*/
+#define TSTATE_PSTATE  _AC(0x00000000000fff00,UL) /* PSTATE.           */
+#define TSTATE_IG      _AC(0x0000000000080000,UL) /* Interrupt Globals.*/
+#define TSTATE_MG      _AC(0x0000000000040000,UL) /* MMU Globals.      */
+#define TSTATE_CLE     _AC(0x0000000000020000,UL) /* CurrLittleEndian. */
+#define TSTATE_TLE     _AC(0x0000000000010000,UL) /* TrapLittleEndian. */
+#define TSTATE_MM      _AC(0x000000000000c000,UL) /* Memory Model.     */
+#define TSTATE_TSO     _AC(0x0000000000000000,UL) /* MM: TSO           */
+#define TSTATE_PSO     _AC(0x0000000000004000,UL) /* MM: PSO           */
+#define TSTATE_RMO     _AC(0x0000000000008000,UL) /* MM: RMO           */
+#define TSTATE_RED     _AC(0x0000000000002000,UL) /* Reset Error Debug.*/
+#define TSTATE_PEF     _AC(0x0000000000001000,UL) /* FPU Enable.       */
+#define TSTATE_AM      _AC(0x0000000000000800,UL) /* Address Mask.     */
+#define TSTATE_PRIV    _AC(0x0000000000000400,UL) /* Privilege.        */
+#define TSTATE_IE      _AC(0x0000000000000200,UL) /* Interrupt Enable. */
+#define TSTATE_AG      _AC(0x0000000000000100,UL) /* Alternate Globals.*/
+#define TSTATE_SYSCALL _AC(0x0000000000000020,UL) /* in syscall trap   */
+#define TSTATE_CWP     _AC(0x000000000000001f,UL) /* Curr Win-Pointer. */
+
+/* Floating-Point Registers State Register.
+ *
+ * --------------------------------
+ * |  Resv  |  FEF  |  DU  |  DL  |
+ * --------------------------------
+ *  63     3    2       1      0
+ */
+#define FPRS_FEF       _AC(0x0000000000000004,UL) /* FPU Enable.       */
+#define FPRS_DU                _AC(0x0000000000000002,UL) /* Dirty Upper.      */
+#define FPRS_DL                _AC(0x0000000000000001,UL) /* Dirty Lower.      */
+
+/* Version Register.
+ *
+ * ------------------------------------------------------
+ * | MANUF | IMPL | MASK | Resv | MAXTL | Resv | MAXWIN |
+ * ------------------------------------------------------
+ *  63   48 47  32 31  24 23  16 15    8 7    5 4      0
+ */
+#define VERS_MANUF     _AC(0xffff000000000000,UL) /* Manufacturer.     */
+#define VERS_IMPL      _AC(0x0000ffff00000000,UL) /* Implementation.   */
+#define VERS_MASK      _AC(0x00000000ff000000,UL) /* Mask Set Revision.*/
+#define VERS_MAXTL     _AC(0x000000000000ff00,UL) /* Max Trap Level.   */
+#define VERS_MAXWIN    _AC(0x000000000000001f,UL) /* Max RegWindow Idx.*/
+
+#endif /* !(_SPARC64_PSTATE_H) */
index 11f3bc2bb3f5990462fa94cd48705a0045dc82db..f36ab6c30ff30cbf19c71e39af7a33c877b4b4bb 100644 (file)
@@ -1,175 +1,8 @@
-#ifndef _SPARC_PTRACE_H
-#define _SPARC_PTRACE_H
-
-#include <asm/psr.h>
-
-/* This struct defines the way the registers are stored on the 
- * stack during a system call and basically all traps.
- */
-
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-
-struct pt_regs {
-       unsigned long psr;
-       unsigned long pc;
-       unsigned long npc;
-       unsigned long y;
-       unsigned long u_regs[16]; /* globals and ins */
-};
-
-#define UREG_G0        0
-#define UREG_G1        1
-#define UREG_G2        2
-#define UREG_G3        3
-#define UREG_G4        4
-#define UREG_G5        5
-#define UREG_G6        6
-#define UREG_G7        7
-#define UREG_I0        8
-#define UREG_I1        9
-#define UREG_I2        10
-#define UREG_I3        11
-#define UREG_I4        12
-#define UREG_I5        13
-#define UREG_I6        14
-#define UREG_I7        15
-#define UREG_WIM       UREG_G0
-#define UREG_FADDR     UREG_G0
-#define UREG_FP        UREG_I6
-#define UREG_RETPC     UREG_I7
-
-static inline bool pt_regs_is_syscall(struct pt_regs *regs)
-{
-       return (regs->psr & PSR_SYSCALL);
-}
-
-static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
-{
-       return (regs->psr &= ~PSR_SYSCALL);
-}
-
-/* A register window */
-struct reg_window {
-       unsigned long locals[8];
-       unsigned long ins[8];
-};
-
-/* A Sparc stack frame */
-struct sparc_stackf {
-       unsigned long locals[8];
-        unsigned long ins[6];
-       struct sparc_stackf *fp;
-       unsigned long callers_pc;
-       char *structptr;
-       unsigned long xargs[6];
-       unsigned long xxargs[1];
-};     
-
-#define TRACEREG_SZ   sizeof(struct pt_regs)
-#define STACKFRAME_SZ sizeof(struct sparc_stackf)
-
-#ifdef __KERNEL__
-
-#define user_mode(regs) (!((regs)->psr & PSR_PS))
-#define instruction_pointer(regs) ((regs)->pc)
-unsigned long profile_pc(struct pt_regs *);
-extern void show_regs(struct pt_regs *);
+#ifndef ___ASM_SPARC_PTRACE_H
+#define ___ASM_SPARC_PTRACE_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/ptrace_64.h>
+#else
+#include <asm-sparc/ptrace_32.h>
 #endif
-
-#else /* __ASSEMBLY__ */
-/* For assembly code. */
-#define TRACEREG_SZ       0x50
-#define STACKFRAME_SZ     0x60
 #endif
-
-/*
- * The asm-offsets.h is a generated file, so we cannot include it.
- * It may be OK for glibc headers, but it's utterly pointless for C code.
- * The assembly code using those offsets has to include it explicitly.
- */
-/* #include <asm/asm-offsets.h> */
-
-/* These are for pt_regs. */
-#define PT_PSR    0x0
-#define PT_PC     0x4
-#define PT_NPC    0x8
-#define PT_Y      0xc
-#define PT_G0     0x10
-#define PT_WIM    PT_G0
-#define PT_G1     0x14
-#define PT_G2     0x18
-#define PT_G3     0x1c
-#define PT_G4     0x20
-#define PT_G5     0x24
-#define PT_G6     0x28
-#define PT_G7     0x2c
-#define PT_I0     0x30
-#define PT_I1     0x34
-#define PT_I2     0x38
-#define PT_I3     0x3c
-#define PT_I4     0x40
-#define PT_I5     0x44
-#define PT_I6     0x48
-#define PT_FP     PT_I6
-#define PT_I7     0x4c
-
-/* Reg_window offsets */
-#define RW_L0     0x00
-#define RW_L1     0x04
-#define RW_L2     0x08
-#define RW_L3     0x0c
-#define RW_L4     0x10
-#define RW_L5     0x14
-#define RW_L6     0x18
-#define RW_L7     0x1c
-#define RW_I0     0x20
-#define RW_I1     0x24
-#define RW_I2     0x28
-#define RW_I3     0x2c
-#define RW_I4     0x30
-#define RW_I5     0x34
-#define RW_I6     0x38
-#define RW_I7     0x3c
-
-/* Stack_frame offsets */
-#define SF_L0     0x00
-#define SF_L1     0x04
-#define SF_L2     0x08
-#define SF_L3     0x0c
-#define SF_L4     0x10
-#define SF_L5     0x14
-#define SF_L6     0x18
-#define SF_L7     0x1c
-#define SF_I0     0x20
-#define SF_I1     0x24
-#define SF_I2     0x28
-#define SF_I3     0x2c
-#define SF_I4     0x30
-#define SF_I5     0x34
-#define SF_FP     0x38
-#define SF_PC     0x3c
-#define SF_RETP   0x40
-#define SF_XARG0  0x44
-#define SF_XARG1  0x48
-#define SF_XARG2  0x4c
-#define SF_XARG3  0x50
-#define SF_XARG4  0x54
-#define SF_XARG5  0x58
-#define SF_XXARG  0x5c
-
-/* Stuff for the ptrace system call */
-#define PTRACE_SPARC_DETACH       11
-#define PTRACE_GETREGS            12
-#define PTRACE_SETREGS            13
-#define PTRACE_GETFPREGS          14
-#define PTRACE_SETFPREGS          15
-#define PTRACE_READDATA           16
-#define PTRACE_WRITEDATA          17
-#define PTRACE_READTEXT           18
-#define PTRACE_WRITETEXT          19
-#define PTRACE_GETFPAREGS         20
-#define PTRACE_SETFPAREGS         21
-
-#endif /* !(_SPARC_PTRACE_H) */
diff --git a/include/asm-sparc/ptrace_32.h b/include/asm-sparc/ptrace_32.h
new file mode 100644 (file)
index 0000000..0401cc7
--- /dev/null
@@ -0,0 +1,175 @@
+#ifndef _SPARC_PTRACE_H
+#define _SPARC_PTRACE_H
+
+#include <asm/psr.h>
+
+/* This struct defines the way the registers are stored on the
+ * stack during a system call and basically all traps.
+ */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+struct pt_regs {
+       unsigned long psr;
+       unsigned long pc;
+       unsigned long npc;
+       unsigned long y;
+       unsigned long u_regs[16]; /* globals and ins */
+};
+
+#define UREG_G0        0
+#define UREG_G1        1
+#define UREG_G2        2
+#define UREG_G3        3
+#define UREG_G4        4
+#define UREG_G5        5
+#define UREG_G6        6
+#define UREG_G7        7
+#define UREG_I0        8
+#define UREG_I1        9
+#define UREG_I2        10
+#define UREG_I3        11
+#define UREG_I4        12
+#define UREG_I5        13
+#define UREG_I6        14
+#define UREG_I7        15
+#define UREG_WIM       UREG_G0
+#define UREG_FADDR     UREG_G0
+#define UREG_FP        UREG_I6
+#define UREG_RETPC     UREG_I7
+
+static inline bool pt_regs_is_syscall(struct pt_regs *regs)
+{
+       return (regs->psr & PSR_SYSCALL);
+}
+
+static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
+{
+       return (regs->psr &= ~PSR_SYSCALL);
+}
+
+/* A register window */
+struct reg_window {
+       unsigned long locals[8];
+       unsigned long ins[8];
+};
+
+/* A Sparc stack frame */
+struct sparc_stackf {
+       unsigned long locals[8];
+        unsigned long ins[6];
+       struct sparc_stackf *fp;
+       unsigned long callers_pc;
+       char *structptr;
+       unsigned long xargs[6];
+       unsigned long xxargs[1];
+};
+
+#define TRACEREG_SZ   sizeof(struct pt_regs)
+#define STACKFRAME_SZ sizeof(struct sparc_stackf)
+
+#ifdef __KERNEL__
+
+#define user_mode(regs) (!((regs)->psr & PSR_PS))
+#define instruction_pointer(regs) ((regs)->pc)
+unsigned long profile_pc(struct pt_regs *);
+extern void show_regs(struct pt_regs *);
+#endif
+
+#else /* __ASSEMBLY__ */
+/* For assembly code. */
+#define TRACEREG_SZ       0x50
+#define STACKFRAME_SZ     0x60
+#endif
+
+/*
+ * The asm-offsets.h is a generated file, so we cannot include it.
+ * It may be OK for glibc headers, but it's utterly pointless for C code.
+ * The assembly code using those offsets has to include it explicitly.
+ */
+/* #include <asm/asm-offsets.h> */
+
+/* These are for pt_regs. */
+#define PT_PSR    0x0
+#define PT_PC     0x4
+#define PT_NPC    0x8
+#define PT_Y      0xc
+#define PT_G0     0x10
+#define PT_WIM    PT_G0
+#define PT_G1     0x14
+#define PT_G2     0x18
+#define PT_G3     0x1c
+#define PT_G4     0x20
+#define PT_G5     0x24
+#define PT_G6     0x28
+#define PT_G7     0x2c
+#define PT_I0     0x30
+#define PT_I1     0x34
+#define PT_I2     0x38
+#define PT_I3     0x3c
+#define PT_I4     0x40
+#define PT_I5     0x44
+#define PT_I6     0x48
+#define PT_FP     PT_I6
+#define PT_I7     0x4c
+
+/* Reg_window offsets */
+#define RW_L0     0x00
+#define RW_L1     0x04
+#define RW_L2     0x08
+#define RW_L3     0x0c
+#define RW_L4     0x10
+#define RW_L5     0x14
+#define RW_L6     0x18
+#define RW_L7     0x1c
+#define RW_I0     0x20
+#define RW_I1     0x24
+#define RW_I2     0x28
+#define RW_I3     0x2c
+#define RW_I4     0x30
+#define RW_I5     0x34
+#define RW_I6     0x38
+#define RW_I7     0x3c
+
+/* Stack_frame offsets */
+#define SF_L0     0x00
+#define SF_L1     0x04
+#define SF_L2     0x08
+#define SF_L3     0x0c
+#define SF_L4     0x10
+#define SF_L5     0x14
+#define SF_L6     0x18
+#define SF_L7     0x1c
+#define SF_I0     0x20
+#define SF_I1     0x24
+#define SF_I2     0x28
+#define SF_I3     0x2c
+#define SF_I4     0x30
+#define SF_I5     0x34
+#define SF_FP     0x38
+#define SF_PC     0x3c
+#define SF_RETP   0x40
+#define SF_XARG0  0x44
+#define SF_XARG1  0x48
+#define SF_XARG2  0x4c
+#define SF_XARG3  0x50
+#define SF_XARG4  0x54
+#define SF_XARG5  0x58
+#define SF_XXARG  0x5c
+
+/* Stuff for the ptrace system call */
+#define PTRACE_SPARC_DETACH       11
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+#define PTRACE_GETFPREGS          14
+#define PTRACE_SETFPREGS          15
+#define PTRACE_READDATA           16
+#define PTRACE_WRITEDATA          17
+#define PTRACE_READTEXT           18
+#define PTRACE_WRITETEXT          19
+#define PTRACE_GETFPAREGS         20
+#define PTRACE_SETFPAREGS         21
+
+#endif /* !(_SPARC_PTRACE_H) */
diff --git a/include/asm-sparc/ptrace_64.h b/include/asm-sparc/ptrace_64.h
new file mode 100644 (file)
index 0000000..a682e66
--- /dev/null
@@ -0,0 +1,346 @@
+#ifndef _SPARC64_PTRACE_H
+#define _SPARC64_PTRACE_H
+
+#include <asm/pstate.h>
+
+/* This struct defines the way the registers are stored on the
+ * stack during a system call and basically all traps.
+ */
+
+/* This magic value must have the low 9 bits clear,
+ * as that is where we encode the %tt value, see below.
+ */
+#define PT_REGS_MAGIC 0x57ac6c00
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+struct pt_regs {
+       unsigned long u_regs[16]; /* globals and ins */
+       unsigned long tstate;
+       unsigned long tpc;
+       unsigned long tnpc;
+       unsigned int y;
+
+       /* We encode a magic number, PT_REGS_MAGIC, along
+        * with the %tt (trap type) register value at trap
+        * entry time.  The magic number allows us to identify
+        * accurately a trap stack frame in the stack
+        * unwinder, and the %tt value allows us to test
+        * things like "in a system call" etc. for an arbitray
+        * process.
+        *
+        * The PT_REGS_MAGIC is choosen such that it can be
+        * loaded completely using just a sethi instruction.
+        */
+       unsigned int magic;
+};
+
+static inline int pt_regs_trap_type(struct pt_regs *regs)
+{
+       return regs->magic & 0x1ff;
+}
+
+static inline bool pt_regs_is_syscall(struct pt_regs *regs)
+{
+       return (regs->tstate & TSTATE_SYSCALL);
+}
+
+static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
+{
+       return (regs->tstate &= ~TSTATE_SYSCALL);
+}
+
+struct pt_regs32 {
+       unsigned int psr;
+       unsigned int pc;
+       unsigned int npc;
+       unsigned int y;
+       unsigned int u_regs[16]; /* globals and ins */
+};
+
+#define UREG_G0        0
+#define UREG_G1        1
+#define UREG_G2        2
+#define UREG_G3        3
+#define UREG_G4        4
+#define UREG_G5        5
+#define UREG_G6        6
+#define UREG_G7        7
+#define UREG_I0        8
+#define UREG_I1        9
+#define UREG_I2        10
+#define UREG_I3        11
+#define UREG_I4        12
+#define UREG_I5        13
+#define UREG_I6        14
+#define UREG_I7        15
+#define UREG_FP        UREG_I6
+#define UREG_RETPC     UREG_I7
+
+/* A V9 register window */
+struct reg_window {
+       unsigned long locals[8];
+       unsigned long ins[8];
+};
+
+/* A 32-bit register window. */
+struct reg_window32 {
+       unsigned int locals[8];
+       unsigned int ins[8];
+};
+
+/* A V9 Sparc stack frame */
+struct sparc_stackf {
+       unsigned long locals[8];
+        unsigned long ins[6];
+       struct sparc_stackf *fp;
+       unsigned long callers_pc;
+       char *structptr;
+       unsigned long xargs[6];
+       unsigned long xxargs[1];
+};
+
+/* A 32-bit Sparc stack frame */
+struct sparc_stackf32 {
+       unsigned int locals[8];
+        unsigned int ins[6];
+       unsigned int fp;
+       unsigned int callers_pc;
+       unsigned int structptr;
+       unsigned int xargs[6];
+       unsigned int xxargs[1];
+};
+
+struct sparc_trapf {
+       unsigned long locals[8];
+       unsigned long ins[8];
+       unsigned long _unused;
+       struct pt_regs *regs;
+};
+
+#define TRACEREG_SZ    sizeof(struct pt_regs)
+#define STACKFRAME_SZ  sizeof(struct sparc_stackf)
+
+#define TRACEREG32_SZ  sizeof(struct pt_regs32)
+#define STACKFRAME32_SZ        sizeof(struct sparc_stackf32)
+
+#ifdef __KERNEL__
+
+struct global_reg_snapshot {
+       unsigned long           tstate;
+       unsigned long           tpc;
+       unsigned long           tnpc;
+       unsigned long           o7;
+       unsigned long           i7;
+       struct thread_info      *thread;
+       unsigned long           pad1;
+       unsigned long           pad2;
+};
+
+#define __ARCH_WANT_COMPAT_SYS_PTRACE
+
+#define force_successful_syscall_return()          \
+do {   current_thread_info()->syscall_noerror = 1; \
+} while (0)
+#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
+#define instruction_pointer(regs) ((regs)->tpc)
+#define regs_return_value(regs) ((regs)->u_regs[UREG_I0])
+#ifdef CONFIG_SMP
+extern unsigned long profile_pc(struct pt_regs *);
+#else
+#define profile_pc(regs) instruction_pointer(regs)
+#endif
+extern void show_regs(struct pt_regs *);
+extern void __show_regs(struct pt_regs *);
+#endif
+
+#else /* __ASSEMBLY__ */
+/* For assembly code. */
+#define TRACEREG_SZ            0xa0
+#define STACKFRAME_SZ          0xc0
+
+#define TRACEREG32_SZ          0x50
+#define STACKFRAME32_SZ                0x60
+#endif
+
+#ifdef __KERNEL__
+#define STACK_BIAS             2047
+#endif
+
+/* These are for pt_regs. */
+#define PT_V9_G0     0x00
+#define PT_V9_G1     0x08
+#define PT_V9_G2     0x10
+#define PT_V9_G3     0x18
+#define PT_V9_G4     0x20
+#define PT_V9_G5     0x28
+#define PT_V9_G6     0x30
+#define PT_V9_G7     0x38
+#define PT_V9_I0     0x40
+#define PT_V9_I1     0x48
+#define PT_V9_I2     0x50
+#define PT_V9_I3     0x58
+#define PT_V9_I4     0x60
+#define PT_V9_I5     0x68
+#define PT_V9_I6     0x70
+#define PT_V9_FP     PT_V9_I6
+#define PT_V9_I7     0x78
+#define PT_V9_TSTATE 0x80
+#define PT_V9_TPC    0x88
+#define PT_V9_TNPC   0x90
+#define PT_V9_Y      0x98
+#define PT_V9_MAGIC  0x9c
+#define PT_TSTATE      PT_V9_TSTATE
+#define PT_TPC         PT_V9_TPC
+#define PT_TNPC                PT_V9_TNPC
+
+/* These for pt_regs32. */
+#define PT_PSR    0x0
+#define PT_PC     0x4
+#define PT_NPC    0x8
+#define PT_Y      0xc
+#define PT_G0     0x10
+#define PT_WIM    PT_G0
+#define PT_G1     0x14
+#define PT_G2     0x18
+#define PT_G3     0x1c
+#define PT_G4     0x20
+#define PT_G5     0x24
+#define PT_G6     0x28
+#define PT_G7     0x2c
+#define PT_I0     0x30
+#define PT_I1     0x34
+#define PT_I2     0x38
+#define PT_I3     0x3c
+#define PT_I4     0x40
+#define PT_I5     0x44
+#define PT_I6     0x48
+#define PT_FP     PT_I6
+#define PT_I7     0x4c
+
+/* Reg_window offsets */
+#define RW_V9_L0     0x00
+#define RW_V9_L1     0x08
+#define RW_V9_L2     0x10
+#define RW_V9_L3     0x18
+#define RW_V9_L4     0x20
+#define RW_V9_L5     0x28
+#define RW_V9_L6     0x30
+#define RW_V9_L7     0x38
+#define RW_V9_I0     0x40
+#define RW_V9_I1     0x48
+#define RW_V9_I2     0x50
+#define RW_V9_I3     0x58
+#define RW_V9_I4     0x60
+#define RW_V9_I5     0x68
+#define RW_V9_I6     0x70
+#define RW_V9_I7     0x78
+
+#define RW_L0     0x00
+#define RW_L1     0x04
+#define RW_L2     0x08
+#define RW_L3     0x0c
+#define RW_L4     0x10
+#define RW_L5     0x14
+#define RW_L6     0x18
+#define RW_L7     0x1c
+#define RW_I0     0x20
+#define RW_I1     0x24
+#define RW_I2     0x28
+#define RW_I3     0x2c
+#define RW_I4     0x30
+#define RW_I5     0x34
+#define RW_I6     0x38
+#define RW_I7     0x3c
+
+/* Stack_frame offsets */
+#define SF_V9_L0     0x00
+#define SF_V9_L1     0x08
+#define SF_V9_L2     0x10
+#define SF_V9_L3     0x18
+#define SF_V9_L4     0x20
+#define SF_V9_L5     0x28
+#define SF_V9_L6     0x30
+#define SF_V9_L7     0x38
+#define SF_V9_I0     0x40
+#define SF_V9_I1     0x48
+#define SF_V9_I2     0x50
+#define SF_V9_I3     0x58
+#define SF_V9_I4     0x60
+#define SF_V9_I5     0x68
+#define SF_V9_FP     0x70
+#define SF_V9_PC     0x78
+#define SF_V9_RETP   0x80
+#define SF_V9_XARG0  0x88
+#define SF_V9_XARG1  0x90
+#define SF_V9_XARG2  0x98
+#define SF_V9_XARG3  0xa0
+#define SF_V9_XARG4  0xa8
+#define SF_V9_XARG5  0xb0
+#define SF_V9_XXARG  0xb8
+
+#define SF_L0     0x00
+#define SF_L1     0x04
+#define SF_L2     0x08
+#define SF_L3     0x0c
+#define SF_L4     0x10
+#define SF_L5     0x14
+#define SF_L6     0x18
+#define SF_L7     0x1c
+#define SF_I0     0x20
+#define SF_I1     0x24
+#define SF_I2     0x28
+#define SF_I3     0x2c
+#define SF_I4     0x30
+#define SF_I5     0x34
+#define SF_FP     0x38
+#define SF_PC     0x3c
+#define SF_RETP   0x40
+#define SF_XARG0  0x44
+#define SF_XARG1  0x48
+#define SF_XARG2  0x4c
+#define SF_XARG3  0x50
+#define SF_XARG4  0x54
+#define SF_XARG5  0x58
+#define SF_XXARG  0x5c
+
+#ifdef __KERNEL__
+
+/* global_reg_snapshot offsets */
+#define GR_SNAP_TSTATE 0x00
+#define GR_SNAP_TPC    0x08
+#define GR_SNAP_TNPC   0x10
+#define GR_SNAP_O7     0x18
+#define GR_SNAP_I7     0x20
+#define GR_SNAP_THREAD 0x28
+#define GR_SNAP_PAD1   0x30
+#define GR_SNAP_PAD2   0x38
+
+#endif  /*  __KERNEL__  */
+
+/* Stuff for the ptrace system call */
+#define PTRACE_SPARC_DETACH       11
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+#define PTRACE_GETFPREGS          14
+#define PTRACE_SETFPREGS          15
+#define PTRACE_READDATA           16
+#define PTRACE_WRITEDATA          17
+#define PTRACE_READTEXT           18
+#define PTRACE_WRITETEXT          19
+#define PTRACE_GETFPAREGS         20
+#define PTRACE_SETFPAREGS         21
+
+/* There are for debugging 64-bit processes, either from a 32 or 64 bit
+ * parent.  Thus their complements are for debugging 32-bit processes only.
+ */
+
+#define PTRACE_GETREGS64         22
+#define PTRACE_SETREGS64         23
+/* PTRACE_SYSCALL is 24 */
+#define PTRACE_GETFPREGS64       25
+#define PTRACE_SETFPREGS64       26
+
+#endif /* !(_SPARC64_PTRACE_H) */
diff --git a/include/asm-sparc/reboot.h b/include/asm-sparc/reboot.h
new file mode 100644 (file)
index 0000000..3f3f43f
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _SPARC64_REBOOT_H
+#define _SPARC64_REBOOT_H
+
+extern void machine_alt_power_off(void);
+
+#endif /* _SPARC64_REBOOT_H */
index ea0a7e590bb3fb1e8ecd9bc2c7be01ee96efda34..cb34b0a49aad47375066c73ed031845d64be868d 100644 (file)
@@ -1,79 +1,8 @@
-/*
- * linux/include/asm-sparc/reg.h
- * Layout of the registers as expected by gdb on the Sparc
- * we should replace the user.h definitions with those in
- * this file, we don't even use the other 
- * -miguel
- *
- * The names of the structures, constants and aliases in this file
- * have the same names as the sunos ones, some programs rely on these
- * names (gdb for example).
- *
- */
-
-#ifndef __SPARC_REG_H
-#define __SPARC_REG_H
-
-struct regs {
-       int     r_psr;
-#define r_ps r_psr
-        int     r_pc; 
-        int     r_npc;
-        int     r_y;  
-        int     r_g1; 
-        int     r_g2;
-        int     r_g3;
-        int     r_g4;
-        int     r_g5;
-        int     r_g6;
-        int     r_g7;
-        int     r_o0;
-        int     r_o1;
-        int     r_o2;
-        int     r_o3;
-        int     r_o4;
-        int     r_o5;
-        int     r_o6;
-        int     r_o7;
-};
-
-struct fpq {
-        unsigned long *addr;
-        unsigned long instr;
-};
-
-struct  fq {
-        union {
-                double  whole;
-                struct  fpq fpq;
-        } FQu;
-};
-
-#define FPU_REGS_TYPE unsigned int
-#define FPU_FSR_TYPE unsigned
-
-struct fp_status {
-        union {
-                FPU_REGS_TYPE Fpu_regs[32];
-                double  Fpu_dregs[16];
-        } fpu_fr;
-        FPU_FSR_TYPE Fpu_fsr;
-        unsigned Fpu_flags;
-        unsigned Fpu_extra;
-        unsigned Fpu_qcnt;
-        struct fq Fpu_q[16];
-};
-
-#define fpu_regs  f_fpstatus.fpu_fr.Fpu_regs
-#define fpu_dregs f_fpstatus.fpu_fr.Fpu_dregs
-#define fpu_fsr   f_fpstatus.Fpu_fsr
-#define fpu_flags f_fpstatus.Fpu_flags
-#define fpu_extra f_fpstatus.Fpu_extra
-#define fpu_q     f_fpstatus.Fpu_q
-#define fpu_qcnt  f_fpstatus.Fpu_qcnt
-
-struct fpu {
-        struct fp_status f_fpstatus;
-};
-
-#endif /* __SPARC_REG_H */
+#ifndef ___ASM_SPARC_REG_H
+#define ___ASM_SPARC_REG_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/reg_64.h>
+#else
+#include <asm-sparc/reg_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/reg_32.h b/include/asm-sparc/reg_32.h
new file mode 100644 (file)
index 0000000..42fecfc
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * linux/include/asm-sparc/reg.h
+ * Layout of the registers as expected by gdb on the Sparc
+ * we should replace the user.h definitions with those in
+ * this file, we don't even use the other
+ * -miguel
+ *
+ * The names of the structures, constants and aliases in this file
+ * have the same names as the sunos ones, some programs rely on these
+ * names (gdb for example).
+ *
+ */
+
+#ifndef __SPARC_REG_H
+#define __SPARC_REG_H
+
+struct regs {
+       int     r_psr;
+#define r_ps r_psr
+        int     r_pc;
+        int     r_npc;
+        int     r_y;
+        int     r_g1;
+        int     r_g2;
+        int     r_g3;
+        int     r_g4;
+        int     r_g5;
+        int     r_g6;
+        int     r_g7;
+        int     r_o0;
+        int     r_o1;
+        int     r_o2;
+        int     r_o3;
+        int     r_o4;
+        int     r_o5;
+        int     r_o6;
+        int     r_o7;
+};
+
+struct fpq {
+        unsigned long *addr;
+        unsigned long instr;
+};
+
+struct  fq {
+        union {
+                double  whole;
+                struct  fpq fpq;
+        } FQu;
+};
+
+#define FPU_REGS_TYPE unsigned int
+#define FPU_FSR_TYPE unsigned
+
+struct fp_status {
+        union {
+                FPU_REGS_TYPE Fpu_regs[32];
+                double  Fpu_dregs[16];
+        } fpu_fr;
+        FPU_FSR_TYPE Fpu_fsr;
+        unsigned Fpu_flags;
+        unsigned Fpu_extra;
+        unsigned Fpu_qcnt;
+        struct fq Fpu_q[16];
+};
+
+#define fpu_regs  f_fpstatus.fpu_fr.Fpu_regs
+#define fpu_dregs f_fpstatus.fpu_fr.Fpu_dregs
+#define fpu_fsr   f_fpstatus.Fpu_fsr
+#define fpu_flags f_fpstatus.Fpu_flags
+#define fpu_extra f_fpstatus.Fpu_extra
+#define fpu_q     f_fpstatus.Fpu_q
+#define fpu_qcnt  f_fpstatus.Fpu_qcnt
+
+struct fpu {
+        struct fp_status f_fpstatus;
+};
+
+#endif /* __SPARC_REG_H */
diff --git a/include/asm-sparc/reg_64.h b/include/asm-sparc/reg_64.h
new file mode 100644 (file)
index 0000000..eb24a07
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * linux/asm-sparc64/reg.h
+ * Layout of the registers as expected by gdb on the Sparc
+ * we should replace the user.h definitions with those in
+ * this file, we don't even use the other
+ * -miguel
+ *
+ * The names of the structures, constants and aliases in this file
+ * have the same names as the sunos ones, some programs rely on these
+ * names (gdb for example).
+ *
+ */
+
+#ifndef __SPARC64_REG_H
+#define __SPARC64_REG_H
+
+struct regs {
+        unsigned long r_g1;
+        unsigned long r_g2;
+        unsigned long r_g3;
+        unsigned long r_g4;
+        unsigned long r_g5;
+        unsigned long r_g6;
+        unsigned long r_g7;
+        unsigned long r_o0;
+        unsigned long r_o1;
+        unsigned long r_o2;
+        unsigned long r_o3;
+        unsigned long r_o4;
+        unsigned long r_o5;
+        unsigned long r_o6;
+        unsigned long r_o7;
+        unsigned long __pad;
+        unsigned long r_tstate;
+        unsigned long r_tpc;
+        unsigned long r_tnpc;
+        unsigned int  r_y;
+        unsigned int  r_fprs;
+};
+
+#define FPU_REGS_TYPE unsigned int
+#define FPU_FSR_TYPE unsigned long
+
+struct fp_status {
+        unsigned long fpu_fr[32];
+        unsigned long Fpu_fsr;
+};
+
+struct fpu {
+       struct fp_status f_fpstatus;
+};
+
+#define fpu_regs  f_fpstatus.fpu_fr
+#define fpu_fsr   f_fpstatus.Fpu_fsr
+
+#endif /* __SPARC64_REG_H */
index 985948a412990797f5e70550d479d143a9f74299..fe163cafb4c7553ba6c8ec61b727e6c8673854df 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * resource.h: Resource definitions.
  *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
  */
 
 #ifndef _SPARC_RESOURCE_H
 #define RLIMIT_NOFILE          6       /* max number of open files */
 #define RLIMIT_NPROC           7       /* max number of processes */
 
+#if defined(__sparc__) && defined(__arch64__)
+/* Use generic version */
+#else
 /*
  * SuS says limits have to be unsigned.
  * We make this unsigned, but keep the
  * old value for compatibility:
  */
 #define RLIM_INFINITY          0x7fffffff
+#endif
 
 #include <asm-generic/resource.h>
 
diff --git a/include/asm-sparc/rwsem-const.h b/include/asm-sparc/rwsem-const.h
new file mode 100644 (file)
index 0000000..a303c9d
--- /dev/null
@@ -0,0 +1,12 @@
+/* rwsem-const.h: RW semaphore counter constants.  */
+#ifndef _SPARC64_RWSEM_CONST_H
+#define _SPARC64_RWSEM_CONST_H
+
+#define RWSEM_UNLOCKED_VALUE           0x00000000
+#define RWSEM_ACTIVE_BIAS              0x00000001
+#define RWSEM_ACTIVE_MASK              0x0000ffff
+#define RWSEM_WAITING_BIAS             0xffff0000
+#define RWSEM_ACTIVE_READ_BIAS         RWSEM_ACTIVE_BIAS
+#define RWSEM_ACTIVE_WRITE_BIAS                (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+
+#endif /* _SPARC64_RWSEM_CONST_H */
diff --git a/include/asm-sparc/rwsem.h b/include/asm-sparc/rwsem.h
new file mode 100644 (file)
index 0000000..1dc129a
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * rwsem.h: R/W semaphores implemented using CAS
+ *
+ * Written by David S. Miller (davem@redhat.com), 2001.
+ * Derived from asm-i386/rwsem.h
+ */
+#ifndef _SPARC64_RWSEM_H
+#define _SPARC64_RWSEM_H
+
+#ifndef _LINUX_RWSEM_H
+#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
+#endif
+
+#ifdef __KERNEL__
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <asm/rwsem-const.h>
+
+struct rwsem_waiter;
+
+struct rw_semaphore {
+       signed int count;
+       spinlock_t              wait_lock;
+       struct list_head        wait_list;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+       struct lockdep_map      dep_map;
+#endif
+};
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname }
+#else
+# define __RWSEM_DEP_MAP_INIT(lockname)
+#endif
+
+#define __RWSEM_INITIALIZER(name) \
+{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) \
+  __RWSEM_DEP_MAP_INIT(name) }
+
+#define DECLARE_RWSEM(name) \
+       struct rw_semaphore name = __RWSEM_INITIALIZER(name)
+
+extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
+                        struct lock_class_key *key);
+
+#define init_rwsem(sem)                                                \
+do {                                                           \
+       static struct lock_class_key __key;                     \
+                                                               \
+       __init_rwsem((sem), #sem, &__key);                      \
+} while (0)
+
+extern void __down_read(struct rw_semaphore *sem);
+extern int __down_read_trylock(struct rw_semaphore *sem);
+extern void __down_write(struct rw_semaphore *sem);
+extern int __down_write_trylock(struct rw_semaphore *sem);
+extern void __up_read(struct rw_semaphore *sem);
+extern void __up_write(struct rw_semaphore *sem);
+extern void __downgrade_write(struct rw_semaphore *sem);
+
+static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
+{
+       __down_write(sem);
+}
+
+static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+{
+       return atomic_add_return(delta, (atomic_t *)(&sem->count));
+}
+
+static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
+{
+       atomic_add(delta, (atomic_t *)(&sem->count));
+}
+
+static inline int rwsem_is_locked(struct rw_semaphore *sem)
+{
+       return (sem->count != 0);
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _SPARC64_RWSEM_H */
index f1d2fe1c9a304980a3c47d18022d51a5ab1a097d..8f29a19796658336930648cd958b6b3f4f2833cd 100644 (file)
@@ -1,153 +1,8 @@
-/*
- * sbus.h:  Defines for the Sun SBus.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef _SPARC_SBUS_H
-#define _SPARC_SBUS_H
-
-#include <linux/dma-mapping.h>
-#include <linux/ioport.h>
-
-#include <asm/oplib.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
-#include <asm/scatterlist.h>
-
-/* We scan which devices are on the SBus using the PROM node device
- * tree.  SBus devices are described in two different ways.  You can
- * either get an absolute address at which to access the device, or
- * you can get a SBus 'slot' number and an offset within that slot.
- */
-
-/* The base address at which to calculate device OBIO addresses. */
-#define SUN_SBUS_BVADDR        0xf8000000
-#define SBUS_OFF_MASK          0x01ffffff
-
-/* These routines are used to calculate device address from slot
- * numbers + offsets, and vice versa.
- */
-
-static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset)
-{
-  return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<25)+(offset));
-}
-
-static inline int sbus_dev_slot(unsigned long dev_addr)
-{
-  return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>25);
-}
-
-struct sbus_bus;
-
-/* Linux SBUS device tables */
-struct sbus_dev {
-       struct of_device        ofdev;
-       struct sbus_bus         *bus;
-       struct sbus_dev         *next;
-       struct sbus_dev         *child;
-       struct sbus_dev         *parent;
-       int prom_node;  
-       char prom_name[64];
-       int slot;
-
-       struct resource resource[PROMREG_MAX];
-
-       struct linux_prom_registers reg_addrs[PROMREG_MAX];
-       int num_registers;
-
-       struct linux_prom_ranges device_ranges[PROMREG_MAX];
-       int num_device_ranges;
-
-       unsigned int irqs[4];
-       int num_irqs;
-};
-#define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev)
-
-/* This struct describes the SBus(s) found on this machine. */
-struct sbus_bus {
-       struct of_device        ofdev;
-       struct sbus_dev         *devices;       /* Link to devices on this SBus */
-       struct sbus_bus         *next;          /* next SBus, if more than one SBus */
-       int                     prom_node;      /* PROM device tree node for this SBus */
-       char                    prom_name[64];  /* Usually "sbus" or "sbi" */
-       int                     clock_freq;
-
-       struct linux_prom_ranges sbus_ranges[PROMREG_MAX];
-       int num_sbus_ranges;
-
-       int devid;
-       int board;
-};
-#define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev)
-
-extern struct sbus_bus *sbus_root;
-
-static inline int
-sbus_is_slave(struct sbus_dev *dev)
-{
-       /* XXX Have to write this for sun4c's */
-       return 0;
-}
-
-/* Device probing routines could find these handy */
-#define for_each_sbus(bus) \
-        for((bus) = sbus_root; (bus); (bus)=(bus)->next)
-
-#define for_each_sbusdev(device, bus) \
-        for((device) = (bus)->devices; (device); (device)=(device)->next)
-        
-#define for_all_sbusdev(device, bus) \
-       for ((bus) = sbus_root; (bus); (bus) = (bus)->next) \
-               for ((device) = (bus)->devices; (device); (device) = (device)->next)
-
-/* Driver DVMA interfaces. */
-#define sbus_can_dma_64bit(sdev)       (0) /* actually, sparc_cpu_model==sun4d */
-#define sbus_can_burst64(sdev)         (0) /* actually, sparc_cpu_model==sun4d */
-extern void sbus_set_sbus64(struct sbus_dev *, int);
-extern void sbus_fill_device_irq(struct sbus_dev *);
-
-/* These yield IOMMU mappings in consistent mode. */
-extern void *sbus_alloc_consistent(struct sbus_dev *, long, u32 *dma_addrp);
-extern void sbus_free_consistent(struct sbus_dev *, long, void *, u32);
-void prom_adjust_ranges(struct linux_prom_ranges *, int,
-                       struct linux_prom_ranges *, int);
-
-#define SBUS_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL
-#define SBUS_DMA_TODEVICE      DMA_TO_DEVICE
-#define SBUS_DMA_FROMDEVICE    DMA_FROM_DEVICE
-#define        SBUS_DMA_NONE           DMA_NONE
-
-/* All the rest use streaming mode mappings. */
-extern dma_addr_t sbus_map_single(struct sbus_dev *, void *, size_t, int);
-extern void sbus_unmap_single(struct sbus_dev *, dma_addr_t, size_t, int);
-extern int sbus_map_sg(struct sbus_dev *, struct scatterlist *, int, int);
-extern void sbus_unmap_sg(struct sbus_dev *, struct scatterlist *, int, int);
-
-/* Finally, allow explicit synchronization of streamable mappings. */
-extern void sbus_dma_sync_single_for_cpu(struct sbus_dev *, dma_addr_t, size_t, int);
-#define sbus_dma_sync_single sbus_dma_sync_single_for_cpu
-extern void sbus_dma_sync_single_for_device(struct sbus_dev *, dma_addr_t, size_t, int);
-extern void sbus_dma_sync_sg_for_cpu(struct sbus_dev *, struct scatterlist *, int, int);
-#define sbus_dma_sync_sg sbus_dma_sync_sg_for_cpu
-extern void sbus_dma_sync_sg_for_device(struct sbus_dev *, struct scatterlist *, int, int);
-
-/* Eric Brower (ebrower@usa.net)
- * Translate SBus interrupt levels to ino values--
- * this is used when converting sbus "interrupts" OBP 
- * node values to "intr" node values, and is platform 
- * dependent.  If only we could call OBP with 
- * "sbus-intr>cpu (sbint -- ino)" from kernel...
- * See .../drivers/sbus/sbus.c for details.
- */
-BTFIXUPDEF_CALL(unsigned int, sbint_to_irq, struct sbus_dev *sdev, unsigned int)
-#define sbint_to_irq(sdev, sbint) BTFIXUP_CALL(sbint_to_irq)(sdev, sbint)
-
-extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *);
-extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *);
-extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *);
-extern int sbus_arch_preinit(void);
-extern void sbus_arch_postinit(void);
-
-#endif /* !(_SPARC_SBUS_H) */
+#ifndef ___ASM_SPARC_SBUS_H
+#define ___ASM_SPARC_SBUS_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/sbus_64.h>
+#else
+#include <asm-sparc/sbus_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/sbus_32.h b/include/asm-sparc/sbus_32.h
new file mode 100644 (file)
index 0000000..77b5d3a
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * sbus.h:  Defines for the Sun SBus.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_SBUS_H
+#define _SPARC_SBUS_H
+
+#include <linux/dma-mapping.h>
+#include <linux/ioport.h>
+
+#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
+#include <asm/scatterlist.h>
+
+/* We scan which devices are on the SBus using the PROM node device
+ * tree.  SBus devices are described in two different ways.  You can
+ * either get an absolute address at which to access the device, or
+ * you can get a SBus 'slot' number and an offset within that slot.
+ */
+
+/* The base address at which to calculate device OBIO addresses. */
+#define SUN_SBUS_BVADDR        0xf8000000
+#define SBUS_OFF_MASK          0x01ffffff
+
+/* These routines are used to calculate device address from slot
+ * numbers + offsets, and vice versa.
+ */
+
+static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset)
+{
+  return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<25)+(offset));
+}
+
+static inline int sbus_dev_slot(unsigned long dev_addr)
+{
+  return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>25);
+}
+
+struct sbus_bus;
+
+/* Linux SBUS device tables */
+struct sbus_dev {
+       struct of_device        ofdev;
+       struct sbus_bus         *bus;
+       struct sbus_dev         *next;
+       struct sbus_dev         *child;
+       struct sbus_dev         *parent;
+       int prom_node;
+       char prom_name[64];
+       int slot;
+
+       struct resource resource[PROMREG_MAX];
+
+       struct linux_prom_registers reg_addrs[PROMREG_MAX];
+       int num_registers;
+
+       struct linux_prom_ranges device_ranges[PROMREG_MAX];
+       int num_device_ranges;
+
+       unsigned int irqs[4];
+       int num_irqs;
+};
+#define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev)
+
+/* This struct describes the SBus(s) found on this machine. */
+struct sbus_bus {
+       struct of_device        ofdev;
+       struct sbus_dev         *devices;       /* Link to devices on this SBus */
+       struct sbus_bus         *next;          /* next SBus, if more than one SBus */
+       int                     prom_node;      /* PROM device tree node for this SBus */
+       char                    prom_name[64];  /* Usually "sbus" or "sbi" */
+       int                     clock_freq;
+
+       struct linux_prom_ranges sbus_ranges[PROMREG_MAX];
+       int num_sbus_ranges;
+
+       int devid;
+       int board;
+};
+#define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev)
+
+extern struct sbus_bus *sbus_root;
+
+static inline int
+sbus_is_slave(struct sbus_dev *dev)
+{
+       /* XXX Have to write this for sun4c's */
+       return 0;
+}
+
+/* Device probing routines could find these handy */
+#define for_each_sbus(bus) \
+        for((bus) = sbus_root; (bus); (bus)=(bus)->next)
+
+#define for_each_sbusdev(device, bus) \
+        for((device) = (bus)->devices; (device); (device)=(device)->next)
+
+#define for_all_sbusdev(device, bus) \
+       for ((bus) = sbus_root; (bus); (bus) = (bus)->next) \
+               for ((device) = (bus)->devices; (device); (device) = (device)->next)
+
+/* Driver DVMA interfaces. */
+#define sbus_can_dma_64bit(sdev)       (0) /* actually, sparc_cpu_model==sun4d */
+#define sbus_can_burst64(sdev)         (0) /* actually, sparc_cpu_model==sun4d */
+extern void sbus_set_sbus64(struct sbus_dev *, int);
+extern void sbus_fill_device_irq(struct sbus_dev *);
+
+/* These yield IOMMU mappings in consistent mode. */
+extern void *sbus_alloc_consistent(struct sbus_dev *, long, u32 *dma_addrp);
+extern void sbus_free_consistent(struct sbus_dev *, long, void *, u32);
+void prom_adjust_ranges(struct linux_prom_ranges *, int,
+                       struct linux_prom_ranges *, int);
+
+#define SBUS_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL
+#define SBUS_DMA_TODEVICE      DMA_TO_DEVICE
+#define SBUS_DMA_FROMDEVICE    DMA_FROM_DEVICE
+#define        SBUS_DMA_NONE           DMA_NONE
+
+/* All the rest use streaming mode mappings. */
+extern dma_addr_t sbus_map_single(struct sbus_dev *, void *, size_t, int);
+extern void sbus_unmap_single(struct sbus_dev *, dma_addr_t, size_t, int);
+extern int sbus_map_sg(struct sbus_dev *, struct scatterlist *, int, int);
+extern void sbus_unmap_sg(struct sbus_dev *, struct scatterlist *, int, int);
+
+/* Finally, allow explicit synchronization of streamable mappings. */
+extern void sbus_dma_sync_single_for_cpu(struct sbus_dev *, dma_addr_t, size_t, int);
+#define sbus_dma_sync_single sbus_dma_sync_single_for_cpu
+extern void sbus_dma_sync_single_for_device(struct sbus_dev *, dma_addr_t, size_t, int);
+extern void sbus_dma_sync_sg_for_cpu(struct sbus_dev *, struct scatterlist *, int, int);
+#define sbus_dma_sync_sg sbus_dma_sync_sg_for_cpu
+extern void sbus_dma_sync_sg_for_device(struct sbus_dev *, struct scatterlist *, int, int);
+
+/* Eric Brower (ebrower@usa.net)
+ * Translate SBus interrupt levels to ino values--
+ * this is used when converting sbus "interrupts" OBP
+ * node values to "intr" node values, and is platform
+ * dependent.  If only we could call OBP with
+ * "sbus-intr>cpu (sbint -- ino)" from kernel...
+ * See .../drivers/sbus/sbus.c for details.
+ */
+BTFIXUPDEF_CALL(unsigned int, sbint_to_irq, struct sbus_dev *sdev, unsigned int)
+#define sbint_to_irq(sdev, sbint) BTFIXUP_CALL(sbint_to_irq)(sdev, sbint)
+
+extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *);
+extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *);
+extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *);
+extern int sbus_arch_preinit(void);
+extern void sbus_arch_postinit(void);
+
+#endif /* !(_SPARC_SBUS_H) */
diff --git a/include/asm-sparc/sbus_64.h b/include/asm-sparc/sbus_64.h
new file mode 100644 (file)
index 0000000..0e16b6d
--- /dev/null
@@ -0,0 +1,190 @@
+/* sbus.h: Defines for the Sun SBus.
+ *
+ * Copyright (C) 1996, 1999, 2007 David S. Miller (davem@davemloft.net)
+ */
+
+#ifndef _SPARC64_SBUS_H
+#define _SPARC64_SBUS_H
+
+#include <linux/dma-mapping.h>
+#include <linux/ioport.h>
+
+#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
+#include <asm/iommu.h>
+#include <asm/scatterlist.h>
+
+/* We scan which devices are on the SBus using the PROM node device
+ * tree.  SBus devices are described in two different ways.  You can
+ * either get an absolute address at which to access the device, or
+ * you can get a SBus 'slot' number and an offset within that slot.
+ */
+
+/* The base address at which to calculate device OBIO addresses. */
+#define SUN_SBUS_BVADDR        0x00000000
+#define SBUS_OFF_MASK          0x0fffffff
+
+/* These routines are used to calculate device address from slot
+ * numbers + offsets, and vice versa.
+ */
+
+static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset)
+{
+  return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<28)+(offset));
+}
+
+static inline int sbus_dev_slot(unsigned long dev_addr)
+{
+  return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>28);
+}
+
+struct sbus_bus;
+
+/* Linux SBUS device tables */
+struct sbus_dev {
+       struct of_device        ofdev;
+       struct sbus_bus         *bus;
+       struct sbus_dev         *next;
+       struct sbus_dev         *child;
+       struct sbus_dev         *parent;
+       int prom_node;
+       char prom_name[64];
+       int slot;
+
+       struct resource resource[PROMREG_MAX];
+
+       struct linux_prom_registers reg_addrs[PROMREG_MAX];
+       int num_registers;
+
+       struct linux_prom_ranges device_ranges[PROMREG_MAX];
+       int num_device_ranges;
+
+       unsigned int irqs[4];
+       int num_irqs;
+};
+#define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev)
+
+/* This struct describes the SBus(s) found on this machine. */
+struct sbus_bus {
+       struct of_device        ofdev;
+       struct sbus_dev         *devices;       /* Tree of SBUS devices */
+       struct sbus_bus         *next;          /* Next SBUS in system  */
+       int                     prom_node;      /* OBP node of SBUS     */
+       char                    prom_name[64];  /* Usually "sbus" or "sbi" */
+       int                     clock_freq;
+
+       struct linux_prom_ranges sbus_ranges[PROMREG_MAX];
+       int num_sbus_ranges;
+
+       int portid;
+};
+#define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev)
+
+extern struct sbus_bus *sbus_root;
+
+/* Device probing routines could find these handy */
+#define for_each_sbus(bus) \
+        for((bus) = sbus_root; (bus); (bus)=(bus)->next)
+
+#define for_each_sbusdev(device, bus) \
+        for((device) = (bus)->devices; (device); (device)=(device)->next)
+
+#define for_all_sbusdev(device, bus) \
+       for ((bus) = sbus_root; (bus); (bus) = (bus)->next) \
+               for ((device) = (bus)->devices; (device); (device) = (device)->next)
+
+/* Driver DVMA interfaces. */
+#define sbus_can_dma_64bit(sdev)       (1)
+#define sbus_can_burst64(sdev)         (1)
+extern void sbus_set_sbus64(struct sbus_dev *, int);
+extern void sbus_fill_device_irq(struct sbus_dev *);
+
+static inline void *sbus_alloc_consistent(struct sbus_dev *sdev , size_t size,
+                                         dma_addr_t *dma_handle)
+{
+       return dma_alloc_coherent(&sdev->ofdev.dev, size,
+                                 dma_handle, GFP_ATOMIC);
+}
+
+static inline void sbus_free_consistent(struct sbus_dev *sdev, size_t size,
+                                       void *vaddr, dma_addr_t dma_handle)
+{
+       return dma_free_coherent(&sdev->ofdev.dev, size, vaddr, dma_handle);
+}
+
+#define SBUS_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL
+#define SBUS_DMA_TODEVICE      DMA_TO_DEVICE
+#define SBUS_DMA_FROMDEVICE    DMA_FROM_DEVICE
+#define        SBUS_DMA_NONE           DMA_NONE
+
+/* All the rest use streaming mode mappings. */
+static inline dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr,
+                                        size_t size, int direction)
+{
+       return dma_map_single(&sdev->ofdev.dev, ptr, size,
+                             (enum dma_data_direction) direction);
+}
+
+static inline void sbus_unmap_single(struct sbus_dev *sdev,
+                                    dma_addr_t dma_addr, size_t size,
+                                    int direction)
+{
+       dma_unmap_single(&sdev->ofdev.dev, dma_addr, size,
+                        (enum dma_data_direction) direction);
+}
+
+static inline int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg,
+                             int nents, int direction)
+{
+       return dma_map_sg(&sdev->ofdev.dev, sg, nents,
+                         (enum dma_data_direction) direction);
+}
+
+static inline void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg,
+                                int nents, int direction)
+{
+       dma_unmap_sg(&sdev->ofdev.dev, sg, nents,
+                    (enum dma_data_direction) direction);
+}
+
+/* Finally, allow explicit synchronization of streamable mappings. */
+static inline void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev,
+                                               dma_addr_t dma_handle,
+                                               size_t size, int direction)
+{
+       dma_sync_single_for_cpu(&sdev->ofdev.dev, dma_handle, size,
+                               (enum dma_data_direction) direction);
+}
+#define sbus_dma_sync_single sbus_dma_sync_single_for_cpu
+
+static inline void sbus_dma_sync_single_for_device(struct sbus_dev *sdev,
+                                                  dma_addr_t dma_handle,
+                                                  size_t size, int direction)
+{
+       /* No flushing needed to sync cpu writes to the device.  */
+}
+
+static inline void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev,
+                                           struct scatterlist *sg,
+                                           int nents, int direction)
+{
+       dma_sync_sg_for_cpu(&sdev->ofdev.dev, sg, nents,
+                           (enum dma_data_direction) direction);
+}
+#define sbus_dma_sync_sg sbus_dma_sync_sg_for_cpu
+
+static inline void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev,
+                                              struct scatterlist *sg,
+                                              int nents, int direction)
+{
+       /* No flushing needed to sync cpu writes to the device.  */
+}
+
+extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *);
+extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *);
+extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *);
+extern int sbus_arch_preinit(void);
+extern void sbus_arch_postinit(void);
+
+#endif /* !(_SPARC64_SBUS_H) */
index c82609ca1d0faa6ae9a85bd23b062cf386081608..b1a0e316c2b6f762d9f26c3dd530a82caa967fd4 100644 (file)
@@ -1,26 +1,8 @@
-#ifndef _SPARC_SCATTERLIST_H
-#define _SPARC_SCATTERLIST_H
-
-#include <linux/types.h>
-
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
-       unsigned long sg_magic;
+#ifndef ___ASM_SPARC_SCATTERLIST_H
+#define ___ASM_SPARC_SCATTERLIST_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/scatterlist_64.h>
+#else
+#include <asm-sparc/scatterlist_32.h>
+#endif
 #endif
-       unsigned long page_link;
-       unsigned int offset;
-
-       unsigned int length;
-
-       __u32 dvma_address; /* A place to hang host-specific addresses at. */
-       __u32 dvma_length;
-};
-
-#define sg_dma_address(sg) ((sg)->dvma_address)
-#define sg_dma_len(sg)     ((sg)->dvma_length)
-
-#define ISA_DMA_THRESHOLD (~0UL)
-
-#define ARCH_HAS_SG_CHAIN
-
-#endif /* !(_SPARC_SCATTERLIST_H) */
diff --git a/include/asm-sparc/scatterlist_32.h b/include/asm-sparc/scatterlist_32.h
new file mode 100644 (file)
index 0000000..c82609c
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef _SPARC_SCATTERLIST_H
+#define _SPARC_SCATTERLIST_H
+
+#include <linux/types.h>
+
+struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+       unsigned long sg_magic;
+#endif
+       unsigned long page_link;
+       unsigned int offset;
+
+       unsigned int length;
+
+       __u32 dvma_address; /* A place to hang host-specific addresses at. */
+       __u32 dvma_length;
+};
+
+#define sg_dma_address(sg) ((sg)->dvma_address)
+#define sg_dma_len(sg)     ((sg)->dvma_length)
+
+#define ISA_DMA_THRESHOLD (~0UL)
+
+#define ARCH_HAS_SG_CHAIN
+
+#endif /* !(_SPARC_SCATTERLIST_H) */
diff --git a/include/asm-sparc/scatterlist_64.h b/include/asm-sparc/scatterlist_64.h
new file mode 100644 (file)
index 0000000..81bd058
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _SPARC64_SCATTERLIST_H
+#define _SPARC64_SCATTERLIST_H
+
+#include <asm/page.h>
+#include <asm/types.h>
+
+struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+       unsigned long   sg_magic;
+#endif
+       unsigned long   page_link;
+       unsigned int    offset;
+
+       unsigned int    length;
+
+       dma_addr_t      dma_address;
+       __u32           dma_length;
+};
+
+#define sg_dma_address(sg)     ((sg)->dma_address)
+#define sg_dma_len(sg)         ((sg)->dma_length)
+
+#define ISA_DMA_THRESHOLD      (~0UL)
+
+#define ARCH_HAS_SG_CHAIN
+
+#endif /* !(_SPARC64_SCATTERLIST_H) */
diff --git a/include/asm-sparc/scratchpad.h b/include/asm-sparc/scratchpad.h
new file mode 100644 (file)
index 0000000..5e8b01f
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _SPARC64_SCRATCHPAD_H
+#define _SPARC64_SCRATCHPAD_H
+
+/* Sun4v scratchpad registers, accessed via ASI_SCRATCHPAD.  */
+
+#define SCRATCHPAD_MMU_MISS    0x00 /* Shared with OBP - set by OBP        */
+#define SCRATCHPAD_CPUID       0x08 /* Shared with OBP - set by hypervisor */
+#define SCRATCHPAD_UTSBREG1    0x10
+#define SCRATCHPAD_UTSBREG2    0x18
+       /* 0x20 and 0x28, hypervisor only... */
+#define SCRATCHPAD_UNUSED1     0x30
+#define SCRATCHPAD_UNUSED2     0x38 /* Reserved for OBP                    */
+
+#endif /* !(_SPARC64_SCRATCHPAD_H) */
diff --git a/include/asm-sparc/seccomp.h b/include/asm-sparc/seccomp.h
new file mode 100644 (file)
index 0000000..7fcd996
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _ASM_SECCOMP_H
+
+#include <linux/thread_info.h> /* already defines TIF_32BIT */
+
+#ifndef TIF_32BIT
+#error "unexpected TIF_32BIT on sparc64"
+#endif
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+#define __NR_seccomp_read_32 __NR_read
+#define __NR_seccomp_write_32 __NR_write
+#define __NR_seccomp_exit_32 __NR_exit
+#define __NR_seccomp_sigreturn_32 __NR_sigreturn
+
+#endif /* _ASM_SECCOMP_H */
index 6832841df0515de93383a151a95ae15d7ad26c3b..cbd019162425bf90b4df4ef526b7c42370513cc1 100644 (file)
@@ -1,6 +1,8 @@
-#ifndef _SPARC_SECTIONS_H
-#define _SPARC_SECTIONS_H
-
-#include <asm-generic/sections.h>
-
+#ifndef ___ASM_SPARC_SECTIONS_H
+#define ___ASM_SPARC_SECTIONS_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/sections_64.h>
+#else
+#include <asm-sparc/sections_32.h>
+#endif
 #endif
diff --git a/include/asm-sparc/sections_32.h b/include/asm-sparc/sections_32.h
new file mode 100644 (file)
index 0000000..6832841
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _SPARC_SECTIONS_H
+#define _SPARC_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+#endif
diff --git a/include/asm-sparc/sections_64.h b/include/asm-sparc/sections_64.h
new file mode 100644 (file)
index 0000000..3f4b9fd
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _SPARC64_SECTIONS_H
+#define _SPARC64_SECTIONS_H
+
+/* nothing to see, move along */
+#include <asm-generic/sections.h>
+
+extern char _start[];
+
+#endif
index a79c4bb3c08ac6205413b62e7bbbee599b43bd49..faee1be08d67b223deef379a411df0ec40f51fbe 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _SPARC_SEMBUF_H
 #define _SPARC_SEMBUF_H
 
-/* 
+/*
  * The semid64_ds structure for sparc architecture.
  * Note extra padding because this structure is passed back and forth
  * between kernel and user space.
  * - 64-bit time_t to solve y2038 problem
  * - 2 miscellaneous 32-bit values
  */
+#if defined(__sparc__) && defined(__arch64__)
+# define PADDING(x)
+#else
+# define PADDING(x) unsigned int x;
+#endif
 
 struct semid64_ds {
        struct ipc64_perm sem_perm;             /* permissions .. see ipc.h */
-       unsigned int    __pad1;
+       PADDING(__pad1)
        __kernel_time_t sem_otime;              /* last semop time */
-       unsigned int    __pad2;
+       PADDING(__pad2)
        __kernel_time_t sem_ctime;              /* last change time */
        unsigned long   sem_nsems;              /* no. of semaphores in array */
        unsigned long   __unused1;
        unsigned long   __unused2;
 };
+#undef PADDING
 
 #endif /* _SPARC64_SEMBUF_H */
index b3af958a2ad2d2fbce85d20368f6553592370063..2643c62f4ac0d6809797e2b851e98fe8ce5e8042 100644 (file)
@@ -5,6 +5,10 @@
 #ifndef _SPARC_SETUP_H
 #define _SPARC_SETUP_H
 
-#define COMMAND_LINE_SIZE      256
+#if defined(__sparc__) && defined(__arch64__)
+# define COMMAND_LINE_SIZE 2048
+#else
+# define COMMAND_LINE_SIZE 256
+#endif
 
 #endif /* _SPARC_SETUP_H */
diff --git a/include/asm-sparc/sfafsr.h b/include/asm-sparc/sfafsr.h
new file mode 100644 (file)
index 0000000..e96137b
--- /dev/null
@@ -0,0 +1,82 @@
+#ifndef _SPARC64_SFAFSR_H
+#define _SPARC64_SFAFSR_H
+
+#include <linux/const.h>
+
+/* Spitfire Asynchronous Fault Status register, ASI=0x4C VA<63:0>=0x0 */
+
+#define SFAFSR_ME              (_AC(1,UL) << SFAFSR_ME_SHIFT)
+#define SFAFSR_ME_SHIFT                32
+#define SFAFSR_PRIV            (_AC(1,UL) << SFAFSR_PRIV_SHIFT)
+#define SFAFSR_PRIV_SHIFT      31
+#define SFAFSR_ISAP            (_AC(1,UL) << SFAFSR_ISAP_SHIFT)
+#define SFAFSR_ISAP_SHIFT      30
+#define SFAFSR_ETP             (_AC(1,UL) << SFAFSR_ETP_SHIFT)
+#define SFAFSR_ETP_SHIFT       29
+#define SFAFSR_IVUE            (_AC(1,UL) << SFAFSR_IVUE_SHIFT)
+#define SFAFSR_IVUE_SHIFT      28
+#define SFAFSR_TO              (_AC(1,UL) << SFAFSR_TO_SHIFT)
+#define SFAFSR_TO_SHIFT                27
+#define SFAFSR_BERR            (_AC(1,UL) << SFAFSR_BERR_SHIFT)
+#define SFAFSR_BERR_SHIFT      26
+#define SFAFSR_LDP             (_AC(1,UL) << SFAFSR_LDP_SHIFT)
+#define SFAFSR_LDP_SHIFT       25
+#define SFAFSR_CP              (_AC(1,UL) << SFAFSR_CP_SHIFT)
+#define SFAFSR_CP_SHIFT                24
+#define SFAFSR_WP              (_AC(1,UL) << SFAFSR_WP_SHIFT)
+#define SFAFSR_WP_SHIFT                23
+#define SFAFSR_EDP             (_AC(1,UL) << SFAFSR_EDP_SHIFT)
+#define SFAFSR_EDP_SHIFT       22
+#define SFAFSR_UE              (_AC(1,UL) << SFAFSR_UE_SHIFT)
+#define SFAFSR_UE_SHIFT                21
+#define SFAFSR_CE              (_AC(1,UL) << SFAFSR_CE_SHIFT)
+#define SFAFSR_CE_SHIFT                20
+#define SFAFSR_ETS             (_AC(0xf,UL) << SFAFSR_ETS_SHIFT)
+#define SFAFSR_ETS_SHIFT       16
+#define SFAFSR_PSYND           (_AC(0xffff,UL) << SFAFSR_PSYND_SHIFT)
+#define SFAFSR_PSYND_SHIFT     0
+
+/* UDB Error Register, ASI=0x7f VA<63:0>=0x0(High),0x18(Low) for read
+ *                     ASI=0x77 VA<63:0>=0x0(High),0x18(Low) for write
+ */
+
+#define UDBE_UE                        (_AC(1,UL) << 9)
+#define UDBE_CE                        (_AC(1,UL) << 8)
+#define UDBE_E_SYNDR           (_AC(0xff,UL) << 0)
+
+/* The trap handlers for asynchronous errors encode the AFSR and
+ * other pieces of information into a 64-bit argument for C code
+ * encoded as follows:
+ *
+ * -----------------------------------------------
+ * |  UDB_H  |  UDB_L  | TL>1  |  TT  |   AFSR   |
+ * -----------------------------------------------
+ *  63     54 53     44    42   41  33 32       0
+ *
+ * The AFAR is passed in unchanged.
+ */
+#define SFSTAT_UDBH_MASK       (_AC(0x3ff,UL) << SFSTAT_UDBH_SHIFT)
+#define SFSTAT_UDBH_SHIFT      54
+#define SFSTAT_UDBL_MASK       (_AC(0x3ff,UL) << SFSTAT_UDBH_SHIFT)
+#define SFSTAT_UDBL_SHIFT      44
+#define SFSTAT_TL_GT_ONE       (_AC(1,UL) << SFSTAT_TL_GT_ONE_SHIFT)
+#define SFSTAT_TL_GT_ONE_SHIFT 42
+#define SFSTAT_TRAP_TYPE       (_AC(0x1FF,UL) << SFSTAT_TRAP_TYPE_SHIFT)
+#define SFSTAT_TRAP_TYPE_SHIFT 33
+#define SFSTAT_AFSR_MASK       (_AC(0x1ffffffff,UL) << SFSTAT_AFSR_SHIFT)
+#define SFSTAT_AFSR_SHIFT      0
+
+/* ESTATE Error Enable Register, ASI=0x4b VA<63:0>=0x0 */
+#define ESTATE_ERR_CE          0x1 /* Correctable errors                    */
+#define ESTATE_ERR_NCE         0x2 /* TO, BERR, LDP, ETP, EDP, WP, UE, IVUE */
+#define ESTATE_ERR_ISAP                0x4 /* System address parity error           */
+#define ESTATE_ERR_ALL         (ESTATE_ERR_CE | \
+                                ESTATE_ERR_NCE | \
+                                ESTATE_ERR_ISAP)
+
+/* The various trap types that report using the above state. */
+#define TRAP_TYPE_IAE          0x09 /* Instruction Access Error             */
+#define TRAP_TYPE_DAE          0x32 /* Data Access Error                    */
+#define TRAP_TYPE_CEE          0x63 /* Correctable ECC Error                */
+
+#endif /* _SPARC64_SFAFSR_H */
index 266a42b8f99fad61d7f907bad23d306b4846846d..c676fcc2dd277df52fe27378f00f97f91ad32706 100644 (file)
@@ -1,212 +1,8 @@
-/* Machine-dependent software floating-point definitions.
-   Sparc userland (_Q_*) version.
-   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Richard Henderson (rth@cygnus.com),
-                 Jakub Jelinek (jj@ultra.linux.cz),
-                 David S. Miller (davem@redhat.com) and
-                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If
-   not, write to the Free Software Foundation, Inc.,
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#ifndef _SFP_MACHINE_H
-#define _SFP_MACHINE_H
-
-   
-#define _FP_W_TYPE_SIZE                32
-#define _FP_W_TYPE             unsigned long
-#define _FP_WS_TYPE            signed long
-#define _FP_I_TYPE             long
-
-#define _FP_MUL_MEAT_S(R,X,Y)                                  \
-  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_D(R,X,Y)                                  \
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_Q(R,X,Y)                                  \
-  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_udiv(S,R,X,Y)
-#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_2_udiv(D,R,X,Y)
-#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 1) - 1)
-#define _FP_NANFRAC_D          ((_FP_QNANBIT_D << 1) - 1), -1
-#define _FP_NANFRAC_Q          ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
-#define _FP_NANSIGN_S          0
-#define _FP_NANSIGN_D          0
-#define _FP_NANSIGN_Q          0
-
-#define _FP_KEEPNANFRACP 1
-
-/* If one NaN is signaling and the other is not,
- * we choose that one, otherwise we choose X.
- */
-/* For _Qp_* and _Q_*, this should prefer X, for
- * CPU instruction emulation this should prefer Y.
- * (see SPAMv9 B.2.2 section).
- */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
-  do {                                                         \
-    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)         \
-       && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))     \
-      {                                                                \
-       R##_s = X##_s;                                          \
-       _FP_FRAC_COPY_##wc(R,X);                                \
-      }                                                                \
-    else                                                       \
-      {                                                                \
-       R##_s = Y##_s;                                          \
-       _FP_FRAC_COPY_##wc(R,Y);                                \
-      }                                                                \
-    R##_c = FP_CLS_NAN;                                                \
-  } while (0)
-
-/* Some assembly to speed things up. */
-#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)                    \
-  __asm__ ("addcc %r7,%8,%2\n\t"                                       \
-          "addxcc %r5,%6,%1\n\t"                                       \
-          "addx %r3,%4,%0\n"                                           \
-          : "=r" ((USItype)(r2)),                                      \
-            "=&r" ((USItype)(r1)),                                     \
-            "=&r" ((USItype)(r0))                                      \
-          : "%rJ" ((USItype)(x2)),                                     \
-            "rI" ((USItype)(y2)),                                      \
-            "%rJ" ((USItype)(x1)),                                     \
-            "rI" ((USItype)(y1)),                                      \
-            "%rJ" ((USItype)(x0)),                                     \
-            "rI" ((USItype)(y0))                                       \
-          : "cc")
-
-#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)                    \
-  __asm__ ("subcc %r7,%8,%2\n\t"                                       \
-           "subxcc %r5,%6,%1\n\t"                                      \
-           "subx %r3,%4,%0\n"                                          \
-          : "=r" ((USItype)(r2)),                                      \
-            "=&r" ((USItype)(r1)),                                     \
-            "=&r" ((USItype)(r0))                                      \
-          : "%rJ" ((USItype)(x2)),                                     \
-            "rI" ((USItype)(y2)),                                      \
-            "%rJ" ((USItype)(x1)),                                     \
-            "rI" ((USItype)(y1)),                                      \
-            "%rJ" ((USItype)(x0)),                                     \
-            "rI" ((USItype)(y0))                                       \
-          : "cc")
-
-#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
-  do {                                                                 \
-    /* We need to fool gcc,  as we need to pass more than 10           \
-       input/outputs.  */                                              \
-    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");           \
-    __asm__ __volatile__ (                                             \
-           "addcc %r8,%9,%1\n\t"                                       \
-           "addxcc %r6,%7,%0\n\t"                                      \
-           "addxcc %r4,%5,%%g2\n\t"                                    \
-           "addx %r2,%3,%%g1\n\t"                                      \
-          : "=&r" ((USItype)(r1)),                                     \
-            "=&r" ((USItype)(r0))                                      \
-          : "%rJ" ((USItype)(x3)),                                     \
-            "rI" ((USItype)(y3)),                                      \
-            "%rJ" ((USItype)(x2)),                                     \
-            "rI" ((USItype)(y2)),                                      \
-            "%rJ" ((USItype)(x1)),                                     \
-            "rI" ((USItype)(y1)),                                      \
-            "%rJ" ((USItype)(x0)),                                     \
-            "rI" ((USItype)(y0))                                       \
-          : "cc", "g1", "g2");                                         \
-    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));                        \
-    r3 = _t1; r2 = _t2;                                                        \
-  } while (0)
-
-#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
-  do {                                                                 \
-    /* We need to fool gcc,  as we need to pass more than 10           \
-       input/outputs.  */                                              \
-    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");           \
-    __asm__ __volatile__ (                                             \
-           "subcc %r8,%9,%1\n\t"                                       \
-           "subxcc %r6,%7,%0\n\t"                                      \
-           "subxcc %r4,%5,%%g2\n\t"                                    \
-           "subx %r2,%3,%%g1\n\t"                                      \
-          : "=&r" ((USItype)(r1)),                                     \
-            "=&r" ((USItype)(r0))                                      \
-          : "%rJ" ((USItype)(x3)),                                     \
-            "rI" ((USItype)(y3)),                                      \
-            "%rJ" ((USItype)(x2)),                                     \
-            "rI" ((USItype)(y2)),                                      \
-            "%rJ" ((USItype)(x1)),                                     \
-            "rI" ((USItype)(y1)),                                      \
-            "%rJ" ((USItype)(x0)),                                     \
-            "rI" ((USItype)(y0))                                       \
-          : "cc", "g1", "g2");                                         \
-    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));                        \
-    r3 = _t1; r2 = _t2;                                                        \
-  } while (0)
-
-#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0)
-
-#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0)
-
-#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)                                        \
-  __asm__ ("addcc %3,%4,%3\n\t"                                                \
-          "addxcc %2,%%g0,%2\n\t"                                      \
-          "addxcc %1,%%g0,%1\n\t"                                      \
-          "addx %0,%%g0,%0\n\t"                                        \
-          : "=&r" ((USItype)(x3)),                                     \
-            "=&r" ((USItype)(x2)),                                     \
-            "=&r" ((USItype)(x1)),                                     \
-            "=&r" ((USItype)(x0))                                      \
-          : "rI" ((USItype)(i)),                                       \
-            "0" ((USItype)(x3)),                                       \
-            "1" ((USItype)(x2)),                                       \
-            "2" ((USItype)(x1)),                                       \
-            "3" ((USItype)(x0))                                        \
-          : "cc")
-
-#ifndef CONFIG_SMP
-extern struct task_struct *last_task_used_math;
-#endif
-
-/* Obtain the current rounding mode. */
-#ifndef FP_ROUNDMODE
-#ifdef CONFIG_SMP
-#define FP_ROUNDMODE   ((current->thread.fsr >> 30) & 0x3)
-#else
-#define FP_ROUNDMODE   ((last_task_used_math->thread.fsr >> 30) & 0x3)
-#endif
-#endif
-
-/* Exception flags. */
-#define FP_EX_INVALID          (1 << 4)
-#define FP_EX_OVERFLOW         (1 << 3)
-#define FP_EX_UNDERFLOW                (1 << 2)
-#define FP_EX_DIVZERO          (1 << 1)
-#define FP_EX_INEXACT          (1 << 0)
-
-#define FP_HANDLE_EXCEPTIONS return _fex
-
-#ifdef CONFIG_SMP
-#define FP_INHIBIT_RESULTS ((current->thread.fsr >> 23) & _fex)
-#else
-#define FP_INHIBIT_RESULTS ((last_task_used_math->thread.fsr >> 23) & _fex)
-#endif
-
-#ifdef CONFIG_SMP
-#define FP_TRAPPING_EXCEPTIONS ((current->thread.fsr >> 23) & 0x1f)
+#ifndef ___ASM_SPARC_SFP_MACHINE_H
+#define ___ASM_SPARC_SFP_MACHINE_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/sfp-machine_64.h>
 #else
-#define FP_TRAPPING_EXCEPTIONS ((last_task_used_math->thread.fsr >> 23) & 0x1f)
+#include <asm-sparc/sfp-machine_32.h>
 #endif
-
 #endif
diff --git a/include/asm-sparc/sfp-machine_32.h b/include/asm-sparc/sfp-machine_32.h
new file mode 100644 (file)
index 0000000..01d9c3b
--- /dev/null
@@ -0,0 +1,212 @@
+/* Machine-dependent software floating-point definitions.
+   Sparc userland (_Q_*) version.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jj@ultra.linux.cz),
+                 David S. Miller (davem@redhat.com) and
+                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _SFP_MACHINE_H
+#define _SFP_MACHINE_H
+
+
+#define _FP_W_TYPE_SIZE                32
+#define _FP_W_TYPE             unsigned long
+#define _FP_WS_TYPE            signed long
+#define _FP_I_TYPE             long
+
+#define _FP_MUL_MEAT_S(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)                                  \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)                                  \
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D          ((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q          ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S          0
+#define _FP_NANSIGN_D          0
+#define _FP_NANSIGN_Q          0
+
+#define _FP_KEEPNANFRACP 1
+
+/* If one NaN is signaling and the other is not,
+ * we choose that one, otherwise we choose X.
+ */
+/* For _Qp_* and _Q_*, this should prefer X, for
+ * CPU instruction emulation this should prefer Y.
+ * (see SPAMv9 B.2.2 section).
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+  do {                                                         \
+    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)         \
+       && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))     \
+      {                                                                \
+       R##_s = X##_s;                                          \
+       _FP_FRAC_COPY_##wc(R,X);                                \
+      }                                                                \
+    else                                                       \
+      {                                                                \
+       R##_s = Y##_s;                                          \
+       _FP_FRAC_COPY_##wc(R,Y);                                \
+      }                                                                \
+    R##_c = FP_CLS_NAN;                                                \
+  } while (0)
+
+/* Some assembly to speed things up. */
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)                    \
+  __asm__ ("addcc %r7,%8,%2\n\t"                                       \
+          "addxcc %r5,%6,%1\n\t"                                       \
+          "addx %r3,%4,%0\n"                                           \
+          : "=r" ((USItype)(r2)),                                      \
+            "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x2)),                                     \
+            "rI" ((USItype)(y2)),                                      \
+            "%rJ" ((USItype)(x1)),                                     \
+            "rI" ((USItype)(y1)),                                      \
+            "%rJ" ((USItype)(x0)),                                     \
+            "rI" ((USItype)(y0))                                       \
+          : "cc")
+
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)                    \
+  __asm__ ("subcc %r7,%8,%2\n\t"                                       \
+           "subxcc %r5,%6,%1\n\t"                                      \
+           "subx %r3,%4,%0\n"                                          \
+          : "=r" ((USItype)(r2)),                                      \
+            "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x2)),                                     \
+            "rI" ((USItype)(y2)),                                      \
+            "%rJ" ((USItype)(x1)),                                     \
+            "rI" ((USItype)(y1)),                                      \
+            "%rJ" ((USItype)(x0)),                                     \
+            "rI" ((USItype)(y0))                                       \
+          : "cc")
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
+  do {                                                                 \
+    /* We need to fool gcc,  as we need to pass more than 10           \
+       input/outputs.  */                                              \
+    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");           \
+    __asm__ __volatile__ (                                             \
+           "addcc %r8,%9,%1\n\t"                                       \
+           "addxcc %r6,%7,%0\n\t"                                      \
+           "addxcc %r4,%5,%%g2\n\t"                                    \
+           "addx %r2,%3,%%g1\n\t"                                      \
+          : "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x3)),                                     \
+            "rI" ((USItype)(y3)),                                      \
+            "%rJ" ((USItype)(x2)),                                     \
+            "rI" ((USItype)(y2)),                                      \
+            "%rJ" ((USItype)(x1)),                                     \
+            "rI" ((USItype)(y1)),                                      \
+            "%rJ" ((USItype)(x0)),                                     \
+            "rI" ((USItype)(y0))                                       \
+          : "cc", "g1", "g2");                                         \
+    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));                        \
+    r3 = _t1; r2 = _t2;                                                        \
+  } while (0)
+
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
+  do {                                                                 \
+    /* We need to fool gcc,  as we need to pass more than 10           \
+       input/outputs.  */                                              \
+    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");           \
+    __asm__ __volatile__ (                                             \
+           "subcc %r8,%9,%1\n\t"                                       \
+           "subxcc %r6,%7,%0\n\t"                                      \
+           "subxcc %r4,%5,%%g2\n\t"                                    \
+           "subx %r2,%3,%%g1\n\t"                                      \
+          : "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x3)),                                     \
+            "rI" ((USItype)(y3)),                                      \
+            "%rJ" ((USItype)(x2)),                                     \
+            "rI" ((USItype)(y2)),                                      \
+            "%rJ" ((USItype)(x1)),                                     \
+            "rI" ((USItype)(y1)),                                      \
+            "%rJ" ((USItype)(x0)),                                     \
+            "rI" ((USItype)(y0))                                       \
+          : "cc", "g1", "g2");                                         \
+    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));                        \
+    r3 = _t1; r2 = _t2;                                                        \
+  } while (0)
+
+#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0)
+
+#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0)
+
+#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)                                        \
+  __asm__ ("addcc %3,%4,%3\n\t"                                                \
+          "addxcc %2,%%g0,%2\n\t"                                      \
+          "addxcc %1,%%g0,%1\n\t"                                      \
+          "addx %0,%%g0,%0\n\t"                                        \
+          : "=&r" ((USItype)(x3)),                                     \
+            "=&r" ((USItype)(x2)),                                     \
+            "=&r" ((USItype)(x1)),                                     \
+            "=&r" ((USItype)(x0))                                      \
+          : "rI" ((USItype)(i)),                                       \
+            "0" ((USItype)(x3)),                                       \
+            "1" ((USItype)(x2)),                                       \
+            "2" ((USItype)(x1)),                                       \
+            "3" ((USItype)(x0))                                        \
+          : "cc")
+
+#ifndef CONFIG_SMP
+extern struct task_struct *last_task_used_math;
+#endif
+
+/* Obtain the current rounding mode. */
+#ifndef FP_ROUNDMODE
+#ifdef CONFIG_SMP
+#define FP_ROUNDMODE   ((current->thread.fsr >> 30) & 0x3)
+#else
+#define FP_ROUNDMODE   ((last_task_used_math->thread.fsr >> 30) & 0x3)
+#endif
+#endif
+
+/* Exception flags. */
+#define FP_EX_INVALID          (1 << 4)
+#define FP_EX_OVERFLOW         (1 << 3)
+#define FP_EX_UNDERFLOW                (1 << 2)
+#define FP_EX_DIVZERO          (1 << 1)
+#define FP_EX_INEXACT          (1 << 0)
+
+#define FP_HANDLE_EXCEPTIONS return _fex
+
+#ifdef CONFIG_SMP
+#define FP_INHIBIT_RESULTS ((current->thread.fsr >> 23) & _fex)
+#else
+#define FP_INHIBIT_RESULTS ((last_task_used_math->thread.fsr >> 23) & _fex)
+#endif
+
+#ifdef CONFIG_SMP
+#define FP_TRAPPING_EXCEPTIONS ((current->thread.fsr >> 23) & 0x1f)
+#else
+#define FP_TRAPPING_EXCEPTIONS ((last_task_used_math->thread.fsr >> 23) & 0x1f)
+#endif
+
+#endif
diff --git a/include/asm-sparc/sfp-machine_64.h b/include/asm-sparc/sfp-machine_64.h
new file mode 100644 (file)
index 0000000..ca913ef
--- /dev/null
@@ -0,0 +1,93 @@
+/* Machine-dependent software floating-point definitions.
+   Sparc64 kernel version.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jj@ultra.linux.cz) and
+                 David S. Miller (davem@redhat.com).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _SFP_MACHINE_H
+#define _SFP_MACHINE_H
+
+#define _FP_W_TYPE_SIZE                64
+#define _FP_W_TYPE             unsigned long
+#define _FP_WS_TYPE            signed long
+#define _FP_I_TYPE             long
+
+#define _FP_MUL_MEAT_S(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
+#define _FP_MUL_MEAT_D(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)                                  \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D          ((_FP_QNANBIT_D << 1) - 1)
+#define _FP_NANFRAC_Q          ((_FP_QNANBIT_Q << 1) - 1), -1
+#define _FP_NANSIGN_S          0
+#define _FP_NANSIGN_D          0
+#define _FP_NANSIGN_Q          0
+
+#define _FP_KEEPNANFRACP 1
+
+/* If one NaN is signaling and the other is not,
+ * we choose that one, otherwise we choose X.
+ */
+/* For _Qp_* and _Q_*, this should prefer X, for
+ * CPU instruction emulation this should prefer Y.
+ * (see SPAMv9 B.2.2 section).
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+  do {                                                         \
+    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)         \
+       && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))     \
+      {                                                                \
+       R##_s = X##_s;                                          \
+       _FP_FRAC_COPY_##wc(R,X);                                \
+      }                                                                \
+    else                                                       \
+      {                                                                \
+       R##_s = Y##_s;                                          \
+       _FP_FRAC_COPY_##wc(R,Y);                                \
+      }                                                                \
+    R##_c = FP_CLS_NAN;                                                \
+  } while (0)
+
+/* Obtain the current rounding mode. */
+#ifndef FP_ROUNDMODE
+#define FP_ROUNDMODE   ((current_thread_info()->xfsr[0] >> 30) & 0x3)
+#endif
+
+/* Exception flags. */
+#define FP_EX_INVALID          (1 << 4)
+#define FP_EX_OVERFLOW         (1 << 3)
+#define FP_EX_UNDERFLOW                (1 << 2)
+#define FP_EX_DIVZERO          (1 << 1)
+#define FP_EX_INEXACT          (1 << 0)
+
+#define FP_HANDLE_EXCEPTIONS return _fex
+
+#define FP_INHIBIT_RESULTS ((current_thread_info()->xfsr[0] >> 23) & _fex)
+
+#define FP_TRAPPING_EXCEPTIONS ((current_thread_info()->xfsr[0] >> 23) & 0x1f)
+
+#endif
index 1ff9da8bec73c37f38b07f9f25fa01aebdd95e67..83a16055363fc4b7498625d4f62e24e62cc31c73 100644 (file)
  * - 2 miscellaneous 32-bit values
  */
 
+#if defined(__sparc__) && defined(__arch64__)
+# define PADDING(x)
+#else
+# define PADDING(x) unsigned int x;
+#endif
+
 struct shmid64_ds {
        struct ipc64_perm       shm_perm;       /* operation perms */
-       unsigned int            __pad1;
+       PADDING(__pad1)
        __kernel_time_t         shm_atime;      /* last attach time */
-       unsigned int            __pad2;
+       PADDING(__pad2)
        __kernel_time_t         shm_dtime;      /* last detach time */
-       unsigned int            __pad3;
+       PADDING(__pad3)
        __kernel_time_t         shm_ctime;      /* last change time */
        size_t                  shm_segsz;      /* size of segment (bytes) */
        __kernel_pid_t          shm_cpid;       /* pid of creator */
@@ -39,4 +45,6 @@ struct shminfo64 {
        unsigned long   __unused4;
 };
 
+#undef PADDING
+
 #endif /* _SPARC_SHMBUF_H */
index 59a1243c12f3a493771ad6dea2bf326eb5f50306..16fda7e9acc851c17ba99616e5c677ecceb73e46 100644 (file)
@@ -1,11 +1,8 @@
-#ifndef _ASMSPARC_SHMPARAM_H
-#define _ASMSPARC_SHMPARAM_H
-
-#define __ARCH_FORCE_SHMLBA    1
-
-extern int vac_cache_size;
-#define SHMLBA (vac_cache_size ? vac_cache_size : \
-               (sparc_cpu_model == sun4c ? (64 * 1024) : \
-                (sparc_cpu_model == sun4 ? (128 * 1024) : PAGE_SIZE)))
-
-#endif /* _ASMSPARC_SHMPARAM_H */
+#ifndef ___ASM_SPARC_SHMPARAM_H
+#define ___ASM_SPARC_SHMPARAM_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/shmparam_64.h>
+#else
+#include <asm-sparc/shmparam_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/shmparam_32.h b/include/asm-sparc/shmparam_32.h
new file mode 100644 (file)
index 0000000..59a1243
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _ASMSPARC_SHMPARAM_H
+#define _ASMSPARC_SHMPARAM_H
+
+#define __ARCH_FORCE_SHMLBA    1
+
+extern int vac_cache_size;
+#define SHMLBA (vac_cache_size ? vac_cache_size : \
+               (sparc_cpu_model == sun4c ? (64 * 1024) : \
+                (sparc_cpu_model == sun4 ? (128 * 1024) : PAGE_SIZE)))
+
+#endif /* _ASMSPARC_SHMPARAM_H */
diff --git a/include/asm-sparc/shmparam_64.h b/include/asm-sparc/shmparam_64.h
new file mode 100644 (file)
index 0000000..1ed0d67
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _ASMSPARC64_SHMPARAM_H
+#define _ASMSPARC64_SHMPARAM_H
+
+#include <asm/spitfire.h>
+
+#define __ARCH_FORCE_SHMLBA    1
+/* attach addr a multiple of this */
+#define        SHMLBA  ((PAGE_SIZE > L1DCACHE_SIZE) ? PAGE_SIZE : L1DCACHE_SIZE)
+
+#endif /* _ASMSPARC64_SHMPARAM_H */
index c5fb60dcbd7533491664cda113baee427c503b9f..82fc7d54a4fa18a55af42944c99ed6fed0d18751 100644 (file)
@@ -1,62 +1,8 @@
-#ifndef __SPARC_SIGCONTEXT_H
-#define __SPARC_SIGCONTEXT_H
-
-#ifdef __KERNEL__
-#include <asm/ptrace.h>
-
-#ifndef __ASSEMBLY__
-
-#define __SUNOS_MAXWIN   31
-
-/* This is what SunOS does, so shall I. */
-struct sigcontext {
-       int sigc_onstack;      /* state to restore */
-       int sigc_mask;         /* sigmask to restore */
-       int sigc_sp;           /* stack pointer */
-       int sigc_pc;           /* program counter */
-       int sigc_npc;          /* next program counter */
-       int sigc_psr;          /* for condition codes etc */
-       int sigc_g1;           /* User uses these two registers */
-       int sigc_o0;           /* within the trampoline code. */
-
-       /* Now comes information regarding the users window set
-        * at the time of the signal.
-        */
-       int sigc_oswins;       /* outstanding windows */
-
-       /* stack ptrs for each regwin buf */
-       char *sigc_spbuf[__SUNOS_MAXWIN];
-
-       /* Windows to restore after signal */
-       struct {
-               unsigned long   locals[8];
-               unsigned long   ins[8];
-       } sigc_wbuf[__SUNOS_MAXWIN];
-};
-
-typedef struct {
-       struct {
-               unsigned long psr;
-               unsigned long pc;
-               unsigned long npc;
-               unsigned long y;
-               unsigned long u_regs[16]; /* globals and ins */
-       }               si_regs;
-       int             si_mask;
-} __siginfo_t;
-
-typedef struct {
-       unsigned   long si_float_regs [32];
-       unsigned   long si_fsr;
-       unsigned   long si_fpqdepth;
-       struct {
-               unsigned long *insn_addr;
-               unsigned long insn;
-       } si_fpqueue [16];
-} __siginfo_fpu_t;
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* (__KERNEL__) */
-
-#endif /* !(__SPARC_SIGCONTEXT_H) */
+#ifndef ___ASM_SPARC_SIGCONTEXT_H
+#define ___ASM_SPARC_SIGCONTEXT_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/sigcontext_64.h>
+#else
+#include <asm-sparc/sigcontext_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/sigcontext_32.h b/include/asm-sparc/sigcontext_32.h
new file mode 100644 (file)
index 0000000..c5fb60d
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef __SPARC_SIGCONTEXT_H
+#define __SPARC_SIGCONTEXT_H
+
+#ifdef __KERNEL__
+#include <asm/ptrace.h>
+
+#ifndef __ASSEMBLY__
+
+#define __SUNOS_MAXWIN   31
+
+/* This is what SunOS does, so shall I. */
+struct sigcontext {
+       int sigc_onstack;      /* state to restore */
+       int sigc_mask;         /* sigmask to restore */
+       int sigc_sp;           /* stack pointer */
+       int sigc_pc;           /* program counter */
+       int sigc_npc;          /* next program counter */
+       int sigc_psr;          /* for condition codes etc */
+       int sigc_g1;           /* User uses these two registers */
+       int sigc_o0;           /* within the trampoline code. */
+
+       /* Now comes information regarding the users window set
+        * at the time of the signal.
+        */
+       int sigc_oswins;       /* outstanding windows */
+
+       /* stack ptrs for each regwin buf */
+       char *sigc_spbuf[__SUNOS_MAXWIN];
+
+       /* Windows to restore after signal */
+       struct {
+               unsigned long   locals[8];
+               unsigned long   ins[8];
+       } sigc_wbuf[__SUNOS_MAXWIN];
+};
+
+typedef struct {
+       struct {
+               unsigned long psr;
+               unsigned long pc;
+               unsigned long npc;
+               unsigned long y;
+               unsigned long u_regs[16]; /* globals and ins */
+       }               si_regs;
+       int             si_mask;
+} __siginfo_t;
+
+typedef struct {
+       unsigned   long si_float_regs [32];
+       unsigned   long si_fsr;
+       unsigned   long si_fpqdepth;
+       struct {
+               unsigned long *insn_addr;
+               unsigned long insn;
+       } si_fpqueue [16];
+} __siginfo_fpu_t;
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* (__KERNEL__) */
+
+#endif /* !(__SPARC_SIGCONTEXT_H) */
diff --git a/include/asm-sparc/sigcontext_64.h b/include/asm-sparc/sigcontext_64.h
new file mode 100644 (file)
index 0000000..1c868d6
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef __SPARC64_SIGCONTEXT_H
+#define __SPARC64_SIGCONTEXT_H
+
+#ifdef __KERNEL__
+#include <asm/ptrace.h>
+#endif
+
+#ifndef __ASSEMBLY__
+
+#ifdef __KERNEL__
+
+#define __SUNOS_MAXWIN   31
+
+/* This is what SunOS does, so shall I unless we use new 32bit signals or rt signals. */
+struct sigcontext32 {
+       int sigc_onstack;      /* state to restore */
+       int sigc_mask;         /* sigmask to restore */
+       int sigc_sp;           /* stack pointer */
+       int sigc_pc;           /* program counter */
+       int sigc_npc;          /* next program counter */
+       int sigc_psr;          /* for condition codes etc */
+       int sigc_g1;           /* User uses these two registers */
+       int sigc_o0;           /* within the trampoline code. */
+
+       /* Now comes information regarding the users window set
+        * at the time of the signal.
+        */
+       int sigc_oswins;       /* outstanding windows */
+
+       /* stack ptrs for each regwin buf */
+       unsigned sigc_spbuf[__SUNOS_MAXWIN];
+
+       /* Windows to restore after signal */
+       struct reg_window32 sigc_wbuf[__SUNOS_MAXWIN];
+};
+
+#endif
+
+#ifdef __KERNEL__
+
+/* This is what we use for 32bit new non-rt signals. */
+
+typedef struct {
+       struct {
+               unsigned int psr;
+               unsigned int pc;
+               unsigned int npc;
+               unsigned int y;
+               unsigned int u_regs[16]; /* globals and ins */
+       }                       si_regs;
+       int                     si_mask;
+} __siginfo32_t;
+
+#endif
+
+typedef struct {
+       unsigned   int si_float_regs [64];
+       unsigned   long si_fsr;
+       unsigned   long si_gsr;
+       unsigned   long si_fprs;
+} __siginfo_fpu_t;
+
+/* This is what SunOS doesn't, so we have to write this alone
+   and do it properly. */
+struct sigcontext {
+       /* The size of this array has to match SI_MAX_SIZE from siginfo.h */
+       char                    sigc_info[128];
+       struct {
+               unsigned long   u_regs[16]; /* globals and ins */
+               unsigned long   tstate;
+               unsigned long   tpc;
+               unsigned long   tnpc;
+               unsigned int    y;
+               unsigned int    fprs;
+       }                       sigc_regs;
+       __siginfo_fpu_t *       sigc_fpu_save;
+       struct {
+               void    *       ss_sp;
+               int             ss_flags;
+               unsigned long   ss_size;
+       }                       sigc_stack;
+       unsigned long           sigc_mask;
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__SPARC64_SIGCONTEXT_H) */
index 3c71af135c52c187a719f54c086014088c23a2d9..2c9fccf4ce18f65bccf3becbb1e110cc79057cc3 100644 (file)
@@ -1,17 +1,8 @@
-#ifndef _SPARC_SIGINFO_H
-#define _SPARC_SIGINFO_H
-
-#define __ARCH_SI_UID_T                unsigned int
-#define __ARCH_SI_TRAPNO
-
-#include <asm-generic/siginfo.h>
-
-#define SI_NOINFO      32767           /* no information in siginfo_t */
-
-/*
- * SIGEMT si_codes
- */
-#define EMT_TAGOVF     (__SI_FAULT|1)  /* tag overflow */
-#define NSIGEMT                1
-
-#endif /* !(_SPARC_SIGINFO_H) */
+#ifndef ___ASM_SPARC_SIGINFO_H
+#define ___ASM_SPARC_SIGINFO_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/siginfo_64.h>
+#else
+#include <asm-sparc/siginfo_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/siginfo_32.h b/include/asm-sparc/siginfo_32.h
new file mode 100644 (file)
index 0000000..3c71af1
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _SPARC_SIGINFO_H
+#define _SPARC_SIGINFO_H
+
+#define __ARCH_SI_UID_T                unsigned int
+#define __ARCH_SI_TRAPNO
+
+#include <asm-generic/siginfo.h>
+
+#define SI_NOINFO      32767           /* no information in siginfo_t */
+
+/*
+ * SIGEMT si_codes
+ */
+#define EMT_TAGOVF     (__SI_FAULT|1)  /* tag overflow */
+#define NSIGEMT                1
+
+#endif /* !(_SPARC_SIGINFO_H) */
diff --git a/include/asm-sparc/siginfo_64.h b/include/asm-sparc/siginfo_64.h
new file mode 100644 (file)
index 0000000..c96e6c3
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _SPARC64_SIGINFO_H
+#define _SPARC64_SIGINFO_H
+
+#define SI_PAD_SIZE32  ((SI_MAX_SIZE/sizeof(int)) - 3)
+
+#define __ARCH_SI_PREAMBLE_SIZE        (4 * sizeof(int))
+#define __ARCH_SI_TRAPNO
+#define __ARCH_SI_BAND_T int
+
+#include <asm-generic/siginfo.h>
+
+#ifdef __KERNEL__
+
+#include <linux/compat.h>
+
+#ifdef CONFIG_COMPAT
+
+struct compat_siginfo;
+
+#endif /* CONFIG_COMPAT */
+
+#endif /* __KERNEL__ */
+
+#define SI_NOINFO      32767           /* no information in siginfo_t */
+
+/*
+ * SIGEMT si_codes
+ */
+#define EMT_TAGOVF     (__SI_FAULT|1)  /* tag overflow */
+#define NSIGEMT                1
+
+#endif
index 683657d6e685fb96640e4f5d9508a98a9daf1ac2..36f5f9e482f7240ad91f199d4468d114cadd8ac2 100644 (file)
@@ -1,207 +1,8 @@
-#ifndef _ASMSPARC_SIGNAL_H
-#define _ASMSPARC_SIGNAL_H
-
-#include <asm/sigcontext.h>
-#include <linux/compiler.h>
-
-#ifdef __KERNEL__
-#ifndef __ASSEMBLY__
-#include <linux/personality.h>
-#include <linux/types.h>
-#endif
-#endif
-
-/* On the Sparc the signal handlers get passed a 'sub-signal' code
- * for certain signal types, which we document here.
- */
-#define SIGHUP          1
-#define SIGINT          2
-#define SIGQUIT                 3
-#define SIGILL          4
-#define    SUBSIG_STACK       0
-#define    SUBSIG_ILLINST     2
-#define    SUBSIG_PRIVINST    3
-#define    SUBSIG_BADTRAP(t)  (0x80 + (t))
-
-#define SIGTRAP                 5
-#define SIGABRT                 6
-#define SIGIOT          6
-
-#define SIGEMT           7
-#define    SUBSIG_TAG    10
-
-#define SIGFPE          8
-#define    SUBSIG_FPDISABLED     0x400
-#define    SUBSIG_FPERROR        0x404
-#define    SUBSIG_FPINTOVFL      0x001
-#define    SUBSIG_FPSTSIG        0x002
-#define    SUBSIG_IDIVZERO       0x014
-#define    SUBSIG_FPINEXACT      0x0c4
-#define    SUBSIG_FPDIVZERO      0x0c8
-#define    SUBSIG_FPUNFLOW       0x0cc
-#define    SUBSIG_FPOPERROR      0x0d0
-#define    SUBSIG_FPOVFLOW       0x0d4
-
-#define SIGKILL                 9
-#define SIGBUS          10
-#define    SUBSIG_BUSTIMEOUT    1
-#define    SUBSIG_ALIGNMENT     2
-#define    SUBSIG_MISCERROR     5
-
-#define SIGSEGV                11
-#define    SUBSIG_NOMAPPING     3
-#define    SUBSIG_PROTECTION    4
-#define    SUBSIG_SEGERROR      5
-
-#define SIGSYS         12
-
-#define SIGPIPE                13
-#define SIGALRM                14
-#define SIGTERM                15
-#define SIGURG          16
-
-/* SunOS values which deviate from the Linux/i386 ones */
-#define SIGSTOP                17
-#define SIGTSTP                18
-#define SIGCONT                19
-#define SIGCHLD                20
-#define SIGTTIN                21
-#define SIGTTOU                22
-#define SIGIO          23
-#define SIGPOLL                SIGIO   /* SysV name for SIGIO */
-#define SIGXCPU                24
-#define SIGXFSZ                25
-#define SIGVTALRM      26
-#define SIGPROF                27
-#define SIGWINCH       28
-#define SIGLOST                29
-#define SIGPWR         SIGLOST
-#define SIGUSR1                30
-#define SIGUSR2                31
-
-/* Most things should be clean enough to redefine this at will, if care
- * is taken to make libc match.
- */
-
-#define __OLD_NSIG     32
-#define __NEW_NSIG     64
-#define _NSIG_BPW      32
-#define _NSIG_WORDS    (__NEW_NSIG / _NSIG_BPW)
-
-#define SIGRTMIN       32
-#define SIGRTMAX       __NEW_NSIG
-
-#if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
-#define        _NSIG           __NEW_NSIG
-#define __new_sigset_t sigset_t
-#define __new_sigaction        sigaction
-#define __old_sigset_t old_sigset_t
-#define __old_sigaction        old_sigaction
+#ifndef ___ASM_SPARC_SIGNAL_H
+#define ___ASM_SPARC_SIGNAL_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/signal_64.h>
 #else
-#define _NSIG          __OLD_NSIG
-#define __old_sigset_t sigset_t
-#define __old_sigaction        sigaction
-#endif
-
-#ifndef __ASSEMBLY__
-
-typedef unsigned long __old_sigset_t;
-
-typedef struct {
-       unsigned long   sig[_NSIG_WORDS];
-} __new_sigset_t;
-
-
-#ifdef __KERNEL__
-/* A SunOS sigstack */
-struct sigstack {
-       char *the_stack;
-       int   cur_status;
-};
+#include <asm-sparc/signal_32.h>
 #endif
-
-/* Sigvec flags */
-#define _SV_SSTACK    1u    /* This signal handler should use sig-stack */
-#define _SV_INTR      2u    /* Sig return should not restart system call */
-#define _SV_RESET     4u    /* Set handler to SIG_DFL upon taken signal */
-#define _SV_IGNCHILD  8u    /* Do not send SIGCHLD */
-
-/*
- * sa_flags values: SA_STACK is not currently supported, but will allow the
- * usage of signal stacks by using the (now obsolete) sa_restorer field in
- * the sigaction structure as a stack pointer. This is now possible due to
- * the changes in signal handling. LBT 010493.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- */
-#define SA_NOCLDSTOP   _SV_IGNCHILD
-#define SA_STACK       _SV_SSTACK
-#define SA_ONSTACK     _SV_SSTACK
-#define SA_RESTART     _SV_INTR
-#define SA_ONESHOT     _SV_RESET
-#define SA_NOMASK      0x20u
-#define SA_NOCLDWAIT   0x100u
-#define SA_SIGINFO     0x200u
-
-#define SIG_BLOCK          0x01        /* for blocking signals */
-#define SIG_UNBLOCK        0x02        /* for unblocking signals */
-#define SIG_SETMASK        0x04        /* for setting the signal mask */
-
-/* 
- * sigaltstack controls
- */
-#define SS_ONSTACK     1
-#define SS_DISABLE     2
-
-#define MINSIGSTKSZ    4096
-#define SIGSTKSZ       16384
-
-#ifdef __KERNEL__
-/*
- * DJHR
- * SA_STATIC_ALLOC is used for the SPARC system to indicate that this
- * interrupt handler's irq structure should be statically allocated
- * by the request_irq routine.
- * The alternative is that arch/sparc/kernel/irq.c has carnal knowledge
- * of interrupt usage and that sucks. Also without a flag like this
- * it may be possible for the free_irq routine to attempt to free
- * statically allocated data.. which is NOT GOOD.
- *
- */
-#define SA_STATIC_ALLOC                0x8000
 #endif
-
-#include <asm-generic/signal.h>
-
-#ifdef __KERNEL__
-struct __new_sigaction {
-       __sighandler_t  sa_handler;
-       unsigned long   sa_flags;
-       void            (*sa_restorer)(void);   /* Not used by Linux/SPARC */
-       __new_sigset_t  sa_mask;
-};
-
-struct k_sigaction {
-       struct __new_sigaction  sa;
-       void                    __user *ka_restorer;
-};
-
-struct __old_sigaction {
-       __sighandler_t  sa_handler;
-       __old_sigset_t  sa_mask;
-       unsigned long   sa_flags;
-       void            (*sa_restorer) (void);  /* not used by Linux/SPARC */
-};
-
-typedef struct sigaltstack {
-       void            __user *ss_sp;
-       int             ss_flags;
-       size_t          ss_size;
-} stack_t;
-
-#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-
-#endif /* !(__KERNEL__) */
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(_ASMSPARC_SIGNAL_H) */
diff --git a/include/asm-sparc/signal_32.h b/include/asm-sparc/signal_32.h
new file mode 100644 (file)
index 0000000..96a60ab
--- /dev/null
@@ -0,0 +1,207 @@
+#ifndef _ASMSPARC_SIGNAL_H
+#define _ASMSPARC_SIGNAL_H
+
+#include <asm/sigcontext.h>
+#include <linux/compiler.h>
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+#include <linux/personality.h>
+#include <linux/types.h>
+#endif
+#endif
+
+/* On the Sparc the signal handlers get passed a 'sub-signal' code
+ * for certain signal types, which we document here.
+ */
+#define SIGHUP          1
+#define SIGINT          2
+#define SIGQUIT                 3
+#define SIGILL          4
+#define    SUBSIG_STACK       0
+#define    SUBSIG_ILLINST     2
+#define    SUBSIG_PRIVINST    3
+#define    SUBSIG_BADTRAP(t)  (0x80 + (t))
+
+#define SIGTRAP                 5
+#define SIGABRT                 6
+#define SIGIOT          6
+
+#define SIGEMT           7
+#define    SUBSIG_TAG    10
+
+#define SIGFPE          8
+#define    SUBSIG_FPDISABLED     0x400
+#define    SUBSIG_FPERROR        0x404
+#define    SUBSIG_FPINTOVFL      0x001
+#define    SUBSIG_FPSTSIG        0x002
+#define    SUBSIG_IDIVZERO       0x014
+#define    SUBSIG_FPINEXACT      0x0c4
+#define    SUBSIG_FPDIVZERO      0x0c8
+#define    SUBSIG_FPUNFLOW       0x0cc
+#define    SUBSIG_FPOPERROR      0x0d0
+#define    SUBSIG_FPOVFLOW       0x0d4
+
+#define SIGKILL                 9
+#define SIGBUS          10
+#define    SUBSIG_BUSTIMEOUT    1
+#define    SUBSIG_ALIGNMENT     2
+#define    SUBSIG_MISCERROR     5
+
+#define SIGSEGV                11
+#define    SUBSIG_NOMAPPING     3
+#define    SUBSIG_PROTECTION    4
+#define    SUBSIG_SEGERROR      5
+
+#define SIGSYS         12
+
+#define SIGPIPE                13
+#define SIGALRM                14
+#define SIGTERM                15
+#define SIGURG          16
+
+/* SunOS values which deviate from the Linux/i386 ones */
+#define SIGSTOP                17
+#define SIGTSTP                18
+#define SIGCONT                19
+#define SIGCHLD                20
+#define SIGTTIN                21
+#define SIGTTOU                22
+#define SIGIO          23
+#define SIGPOLL                SIGIO   /* SysV name for SIGIO */
+#define SIGXCPU                24
+#define SIGXFSZ                25
+#define SIGVTALRM      26
+#define SIGPROF                27
+#define SIGWINCH       28
+#define SIGLOST                29
+#define SIGPWR         SIGLOST
+#define SIGUSR1                30
+#define SIGUSR2                31
+
+/* Most things should be clean enough to redefine this at will, if care
+ * is taken to make libc match.
+ */
+
+#define __OLD_NSIG     32
+#define __NEW_NSIG     64
+#define _NSIG_BPW      32
+#define _NSIG_WORDS    (__NEW_NSIG / _NSIG_BPW)
+
+#define SIGRTMIN       32
+#define SIGRTMAX       __NEW_NSIG
+
+#if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
+#define        _NSIG           __NEW_NSIG
+#define __new_sigset_t sigset_t
+#define __new_sigaction        sigaction
+#define __old_sigset_t old_sigset_t
+#define __old_sigaction        old_sigaction
+#else
+#define _NSIG          __OLD_NSIG
+#define __old_sigset_t sigset_t
+#define __old_sigaction        sigaction
+#endif
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long __old_sigset_t;
+
+typedef struct {
+       unsigned long   sig[_NSIG_WORDS];
+} __new_sigset_t;
+
+
+#ifdef __KERNEL__
+/* A SunOS sigstack */
+struct sigstack {
+       char *the_stack;
+       int   cur_status;
+};
+#endif
+
+/* Sigvec flags */
+#define _SV_SSTACK    1u    /* This signal handler should use sig-stack */
+#define _SV_INTR      2u    /* Sig return should not restart system call */
+#define _SV_RESET     4u    /* Set handler to SIG_DFL upon taken signal */
+#define _SV_IGNCHILD  8u    /* Do not send SIGCHLD */
+
+/*
+ * sa_flags values: SA_STACK is not currently supported, but will allow the
+ * usage of signal stacks by using the (now obsolete) sa_restorer field in
+ * the sigaction structure as a stack pointer. This is now possible due to
+ * the changes in signal handling. LBT 010493.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ */
+#define SA_NOCLDSTOP   _SV_IGNCHILD
+#define SA_STACK       _SV_SSTACK
+#define SA_ONSTACK     _SV_SSTACK
+#define SA_RESTART     _SV_INTR
+#define SA_ONESHOT     _SV_RESET
+#define SA_NOMASK      0x20u
+#define SA_NOCLDWAIT   0x100u
+#define SA_SIGINFO     0x200u
+
+#define SIG_BLOCK          0x01        /* for blocking signals */
+#define SIG_UNBLOCK        0x02        /* for unblocking signals */
+#define SIG_SETMASK        0x04        /* for setting the signal mask */
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK     1
+#define SS_DISABLE     2
+
+#define MINSIGSTKSZ    4096
+#define SIGSTKSZ       16384
+
+#ifdef __KERNEL__
+/*
+ * DJHR
+ * SA_STATIC_ALLOC is used for the SPARC system to indicate that this
+ * interrupt handler's irq structure should be statically allocated
+ * by the request_irq routine.
+ * The alternative is that arch/sparc/kernel/irq.c has carnal knowledge
+ * of interrupt usage and that sucks. Also without a flag like this
+ * it may be possible for the free_irq routine to attempt to free
+ * statically allocated data.. which is NOT GOOD.
+ *
+ */
+#define SA_STATIC_ALLOC                0x8000
+#endif
+
+#include <asm-generic/signal.h>
+
+#ifdef __KERNEL__
+struct __new_sigaction {
+       __sighandler_t  sa_handler;
+       unsigned long   sa_flags;
+       void            (*sa_restorer)(void);   /* Not used by Linux/SPARC */
+       __new_sigset_t  sa_mask;
+};
+
+struct k_sigaction {
+       struct __new_sigaction  sa;
+       void                    __user *ka_restorer;
+};
+
+struct __old_sigaction {
+       __sighandler_t  sa_handler;
+       __old_sigset_t  sa_mask;
+       unsigned long   sa_flags;
+       void            (*sa_restorer) (void);  /* not used by Linux/SPARC */
+};
+
+typedef struct sigaltstack {
+       void            __user *ss_sp;
+       int             ss_flags;
+       size_t          ss_size;
+} stack_t;
+
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#endif /* !(__KERNEL__) */
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_ASMSPARC_SIGNAL_H) */
diff --git a/include/asm-sparc/signal_64.h b/include/asm-sparc/signal_64.h
new file mode 100644 (file)
index 0000000..ab1509a
--- /dev/null
@@ -0,0 +1,194 @@
+#ifndef _ASMSPARC64_SIGNAL_H
+#define _ASMSPARC64_SIGNAL_H
+
+#include <asm/sigcontext.h>
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+#include <linux/personality.h>
+#include <linux/types.h>
+#endif
+#endif
+
+/* On the Sparc the signal handlers get passed a 'sub-signal' code
+ * for certain signal types, which we document here.
+ */
+#define SIGHUP          1
+#define SIGINT          2
+#define SIGQUIT                 3
+#define SIGILL          4
+#define    SUBSIG_STACK       0
+#define    SUBSIG_ILLINST     2
+#define    SUBSIG_PRIVINST    3
+#define    SUBSIG_BADTRAP(t)  (0x80 + (t))
+
+#define SIGTRAP                 5
+#define SIGABRT                 6
+#define SIGIOT          6
+
+#define SIGEMT           7
+#define    SUBSIG_TAG    10
+
+#define SIGFPE          8
+#define    SUBSIG_FPDISABLED     0x400
+#define    SUBSIG_FPERROR        0x404
+#define    SUBSIG_FPINTOVFL      0x001
+#define    SUBSIG_FPSTSIG        0x002
+#define    SUBSIG_IDIVZERO       0x014
+#define    SUBSIG_FPINEXACT      0x0c4
+#define    SUBSIG_FPDIVZERO      0x0c8
+#define    SUBSIG_FPUNFLOW       0x0cc
+#define    SUBSIG_FPOPERROR      0x0d0
+#define    SUBSIG_FPOVFLOW       0x0d4
+
+#define SIGKILL                 9
+#define SIGBUS          10
+#define    SUBSIG_BUSTIMEOUT    1
+#define    SUBSIG_ALIGNMENT     2
+#define    SUBSIG_MISCERROR     5
+
+#define SIGSEGV                11
+#define    SUBSIG_NOMAPPING     3
+#define    SUBSIG_PROTECTION    4
+#define    SUBSIG_SEGERROR      5
+
+#define SIGSYS         12
+
+#define SIGPIPE                13
+#define SIGALRM                14
+#define SIGTERM                15
+#define SIGURG          16
+
+/* SunOS values which deviate from the Linux/i386 ones */
+#define SIGSTOP                17
+#define SIGTSTP                18
+#define SIGCONT                19
+#define SIGCHLD                20
+#define SIGTTIN                21
+#define SIGTTOU                22
+#define SIGIO          23
+#define SIGPOLL                SIGIO   /* SysV name for SIGIO */
+#define SIGXCPU                24
+#define SIGXFSZ                25
+#define SIGVTALRM      26
+#define SIGPROF                27
+#define SIGWINCH       28
+#define SIGLOST                29
+#define SIGPWR         SIGLOST
+#define SIGUSR1                30
+#define SIGUSR2                31
+
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define __OLD_NSIG     32
+#define __NEW_NSIG      64
+#define _NSIG_BPW      64
+#define _NSIG_WORDS    (__NEW_NSIG / _NSIG_BPW)
+
+#define SIGRTMIN       32
+#define SIGRTMAX       __NEW_NSIG
+
+#if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
+#define _NSIG                  __NEW_NSIG
+#define __new_sigset_t         sigset_t
+#define __new_sigaction                sigaction
+#define __new_sigaction32      sigaction32
+#define __old_sigset_t         old_sigset_t
+#define __old_sigaction                old_sigaction
+#define __old_sigaction32      old_sigaction32
+#else
+#define _NSIG                  __OLD_NSIG
+#define NSIG                   _NSIG
+#define __old_sigset_t         sigset_t
+#define __old_sigaction                sigaction
+#define __old_sigaction32      sigaction32
+#endif
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long __old_sigset_t;            /* at least 32 bits */
+
+typedef struct {
+       unsigned long sig[_NSIG_WORDS];
+} __new_sigset_t;
+
+/* A SunOS sigstack */
+struct sigstack {
+       /* XXX 32-bit pointers pinhead XXX */
+       char *the_stack;
+       int   cur_status;
+};
+
+/* Sigvec flags */
+#define _SV_SSTACK    1u    /* This signal handler should use sig-stack */
+#define _SV_INTR      2u    /* Sig return should not restart system call */
+#define _SV_RESET     4u    /* Set handler to SIG_DFL upon taken signal */
+#define _SV_IGNCHILD  8u    /* Do not send SIGCHLD */
+
+/*
+ * sa_flags values: SA_STACK is not currently supported, but will allow the
+ * usage of signal stacks by using the (now obsolete) sa_restorer field in
+ * the sigaction structure as a stack pointer. This is now possible due to
+ * the changes in signal handling. LBT 010493.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ */
+#define SA_NOCLDSTOP   _SV_IGNCHILD
+#define SA_STACK       _SV_SSTACK
+#define SA_ONSTACK     _SV_SSTACK
+#define SA_RESTART     _SV_INTR
+#define SA_ONESHOT     _SV_RESET
+#define SA_NOMASK      0x20u
+#define SA_NOCLDWAIT    0x100u
+#define SA_SIGINFO      0x200u
+
+
+#define SIG_BLOCK          0x01        /* for blocking signals */
+#define SIG_UNBLOCK        0x02        /* for unblocking signals */
+#define SIG_SETMASK        0x04        /* for setting the signal mask */
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK     1
+#define SS_DISABLE     2
+
+#define MINSIGSTKSZ    4096
+#define SIGSTKSZ       16384
+
+#include <asm-generic/signal.h>
+
+struct __new_sigaction {
+       __sighandler_t          sa_handler;
+       unsigned long           sa_flags;
+       __sigrestore_t          sa_restorer;  /* not used by Linux/SPARC yet */
+       __new_sigset_t          sa_mask;
+};
+
+struct __old_sigaction {
+       __sighandler_t          sa_handler;
+       __old_sigset_t          sa_mask;
+       unsigned long           sa_flags;
+       void                    (*sa_restorer)(void);     /* not used by Linux/SPARC yet */
+};
+
+typedef struct sigaltstack {
+       void                    __user *ss_sp;
+       int                     ss_flags;
+       size_t                  ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+struct k_sigaction {
+       struct __new_sigaction  sa;
+       void __user             *ka_restorer;
+};
+
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#endif /* !(__KERNEL__) */
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_ASMSPARC64_SIGNAL_H) */
index b61e74bea06a9a7180c632ce83576d0af2719405..1f9dedfbabd816c0cbd8c2abb7d9d1f4e4c10e5c 100644 (file)
@@ -1,173 +1,8 @@
-/* smp.h: Sparc specific SMP stuff.
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef _SPARC_SMP_H
-#define _SPARC_SMP_H
-
-#include <linux/threads.h>
-#include <asm/head.h>
-#include <asm/btfixup.h>
-
-#ifndef __ASSEMBLY__
-
-#include <linux/cpumask.h>
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef CONFIG_SMP
-
-#ifndef __ASSEMBLY__
-
-#include <asm/ptrace.h>
-#include <asm/asi.h>
-#include <asm/atomic.h>
-
-/*
- *     Private routines/data
- */
-extern unsigned char boot_cpu_id;
-extern cpumask_t phys_cpu_present_map;
-#define cpu_possible_map phys_cpu_present_map
-
-typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long,
-                      unsigned long, unsigned long);
-
-/*
- *     General functions that each host system must provide.
- */
-void sun4m_init_smp(void);
-void sun4d_init_smp(void);
-
-void smp_callin(void);
-void smp_boot_cpus(void);
-void smp_store_cpu_info(int);
-
-struct seq_file;
-void smp_bogo(struct seq_file *);
-void smp_info(struct seq_file *);
-
-BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void)
-BTFIXUPDEF_BLACKBOX(hard_smp_processor_id)
-BTFIXUPDEF_BLACKBOX(load_current)
-
-#define smp_cross_call(func,arg1,arg2,arg3,arg4,arg5) BTFIXUP_CALL(smp_cross_call)(func,arg1,arg2,arg3,arg4,arg5)
-
-static inline void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); }
-static inline void xc1(smpfunc_t func, unsigned long arg1)
-{ smp_cross_call(func, arg1, 0, 0, 0, 0); }
-static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
-{ smp_cross_call(func, arg1, arg2, 0, 0, 0); }
-static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
-                          unsigned long arg3)
-{ smp_cross_call(func, arg1, arg2, arg3, 0, 0); }
-static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
-                          unsigned long arg3, unsigned long arg4)
-{ smp_cross_call(func, arg1, arg2, arg3, arg4, 0); }
-static inline void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2,
-                          unsigned long arg3, unsigned long arg4, unsigned long arg5)
-{ smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); }
-
-static inline int smp_call_function(void (*func)(void *info), void *info, int wait)
-{
-       xc1((smpfunc_t)func, (unsigned long)info);
-       return 0;
-}
-
-static inline int cpu_logical_map(int cpu)
-{
-       return cpu;
-}
-
-static inline int hard_smp4m_processor_id(void)
-{
-       int cpuid;
-
-       __asm__ __volatile__("rd %%tbr, %0\n\t"
-                            "srl %0, 12, %0\n\t"
-                            "and %0, 3, %0\n\t" :
-                            "=&r" (cpuid));
-       return cpuid;
-}
-
-static inline int hard_smp4d_processor_id(void)
-{
-       int cpuid;
-
-       __asm__ __volatile__("lda [%%g0] %1, %0\n\t" :
-                            "=&r" (cpuid) : "i" (ASI_M_VIKING_TMP1));
-       return cpuid;
-}
-
-#ifndef MODULE
-static inline int hard_smp_processor_id(void)
-{
-       int cpuid;
-
-       /* Black box - sun4m
-               __asm__ __volatile__("rd %%tbr, %0\n\t"
-                                    "srl %0, 12, %0\n\t"
-                                    "and %0, 3, %0\n\t" :
-                                    "=&r" (cpuid));
-                    - sun4d
-               __asm__ __volatile__("lda [%g0] ASI_M_VIKING_TMP1, %0\n\t"
-                                    "nop; nop" :
-                                    "=&r" (cpuid));
-          See btfixup.h and btfixupprep.c to understand how a blackbox works.
-        */
-       __asm__ __volatile__("sethi %%hi(___b_hard_smp_processor_id), %0\n\t"
-                            "sethi %%hi(boot_cpu_id), %0\n\t"
-                            "ldub [%0 + %%lo(boot_cpu_id)], %0\n\t" :
-                            "=&r" (cpuid));
-       return cpuid;
-}
+#ifndef ___ASM_SPARC_SMP_H
+#define ___ASM_SPARC_SMP_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/smp_64.h>
 #else
-static inline int hard_smp_processor_id(void)
-{
-       int cpuid;
-       
-       __asm__ __volatile__("mov %%o7, %%g1\n\t"
-                            "call ___f___hard_smp_processor_id\n\t"
-                            " nop\n\t"
-                            "mov %%g2, %0\n\t" : "=r"(cpuid) : : "g1", "g2");
-       return cpuid;
-}
+#include <asm-sparc/smp_32.h>
+#endif
 #endif
-
-#define raw_smp_processor_id()         (current_thread_info()->cpu)
-
-#define prof_multiplier(__cpu)         cpu_data(__cpu).multiplier
-#define prof_counter(__cpu)            cpu_data(__cpu).counter
-
-void smp_setup_cpu_possible_map(void);
-
-#endif /* !(__ASSEMBLY__) */
-
-/* Sparc specific messages. */
-#define MSG_CROSS_CALL         0x0005       /* run func on cpus */
-
-/* Empirical PROM processor mailbox constants.  If the per-cpu mailbox
- * contains something other than one of these then the ipi is from
- * Linux's active_kernel_processor.  This facility exists so that
- * the boot monitor can capture all the other cpus when one catches
- * a watchdog reset or the user enters the monitor using L1-A keys.
- */
-#define MBOX_STOPCPU          0xFB
-#define MBOX_IDLECPU          0xFC
-#define MBOX_IDLECPU2         0xFD
-#define MBOX_STOPCPU2         0xFE
-
-#else /* SMP */
-
-#define hard_smp_processor_id()                0
-#define smp_setup_cpu_possible_map() do { } while (0)
-
-#endif /* !(SMP) */
-
-#define NO_PROC_ID            0xFF
-
-#endif /* !(_SPARC_SMP_H) */
diff --git a/include/asm-sparc/smp_32.h b/include/asm-sparc/smp_32.h
new file mode 100644 (file)
index 0000000..7201752
--- /dev/null
@@ -0,0 +1,173 @@
+/* smp.h: Sparc specific SMP stuff.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC_SMP_H
+#define _SPARC_SMP_H
+
+#include <linux/threads.h>
+#include <asm/head.h>
+#include <asm/btfixup.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/cpumask.h>
+
+#endif /* __ASSEMBLY__ */
+
+#ifdef CONFIG_SMP
+
+#ifndef __ASSEMBLY__
+
+#include <asm/ptrace.h>
+#include <asm/asi.h>
+#include <asm/atomic.h>
+
+/*
+ *     Private routines/data
+ */
+
+extern unsigned char boot_cpu_id;
+extern cpumask_t phys_cpu_present_map;
+#define cpu_possible_map phys_cpu_present_map
+
+typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long,
+                      unsigned long, unsigned long);
+
+/*
+ *     General functions that each host system must provide.
+ */
+
+void sun4m_init_smp(void);
+void sun4d_init_smp(void);
+
+void smp_callin(void);
+void smp_boot_cpus(void);
+void smp_store_cpu_info(int);
+
+struct seq_file;
+void smp_bogo(struct seq_file *);
+void smp_info(struct seq_file *);
+
+BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
+BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void)
+BTFIXUPDEF_BLACKBOX(hard_smp_processor_id)
+BTFIXUPDEF_BLACKBOX(load_current)
+
+#define smp_cross_call(func,arg1,arg2,arg3,arg4,arg5) BTFIXUP_CALL(smp_cross_call)(func,arg1,arg2,arg3,arg4,arg5)
+
+static inline void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); }
+static inline void xc1(smpfunc_t func, unsigned long arg1)
+{ smp_cross_call(func, arg1, 0, 0, 0, 0); }
+static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
+{ smp_cross_call(func, arg1, arg2, 0, 0, 0); }
+static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+                          unsigned long arg3)
+{ smp_cross_call(func, arg1, arg2, arg3, 0, 0); }
+static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+                          unsigned long arg3, unsigned long arg4)
+{ smp_cross_call(func, arg1, arg2, arg3, arg4, 0); }
+static inline void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+                          unsigned long arg3, unsigned long arg4, unsigned long arg5)
+{ smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); }
+
+static inline int smp_call_function(void (*func)(void *info), void *info, int wait)
+{
+       xc1((smpfunc_t)func, (unsigned long)info);
+       return 0;
+}
+
+static inline int cpu_logical_map(int cpu)
+{
+       return cpu;
+}
+
+static inline int hard_smp4m_processor_id(void)
+{
+       int cpuid;
+
+       __asm__ __volatile__("rd %%tbr, %0\n\t"
+                            "srl %0, 12, %0\n\t"
+                            "and %0, 3, %0\n\t" :
+                            "=&r" (cpuid));
+       return cpuid;
+}
+
+static inline int hard_smp4d_processor_id(void)
+{
+       int cpuid;
+
+       __asm__ __volatile__("lda [%%g0] %1, %0\n\t" :
+                            "=&r" (cpuid) : "i" (ASI_M_VIKING_TMP1));
+       return cpuid;
+}
+
+#ifndef MODULE
+static inline int hard_smp_processor_id(void)
+{
+       int cpuid;
+
+       /* Black box - sun4m
+               __asm__ __volatile__("rd %%tbr, %0\n\t"
+                                    "srl %0, 12, %0\n\t"
+                                    "and %0, 3, %0\n\t" :
+                                    "=&r" (cpuid));
+                    - sun4d
+               __asm__ __volatile__("lda [%g0] ASI_M_VIKING_TMP1, %0\n\t"
+                                    "nop; nop" :
+                                    "=&r" (cpuid));
+          See btfixup.h and btfixupprep.c to understand how a blackbox works.
+        */
+       __asm__ __volatile__("sethi %%hi(___b_hard_smp_processor_id), %0\n\t"
+                            "sethi %%hi(boot_cpu_id), %0\n\t"
+                            "ldub [%0 + %%lo(boot_cpu_id)], %0\n\t" :
+                            "=&r" (cpuid));
+       return cpuid;
+}
+#else
+static inline int hard_smp_processor_id(void)
+{
+       int cpuid;
+
+       __asm__ __volatile__("mov %%o7, %%g1\n\t"
+                            "call ___f___hard_smp_processor_id\n\t"
+                            " nop\n\t"
+                            "mov %%g2, %0\n\t" : "=r"(cpuid) : : "g1", "g2");
+       return cpuid;
+}
+#endif
+
+#define raw_smp_processor_id()         (current_thread_info()->cpu)
+
+#define prof_multiplier(__cpu)         cpu_data(__cpu).multiplier
+#define prof_counter(__cpu)            cpu_data(__cpu).counter
+
+void smp_setup_cpu_possible_map(void);
+
+#endif /* !(__ASSEMBLY__) */
+
+/* Sparc specific messages. */
+#define MSG_CROSS_CALL         0x0005       /* run func on cpus */
+
+/* Empirical PROM processor mailbox constants.  If the per-cpu mailbox
+ * contains something other than one of these then the ipi is from
+ * Linux's active_kernel_processor.  This facility exists so that
+ * the boot monitor can capture all the other cpus when one catches
+ * a watchdog reset or the user enters the monitor using L1-A keys.
+ */
+#define MBOX_STOPCPU          0xFB
+#define MBOX_IDLECPU          0xFC
+#define MBOX_IDLECPU2         0xFD
+#define MBOX_STOPCPU2         0xFE
+
+#else /* SMP */
+
+#define hard_smp_processor_id()                0
+#define smp_setup_cpu_possible_map() do { } while (0)
+
+#endif /* !(SMP) */
+
+#define NO_PROC_ID            0xFF
+
+#endif /* !(_SPARC_SMP_H) */
diff --git a/include/asm-sparc/smp_64.h b/include/asm-sparc/smp_64.h
new file mode 100644 (file)
index 0000000..57224dd
--- /dev/null
@@ -0,0 +1,67 @@
+/* smp.h: Sparc64 specific SMP stuff.
+ *
+ * Copyright (C) 1996, 2008 David S. Miller (davem@davemloft.net)
+ */
+
+#ifndef _SPARC64_SMP_H
+#define _SPARC64_SMP_H
+
+#include <linux/threads.h>
+#include <asm/asi.h>
+#include <asm/starfire.h>
+#include <asm/spitfire.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/cpumask.h>
+#include <linux/cache.h>
+
+#endif /* !(__ASSEMBLY__) */
+
+#ifdef CONFIG_SMP
+
+#ifndef __ASSEMBLY__
+
+/*
+ *     Private routines/data
+ */
+
+#include <linux/bitops.h>
+#include <asm/atomic.h>
+#include <asm/percpu.h>
+
+DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
+extern cpumask_t cpu_core_map[NR_CPUS];
+extern int sparc64_multi_core;
+
+extern void arch_send_call_function_single_ipi(int cpu);
+extern void arch_send_call_function_ipi(cpumask_t mask);
+
+/*
+ *     General functions that each host system must provide.
+ */
+
+extern int hard_smp_processor_id(void);
+#define raw_smp_processor_id() (current_thread_info()->cpu)
+
+extern void smp_fill_in_sib_core_maps(void);
+extern void cpu_play_dead(void);
+
+extern void smp_fetch_global_regs(void);
+
+#ifdef CONFIG_HOTPLUG_CPU
+extern int __cpu_disable(void);
+extern void __cpu_die(unsigned int cpu);
+#endif
+
+#endif /* !(__ASSEMBLY__) */
+
+#else
+
+#define hard_smp_processor_id()                0
+#define smp_fill_in_sib_core_maps() do { } while (0)
+#define smp_fetch_global_regs() do { } while (0)
+
+#endif /* !(CONFIG_SMP) */
+
+#endif /* !(_SPARC64_SMP_H) */
diff --git a/include/asm-sparc/sparsemem.h b/include/asm-sparc/sparsemem.h
new file mode 100644 (file)
index 0000000..b99d4e4
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _SPARC64_SPARSEMEM_H
+#define _SPARC64_SPARSEMEM_H
+
+#ifdef __KERNEL__
+
+#define SECTION_SIZE_BITS       30
+#define MAX_PHYSADDR_BITS       42
+#define MAX_PHYSMEM_BITS        42
+
+#endif /* !(__KERNEL__) */
+
+#endif /* !(_SPARC64_SPARSEMEM_H) */
index de2249b267c626bd0066a986afc2d910327a3dce..3b71c50b72eb10c615dc6cd3ba481433bb5352c2 100644 (file)
@@ -1,192 +1,8 @@
-/* spinlock.h: 32-bit Sparc spinlock support.
- *
- * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef __SPARC_SPINLOCK_H
-#define __SPARC_SPINLOCK_H
-
-#include <linux/threads.h>     /* For NR_CPUS */
-
-#ifndef __ASSEMBLY__
-
-#include <asm/psr.h>
-
-#define __raw_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0)
-
-#define __raw_spin_unlock_wait(lock) \
-       do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
-
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
-{
-       __asm__ __volatile__(
-       "\n1:\n\t"
-       "ldstub [%0], %%g2\n\t"
-       "orcc   %%g2, 0x0, %%g0\n\t"
-       "bne,a  2f\n\t"
-       " ldub  [%0], %%g2\n\t"
-       ".subsection    2\n"
-       "2:\n\t"
-       "orcc   %%g2, 0x0, %%g0\n\t"
-       "bne,a  2b\n\t"
-       " ldub  [%0], %%g2\n\t"
-       "b,a    1b\n\t"
-       ".previous\n"
-       : /* no outputs */
-       : "r" (lock)
-       : "g2", "memory", "cc");
-}
-
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
-{
-       unsigned int result;
-       __asm__ __volatile__("ldstub [%1], %0"
-                            : "=r" (result)
-                            : "r" (lock)
-                            : "memory");
-       return (result == 0);
-}
-
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
-{
-       __asm__ __volatile__("stb %%g0, [%0]" : : "r" (lock) : "memory");
-}
-
-/* Read-write spinlocks, allowing multiple readers
- * but only one writer.
- *
- * NOTE! it is quite common to have readers in interrupts
- * but no interrupt writers. For those circumstances we
- * can "mix" irq-safe locks - any writer needs to get a
- * irq-safe write-lock, but readers can get non-irqsafe
- * read-locks.
- *
- * XXX This might create some problems with my dual spinlock
- * XXX scheme, deadlocks etc. -DaveM
- *
- * Sort of like atomic_t's on Sparc, but even more clever.
- *
- *     ------------------------------------
- *     | 24-bit counter           | wlock |  raw_rwlock_t
- *     ------------------------------------
- *      31                       8 7     0
- *
- * wlock signifies the one writer is in or somebody is updating
- * counter. For a writer, if he successfully acquires the wlock,
- * but counter is non-zero, he has to release the lock and wait,
- * till both counter and wlock are zero.
- *
- * Unfortunately this scheme limits us to ~16,000,000 cpus.
- */
-static inline void __read_lock(raw_rwlock_t *rw)
-{
-       register raw_rwlock_t *lp asm("g1");
-       lp = rw;
-       __asm__ __volatile__(
-       "mov    %%o7, %%g4\n\t"
-       "call   ___rw_read_enter\n\t"
-       " ldstub        [%%g1 + 3], %%g2\n"
-       : /* no outputs */
-       : "r" (lp)
-       : "g2", "g4", "memory", "cc");
-}
-
-#define __raw_read_lock(lock) \
-do {   unsigned long flags; \
-       local_irq_save(flags); \
-       __read_lock(lock); \
-       local_irq_restore(flags); \
-} while(0)
-
-static inline void __read_unlock(raw_rwlock_t *rw)
-{
-       register raw_rwlock_t *lp asm("g1");
-       lp = rw;
-       __asm__ __volatile__(
-       "mov    %%o7, %%g4\n\t"
-       "call   ___rw_read_exit\n\t"
-       " ldstub        [%%g1 + 3], %%g2\n"
-       : /* no outputs */
-       : "r" (lp)
-       : "g2", "g4", "memory", "cc");
-}
-
-#define __raw_read_unlock(lock) \
-do {   unsigned long flags; \
-       local_irq_save(flags); \
-       __read_unlock(lock); \
-       local_irq_restore(flags); \
-} while(0)
-
-static inline void __raw_write_lock(raw_rwlock_t *rw)
-{
-       register raw_rwlock_t *lp asm("g1");
-       lp = rw;
-       __asm__ __volatile__(
-       "mov    %%o7, %%g4\n\t"
-       "call   ___rw_write_enter\n\t"
-       " ldstub        [%%g1 + 3], %%g2\n"
-       : /* no outputs */
-       : "r" (lp)
-       : "g2", "g4", "memory", "cc");
-       *(volatile __u32 *)&lp->lock = ~0U;
-}
-
-static inline int __raw_write_trylock(raw_rwlock_t *rw)
-{
-       unsigned int val;
-
-       __asm__ __volatile__("ldstub [%1 + 3], %0"
-                            : "=r" (val)
-                            : "r" (&rw->lock)
-                            : "memory");
-
-       if (val == 0) {
-               val = rw->lock & ~0xff;
-               if (val)
-                       ((volatile u8*)&rw->lock)[3] = 0;
-               else
-                       *(volatile u32*)&rw->lock = ~0U;
-       }
-
-       return (val == 0);
-}
-
-static inline int __read_trylock(raw_rwlock_t *rw)
-{
-       register raw_rwlock_t *lp asm("g1");
-       register int res asm("o0");
-       lp = rw;
-       __asm__ __volatile__(
-       "mov    %%o7, %%g4\n\t"
-       "call   ___rw_read_try\n\t"
-       " ldstub        [%%g1 + 3], %%g2\n"
-       : "=r" (res)
-       : "r" (lp)
-       : "g2", "g4", "memory", "cc");
-       return res;
-}
-
-#define __raw_read_trylock(lock) \
-({     unsigned long flags; \
-       int res; \
-       local_irq_save(flags); \
-       res = __read_trylock(lock); \
-       local_irq_restore(flags); \
-       res; \
-})
-
-#define __raw_write_unlock(rw) do { (rw)->lock = 0; } while(0)
-
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-
-#define _raw_spin_relax(lock)  cpu_relax()
-#define _raw_read_relax(lock)  cpu_relax()
-#define _raw_write_relax(lock) cpu_relax()
-
-#define __raw_read_can_lock(rw) (!((rw)->lock & 0xff))
-#define __raw_write_can_lock(rw) (!(rw)->lock)
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* __SPARC_SPINLOCK_H */
+#ifndef ___ASM_SPARC_SPINLOCK_H
+#define ___ASM_SPARC_SPINLOCK_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/spinlock_64.h>
+#else
+#include <asm-sparc/spinlock_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/spinlock_32.h b/include/asm-sparc/spinlock_32.h
new file mode 100644 (file)
index 0000000..de2249b
--- /dev/null
@@ -0,0 +1,192 @@
+/* spinlock.h: 32-bit Sparc spinlock support.
+ *
+ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __SPARC_SPINLOCK_H
+#define __SPARC_SPINLOCK_H
+
+#include <linux/threads.h>     /* For NR_CPUS */
+
+#ifndef __ASSEMBLY__
+
+#include <asm/psr.h>
+
+#define __raw_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0)
+
+#define __raw_spin_unlock_wait(lock) \
+       do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
+
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
+{
+       __asm__ __volatile__(
+       "\n1:\n\t"
+       "ldstub [%0], %%g2\n\t"
+       "orcc   %%g2, 0x0, %%g0\n\t"
+       "bne,a  2f\n\t"
+       " ldub  [%0], %%g2\n\t"
+       ".subsection    2\n"
+       "2:\n\t"
+       "orcc   %%g2, 0x0, %%g0\n\t"
+       "bne,a  2b\n\t"
+       " ldub  [%0], %%g2\n\t"
+       "b,a    1b\n\t"
+       ".previous\n"
+       : /* no outputs */
+       : "r" (lock)
+       : "g2", "memory", "cc");
+}
+
+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+{
+       unsigned int result;
+       __asm__ __volatile__("ldstub [%1], %0"
+                            : "=r" (result)
+                            : "r" (lock)
+                            : "memory");
+       return (result == 0);
+}
+
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+{
+       __asm__ __volatile__("stb %%g0, [%0]" : : "r" (lock) : "memory");
+}
+
+/* Read-write spinlocks, allowing multiple readers
+ * but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts
+ * but no interrupt writers. For those circumstances we
+ * can "mix" irq-safe locks - any writer needs to get a
+ * irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ *
+ * XXX This might create some problems with my dual spinlock
+ * XXX scheme, deadlocks etc. -DaveM
+ *
+ * Sort of like atomic_t's on Sparc, but even more clever.
+ *
+ *     ------------------------------------
+ *     | 24-bit counter           | wlock |  raw_rwlock_t
+ *     ------------------------------------
+ *      31                       8 7     0
+ *
+ * wlock signifies the one writer is in or somebody is updating
+ * counter. For a writer, if he successfully acquires the wlock,
+ * but counter is non-zero, he has to release the lock and wait,
+ * till both counter and wlock are zero.
+ *
+ * Unfortunately this scheme limits us to ~16,000,000 cpus.
+ */
+static inline void __read_lock(raw_rwlock_t *rw)
+{
+       register raw_rwlock_t *lp asm("g1");
+       lp = rw;
+       __asm__ __volatile__(
+       "mov    %%o7, %%g4\n\t"
+       "call   ___rw_read_enter\n\t"
+       " ldstub        [%%g1 + 3], %%g2\n"
+       : /* no outputs */
+       : "r" (lp)
+       : "g2", "g4", "memory", "cc");
+}
+
+#define __raw_read_lock(lock) \
+do {   unsigned long flags; \
+       local_irq_save(flags); \
+       __read_lock(lock); \
+       local_irq_restore(flags); \
+} while(0)
+
+static inline void __read_unlock(raw_rwlock_t *rw)
+{
+       register raw_rwlock_t *lp asm("g1");
+       lp = rw;
+       __asm__ __volatile__(
+       "mov    %%o7, %%g4\n\t"
+       "call   ___rw_read_exit\n\t"
+       " ldstub        [%%g1 + 3], %%g2\n"
+       : /* no outputs */
+       : "r" (lp)
+       : "g2", "g4", "memory", "cc");
+}
+
+#define __raw_read_unlock(lock) \
+do {   unsigned long flags; \
+       local_irq_save(flags); \
+       __read_unlock(lock); \
+       local_irq_restore(flags); \
+} while(0)
+
+static inline void __raw_write_lock(raw_rwlock_t *rw)
+{
+       register raw_rwlock_t *lp asm("g1");
+       lp = rw;
+       __asm__ __volatile__(
+       "mov    %%o7, %%g4\n\t"
+       "call   ___rw_write_enter\n\t"
+       " ldstub        [%%g1 + 3], %%g2\n"
+       : /* no outputs */
+       : "r" (lp)
+       : "g2", "g4", "memory", "cc");
+       *(volatile __u32 *)&lp->lock = ~0U;
+}
+
+static inline int __raw_write_trylock(raw_rwlock_t *rw)
+{
+       unsigned int val;
+
+       __asm__ __volatile__("ldstub [%1 + 3], %0"
+                            : "=r" (val)
+                            : "r" (&rw->lock)
+                            : "memory");
+
+       if (val == 0) {
+               val = rw->lock & ~0xff;
+               if (val)
+                       ((volatile u8*)&rw->lock)[3] = 0;
+               else
+                       *(volatile u32*)&rw->lock = ~0U;
+       }
+
+       return (val == 0);
+}
+
+static inline int __read_trylock(raw_rwlock_t *rw)
+{
+       register raw_rwlock_t *lp asm("g1");
+       register int res asm("o0");
+       lp = rw;
+       __asm__ __volatile__(
+       "mov    %%o7, %%g4\n\t"
+       "call   ___rw_read_try\n\t"
+       " ldstub        [%%g1 + 3], %%g2\n"
+       : "=r" (res)
+       : "r" (lp)
+       : "g2", "g4", "memory", "cc");
+       return res;
+}
+
+#define __raw_read_trylock(lock) \
+({     unsigned long flags; \
+       int res; \
+       local_irq_save(flags); \
+       res = __read_trylock(lock); \
+       local_irq_restore(flags); \
+       res; \
+})
+
+#define __raw_write_unlock(rw) do { (rw)->lock = 0; } while(0)
+
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+
+#define _raw_spin_relax(lock)  cpu_relax()
+#define _raw_read_relax(lock)  cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
+#define __raw_read_can_lock(rw) (!((rw)->lock & 0xff))
+#define __raw_write_can_lock(rw) (!(rw)->lock)
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* __SPARC_SPINLOCK_H */
diff --git a/include/asm-sparc/spinlock_64.h b/include/asm-sparc/spinlock_64.h
new file mode 100644 (file)
index 0000000..0006fe9
--- /dev/null
@@ -0,0 +1,250 @@
+/* spinlock.h: 64-bit Sparc spinlock support.
+ *
+ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __SPARC64_SPINLOCK_H
+#define __SPARC64_SPINLOCK_H
+
+#include <linux/threads.h>     /* For NR_CPUS */
+
+#ifndef __ASSEMBLY__
+
+/* To get debugging spinlocks which detect and catch
+ * deadlock situations, set CONFIG_DEBUG_SPINLOCK
+ * and rebuild your kernel.
+ */
+
+/* All of these locking primitives are expected to work properly
+ * even in an RMO memory model, which currently is what the kernel
+ * runs in.
+ *
+ * There is another issue.  Because we play games to save cycles
+ * in the non-contention case, we need to be extra careful about
+ * branch targets into the "spinning" code.  They live in their
+ * own section, but the newer V9 branches have a shorter range
+ * than the traditional 32-bit sparc branch variants.  The rule
+ * is that the branches that go into and out of the spinner sections
+ * must be pre-V9 branches.
+ */
+
+#define __raw_spin_is_locked(lp)       ((lp)->lock != 0)
+
+#define __raw_spin_unlock_wait(lp)     \
+       do {    rmb();                  \
+       } while((lp)->lock)
+
+static inline void __raw_spin_lock(raw_spinlock_t *lock)
+{
+       unsigned long tmp;
+
+       __asm__ __volatile__(
+"1:    ldstub          [%1], %0\n"
+"      membar          #StoreLoad | #StoreStore\n"
+"      brnz,pn         %0, 2f\n"
+"       nop\n"
+"      .subsection     2\n"
+"2:    ldub            [%1], %0\n"
+"      membar          #LoadLoad\n"
+"      brnz,pt         %0, 2b\n"
+"       nop\n"
+"      ba,a,pt         %%xcc, 1b\n"
+"      .previous"
+       : "=&r" (tmp)
+       : "r" (lock)
+       : "memory");
+}
+
+static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+{
+       unsigned long result;
+
+       __asm__ __volatile__(
+"      ldstub          [%1], %0\n"
+"      membar          #StoreLoad | #StoreStore"
+       : "=r" (result)
+       : "r" (lock)
+       : "memory");
+
+       return (result == 0UL);
+}
+
+static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+{
+       __asm__ __volatile__(
+"      membar          #StoreStore | #LoadStore\n"
+"      stb             %%g0, [%0]"
+       : /* No outputs */
+       : "r" (lock)
+       : "memory");
+}
+
+static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
+{
+       unsigned long tmp1, tmp2;
+
+       __asm__ __volatile__(
+"1:    ldstub          [%2], %0\n"
+"      membar          #StoreLoad | #StoreStore\n"
+"      brnz,pn         %0, 2f\n"
+"       nop\n"
+"      .subsection     2\n"
+"2:    rdpr            %%pil, %1\n"
+"      wrpr            %3, %%pil\n"
+"3:    ldub            [%2], %0\n"
+"      membar          #LoadLoad\n"
+"      brnz,pt         %0, 3b\n"
+"       nop\n"
+"      ba,pt           %%xcc, 1b\n"
+"       wrpr           %1, %%pil\n"
+"      .previous"
+       : "=&r" (tmp1), "=&r" (tmp2)
+       : "r"(lock), "r"(flags)
+       : "memory");
+}
+
+/* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */
+
+static void inline __read_lock(raw_rwlock_t *lock)
+{
+       unsigned long tmp1, tmp2;
+
+       __asm__ __volatile__ (
+"1:    ldsw            [%2], %0\n"
+"      brlz,pn         %0, 2f\n"
+"4:     add            %0, 1, %1\n"
+"      cas             [%2], %0, %1\n"
+"      cmp             %0, %1\n"
+"      membar          #StoreLoad | #StoreStore\n"
+"      bne,pn          %%icc, 1b\n"
+"       nop\n"
+"      .subsection     2\n"
+"2:    ldsw            [%2], %0\n"
+"      membar          #LoadLoad\n"
+"      brlz,pt         %0, 2b\n"
+"       nop\n"
+"      ba,a,pt         %%xcc, 4b\n"
+"      .previous"
+       : "=&r" (tmp1), "=&r" (tmp2)
+       : "r" (lock)
+       : "memory");
+}
+
+static int inline __read_trylock(raw_rwlock_t *lock)
+{
+       int tmp1, tmp2;
+
+       __asm__ __volatile__ (
+"1:    ldsw            [%2], %0\n"
+"      brlz,a,pn       %0, 2f\n"
+"       mov            0, %0\n"
+"      add             %0, 1, %1\n"
+"      cas             [%2], %0, %1\n"
+"      cmp             %0, %1\n"
+"      membar          #StoreLoad | #StoreStore\n"
+"      bne,pn          %%icc, 1b\n"
+"       mov            1, %0\n"
+"2:"
+       : "=&r" (tmp1), "=&r" (tmp2)
+       : "r" (lock)
+       : "memory");
+
+       return tmp1;
+}
+
+static void inline __read_unlock(raw_rwlock_t *lock)
+{
+       unsigned long tmp1, tmp2;
+
+       __asm__ __volatile__(
+"      membar  #StoreLoad | #LoadLoad\n"
+"1:    lduw    [%2], %0\n"
+"      sub     %0, 1, %1\n"
+"      cas     [%2], %0, %1\n"
+"      cmp     %0, %1\n"
+"      bne,pn  %%xcc, 1b\n"
+"       nop"
+       : "=&r" (tmp1), "=&r" (tmp2)
+       : "r" (lock)
+       : "memory");
+}
+
+static void inline __write_lock(raw_rwlock_t *lock)
+{
+       unsigned long mask, tmp1, tmp2;
+
+       mask = 0x80000000UL;
+
+       __asm__ __volatile__(
+"1:    lduw            [%2], %0\n"
+"      brnz,pn         %0, 2f\n"
+"4:     or             %0, %3, %1\n"
+"      cas             [%2], %0, %1\n"
+"      cmp             %0, %1\n"
+"      membar          #StoreLoad | #StoreStore\n"
+"      bne,pn          %%icc, 1b\n"
+"       nop\n"
+"      .subsection     2\n"
+"2:    lduw            [%2], %0\n"
+"      membar          #LoadLoad\n"
+"      brnz,pt         %0, 2b\n"
+"       nop\n"
+"      ba,a,pt         %%xcc, 4b\n"
+"      .previous"
+       : "=&r" (tmp1), "=&r" (tmp2)
+       : "r" (lock), "r" (mask)
+       : "memory");
+}
+
+static void inline __write_unlock(raw_rwlock_t *lock)
+{
+       __asm__ __volatile__(
+"      membar          #LoadStore | #StoreStore\n"
+"      stw             %%g0, [%0]"
+       : /* no outputs */
+       : "r" (lock)
+       : "memory");
+}
+
+static int inline __write_trylock(raw_rwlock_t *lock)
+{
+       unsigned long mask, tmp1, tmp2, result;
+
+       mask = 0x80000000UL;
+
+       __asm__ __volatile__(
+"      mov             0, %2\n"
+"1:    lduw            [%3], %0\n"
+"      brnz,pn         %0, 2f\n"
+"       or             %0, %4, %1\n"
+"      cas             [%3], %0, %1\n"
+"      cmp             %0, %1\n"
+"      membar          #StoreLoad | #StoreStore\n"
+"      bne,pn          %%icc, 1b\n"
+"       nop\n"
+"      mov             1, %2\n"
+"2:"
+       : "=&r" (tmp1), "=&r" (tmp2), "=&r" (result)
+       : "r" (lock), "r" (mask)
+       : "memory");
+
+       return result;
+}
+
+#define __raw_read_lock(p)     __read_lock(p)
+#define __raw_read_trylock(p)  __read_trylock(p)
+#define __raw_read_unlock(p)   __read_unlock(p)
+#define __raw_write_lock(p)    __write_lock(p)
+#define __raw_write_unlock(p)  __write_unlock(p)
+#define __raw_write_trylock(p) __write_trylock(p)
+
+#define __raw_read_can_lock(rw)                (!((rw)->lock & 0x80000000UL))
+#define __raw_write_can_lock(rw)       (!(rw)->lock)
+
+#define _raw_spin_relax(lock)  cpu_relax()
+#define _raw_read_relax(lock)  cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__SPARC64_SPINLOCK_H) */
index 0a0fb116c4ec360ea736f4029a8bdea9450d71fa..37cbe01c585b5c9e91bdab7c013946bf11b87e65 100644 (file)
@@ -6,7 +6,7 @@
 #endif
 
 typedef struct {
-       unsigned char lock;
+       volatile unsigned char lock;
 } raw_spinlock_t;
 
 #define __RAW_SPIN_LOCK_UNLOCKED       { 0 }
diff --git a/include/asm-sparc/spitfire.h b/include/asm-sparc/spitfire.h
new file mode 100644 (file)
index 0000000..985ea7e
--- /dev/null
@@ -0,0 +1,342 @@
+/* spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ */
+
+#ifndef _SPARC64_SPITFIRE_H
+#define _SPARC64_SPITFIRE_H
+
+#include <asm/asi.h>
+
+/* The following register addresses are accessible via ASI_DMMU
+ * and ASI_IMMU, that is there is a distinct and unique copy of
+ * each these registers for each TLB.
+ */
+#define TSB_TAG_TARGET         0x0000000000000000 /* All chips                         */
+#define TLB_SFSR               0x0000000000000018 /* All chips                         */
+#define TSB_REG                        0x0000000000000028 /* All chips                         */
+#define TLB_TAG_ACCESS         0x0000000000000030 /* All chips                         */
+#define VIRT_WATCHPOINT                0x0000000000000038 /* All chips                         */
+#define PHYS_WATCHPOINT                0x0000000000000040 /* All chips                         */
+#define TSB_EXTENSION_P                0x0000000000000048 /* Ultra-III and later               */
+#define TSB_EXTENSION_S                0x0000000000000050 /* Ultra-III and later, D-TLB only   */
+#define TSB_EXTENSION_N                0x0000000000000058 /* Ultra-III and later               */
+#define TLB_TAG_ACCESS_EXT     0x0000000000000060 /* Ultra-III+ and later              */
+
+/* These registers only exist as one entity, and are accessed
+ * via ASI_DMMU only.
+ */
+#define PRIMARY_CONTEXT                0x0000000000000008
+#define SECONDARY_CONTEXT      0x0000000000000010
+#define DMMU_SFAR              0x0000000000000020
+#define VIRT_WATCHPOINT                0x0000000000000038
+#define PHYS_WATCHPOINT                0x0000000000000040
+
+#define SPITFIRE_HIGHEST_LOCKED_TLBENT (64 - 1)
+#define CHEETAH_HIGHEST_LOCKED_TLBENT  (16 - 1)
+
+#define L1DCACHE_SIZE          0x4000
+
+#define SUN4V_CHIP_INVALID     0x00
+#define SUN4V_CHIP_NIAGARA1    0x01
+#define SUN4V_CHIP_NIAGARA2    0x02
+#define SUN4V_CHIP_UNKNOWN     0xff
+
+#ifndef __ASSEMBLY__
+
+enum ultra_tlb_layout {
+       spitfire = 0,
+       cheetah = 1,
+       cheetah_plus = 2,
+       hypervisor = 3,
+};
+
+extern enum ultra_tlb_layout tlb_type;
+
+extern int sun4v_chip_type;
+
+extern int cheetah_pcache_forced_on;
+extern void cheetah_enable_pcache(void);
+
+#define sparc64_highest_locked_tlbent()        \
+       (tlb_type == spitfire ? \
+        SPITFIRE_HIGHEST_LOCKED_TLBENT : \
+        CHEETAH_HIGHEST_LOCKED_TLBENT)
+
+extern int num_kernel_image_mappings;
+
+/* The data cache is write through, so this just invalidates the
+ * specified line.
+ */
+static inline void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
+                            "membar    #Sync"
+                            : /* No outputs */
+                            : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG));
+}
+
+/* The instruction cache lines are flushed with this, but note that
+ * this does not flush the pipeline.  It is possible for a line to
+ * get flushed but stale instructions to still be in the pipeline,
+ * a flush instruction (to any address) is sufficient to handle
+ * this issue after the line is invalidated.
+ */
+static inline void spitfire_put_icache_tag(unsigned long addr, unsigned long tag)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
+                            "membar    #Sync"
+                            : /* No outputs */
+                            : "r" (tag), "r" (addr), "i" (ASI_IC_TAG));
+}
+
+static inline unsigned long spitfire_get_dtlb_data(int entry)
+{
+       unsigned long data;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %0"
+                            : "=r" (data)
+                            : "r" (entry << 3), "i" (ASI_DTLB_DATA_ACCESS));
+
+       /* Clear TTE diag bits. */
+       data &= ~0x0003fe0000000000UL;
+
+       return data;
+}
+
+static inline unsigned long spitfire_get_dtlb_tag(int entry)
+{
+       unsigned long tag;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %0"
+                            : "=r" (tag)
+                            : "r" (entry << 3), "i" (ASI_DTLB_TAG_READ));
+       return tag;
+}
+
+static inline void spitfire_put_dtlb_data(int entry, unsigned long data)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
+                            "membar    #Sync"
+                            : /* No outputs */
+                            : "r" (data), "r" (entry << 3),
+                              "i" (ASI_DTLB_DATA_ACCESS));
+}
+
+static inline unsigned long spitfire_get_itlb_data(int entry)
+{
+       unsigned long data;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %0"
+                            : "=r" (data)
+                            : "r" (entry << 3), "i" (ASI_ITLB_DATA_ACCESS));
+
+       /* Clear TTE diag bits. */
+       data &= ~0x0003fe0000000000UL;
+
+       return data;
+}
+
+static inline unsigned long spitfire_get_itlb_tag(int entry)
+{
+       unsigned long tag;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %0"
+                            : "=r" (tag)
+                            : "r" (entry << 3), "i" (ASI_ITLB_TAG_READ));
+       return tag;
+}
+
+static inline void spitfire_put_itlb_data(int entry, unsigned long data)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
+                            "membar    #Sync"
+                            : /* No outputs */
+                            : "r" (data), "r" (entry << 3),
+                              "i" (ASI_ITLB_DATA_ACCESS));
+}
+
+static inline void spitfire_flush_dtlb_nucleus_page(unsigned long page)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1\n\t"
+                            "membar    #Sync"
+                            : /* No outputs */
+                            : "r" (page | 0x20), "i" (ASI_DMMU_DEMAP));
+}
+
+static inline void spitfire_flush_itlb_nucleus_page(unsigned long page)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1\n\t"
+                            "membar    #Sync"
+                            : /* No outputs */
+                            : "r" (page | 0x20), "i" (ASI_IMMU_DEMAP));
+}
+
+/* Cheetah has "all non-locked" tlb flushes. */
+static inline void cheetah_flush_dtlb_all(void)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1\n\t"
+                            "membar    #Sync"
+                            : /* No outputs */
+                            : "r" (0x80), "i" (ASI_DMMU_DEMAP));
+}
+
+static inline void cheetah_flush_itlb_all(void)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1\n\t"
+                            "membar    #Sync"
+                            : /* No outputs */
+                            : "r" (0x80), "i" (ASI_IMMU_DEMAP));
+}
+
+/* Cheetah has a 4-tlb layout so direct access is a bit different.
+ * The first two TLBs are fully assosciative, hold 16 entries, and are
+ * used only for locked and >8K sized translations.  One exists for
+ * data accesses and one for instruction accesses.
+ *
+ * The third TLB is for data accesses to 8K non-locked translations, is
+ * 2 way assosciative, and holds 512 entries.  The fourth TLB is for
+ * instruction accesses to 8K non-locked translations, is 2 way
+ * assosciative, and holds 128 entries.
+ *
+ * Cheetah has some bug where bogus data can be returned from
+ * ASI_{D,I}TLB_DATA_ACCESS loads, doing the load twice fixes
+ * the problem for me. -DaveM
+ */
+static inline unsigned long cheetah_get_ldtlb_data(int entry)
+{
+       unsigned long data;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %%g0\n\t"
+                            "ldxa      [%1] %2, %0"
+                            : "=r" (data)
+                            : "r" ((0 << 16) | (entry << 3)),
+                            "i" (ASI_DTLB_DATA_ACCESS));
+
+       return data;
+}
+
+static inline unsigned long cheetah_get_litlb_data(int entry)
+{
+       unsigned long data;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %%g0\n\t"
+                            "ldxa      [%1] %2, %0"
+                            : "=r" (data)
+                            : "r" ((0 << 16) | (entry << 3)),
+                            "i" (ASI_ITLB_DATA_ACCESS));
+
+       return data;
+}
+
+static inline unsigned long cheetah_get_ldtlb_tag(int entry)
+{
+       unsigned long tag;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %0"
+                            : "=r" (tag)
+                            : "r" ((0 << 16) | (entry << 3)),
+                            "i" (ASI_DTLB_TAG_READ));
+
+       return tag;
+}
+
+static inline unsigned long cheetah_get_litlb_tag(int entry)
+{
+       unsigned long tag;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %0"
+                            : "=r" (tag)
+                            : "r" ((0 << 16) | (entry << 3)),
+                            "i" (ASI_ITLB_TAG_READ));
+
+       return tag;
+}
+
+static inline void cheetah_put_ldtlb_data(int entry, unsigned long data)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
+                            "membar    #Sync"
+                            : /* No outputs */
+                            : "r" (data),
+                              "r" ((0 << 16) | (entry << 3)),
+                              "i" (ASI_DTLB_DATA_ACCESS));
+}
+
+static inline void cheetah_put_litlb_data(int entry, unsigned long data)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
+                            "membar    #Sync"
+                            : /* No outputs */
+                            : "r" (data),
+                              "r" ((0 << 16) | (entry << 3)),
+                              "i" (ASI_ITLB_DATA_ACCESS));
+}
+
+static inline unsigned long cheetah_get_dtlb_data(int entry, int tlb)
+{
+       unsigned long data;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %%g0\n\t"
+                            "ldxa      [%1] %2, %0"
+                            : "=r" (data)
+                            : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_DATA_ACCESS));
+
+       return data;
+}
+
+static inline unsigned long cheetah_get_dtlb_tag(int entry, int tlb)
+{
+       unsigned long tag;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %0"
+                            : "=r" (tag)
+                            : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_TAG_READ));
+       return tag;
+}
+
+static inline void cheetah_put_dtlb_data(int entry, unsigned long data, int tlb)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
+                            "membar    #Sync"
+                            : /* No outputs */
+                            : "r" (data),
+                              "r" ((tlb << 16) | (entry << 3)),
+                              "i" (ASI_DTLB_DATA_ACCESS));
+}
+
+static inline unsigned long cheetah_get_itlb_data(int entry)
+{
+       unsigned long data;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %%g0\n\t"
+                            "ldxa      [%1] %2, %0"
+                            : "=r" (data)
+                            : "r" ((2 << 16) | (entry << 3)),
+                               "i" (ASI_ITLB_DATA_ACCESS));
+
+       return data;
+}
+
+static inline unsigned long cheetah_get_itlb_tag(int entry)
+{
+       unsigned long tag;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %0"
+                            : "=r" (tag)
+                            : "r" ((2 << 16) | (entry << 3)), "i" (ASI_ITLB_TAG_READ));
+       return tag;
+}
+
+static inline void cheetah_put_itlb_data(int entry, unsigned long data)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
+                            "membar    #Sync"
+                            : /* No outputs */
+                            : "r" (data), "r" ((2 << 16) | (entry << 3)),
+                              "i" (ASI_ITLB_DATA_ACCESS));
+}
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_SPARC64_SPITFIRE_H) */
diff --git a/include/asm-sparc/sstate.h b/include/asm-sparc/sstate.h
new file mode 100644 (file)
index 0000000..a7c35db
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _SPARC64_SSTATE_H
+#define _SPARC64_SSTATE_H
+
+extern void sstate_booting(void);
+extern void sstate_running(void);
+extern void sstate_halt(void);
+extern void sstate_poweroff(void);
+extern void sstate_panic(void);
+extern void sstate_reboot(void);
+
+extern void sun4v_sstate_init(void);
+
+#endif /* _SPARC64_SSTATE_H */
diff --git a/include/asm-sparc/stacktrace.h b/include/asm-sparc/stacktrace.h
new file mode 100644 (file)
index 0000000..6cee39a
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _SPARC64_STACKTRACE_H
+#define _SPARC64_STACKTRACE_H
+
+extern void stack_trace_flush(void);
+
+#endif /* _SPARC64_STACKTRACE_H */
diff --git a/include/asm-sparc/starfire.h b/include/asm-sparc/starfire.h
new file mode 100644 (file)
index 0000000..07bafd3
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * starfire.h: Group all starfire specific code together.
+ *
+ * Copyright (C) 2000 Anton Blanchard (anton@samba.org)
+ */
+
+#ifndef _SPARC64_STARFIRE_H
+#define _SPARC64_STARFIRE_H
+
+#ifndef __ASSEMBLY__
+
+extern int this_is_starfire;
+
+extern void check_if_starfire(void);
+extern void starfire_cpu_setup(void);
+extern int starfire_hard_smp_processor_id(void);
+extern void starfire_hookup(int);
+extern unsigned int starfire_translate(unsigned long imap, unsigned int upaid);
+
+#endif
+#endif
index 2299e1d5d94c2d43aa1db823c575e64e47467035..9fdcaf8c9cd30b180b81bbb1dedff0f437601ac3 100644 (file)
@@ -1,76 +1,8 @@
-#ifndef _SPARC_STAT_H
-#define _SPARC_STAT_H
-
-#include <linux/types.h>
-
-struct __old_kernel_stat {
-       unsigned short st_dev;
-       unsigned short st_ino;
-       unsigned short st_mode;
-       unsigned short st_nlink;
-       unsigned short st_uid;
-       unsigned short st_gid;
-       unsigned short st_rdev;
-       unsigned long  st_size;
-       unsigned long  st_atime;
-       unsigned long  st_mtime;
-       unsigned long  st_ctime;
-};
-
-struct stat {
-       unsigned short  st_dev;
-       unsigned long   st_ino;
-       unsigned short  st_mode;
-       short           st_nlink;
-       unsigned short  st_uid;
-       unsigned short  st_gid;
-       unsigned short  st_rdev;
-       long            st_size;
-       long            st_atime;
-       unsigned long   st_atime_nsec;
-       long            st_mtime;
-       unsigned long   st_mtime_nsec;
-       long            st_ctime;
-       unsigned long   st_ctime_nsec;
-       long            st_blksize;
-       long            st_blocks;
-       unsigned long   __unused4[2];
-};
-
-#define STAT_HAVE_NSEC 1
-
-struct stat64 {
-       unsigned long long st_dev;
-
-       unsigned long long st_ino;
-
-       unsigned int    st_mode;
-       unsigned int    st_nlink;
-
-       unsigned int    st_uid;
-       unsigned int    st_gid;
-
-       unsigned long long st_rdev;
-
-       unsigned char   __pad3[8];
-
-       long long       st_size;
-       unsigned int    st_blksize;
-
-       unsigned char   __pad4[8];
-       unsigned int    st_blocks;
-
-       unsigned int    st_atime;
-       unsigned int    st_atime_nsec;
-
-       unsigned int    st_mtime;
-       unsigned int    st_mtime_nsec;
-
-       unsigned int    st_ctime;
-       unsigned int    st_ctime_nsec;
-
-       unsigned int    __unused4;
-       unsigned int    __unused5;
-};
-
+#ifndef ___ASM_SPARC_STAT_H
+#define ___ASM_SPARC_STAT_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/stat_64.h>
+#else
+#include <asm-sparc/stat_32.h>
+#endif
 #endif
diff --git a/include/asm-sparc/stat_32.h b/include/asm-sparc/stat_32.h
new file mode 100644 (file)
index 0000000..2299e1d
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef _SPARC_STAT_H
+#define _SPARC_STAT_H
+
+#include <linux/types.h>
+
+struct __old_kernel_stat {
+       unsigned short st_dev;
+       unsigned short st_ino;
+       unsigned short st_mode;
+       unsigned short st_nlink;
+       unsigned short st_uid;
+       unsigned short st_gid;
+       unsigned short st_rdev;
+       unsigned long  st_size;
+       unsigned long  st_atime;
+       unsigned long  st_mtime;
+       unsigned long  st_ctime;
+};
+
+struct stat {
+       unsigned short  st_dev;
+       unsigned long   st_ino;
+       unsigned short  st_mode;
+       short           st_nlink;
+       unsigned short  st_uid;
+       unsigned short  st_gid;
+       unsigned short  st_rdev;
+       long            st_size;
+       long            st_atime;
+       unsigned long   st_atime_nsec;
+       long            st_mtime;
+       unsigned long   st_mtime_nsec;
+       long            st_ctime;
+       unsigned long   st_ctime_nsec;
+       long            st_blksize;
+       long            st_blocks;
+       unsigned long   __unused4[2];
+};
+
+#define STAT_HAVE_NSEC 1
+
+struct stat64 {
+       unsigned long long st_dev;
+
+       unsigned long long st_ino;
+
+       unsigned int    st_mode;
+       unsigned int    st_nlink;
+
+       unsigned int    st_uid;
+       unsigned int    st_gid;
+
+       unsigned long long st_rdev;
+
+       unsigned char   __pad3[8];
+
+       long long       st_size;
+       unsigned int    st_blksize;
+
+       unsigned char   __pad4[8];
+       unsigned int    st_blocks;
+
+       unsigned int    st_atime;
+       unsigned int    st_atime_nsec;
+
+       unsigned int    st_mtime;
+       unsigned int    st_mtime_nsec;
+
+       unsigned int    st_ctime;
+       unsigned int    st_ctime_nsec;
+
+       unsigned int    __unused4;
+       unsigned int    __unused5;
+};
+
+#endif
diff --git a/include/asm-sparc/stat_64.h b/include/asm-sparc/stat_64.h
new file mode 100644 (file)
index 0000000..9650fde
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _SPARC64_STAT_H
+#define _SPARC64_STAT_H
+
+#include <linux/types.h>
+
+struct stat {
+       unsigned   st_dev;
+       ino_t   st_ino;
+       mode_t  st_mode;
+       short   st_nlink;
+       uid_t   st_uid;
+       gid_t   st_gid;
+       unsigned   st_rdev;
+       off_t   st_size;
+       time_t  st_atime;
+       time_t  st_mtime;
+       time_t  st_ctime;
+       off_t   st_blksize;
+       off_t   st_blocks;
+       unsigned long  __unused4[2];
+};
+
+struct stat64 {
+       unsigned long   st_dev;
+       unsigned long   st_ino;
+       unsigned long   st_nlink;
+
+       unsigned int    st_mode;
+       unsigned int    st_uid;
+       unsigned int    st_gid;
+       unsigned int    __pad0;
+
+       unsigned long   st_rdev;
+       long            st_size;
+       long            st_blksize;
+       long            st_blocks;
+
+       unsigned long   st_atime;
+       unsigned long   st_atime_nsec;
+       unsigned long   st_mtime;
+       unsigned long   st_mtime_nsec;
+       unsigned long   st_ctime;
+       unsigned long   st_ctime_nsec;
+       long            __unused[3];
+};
+
+#endif
index 304520fa88639977acdd8e2856934ed0f8e00c4c..a70cc52e7018f6fad845c7f6d8f826924e97a7c7 100644 (file)
@@ -1,6 +1,8 @@
-#ifndef _SPARC_STATFS_H
-#define _SPARC_STATFS_H
-
-#include <asm-generic/statfs.h>
-
+#ifndef ___ASM_SPARC_STATFS_H
+#define ___ASM_SPARC_STATFS_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/statfs_64.h>
+#else
+#include <asm-sparc/statfs_32.h>
+#endif
 #endif
diff --git a/include/asm-sparc/statfs_32.h b/include/asm-sparc/statfs_32.h
new file mode 100644 (file)
index 0000000..304520f
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _SPARC_STATFS_H
+#define _SPARC_STATFS_H
+
+#include <asm-generic/statfs.h>
+
+#endif
diff --git a/include/asm-sparc/statfs_64.h b/include/asm-sparc/statfs_64.h
new file mode 100644 (file)
index 0000000..79b3c89
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef _SPARC64_STATFS_H
+#define _SPARC64_STATFS_H
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t        fsid_t;
+
+#endif
+
+struct statfs {
+       long f_type;
+       long f_bsize;
+       long f_blocks;
+       long f_bfree;
+       long f_bavail;
+       long f_files;
+       long f_ffree;
+       __kernel_fsid_t f_fsid;
+       long f_namelen;
+       long f_frsize;
+       long f_spare[5];
+};
+
+struct statfs64 {
+       long f_type;
+       long f_bsize;
+       long f_blocks;
+       long f_bfree;
+       long f_bavail;
+       long f_files;
+       long f_ffree;
+       __kernel_fsid_t f_fsid;
+       long f_namelen;
+       long f_frsize;
+       long f_spare[5];
+};
+
+struct compat_statfs64 {
+       __u32 f_type;
+       __u32 f_bsize;
+       __u64 f_blocks;
+       __u64 f_bfree;
+       __u64 f_bavail;
+       __u64 f_files;
+       __u64 f_ffree;
+       __kernel_fsid_t f_fsid;
+       __u32 f_namelen;
+       __u32 f_frsize;
+       __u32 f_spare[5];
+};
+
+#endif
index 8d7c0dd4f2994f15ff8524a8d2415da2bebc6a90..14c04c7697a5e4b61c3bc1703409a1c477d55ca1 100644 (file)
@@ -1,205 +1,8 @@
-/*
- * string.h: External definitions for optimized assembly string
- *           routines for the Linux Kernel.
- *
- * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#ifndef __SPARC_STRING_H__
-#define __SPARC_STRING_H__
-
-#include <asm/page.h>
-
-/* Really, userland/ksyms should not see any of this stuff. */
-
-#ifdef __KERNEL__
-
-extern void __memmove(void *,const void *,__kernel_size_t);
-extern __kernel_size_t __memcpy(void *,const void *,__kernel_size_t);
-extern __kernel_size_t __memset(void *,int,__kernel_size_t);
-
-#ifndef EXPORT_SYMTAB_STROPS
-
-/* First the mem*() things. */
-#define __HAVE_ARCH_MEMMOVE
-#undef memmove
-#define memmove(_to, _from, _n) \
-({ \
-       void *_t = (_to); \
-       __memmove(_t, (_from), (_n)); \
-       _t; \
-})
-
-#define __HAVE_ARCH_MEMCPY
-
-static inline void *__constant_memcpy(void *to, const void *from, __kernel_size_t n)
-{
-       extern void __copy_1page(void *, const void *);
-
-       if(n <= 32) {
-               __builtin_memcpy(to, from, n);
-       } else if (((unsigned int) to & 7) != 0) {
-               /* Destination is not aligned on the double-word boundary */
-               __memcpy(to, from, n);
-       } else {
-               switch(n) {
-               case PAGE_SIZE:
-                       __copy_1page(to, from);
-                       break;
-               default:
-                       __memcpy(to, from, n);
-                       break;
-               }
-       }
-       return to;
-}
-
-static inline void *__nonconstant_memcpy(void *to, const void *from, __kernel_size_t n)
-{
-       __memcpy(to, from, n);
-       return to;
-}
-
-#undef memcpy
-#define memcpy(t, f, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy((t),(f),(n)) : \
- __nonconstant_memcpy((t),(f),(n)))
-
-#define __HAVE_ARCH_MEMSET
-
-static inline void *__constant_c_and_count_memset(void *s, char c, __kernel_size_t count)
-{
-       extern void bzero_1page(void *);
-       extern __kernel_size_t __bzero(void *, __kernel_size_t);
-
-       if(!c) {
-               if(count == PAGE_SIZE)
-                       bzero_1page(s);
-               else
-                       __bzero(s, count);
-       } else {
-               __memset(s, c, count);
-       }
-       return s;
-}
-
-static inline void *__constant_c_memset(void *s, char c, __kernel_size_t count)
-{
-       extern __kernel_size_t __bzero(void *, __kernel_size_t);
-
-       if(!c)
-               __bzero(s, count);
-       else
-               __memset(s, c, count);
-       return s;
-}
-
-static inline void *__nonconstant_memset(void *s, char c, __kernel_size_t count)
-{
-       __memset(s, c, count);
-       return s;
-}
-
-#undef memset
-#define memset(s, c, count) \
-(__builtin_constant_p(c) ? (__builtin_constant_p(count) ? \
-                            __constant_c_and_count_memset((s), (c), (count)) : \
-                            __constant_c_memset((s), (c), (count))) \
-                          : __nonconstant_memset((s), (c), (count)))
-
-#define __HAVE_ARCH_MEMSCAN
-
-#undef memscan
-#define memscan(__arg0, __char, __arg2)                                                \
-({                                                                             \
-       extern void *__memscan_zero(void *, size_t);                            \
-       extern void *__memscan_generic(void *, int, size_t);                    \
-       void *__retval, *__addr = (__arg0);                                     \
-       size_t __size = (__arg2);                                               \
-                                                                               \
-       if(__builtin_constant_p(__char) && !(__char))                           \
-               __retval = __memscan_zero(__addr, __size);                      \
-       else                                                                    \
-               __retval = __memscan_generic(__addr, (__char), __size);         \
-                                                                               \
-       __retval;                                                               \
-})
-
-#define __HAVE_ARCH_MEMCMP
-extern int memcmp(const void *,const void *,__kernel_size_t);
-
-/* Now the str*() stuff... */
-#define __HAVE_ARCH_STRLEN
-extern __kernel_size_t strlen(const char *);
-
-#define __HAVE_ARCH_STRNCMP
-
-extern int __strncmp(const char *, const char *, __kernel_size_t);
-
-static inline int __constant_strncmp(const char *src, const char *dest, __kernel_size_t count)
-{
-       register int retval;
-       switch(count) {
-       case 0: return 0;
-       case 1: return (src[0] - dest[0]);
-       case 2: retval = (src[0] - dest[0]);
-               if(!retval && src[0])
-                 retval = (src[1] - dest[1]);
-               return retval;
-       case 3: retval = (src[0] - dest[0]);
-               if(!retval && src[0]) {
-                 retval = (src[1] - dest[1]);
-                 if(!retval && src[1])
-                   retval = (src[2] - dest[2]);
-               }
-               return retval;
-       case 4: retval = (src[0] - dest[0]);
-               if(!retval && src[0]) {
-                 retval = (src[1] - dest[1]);
-                 if(!retval && src[1]) {
-                   retval = (src[2] - dest[2]);
-                   if (!retval && src[2])
-                     retval = (src[3] - dest[3]);
-                 }
-               }
-               return retval;
-       case 5: retval = (src[0] - dest[0]);
-               if(!retval && src[0]) {
-                 retval = (src[1] - dest[1]);
-                 if(!retval && src[1]) {
-                   retval = (src[2] - dest[2]);
-                   if (!retval && src[2]) {
-                     retval = (src[3] - dest[3]);
-                     if (!retval && src[3])
-                       retval = (src[4] - dest[4]);
-                   }
-                 }
-               }
-               return retval;
-       default:
-               retval = (src[0] - dest[0]);
-               if(!retval && src[0]) {
-                 retval = (src[1] - dest[1]);
-                 if(!retval && src[1]) {
-                   retval = (src[2] - dest[2]);
-                   if(!retval && src[2])
-                     retval = __strncmp(src+3,dest+3,count-3);
-                 }
-               }
-               return retval;
-       }
-}
-
-#undef strncmp
-#define strncmp(__arg0, __arg1, __arg2)        \
-(__builtin_constant_p(__arg2) ?        \
- __constant_strncmp(__arg0, __arg1, __arg2) : \
- __strncmp(__arg0, __arg1, __arg2))
-#endif /* !EXPORT_SYMTAB_STROPS */
-
-#endif /* __KERNEL__ */
-
-#endif /* !(__SPARC_STRING_H__) */
+#ifndef ___ASM_SPARC_STRING_H
+#define ___ASM_SPARC_STRING_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/string_64.h>
+#else
+#include <asm-sparc/string_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/string_32.h b/include/asm-sparc/string_32.h
new file mode 100644 (file)
index 0000000..6c5fddb
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * string.h: External definitions for optimized assembly string
+ *           routines for the Linux Kernel.
+ *
+ * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#ifndef __SPARC_STRING_H__
+#define __SPARC_STRING_H__
+
+#include <asm/page.h>
+
+/* Really, userland/ksyms should not see any of this stuff. */
+
+#ifdef __KERNEL__
+
+extern void __memmove(void *,const void *,__kernel_size_t);
+extern __kernel_size_t __memcpy(void *,const void *,__kernel_size_t);
+extern __kernel_size_t __memset(void *,int,__kernel_size_t);
+
+#ifndef EXPORT_SYMTAB_STROPS
+
+/* First the mem*() things. */
+#define __HAVE_ARCH_MEMMOVE
+#undef memmove
+#define memmove(_to, _from, _n) \
+({ \
+       void *_t = (_to); \
+       __memmove(_t, (_from), (_n)); \
+       _t; \
+})
+
+#define __HAVE_ARCH_MEMCPY
+
+static inline void *__constant_memcpy(void *to, const void *from, __kernel_size_t n)
+{
+       extern void __copy_1page(void *, const void *);
+
+       if(n <= 32) {
+               __builtin_memcpy(to, from, n);
+       } else if (((unsigned int) to & 7) != 0) {
+               /* Destination is not aligned on the double-word boundary */
+               __memcpy(to, from, n);
+       } else {
+               switch(n) {
+               case PAGE_SIZE:
+                       __copy_1page(to, from);
+                       break;
+               default:
+                       __memcpy(to, from, n);
+                       break;
+               }
+       }
+       return to;
+}
+
+static inline void *__nonconstant_memcpy(void *to, const void *from, __kernel_size_t n)
+{
+       __memcpy(to, from, n);
+       return to;
+}
+
+#undef memcpy
+#define memcpy(t, f, n) \
+(__builtin_constant_p(n) ? \
+ __constant_memcpy((t),(f),(n)) : \
+ __nonconstant_memcpy((t),(f),(n)))
+
+#define __HAVE_ARCH_MEMSET
+
+static inline void *__constant_c_and_count_memset(void *s, char c, __kernel_size_t count)
+{
+       extern void bzero_1page(void *);
+       extern __kernel_size_t __bzero(void *, __kernel_size_t);
+
+       if(!c) {
+               if(count == PAGE_SIZE)
+                       bzero_1page(s);
+               else
+                       __bzero(s, count);
+       } else {
+               __memset(s, c, count);
+       }
+       return s;
+}
+
+static inline void *__constant_c_memset(void *s, char c, __kernel_size_t count)
+{
+       extern __kernel_size_t __bzero(void *, __kernel_size_t);
+
+       if(!c)
+               __bzero(s, count);
+       else
+               __memset(s, c, count);
+       return s;
+}
+
+static inline void *__nonconstant_memset(void *s, char c, __kernel_size_t count)
+{
+       __memset(s, c, count);
+       return s;
+}
+
+#undef memset
+#define memset(s, c, count) \
+(__builtin_constant_p(c) ? (__builtin_constant_p(count) ? \
+                            __constant_c_and_count_memset((s), (c), (count)) : \
+                            __constant_c_memset((s), (c), (count))) \
+                          : __nonconstant_memset((s), (c), (count)))
+
+#define __HAVE_ARCH_MEMSCAN
+
+#undef memscan
+#define memscan(__arg0, __char, __arg2)                                                \
+({                                                                             \
+       extern void *__memscan_zero(void *, size_t);                            \
+       extern void *__memscan_generic(void *, int, size_t);                    \
+       void *__retval, *__addr = (__arg0);                                     \
+       size_t __size = (__arg2);                                               \
+                                                                               \
+       if(__builtin_constant_p(__char) && !(__char))                           \
+               __retval = __memscan_zero(__addr, __size);                      \
+       else                                                                    \
+               __retval = __memscan_generic(__addr, (__char), __size);         \
+                                                                               \
+       __retval;                                                               \
+})
+
+#define __HAVE_ARCH_MEMCMP
+extern int memcmp(const void *,const void *,__kernel_size_t);
+
+/* Now the str*() stuff... */
+#define __HAVE_ARCH_STRLEN
+extern __kernel_size_t strlen(const char *);
+
+#define __HAVE_ARCH_STRNCMP
+
+extern int __strncmp(const char *, const char *, __kernel_size_t);
+
+static inline int __constant_strncmp(const char *src, const char *dest, __kernel_size_t count)
+{
+       register int retval;
+       switch(count) {
+       case 0: return 0;
+       case 1: return (src[0] - dest[0]);
+       case 2: retval = (src[0] - dest[0]);
+               if(!retval && src[0])
+                 retval = (src[1] - dest[1]);
+               return retval;
+       case 3: retval = (src[0] - dest[0]);
+               if(!retval && src[0]) {
+                 retval = (src[1] - dest[1]);
+                 if(!retval && src[1])
+                   retval = (src[2] - dest[2]);
+               }
+               return retval;
+       case 4: retval = (src[0] - dest[0]);
+               if(!retval && src[0]) {
+                 retval = (src[1] - dest[1]);
+                 if(!retval && src[1]) {
+                   retval = (src[2] - dest[2]);
+                   if (!retval && src[2])
+                     retval = (src[3] - dest[3]);
+                 }
+               }
+               return retval;
+       case 5: retval = (src[0] - dest[0]);
+               if(!retval && src[0]) {
+                 retval = (src[1] - dest[1]);
+                 if(!retval && src[1]) {
+                   retval = (src[2] - dest[2]);
+                   if (!retval && src[2]) {
+                     retval = (src[3] - dest[3]);
+                     if (!retval && src[3])
+                       retval = (src[4] - dest[4]);
+                   }
+                 }
+               }
+               return retval;
+       default:
+               retval = (src[0] - dest[0]);
+               if(!retval && src[0]) {
+                 retval = (src[1] - dest[1]);
+                 if(!retval && src[1]) {
+                   retval = (src[2] - dest[2]);
+                   if(!retval && src[2])
+                     retval = __strncmp(src+3,dest+3,count-3);
+                 }
+               }
+               return retval;
+       }
+}
+
+#undef strncmp
+#define strncmp(__arg0, __arg1, __arg2)        \
+(__builtin_constant_p(__arg2) ?        \
+ __constant_strncmp(__arg0, __arg1, __arg2) : \
+ __strncmp(__arg0, __arg1, __arg2))
+
+#endif /* !EXPORT_SYMTAB_STROPS */
+
+#endif /* __KERNEL__ */
+
+#endif /* !(__SPARC_STRING_H__) */
diff --git a/include/asm-sparc/string_64.h b/include/asm-sparc/string_64.h
new file mode 100644 (file)
index 0000000..43161f2
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * string.h: External definitions for optimized assembly string
+ *           routines for the Linux Kernel.
+ *
+ * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996,1997,1999 Jakub Jelinek (jakub@redhat.com)
+ */
+
+#ifndef __SPARC64_STRING_H__
+#define __SPARC64_STRING_H__
+
+/* Really, userland/ksyms should not see any of this stuff. */
+
+#ifdef __KERNEL__
+
+#include <asm/asi.h>
+
+extern void *__memset(void *,int,__kernel_size_t);
+
+#ifndef EXPORT_SYMTAB_STROPS
+
+/* First the mem*() things. */
+#define __HAVE_ARCH_MEMMOVE
+extern void *memmove(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMSET
+extern void *__builtin_memset(void *,int,__kernel_size_t);
+
+static inline void *__constant_memset(void *s, int c, __kernel_size_t count)
+{
+       extern __kernel_size_t __bzero(void *, __kernel_size_t);
+
+       if (!c) {
+               __bzero(s, count);
+               return s;
+       } else
+               return __memset(s, c, count);
+}
+
+#undef memset
+#define memset(s, c, count) \
+((__builtin_constant_p(count) && (count) <= 32) ? \
+ __builtin_memset((s), (c), (count)) : \
+ (__builtin_constant_p(c) ? \
+  __constant_memset((s), (c), (count)) : \
+  __memset((s), (c), (count))))
+
+#define __HAVE_ARCH_MEMSCAN
+
+#undef memscan
+#define memscan(__arg0, __char, __arg2)                                        \
+({                                                                     \
+       extern void *__memscan_zero(void *, size_t);                    \
+       extern void *__memscan_generic(void *, int, size_t);            \
+       void *__retval, *__addr = (__arg0);                             \
+       size_t __size = (__arg2);                                       \
+                                                                       \
+       if(__builtin_constant_p(__char) && !(__char))                   \
+               __retval = __memscan_zero(__addr, __size);              \
+       else                                                            \
+               __retval = __memscan_generic(__addr, (__char), __size); \
+                                                                       \
+       __retval;                                                       \
+})
+
+#define __HAVE_ARCH_MEMCMP
+extern int memcmp(const void *,const void *,__kernel_size_t);
+
+/* Now the str*() stuff... */
+#define __HAVE_ARCH_STRLEN
+extern __kernel_size_t strlen(const char *);
+
+#define __HAVE_ARCH_STRNCMP
+extern int strncmp(const char *, const char *, __kernel_size_t);
+
+#endif /* !EXPORT_SYMTAB_STROPS */
+
+#endif /* __KERNEL__ */
+
+#endif /* !(__SPARC64_STRING_H__) */
diff --git a/include/asm-sparc/syscalls.h b/include/asm-sparc/syscalls.h
new file mode 100644 (file)
index 0000000..45a43f6
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _SPARC64_SYSCALLS_H
+#define _SPARC64_SYSCALLS_H
+
+struct pt_regs;
+
+extern asmlinkage long sparc_do_fork(unsigned long clone_flags,
+                                    unsigned long stack_start,
+                                    struct pt_regs *regs,
+                                    unsigned long stack_size);
+
+extern asmlinkage int sparc_execve(struct pt_regs *regs);
+
+#endif /* _SPARC64_SYSCALLS_H */
index b4b024445fc984f0d419f5f997690b83a8efd733..15e2a3bc4f6154f95f17a8bb2a1de37214b3a381 100644 (file)
@@ -1,288 +1,8 @@
-#ifndef __SPARC_SYSTEM_H
-#define __SPARC_SYSTEM_H
-
-#include <linux/kernel.h>
-#include <linux/threads.h>     /* NR_CPUS */
-#include <linux/thread_info.h>
-
-#include <asm/page.h>
-#include <asm/psr.h>
-#include <asm/ptrace.h>
-#include <asm/btfixup.h>
-#include <asm/smp.h>
-
-#ifndef __ASSEMBLY__
-
-#include <linux/irqflags.h>
-
-/*
- * Sparc (general) CPU types
- */
-enum sparc_cpu {
-  sun4        = 0x00,
-  sun4c       = 0x01,
-  sun4m       = 0x02,
-  sun4d       = 0x03,
-  sun4e       = 0x04,
-  sun4u       = 0x05, /* V8 ploos ploos */
-  sun_unknown = 0x06,
-  ap1000      = 0x07, /* almost a sun4m */
-};
-
-/* Really, userland should not be looking at any of this... */
-#ifdef __KERNEL__
-
-extern enum sparc_cpu sparc_cpu_model;
-
-#ifndef CONFIG_SUN4
-#define ARCH_SUN4C_SUN4 (sparc_cpu_model==sun4c)
-#define ARCH_SUN4 0
+#ifndef ___ASM_SPARC_SYSTEM_H
+#define ___ASM_SPARC_SYSTEM_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/system_64.h>
 #else
-#define ARCH_SUN4C_SUN4 1
-#define ARCH_SUN4 1
+#include <asm-sparc/system_32.h>
 #endif
-
-#define SUN4M_NCPUS            4              /* Architectural limit of sun4m. */
-
-extern char reboot_command[];
-
-extern struct thread_info *current_set[NR_CPUS];
-
-extern unsigned long empty_bad_page;
-extern unsigned long empty_bad_page_table;
-extern unsigned long empty_zero_page;
-
-extern void sun_do_break(void);
-extern int serial_console;
-extern int stop_a_enabled;
-
-static inline int con_is_present(void)
-{
-       return serial_console ? 0 : 1;
-}
-
-/* When a context switch happens we must flush all user windows so that
- * the windows of the current process are flushed onto its stack. This
- * way the windows are all clean for the next process and the stack
- * frames are up to date.
- */
-extern void flush_user_windows(void);
-extern void kill_user_windows(void);
-extern void synchronize_user_stack(void);
-extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
-                  void *fpqueue, unsigned long *fpqdepth);
-
-#ifdef CONFIG_SMP
-#define SWITCH_ENTER(prv) \
-       do {                    \
-       if (test_tsk_thread_flag(prv, TIF_USEDFPU)) { \
-               put_psr(get_psr() | PSR_EF); \
-               fpsave(&(prv)->thread.float_regs[0], &(prv)->thread.fsr, \
-                      &(prv)->thread.fpqueue[0], &(prv)->thread.fpqdepth); \
-               clear_tsk_thread_flag(prv, TIF_USEDFPU); \
-               (prv)->thread.kregs->psr &= ~PSR_EF; \
-       } \
-       } while(0)
-
-#define SWITCH_DO_LAZY_FPU(next)       /* */
-#else
-#define SWITCH_ENTER(prv)              /* */
-#define SWITCH_DO_LAZY_FPU(nxt)        \
-       do {                    \
-       if (last_task_used_math != (nxt))               \
-               (nxt)->thread.kregs->psr&=~PSR_EF;      \
-       } while(0)
-#endif
-
-extern void flushw_all(void);
-
-/*
- * Flush windows so that the VM switch which follows
- * would not pull the stack from under us.
- *
- * SWITCH_ENTER and SWITH_DO_LAZY_FPU do not work yet (e.g. SMP does not work)
- * XXX WTF is the above comment? Found in late teen 2.4.x.
- */
-#define prepare_arch_switch(next) do { \
-       __asm__ __volatile__( \
-       ".globl\tflush_patch_switch\nflush_patch_switch:\n\t" \
-       "save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \
-       "save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \
-       "save %sp, -0x40, %sp\n\t" \
-       "restore; restore; restore; restore; restore; restore; restore"); \
-} while(0)
-
-       /* Much care has gone into this code, do not touch it.
-        *
-        * We need to loadup regs l0/l1 for the newly forked child
-        * case because the trap return path relies on those registers
-        * holding certain values, gcc is told that they are clobbered.
-        * Gcc needs registers for 3 values in and 1 value out, so we
-        * clobber every non-fixed-usage register besides l2/l3/o4/o5.  -DaveM
-        *
-        * Hey Dave, that do not touch sign is too much of an incentive
-        * - Anton & Pete
-        */
-#define switch_to(prev, next, last) do {                                               \
-       SWITCH_ENTER(prev);                                                             \
-       SWITCH_DO_LAZY_FPU(next);                                                       \
-       cpu_set(smp_processor_id(), next->active_mm->cpu_vm_mask);                      \
-       __asm__ __volatile__(                                                           \
-       "sethi  %%hi(here - 0x8), %%o7\n\t"                                             \
-       "mov    %%g6, %%g3\n\t"                                                         \
-       "or     %%o7, %%lo(here - 0x8), %%o7\n\t"                                       \
-       "rd     %%psr, %%g4\n\t"                                                        \
-       "std    %%sp, [%%g6 + %4]\n\t"                                                  \
-       "rd     %%wim, %%g5\n\t"                                                        \
-       "wr     %%g4, 0x20, %%psr\n\t"                                                  \
-       "nop\n\t"                                                                       \
-       "std    %%g4, [%%g6 + %3]\n\t"                                                  \
-       "ldd    [%2 + %3], %%g4\n\t"                                                    \
-       "mov    %2, %%g6\n\t"                                                           \
-       ".globl patchme_store_new_current\n"                                            \
-"patchme_store_new_current:\n\t"                                                       \
-       "st     %2, [%1]\n\t"                                                           \
-       "wr     %%g4, 0x20, %%psr\n\t"                                                  \
-       "nop\n\t"                                                                       \
-       "nop\n\t"                                                                       \
-       "nop\n\t"       /* LEON needs all 3 nops: load to %sp depends on CWP. */                \
-       "ldd    [%%g6 + %4], %%sp\n\t"                                                  \
-       "wr     %%g5, 0x0, %%wim\n\t"                                                   \
-       "ldd    [%%sp + 0x00], %%l0\n\t"                                                \
-       "ldd    [%%sp + 0x38], %%i6\n\t"                                                \
-       "wr     %%g4, 0x0, %%psr\n\t"                                                   \
-       "nop\n\t"                                                                       \
-       "nop\n\t"                                                                       \
-       "jmpl   %%o7 + 0x8, %%g0\n\t"                                                   \
-       " ld    [%%g3 + %5], %0\n\t"                                                    \
-       "here:\n"                                                                       \
-        : "=&r" (last)                                                                 \
-        : "r" (&(current_set[hard_smp_processor_id()])),       \
-         "r" (task_thread_info(next)),                         \
-         "i" (TI_KPSR),                                        \
-         "i" (TI_KSP),                                         \
-         "i" (TI_TASK)                                         \
-       :       "g1", "g2", "g3", "g4", "g5",       "g7",       \
-         "l0", "l1",       "l3", "l4", "l5", "l6", "l7",       \
-         "i0", "i1", "i2", "i3", "i4", "i5",                   \
-         "o0", "o1", "o2", "o3",                   "o7");      \
-       } while(0)
-
-/* XXX Change this if we ever use a PSO mode kernel. */
-#define mb()   __asm__ __volatile__ ("" : : : "memory")
-#define rmb()  mb()
-#define wmb()  mb()
-#define read_barrier_depends() do { } while(0)
-#define set_mb(__var, __value)  do { __var = __value; mb(); } while(0)
-#define smp_mb()       __asm__ __volatile__("":::"memory")
-#define smp_rmb()      __asm__ __volatile__("":::"memory")
-#define smp_wmb()      __asm__ __volatile__("":::"memory")
-#define smp_read_barrier_depends()     do { } while(0)
-
-#define nop() __asm__ __volatile__ ("nop")
-
-/* This has special calling conventions */
-#ifndef CONFIG_SMP
-BTFIXUPDEF_CALL(void, ___xchg32, void)
-#endif
-
-static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)
-{
-#ifdef CONFIG_SMP
-       __asm__ __volatile__("swap [%2], %0"
-                            : "=&r" (val)
-                            : "0" (val), "r" (m)
-                            : "memory");
-       return val;
-#else
-       register unsigned long *ptr asm("g1");
-       register unsigned long ret asm("g2");
-
-       ptr = (unsigned long *) m;
-       ret = val;
-
-       /* Note: this is magic and the nop there is
-          really needed. */
-       __asm__ __volatile__(
-       "mov    %%o7, %%g4\n\t"
-       "call   ___f____xchg32\n\t"
-       " nop\n\t"
-       : "=&r" (ret)
-       : "0" (ret), "r" (ptr)
-       : "g3", "g4", "g7", "memory", "cc");
-
-       return ret;
 #endif
-}
-
-#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-
-extern void __xchg_called_with_bad_pointer(void);
-
-static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
-{
-       switch (size) {
-       case 4:
-               return xchg_u32(ptr, x);
-       };
-       __xchg_called_with_bad_pointer();
-       return x;
-}
-
-/* Emulate cmpxchg() the same way we emulate atomics,
- * by hashing the object address and indexing into an array
- * of spinlocks to get a bit of performance...
- *
- * See arch/sparc/lib/atomic32.c for implementation.
- *
- * Cribbed from <asm-parisc/atomic.h>
- */
-#define __HAVE_ARCH_CMPXCHG    1
-
-/* bug catcher for when unsupported size is used - won't link */
-extern void __cmpxchg_called_with_bad_pointer(void);
-/* we only need to support cmpxchg of a u32 on sparc */
-extern unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
-
-/* don't worry...optimizer will get rid of most of this */
-static inline unsigned long
-__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
-{
-       switch (size) {
-       case 4:
-               return __cmpxchg_u32((u32 *)ptr, (u32)old, (u32)new_);
-       default:
-               __cmpxchg_called_with_bad_pointer();
-               break;
-       }
-       return old;
-}
-
-#define cmpxchg(ptr, o, n)                                             \
-({                                                                     \
-       __typeof__(*(ptr)) _o_ = (o);                                   \
-       __typeof__(*(ptr)) _n_ = (n);                                   \
-       (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,       \
-                       (unsigned long)_n_, sizeof(*(ptr)));            \
-})
-
-#include <asm-generic/cmpxchg-local.h>
-
-/*
- * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
- * them available.
- */
-#define cmpxchg_local(ptr, o, n)                                              \
-       ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
-                       (unsigned long)(n), sizeof(*(ptr))))
-#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
-
-extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noreturn));
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASSEMBLY__ */
-
-#define arch_align_stack(x) (x)
-
-#endif /* !(__SPARC_SYSTEM_H) */
diff --git a/include/asm-sparc/system_32.h b/include/asm-sparc/system_32.h
new file mode 100644 (file)
index 0000000..b4b0244
--- /dev/null
@@ -0,0 +1,288 @@
+#ifndef __SPARC_SYSTEM_H
+#define __SPARC_SYSTEM_H
+
+#include <linux/kernel.h>
+#include <linux/threads.h>     /* NR_CPUS */
+#include <linux/thread_info.h>
+
+#include <asm/page.h>
+#include <asm/psr.h>
+#include <asm/ptrace.h>
+#include <asm/btfixup.h>
+#include <asm/smp.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/irqflags.h>
+
+/*
+ * Sparc (general) CPU types
+ */
+enum sparc_cpu {
+  sun4        = 0x00,
+  sun4c       = 0x01,
+  sun4m       = 0x02,
+  sun4d       = 0x03,
+  sun4e       = 0x04,
+  sun4u       = 0x05, /* V8 ploos ploos */
+  sun_unknown = 0x06,
+  ap1000      = 0x07, /* almost a sun4m */
+};
+
+/* Really, userland should not be looking at any of this... */
+#ifdef __KERNEL__
+
+extern enum sparc_cpu sparc_cpu_model;
+
+#ifndef CONFIG_SUN4
+#define ARCH_SUN4C_SUN4 (sparc_cpu_model==sun4c)
+#define ARCH_SUN4 0
+#else
+#define ARCH_SUN4C_SUN4 1
+#define ARCH_SUN4 1
+#endif
+
+#define SUN4M_NCPUS            4              /* Architectural limit of sun4m. */
+
+extern char reboot_command[];
+
+extern struct thread_info *current_set[NR_CPUS];
+
+extern unsigned long empty_bad_page;
+extern unsigned long empty_bad_page_table;
+extern unsigned long empty_zero_page;
+
+extern void sun_do_break(void);
+extern int serial_console;
+extern int stop_a_enabled;
+
+static inline int con_is_present(void)
+{
+       return serial_console ? 0 : 1;
+}
+
+/* When a context switch happens we must flush all user windows so that
+ * the windows of the current process are flushed onto its stack. This
+ * way the windows are all clean for the next process and the stack
+ * frames are up to date.
+ */
+extern void flush_user_windows(void);
+extern void kill_user_windows(void);
+extern void synchronize_user_stack(void);
+extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
+                  void *fpqueue, unsigned long *fpqdepth);
+
+#ifdef CONFIG_SMP
+#define SWITCH_ENTER(prv) \
+       do {                    \
+       if (test_tsk_thread_flag(prv, TIF_USEDFPU)) { \
+               put_psr(get_psr() | PSR_EF); \
+               fpsave(&(prv)->thread.float_regs[0], &(prv)->thread.fsr, \
+                      &(prv)->thread.fpqueue[0], &(prv)->thread.fpqdepth); \
+               clear_tsk_thread_flag(prv, TIF_USEDFPU); \
+               (prv)->thread.kregs->psr &= ~PSR_EF; \
+       } \
+       } while(0)
+
+#define SWITCH_DO_LAZY_FPU(next)       /* */
+#else
+#define SWITCH_ENTER(prv)              /* */
+#define SWITCH_DO_LAZY_FPU(nxt)        \
+       do {                    \
+       if (last_task_used_math != (nxt))               \
+               (nxt)->thread.kregs->psr&=~PSR_EF;      \
+       } while(0)
+#endif
+
+extern void flushw_all(void);
+
+/*
+ * Flush windows so that the VM switch which follows
+ * would not pull the stack from under us.
+ *
+ * SWITCH_ENTER and SWITH_DO_LAZY_FPU do not work yet (e.g. SMP does not work)
+ * XXX WTF is the above comment? Found in late teen 2.4.x.
+ */
+#define prepare_arch_switch(next) do { \
+       __asm__ __volatile__( \
+       ".globl\tflush_patch_switch\nflush_patch_switch:\n\t" \
+       "save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \
+       "save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \
+       "save %sp, -0x40, %sp\n\t" \
+       "restore; restore; restore; restore; restore; restore; restore"); \
+} while(0)
+
+       /* Much care has gone into this code, do not touch it.
+        *
+        * We need to loadup regs l0/l1 for the newly forked child
+        * case because the trap return path relies on those registers
+        * holding certain values, gcc is told that they are clobbered.
+        * Gcc needs registers for 3 values in and 1 value out, so we
+        * clobber every non-fixed-usage register besides l2/l3/o4/o5.  -DaveM
+        *
+        * Hey Dave, that do not touch sign is too much of an incentive
+        * - Anton & Pete
+        */
+#define switch_to(prev, next, last) do {                                               \
+       SWITCH_ENTER(prev);                                                             \
+       SWITCH_DO_LAZY_FPU(next);                                                       \
+       cpu_set(smp_processor_id(), next->active_mm->cpu_vm_mask);                      \
+       __asm__ __volatile__(                                                           \
+       "sethi  %%hi(here - 0x8), %%o7\n\t"                                             \
+       "mov    %%g6, %%g3\n\t"                                                         \
+       "or     %%o7, %%lo(here - 0x8), %%o7\n\t"                                       \
+       "rd     %%psr, %%g4\n\t"                                                        \
+       "std    %%sp, [%%g6 + %4]\n\t"                                                  \
+       "rd     %%wim, %%g5\n\t"                                                        \
+       "wr     %%g4, 0x20, %%psr\n\t"                                                  \
+       "nop\n\t"                                                                       \
+       "std    %%g4, [%%g6 + %3]\n\t"                                                  \
+       "ldd    [%2 + %3], %%g4\n\t"                                                    \
+       "mov    %2, %%g6\n\t"                                                           \
+       ".globl patchme_store_new_current\n"                                            \
+"patchme_store_new_current:\n\t"                                                       \
+       "st     %2, [%1]\n\t"                                                           \
+       "wr     %%g4, 0x20, %%psr\n\t"                                                  \
+       "nop\n\t"                                                                       \
+       "nop\n\t"                                                                       \
+       "nop\n\t"       /* LEON needs all 3 nops: load to %sp depends on CWP. */                \
+       "ldd    [%%g6 + %4], %%sp\n\t"                                                  \
+       "wr     %%g5, 0x0, %%wim\n\t"                                                   \
+       "ldd    [%%sp + 0x00], %%l0\n\t"                                                \
+       "ldd    [%%sp + 0x38], %%i6\n\t"                                                \
+       "wr     %%g4, 0x0, %%psr\n\t"                                                   \
+       "nop\n\t"                                                                       \
+       "nop\n\t"                                                                       \
+       "jmpl   %%o7 + 0x8, %%g0\n\t"                                                   \
+       " ld    [%%g3 + %5], %0\n\t"                                                    \
+       "here:\n"                                                                       \
+        : "=&r" (last)                                                                 \
+        : "r" (&(current_set[hard_smp_processor_id()])),       \
+         "r" (task_thread_info(next)),                         \
+         "i" (TI_KPSR),                                        \
+         "i" (TI_KSP),                                         \
+         "i" (TI_TASK)                                         \
+       :       "g1", "g2", "g3", "g4", "g5",       "g7",       \
+         "l0", "l1",       "l3", "l4", "l5", "l6", "l7",       \
+         "i0", "i1", "i2", "i3", "i4", "i5",                   \
+         "o0", "o1", "o2", "o3",                   "o7");      \
+       } while(0)
+
+/* XXX Change this if we ever use a PSO mode kernel. */
+#define mb()   __asm__ __volatile__ ("" : : : "memory")
+#define rmb()  mb()
+#define wmb()  mb()
+#define read_barrier_depends() do { } while(0)
+#define set_mb(__var, __value)  do { __var = __value; mb(); } while(0)
+#define smp_mb()       __asm__ __volatile__("":::"memory")
+#define smp_rmb()      __asm__ __volatile__("":::"memory")
+#define smp_wmb()      __asm__ __volatile__("":::"memory")
+#define smp_read_barrier_depends()     do { } while(0)
+
+#define nop() __asm__ __volatile__ ("nop")
+
+/* This has special calling conventions */
+#ifndef CONFIG_SMP
+BTFIXUPDEF_CALL(void, ___xchg32, void)
+#endif
+
+static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)
+{
+#ifdef CONFIG_SMP
+       __asm__ __volatile__("swap [%2], %0"
+                            : "=&r" (val)
+                            : "0" (val), "r" (m)
+                            : "memory");
+       return val;
+#else
+       register unsigned long *ptr asm("g1");
+       register unsigned long ret asm("g2");
+
+       ptr = (unsigned long *) m;
+       ret = val;
+
+       /* Note: this is magic and the nop there is
+          really needed. */
+       __asm__ __volatile__(
+       "mov    %%o7, %%g4\n\t"
+       "call   ___f____xchg32\n\t"
+       " nop\n\t"
+       : "=&r" (ret)
+       : "0" (ret), "r" (ptr)
+       : "g3", "g4", "g7", "memory", "cc");
+
+       return ret;
+#endif
+}
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+extern void __xchg_called_with_bad_pointer(void);
+
+static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
+{
+       switch (size) {
+       case 4:
+               return xchg_u32(ptr, x);
+       };
+       __xchg_called_with_bad_pointer();
+       return x;
+}
+
+/* Emulate cmpxchg() the same way we emulate atomics,
+ * by hashing the object address and indexing into an array
+ * of spinlocks to get a bit of performance...
+ *
+ * See arch/sparc/lib/atomic32.c for implementation.
+ *
+ * Cribbed from <asm-parisc/atomic.h>
+ */
+#define __HAVE_ARCH_CMPXCHG    1
+
+/* bug catcher for when unsupported size is used - won't link */
+extern void __cmpxchg_called_with_bad_pointer(void);
+/* we only need to support cmpxchg of a u32 on sparc */
+extern unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
+
+/* don't worry...optimizer will get rid of most of this */
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
+{
+       switch (size) {
+       case 4:
+               return __cmpxchg_u32((u32 *)ptr, (u32)old, (u32)new_);
+       default:
+               __cmpxchg_called_with_bad_pointer();
+               break;
+       }
+       return old;
+}
+
+#define cmpxchg(ptr, o, n)                                             \
+({                                                                     \
+       __typeof__(*(ptr)) _o_ = (o);                                   \
+       __typeof__(*(ptr)) _n_ = (n);                                   \
+       (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,       \
+                       (unsigned long)_n_, sizeof(*(ptr)));            \
+})
+
+#include <asm-generic/cmpxchg-local.h>
+
+/*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+ * them available.
+ */
+#define cmpxchg_local(ptr, o, n)                                              \
+       ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
+                       (unsigned long)(n), sizeof(*(ptr))))
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+
+extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noreturn));
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
+
+#define arch_align_stack(x) (x)
+
+#endif /* !(__SPARC_SYSTEM_H) */
diff --git a/include/asm-sparc/system_64.h b/include/asm-sparc/system_64.h
new file mode 100644 (file)
index 0000000..db9e742
--- /dev/null
@@ -0,0 +1,355 @@
+#ifndef __SPARC64_SYSTEM_H
+#define __SPARC64_SYSTEM_H
+
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/visasm.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/irqflags.h>
+#include <asm-generic/cmpxchg-local.h>
+
+/*
+ * Sparc (general) CPU types
+ */
+enum sparc_cpu {
+  sun4        = 0x00,
+  sun4c       = 0x01,
+  sun4m       = 0x02,
+  sun4d       = 0x03,
+  sun4e       = 0x04,
+  sun4u       = 0x05, /* V8 ploos ploos */
+  sun_unknown = 0x06,
+  ap1000      = 0x07, /* almost a sun4m */
+};
+
+#define sparc_cpu_model sun4u
+
+/* This cannot ever be a sun4c nor sun4 :) That's just history. */
+#define ARCH_SUN4C_SUN4 0
+#define ARCH_SUN4 0
+
+extern char reboot_command[];
+
+/* These are here in an effort to more fully work around Spitfire Errata
+ * #51.  Essentially, if a memory barrier occurs soon after a mispredicted
+ * branch, the chip can stop executing instructions until a trap occurs.
+ * Therefore, if interrupts are disabled, the chip can hang forever.
+ *
+ * It used to be believed that the memory barrier had to be right in the
+ * delay slot, but a case has been traced recently wherein the memory barrier
+ * was one instruction after the branch delay slot and the chip still hung.
+ * The offending sequence was the following in sym_wakeup_done() of the
+ * sym53c8xx_2 driver:
+ *
+ *     call    sym_ccb_from_dsa, 0
+ *      movge  %icc, 0, %l0
+ *     brz,pn  %o0, .LL1303
+ *      mov    %o0, %l2
+ *     membar  #LoadLoad
+ *
+ * The branch has to be mispredicted for the bug to occur.  Therefore, we put
+ * the memory barrier explicitly into a "branch always, predicted taken"
+ * delay slot to avoid the problem case.
+ */
+#define membar_safe(type) \
+do {   __asm__ __volatile__("ba,pt     %%xcc, 1f\n\t" \
+                            " membar   " type "\n" \
+                            "1:\n" \
+                            : : : "memory"); \
+} while (0)
+
+#define mb()   \
+       membar_safe("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad")
+#define rmb()  \
+       membar_safe("#LoadLoad")
+#define wmb()  \
+       membar_safe("#StoreStore")
+#define membar_storeload() \
+       membar_safe("#StoreLoad")
+#define membar_storeload_storestore() \
+       membar_safe("#StoreLoad | #StoreStore")
+#define membar_storeload_loadload() \
+       membar_safe("#StoreLoad | #LoadLoad")
+#define membar_storestore_loadstore() \
+       membar_safe("#StoreStore | #LoadStore")
+
+#endif
+
+#define nop()          __asm__ __volatile__ ("nop")
+
+#define read_barrier_depends()         do { } while(0)
+#define set_mb(__var, __value) \
+       do { __var = __value; membar_storeload_storestore(); } while(0)
+
+#ifdef CONFIG_SMP
+#define smp_mb()       mb()
+#define smp_rmb()      rmb()
+#define smp_wmb()      wmb()
+#define smp_read_barrier_depends()     read_barrier_depends()
+#else
+#define smp_mb()       __asm__ __volatile__("":::"memory")
+#define smp_rmb()      __asm__ __volatile__("":::"memory")
+#define smp_wmb()      __asm__ __volatile__("":::"memory")
+#define smp_read_barrier_depends()     do { } while(0)
+#endif
+
+#define flushi(addr)   __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory")
+
+#define flushw_all()   __asm__ __volatile__("flushw")
+
+/* Performance counter register access. */
+#define read_pcr(__p)  __asm__ __volatile__("rd        %%pcr, %0" : "=r" (__p))
+#define write_pcr(__p) __asm__ __volatile__("wr        %0, 0x0, %%pcr" : : "r" (__p))
+#define read_pic(__p)  __asm__ __volatile__("rd %%pic, %0" : "=r" (__p))
+
+/* Blackbird errata workaround.  See commentary in
+ * arch/sparc64/kernel/smp.c:smp_percpu_timer_interrupt()
+ * for more information.
+ */
+#define reset_pic()                                                    \
+       __asm__ __volatile__("ba,pt     %xcc, 99f\n\t"          \
+                            ".align    64\n"                   \
+                         "99:wr        %g0, 0x0, %pic\n\t"     \
+                            "rd        %pic, %g0")
+
+#ifndef __ASSEMBLY__
+
+extern void sun_do_break(void);
+extern int stop_a_enabled;
+
+extern void fault_in_user_windows(void);
+extern void synchronize_user_stack(void);
+
+extern void __flushw_user(void);
+#define flushw_user() __flushw_user()
+
+#define flush_user_windows flushw_user
+#define flush_register_windows flushw_all
+
+/* Don't hold the runqueue lock over context switch */
+#define __ARCH_WANT_UNLOCKED_CTXSW
+#define prepare_arch_switch(next)              \
+do {                                           \
+       flushw_all();                           \
+} while (0)
+
+       /* See what happens when you design the chip correctly?
+        *
+        * We tell gcc we clobber all non-fixed-usage registers except
+        * for l0/l1.  It will use one for 'next' and the other to hold
+        * the output value of 'last'.  'next' is not referenced again
+        * past the invocation of switch_to in the scheduler, so we need
+        * not preserve it's value.  Hairy, but it lets us remove 2 loads
+        * and 2 stores in this critical code path.  -DaveM
+        */
+#define switch_to(prev, next, last)                                    \
+do {   if (test_thread_flag(TIF_PERFCTR)) {                            \
+               unsigned long __tmp;                                    \
+               read_pcr(__tmp);                                        \
+               current_thread_info()->pcr_reg = __tmp;                 \
+               read_pic(__tmp);                                        \
+               current_thread_info()->kernel_cntd0 += (unsigned int)(__tmp);\
+               current_thread_info()->kernel_cntd1 += ((__tmp) >> 32); \
+       }                                                               \
+       flush_tlb_pending();                                            \
+       save_and_clear_fpu();                                           \
+       /* If you are tempted to conditionalize the following */        \
+       /* so that ASI is only written if it changes, think again. */   \
+       __asm__ __volatile__("wr %%g0, %0, %%asi"                       \
+       : : "r" (__thread_flag_byte_ptr(task_thread_info(next))[TI_FLAG_BYTE_CURRENT_DS]));\
+       trap_block[current_thread_info()->cpu].thread =                 \
+               task_thread_info(next);                                 \
+       __asm__ __volatile__(                                           \
+       "mov    %%g4, %%g7\n\t"                                         \
+       "stx    %%i6, [%%sp + 2047 + 0x70]\n\t"                         \
+       "stx    %%i7, [%%sp + 2047 + 0x78]\n\t"                         \
+       "rdpr   %%wstate, %%o5\n\t"                                     \
+       "stx    %%o6, [%%g6 + %6]\n\t"                                  \
+       "stb    %%o5, [%%g6 + %5]\n\t"                                  \
+       "rdpr   %%cwp, %%o5\n\t"                                        \
+       "stb    %%o5, [%%g6 + %8]\n\t"                                  \
+       "mov    %4, %%g6\n\t"                                           \
+       "ldub   [%4 + %8], %%g1\n\t"                                    \
+       "wrpr   %%g1, %%cwp\n\t"                                        \
+       "ldx    [%%g6 + %6], %%o6\n\t"                                  \
+       "ldub   [%%g6 + %5], %%o5\n\t"                                  \
+       "ldub   [%%g6 + %7], %%o7\n\t"                                  \
+       "wrpr   %%o5, 0x0, %%wstate\n\t"                                \
+       "ldx    [%%sp + 2047 + 0x70], %%i6\n\t"                         \
+       "ldx    [%%sp + 2047 + 0x78], %%i7\n\t"                         \
+       "ldx    [%%g6 + %9], %%g4\n\t"                                  \
+       "brz,pt %%o7, switch_to_pc\n\t"                                 \
+       " mov   %%g7, %0\n\t"                                           \
+       "sethi  %%hi(ret_from_syscall), %%g1\n\t"                       \
+       "jmpl   %%g1 + %%lo(ret_from_syscall), %%g0\n\t"                \
+       " nop\n\t"                                                      \
+       ".globl switch_to_pc\n\t"                                       \
+       "switch_to_pc:\n\t"                                             \
+       : "=&r" (last), "=r" (current), "=r" (current_thread_info_reg), \
+         "=r" (__local_per_cpu_offset)                                 \
+       : "0" (task_thread_info(next)),                                 \
+         "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_NEW_CHILD),            \
+         "i" (TI_CWP), "i" (TI_TASK)                                   \
+       : "cc",                                                         \
+               "g1", "g2", "g3",                   "g7",               \
+               "l1", "l2", "l3", "l4", "l5", "l6", "l7",               \
+         "i0", "i1", "i2", "i3", "i4", "i5",                           \
+         "o0", "o1", "o2", "o3", "o4", "o5",       "o7");              \
+       /* If you fuck with this, update ret_from_syscall code too. */  \
+       if (test_thread_flag(TIF_PERFCTR)) {                            \
+               write_pcr(current_thread_info()->pcr_reg);              \
+               reset_pic();                                            \
+       }                                                               \
+} while(0)
+
+static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val)
+{
+       unsigned long tmp1, tmp2;
+
+       __asm__ __volatile__(
+"      membar          #StoreLoad | #LoadLoad\n"
+"      mov             %0, %1\n"
+"1:    lduw            [%4], %2\n"
+"      cas             [%4], %2, %0\n"
+"      cmp             %2, %0\n"
+"      bne,a,pn        %%icc, 1b\n"
+"       mov            %1, %0\n"
+"      membar          #StoreLoad | #StoreStore\n"
+       : "=&r" (val), "=&r" (tmp1), "=&r" (tmp2)
+       : "0" (val), "r" (m)
+       : "cc", "memory");
+       return val;
+}
+
+static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long val)
+{
+       unsigned long tmp1, tmp2;
+
+       __asm__ __volatile__(
+"      membar          #StoreLoad | #LoadLoad\n"
+"      mov             %0, %1\n"
+"1:    ldx             [%4], %2\n"
+"      casx            [%4], %2, %0\n"
+"      cmp             %2, %0\n"
+"      bne,a,pn        %%xcc, 1b\n"
+"       mov            %1, %0\n"
+"      membar          #StoreLoad | #StoreStore\n"
+       : "=&r" (val), "=&r" (tmp1), "=&r" (tmp2)
+       : "0" (val), "r" (m)
+       : "cc", "memory");
+       return val;
+}
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+extern void __xchg_called_with_bad_pointer(void);
+
+static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
+                                      int size)
+{
+       switch (size) {
+       case 4:
+               return xchg32(ptr, x);
+       case 8:
+               return xchg64(ptr, x);
+       };
+       __xchg_called_with_bad_pointer();
+       return x;
+}
+
+extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noreturn));
+
+/*
+ * Atomic compare and exchange.  Compare OLD with MEM, if identical,
+ * store NEW in MEM.  Return the initial value in MEM.  Success is
+ * indicated by comparing RETURN with OLD.
+ */
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+static inline unsigned long
+__cmpxchg_u32(volatile int *m, int old, int new)
+{
+       __asm__ __volatile__("membar #StoreLoad | #LoadLoad\n"
+                            "cas [%2], %3, %0\n\t"
+                            "membar #StoreLoad | #StoreStore"
+                            : "=&r" (new)
+                            : "0" (new), "r" (m), "r" (old)
+                            : "memory");
+
+       return new;
+}
+
+static inline unsigned long
+__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
+{
+       __asm__ __volatile__("membar #StoreLoad | #LoadLoad\n"
+                            "casx [%2], %3, %0\n\t"
+                            "membar #StoreLoad | #StoreStore"
+                            : "=&r" (new)
+                            : "0" (new), "r" (m), "r" (old)
+                            : "memory");
+
+       return new;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+   if something tries to do an invalid cmpxchg().  */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+{
+       switch (size) {
+               case 4:
+                       return __cmpxchg_u32(ptr, old, new);
+               case 8:
+                       return __cmpxchg_u64(ptr, old, new);
+       }
+       __cmpxchg_called_with_bad_pointer();
+       return old;
+}
+
+#define cmpxchg(ptr,o,n)                                                \
+  ({                                                                    \
+     __typeof__(*(ptr)) _o_ = (o);                                      \
+     __typeof__(*(ptr)) _n_ = (n);                                      \
+     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,          \
+                                   (unsigned long)_n_, sizeof(*(ptr))); \
+  })
+
+/*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+ * them available.
+ */
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+                                     unsigned long old,
+                                     unsigned long new, int size)
+{
+       switch (size) {
+       case 4:
+       case 8: return __cmpxchg(ptr, old, new, size);
+       default:
+               return __cmpxchg_local_generic(ptr, old, new, size);
+       }
+
+       return old;
+}
+
+#define cmpxchg_local(ptr, o, n)                                       \
+       ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
+                       (unsigned long)(n), sizeof(*(ptr))))
+#define cmpxchg64_local(ptr, o, n)                                     \
+  ({                                                                   \
+       BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
+       cmpxchg_local((ptr), (o), (n));                                 \
+  })
+
+#endif /* !(__ASSEMBLY__) */
+
+#define arch_align_stack(x) (x)
+
+#endif /* !(__SPARC64_SYSTEM_H) */
index 90cf2210118b809e19818d8334941c31252951ab..d6ca3e2754f5f37e792f3a060fed8bfc68a76305 100644 (file)
@@ -5,7 +5,12 @@
 
 typedef unsigned char   cc_t;
 typedef unsigned int    speed_t;
+
+#if defined(__sparc__) && defined(__arch64__)
+typedef unsigned int    tcflag_t;
+#else
 typedef unsigned long   tcflag_t;
+#endif
 
 #define NCC 8
 struct termio {
index f7b4409c35ffc9ed964b941f2d71f3632e2b9429..e8ba95399643399592e3699f756e374701f61518 100644 (file)
@@ -53,7 +53,6 @@ struct winsize {
 #define _VMIN  4
 #define _VTIME 5
 
-
 /*     intr=^C         quit=^\         erase=del       kill=^U
        eof=^D          eol=\0          eol2=\0         sxtc=\0
        start=^Q        stop=^S         susp=^Z         dsusp=^Y
@@ -68,16 +67,17 @@ struct winsize {
 #define user_termio_to_kernel_termios(termios, termio) \
 ({ \
        unsigned short tmp; \
-       get_user(tmp, &(termio)->c_iflag); \
+       int err; \
+       err = get_user(tmp, &(termio)->c_iflag); \
        (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
-       get_user(tmp, &(termio)->c_oflag); \
+       err |= get_user(tmp, &(termio)->c_oflag); \
        (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
-       get_user(tmp, &(termio)->c_cflag); \
+       err |= get_user(tmp, &(termio)->c_cflag); \
        (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
-       get_user(tmp, &(termio)->c_lflag); \
+       err |= get_user(tmp, &(termio)->c_lflag); \
        (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
-       copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
-       0; \
+       err |= copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+       err; \
 })
 
 /*
@@ -87,17 +87,18 @@ struct winsize {
  */
 #define kernel_termios_to_user_termio(termio, termios) \
 ({ \
-       put_user((termios)->c_iflag, &(termio)->c_iflag); \
-       put_user((termios)->c_oflag, &(termio)->c_oflag); \
-       put_user((termios)->c_cflag, &(termio)->c_cflag); \
-       put_user((termios)->c_lflag, &(termio)->c_lflag); \
-       put_user((termios)->c_line,  &(termio)->c_line); \
-       copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+       int err; \
+       err  = put_user((termios)->c_iflag, &(termio)->c_iflag); \
+       err |= put_user((termios)->c_oflag, &(termio)->c_oflag); \
+       err |= put_user((termios)->c_cflag, &(termio)->c_cflag); \
+       err |= put_user((termios)->c_lflag, &(termio)->c_lflag); \
+       err |= put_user((termios)->c_line,  &(termio)->c_line); \
+       err |= copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
        if (!((termios)->c_lflag & ICANON)) { \
-               put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
-               put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+               err |= put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+               err |= put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
        } \
-       0; \
+       err; \
 })
 
 #define user_termios_to_kernel_termios(k, u) \
@@ -144,38 +145,40 @@ struct winsize {
 
 #define user_termios_to_kernel_termios_1(k, u) \
 ({ \
-       get_user((k)->c_iflag, &(u)->c_iflag); \
-       get_user((k)->c_oflag, &(u)->c_oflag); \
-       get_user((k)->c_cflag, &(u)->c_cflag); \
-       get_user((k)->c_lflag, &(u)->c_lflag); \
-       get_user((k)->c_line,  &(u)->c_line); \
-       copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
+       int err; \
+       err  = get_user((k)->c_iflag, &(u)->c_iflag); \
+       err |= get_user((k)->c_oflag, &(u)->c_oflag); \
+       err |= get_user((k)->c_cflag, &(u)->c_cflag); \
+       err |= get_user((k)->c_lflag, &(u)->c_lflag); \
+       err |= get_user((k)->c_line,  &(u)->c_line); \
+       err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
        if ((k)->c_lflag & ICANON) { \
-               get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
-               get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+               err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+               err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
        } else { \
-               get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
-               get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+               err |= get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+               err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
        } \
-       0; \
+       err; \
 })
 
 #define kernel_termios_to_user_termios_1(u, k) \
 ({ \
-       put_user((k)->c_iflag, &(u)->c_iflag); \
-       put_user((k)->c_oflag, &(u)->c_oflag); \
-       put_user((k)->c_cflag, &(u)->c_cflag); \
-       put_user((k)->c_lflag, &(u)->c_lflag); \
-       put_user((k)->c_line, &(u)->c_line); \
-       copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
+       int err; \
+       err  = put_user((k)->c_iflag, &(u)->c_iflag); \
+       err |= put_user((k)->c_oflag, &(u)->c_oflag); \
+       err |= put_user((k)->c_cflag, &(u)->c_cflag); \
+       err |= put_user((k)->c_lflag, &(u)->c_lflag); \
+       err |= put_user((k)->c_line, &(u)->c_line); \
+       err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
        if (!((k)->c_lflag & ICANON)) { \
-               put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
-               put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+               err |= put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+               err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
        } else { \
-               put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
-               put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+               err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+               err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
        } \
-       0; \
+       err; \
 })
 
 #endif /* __KERNEL__ */
index 91b9f5888c855defa112d38ec20761a6664f1875..64155cf89f3706130c586bb5a0eebc2eb6ef87d8 100644 (file)
@@ -1,151 +1,8 @@
-/*
- * thread_info.h: sparc low-level thread information
- * adapted from the ppc version by Pete Zaitcev, which was
- * adapted from the i386 version by Paul Mackerras
- *
- * Copyright (C) 2002  David Howells (dhowells@redhat.com)
- * Copyright (c) 2002  Pete Zaitcev (zaitcev@yahoo.com)
- * - Incorporating suggestions made by Linus Torvalds and Dave Miller
- */
-
-#ifndef _ASM_THREAD_INFO_H
-#define _ASM_THREAD_INFO_H
-
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-
-#include <asm/btfixup.h>
-#include <asm/ptrace.h>
-#include <asm/page.h>
-
-/*
- * Low level task data.
- *
- * If you change this, change the TI_* offsets below to match.
- */
-#define NSWINS 8
-struct thread_info {
-       unsigned long           uwinmask;
-       struct task_struct      *task;          /* main task structure */
-       struct exec_domain      *exec_domain;   /* execution domain */
-       unsigned long           flags;          /* low level flags */
-       int                     cpu;            /* cpu we're on */
-       int                     preempt_count;  /* 0 => preemptable,
-                                                  <0 => BUG */
-       int                     softirq_count;
-       int                     hardirq_count;
-
-       /* Context switch saved kernel state. */
-       unsigned long ksp;      /* ... ksp __attribute__ ((aligned (8))); */
-       unsigned long kpc;
-       unsigned long kpsr;
-       unsigned long kwim;
-
-       /* A place to store user windows and stack pointers
-        * when the stack needs inspection.
-        */
-       struct reg_window       reg_window[NSWINS];     /* align for ldd! */
-       unsigned long           rwbuf_stkptrs[NSWINS];
-       unsigned long           w_saved;
-
-       struct restart_block    restart_block;
-};
-
-/*
- * macros/functions for gaining access to the thread information structure
- *
- * preempt_count needs to be 1 initially, until the scheduler is functional.
- */
-#define INIT_THREAD_INFO(tsk)                          \
-{                                                      \
-       .uwinmask       =       0,                      \
-       .task           =       &tsk,                   \
-       .exec_domain    =       &default_exec_domain,   \
-       .flags          =       0,                      \
-       .cpu            =       0,                      \
-       .preempt_count  =       1,                      \
-       .restart_block  = {                             \
-               .fn     =       do_no_restart_syscall,  \
-       },                                              \
-}
-
-#define init_thread_info       (init_thread_union.thread_info)
-#define init_stack             (init_thread_union.stack)
-
-/* how to get the thread information struct from C */
-register struct thread_info *current_thread_info_reg asm("g6");
-#define current_thread_info()   (current_thread_info_reg)
-
-/*
- * thread information allocation
- */
-#if PAGE_SHIFT == 13
-#define THREAD_INFO_ORDER  0
-#else /* PAGE_SHIFT */
-#define THREAD_INFO_ORDER  1
+#ifndef ___ASM_SPARC_THREAD_INFO_H
+#define ___ASM_SPARC_THREAD_INFO_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/thread_info_64.h>
+#else
+#include <asm-sparc/thread_info_32.h>
+#endif
 #endif
-
-BTFIXUPDEF_CALL(struct thread_info *, alloc_thread_info, void)
-#define alloc_thread_info(tsk) BTFIXUP_CALL(alloc_thread_info)()
-
-BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
-#define free_thread_info(ti) BTFIXUP_CALL(free_thread_info)(ti)
-
-#endif /* __ASSEMBLY__ */
-
-/*
- * Size of kernel stack for each process.
- * Observe the order of get_free_pages() in alloc_thread_info().
- * The sun4 has 8K stack too, because it's short on memory, and 16K is a waste.
- */
-#define THREAD_SIZE            8192
-
-/*
- * Offsets in thread_info structure, used in assembly code
- * The "#define REGWIN_SZ 0x40" was abolished, so no multiplications.
- */
-#define TI_UWINMASK    0x00    /* uwinmask */
-#define TI_TASK                0x04
-#define TI_EXECDOMAIN  0x08    /* exec_domain */
-#define TI_FLAGS       0x0c
-#define TI_CPU         0x10
-#define TI_PREEMPT     0x14    /* preempt_count */
-#define TI_SOFTIRQ     0x18    /* softirq_count */
-#define TI_HARDIRQ     0x1c    /* hardirq_count */
-#define TI_KSP         0x20    /* ksp */
-#define TI_KPC         0x24    /* kpc (ldd'ed with kpc) */
-#define TI_KPSR                0x28    /* kpsr */
-#define TI_KWIM                0x2c    /* kwim (ldd'ed with kpsr) */
-#define TI_REG_WINDOW  0x30
-#define TI_RWIN_SPTRS  0x230
-#define TI_W_SAVED     0x250
-/* #define TI_RESTART_BLOCK 0x25n */ /* Nobody cares */
-
-#define PREEMPT_ACTIVE         0x4000000
-
-/*
- * thread information flag bit numbers
- */
-#define TIF_SYSCALL_TRACE      0       /* syscall trace active */
-/* flag bit 1 is available */
-#define TIF_SIGPENDING         2       /* signal pending */
-#define TIF_NEED_RESCHED       3       /* rescheduling necessary */
-#define TIF_RESTORE_SIGMASK    4       /* restore signal mask in do_signal() */
-#define TIF_USEDFPU            8       /* FPU was used by this task
-                                        * this quantum (SMP) */
-#define TIF_POLLING_NRFLAG     9       /* true if poll_idle() is polling
-                                        * TIF_NEED_RESCHED */
-#define TIF_MEMDIE             10
-
-/* as above, but as bit values */
-#define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
-#define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
-#define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
-#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
-#define _TIF_USEDFPU           (1<<TIF_USEDFPU)
-#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_THREAD_INFO_H */
diff --git a/include/asm-sparc/thread_info_32.h b/include/asm-sparc/thread_info_32.h
new file mode 100644 (file)
index 0000000..91b9f58
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * thread_info.h: sparc low-level thread information
+ * adapted from the ppc version by Pete Zaitcev, which was
+ * adapted from the i386 version by Paul Mackerras
+ *
+ * Copyright (C) 2002  David Howells (dhowells@redhat.com)
+ * Copyright (c) 2002  Pete Zaitcev (zaitcev@yahoo.com)
+ * - Incorporating suggestions made by Linus Torvalds and Dave Miller
+ */
+
+#ifndef _ASM_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#include <asm/btfixup.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+
+/*
+ * Low level task data.
+ *
+ * If you change this, change the TI_* offsets below to match.
+ */
+#define NSWINS 8
+struct thread_info {
+       unsigned long           uwinmask;
+       struct task_struct      *task;          /* main task structure */
+       struct exec_domain      *exec_domain;   /* execution domain */
+       unsigned long           flags;          /* low level flags */
+       int                     cpu;            /* cpu we're on */
+       int                     preempt_count;  /* 0 => preemptable,
+                                                  <0 => BUG */
+       int                     softirq_count;
+       int                     hardirq_count;
+
+       /* Context switch saved kernel state. */
+       unsigned long ksp;      /* ... ksp __attribute__ ((aligned (8))); */
+       unsigned long kpc;
+       unsigned long kpsr;
+       unsigned long kwim;
+
+       /* A place to store user windows and stack pointers
+        * when the stack needs inspection.
+        */
+       struct reg_window       reg_window[NSWINS];     /* align for ldd! */
+       unsigned long           rwbuf_stkptrs[NSWINS];
+       unsigned long           w_saved;
+
+       struct restart_block    restart_block;
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+#define INIT_THREAD_INFO(tsk)                          \
+{                                                      \
+       .uwinmask       =       0,                      \
+       .task           =       &tsk,                   \
+       .exec_domain    =       &default_exec_domain,   \
+       .flags          =       0,                      \
+       .cpu            =       0,                      \
+       .preempt_count  =       1,                      \
+       .restart_block  = {                             \
+               .fn     =       do_no_restart_syscall,  \
+       },                                              \
+}
+
+#define init_thread_info       (init_thread_union.thread_info)
+#define init_stack             (init_thread_union.stack)
+
+/* how to get the thread information struct from C */
+register struct thread_info *current_thread_info_reg asm("g6");
+#define current_thread_info()   (current_thread_info_reg)
+
+/*
+ * thread information allocation
+ */
+#if PAGE_SHIFT == 13
+#define THREAD_INFO_ORDER  0
+#else /* PAGE_SHIFT */
+#define THREAD_INFO_ORDER  1
+#endif
+
+BTFIXUPDEF_CALL(struct thread_info *, alloc_thread_info, void)
+#define alloc_thread_info(tsk) BTFIXUP_CALL(alloc_thread_info)()
+
+BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
+#define free_thread_info(ti) BTFIXUP_CALL(free_thread_info)(ti)
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Size of kernel stack for each process.
+ * Observe the order of get_free_pages() in alloc_thread_info().
+ * The sun4 has 8K stack too, because it's short on memory, and 16K is a waste.
+ */
+#define THREAD_SIZE            8192
+
+/*
+ * Offsets in thread_info structure, used in assembly code
+ * The "#define REGWIN_SZ 0x40" was abolished, so no multiplications.
+ */
+#define TI_UWINMASK    0x00    /* uwinmask */
+#define TI_TASK                0x04
+#define TI_EXECDOMAIN  0x08    /* exec_domain */
+#define TI_FLAGS       0x0c
+#define TI_CPU         0x10
+#define TI_PREEMPT     0x14    /* preempt_count */
+#define TI_SOFTIRQ     0x18    /* softirq_count */
+#define TI_HARDIRQ     0x1c    /* hardirq_count */
+#define TI_KSP         0x20    /* ksp */
+#define TI_KPC         0x24    /* kpc (ldd'ed with kpc) */
+#define TI_KPSR                0x28    /* kpsr */
+#define TI_KWIM                0x2c    /* kwim (ldd'ed with kpsr) */
+#define TI_REG_WINDOW  0x30
+#define TI_RWIN_SPTRS  0x230
+#define TI_W_SAVED     0x250
+/* #define TI_RESTART_BLOCK 0x25n */ /* Nobody cares */
+
+#define PREEMPT_ACTIVE         0x4000000
+
+/*
+ * thread information flag bit numbers
+ */
+#define TIF_SYSCALL_TRACE      0       /* syscall trace active */
+/* flag bit 1 is available */
+#define TIF_SIGPENDING         2       /* signal pending */
+#define TIF_NEED_RESCHED       3       /* rescheduling necessary */
+#define TIF_RESTORE_SIGMASK    4       /* restore signal mask in do_signal() */
+#define TIF_USEDFPU            8       /* FPU was used by this task
+                                        * this quantum (SMP) */
+#define TIF_POLLING_NRFLAG     9       /* true if poll_idle() is polling
+                                        * TIF_NEED_RESCHED */
+#define TIF_MEMDIE             10
+
+/* as above, but as bit values */
+#define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
+#define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
+#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
+#define _TIF_USEDFPU           (1<<TIF_USEDFPU)
+#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_THREAD_INFO_H */
diff --git a/include/asm-sparc/thread_info_64.h b/include/asm-sparc/thread_info_64.h
new file mode 100644 (file)
index 0000000..c6d2e6c
--- /dev/null
@@ -0,0 +1,277 @@
+/* thread_info.h: sparc64 low-level thread information
+ *
+ * Copyright (C) 2002  David S. Miller (davem@redhat.com)
+ */
+
+#ifndef _ASM_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#define NSWINS         7
+
+#define TI_FLAG_BYTE_FAULT_CODE                0
+#define TI_FLAG_FAULT_CODE_SHIFT       56
+#define TI_FLAG_BYTE_WSTATE            1
+#define TI_FLAG_WSTATE_SHIFT           48
+#define TI_FLAG_BYTE_CWP               2
+#define TI_FLAG_CWP_SHIFT              40
+#define TI_FLAG_BYTE_CURRENT_DS                3
+#define TI_FLAG_CURRENT_DS_SHIFT       32
+#define TI_FLAG_BYTE_FPDEPTH           4
+#define TI_FLAG_FPDEPTH_SHIFT          24
+#define TI_FLAG_BYTE_WSAVED            5
+#define TI_FLAG_WSAVED_SHIFT           16
+
+#include <asm/page.h>
+
+#ifndef __ASSEMBLY__
+
+#include <asm/ptrace.h>
+#include <asm/types.h>
+
+struct task_struct;
+struct exec_domain;
+
+struct thread_info {
+       /* D$ line 1 */
+       struct task_struct      *task;
+       unsigned long           flags;
+       __u8                    fpsaved[7];
+       __u8                    status;
+       unsigned long           ksp;
+
+       /* D$ line 2 */
+       unsigned long           fault_address;
+       struct pt_regs          *kregs;
+       struct exec_domain      *exec_domain;
+       int                     preempt_count;  /* 0 => preemptable, <0 => BUG */
+       __u8                    new_child;
+       __u8                    syscall_noerror;
+       __u16                   cpu;
+
+       unsigned long           *utraps;
+
+       struct reg_window       reg_window[NSWINS];
+       unsigned long           rwbuf_stkptrs[NSWINS];
+
+       unsigned long           gsr[7];
+       unsigned long           xfsr[7];
+
+       __u64                   __user *user_cntd0;
+       __u64                   __user *user_cntd1;
+       __u64                   kernel_cntd0, kernel_cntd1;
+       __u64                   pcr_reg;
+
+       struct restart_block    restart_block;
+
+       struct pt_regs          *kern_una_regs;
+       unsigned int            kern_una_insn;
+
+       unsigned long           fpregs[0] __attribute__ ((aligned(64)));
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+/* offsets into the thread_info struct for assembly code access */
+#define TI_TASK                0x00000000
+#define TI_FLAGS       0x00000008
+#define TI_FAULT_CODE  (TI_FLAGS + TI_FLAG_BYTE_FAULT_CODE)
+#define TI_WSTATE      (TI_FLAGS + TI_FLAG_BYTE_WSTATE)
+#define TI_CWP         (TI_FLAGS + TI_FLAG_BYTE_CWP)
+#define TI_CURRENT_DS  (TI_FLAGS + TI_FLAG_BYTE_CURRENT_DS)
+#define TI_FPDEPTH     (TI_FLAGS + TI_FLAG_BYTE_FPDEPTH)
+#define TI_WSAVED      (TI_FLAGS + TI_FLAG_BYTE_WSAVED)
+#define TI_FPSAVED     0x00000010
+#define TI_KSP         0x00000018
+#define TI_FAULT_ADDR  0x00000020
+#define TI_KREGS       0x00000028
+#define TI_EXEC_DOMAIN 0x00000030
+#define TI_PRE_COUNT   0x00000038
+#define TI_NEW_CHILD   0x0000003c
+#define TI_SYS_NOERROR 0x0000003d
+#define TI_CPU         0x0000003e
+#define TI_UTRAPS      0x00000040
+#define TI_REG_WINDOW  0x00000048
+#define TI_RWIN_SPTRS  0x000003c8
+#define TI_GSR         0x00000400
+#define TI_XFSR                0x00000438
+#define TI_USER_CNTD0  0x00000470
+#define TI_USER_CNTD1  0x00000478
+#define TI_KERN_CNTD0  0x00000480
+#define TI_KERN_CNTD1  0x00000488
+#define TI_PCR         0x00000490
+#define TI_RESTART_BLOCK 0x00000498
+#define TI_KUNA_REGS   0x000004c0
+#define TI_KUNA_INSN   0x000004c8
+#define TI_FPREGS      0x00000500
+
+/* We embed this in the uppermost byte of thread_info->flags */
+#define FAULT_CODE_WRITE       0x01    /* Write access, implies D-TLB     */
+#define FAULT_CODE_DTLB                0x02    /* Miss happened in D-TLB          */
+#define FAULT_CODE_ITLB                0x04    /* Miss happened in I-TLB          */
+#define FAULT_CODE_WINFIXUP    0x08    /* Miss happened during spill/fill */
+#define FAULT_CODE_BLKCOMMIT   0x10    /* Use blk-commit ASI in copy_page */
+
+#if PAGE_SHIFT == 13
+#define THREAD_SIZE (2*PAGE_SIZE)
+#define THREAD_SHIFT (PAGE_SHIFT + 1)
+#else /* PAGE_SHIFT == 13 */
+#define THREAD_SIZE PAGE_SIZE
+#define THREAD_SHIFT PAGE_SHIFT
+#endif /* PAGE_SHIFT == 13 */
+
+#define PREEMPT_ACTIVE         0x4000000
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+#ifndef __ASSEMBLY__
+
+#define INIT_THREAD_INFO(tsk)                          \
+{                                                      \
+       .task           =       &tsk,                   \
+       .flags          = ((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT,   \
+       .exec_domain    =       &default_exec_domain,   \
+       .preempt_count  =       1,                      \
+       .restart_block  = {                             \
+               .fn     =       do_no_restart_syscall,  \
+       },                                              \
+}
+
+#define init_thread_info       (init_thread_union.thread_info)
+#define init_stack             (init_thread_union.stack)
+
+/* how to get the thread information struct from C */
+register struct thread_info *current_thread_info_reg asm("g6");
+#define current_thread_info()  (current_thread_info_reg)
+
+/* thread information allocation */
+#if PAGE_SHIFT == 13
+#define __THREAD_INFO_ORDER    1
+#else /* PAGE_SHIFT == 13 */
+#define __THREAD_INFO_ORDER    0
+#endif /* PAGE_SHIFT == 13 */
+
+#ifdef CONFIG_DEBUG_STACK_USAGE
+#define alloc_thread_info(tsk)                                 \
+({                                                             \
+       struct thread_info *ret;                                \
+                                                               \
+       ret = (struct thread_info *)                            \
+         __get_free_pages(GFP_KERNEL, __THREAD_INFO_ORDER);    \
+       if (ret)                                                \
+               memset(ret, 0, PAGE_SIZE<<__THREAD_INFO_ORDER); \
+       ret;                                                    \
+})
+#else
+#define alloc_thread_info(tsk) \
+       ((struct thread_info *)__get_free_pages(GFP_KERNEL, __THREAD_INFO_ORDER))
+#endif
+
+#define free_thread_info(ti) \
+       free_pages((unsigned long)(ti),__THREAD_INFO_ORDER)
+
+#define __thread_flag_byte_ptr(ti)     \
+       ((unsigned char *)(&((ti)->flags)))
+#define __cur_thread_flag_byte_ptr     __thread_flag_byte_ptr(current_thread_info())
+
+#define get_thread_fault_code()                (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FAULT_CODE])
+#define set_thread_fault_code(val)     (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FAULT_CODE] = (val))
+#define get_thread_wstate()            (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE])
+#define set_thread_wstate(val)         (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE] = (val))
+#define get_thread_cwp()               (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP])
+#define set_thread_cwp(val)            (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP] = (val))
+#define get_thread_current_ds()                (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS])
+#define set_thread_current_ds(val)     (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS] = (val))
+#define get_thread_fpdepth()           (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH])
+#define set_thread_fpdepth(val)                (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH] = (val))
+#define get_thread_wsaved()            (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED])
+#define set_thread_wsaved(val)         (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED] = (val))
+
+#endif /* !(__ASSEMBLY__) */
+
+/*
+ * Thread information flags, only 16 bits are available as we encode
+ * other values into the upper 6 bytes.
+ *
+ * On trap return we need to test several values:
+ *
+ * user:       need_resched, notify_resume, sigpending, wsaved, perfctr
+ * kernel:     fpdepth
+ *
+ * So to check for work in the kernel case we simply load the fpdepth
+ * byte out of the flags and test it.  For the user case we encode the
+ * lower 3 bytes of flags as follows:
+ *     ----------------------------------------
+ *     | wsaved | flags byte 1 | flags byte 2 |
+ *     ----------------------------------------
+ * This optimizes the user test into:
+ *     ldx             [%g6 + TI_FLAGS], REG1
+ *     sethi           %hi(_TIF_USER_WORK_MASK), REG2
+ *     or              REG2, %lo(_TIF_USER_WORK_MASK), REG2
+ *     andcc           REG1, REG2, %g0
+ *     be,pt           no_work_to_do
+ *      nop
+ */
+#define TIF_SYSCALL_TRACE      0       /* syscall trace active */
+/* flags bit 1 is available */
+#define TIF_SIGPENDING         2       /* signal pending */
+#define TIF_NEED_RESCHED       3       /* rescheduling necessary */
+#define TIF_PERFCTR            4       /* performance counters active */
+#define TIF_UNALIGNED          5       /* allowed to do unaligned accesses */
+/* flag bit 6 is available */
+#define TIF_32BIT              7       /* 32-bit binary */
+/* flag bit 8 is available */
+#define TIF_SECCOMP            9       /* secure computing */
+#define TIF_SYSCALL_AUDIT      10      /* syscall auditing active */
+/* flag bit 11 is available */
+/* NOTE: Thread flags >= 12 should be ones we have no interest
+ *       in using in assembly, else we can't use the mask as
+ *       an immediate value in instructions such as andcc.
+ */
+#define TIF_ABI_PENDING                12
+#define TIF_MEMDIE             13
+#define TIF_POLLING_NRFLAG     14
+
+#define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
+#define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
+#define _TIF_PERFCTR           (1<<TIF_PERFCTR)
+#define _TIF_UNALIGNED         (1<<TIF_UNALIGNED)
+#define _TIF_32BIT             (1<<TIF_32BIT)
+#define _TIF_SECCOMP           (1<<TIF_SECCOMP)
+#define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_ABI_PENDING       (1<<TIF_ABI_PENDING)
+#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
+
+#define _TIF_USER_WORK_MASK    ((0xff << TI_FLAG_WSAVED_SHIFT) | \
+                                (_TIF_SIGPENDING | \
+                                 _TIF_NEED_RESCHED | _TIF_PERFCTR))
+
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ *
+ * Note that there are only 8 bits available.
+ */
+#define TS_RESTORE_SIGMASK     0x0001  /* restore signal mask in do_signal() */
+
+#ifndef __ASSEMBLY__
+#define HAVE_SET_RESTORE_SIGMASK       1
+static inline void set_restore_sigmask(void)
+{
+       struct thread_info *ti = current_thread_info();
+       ti->status |= TS_RESTORE_SIGMASK;
+       set_bit(TIF_SIGPENDING, &ti->flags);
+}
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_THREAD_INFO_H */
index d909565f9410cf267202805bcdc585fbc92b65c5..475baa05a96eff30f0a5a71e7ac2b9b5b923b9e8 100644 (file)
@@ -1,109 +1,8 @@
-/*
- * timer.h:  Definitions for the timer chips on the Sparc.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-
-
-#ifndef _SPARC_TIMER_H
-#define _SPARC_TIMER_H
-
-#include <asm/system.h>  /* For SUN4M_NCPUS */
-#include <asm/sun4paddr.h>
-#include <asm/btfixup.h>
-
-/* Timer structures. The interrupt timer has two properties which
- * are the counter (which is handled in do_timer in sched.c) and the limit.
- * This limit is where the timer's counter 'wraps' around. Oddly enough,
- * the sun4c timer when it hits the limit wraps back to 1 and not zero
- * thus when calculating the value at which it will fire a microsecond you
- * must adjust by one.  Thanks SUN for designing such great hardware ;(
- */
-
-/* Note that I am only going to use the timer that interrupts at
- * Sparc IRQ 10.  There is another one available that can fire at
- * IRQ 14. Currently it is left untouched, we keep the PROM's limit
- * register value and let the prom take these interrupts.  This allows
- * L1-A to work.
- */
-
-struct sun4c_timer_info {
-  __volatile__ unsigned int cur_count10;
-  __volatile__ unsigned int timer_limit10;
-  __volatile__ unsigned int cur_count14;
-  __volatile__ unsigned int timer_limit14;
-};
-
-#define SUN4C_TIMER_PHYSADDR   0xf3000000
-#ifdef CONFIG_SUN4
-#define SUN_TIMER_PHYSADDR SUN4_300_TIMER_PHYSADDR
+#ifndef ___ASM_SPARC_TIMER_H
+#define ___ASM_SPARC_TIMER_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/timer_64.h>
 #else
-#define SUN_TIMER_PHYSADDR SUN4C_TIMER_PHYSADDR
+#include <asm-sparc/timer_32.h>
+#endif
 #endif
-
-/* A sun4m has two blocks of registers which are probably of the same
- * structure. LSI Logic's L64851 is told to _decrement_ from the limit
- * value. Aurora behaves similarly but its limit value is compacted in
- * other fashion (it's wider). Documented fields are defined here.
- */
-
-/* As with the interrupt register, we have two classes of timer registers
- * which are per-cpu and master.  Per-cpu timers only hit that cpu and are
- * only level 14 ticks, master timer hits all cpus and is level 10.
- */
-
-#define SUN4M_PRM_CNT_L       0x80000000
-#define SUN4M_PRM_CNT_LVALUE  0x7FFFFC00
-
-struct sun4m_timer_percpu_info {
-  __volatile__ unsigned int l14_timer_limit;    /* Initial value is 0x009c4000 */
-  __volatile__ unsigned int l14_cur_count;
-
-  /* This register appears to be write only and/or inaccessible
-   * on Uni-Processor sun4m machines.
-   */
-  __volatile__ unsigned int l14_limit_noclear;  /* Data access error is here */
-
-  __volatile__ unsigned int cntrl;            /* =1 after POST on Aurora */
-  __volatile__ unsigned char space[PAGE_SIZE - 16];
-};
-
-struct sun4m_timer_regs {
-       struct sun4m_timer_percpu_info cpu_timers[SUN4M_NCPUS];
-       volatile unsigned int l10_timer_limit;
-       volatile unsigned int l10_cur_count;
-
-       /* Again, this appears to be write only and/or inaccessible
-        * on uni-processor sun4m machines.
-        */
-       volatile unsigned int l10_limit_noclear;
-
-       /* This register too, it must be magic. */
-       volatile unsigned int foobar;
-
-       volatile unsigned int cfg;     /* equals zero at boot time... */
-};
-
-extern struct sun4m_timer_regs *sun4m_timers;
-
-#define SUN4D_PRM_CNT_L       0x80000000
-#define SUN4D_PRM_CNT_LVALUE  0x7FFFFC00
-
-struct sun4d_timer_regs {
-       volatile unsigned int l10_timer_limit;
-       volatile unsigned int l10_cur_countx;
-       volatile unsigned int l10_limit_noclear;
-       volatile unsigned int ctrl;
-       volatile unsigned int l10_cur_count;
-};
-
-extern struct sun4d_timer_regs *sun4d_timers;
-
-extern __volatile__ unsigned int *master_l10_counter;
-extern __volatile__ unsigned int *master_l10_limit;
-
-/* FIXME: Make do_[gs]ettimeofday btfixup calls */
-BTFIXUPDEF_CALL(int, bus_do_settimeofday, struct timespec *tv)
-#define bus_do_settimeofday(tv) BTFIXUP_CALL(bus_do_settimeofday)(tv)
-
-#endif /* !(_SPARC_TIMER_H) */
diff --git a/include/asm-sparc/timer_32.h b/include/asm-sparc/timer_32.h
new file mode 100644 (file)
index 0000000..361e538
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * timer.h:  Definitions for the timer chips on the Sparc.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+
+#ifndef _SPARC_TIMER_H
+#define _SPARC_TIMER_H
+
+#include <asm/system.h>  /* For SUN4M_NCPUS */
+#include <asm/sun4paddr.h>
+#include <asm/btfixup.h>
+
+/* Timer structures. The interrupt timer has two properties which
+ * are the counter (which is handled in do_timer in sched.c) and the limit.
+ * This limit is where the timer's counter 'wraps' around. Oddly enough,
+ * the sun4c timer when it hits the limit wraps back to 1 and not zero
+ * thus when calculating the value at which it will fire a microsecond you
+ * must adjust by one.  Thanks SUN for designing such great hardware ;(
+ */
+
+/* Note that I am only going to use the timer that interrupts at
+ * Sparc IRQ 10.  There is another one available that can fire at
+ * IRQ 14. Currently it is left untouched, we keep the PROM's limit
+ * register value and let the prom take these interrupts.  This allows
+ * L1-A to work.
+ */
+
+struct sun4c_timer_info {
+  __volatile__ unsigned int cur_count10;
+  __volatile__ unsigned int timer_limit10;
+  __volatile__ unsigned int cur_count14;
+  __volatile__ unsigned int timer_limit14;
+};
+
+#define SUN4C_TIMER_PHYSADDR   0xf3000000
+#ifdef CONFIG_SUN4
+#define SUN_TIMER_PHYSADDR SUN4_300_TIMER_PHYSADDR
+#else
+#define SUN_TIMER_PHYSADDR SUN4C_TIMER_PHYSADDR
+#endif
+
+/* A sun4m has two blocks of registers which are probably of the same
+ * structure. LSI Logic's L64851 is told to _decrement_ from the limit
+ * value. Aurora behaves similarly but its limit value is compacted in
+ * other fashion (it's wider). Documented fields are defined here.
+ */
+
+/* As with the interrupt register, we have two classes of timer registers
+ * which are per-cpu and master.  Per-cpu timers only hit that cpu and are
+ * only level 14 ticks, master timer hits all cpus and is level 10.
+ */
+
+#define SUN4M_PRM_CNT_L       0x80000000
+#define SUN4M_PRM_CNT_LVALUE  0x7FFFFC00
+
+struct sun4m_timer_percpu_info {
+  __volatile__ unsigned int l14_timer_limit;    /* Initial value is 0x009c4000 */
+  __volatile__ unsigned int l14_cur_count;
+
+  /* This register appears to be write only and/or inaccessible
+   * on Uni-Processor sun4m machines.
+   */
+  __volatile__ unsigned int l14_limit_noclear;  /* Data access error is here */
+
+  __volatile__ unsigned int cntrl;            /* =1 after POST on Aurora */
+  __volatile__ unsigned char space[PAGE_SIZE - 16];
+};
+
+struct sun4m_timer_regs {
+       struct sun4m_timer_percpu_info cpu_timers[SUN4M_NCPUS];
+       volatile unsigned int l10_timer_limit;
+       volatile unsigned int l10_cur_count;
+
+       /* Again, this appears to be write only and/or inaccessible
+        * on uni-processor sun4m machines.
+        */
+       volatile unsigned int l10_limit_noclear;
+
+       /* This register too, it must be magic. */
+       volatile unsigned int foobar;
+
+       volatile unsigned int cfg;     /* equals zero at boot time... */
+};
+
+#define SUN4D_PRM_CNT_L       0x80000000
+#define SUN4D_PRM_CNT_LVALUE  0x7FFFFC00
+
+struct sun4d_timer_regs {
+       volatile unsigned int l10_timer_limit;
+       volatile unsigned int l10_cur_countx;
+       volatile unsigned int l10_limit_noclear;
+       volatile unsigned int ctrl;
+       volatile unsigned int l10_cur_count;
+};
+
+extern struct sun4d_timer_regs *sun4d_timers;
+
+extern __volatile__ unsigned int *master_l10_counter;
+extern __volatile__ unsigned int *master_l10_limit;
+
+/* FIXME: Make do_[gs]ettimeofday btfixup calls */
+BTFIXUPDEF_CALL(int, bus_do_settimeofday, struct timespec *tv)
+#define bus_do_settimeofday(tv) BTFIXUP_CALL(bus_do_settimeofday)(tv)
+
+#endif /* !(_SPARC_TIMER_H) */
diff --git a/include/asm-sparc/timer_64.h b/include/asm-sparc/timer_64.h
new file mode 100644 (file)
index 0000000..5b779fd
--- /dev/null
@@ -0,0 +1,30 @@
+/* timer.h: System timer definitions for sun5.
+ *
+ * Copyright (C) 1997, 2008 David S. Miller (davem@davemloft.net)
+ */
+
+#ifndef _SPARC64_TIMER_H
+#define _SPARC64_TIMER_H
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+struct sparc64_tick_ops {
+       unsigned long (*get_tick)(void);
+       int (*add_compare)(unsigned long);
+       unsigned long softint_mask;
+       void (*disable_irq)(void);
+
+       void (*init_tick)(void);
+       unsigned long (*add_tick)(unsigned long);
+
+       char *name;
+};
+
+extern struct sparc64_tick_ops *tick_ops;
+
+extern unsigned long sparc64_get_clock_tick(unsigned int cpu);
+extern void __devinit setup_sparc64_timer(void);
+extern void __init time_init(void);
+
+#endif /* _SPARC64_TIMER_H */
index 71b45c90ccae3d5db1959b755d5ad4e7690b386e..01d9f199d45243c1025fcbf15c48c4c79d47af01 100644 (file)
@@ -1,15 +1,8 @@
-/*
- * linux/include/asm-sparc/timex.h
- *
- * sparc architecture timex specifications
- */
-#ifndef _ASMsparc_TIMEX_H
-#define _ASMsparc_TIMEX_H
-
-#define CLOCK_TICK_RATE        1193180 /* Underlying HZ */
-
-/* XXX Maybe do something better at some point... -DaveM */
-typedef unsigned long cycles_t;
-#define get_cycles()   (0)
-
+#ifndef ___ASM_SPARC_TIMEX_H
+#define ___ASM_SPARC_TIMEX_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/timex_64.h>
+#else
+#include <asm-sparc/timex_32.h>
+#endif
 #endif
diff --git a/include/asm-sparc/timex_32.h b/include/asm-sparc/timex_32.h
new file mode 100644 (file)
index 0000000..71b45c9
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * linux/include/asm-sparc/timex.h
+ *
+ * sparc architecture timex specifications
+ */
+#ifndef _ASMsparc_TIMEX_H
+#define _ASMsparc_TIMEX_H
+
+#define CLOCK_TICK_RATE        1193180 /* Underlying HZ */
+
+/* XXX Maybe do something better at some point... -DaveM */
+typedef unsigned long cycles_t;
+#define get_cycles()   (0)
+
+#endif
diff --git a/include/asm-sparc/timex_64.h b/include/asm-sparc/timex_64.h
new file mode 100644 (file)
index 0000000..c622535
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * linux/include/asm-sparc64/timex.h
+ *
+ * sparc64 architecture timex specifications
+ */
+#ifndef _ASMsparc64_TIMEX_H
+#define _ASMsparc64_TIMEX_H
+
+#include <asm/timer.h>
+
+#define CLOCK_TICK_RATE        1193180 /* Underlying HZ */
+
+/* Getting on the cycle counter on sparc64. */
+typedef unsigned long cycles_t;
+#define get_cycles()   tick_ops->get_tick()
+
+#define ARCH_HAS_READ_CURRENT_TIMER
+
+#endif
index 6d02d1ce53f31b691eb86814dc6af81131ec99b2..a821057327c4994d34544d87c9aab549b40971c0 100644 (file)
@@ -1,24 +1,8 @@
-#ifndef _SPARC_TLB_H
-#define _SPARC_TLB_H
-
-#define tlb_start_vma(tlb, vma) \
-do {                                                           \
-       flush_cache_range(vma, vma->vm_start, vma->vm_end);     \
-} while (0)
-
-#define tlb_end_vma(tlb, vma) \
-do {                                                           \
-       flush_tlb_range(vma, vma->vm_start, vma->vm_end);       \
-} while (0)
-
-#define __tlb_remove_tlb_entry(tlb, pte, address) \
-       do { } while (0)
-
-#define tlb_flush(tlb) \
-do {                                                           \
-       flush_tlb_mm((tlb)->mm);                                \
-} while (0)
-
-#include <asm-generic/tlb.h>
-
-#endif /* _SPARC_TLB_H */
+#ifndef ___ASM_SPARC_TLB_H
+#define ___ASM_SPARC_TLB_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/tlb_64.h>
+#else
+#include <asm-sparc/tlb_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/tlb_32.h b/include/asm-sparc/tlb_32.h
new file mode 100644 (file)
index 0000000..6d02d1c
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _SPARC_TLB_H
+#define _SPARC_TLB_H
+
+#define tlb_start_vma(tlb, vma) \
+do {                                                           \
+       flush_cache_range(vma, vma->vm_start, vma->vm_end);     \
+} while (0)
+
+#define tlb_end_vma(tlb, vma) \
+do {                                                           \
+       flush_tlb_range(vma, vma->vm_start, vma->vm_end);       \
+} while (0)
+
+#define __tlb_remove_tlb_entry(tlb, pte, address) \
+       do { } while (0)
+
+#define tlb_flush(tlb) \
+do {                                                           \
+       flush_tlb_mm((tlb)->mm);                                \
+} while (0)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _SPARC_TLB_H */
diff --git a/include/asm-sparc/tlb_64.h b/include/asm-sparc/tlb_64.h
new file mode 100644 (file)
index 0000000..ec81cde
--- /dev/null
@@ -0,0 +1,111 @@
+#ifndef _SPARC64_TLB_H
+#define _SPARC64_TLB_H
+
+#include <linux/swap.h>
+#include <linux/pagemap.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+
+#define TLB_BATCH_NR   192
+
+/*
+ * For UP we don't need to worry about TLB flush
+ * and page free order so much..
+ */
+#ifdef CONFIG_SMP
+  #define FREE_PTE_NR  506
+  #define tlb_fast_mode(bp) ((bp)->pages_nr == ~0U)
+#else
+  #define FREE_PTE_NR  1
+  #define tlb_fast_mode(bp) 1
+#endif
+
+struct mmu_gather {
+       struct mm_struct *mm;
+       unsigned int pages_nr;
+       unsigned int need_flush;
+       unsigned int fullmm;
+       unsigned int tlb_nr;
+       unsigned long vaddrs[TLB_BATCH_NR];
+       struct page *pages[FREE_PTE_NR];
+};
+
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+#ifdef CONFIG_SMP
+extern void smp_flush_tlb_pending(struct mm_struct *,
+                                 unsigned long, unsigned long *);
+#endif
+
+extern void __flush_tlb_pending(unsigned long, unsigned long, unsigned long *);
+extern void flush_tlb_pending(void);
+
+static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+{
+       struct mmu_gather *mp = &get_cpu_var(mmu_gathers);
+
+       BUG_ON(mp->tlb_nr);
+
+       mp->mm = mm;
+       mp->pages_nr = num_online_cpus() > 1 ? 0U : ~0U;
+       mp->fullmm = full_mm_flush;
+
+       return mp;
+}
+
+
+static inline void tlb_flush_mmu(struct mmu_gather *mp)
+{
+       if (mp->need_flush) {
+               free_pages_and_swap_cache(mp->pages, mp->pages_nr);
+               mp->pages_nr = 0;
+               mp->need_flush = 0;
+       }
+
+}
+
+#ifdef CONFIG_SMP
+extern void smp_flush_tlb_mm(struct mm_struct *mm);
+#define do_flush_tlb_mm(mm) smp_flush_tlb_mm(mm)
+#else
+#define do_flush_tlb_mm(mm) __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT)
+#endif
+
+static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, unsigned long end)
+{
+       tlb_flush_mmu(mp);
+
+       if (mp->fullmm)
+               mp->fullmm = 0;
+       else
+               flush_tlb_pending();
+
+       /* keep the page table cache within bounds */
+       check_pgt_cache();
+
+       put_cpu_var(mmu_gathers);
+}
+
+static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page)
+{
+       if (tlb_fast_mode(mp)) {
+               free_page_and_swap_cache(page);
+               return;
+       }
+       mp->need_flush = 1;
+       mp->pages[mp->pages_nr++] = page;
+       if (mp->pages_nr >= FREE_PTE_NR)
+               tlb_flush_mmu(mp);
+}
+
+#define tlb_remove_tlb_entry(mp,ptep,addr) do { } while (0)
+#define pte_free_tlb(mp, ptepage) pte_free((mp)->mm, ptepage)
+#define pmd_free_tlb(mp, pmdp) pmd_free((mp)->mm, pmdp)
+#define pud_free_tlb(tlb,pudp) __pud_free_tlb(tlb,pudp)
+
+#define tlb_migrate_finish(mm) do { } while (0)
+#define tlb_start_vma(tlb, vma) do { } while (0)
+#define tlb_end_vma(tlb, vma)  do { } while (0)
+
+#endif /* _SPARC64_TLB_H */
index b957e29d2ae186510f627094e69699ea3ec41f18..6e6bc12227b86f180108a1df5f26f01b07917aa6 100644 (file)
@@ -1,60 +1,8 @@
-#ifndef _SPARC_TLBFLUSH_H
-#define _SPARC_TLBFLUSH_H
-
-#include <linux/mm.h>
-// #include <asm/processor.h>
-
-/*
- * TLB flushing:
- *
- *  - flush_tlb() flushes the current mm struct TLBs   XXX Exists?
- *  - flush_tlb_all() flushes all processes TLBs 
- *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
- *  - flush_tlb_page(vma, vmaddr) flushes one page
- *  - flush_tlb_range(vma, start, end) flushes a range of pages
- *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- */
-
-#ifdef CONFIG_SMP
-
-BTFIXUPDEF_CALL(void, local_flush_tlb_all, void)
-BTFIXUPDEF_CALL(void, local_flush_tlb_mm, struct mm_struct *)
-BTFIXUPDEF_CALL(void, local_flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(void, local_flush_tlb_page, struct vm_area_struct *, unsigned long)
-
-#define local_flush_tlb_all() BTFIXUP_CALL(local_flush_tlb_all)()
-#define local_flush_tlb_mm(mm) BTFIXUP_CALL(local_flush_tlb_mm)(mm)
-#define local_flush_tlb_range(vma,start,end) BTFIXUP_CALL(local_flush_tlb_range)(vma,start,end)
-#define local_flush_tlb_page(vma,addr) BTFIXUP_CALL(local_flush_tlb_page)(vma,addr)
-
-extern void smp_flush_tlb_all(void);
-extern void smp_flush_tlb_mm(struct mm_struct *mm);
-extern void smp_flush_tlb_range(struct vm_area_struct *vma,
-                                 unsigned long start,
-                                 unsigned long end);
-extern void smp_flush_tlb_page(struct vm_area_struct *mm, unsigned long page);
-
-#endif /* CONFIG_SMP */
-
-BTFIXUPDEF_CALL(void, flush_tlb_all, void)
-BTFIXUPDEF_CALL(void, flush_tlb_mm, struct mm_struct *)
-BTFIXUPDEF_CALL(void, flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(void, flush_tlb_page, struct vm_area_struct *, unsigned long)
-
-#define flush_tlb_all() BTFIXUP_CALL(flush_tlb_all)()
-#define flush_tlb_mm(mm) BTFIXUP_CALL(flush_tlb_mm)(mm)
-#define flush_tlb_range(vma,start,end) BTFIXUP_CALL(flush_tlb_range)(vma,start,end)
-#define flush_tlb_page(vma,addr) BTFIXUP_CALL(flush_tlb_page)(vma,addr)
-
-// #define flush_tlb() flush_tlb_mm(current->active_mm)        /* XXX Sure? */
-
-/*
- * This is a kludge, until I know better. --zaitcev XXX
- */
-static inline void flush_tlb_kernel_range(unsigned long start,
-                                         unsigned long end)
-{
-       flush_tlb_all();
-}
-
-#endif /* _SPARC_TLBFLUSH_H */
+#ifndef ___ASM_SPARC_TLBFLUSH_H
+#define ___ASM_SPARC_TLBFLUSH_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/tlbflush_64.h>
+#else
+#include <asm-sparc/tlbflush_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/tlbflush_32.h b/include/asm-sparc/tlbflush_32.h
new file mode 100644 (file)
index 0000000..fe0a71a
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef _SPARC_TLBFLUSH_H
+#define _SPARC_TLBFLUSH_H
+
+#include <linux/mm.h>
+// #include <asm/processor.h>
+
+/*
+ * TLB flushing:
+ *
+ *  - flush_tlb() flushes the current mm struct TLBs   XXX Exists?
+ *  - flush_tlb_all() flushes all processes TLBs
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ *  - flush_tlb_page(vma, vmaddr) flushes one page
+ *  - flush_tlb_range(vma, start, end) flushes a range of pages
+ *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
+ */
+
+#ifdef CONFIG_SMP
+
+BTFIXUPDEF_CALL(void, local_flush_tlb_all, void)
+BTFIXUPDEF_CALL(void, local_flush_tlb_mm, struct mm_struct *)
+BTFIXUPDEF_CALL(void, local_flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long)
+BTFIXUPDEF_CALL(void, local_flush_tlb_page, struct vm_area_struct *, unsigned long)
+
+#define local_flush_tlb_all() BTFIXUP_CALL(local_flush_tlb_all)()
+#define local_flush_tlb_mm(mm) BTFIXUP_CALL(local_flush_tlb_mm)(mm)
+#define local_flush_tlb_range(vma,start,end) BTFIXUP_CALL(local_flush_tlb_range)(vma,start,end)
+#define local_flush_tlb_page(vma,addr) BTFIXUP_CALL(local_flush_tlb_page)(vma,addr)
+
+extern void smp_flush_tlb_all(void);
+extern void smp_flush_tlb_mm(struct mm_struct *mm);
+extern void smp_flush_tlb_range(struct vm_area_struct *vma,
+                                 unsigned long start,
+                                 unsigned long end);
+extern void smp_flush_tlb_page(struct vm_area_struct *mm, unsigned long page);
+
+#endif /* CONFIG_SMP */
+
+BTFIXUPDEF_CALL(void, flush_tlb_all, void)
+BTFIXUPDEF_CALL(void, flush_tlb_mm, struct mm_struct *)
+BTFIXUPDEF_CALL(void, flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long)
+BTFIXUPDEF_CALL(void, flush_tlb_page, struct vm_area_struct *, unsigned long)
+
+#define flush_tlb_all() BTFIXUP_CALL(flush_tlb_all)()
+#define flush_tlb_mm(mm) BTFIXUP_CALL(flush_tlb_mm)(mm)
+#define flush_tlb_range(vma,start,end) BTFIXUP_CALL(flush_tlb_range)(vma,start,end)
+#define flush_tlb_page(vma,addr) BTFIXUP_CALL(flush_tlb_page)(vma,addr)
+
+// #define flush_tlb() flush_tlb_mm(current->active_mm)        /* XXX Sure? */
+
+/*
+ * This is a kludge, until I know better. --zaitcev XXX
+ */
+static inline void flush_tlb_kernel_range(unsigned long start,
+                                         unsigned long end)
+{
+       flush_tlb_all();
+}
+
+#endif /* _SPARC_TLBFLUSH_H */
diff --git a/include/asm-sparc/tlbflush_64.h b/include/asm-sparc/tlbflush_64.h
new file mode 100644 (file)
index 0000000..fbb675d
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef _SPARC64_TLBFLUSH_H
+#define _SPARC64_TLBFLUSH_H
+
+#include <linux/mm.h>
+#include <asm/mmu_context.h>
+
+/* TSB flush operations. */
+struct mmu_gather;
+extern void flush_tsb_kernel_range(unsigned long start, unsigned long end);
+extern void flush_tsb_user(struct mmu_gather *mp);
+
+/* TLB flush operations. */
+
+extern void flush_tlb_pending(void);
+
+#define flush_tlb_range(vma,start,end) \
+       do { (void)(start); flush_tlb_pending(); } while (0)
+#define flush_tlb_page(vma,addr)       flush_tlb_pending()
+#define flush_tlb_mm(mm)               flush_tlb_pending()
+
+/* Local cpu only.  */
+extern void __flush_tlb_all(void);
+
+extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end);
+
+#ifndef CONFIG_SMP
+
+#define flush_tlb_kernel_range(start,end) \
+do {   flush_tsb_kernel_range(start,end); \
+       __flush_tlb_kernel_range(start,end); \
+} while (0)
+
+#else /* CONFIG_SMP */
+
+extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end);
+
+#define flush_tlb_kernel_range(start, end) \
+do {   flush_tsb_kernel_range(start,end); \
+       smp_flush_tlb_kernel_range(start, end); \
+} while (0)
+
+#endif /* ! CONFIG_SMP */
+
+#endif /* _SPARC64_TLBFLUSH_H */
index ee5ac9c9da284defa0bf1a2ebdfe46198a855871..ed13630f32e25f68057f134b4a3083ef6c668f0f 100644 (file)
@@ -1,6 +1,8 @@
-#ifndef _ASM_SPARC_TOPOLOGY_H
-#define _ASM_SPARC_TOPOLOGY_H
-
-#include <asm-generic/topology.h>
-
-#endif /* _ASM_SPARC_TOPOLOGY_H */
+#ifndef ___ASM_SPARC_TOPOLOGY_H
+#define ___ASM_SPARC_TOPOLOGY_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/topology_64.h>
+#else
+#include <asm-sparc/topology_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/topology_32.h b/include/asm-sparc/topology_32.h
new file mode 100644 (file)
index 0000000..ee5ac9c
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _ASM_SPARC_TOPOLOGY_H
+#define _ASM_SPARC_TOPOLOGY_H
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_SPARC_TOPOLOGY_H */
diff --git a/include/asm-sparc/topology_64.h b/include/asm-sparc/topology_64.h
new file mode 100644 (file)
index 0000000..001c040
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef _ASM_SPARC64_TOPOLOGY_H
+#define _ASM_SPARC64_TOPOLOGY_H
+
+#ifdef CONFIG_NUMA
+
+#include <asm/mmzone.h>
+
+static inline int cpu_to_node(int cpu)
+{
+       return numa_cpu_lookup_table[cpu];
+}
+
+#define parent_node(node)      (node)
+
+static inline cpumask_t node_to_cpumask(int node)
+{
+       return numa_cpumask_lookup_table[node];
+}
+
+/* Returns a pointer to the cpumask of CPUs on Node 'node'. */
+#define node_to_cpumask_ptr(v, node)           \
+               cpumask_t *v = &(numa_cpumask_lookup_table[node])
+
+#define node_to_cpumask_ptr_next(v, node)      \
+                          v = &(numa_cpumask_lookup_table[node])
+
+static inline int node_to_first_cpu(int node)
+{
+       cpumask_t tmp;
+       tmp = node_to_cpumask(node);
+       return first_cpu(tmp);
+}
+
+struct pci_bus;
+#ifdef CONFIG_PCI
+extern int pcibus_to_node(struct pci_bus *pbus);
+#else
+static inline int pcibus_to_node(struct pci_bus *pbus)
+{
+       return -1;
+}
+#endif
+
+#define pcibus_to_cpumask(bus) \
+       (pcibus_to_node(bus) == -1 ? \
+        CPU_MASK_ALL : \
+        node_to_cpumask(pcibus_to_node(bus)))
+
+#define SD_NODE_INIT (struct sched_domain) {           \
+       .min_interval           = 8,                    \
+       .max_interval           = 32,                   \
+       .busy_factor            = 32,                   \
+       .imbalance_pct          = 125,                  \
+       .cache_nice_tries       = 2,                    \
+       .busy_idx               = 3,                    \
+       .idle_idx               = 2,                    \
+       .newidle_idx            = 0,                    \
+       .wake_idx               = 1,                    \
+       .forkexec_idx           = 1,                    \
+       .flags                  = SD_LOAD_BALANCE       \
+                               | SD_BALANCE_FORK       \
+                               | SD_BALANCE_EXEC       \
+                               | SD_SERIALIZE          \
+                               | SD_WAKE_BALANCE,      \
+       .last_balance           = jiffies,              \
+       .balance_interval       = 1,                    \
+}
+
+#else /* CONFIG_NUMA */
+
+#include <asm-generic/topology.h>
+
+#endif /* !(CONFIG_NUMA) */
+
+#ifdef CONFIG_SMP
+#define topology_physical_package_id(cpu)      (cpu_data(cpu).proc_id)
+#define topology_core_id(cpu)                  (cpu_data(cpu).core_id)
+#define topology_core_siblings(cpu)            (cpu_core_map[cpu])
+#define topology_thread_siblings(cpu)          (per_cpu(cpu_sibling_map, cpu))
+#define mc_capable()                           (sparc64_multi_core)
+#define smt_capable()                          (sparc64_multi_core)
+#endif /* CONFIG_SMP */
+
+#define cpu_coregroup_map(cpu)                 (cpu_core_map[cpu])
+
+#endif /* _ASM_SPARC64_TOPOLOGY_H */
diff --git a/include/asm-sparc/tsb.h b/include/asm-sparc/tsb.h
new file mode 100644 (file)
index 0000000..76e4299
--- /dev/null
@@ -0,0 +1,283 @@
+#ifndef _SPARC64_TSB_H
+#define _SPARC64_TSB_H
+
+/* The sparc64 TSB is similar to the powerpc hashtables.  It's a
+ * power-of-2 sized table of TAG/PTE pairs.  The cpu precomputes
+ * pointers into this table for 8K and 64K page sizes, and also a
+ * comparison TAG based upon the virtual address and context which
+ * faults.
+ *
+ * TLB miss trap handler software does the actual lookup via something
+ * of the form:
+ *
+ *     ldxa            [%g0] ASI_{D,I}MMU_TSB_8KB_PTR, %g1
+ *     ldxa            [%g0] ASI_{D,I}MMU, %g6
+ *     sllx            %g6, 22, %g6
+ *     srlx            %g6, 22, %g6
+ *     ldda            [%g1] ASI_NUCLEUS_QUAD_LDD, %g4
+ *     cmp             %g4, %g6
+ *     bne,pn  %xcc, tsb_miss_{d,i}tlb
+ *      mov            FAULT_CODE_{D,I}TLB, %g3
+ *     stxa            %g5, [%g0] ASI_{D,I}TLB_DATA_IN
+ *     retry
+ *
+ *
+ * Each 16-byte slot of the TSB is the 8-byte tag and then the 8-byte
+ * PTE.  The TAG is of the same layout as the TLB TAG TARGET mmu
+ * register which is:
+ *
+ * -------------------------------------------------
+ * |  -  |  CONTEXT |  -  |    VADDR bits 63:22    |
+ * -------------------------------------------------
+ *  63 61 60      48 47 42 41                     0
+ *
+ * But actually, since we use per-mm TSB's, we zero out the CONTEXT
+ * field.
+ *
+ * Like the powerpc hashtables we need to use locking in order to
+ * synchronize while we update the entries.  PTE updates need locking
+ * as well.
+ *
+ * We need to carefully choose a lock bits for the TSB entry.  We
+ * choose to use bit 47 in the tag.  Also, since we never map anything
+ * at page zero in context zero, we use zero as an invalid tag entry.
+ * When the lock bit is set, this forces a tag comparison failure.
+ */
+
+#define TSB_TAG_LOCK_BIT       47
+#define TSB_TAG_LOCK_HIGH      (1 << (TSB_TAG_LOCK_BIT - 32))
+
+#define TSB_TAG_INVALID_BIT    46
+#define TSB_TAG_INVALID_HIGH   (1 << (TSB_TAG_INVALID_BIT - 32))
+
+#define TSB_MEMBAR     membar  #StoreStore
+
+/* Some cpus support physical address quad loads.  We want to use
+ * those if possible so we don't need to hard-lock the TSB mapping
+ * into the TLB.  We encode some instruction patching in order to
+ * support this.
+ *
+ * The kernel TSB is locked into the TLB by virtue of being in the
+ * kernel image, so we don't play these games for swapper_tsb access.
+ */
+#ifndef __ASSEMBLY__
+struct tsb_ldquad_phys_patch_entry {
+       unsigned int    addr;
+       unsigned int    sun4u_insn;
+       unsigned int    sun4v_insn;
+};
+extern struct tsb_ldquad_phys_patch_entry __tsb_ldquad_phys_patch,
+       __tsb_ldquad_phys_patch_end;
+
+struct tsb_phys_patch_entry {
+       unsigned int    addr;
+       unsigned int    insn;
+};
+extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
+#endif
+#define TSB_LOAD_QUAD(TSB, REG)        \
+661:   ldda            [TSB] ASI_NUCLEUS_QUAD_LDD, REG; \
+       .section        .tsb_ldquad_phys_patch, "ax"; \
+       .word           661b; \
+       ldda            [TSB] ASI_QUAD_LDD_PHYS, REG; \
+       ldda            [TSB] ASI_QUAD_LDD_PHYS_4V, REG; \
+       .previous
+
+#define TSB_LOAD_TAG_HIGH(TSB, REG) \
+661:   lduwa           [TSB] ASI_N, REG; \
+       .section        .tsb_phys_patch, "ax"; \
+       .word           661b; \
+       lduwa           [TSB] ASI_PHYS_USE_EC, REG; \
+       .previous
+
+#define TSB_LOAD_TAG(TSB, REG) \
+661:   ldxa            [TSB] ASI_N, REG; \
+       .section        .tsb_phys_patch, "ax"; \
+       .word           661b; \
+       ldxa            [TSB] ASI_PHYS_USE_EC, REG; \
+       .previous
+
+#define TSB_CAS_TAG_HIGH(TSB, REG1, REG2) \
+661:   casa            [TSB] ASI_N, REG1, REG2; \
+       .section        .tsb_phys_patch, "ax"; \
+       .word           661b; \
+       casa            [TSB] ASI_PHYS_USE_EC, REG1, REG2; \
+       .previous
+
+#define TSB_CAS_TAG(TSB, REG1, REG2) \
+661:   casxa           [TSB] ASI_N, REG1, REG2; \
+       .section        .tsb_phys_patch, "ax"; \
+       .word           661b; \
+       casxa           [TSB] ASI_PHYS_USE_EC, REG1, REG2; \
+       .previous
+
+#define TSB_STORE(ADDR, VAL) \
+661:   stxa            VAL, [ADDR] ASI_N; \
+       .section        .tsb_phys_patch, "ax"; \
+       .word           661b; \
+       stxa            VAL, [ADDR] ASI_PHYS_USE_EC; \
+       .previous
+
+#define TSB_LOCK_TAG(TSB, REG1, REG2)  \
+99:    TSB_LOAD_TAG_HIGH(TSB, REG1);   \
+       sethi   %hi(TSB_TAG_LOCK_HIGH), REG2;\
+       andcc   REG1, REG2, %g0;        \
+       bne,pn  %icc, 99b;              \
+        nop;                           \
+       TSB_CAS_TAG_HIGH(TSB, REG1, REG2);      \
+       cmp     REG1, REG2;             \
+       bne,pn  %icc, 99b;              \
+        nop;                           \
+       TSB_MEMBAR
+
+#define TSB_WRITE(TSB, TTE, TAG) \
+       add     TSB, 0x8, TSB;   \
+       TSB_STORE(TSB, TTE);     \
+       sub     TSB, 0x8, TSB;   \
+       TSB_MEMBAR;              \
+       TSB_STORE(TSB, TAG);
+
+#define KTSB_LOAD_QUAD(TSB, REG) \
+       ldda            [TSB] ASI_NUCLEUS_QUAD_LDD, REG;
+
+#define KTSB_STORE(ADDR, VAL) \
+       stxa            VAL, [ADDR] ASI_N;
+
+#define KTSB_LOCK_TAG(TSB, REG1, REG2) \
+99:    lduwa   [TSB] ASI_N, REG1;      \
+       sethi   %hi(TSB_TAG_LOCK_HIGH), REG2;\
+       andcc   REG1, REG2, %g0;        \
+       bne,pn  %icc, 99b;              \
+        nop;                           \
+       casa    [TSB] ASI_N, REG1, REG2;\
+       cmp     REG1, REG2;             \
+       bne,pn  %icc, 99b;              \
+        nop;                           \
+       TSB_MEMBAR
+
+#define KTSB_WRITE(TSB, TTE, TAG) \
+       add     TSB, 0x8, TSB;   \
+       stxa    TTE, [TSB] ASI_N;     \
+       sub     TSB, 0x8, TSB;   \
+       TSB_MEMBAR;              \
+       stxa    TAG, [TSB] ASI_N;
+
+       /* Do a kernel page table walk.  Leaves physical PTE pointer in
+        * REG1.  Jumps to FAIL_LABEL on early page table walk termination.
+        * VADDR will not be clobbered, but REG2 will.
+        */
+#define KERN_PGTABLE_WALK(VADDR, REG1, REG2, FAIL_LABEL)       \
+       sethi           %hi(swapper_pg_dir), REG1; \
+       or              REG1, %lo(swapper_pg_dir), REG1; \
+       sllx            VADDR, 64 - (PGDIR_SHIFT + PGDIR_BITS), REG2; \
+       srlx            REG2, 64 - PAGE_SHIFT, REG2; \
+       andn            REG2, 0x3, REG2; \
+       lduw            [REG1 + REG2], REG1; \
+       brz,pn          REG1, FAIL_LABEL; \
+        sllx           VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \
+       srlx            REG2, 64 - PAGE_SHIFT, REG2; \
+       sllx            REG1, 11, REG1; \
+       andn            REG2, 0x3, REG2; \
+       lduwa           [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \
+       brz,pn          REG1, FAIL_LABEL; \
+        sllx           VADDR, 64 - PMD_SHIFT, REG2; \
+       srlx            REG2, 64 - PAGE_SHIFT, REG2; \
+       sllx            REG1, 11, REG1; \
+       andn            REG2, 0x7, REG2; \
+       add             REG1, REG2, REG1;
+
+       /* Do a user page table walk in MMU globals.  Leaves physical PTE
+        * pointer in REG1.  Jumps to FAIL_LABEL on early page table walk
+        * termination.  Physical base of page tables is in PHYS_PGD which
+        * will not be modified.
+        *
+        * VADDR will not be clobbered, but REG1 and REG2 will.
+        */
+#define USER_PGTABLE_WALK_TL1(VADDR, PHYS_PGD, REG1, REG2, FAIL_LABEL) \
+       sllx            VADDR, 64 - (PGDIR_SHIFT + PGDIR_BITS), REG2; \
+       srlx            REG2, 64 - PAGE_SHIFT, REG2; \
+       andn            REG2, 0x3, REG2; \
+       lduwa           [PHYS_PGD + REG2] ASI_PHYS_USE_EC, REG1; \
+       brz,pn          REG1, FAIL_LABEL; \
+        sllx           VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \
+       srlx            REG2, 64 - PAGE_SHIFT, REG2; \
+       sllx            REG1, 11, REG1; \
+       andn            REG2, 0x3, REG2; \
+       lduwa           [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \
+       brz,pn          REG1, FAIL_LABEL; \
+        sllx           VADDR, 64 - PMD_SHIFT, REG2; \
+       srlx            REG2, 64 - PAGE_SHIFT, REG2; \
+       sllx            REG1, 11, REG1; \
+       andn            REG2, 0x7, REG2; \
+       add             REG1, REG2, REG1;
+
+/* Lookup a OBP mapping on VADDR in the prom_trans[] table at TL>0.
+ * If no entry is found, FAIL_LABEL will be branched to.  On success
+ * the resulting PTE value will be left in REG1.  VADDR is preserved
+ * by this routine.
+ */
+#define OBP_TRANS_LOOKUP(VADDR, REG1, REG2, REG3, FAIL_LABEL) \
+       sethi           %hi(prom_trans), REG1; \
+       or              REG1, %lo(prom_trans), REG1; \
+97:    ldx             [REG1 + 0x00], REG2; \
+       brz,pn          REG2, FAIL_LABEL; \
+        nop; \
+       ldx             [REG1 + 0x08], REG3; \
+       add             REG2, REG3, REG3; \
+       cmp             REG2, VADDR; \
+       bgu,pt          %xcc, 98f; \
+        cmp            VADDR, REG3; \
+       bgeu,pt         %xcc, 98f; \
+        ldx            [REG1 + 0x10], REG3; \
+       sub             VADDR, REG2, REG2; \
+       ba,pt           %xcc, 99f; \
+        add            REG3, REG2, REG1; \
+98:    ba,pt           %xcc, 97b; \
+        add            REG1, (3 * 8), REG1; \
+99:
+
+       /* We use a 32K TSB for the whole kernel, this allows to
+        * handle about 16MB of modules and vmalloc mappings without
+        * incurring many hash conflicts.
+        */
+#define KERNEL_TSB_SIZE_BYTES  (32 * 1024)
+#define KERNEL_TSB_NENTRIES    \
+       (KERNEL_TSB_SIZE_BYTES / 16)
+#define KERNEL_TSB4M_NENTRIES  4096
+
+       /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL
+        * on TSB hit.  REG1, REG2, REG3, and REG4 are used as temporaries
+        * and the found TTE will be left in REG1.  REG3 and REG4 must
+        * be an even/odd pair of registers.
+        *
+        * VADDR and TAG will be preserved and not clobbered by this macro.
+        */
+#define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
+       sethi           %hi(swapper_tsb), REG1; \
+       or              REG1, %lo(swapper_tsb), REG1; \
+       srlx            VADDR, PAGE_SHIFT, REG2; \
+       and             REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \
+       sllx            REG2, 4, REG2; \
+       add             REG1, REG2, REG2; \
+       KTSB_LOAD_QUAD(REG2, REG3); \
+       cmp             REG3, TAG; \
+       be,a,pt         %xcc, OK_LABEL; \
+        mov            REG4, REG1;
+
+#ifndef CONFIG_DEBUG_PAGEALLOC
+       /* This version uses a trick, the TAG is already (VADDR >> 22) so
+        * we can make use of that for the index computation.
+        */
+#define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
+       sethi           %hi(swapper_4m_tsb), REG1; \
+       or              REG1, %lo(swapper_4m_tsb), REG1; \
+       and             TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \
+       sllx            REG2, 4, REG2; \
+       add             REG1, REG2, REG2; \
+       KTSB_LOAD_QUAD(REG2, REG3); \
+       cmp             REG3, TAG; \
+       be,a,pt         %xcc, OK_LABEL; \
+        mov            REG4, REG1;
+#endif
+
+#endif /* !(_SPARC64_TSB_H) */
diff --git a/include/asm-sparc/ttable.h b/include/asm-sparc/ttable.h
new file mode 100644 (file)
index 0000000..5708ba2
--- /dev/null
@@ -0,0 +1,658 @@
+#ifndef _SPARC64_TTABLE_H
+#define _SPARC64_TTABLE_H
+
+#include <asm/utrap.h>
+
+#ifdef __ASSEMBLY__
+#include <asm/thread_info.h>
+#endif
+
+#define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop;
+
+/* We need a "cleaned" instruction... */
+#define CLEAN_WINDOW                                                   \
+       rdpr    %cleanwin, %l0;         add     %l0, 1, %l0;            \
+       wrpr    %l0, 0x0, %cleanwin;                                    \
+       clr     %o0;    clr     %o1;    clr     %o2;    clr     %o3;    \
+       clr     %o4;    clr     %o5;    clr     %o6;    clr     %o7;    \
+       clr     %l0;    clr     %l1;    clr     %l2;    clr     %l3;    \
+       clr     %l4;    clr     %l5;    clr     %l6;    clr     %l7;    \
+       retry;                                                          \
+       nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
+
+#define TRAP(routine)                                  \
+       sethi   %hi(109f), %g7;                         \
+       ba,pt   %xcc, etrap;                            \
+109:    or     %g7, %lo(109b), %g7;                    \
+       call    routine;                                \
+        add    %sp, PTREGS_OFF, %o0;                   \
+       ba,pt   %xcc, rtrap;                            \
+        nop;                                           \
+       nop;
+
+#define TRAP_7INSNS(routine)                           \
+       sethi   %hi(109f), %g7;                         \
+       ba,pt   %xcc, etrap;                            \
+109:    or     %g7, %lo(109b), %g7;                    \
+       call    routine;                                \
+        add    %sp, PTREGS_OFF, %o0;                   \
+       ba,pt   %xcc, rtrap;                            \
+        nop;
+
+#define TRAP_SAVEFPU(routine)                          \
+       sethi   %hi(109f), %g7;                         \
+       ba,pt   %xcc, do_fptrap;                        \
+109:    or     %g7, %lo(109b), %g7;                    \
+       call    routine;                                \
+        add    %sp, PTREGS_OFF, %o0;                   \
+       ba,pt   %xcc, rtrap;                            \
+        nop;                                           \
+       nop;
+
+#define TRAP_NOSAVE(routine)                           \
+       ba,pt   %xcc, routine;                          \
+        nop;                                           \
+       nop; nop; nop; nop; nop; nop;
+
+#define TRAP_NOSAVE_7INSNS(routine)                    \
+       ba,pt   %xcc, routine;                          \
+        nop;                                           \
+       nop; nop; nop; nop; nop;
+
+#define TRAPTL1(routine)                               \
+       sethi   %hi(109f), %g7;                         \
+       ba,pt   %xcc, etraptl1;                         \
+109:    or     %g7, %lo(109b), %g7;                    \
+       call    routine;                                \
+        add    %sp, PTREGS_OFF, %o0;                   \
+       ba,pt   %xcc, rtrap;                            \
+        nop;                                           \
+       nop;
+
+#define TRAP_ARG(routine, arg)                         \
+       sethi   %hi(109f), %g7;                         \
+       ba,pt   %xcc, etrap;                            \
+109:    or     %g7, %lo(109b), %g7;                    \
+       add     %sp, PTREGS_OFF, %o0;                   \
+       call    routine;                                \
+        mov    arg, %o1;                               \
+       ba,pt   %xcc, rtrap;                            \
+        nop;
+
+#define TRAPTL1_ARG(routine, arg)                      \
+       sethi   %hi(109f), %g7;                         \
+       ba,pt   %xcc, etraptl1;                         \
+109:    or     %g7, %lo(109b), %g7;                    \
+       add     %sp, PTREGS_OFF, %o0;                   \
+       call    routine;                                \
+        mov    arg, %o1;                               \
+       ba,pt   %xcc, rtrap;                            \
+        nop;
+
+#define SYSCALL_TRAP(routine, systbl)                  \
+       rdpr    %pil, %g2;                              \
+       mov     TSTATE_SYSCALL, %g3;                    \
+       sethi   %hi(109f), %g7;                         \
+       ba,pt   %xcc, etrap_syscall;                    \
+109:    or     %g7, %lo(109b), %g7;                    \
+       sethi   %hi(systbl), %l7;                       \
+       ba,pt   %xcc, routine;                          \
+        or     %l7, %lo(systbl), %l7;
+
+#define TRAP_UTRAP(handler,lvl)                                \
+       mov     handler, %g3;                           \
+       ba,pt   %xcc, utrap_trap;                       \
+        mov    lvl, %g4;                               \
+       nop;                                            \
+       nop;                                            \
+       nop;                                            \
+       nop;                                            \
+       nop;
+
+#ifdef CONFIG_COMPAT
+#define        LINUX_32BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sys_call_table32)
+#else
+#define        LINUX_32BIT_SYSCALL_TRAP BTRAP(0x110)
+#endif
+#define LINUX_64BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall, sys_call_table64)
+#define GETCC_TRAP TRAP(getcc)
+#define SETCC_TRAP TRAP(setcc)
+#define BREAKPOINT_TRAP TRAP(breakpoint_trap)
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+#define TRAP_IRQ(routine, level)                       \
+       rdpr    %pil, %g2;                              \
+       wrpr    %g0, 15, %pil;                          \
+       sethi   %hi(1f-4), %g7;                         \
+       ba,pt   %xcc, etrap_irq;                        \
+        or     %g7, %lo(1f-4), %g7;                    \
+       nop;                                            \
+       nop;                                            \
+       nop;                                            \
+       .subsection     2;                              \
+1:     call    trace_hardirqs_off;                     \
+        nop;                                           \
+       mov     level, %o0;                             \
+       call    routine;                                \
+        add    %sp, PTREGS_OFF, %o1;                   \
+       ba,a,pt %xcc, rtrap_irq;                        \
+       .previous;
+
+#else
+
+#define TRAP_IRQ(routine, level)                       \
+       rdpr    %pil, %g2;                              \
+       wrpr    %g0, 15, %pil;                          \
+       ba,pt   %xcc, etrap_irq;                        \
+        rd     %pc, %g7;                               \
+       mov     level, %o0;                             \
+       call    routine;                                \
+        add    %sp, PTREGS_OFF, %o1;                   \
+       ba,a,pt %xcc, rtrap_irq;
+
+#endif
+
+#define TRAP_IVEC TRAP_NOSAVE(do_ivec)
+
+#define BTRAP(lvl) TRAP_ARG(bad_trap, lvl)
+
+#define BTRAPTL1(lvl) TRAPTL1_ARG(bad_trap_tl1, lvl)
+
+#define FLUSH_WINDOW_TRAP                                              \
+       ba,pt   %xcc, etrap;                                            \
+        rd     %pc, %g7;                                               \
+       flushw;                                                         \
+       ldx     [%sp + PTREGS_OFF + PT_V9_TNPC], %l1;                   \
+       add     %l1, 4, %l2;                                            \
+       stx     %l1, [%sp + PTREGS_OFF + PT_V9_TPC];                    \
+       ba,pt   %xcc, rtrap;                                            \
+        stx    %l2, [%sp + PTREGS_OFF + PT_V9_TNPC];
+
+#ifdef CONFIG_KPROBES
+#define KPROBES_TRAP(lvl) TRAP_IRQ(kprobe_trap, lvl)
+#else
+#define KPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
+#endif
+
+#ifdef CONFIG_KGDB
+#define KGDB_TRAP(lvl) TRAP_IRQ(kgdb_trap, lvl)
+#else
+#define KGDB_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
+#endif
+
+#define SUN4V_ITSB_MISS                                        \
+       ldxa    [%g0] ASI_SCRATCHPAD, %g2;              \
+       ldx     [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4;    \
+       ldx     [%g2 + HV_FAULT_I_CTX_OFFSET], %g5;     \
+       srlx    %g4, 22, %g6;                           \
+       ba,pt   %xcc, sun4v_itsb_miss;                  \
+        nop;                                           \
+       nop;                                            \
+       nop;
+
+#define SUN4V_DTSB_MISS                                        \
+       ldxa    [%g0] ASI_SCRATCHPAD, %g2;              \
+       ldx     [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4;    \
+       ldx     [%g2 + HV_FAULT_D_CTX_OFFSET], %g5;     \
+       srlx    %g4, 22, %g6;                           \
+       ba,pt   %xcc, sun4v_dtsb_miss;                  \
+        nop;                                           \
+       nop;                                            \
+       nop;
+
+/* Before touching these macros, you owe it to yourself to go and
+ * see how arch/sparc64/kernel/winfixup.S works... -DaveM
+ *
+ * For the user cases we used to use the %asi register, but
+ * it turns out that the "wr xxx, %asi" costs ~5 cycles, so
+ * now we use immediate ASI loads and stores instead.  Kudos
+ * to Greg Onufer for pointing out this performance anomaly.
+ *
+ * Further note that we cannot use the g2, g4, g5, and g7 alternate
+ * globals in the spill routines, check out the save instruction in
+ * arch/sparc64/kernel/etrap.S to see what I mean about g2, and
+ * g4/g5 are the globals which are preserved by etrap processing
+ * for the caller of it.  The g7 register is the return pc for
+ * etrap.  Finally, g6 is the current thread register so we cannot
+ * us it in the spill handlers either.  Most of these rules do not
+ * apply to fill processing, only g6 is not usable.
+ */
+
+/* Normal kernel spill */
+#define SPILL_0_NORMAL                                 \
+       stx     %l0, [%sp + STACK_BIAS + 0x00];         \
+       stx     %l1, [%sp + STACK_BIAS + 0x08];         \
+       stx     %l2, [%sp + STACK_BIAS + 0x10];         \
+       stx     %l3, [%sp + STACK_BIAS + 0x18];         \
+       stx     %l4, [%sp + STACK_BIAS + 0x20];         \
+       stx     %l5, [%sp + STACK_BIAS + 0x28];         \
+       stx     %l6, [%sp + STACK_BIAS + 0x30];         \
+       stx     %l7, [%sp + STACK_BIAS + 0x38];         \
+       stx     %i0, [%sp + STACK_BIAS + 0x40];         \
+       stx     %i1, [%sp + STACK_BIAS + 0x48];         \
+       stx     %i2, [%sp + STACK_BIAS + 0x50];         \
+       stx     %i3, [%sp + STACK_BIAS + 0x58];         \
+       stx     %i4, [%sp + STACK_BIAS + 0x60];         \
+       stx     %i5, [%sp + STACK_BIAS + 0x68];         \
+       stx     %i6, [%sp + STACK_BIAS + 0x70];         \
+       stx     %i7, [%sp + STACK_BIAS + 0x78];         \
+       saved; retry; nop; nop; nop; nop; nop; nop;     \
+       nop; nop; nop; nop; nop; nop; nop; nop;
+
+#define SPILL_0_NORMAL_ETRAP                           \
+etrap_kernel_spill:                                    \
+       stx     %l0, [%sp + STACK_BIAS + 0x00];         \
+       stx     %l1, [%sp + STACK_BIAS + 0x08];         \
+       stx     %l2, [%sp + STACK_BIAS + 0x10];         \
+       stx     %l3, [%sp + STACK_BIAS + 0x18];         \
+       stx     %l4, [%sp + STACK_BIAS + 0x20];         \
+       stx     %l5, [%sp + STACK_BIAS + 0x28];         \
+       stx     %l6, [%sp + STACK_BIAS + 0x30];         \
+       stx     %l7, [%sp + STACK_BIAS + 0x38];         \
+       stx     %i0, [%sp + STACK_BIAS + 0x40];         \
+       stx     %i1, [%sp + STACK_BIAS + 0x48];         \
+       stx     %i2, [%sp + STACK_BIAS + 0x50];         \
+       stx     %i3, [%sp + STACK_BIAS + 0x58];         \
+       stx     %i4, [%sp + STACK_BIAS + 0x60];         \
+       stx     %i5, [%sp + STACK_BIAS + 0x68];         \
+       stx     %i6, [%sp + STACK_BIAS + 0x70];         \
+       stx     %i7, [%sp + STACK_BIAS + 0x78];         \
+       saved;                                          \
+       sub     %g1, 2, %g1;                            \
+       ba,pt   %xcc, etrap_save;                       \
+       wrpr    %g1, %cwp;                              \
+       nop; nop; nop; nop; nop; nop; nop; nop;         \
+       nop; nop; nop; nop;
+
+/* Normal 64bit spill */
+#define SPILL_1_GENERIC(ASI)                           \
+       add     %sp, STACK_BIAS + 0x00, %g1;            \
+       stxa    %l0, [%g1 + %g0] ASI;                   \
+       mov     0x08, %g3;                              \
+       stxa    %l1, [%g1 + %g3] ASI;                   \
+       add     %g1, 0x10, %g1;                         \
+       stxa    %l2, [%g1 + %g0] ASI;                   \
+       stxa    %l3, [%g1 + %g3] ASI;                   \
+       add     %g1, 0x10, %g1;                         \
+       stxa    %l4, [%g1 + %g0] ASI;                   \
+       stxa    %l5, [%g1 + %g3] ASI;                   \
+       add     %g1, 0x10, %g1;                         \
+       stxa    %l6, [%g1 + %g0] ASI;                   \
+       stxa    %l7, [%g1 + %g3] ASI;                   \
+       add     %g1, 0x10, %g1;                         \
+       stxa    %i0, [%g1 + %g0] ASI;                   \
+       stxa    %i1, [%g1 + %g3] ASI;                   \
+       add     %g1, 0x10, %g1;                         \
+       stxa    %i2, [%g1 + %g0] ASI;                   \
+       stxa    %i3, [%g1 + %g3] ASI;                   \
+       add     %g1, 0x10, %g1;                         \
+       stxa    %i4, [%g1 + %g0] ASI;                   \
+       stxa    %i5, [%g1 + %g3] ASI;                   \
+       add     %g1, 0x10, %g1;                         \
+       stxa    %i6, [%g1 + %g0] ASI;                   \
+       stxa    %i7, [%g1 + %g3] ASI;                   \
+       saved;                                          \
+       retry; nop; nop;                                \
+       b,a,pt  %xcc, spill_fixup_dax;                  \
+       b,a,pt  %xcc, spill_fixup_mna;                  \
+       b,a,pt  %xcc, spill_fixup;
+
+#define SPILL_1_GENERIC_ETRAP                          \
+etrap_user_spill_64bit:                                        \
+       stxa    %l0, [%sp + STACK_BIAS + 0x00] %asi;    \
+       stxa    %l1, [%sp + STACK_BIAS + 0x08] %asi;    \
+       stxa    %l2, [%sp + STACK_BIAS + 0x10] %asi;    \
+       stxa    %l3, [%sp + STACK_BIAS + 0x18] %asi;    \
+       stxa    %l4, [%sp + STACK_BIAS + 0x20] %asi;    \
+       stxa    %l5, [%sp + STACK_BIAS + 0x28] %asi;    \
+       stxa    %l6, [%sp + STACK_BIAS + 0x30] %asi;    \
+       stxa    %l7, [%sp + STACK_BIAS + 0x38] %asi;    \
+       stxa    %i0, [%sp + STACK_BIAS + 0x40] %asi;    \
+       stxa    %i1, [%sp + STACK_BIAS + 0x48] %asi;    \
+       stxa    %i2, [%sp + STACK_BIAS + 0x50] %asi;    \
+       stxa    %i3, [%sp + STACK_BIAS + 0x58] %asi;    \
+       stxa    %i4, [%sp + STACK_BIAS + 0x60] %asi;    \
+       stxa    %i5, [%sp + STACK_BIAS + 0x68] %asi;    \
+       stxa    %i6, [%sp + STACK_BIAS + 0x70] %asi;    \
+       stxa    %i7, [%sp + STACK_BIAS + 0x78] %asi;    \
+       saved;                                          \
+       sub     %g1, 2, %g1;                            \
+       ba,pt   %xcc, etrap_save;                       \
+        wrpr   %g1, %cwp;                              \
+       nop; nop; nop; nop; nop;                        \
+       nop; nop; nop; nop;                             \
+       ba,a,pt %xcc, etrap_spill_fixup_64bit;          \
+       ba,a,pt %xcc, etrap_spill_fixup_64bit;          \
+       ba,a,pt %xcc, etrap_spill_fixup_64bit;
+
+#define SPILL_1_GENERIC_ETRAP_FIXUP                    \
+etrap_spill_fixup_64bit:                               \
+       ldub    [%g6 + TI_WSAVED], %g1;                 \
+       sll     %g1, 3, %g3;                            \
+       add     %g6, %g3, %g3;                          \
+       stx     %sp, [%g3 + TI_RWIN_SPTRS];             \
+       sll     %g1, 7, %g3;                            \
+       add     %g6, %g3, %g3;                          \
+       stx     %l0, [%g3 + TI_REG_WINDOW + 0x00];      \
+       stx     %l1, [%g3 + TI_REG_WINDOW + 0x08];      \
+       stx     %l2, [%g3 + TI_REG_WINDOW + 0x10];      \
+       stx     %l3, [%g3 + TI_REG_WINDOW + 0x18];      \
+       stx     %l4, [%g3 + TI_REG_WINDOW + 0x20];      \
+       stx     %l5, [%g3 + TI_REG_WINDOW + 0x28];      \
+       stx     %l6, [%g3 + TI_REG_WINDOW + 0x30];      \
+       stx     %l7, [%g3 + TI_REG_WINDOW + 0x38];      \
+       stx     %i0, [%g3 + TI_REG_WINDOW + 0x40];      \
+       stx     %i1, [%g3 + TI_REG_WINDOW + 0x48];      \
+       stx     %i2, [%g3 + TI_REG_WINDOW + 0x50];      \
+       stx     %i3, [%g3 + TI_REG_WINDOW + 0x58];      \
+       stx     %i4, [%g3 + TI_REG_WINDOW + 0x60];      \
+       stx     %i5, [%g3 + TI_REG_WINDOW + 0x68];      \
+       stx     %i6, [%g3 + TI_REG_WINDOW + 0x70];      \
+       stx     %i7, [%g3 + TI_REG_WINDOW + 0x78];      \
+       add     %g1, 1, %g1;                            \
+       stb     %g1, [%g6 + TI_WSAVED];                 \
+       saved;                                          \
+       rdpr    %cwp, %g1;                              \
+       sub     %g1, 2, %g1;                            \
+       ba,pt   %xcc, etrap_save;                       \
+        wrpr   %g1, %cwp;                              \
+       nop; nop; nop
+
+/* Normal 32bit spill */
+#define SPILL_2_GENERIC(ASI)                           \
+       srl     %sp, 0, %sp;                            \
+       stwa    %l0, [%sp + %g0] ASI;                   \
+       mov     0x04, %g3;                              \
+       stwa    %l1, [%sp + %g3] ASI;                   \
+       add     %sp, 0x08, %g1;                         \
+       stwa    %l2, [%g1 + %g0] ASI;                   \
+       stwa    %l3, [%g1 + %g3] ASI;                   \
+       add     %g1, 0x08, %g1;                         \
+       stwa    %l4, [%g1 + %g0] ASI;                   \
+       stwa    %l5, [%g1 + %g3] ASI;                   \
+       add     %g1, 0x08, %g1;                         \
+       stwa    %l6, [%g1 + %g0] ASI;                   \
+       stwa    %l7, [%g1 + %g3] ASI;                   \
+       add     %g1, 0x08, %g1;                         \
+       stwa    %i0, [%g1 + %g0] ASI;                   \
+       stwa    %i1, [%g1 + %g3] ASI;                   \
+       add     %g1, 0x08, %g1;                         \
+       stwa    %i2, [%g1 + %g0] ASI;                   \
+       stwa    %i3, [%g1 + %g3] ASI;                   \
+       add     %g1, 0x08, %g1;                         \
+       stwa    %i4, [%g1 + %g0] ASI;                   \
+       stwa    %i5, [%g1 + %g3] ASI;                   \
+       add     %g1, 0x08, %g1;                         \
+       stwa    %i6, [%g1 + %g0] ASI;                   \
+       stwa    %i7, [%g1 + %g3] ASI;                   \
+       saved;                                          \
+        retry; nop; nop;                               \
+       b,a,pt  %xcc, spill_fixup_dax;                  \
+       b,a,pt  %xcc, spill_fixup_mna;                  \
+       b,a,pt  %xcc, spill_fixup;
+
+#define SPILL_2_GENERIC_ETRAP          \
+etrap_user_spill_32bit:                        \
+       srl     %sp, 0, %sp;            \
+       stwa    %l0, [%sp + 0x00] %asi; \
+       stwa    %l1, [%sp + 0x04] %asi; \
+       stwa    %l2, [%sp + 0x08] %asi; \
+       stwa    %l3, [%sp + 0x0c] %asi; \
+       stwa    %l4, [%sp + 0x10] %asi; \
+       stwa    %l5, [%sp + 0x14] %asi; \
+       stwa    %l6, [%sp + 0x18] %asi; \
+       stwa    %l7, [%sp + 0x1c] %asi; \
+       stwa    %i0, [%sp + 0x20] %asi; \
+       stwa    %i1, [%sp + 0x24] %asi; \
+       stwa    %i2, [%sp + 0x28] %asi; \
+       stwa    %i3, [%sp + 0x2c] %asi; \
+       stwa    %i4, [%sp + 0x30] %asi; \
+       stwa    %i5, [%sp + 0x34] %asi; \
+       stwa    %i6, [%sp + 0x38] %asi; \
+       stwa    %i7, [%sp + 0x3c] %asi; \
+       saved;                          \
+       sub     %g1, 2, %g1;            \
+       ba,pt   %xcc, etrap_save;       \
+        wrpr   %g1, %cwp;              \
+       nop; nop; nop; nop;             \
+       nop; nop; nop; nop;             \
+       ba,a,pt %xcc, etrap_spill_fixup_32bit; \
+       ba,a,pt %xcc, etrap_spill_fixup_32bit; \
+       ba,a,pt %xcc, etrap_spill_fixup_32bit;
+
+#define SPILL_2_GENERIC_ETRAP_FIXUP                    \
+etrap_spill_fixup_32bit:                               \
+       ldub    [%g6 + TI_WSAVED], %g1;                 \
+       sll     %g1, 3, %g3;                            \
+       add     %g6, %g3, %g3;                          \
+       stx     %sp, [%g3 + TI_RWIN_SPTRS];             \
+       sll     %g1, 7, %g3;                            \
+       add     %g6, %g3, %g3;                          \
+       stw     %l0, [%g3 + TI_REG_WINDOW + 0x00];      \
+       stw     %l1, [%g3 + TI_REG_WINDOW + 0x04];      \
+       stw     %l2, [%g3 + TI_REG_WINDOW + 0x08];      \
+       stw     %l3, [%g3 + TI_REG_WINDOW + 0x0c];      \
+       stw     %l4, [%g3 + TI_REG_WINDOW + 0x10];      \
+       stw     %l5, [%g3 + TI_REG_WINDOW + 0x14];      \
+       stw     %l6, [%g3 + TI_REG_WINDOW + 0x18];      \
+       stw     %l7, [%g3 + TI_REG_WINDOW + 0x1c];      \
+       stw     %i0, [%g3 + TI_REG_WINDOW + 0x20];      \
+       stw     %i1, [%g3 + TI_REG_WINDOW + 0x24];      \
+       stw     %i2, [%g3 + TI_REG_WINDOW + 0x28];      \
+       stw     %i3, [%g3 + TI_REG_WINDOW + 0x2c];      \
+       stw     %i4, [%g3 + TI_REG_WINDOW + 0x30];      \
+       stw     %i5, [%g3 + TI_REG_WINDOW + 0x34];      \
+       stw     %i6, [%g3 + TI_REG_WINDOW + 0x38];      \
+       stw     %i7, [%g3 + TI_REG_WINDOW + 0x3c];      \
+       add     %g1, 1, %g1;                            \
+       stb     %g1, [%g6 + TI_WSAVED];                 \
+       saved;                                          \
+       rdpr    %cwp, %g1;                              \
+       sub     %g1, 2, %g1;                            \
+       ba,pt   %xcc, etrap_save;                       \
+        wrpr   %g1, %cwp;                              \
+       nop; nop; nop
+
+#define SPILL_1_NORMAL SPILL_1_GENERIC(ASI_AIUP)
+#define SPILL_2_NORMAL SPILL_2_GENERIC(ASI_AIUP)
+#define SPILL_3_NORMAL SPILL_0_NORMAL
+#define SPILL_4_NORMAL SPILL_0_NORMAL
+#define SPILL_5_NORMAL SPILL_0_NORMAL
+#define SPILL_6_NORMAL SPILL_0_NORMAL
+#define SPILL_7_NORMAL SPILL_0_NORMAL
+
+#define SPILL_0_OTHER SPILL_0_NORMAL
+#define SPILL_1_OTHER SPILL_1_GENERIC(ASI_AIUS)
+#define SPILL_2_OTHER SPILL_2_GENERIC(ASI_AIUS)
+#define SPILL_3_OTHER SPILL_3_NORMAL
+#define SPILL_4_OTHER SPILL_4_NORMAL
+#define SPILL_5_OTHER SPILL_5_NORMAL
+#define SPILL_6_OTHER SPILL_6_NORMAL
+#define SPILL_7_OTHER SPILL_7_NORMAL
+
+/* Normal kernel fill */
+#define FILL_0_NORMAL                                  \
+       ldx     [%sp + STACK_BIAS + 0x00], %l0;         \
+       ldx     [%sp + STACK_BIAS + 0x08], %l1;         \
+       ldx     [%sp + STACK_BIAS + 0x10], %l2;         \
+       ldx     [%sp + STACK_BIAS + 0x18], %l3;         \
+       ldx     [%sp + STACK_BIAS + 0x20], %l4;         \
+       ldx     [%sp + STACK_BIAS + 0x28], %l5;         \
+       ldx     [%sp + STACK_BIAS + 0x30], %l6;         \
+       ldx     [%sp + STACK_BIAS + 0x38], %l7;         \
+       ldx     [%sp + STACK_BIAS + 0x40], %i0;         \
+       ldx     [%sp + STACK_BIAS + 0x48], %i1;         \
+       ldx     [%sp + STACK_BIAS + 0x50], %i2;         \
+       ldx     [%sp + STACK_BIAS + 0x58], %i3;         \
+       ldx     [%sp + STACK_BIAS + 0x60], %i4;         \
+       ldx     [%sp + STACK_BIAS + 0x68], %i5;         \
+       ldx     [%sp + STACK_BIAS + 0x70], %i6;         \
+       ldx     [%sp + STACK_BIAS + 0x78], %i7;         \
+       restored; retry; nop; nop; nop; nop; nop; nop;  \
+       nop; nop; nop; nop; nop; nop; nop; nop;
+
+#define FILL_0_NORMAL_RTRAP                            \
+kern_rtt_fill:                                         \
+       rdpr    %cwp, %g1;                              \
+       sub     %g1, 1, %g1;                            \
+       wrpr    %g1, %cwp;                              \
+       ldx     [%sp + STACK_BIAS + 0x00], %l0;         \
+       ldx     [%sp + STACK_BIAS + 0x08], %l1;         \
+       ldx     [%sp + STACK_BIAS + 0x10], %l2;         \
+       ldx     [%sp + STACK_BIAS + 0x18], %l3;         \
+       ldx     [%sp + STACK_BIAS + 0x20], %l4;         \
+       ldx     [%sp + STACK_BIAS + 0x28], %l5;         \
+       ldx     [%sp + STACK_BIAS + 0x30], %l6;         \
+       ldx     [%sp + STACK_BIAS + 0x38], %l7;         \
+       ldx     [%sp + STACK_BIAS + 0x40], %i0;         \
+       ldx     [%sp + STACK_BIAS + 0x48], %i1;         \
+       ldx     [%sp + STACK_BIAS + 0x50], %i2;         \
+       ldx     [%sp + STACK_BIAS + 0x58], %i3;         \
+       ldx     [%sp + STACK_BIAS + 0x60], %i4;         \
+       ldx     [%sp + STACK_BIAS + 0x68], %i5;         \
+       ldx     [%sp + STACK_BIAS + 0x70], %i6;         \
+       ldx     [%sp + STACK_BIAS + 0x78], %i7;         \
+       restored;                                       \
+       add     %g1, 1, %g1;                            \
+       ba,pt   %xcc, kern_rtt_restore;                 \
+        wrpr   %g1, %cwp;                              \
+       nop; nop; nop; nop; nop;                        \
+       nop; nop; nop; nop;
+
+
+/* Normal 64bit fill */
+#define FILL_1_GENERIC(ASI)                            \
+       add     %sp, STACK_BIAS + 0x00, %g1;            \
+       ldxa    [%g1 + %g0] ASI, %l0;                   \
+       mov     0x08, %g2;                              \
+       mov     0x10, %g3;                              \
+       ldxa    [%g1 + %g2] ASI, %l1;                   \
+       mov     0x18, %g5;                              \
+       ldxa    [%g1 + %g3] ASI, %l2;                   \
+       ldxa    [%g1 + %g5] ASI, %l3;                   \
+       add     %g1, 0x20, %g1;                         \
+       ldxa    [%g1 + %g0] ASI, %l4;                   \
+       ldxa    [%g1 + %g2] ASI, %l5;                   \
+       ldxa    [%g1 + %g3] ASI, %l6;                   \
+       ldxa    [%g1 + %g5] ASI, %l7;                   \
+       add     %g1, 0x20, %g1;                         \
+       ldxa    [%g1 + %g0] ASI, %i0;                   \
+       ldxa    [%g1 + %g2] ASI, %i1;                   \
+       ldxa    [%g1 + %g3] ASI, %i2;                   \
+       ldxa    [%g1 + %g5] ASI, %i3;                   \
+       add     %g1, 0x20, %g1;                         \
+       ldxa    [%g1 + %g0] ASI, %i4;                   \
+       ldxa    [%g1 + %g2] ASI, %i5;                   \
+       ldxa    [%g1 + %g3] ASI, %i6;                   \
+       ldxa    [%g1 + %g5] ASI, %i7;                   \
+       restored;                                       \
+       retry; nop; nop; nop; nop;                      \
+       b,a,pt  %xcc, fill_fixup_dax;                   \
+       b,a,pt  %xcc, fill_fixup_mna;                   \
+       b,a,pt  %xcc, fill_fixup;
+
+#define FILL_1_GENERIC_RTRAP                           \
+user_rtt_fill_64bit:                                   \
+       ldxa    [%sp + STACK_BIAS + 0x00] %asi, %l0;    \
+       ldxa    [%sp + STACK_BIAS + 0x08] %asi, %l1;    \
+       ldxa    [%sp + STACK_BIAS + 0x10] %asi, %l2;    \
+       ldxa    [%sp + STACK_BIAS + 0x18] %asi, %l3;    \
+       ldxa    [%sp + STACK_BIAS + 0x20] %asi, %l4;    \
+       ldxa    [%sp + STACK_BIAS + 0x28] %asi, %l5;    \
+       ldxa    [%sp + STACK_BIAS + 0x30] %asi, %l6;    \
+       ldxa    [%sp + STACK_BIAS + 0x38] %asi, %l7;    \
+       ldxa    [%sp + STACK_BIAS + 0x40] %asi, %i0;    \
+       ldxa    [%sp + STACK_BIAS + 0x48] %asi, %i1;    \
+       ldxa    [%sp + STACK_BIAS + 0x50] %asi, %i2;    \
+       ldxa    [%sp + STACK_BIAS + 0x58] %asi, %i3;    \
+       ldxa    [%sp + STACK_BIAS + 0x60] %asi, %i4;    \
+       ldxa    [%sp + STACK_BIAS + 0x68] %asi, %i5;    \
+       ldxa    [%sp + STACK_BIAS + 0x70] %asi, %i6;    \
+       ldxa    [%sp + STACK_BIAS + 0x78] %asi, %i7;    \
+       ba,pt   %xcc, user_rtt_pre_restore;             \
+        restored;                                      \
+       nop; nop; nop; nop; nop; nop;                   \
+       nop; nop; nop; nop; nop;                        \
+       ba,a,pt %xcc, user_rtt_fill_fixup;              \
+       ba,a,pt %xcc, user_rtt_fill_fixup;              \
+       ba,a,pt %xcc, user_rtt_fill_fixup;
+
+
+/* Normal 32bit fill */
+#define FILL_2_GENERIC(ASI)                            \
+       srl     %sp, 0, %sp;                            \
+       lduwa   [%sp + %g0] ASI, %l0;                   \
+       mov     0x04, %g2;                              \
+       mov     0x08, %g3;                              \
+       lduwa   [%sp + %g2] ASI, %l1;                   \
+       mov     0x0c, %g5;                              \
+       lduwa   [%sp + %g3] ASI, %l2;                   \
+       lduwa   [%sp + %g5] ASI, %l3;                   \
+       add     %sp, 0x10, %g1;                         \
+       lduwa   [%g1 + %g0] ASI, %l4;                   \
+       lduwa   [%g1 + %g2] ASI, %l5;                   \
+       lduwa   [%g1 + %g3] ASI, %l6;                   \
+       lduwa   [%g1 + %g5] ASI, %l7;                   \
+       add     %g1, 0x10, %g1;                         \
+       lduwa   [%g1 + %g0] ASI, %i0;                   \
+       lduwa   [%g1 + %g2] ASI, %i1;                   \
+       lduwa   [%g1 + %g3] ASI, %i2;                   \
+       lduwa   [%g1 + %g5] ASI, %i3;                   \
+       add     %g1, 0x10, %g1;                         \
+       lduwa   [%g1 + %g0] ASI, %i4;                   \
+       lduwa   [%g1 + %g2] ASI, %i5;                   \
+       lduwa   [%g1 + %g3] ASI, %i6;                   \
+       lduwa   [%g1 + %g5] ASI, %i7;                   \
+       restored;                                       \
+       retry; nop; nop; nop; nop;                      \
+       b,a,pt  %xcc, fill_fixup_dax;                   \
+       b,a,pt  %xcc, fill_fixup_mna;                   \
+       b,a,pt  %xcc, fill_fixup;
+
+#define FILL_2_GENERIC_RTRAP                           \
+user_rtt_fill_32bit:                                   \
+       srl     %sp, 0, %sp;                            \
+       lduwa   [%sp + 0x00] %asi, %l0;                 \
+       lduwa   [%sp + 0x04] %asi, %l1;                 \
+       lduwa   [%sp + 0x08] %asi, %l2;                 \
+       lduwa   [%sp + 0x0c] %asi, %l3;                 \
+       lduwa   [%sp + 0x10] %asi, %l4;                 \
+       lduwa   [%sp + 0x14] %asi, %l5;                 \
+       lduwa   [%sp + 0x18] %asi, %l6;                 \
+       lduwa   [%sp + 0x1c] %asi, %l7;                 \
+       lduwa   [%sp + 0x20] %asi, %i0;                 \
+       lduwa   [%sp + 0x24] %asi, %i1;                 \
+       lduwa   [%sp + 0x28] %asi, %i2;                 \
+       lduwa   [%sp + 0x2c] %asi, %i3;                 \
+       lduwa   [%sp + 0x30] %asi, %i4;                 \
+       lduwa   [%sp + 0x34] %asi, %i5;                 \
+       lduwa   [%sp + 0x38] %asi, %i6;                 \
+       lduwa   [%sp + 0x3c] %asi, %i7;                 \
+       ba,pt   %xcc, user_rtt_pre_restore;             \
+        restored;                                      \
+       nop; nop; nop; nop; nop;                        \
+       nop; nop; nop; nop; nop;                        \
+       ba,a,pt %xcc, user_rtt_fill_fixup;              \
+       ba,a,pt %xcc, user_rtt_fill_fixup;              \
+       ba,a,pt %xcc, user_rtt_fill_fixup;
+
+
+#define FILL_1_NORMAL FILL_1_GENERIC(ASI_AIUP)
+#define FILL_2_NORMAL FILL_2_GENERIC(ASI_AIUP)
+#define FILL_3_NORMAL FILL_0_NORMAL
+#define FILL_4_NORMAL FILL_0_NORMAL
+#define FILL_5_NORMAL FILL_0_NORMAL
+#define FILL_6_NORMAL FILL_0_NORMAL
+#define FILL_7_NORMAL FILL_0_NORMAL
+
+#define FILL_0_OTHER FILL_0_NORMAL
+#define FILL_1_OTHER FILL_1_GENERIC(ASI_AIUS)
+#define FILL_2_OTHER FILL_2_GENERIC(ASI_AIUS)
+#define FILL_3_OTHER FILL_3_NORMAL
+#define FILL_4_OTHER FILL_4_NORMAL
+#define FILL_5_OTHER FILL_5_NORMAL
+#define FILL_6_OTHER FILL_6_NORMAL
+#define FILL_7_OTHER FILL_7_NORMAL
+
+#endif /* !(_SPARC64_TTABLE_H) */
index 07734f9424059ad83537eac13ee7b638bfa5bfb3..8c28fde5eaa2a794fd8b31fd4a95e9e00699f3f5 100644 (file)
@@ -1,6 +1,5 @@
 #ifndef _SPARC_TYPES_H
 #define _SPARC_TYPES_H
-
 /*
  * This file is never included by application software unless
  * explicitly requested (e.g., via linux/types.h) in which case the
@@ -8,6 +7,35 @@
  * not a major issue.  However, for interoperability, libraries still
  * need to be careful to avoid a name clashes.
  */
+
+#if defined(__sparc__) && defined(__arch64__)
+
+/*** SPARC 64 bit ***/
+#include <asm-generic/int-l64.h>
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+#endif /* __ASSEMBLY__ */
+
+#ifdef __KERNEL__
+
+#define BITS_PER_LONG 64
+
+#ifndef __ASSEMBLY__
+
+/* Dma addresses come in generic and 64-bit flavours.  */
+
+typedef u32 dma_addr_t;
+typedef u64 dma64_addr_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+#else
+
+/*** SPARC 32 bit ***/
 #include <asm-generic/int-ll64.h>
 
 #ifndef __ASSEMBLY__
@@ -29,4 +57,6 @@ typedef u32 dma64_addr_t;
 
 #endif /* __KERNEL__ */
 
+#endif /* defined(__sparc__) && defined(__arch64__) */
+
 #endif /* defined(_SPARC_TYPES_H) */
index 47d5619d43fafbdd15a0798b4357aac3f30cbce3..424facce5238774118d29473f2a6218d8f7a5adf 100644 (file)
@@ -1,336 +1,8 @@
-/*
- * uaccess.h: User space memore access functions.
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-#ifndef _ASM_UACCESS_H
-#define _ASM_UACCESS_H
-
-#ifdef __KERNEL__
-#include <linux/compiler.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <asm/vac-ops.h>
+#ifndef ___ASM_SPARC_UACCESS_H
+#define ___ASM_SPARC_UACCESS_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/uaccess_64.h>
+#else
+#include <asm-sparc/uaccess_32.h>
+#endif
 #endif
-
-#ifndef __ASSEMBLY__
-
-/* Sparc is not segmented, however we need to be able to fool access_ok()
- * when doing system calls from kernel mode legitimately.
- *
- * "For historical reasons, these macros are grossly misnamed." -Linus
- */
-
-#define KERNEL_DS   ((mm_segment_t) { 0 })
-#define USER_DS     ((mm_segment_t) { -1 })
-
-#define VERIFY_READ    0
-#define VERIFY_WRITE   1
-
-#define get_ds()       (KERNEL_DS)
-#define get_fs()       (current->thread.current_ds)
-#define set_fs(val)    ((current->thread.current_ds) = (val))
-
-#define segment_eq(a,b)        ((a).seg == (b).seg)
-
-/* We have there a nice not-mapped page at PAGE_OFFSET - PAGE_SIZE, so that this test
- * can be fairly lightweight.
- * No one can read/write anything from userland in the kernel space by setting
- * large size and address near to PAGE_OFFSET - a fault will break his intentions.
- */
-#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
-#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
-#define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
-#define access_ok(type, addr, size)                                    \
-       ({ (void)(type); __access_ok((unsigned long)(addr), size); })
-
-/*
- * The exception table consists of pairs of addresses: the first is the
- * address of an instruction that is allowed to fault, and the second is
- * the address at which the program should continue.  No registers are
- * modified, so it is entirely up to the continuation code to figure out
- * what to do.
- *
- * All the routines below use bits of fixup code that are out of line
- * with the main instruction path.  This means when everything is well,
- * we don't even have to jump over them.  Further, they do not intrude
- * on our cache or tlb entries.
- *
- * There is a special way how to put a range of potentially faulting
- * insns (like twenty ldd/std's with now intervening other instructions)
- * You specify address of first in insn and 0 in fixup and in the next
- * exception_table_entry you specify last potentially faulting insn + 1
- * and in fixup the routine which should handle the fault.
- * That fixup code will get
- * (faulting_insn_address - first_insn_in_the_range_address)/4
- * in %g2 (ie. index of the faulting instruction in the range).
- */
-
-struct exception_table_entry
-{
-        unsigned long insn, fixup;
-};
-
-/* Returns 0 if exception not found and fixup otherwise.  */
-extern unsigned long search_extables_range(unsigned long addr, unsigned long *g2);
-
-extern void __ret_efault(void);
-
-/* Uh, these should become the main single-value transfer routines..
- * They automatically use the right size if we just have the right
- * pointer type..
- *
- * This gets kind of ugly. We want to return _two_ values in "get_user()"
- * and yet we don't want to do any pointers, because that is too much
- * of a performance impact. Thus we have a few rather ugly macros here,
- * and hide all the ugliness from the user.
- */
-#define put_user(x,ptr) ({ \
-unsigned long __pu_addr = (unsigned long)(ptr); \
-__chk_user_ptr(ptr); \
-__put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
-
-#define get_user(x,ptr) ({ \
-unsigned long __gu_addr = (unsigned long)(ptr); \
-__chk_user_ptr(ptr); \
-__get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
-
-/*
- * The "__xxx" versions do not do address space checking, useful when
- * doing multiple accesses to the same area (the user has to do the
- * checks by hand with "access_ok()")
- */
-#define __put_user(x,ptr) __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
-#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr)))
-
-struct __large_struct { unsigned long buf[100]; };
-#define __m(x) ((struct __large_struct __user *)(x))
-
-#define __put_user_check(x,addr,size) ({ \
-register int __pu_ret; \
-if (__access_ok(addr,size)) { \
-switch (size) { \
-case 1: __put_user_asm(x,b,addr,__pu_ret); break; \
-case 2: __put_user_asm(x,h,addr,__pu_ret); break; \
-case 4: __put_user_asm(x,,addr,__pu_ret); break; \
-case 8: __put_user_asm(x,d,addr,__pu_ret); break; \
-default: __pu_ret = __put_user_bad(); break; \
-} } else { __pu_ret = -EFAULT; } __pu_ret; })
-
-#define __put_user_nocheck(x,addr,size) ({ \
-register int __pu_ret; \
-switch (size) { \
-case 1: __put_user_asm(x,b,addr,__pu_ret); break; \
-case 2: __put_user_asm(x,h,addr,__pu_ret); break; \
-case 4: __put_user_asm(x,,addr,__pu_ret); break; \
-case 8: __put_user_asm(x,d,addr,__pu_ret); break; \
-default: __pu_ret = __put_user_bad(); break; \
-} __pu_ret; })
-
-#define __put_user_asm(x,size,addr,ret)                                        \
-__asm__ __volatile__(                                                  \
-       "/* Put user asm, inline. */\n"                                 \
-"1:\t" "st"#size " %1, %2\n\t"                                         \
-       "clr    %0\n"                                                   \
-"2:\n\n\t"                                                             \
-       ".section .fixup,#alloc,#execinstr\n\t"                         \
-       ".align 4\n"                                                    \
-"3:\n\t"                                                               \
-       "b      2b\n\t"                                                 \
-       " mov   %3, %0\n\t"                                             \
-        ".previous\n\n\t"                                              \
-       ".section __ex_table,#alloc\n\t"                                \
-       ".align 4\n\t"                                                  \
-       ".word  1b, 3b\n\t"                                             \
-       ".previous\n\n\t"                                               \
-       : "=&r" (ret) : "r" (x), "m" (*__m(addr)),                      \
-        "i" (-EFAULT))
-
-extern int __put_user_bad(void);
-
-#define __get_user_check(x,addr,size,type) ({ \
-register int __gu_ret; \
-register unsigned long __gu_val; \
-if (__access_ok(addr,size)) { \
-switch (size) { \
-case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
-case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
-case 4: __get_user_asm(__gu_val,,addr,__gu_ret); break; \
-case 8: __get_user_asm(__gu_val,d,addr,__gu_ret); break; \
-default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
-} } else { __gu_val = 0; __gu_ret = -EFAULT; } x = (type) __gu_val; __gu_ret; })
-
-#define __get_user_check_ret(x,addr,size,type,retval) ({ \
-register unsigned long __gu_val __asm__ ("l1"); \
-if (__access_ok(addr,size)) { \
-switch (size) { \
-case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
-case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
-case 4: __get_user_asm_ret(__gu_val,,addr,retval); break; \
-case 8: __get_user_asm_ret(__gu_val,d,addr,retval); break; \
-default: if (__get_user_bad()) return retval; \
-} x = (type) __gu_val; } else return retval; })
-
-#define __get_user_nocheck(x,addr,size,type) ({ \
-register int __gu_ret; \
-register unsigned long __gu_val; \
-switch (size) { \
-case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
-case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
-case 4: __get_user_asm(__gu_val,,addr,__gu_ret); break; \
-case 8: __get_user_asm(__gu_val,d,addr,__gu_ret); break; \
-default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
-} x = (type) __gu_val; __gu_ret; })
-
-#define __get_user_nocheck_ret(x,addr,size,type,retval) ({ \
-register unsigned long __gu_val __asm__ ("l1"); \
-switch (size) { \
-case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
-case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
-case 4: __get_user_asm_ret(__gu_val,,addr,retval); break; \
-case 8: __get_user_asm_ret(__gu_val,d,addr,retval); break; \
-default: if (__get_user_bad()) return retval; \
-} x = (type) __gu_val; })
-
-#define __get_user_asm(x,size,addr,ret)                                        \
-__asm__ __volatile__(                                                  \
-       "/* Get user asm, inline. */\n"                                 \
-"1:\t" "ld"#size " %2, %1\n\t"                                         \
-       "clr    %0\n"                                                   \
-"2:\n\n\t"                                                             \
-       ".section .fixup,#alloc,#execinstr\n\t"                         \
-       ".align 4\n"                                                    \
-"3:\n\t"                                                               \
-       "clr    %1\n\t"                                                 \
-       "b      2b\n\t"                                                 \
-       " mov   %3, %0\n\n\t"                                           \
-       ".previous\n\t"                                                 \
-       ".section __ex_table,#alloc\n\t"                                \
-       ".align 4\n\t"                                                  \
-       ".word  1b, 3b\n\n\t"                                           \
-       ".previous\n\t"                                                 \
-       : "=&r" (ret), "=&r" (x) : "m" (*__m(addr)),                    \
-        "i" (-EFAULT))
-
-#define __get_user_asm_ret(x,size,addr,retval)                         \
-if (__builtin_constant_p(retval) && retval == -EFAULT)                 \
-__asm__ __volatile__(                                                  \
-       "/* Get user asm ret, inline. */\n"                             \
-"1:\t" "ld"#size " %1, %0\n\n\t"                                       \
-       ".section __ex_table,#alloc\n\t"                                \
-       ".align 4\n\t"                                                  \
-       ".word  1b,__ret_efault\n\n\t"                                  \
-       ".previous\n\t"                                                 \
-       : "=&r" (x) : "m" (*__m(addr)));                                        \
-else                                                                   \
-__asm__ __volatile__(                                                  \
-       "/* Get user asm ret, inline. */\n"                             \
-"1:\t" "ld"#size " %1, %0\n\n\t"                                       \
-       ".section .fixup,#alloc,#execinstr\n\t"                         \
-       ".align 4\n"                                                    \
-"3:\n\t"                                                               \
-       "ret\n\t"                                                       \
-       " restore %%g0, %2, %%o0\n\n\t"                                 \
-       ".previous\n\t"                                                 \
-       ".section __ex_table,#alloc\n\t"                                \
-       ".align 4\n\t"                                                  \
-       ".word  1b, 3b\n\n\t"                                           \
-       ".previous\n\t"                                                 \
-       : "=&r" (x) : "m" (*__m(addr)), "i" (retval))
-
-extern int __get_user_bad(void);
-
-extern unsigned long __copy_user(void __user *to, const void __user *from, unsigned long size);
-
-static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
-{
-       if (n && __access_ok((unsigned long) to, n))
-               return __copy_user(to, (__force void __user *) from, n);
-       else
-               return n;
-}
-
-static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)
-{
-       return __copy_user(to, (__force void __user *) from, n);
-}
-
-static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
-{
-       if (n && __access_ok((unsigned long) from, n))
-               return __copy_user((__force void __user *) to, from, n);
-       else
-               return n;
-}
-
-static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
-{
-       return __copy_user((__force void __user *) to, from, n);
-}
-
-#define __copy_to_user_inatomic __copy_to_user
-#define __copy_from_user_inatomic __copy_from_user
-
-static inline unsigned long __clear_user(void __user *addr, unsigned long size)
-{
-       unsigned long ret;
-
-       __asm__ __volatile__ (
-               ".section __ex_table,#alloc\n\t"
-               ".align 4\n\t"
-               ".word 1f,3\n\t"
-               ".previous\n\t"
-               "mov %2, %%o1\n"
-               "1:\n\t"
-               "call __bzero\n\t"
-               " mov %1, %%o0\n\t"
-               "mov %%o0, %0\n"
-               : "=r" (ret) : "r" (addr), "r" (size) :
-               "o0", "o1", "o2", "o3", "o4", "o5", "o7",
-               "g1", "g2", "g3", "g4", "g5", "g7", "cc");
-
-       return ret;
-}
-
-static inline unsigned long clear_user(void __user *addr, unsigned long n)
-{
-       if (n && __access_ok((unsigned long) addr, n))
-               return __clear_user(addr, n);
-       else
-               return n;
-}
-
-extern long __strncpy_from_user(char *dest, const char __user *src, long count);
-
-static inline long strncpy_from_user(char *dest, const char __user *src, long count)
-{
-       if (__access_ok((unsigned long) src, count))
-               return __strncpy_from_user(dest, src, count);
-       else
-               return -EFAULT;
-}
-
-extern long __strlen_user(const char __user *);
-extern long __strnlen_user(const char __user *, long len);
-
-static inline long strlen_user(const char __user *str)
-{
-       if (!access_ok(VERIFY_READ, str, 0))
-               return 0;
-       else
-               return __strlen_user(str);
-}
-
-static inline long strnlen_user(const char __user *str, long len)
-{
-       if (!access_ok(VERIFY_READ, str, 0))
-               return 0;
-       else
-               return __strnlen_user(str, len);
-}
-
-#endif  /* __ASSEMBLY__ */
-
-#endif /* _ASM_UACCESS_H */
diff --git a/include/asm-sparc/uaccess_32.h b/include/asm-sparc/uaccess_32.h
new file mode 100644 (file)
index 0000000..47d5619
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * uaccess.h: User space memore access functions.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
+
+#ifdef __KERNEL__
+#include <linux/compiler.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <asm/vac-ops.h>
+#endif
+
+#ifndef __ASSEMBLY__
+
+/* Sparc is not segmented, however we need to be able to fool access_ok()
+ * when doing system calls from kernel mode legitimately.
+ *
+ * "For historical reasons, these macros are grossly misnamed." -Linus
+ */
+
+#define KERNEL_DS   ((mm_segment_t) { 0 })
+#define USER_DS     ((mm_segment_t) { -1 })
+
+#define VERIFY_READ    0
+#define VERIFY_WRITE   1
+
+#define get_ds()       (KERNEL_DS)
+#define get_fs()       (current->thread.current_ds)
+#define set_fs(val)    ((current->thread.current_ds) = (val))
+
+#define segment_eq(a,b)        ((a).seg == (b).seg)
+
+/* We have there a nice not-mapped page at PAGE_OFFSET - PAGE_SIZE, so that this test
+ * can be fairly lightweight.
+ * No one can read/write anything from userland in the kernel space by setting
+ * large size and address near to PAGE_OFFSET - a fault will break his intentions.
+ */
+#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
+#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+#define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
+#define access_ok(type, addr, size)                                    \
+       ({ (void)(type); __access_ok((unsigned long)(addr), size); })
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ *
+ * There is a special way how to put a range of potentially faulting
+ * insns (like twenty ldd/std's with now intervening other instructions)
+ * You specify address of first in insn and 0 in fixup and in the next
+ * exception_table_entry you specify last potentially faulting insn + 1
+ * and in fixup the routine which should handle the fault.
+ * That fixup code will get
+ * (faulting_insn_address - first_insn_in_the_range_address)/4
+ * in %g2 (ie. index of the faulting instruction in the range).
+ */
+
+struct exception_table_entry
+{
+        unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_extables_range(unsigned long addr, unsigned long *g2);
+
+extern void __ret_efault(void);
+
+/* Uh, these should become the main single-value transfer routines..
+ * They automatically use the right size if we just have the right
+ * pointer type..
+ *
+ * This gets kind of ugly. We want to return _two_ values in "get_user()"
+ * and yet we don't want to do any pointers, because that is too much
+ * of a performance impact. Thus we have a few rather ugly macros here,
+ * and hide all the ugliness from the user.
+ */
+#define put_user(x,ptr) ({ \
+unsigned long __pu_addr = (unsigned long)(ptr); \
+__chk_user_ptr(ptr); \
+__put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
+
+#define get_user(x,ptr) ({ \
+unsigned long __gu_addr = (unsigned long)(ptr); \
+__chk_user_ptr(ptr); \
+__get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
+
+/*
+ * The "__xxx" versions do not do address space checking, useful when
+ * doing multiple accesses to the same area (the user has to do the
+ * checks by hand with "access_ok()")
+ */
+#define __put_user(x,ptr) __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr)))
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) ((struct __large_struct __user *)(x))
+
+#define __put_user_check(x,addr,size) ({ \
+register int __pu_ret; \
+if (__access_ok(addr,size)) { \
+switch (size) { \
+case 1: __put_user_asm(x,b,addr,__pu_ret); break; \
+case 2: __put_user_asm(x,h,addr,__pu_ret); break; \
+case 4: __put_user_asm(x,,addr,__pu_ret); break; \
+case 8: __put_user_asm(x,d,addr,__pu_ret); break; \
+default: __pu_ret = __put_user_bad(); break; \
+} } else { __pu_ret = -EFAULT; } __pu_ret; })
+
+#define __put_user_nocheck(x,addr,size) ({ \
+register int __pu_ret; \
+switch (size) { \
+case 1: __put_user_asm(x,b,addr,__pu_ret); break; \
+case 2: __put_user_asm(x,h,addr,__pu_ret); break; \
+case 4: __put_user_asm(x,,addr,__pu_ret); break; \
+case 8: __put_user_asm(x,d,addr,__pu_ret); break; \
+default: __pu_ret = __put_user_bad(); break; \
+} __pu_ret; })
+
+#define __put_user_asm(x,size,addr,ret)                                        \
+__asm__ __volatile__(                                                  \
+       "/* Put user asm, inline. */\n"                                 \
+"1:\t" "st"#size " %1, %2\n\t"                                         \
+       "clr    %0\n"                                                   \
+"2:\n\n\t"                                                             \
+       ".section .fixup,#alloc,#execinstr\n\t"                         \
+       ".align 4\n"                                                    \
+"3:\n\t"                                                               \
+       "b      2b\n\t"                                                 \
+       " mov   %3, %0\n\t"                                             \
+        ".previous\n\n\t"                                              \
+       ".section __ex_table,#alloc\n\t"                                \
+       ".align 4\n\t"                                                  \
+       ".word  1b, 3b\n\t"                                             \
+       ".previous\n\n\t"                                               \
+       : "=&r" (ret) : "r" (x), "m" (*__m(addr)),                      \
+        "i" (-EFAULT))
+
+extern int __put_user_bad(void);
+
+#define __get_user_check(x,addr,size,type) ({ \
+register int __gu_ret; \
+register unsigned long __gu_val; \
+if (__access_ok(addr,size)) { \
+switch (size) { \
+case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
+case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
+case 4: __get_user_asm(__gu_val,,addr,__gu_ret); break; \
+case 8: __get_user_asm(__gu_val,d,addr,__gu_ret); break; \
+default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
+} } else { __gu_val = 0; __gu_ret = -EFAULT; } x = (type) __gu_val; __gu_ret; })
+
+#define __get_user_check_ret(x,addr,size,type,retval) ({ \
+register unsigned long __gu_val __asm__ ("l1"); \
+if (__access_ok(addr,size)) { \
+switch (size) { \
+case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
+case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
+case 4: __get_user_asm_ret(__gu_val,,addr,retval); break; \
+case 8: __get_user_asm_ret(__gu_val,d,addr,retval); break; \
+default: if (__get_user_bad()) return retval; \
+} x = (type) __gu_val; } else return retval; })
+
+#define __get_user_nocheck(x,addr,size,type) ({ \
+register int __gu_ret; \
+register unsigned long __gu_val; \
+switch (size) { \
+case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
+case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
+case 4: __get_user_asm(__gu_val,,addr,__gu_ret); break; \
+case 8: __get_user_asm(__gu_val,d,addr,__gu_ret); break; \
+default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
+} x = (type) __gu_val; __gu_ret; })
+
+#define __get_user_nocheck_ret(x,addr,size,type,retval) ({ \
+register unsigned long __gu_val __asm__ ("l1"); \
+switch (size) { \
+case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
+case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
+case 4: __get_user_asm_ret(__gu_val,,addr,retval); break; \
+case 8: __get_user_asm_ret(__gu_val,d,addr,retval); break; \
+default: if (__get_user_bad()) return retval; \
+} x = (type) __gu_val; })
+
+#define __get_user_asm(x,size,addr,ret)                                        \
+__asm__ __volatile__(                                                  \
+       "/* Get user asm, inline. */\n"                                 \
+"1:\t" "ld"#size " %2, %1\n\t"                                         \
+       "clr    %0\n"                                                   \
+"2:\n\n\t"                                                             \
+       ".section .fixup,#alloc,#execinstr\n\t"                         \
+       ".align 4\n"                                                    \
+"3:\n\t"                                                               \
+       "clr    %1\n\t"                                                 \
+       "b      2b\n\t"                                                 \
+       " mov   %3, %0\n\n\t"                                           \
+       ".previous\n\t"                                                 \
+       ".section __ex_table,#alloc\n\t"                                \
+       ".align 4\n\t"                                                  \
+       ".word  1b, 3b\n\n\t"                                           \
+       ".previous\n\t"                                                 \
+       : "=&r" (ret), "=&r" (x) : "m" (*__m(addr)),                    \
+        "i" (-EFAULT))
+
+#define __get_user_asm_ret(x,size,addr,retval)                         \
+if (__builtin_constant_p(retval) && retval == -EFAULT)                 \
+__asm__ __volatile__(                                                  \
+       "/* Get user asm ret, inline. */\n"                             \
+"1:\t" "ld"#size " %1, %0\n\n\t"                                       \
+       ".section __ex_table,#alloc\n\t"                                \
+       ".align 4\n\t"                                                  \
+       ".word  1b,__ret_efault\n\n\t"                                  \
+       ".previous\n\t"                                                 \
+       : "=&r" (x) : "m" (*__m(addr)));                                        \
+else                                                                   \
+__asm__ __volatile__(                                                  \
+       "/* Get user asm ret, inline. */\n"                             \
+"1:\t" "ld"#size " %1, %0\n\n\t"                                       \
+       ".section .fixup,#alloc,#execinstr\n\t"                         \
+       ".align 4\n"                                                    \
+"3:\n\t"                                                               \
+       "ret\n\t"                                                       \
+       " restore %%g0, %2, %%o0\n\n\t"                                 \
+       ".previous\n\t"                                                 \
+       ".section __ex_table,#alloc\n\t"                                \
+       ".align 4\n\t"                                                  \
+       ".word  1b, 3b\n\n\t"                                           \
+       ".previous\n\t"                                                 \
+       : "=&r" (x) : "m" (*__m(addr)), "i" (retval))
+
+extern int __get_user_bad(void);
+
+extern unsigned long __copy_user(void __user *to, const void __user *from, unsigned long size);
+
+static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+       if (n && __access_ok((unsigned long) to, n))
+               return __copy_user(to, (__force void __user *) from, n);
+       else
+               return n;
+}
+
+static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+       return __copy_user(to, (__force void __user *) from, n);
+}
+
+static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+       if (n && __access_ok((unsigned long) from, n))
+               return __copy_user((__force void __user *) to, from, n);
+       else
+               return n;
+}
+
+static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+       return __copy_user((__force void __user *) to, from, n);
+}
+
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+
+static inline unsigned long __clear_user(void __user *addr, unsigned long size)
+{
+       unsigned long ret;
+
+       __asm__ __volatile__ (
+               ".section __ex_table,#alloc\n\t"
+               ".align 4\n\t"
+               ".word 1f,3\n\t"
+               ".previous\n\t"
+               "mov %2, %%o1\n"
+               "1:\n\t"
+               "call __bzero\n\t"
+               " mov %1, %%o0\n\t"
+               "mov %%o0, %0\n"
+               : "=r" (ret) : "r" (addr), "r" (size) :
+               "o0", "o1", "o2", "o3", "o4", "o5", "o7",
+               "g1", "g2", "g3", "g4", "g5", "g7", "cc");
+
+       return ret;
+}
+
+static inline unsigned long clear_user(void __user *addr, unsigned long n)
+{
+       if (n && __access_ok((unsigned long) addr, n))
+               return __clear_user(addr, n);
+       else
+               return n;
+}
+
+extern long __strncpy_from_user(char *dest, const char __user *src, long count);
+
+static inline long strncpy_from_user(char *dest, const char __user *src, long count)
+{
+       if (__access_ok((unsigned long) src, count))
+               return __strncpy_from_user(dest, src, count);
+       else
+               return -EFAULT;
+}
+
+extern long __strlen_user(const char __user *);
+extern long __strnlen_user(const char __user *, long len);
+
+static inline long strlen_user(const char __user *str)
+{
+       if (!access_ok(VERIFY_READ, str, 0))
+               return 0;
+       else
+               return __strlen_user(str);
+}
+
+static inline long strnlen_user(const char __user *str, long len)
+{
+       if (!access_ok(VERIFY_READ, str, 0))
+               return 0;
+       else
+               return __strnlen_user(str, len);
+}
+
+#endif  /* __ASSEMBLY__ */
+
+#endif /* _ASM_UACCESS_H */
diff --git a/include/asm-sparc/uaccess_64.h b/include/asm-sparc/uaccess_64.h
new file mode 100644 (file)
index 0000000..296ef30
--- /dev/null
@@ -0,0 +1,273 @@
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+
+#ifdef __KERNEL__
+#include <linux/compiler.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <asm/asi.h>
+#include <asm/system.h>
+#include <asm/spitfire.h>
+#include <asm-generic/uaccess.h>
+#endif
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Sparc64 is segmented, though more like the M68K than the I386.
+ * We use the secondary ASI to address user memory, which references a
+ * completely different VM map, thus there is zero chance of the user
+ * doing something queer and tricking us into poking kernel memory.
+ *
+ * What is left here is basically what is needed for the other parts of
+ * the kernel that expect to be able to manipulate, erum, "segments".
+ * Or perhaps more properly, permissions.
+ *
+ * "For historical reasons, these macros are grossly misnamed." -Linus
+ */
+
+#define KERNEL_DS   ((mm_segment_t) { ASI_P })
+#define USER_DS     ((mm_segment_t) { ASI_AIUS })      /* har har har */
+
+#define VERIFY_READ    0
+#define VERIFY_WRITE   1
+
+#define get_fs() ((mm_segment_t) { get_thread_current_ds() })
+#define get_ds() (KERNEL_DS)
+
+#define segment_eq(a,b)  ((a).seg == (b).seg)
+
+#define set_fs(val)                                                            \
+do {                                                                           \
+       set_thread_current_ds((val).seg);                                       \
+       __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg));        \
+} while(0)
+
+static inline int __access_ok(const void __user * addr, unsigned long size)
+{
+       return 1;
+}
+
+static inline int access_ok(int type, const void __user * addr, unsigned long size)
+{
+       return 1;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry {
+        unsigned int insn, fixup;
+};
+
+extern void __ret_efault(void);
+extern void __retl_efault(void);
+
+/* Uh, these should become the main single-value transfer routines..
+ * They automatically use the right size if we just have the right
+ * pointer type..
+ *
+ * This gets kind of ugly. We want to return _two_ values in "get_user()"
+ * and yet we don't want to do any pointers, because that is too much
+ * of a performance impact. Thus we have a few rather ugly macros here,
+ * and hide all the ugliness from the user.
+ */
+#define put_user(x,ptr) ({ \
+unsigned long __pu_addr = (unsigned long)(ptr); \
+__chk_user_ptr(ptr); \
+__put_user_nocheck((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
+
+#define get_user(x,ptr) ({ \
+unsigned long __gu_addr = (unsigned long)(ptr); \
+__chk_user_ptr(ptr); \
+__get_user_nocheck((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
+
+#define __put_user(x,ptr) put_user(x,ptr)
+#define __get_user(x,ptr) get_user(x,ptr)
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) ((struct __large_struct *)(x))
+
+#define __put_user_nocheck(data,addr,size) ({ \
+register int __pu_ret; \
+switch (size) { \
+case 1: __put_user_asm(data,b,addr,__pu_ret); break; \
+case 2: __put_user_asm(data,h,addr,__pu_ret); break; \
+case 4: __put_user_asm(data,w,addr,__pu_ret); break; \
+case 8: __put_user_asm(data,x,addr,__pu_ret); break; \
+default: __pu_ret = __put_user_bad(); break; \
+} __pu_ret; })
+
+#define __put_user_asm(x,size,addr,ret)                                        \
+__asm__ __volatile__(                                                  \
+       "/* Put user asm, inline. */\n"                                 \
+"1:\t" "st"#size "a %1, [%2] %%asi\n\t"                                \
+       "clr    %0\n"                                                   \
+"2:\n\n\t"                                                             \
+       ".section .fixup,#alloc,#execinstr\n\t"                         \
+       ".align 4\n"                                                    \
+"3:\n\t"                                                               \
+       "sethi  %%hi(2b), %0\n\t"                                       \
+       "jmpl   %0 + %%lo(2b), %%g0\n\t"                                \
+       " mov   %3, %0\n\n\t"                                           \
+       ".previous\n\t"                                                 \
+       ".section __ex_table,\"a\"\n\t"                                 \
+       ".align 4\n\t"                                                  \
+       ".word  1b, 3b\n\t"                                             \
+       ".previous\n\n\t"                                               \
+       : "=r" (ret) : "r" (x), "r" (__m(addr)),                                \
+        "i" (-EFAULT))
+
+extern int __put_user_bad(void);
+
+#define __get_user_nocheck(data,addr,size,type) ({ \
+register int __gu_ret; \
+register unsigned long __gu_val; \
+switch (size) { \
+case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
+case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
+case 4: __get_user_asm(__gu_val,uw,addr,__gu_ret); break; \
+case 8: __get_user_asm(__gu_val,x,addr,__gu_ret); break; \
+default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
+} data = (type) __gu_val; __gu_ret; })
+
+#define __get_user_nocheck_ret(data,addr,size,type,retval) ({ \
+register unsigned long __gu_val __asm__ ("l1"); \
+switch (size) { \
+case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
+case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
+case 4: __get_user_asm_ret(__gu_val,uw,addr,retval); break; \
+case 8: __get_user_asm_ret(__gu_val,x,addr,retval); break; \
+default: if (__get_user_bad()) return retval; \
+} data = (type) __gu_val; })
+
+#define __get_user_asm(x,size,addr,ret)                                        \
+__asm__ __volatile__(                                                  \
+       "/* Get user asm, inline. */\n"                                 \
+"1:\t" "ld"#size "a [%2] %%asi, %1\n\t"                                \
+       "clr    %0\n"                                                   \
+"2:\n\n\t"                                                             \
+       ".section .fixup,#alloc,#execinstr\n\t"                         \
+       ".align 4\n"                                                    \
+"3:\n\t"                                                               \
+       "sethi  %%hi(2b), %0\n\t"                                       \
+       "clr    %1\n\t"                                                 \
+       "jmpl   %0 + %%lo(2b), %%g0\n\t"                                \
+       " mov   %3, %0\n\n\t"                                           \
+       ".previous\n\t"                                                 \
+       ".section __ex_table,\"a\"\n\t"                                 \
+       ".align 4\n\t"                                                  \
+       ".word  1b, 3b\n\n\t"                                           \
+       ".previous\n\t"                                                 \
+       : "=r" (ret), "=r" (x) : "r" (__m(addr)),                       \
+        "i" (-EFAULT))
+
+#define __get_user_asm_ret(x,size,addr,retval)                         \
+if (__builtin_constant_p(retval) && retval == -EFAULT)                 \
+__asm__ __volatile__(                                                  \
+       "/* Get user asm ret, inline. */\n"                             \
+"1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t"                              \
+       ".section __ex_table,\"a\"\n\t"                                 \
+       ".align 4\n\t"                                                  \
+       ".word  1b,__ret_efault\n\n\t"                                  \
+       ".previous\n\t"                                                 \
+       : "=r" (x) : "r" (__m(addr)));                                  \
+else                                                                   \
+__asm__ __volatile__(                                                  \
+       "/* Get user asm ret, inline. */\n"                             \
+"1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t"                              \
+       ".section .fixup,#alloc,#execinstr\n\t"                         \
+       ".align 4\n"                                                    \
+"3:\n\t"                                                               \
+       "ret\n\t"                                                       \
+       " restore %%g0, %2, %%o0\n\n\t"                                 \
+       ".previous\n\t"                                                 \
+       ".section __ex_table,\"a\"\n\t"                                 \
+       ".align 4\n\t"                                                  \
+       ".word  1b, 3b\n\n\t"                                           \
+       ".previous\n\t"                                                 \
+       : "=r" (x) : "r" (__m(addr)), "i" (retval))
+
+extern int __get_user_bad(void);
+
+extern unsigned long __must_check ___copy_from_user(void *to,
+                                                   const void __user *from,
+                                                   unsigned long size);
+extern unsigned long copy_from_user_fixup(void *to, const void __user *from,
+                                         unsigned long size);
+static inline unsigned long __must_check
+copy_from_user(void *to, const void __user *from, unsigned long size)
+{
+       unsigned long ret = ___copy_from_user(to, from, size);
+
+       if (unlikely(ret))
+               ret = copy_from_user_fixup(to, from, size);
+       return ret;
+}
+#define __copy_from_user copy_from_user
+
+extern unsigned long __must_check ___copy_to_user(void __user *to,
+                                                 const void *from,
+                                                 unsigned long size);
+extern unsigned long copy_to_user_fixup(void __user *to, const void *from,
+                                       unsigned long size);
+static inline unsigned long __must_check
+copy_to_user(void __user *to, const void *from, unsigned long size)
+{
+       unsigned long ret = ___copy_to_user(to, from, size);
+
+       if (unlikely(ret))
+               ret = copy_to_user_fixup(to, from, size);
+       return ret;
+}
+#define __copy_to_user copy_to_user
+
+extern unsigned long __must_check ___copy_in_user(void __user *to,
+                                                 const void __user *from,
+                                                 unsigned long size);
+extern unsigned long copy_in_user_fixup(void __user *to, void __user *from,
+                                       unsigned long size);
+static inline unsigned long __must_check
+copy_in_user(void __user *to, void __user *from, unsigned long size)
+{
+       unsigned long ret = ___copy_in_user(to, from, size);
+
+       if (unlikely(ret))
+               ret = copy_in_user_fixup(to, from, size);
+       return ret;
+}
+#define __copy_in_user copy_in_user
+
+extern unsigned long __must_check __clear_user(void __user *, unsigned long);
+
+#define clear_user __clear_user
+
+extern long __must_check __strncpy_from_user(char *dest, const char __user *src, long count);
+
+#define strncpy_from_user __strncpy_from_user
+
+extern long __strlen_user(const char __user *);
+extern long __strnlen_user(const char __user *, long len);
+
+#define strlen_user __strlen_user
+#define strnlen_user __strnlen_user
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+
+#endif  /* __ASSEMBLY__ */
+
+#endif /* _ASM_UACCESS_H */
diff --git a/include/asm-sparc/uctx.h b/include/asm-sparc/uctx.h
new file mode 100644 (file)
index 0000000..dc937c7
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * uctx.h: Sparc64 {set,get}context() register state layouts.
+ *
+ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __SPARC64_UCTX_H
+#define __SPARC64_UCTX_H
+
+#define MC_TSTATE      0
+#define MC_PC          1
+#define MC_NPC         2
+#define MC_Y           3
+#define MC_G1          4
+#define MC_G2          5
+#define MC_G3          6
+#define MC_G4          7
+#define MC_G5          8
+#define MC_G6          9
+#define MC_G7          10
+#define MC_O0          11
+#define MC_O1          12
+#define MC_O2          13
+#define MC_O3          14
+#define MC_O4          15
+#define MC_O5          16
+#define MC_O6          17
+#define MC_O7          18
+#define MC_NGREG       19
+
+typedef unsigned long mc_greg_t;
+typedef mc_greg_t mc_gregset_t[MC_NGREG];
+
+#define MC_MAXFPQ      16
+struct mc_fq {
+       unsigned long   *mcfq_addr;
+       unsigned int    mcfq_insn;
+};
+
+struct mc_fpu {
+       union {
+               unsigned int    sregs[32];
+               unsigned long   dregs[32];
+               long double     qregs[16];
+       } mcfpu_fregs;
+       unsigned long   mcfpu_fsr;
+       unsigned long   mcfpu_fprs;
+       unsigned long   mcfpu_gsr;
+       struct mc_fq    *mcfpu_fq;
+       unsigned char   mcfpu_qcnt;
+       unsigned char   mcfpu_qentsz;
+       unsigned char   mcfpu_enab;
+};
+typedef struct mc_fpu mc_fpu_t;
+
+typedef struct {
+       mc_gregset_t    mc_gregs;
+       mc_greg_t       mc_fp;
+       mc_greg_t       mc_i7;
+       mc_fpu_t        mc_fpregs;
+} mcontext_t;
+
+struct ucontext {
+       struct ucontext         *uc_link;
+       unsigned long           uc_flags;
+       sigset_t                uc_sigmask;
+       mcontext_t              uc_mcontext;
+};
+typedef struct ucontext ucontext_t;
+
+#endif /* __SPARC64_UCTX_H */
index 2338a027637705052632b6c535170bc05ca5e312..3c2609618a099e037306190ce38ebbd56d848218 100644 (file)
@@ -1,378 +1,8 @@
-#ifndef _SPARC_UNISTD_H
-#define _SPARC_UNISTD_H
-
-/*
- * System calls under the Sparc.
- *
- * Don't be scared by the ugly clobbers, it is the only way I can
- * think of right now to force the arguments into fixed registers
- * before the trap into the system call with gcc 'asm' statements.
- *
- * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
- *
- * SunOS compatibility based upon preliminary work which is:
- *
- * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
- */
-
-#define __NR_restart_syscall      0 /* Linux Specific                             */
-#define __NR_exit                 1 /* Common                                      */
-#define __NR_fork                 2 /* Common                                      */
-#define __NR_read                 3 /* Common                                      */
-#define __NR_write                4 /* Common                                      */
-#define __NR_open                 5 /* Common                                      */
-#define __NR_close                6 /* Common                                      */
-#define __NR_wait4                7 /* Common                                      */
-#define __NR_creat                8 /* Common                                      */
-#define __NR_link                 9 /* Common                                      */
-#define __NR_unlink              10 /* Common                                      */
-#define __NR_execv               11 /* SunOS Specific                              */
-#define __NR_chdir               12 /* Common                                      */
-#define __NR_chown              13 /* Common                                      */
-#define __NR_mknod               14 /* Common                                      */
-#define __NR_chmod               15 /* Common                                      */
-#define __NR_lchown              16 /* Common                                      */
-#define __NR_brk                 17 /* Common                                      */
-#define __NR_perfctr             18 /* Performance counter operations              */
-#define __NR_lseek               19 /* Common                                      */
-#define __NR_getpid              20 /* Common                                      */
-#define __NR_capget             21 /* Linux Specific                              */
-#define __NR_capset             22 /* Linux Specific                              */
-#define __NR_setuid              23 /* Implemented via setreuid in SunOS           */
-#define __NR_getuid              24 /* Common                                      */
-#define __NR_vmsplice           25 /* ENOSYS under SunOS                          */
-#define __NR_ptrace              26 /* Common                                      */
-#define __NR_alarm               27 /* Implemented via setitimer in SunOS          */
-#define __NR_sigaltstack        28 /* Common                                      */
-#define __NR_pause               29 /* Is sigblock(0)->sigpause() in SunOS         */
-#define __NR_utime               30 /* Implemented via utimes() under SunOS        */
-#define __NR_lchown32            31 /* Linux sparc32 specific                      */
-#define __NR_fchown32            32 /* Linux sparc32 specific                      */
-#define __NR_access              33 /* Common                                      */
-#define __NR_nice                34 /* Implemented via get/setpriority() in SunOS  */
-#define __NR_chown32             35 /* Linux sparc32 specific                      */
-#define __NR_sync                36 /* Common                                      */
-#define __NR_kill                37 /* Common                                      */
-#define __NR_stat                38 /* Common                                      */
-#define __NR_sendfile           39 /* Linux Specific                              */
-#define __NR_lstat               40 /* Common                                      */
-#define __NR_dup                 41 /* Common                                      */
-#define __NR_pipe                42 /* Common                                      */
-#define __NR_times               43 /* Implemented via getrusage() in SunOS        */
-#define __NR_getuid32            44 /* Linux sparc32 specific                      */
-#define __NR_umount2             45 /* Linux Specific                              */
-#define __NR_setgid              46 /* Implemented via setregid() in SunOS         */
-#define __NR_getgid              47 /* Common                                      */
-#define __NR_signal              48 /* Implemented via sigvec() in SunOS           */
-#define __NR_geteuid             49 /* SunOS calls getuid()                        */
-#define __NR_getegid             50 /* SunOS calls getgid()                        */
-#define __NR_acct                51 /* Common                                      */
-/* #define __NR_memory_ordering  52    Linux sparc64 specific                     */
-#define __NR_getgid32            53 /* Linux sparc32 specific                      */
-#define __NR_ioctl               54 /* Common                                      */
-#define __NR_reboot              55 /* Common                                      */
-#define __NR_mmap2              56 /* Linux sparc32 Specific                      */
-#define __NR_symlink             57 /* Common                                      */
-#define __NR_readlink            58 /* Common                                      */
-#define __NR_execve              59 /* Common                                      */
-#define __NR_umask               60 /* Common                                      */
-#define __NR_chroot              61 /* Common                                      */
-#define __NR_fstat               62 /* Common                                      */
-#define __NR_fstat64            63 /* Linux Specific                              */
-#define __NR_getpagesize         64 /* Common                                      */
-#define __NR_msync               65 /* Common in newer 1.3.x revs...               */
-#define __NR_vfork               66 /* Common                                      */
-#define __NR_pread64             67 /* Linux Specific                              */
-#define __NR_pwrite64            68 /* Linux Specific                              */
-#define __NR_geteuid32           69 /* Linux sparc32, sbrk under SunOS             */
-#define __NR_getegid32           70 /* Linux sparc32, sstk under SunOS             */
-#define __NR_mmap                71 /* Common                                      */
-#define __NR_setreuid32          72 /* Linux sparc32, vadvise under SunOS          */
-#define __NR_munmap              73 /* Common                                      */
-#define __NR_mprotect            74 /* Common                                      */
-#define __NR_madvise             75 /* Common                                      */
-#define __NR_vhangup             76 /* Common                                      */
-#define __NR_truncate64                 77 /* Linux sparc32 Specific                      */
-#define __NR_mincore             78 /* Common                                      */
-#define __NR_getgroups           79 /* Common                                      */
-#define __NR_setgroups           80 /* Common                                      */
-#define __NR_getpgrp             81 /* Common                                      */
-#define __NR_setgroups32         82 /* Linux sparc32, setpgrp under SunOS          */
-#define __NR_setitimer           83 /* Common                                      */
-#define __NR_ftruncate64        84 /* Linux sparc32 Specific                      */
-#define __NR_swapon              85 /* Common                                      */
-#define __NR_getitimer           86 /* Common                                      */
-#define __NR_setuid32            87 /* Linux sparc32, gethostname under SunOS      */
-#define __NR_sethostname         88 /* Common                                      */
-#define __NR_setgid32            89 /* Linux sparc32, getdtablesize under SunOS    */
-#define __NR_dup2                90 /* Common                                      */
-#define __NR_setfsuid32          91 /* Linux sparc32, getdopt under SunOS          */
-#define __NR_fcntl               92 /* Common                                      */
-#define __NR_select              93 /* Common                                      */
-#define __NR_setfsgid32          94 /* Linux sparc32, setdopt under SunOS          */
-#define __NR_fsync               95 /* Common                                      */
-#define __NR_setpriority         96 /* Common                                      */
-#define __NR_socket              97 /* Common                                      */
-#define __NR_connect             98 /* Common                                      */
-#define __NR_accept              99 /* Common                                      */
-#define __NR_getpriority        100 /* Common                                      */
-#define __NR_rt_sigreturn       101 /* Linux Specific                              */
-#define __NR_rt_sigaction       102 /* Linux Specific                              */
-#define __NR_rt_sigprocmask     103 /* Linux Specific                              */
-#define __NR_rt_sigpending      104 /* Linux Specific                              */
-#define __NR_rt_sigtimedwait    105 /* Linux Specific                              */
-#define __NR_rt_sigqueueinfo    106 /* Linux Specific                              */
-#define __NR_rt_sigsuspend      107 /* Linux Specific                              */
-#define __NR_setresuid32        108 /* Linux Specific, sigvec under SunOS         */
-#define __NR_getresuid32        109 /* Linux Specific, sigblock under SunOS       */
-#define __NR_setresgid32        110 /* Linux Specific, sigsetmask under SunOS     */
-#define __NR_getresgid32        111 /* Linux Specific, sigpause under SunOS       */
-#define __NR_setregid32         112 /* Linux sparc32, sigstack under SunOS         */
-#define __NR_recvmsg            113 /* Common                                      */
-#define __NR_sendmsg            114 /* Common                                      */
-#define __NR_getgroups32        115 /* Linux sparc32, vtrace under SunOS           */
-#define __NR_gettimeofday       116 /* Common                                      */
-#define __NR_getrusage          117 /* Common                                      */
-#define __NR_getsockopt         118 /* Common                                      */
-#define __NR_getcwd            119 /* Linux Specific                              */
-#define __NR_readv              120 /* Common                                      */
-#define __NR_writev             121 /* Common                                      */
-#define __NR_settimeofday       122 /* Common                                      */
-#define __NR_fchown             123 /* Common                                      */
-#define __NR_fchmod             124 /* Common                                      */
-#define __NR_recvfrom           125 /* Common                                      */
-#define __NR_setreuid           126 /* Common                                      */
-#define __NR_setregid           127 /* Common                                      */
-#define __NR_rename             128 /* Common                                      */
-#define __NR_truncate           129 /* Common                                      */
-#define __NR_ftruncate          130 /* Common                                      */
-#define __NR_flock              131 /* Common                                      */
-#define __NR_lstat64           132 /* Linux Specific                              */
-#define __NR_sendto             133 /* Common                                      */
-#define __NR_shutdown           134 /* Common                                      */
-#define __NR_socketpair         135 /* Common                                      */
-#define __NR_mkdir              136 /* Common                                      */
-#define __NR_rmdir              137 /* Common                                      */
-#define __NR_utimes             138 /* SunOS Specific                              */
-#define __NR_stat64            139 /* Linux Specific                              */
-#define __NR_sendfile64         140 /* adjtime under SunOS                         */
-#define __NR_getpeername        141 /* Common                                      */
-#define __NR_futex              142 /* gethostid under SunOS                       */
-#define __NR_gettid             143 /* ENOSYS under SunOS                          */
-#define __NR_getrlimit          144 /* Common                                      */
-#define __NR_setrlimit          145 /* Common                                      */
-#define __NR_pivot_root                146 /* Linux Specific, killpg under SunOS          */
-#define __NR_prctl             147 /* ENOSYS under SunOS                          */
-#define __NR_pciconfig_read    148 /* ENOSYS under SunOS                          */
-#define __NR_pciconfig_write   149 /* ENOSYS under SunOS                          */
-#define __NR_getsockname        150 /* Common                                      */
-#define __NR_inotify_init       151 /* Linux specific                              */
-#define __NR_inotify_add_watch  152 /* Linux specific                              */
-#define __NR_poll               153 /* Common                                      */
-#define __NR_getdents64                154 /* Linux specific                              */
-#define __NR_fcntl64           155 /* Linux sparc32 Specific                      */
-#define __NR_inotify_rm_watch   156 /* Linux specific                             */
-#define __NR_statfs             157 /* Common                                      */
-#define __NR_fstatfs            158 /* Common                                      */
-#define __NR_umount             159 /* Common                                      */
-#define __NR_sched_set_affinity 160 /* Linux specific, async_daemon under SunOS    */
-#define __NR_sched_get_affinity 161 /* Linux specific, getfh under SunOS           */
-#define __NR_getdomainname      162 /* SunOS Specific                              */
-#define __NR_setdomainname      163 /* Common                                      */
-/* #define __NR_utrap_install   164    Linux sparc64 specific                     */
-#define __NR_quotactl           165 /* Common                                      */
-#define __NR_set_tid_address    166 /* Linux specific, exportfs under SunOS        */
-#define __NR_mount              167 /* Common                                      */
-#define __NR_ustat              168 /* Common                                      */
-#define __NR_setxattr           169 /* SunOS: semsys                               */
-#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
-#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
-#define __NR_getxattr           172 /* SunOS: auditsys                             */
-#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
-#define __NR_getdents           174 /* Common                                      */
-#define __NR_setsid             175 /* Common                                      */
-#define __NR_fchdir             176 /* Common                                      */
-#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
-#define __NR_listxattr          178 /* SunOS: vpixsys                              */
-#define __NR_llistxattr         179 /* SunOS: aioread                              */
-#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
-#define __NR_removexattr        181 /* SunOS: aiowait                              */
-#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
-#define __NR_sigpending         183 /* Common                                      */
-#define __NR_query_module      184 /* Linux Specific                              */
-#define __NR_setpgid            185 /* Common                                      */
-#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
-#define __NR_tkill              187 /* SunOS: fpathconf                            */
-#define __NR_exit_group                188 /* Linux specific, sysconf undef SunOS         */
-#define __NR_uname              189 /* Linux Specific                              */
-#define __NR_init_module        190 /* Linux Specific                              */
-#define __NR_personality        191 /* Linux Specific                              */
-#define __NR_remap_file_pages   192 /* Linux Specific                              */
-#define __NR_epoll_create       193 /* Linux Specific                              */
-#define __NR_epoll_ctl          194 /* Linux Specific                              */
-#define __NR_epoll_wait         195 /* Linux Specific                              */
-#define __NR_ioprio_set         196 /* Linux Specific                              */
-#define __NR_getppid            197 /* Linux Specific                              */
-#define __NR_sigaction          198 /* Linux Specific                              */
-#define __NR_sgetmask           199 /* Linux Specific                              */
-#define __NR_ssetmask           200 /* Linux Specific                              */
-#define __NR_sigsuspend         201 /* Linux Specific                              */
-#define __NR_oldlstat           202 /* Linux Specific                              */
-#define __NR_uselib             203 /* Linux Specific                              */
-#define __NR_readdir            204 /* Linux Specific                              */
-#define __NR_readahead          205 /* Linux Specific                              */
-#define __NR_socketcall         206 /* Linux Specific                              */
-#define __NR_syslog             207 /* Linux Specific                              */
-#define __NR_lookup_dcookie     208 /* Linux Specific                              */
-#define __NR_fadvise64          209 /* Linux Specific                              */
-#define __NR_fadvise64_64       210 /* Linux Specific                              */
-#define __NR_tgkill             211 /* Linux Specific                              */
-#define __NR_waitpid            212 /* Linux Specific                              */
-#define __NR_swapoff            213 /* Linux Specific                              */
-#define __NR_sysinfo            214 /* Linux Specific                              */
-#define __NR_ipc                215 /* Linux Specific                              */
-#define __NR_sigreturn          216 /* Linux Specific                              */
-#define __NR_clone              217 /* Linux Specific                              */
-#define __NR_ioprio_get         218 /* Linux Specific                              */
-#define __NR_adjtimex           219 /* Linux Specific                              */
-#define __NR_sigprocmask        220 /* Linux Specific                              */
-#define __NR_create_module      221 /* Linux Specific                              */
-#define __NR_delete_module      222 /* Linux Specific                              */
-#define __NR_get_kernel_syms    223 /* Linux Specific                              */
-#define __NR_getpgid            224 /* Linux Specific                              */
-#define __NR_bdflush            225 /* Linux Specific                              */
-#define __NR_sysfs              226 /* Linux Specific                              */
-#define __NR_afs_syscall        227 /* Linux Specific                              */
-#define __NR_setfsuid           228 /* Linux Specific                              */
-#define __NR_setfsgid           229 /* Linux Specific                              */
-#define __NR__newselect         230 /* Linux Specific                              */
-#define __NR_time               231 /* Linux Specific                              */
-#define __NR_splice             232 /* Linux Specific                              */
-#define __NR_stime              233 /* Linux Specific                              */
-#define __NR_statfs64           234 /* Linux Specific                              */
-#define __NR_fstatfs64          235 /* Linux Specific                              */
-#define __NR__llseek            236 /* Linux Specific                              */
-#define __NR_mlock              237
-#define __NR_munlock            238
-#define __NR_mlockall           239
-#define __NR_munlockall         240
-#define __NR_sched_setparam     241
-#define __NR_sched_getparam     242
-#define __NR_sched_setscheduler 243
-#define __NR_sched_getscheduler 244
-#define __NR_sched_yield        245
-#define __NR_sched_get_priority_max 246
-#define __NR_sched_get_priority_min 247
-#define __NR_sched_rr_get_interval  248
-#define __NR_nanosleep          249
-#define __NR_mremap             250
-#define __NR__sysctl            251
-#define __NR_getsid             252
-#define __NR_fdatasync          253
-#define __NR_nfsservctl         254
-#define __NR_sync_file_range   255
-#define __NR_clock_settime     256
-#define __NR_clock_gettime     257
-#define __NR_clock_getres      258
-#define __NR_clock_nanosleep   259
-#define __NR_sched_getaffinity 260
-#define __NR_sched_setaffinity 261
-#define __NR_timer_settime     262
-#define __NR_timer_gettime     263
-#define __NR_timer_getoverrun  264
-#define __NR_timer_delete      265
-#define __NR_timer_create      266
-/* #define __NR_vserver                267 Reserved for VSERVER */
-#define __NR_io_setup          268
-#define __NR_io_destroy                269
-#define __NR_io_submit         270
-#define __NR_io_cancel         271
-#define __NR_io_getevents      272
-#define __NR_mq_open           273
-#define __NR_mq_unlink         274
-#define __NR_mq_timedsend      275
-#define __NR_mq_timedreceive   276
-#define __NR_mq_notify         277
-#define __NR_mq_getsetattr     278
-#define __NR_waitid            279
-#define __NR_tee               280
-#define __NR_add_key           281
-#define __NR_request_key       282
-#define __NR_keyctl            283
-#define __NR_openat            284
-#define __NR_mkdirat           285
-#define __NR_mknodat           286
-#define __NR_fchownat          287
-#define __NR_futimesat         288
-#define __NR_fstatat64         289
-#define __NR_unlinkat          290
-#define __NR_renameat          291
-#define __NR_linkat            292
-#define __NR_symlinkat         293
-#define __NR_readlinkat                294
-#define __NR_fchmodat          295
-#define __NR_faccessat         296
-#define __NR_pselect6          297
-#define __NR_ppoll             298
-#define __NR_unshare           299
-#define __NR_set_robust_list   300
-#define __NR_get_robust_list   301
-#define __NR_migrate_pages     302
-#define __NR_mbind             303
-#define __NR_get_mempolicy     304
-#define __NR_set_mempolicy     305
-#define __NR_kexec_load                306
-#define __NR_move_pages                307
-#define __NR_getcpu            308
-#define __NR_epoll_pwait       309
-#define __NR_utimensat         310
-#define __NR_signalfd          311
-#define __NR_timerfd_create    312
-#define __NR_eventfd           313
-#define __NR_fallocate         314
-#define __NR_timerfd_settime   315
-#define __NR_timerfd_gettime   316
-
-#define NR_SYSCALLS            317
-
-/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
- * it never had the plain ones and there is no value to adding those
- * old versions into the syscall table.
- */
-#define __IGNORE_setresuid
-#define __IGNORE_getresuid
-#define __IGNORE_setresgid
-#define __IGNORE_getresgid
-
-#ifdef __KERNEL__
-#define __ARCH_WANT_IPC_PARSE_VERSION
-#define __ARCH_WANT_OLD_READDIR
-#define __ARCH_WANT_STAT64
-#define __ARCH_WANT_SYS_ALARM
-#define __ARCH_WANT_SYS_GETHOSTNAME
-#define __ARCH_WANT_SYS_PAUSE
-#define __ARCH_WANT_SYS_SGETMASK
-#define __ARCH_WANT_SYS_SIGNAL
-#define __ARCH_WANT_SYS_TIME
-#define __ARCH_WANT_SYS_UTIME
-#define __ARCH_WANT_SYS_WAITPID
-#define __ARCH_WANT_SYS_SOCKETCALL
-#define __ARCH_WANT_SYS_FADVISE64
-#define __ARCH_WANT_SYS_GETPGRP
-#define __ARCH_WANT_SYS_LLSEEK
-#define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_OLDUMOUNT
-#define __ARCH_WANT_SYS_SIGPENDING
-#define __ARCH_WANT_SYS_SIGPROCMASK
-#define __ARCH_WANT_SYS_RT_SIGSUSPEND
-
-/*
- * "Conditional" syscalls
- *
- * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
- * but it doesn't work on all toolchains, so we just do it by hand
- */
-#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
-
-#endif /* __KERNEL__ */
-#endif /* _SPARC_UNISTD_H */
+#ifndef ___ASM_SPARC_UNISTD_H
+#define ___ASM_SPARC_UNISTD_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/unistd_64.h>
+#else
+#include <asm-sparc/unistd_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/unistd_32.h b/include/asm-sparc/unistd_32.h
new file mode 100644 (file)
index 0000000..2338a02
--- /dev/null
@@ -0,0 +1,378 @@
+#ifndef _SPARC_UNISTD_H
+#define _SPARC_UNISTD_H
+
+/*
+ * System calls under the Sparc.
+ *
+ * Don't be scared by the ugly clobbers, it is the only way I can
+ * think of right now to force the arguments into fixed registers
+ * before the trap into the system call with gcc 'asm' statements.
+ *
+ * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
+ *
+ * SunOS compatibility based upon preliminary work which is:
+ *
+ * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
+ */
+
+#define __NR_restart_syscall      0 /* Linux Specific                             */
+#define __NR_exit                 1 /* Common                                      */
+#define __NR_fork                 2 /* Common                                      */
+#define __NR_read                 3 /* Common                                      */
+#define __NR_write                4 /* Common                                      */
+#define __NR_open                 5 /* Common                                      */
+#define __NR_close                6 /* Common                                      */
+#define __NR_wait4                7 /* Common                                      */
+#define __NR_creat                8 /* Common                                      */
+#define __NR_link                 9 /* Common                                      */
+#define __NR_unlink              10 /* Common                                      */
+#define __NR_execv               11 /* SunOS Specific                              */
+#define __NR_chdir               12 /* Common                                      */
+#define __NR_chown              13 /* Common                                      */
+#define __NR_mknod               14 /* Common                                      */
+#define __NR_chmod               15 /* Common                                      */
+#define __NR_lchown              16 /* Common                                      */
+#define __NR_brk                 17 /* Common                                      */
+#define __NR_perfctr             18 /* Performance counter operations              */
+#define __NR_lseek               19 /* Common                                      */
+#define __NR_getpid              20 /* Common                                      */
+#define __NR_capget             21 /* Linux Specific                              */
+#define __NR_capset             22 /* Linux Specific                              */
+#define __NR_setuid              23 /* Implemented via setreuid in SunOS           */
+#define __NR_getuid              24 /* Common                                      */
+#define __NR_vmsplice           25 /* ENOSYS under SunOS                          */
+#define __NR_ptrace              26 /* Common                                      */
+#define __NR_alarm               27 /* Implemented via setitimer in SunOS          */
+#define __NR_sigaltstack        28 /* Common                                      */
+#define __NR_pause               29 /* Is sigblock(0)->sigpause() in SunOS         */
+#define __NR_utime               30 /* Implemented via utimes() under SunOS        */
+#define __NR_lchown32            31 /* Linux sparc32 specific                      */
+#define __NR_fchown32            32 /* Linux sparc32 specific                      */
+#define __NR_access              33 /* Common                                      */
+#define __NR_nice                34 /* Implemented via get/setpriority() in SunOS  */
+#define __NR_chown32             35 /* Linux sparc32 specific                      */
+#define __NR_sync                36 /* Common                                      */
+#define __NR_kill                37 /* Common                                      */
+#define __NR_stat                38 /* Common                                      */
+#define __NR_sendfile           39 /* Linux Specific                              */
+#define __NR_lstat               40 /* Common                                      */
+#define __NR_dup                 41 /* Common                                      */
+#define __NR_pipe                42 /* Common                                      */
+#define __NR_times               43 /* Implemented via getrusage() in SunOS        */
+#define __NR_getuid32            44 /* Linux sparc32 specific                      */
+#define __NR_umount2             45 /* Linux Specific                              */
+#define __NR_setgid              46 /* Implemented via setregid() in SunOS         */
+#define __NR_getgid              47 /* Common                                      */
+#define __NR_signal              48 /* Implemented via sigvec() in SunOS           */
+#define __NR_geteuid             49 /* SunOS calls getuid()                        */
+#define __NR_getegid             50 /* SunOS calls getgid()                        */
+#define __NR_acct                51 /* Common                                      */
+/* #define __NR_memory_ordering  52    Linux sparc64 specific                     */
+#define __NR_getgid32            53 /* Linux sparc32 specific                      */
+#define __NR_ioctl               54 /* Common                                      */
+#define __NR_reboot              55 /* Common                                      */
+#define __NR_mmap2              56 /* Linux sparc32 Specific                      */
+#define __NR_symlink             57 /* Common                                      */
+#define __NR_readlink            58 /* Common                                      */
+#define __NR_execve              59 /* Common                                      */
+#define __NR_umask               60 /* Common                                      */
+#define __NR_chroot              61 /* Common                                      */
+#define __NR_fstat               62 /* Common                                      */
+#define __NR_fstat64            63 /* Linux Specific                              */
+#define __NR_getpagesize         64 /* Common                                      */
+#define __NR_msync               65 /* Common in newer 1.3.x revs...               */
+#define __NR_vfork               66 /* Common                                      */
+#define __NR_pread64             67 /* Linux Specific                              */
+#define __NR_pwrite64            68 /* Linux Specific                              */
+#define __NR_geteuid32           69 /* Linux sparc32, sbrk under SunOS             */
+#define __NR_getegid32           70 /* Linux sparc32, sstk under SunOS             */
+#define __NR_mmap                71 /* Common                                      */
+#define __NR_setreuid32          72 /* Linux sparc32, vadvise under SunOS          */
+#define __NR_munmap              73 /* Common                                      */
+#define __NR_mprotect            74 /* Common                                      */
+#define __NR_madvise             75 /* Common                                      */
+#define __NR_vhangup             76 /* Common                                      */
+#define __NR_truncate64                 77 /* Linux sparc32 Specific                      */
+#define __NR_mincore             78 /* Common                                      */
+#define __NR_getgroups           79 /* Common                                      */
+#define __NR_setgroups           80 /* Common                                      */
+#define __NR_getpgrp             81 /* Common                                      */
+#define __NR_setgroups32         82 /* Linux sparc32, setpgrp under SunOS          */
+#define __NR_setitimer           83 /* Common                                      */
+#define __NR_ftruncate64        84 /* Linux sparc32 Specific                      */
+#define __NR_swapon              85 /* Common                                      */
+#define __NR_getitimer           86 /* Common                                      */
+#define __NR_setuid32            87 /* Linux sparc32, gethostname under SunOS      */
+#define __NR_sethostname         88 /* Common                                      */
+#define __NR_setgid32            89 /* Linux sparc32, getdtablesize under SunOS    */
+#define __NR_dup2                90 /* Common                                      */
+#define __NR_setfsuid32          91 /* Linux sparc32, getdopt under SunOS          */
+#define __NR_fcntl               92 /* Common                                      */
+#define __NR_select              93 /* Common                                      */
+#define __NR_setfsgid32          94 /* Linux sparc32, setdopt under SunOS          */
+#define __NR_fsync               95 /* Common                                      */
+#define __NR_setpriority         96 /* Common                                      */
+#define __NR_socket              97 /* Common                                      */
+#define __NR_connect             98 /* Common                                      */
+#define __NR_accept              99 /* Common                                      */
+#define __NR_getpriority        100 /* Common                                      */
+#define __NR_rt_sigreturn       101 /* Linux Specific                              */
+#define __NR_rt_sigaction       102 /* Linux Specific                              */
+#define __NR_rt_sigprocmask     103 /* Linux Specific                              */
+#define __NR_rt_sigpending      104 /* Linux Specific                              */
+#define __NR_rt_sigtimedwait    105 /* Linux Specific                              */
+#define __NR_rt_sigqueueinfo    106 /* Linux Specific                              */
+#define __NR_rt_sigsuspend      107 /* Linux Specific                              */
+#define __NR_setresuid32        108 /* Linux Specific, sigvec under SunOS         */
+#define __NR_getresuid32        109 /* Linux Specific, sigblock under SunOS       */
+#define __NR_setresgid32        110 /* Linux Specific, sigsetmask under SunOS     */
+#define __NR_getresgid32        111 /* Linux Specific, sigpause under SunOS       */
+#define __NR_setregid32         112 /* Linux sparc32, sigstack under SunOS         */
+#define __NR_recvmsg            113 /* Common                                      */
+#define __NR_sendmsg            114 /* Common                                      */
+#define __NR_getgroups32        115 /* Linux sparc32, vtrace under SunOS           */
+#define __NR_gettimeofday       116 /* Common                                      */
+#define __NR_getrusage          117 /* Common                                      */
+#define __NR_getsockopt         118 /* Common                                      */
+#define __NR_getcwd            119 /* Linux Specific                              */
+#define __NR_readv              120 /* Common                                      */
+#define __NR_writev             121 /* Common                                      */
+#define __NR_settimeofday       122 /* Common                                      */
+#define __NR_fchown             123 /* Common                                      */
+#define __NR_fchmod             124 /* Common                                      */
+#define __NR_recvfrom           125 /* Common                                      */
+#define __NR_setreuid           126 /* Common                                      */
+#define __NR_setregid           127 /* Common                                      */
+#define __NR_rename             128 /* Common                                      */
+#define __NR_truncate           129 /* Common                                      */
+#define __NR_ftruncate          130 /* Common                                      */
+#define __NR_flock              131 /* Common                                      */
+#define __NR_lstat64           132 /* Linux Specific                              */
+#define __NR_sendto             133 /* Common                                      */
+#define __NR_shutdown           134 /* Common                                      */
+#define __NR_socketpair         135 /* Common                                      */
+#define __NR_mkdir              136 /* Common                                      */
+#define __NR_rmdir              137 /* Common                                      */
+#define __NR_utimes             138 /* SunOS Specific                              */
+#define __NR_stat64            139 /* Linux Specific                              */
+#define __NR_sendfile64         140 /* adjtime under SunOS                         */
+#define __NR_getpeername        141 /* Common                                      */
+#define __NR_futex              142 /* gethostid under SunOS                       */
+#define __NR_gettid             143 /* ENOSYS under SunOS                          */
+#define __NR_getrlimit          144 /* Common                                      */
+#define __NR_setrlimit          145 /* Common                                      */
+#define __NR_pivot_root                146 /* Linux Specific, killpg under SunOS          */
+#define __NR_prctl             147 /* ENOSYS under SunOS                          */
+#define __NR_pciconfig_read    148 /* ENOSYS under SunOS                          */
+#define __NR_pciconfig_write   149 /* ENOSYS under SunOS                          */
+#define __NR_getsockname        150 /* Common                                      */
+#define __NR_inotify_init       151 /* Linux specific                              */
+#define __NR_inotify_add_watch  152 /* Linux specific                              */
+#define __NR_poll               153 /* Common                                      */
+#define __NR_getdents64                154 /* Linux specific                              */
+#define __NR_fcntl64           155 /* Linux sparc32 Specific                      */
+#define __NR_inotify_rm_watch   156 /* Linux specific                             */
+#define __NR_statfs             157 /* Common                                      */
+#define __NR_fstatfs            158 /* Common                                      */
+#define __NR_umount             159 /* Common                                      */
+#define __NR_sched_set_affinity 160 /* Linux specific, async_daemon under SunOS    */
+#define __NR_sched_get_affinity 161 /* Linux specific, getfh under SunOS           */
+#define __NR_getdomainname      162 /* SunOS Specific                              */
+#define __NR_setdomainname      163 /* Common                                      */
+/* #define __NR_utrap_install   164    Linux sparc64 specific                     */
+#define __NR_quotactl           165 /* Common                                      */
+#define __NR_set_tid_address    166 /* Linux specific, exportfs under SunOS        */
+#define __NR_mount              167 /* Common                                      */
+#define __NR_ustat              168 /* Common                                      */
+#define __NR_setxattr           169 /* SunOS: semsys                               */
+#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
+#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
+#define __NR_getxattr           172 /* SunOS: auditsys                             */
+#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
+#define __NR_getdents           174 /* Common                                      */
+#define __NR_setsid             175 /* Common                                      */
+#define __NR_fchdir             176 /* Common                                      */
+#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
+#define __NR_listxattr          178 /* SunOS: vpixsys                              */
+#define __NR_llistxattr         179 /* SunOS: aioread                              */
+#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
+#define __NR_removexattr        181 /* SunOS: aiowait                              */
+#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
+#define __NR_sigpending         183 /* Common                                      */
+#define __NR_query_module      184 /* Linux Specific                              */
+#define __NR_setpgid            185 /* Common                                      */
+#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
+#define __NR_tkill              187 /* SunOS: fpathconf                            */
+#define __NR_exit_group                188 /* Linux specific, sysconf undef SunOS         */
+#define __NR_uname              189 /* Linux Specific                              */
+#define __NR_init_module        190 /* Linux Specific                              */
+#define __NR_personality        191 /* Linux Specific                              */
+#define __NR_remap_file_pages   192 /* Linux Specific                              */
+#define __NR_epoll_create       193 /* Linux Specific                              */
+#define __NR_epoll_ctl          194 /* Linux Specific                              */
+#define __NR_epoll_wait         195 /* Linux Specific                              */
+#define __NR_ioprio_set         196 /* Linux Specific                              */
+#define __NR_getppid            197 /* Linux Specific                              */
+#define __NR_sigaction          198 /* Linux Specific                              */
+#define __NR_sgetmask           199 /* Linux Specific                              */
+#define __NR_ssetmask           200 /* Linux Specific                              */
+#define __NR_sigsuspend         201 /* Linux Specific                              */
+#define __NR_oldlstat           202 /* Linux Specific                              */
+#define __NR_uselib             203 /* Linux Specific                              */
+#define __NR_readdir            204 /* Linux Specific                              */
+#define __NR_readahead          205 /* Linux Specific                              */
+#define __NR_socketcall         206 /* Linux Specific                              */
+#define __NR_syslog             207 /* Linux Specific                              */
+#define __NR_lookup_dcookie     208 /* Linux Specific                              */
+#define __NR_fadvise64          209 /* Linux Specific                              */
+#define __NR_fadvise64_64       210 /* Linux Specific                              */
+#define __NR_tgkill             211 /* Linux Specific                              */
+#define __NR_waitpid            212 /* Linux Specific                              */
+#define __NR_swapoff            213 /* Linux Specific                              */
+#define __NR_sysinfo            214 /* Linux Specific                              */
+#define __NR_ipc                215 /* Linux Specific                              */
+#define __NR_sigreturn          216 /* Linux Specific                              */
+#define __NR_clone              217 /* Linux Specific                              */
+#define __NR_ioprio_get         218 /* Linux Specific                              */
+#define __NR_adjtimex           219 /* Linux Specific                              */
+#define __NR_sigprocmask        220 /* Linux Specific                              */
+#define __NR_create_module      221 /* Linux Specific                              */
+#define __NR_delete_module      222 /* Linux Specific                              */
+#define __NR_get_kernel_syms    223 /* Linux Specific                              */
+#define __NR_getpgid            224 /* Linux Specific                              */
+#define __NR_bdflush            225 /* Linux Specific                              */
+#define __NR_sysfs              226 /* Linux Specific                              */
+#define __NR_afs_syscall        227 /* Linux Specific                              */
+#define __NR_setfsuid           228 /* Linux Specific                              */
+#define __NR_setfsgid           229 /* Linux Specific                              */
+#define __NR__newselect         230 /* Linux Specific                              */
+#define __NR_time               231 /* Linux Specific                              */
+#define __NR_splice             232 /* Linux Specific                              */
+#define __NR_stime              233 /* Linux Specific                              */
+#define __NR_statfs64           234 /* Linux Specific                              */
+#define __NR_fstatfs64          235 /* Linux Specific                              */
+#define __NR__llseek            236 /* Linux Specific                              */
+#define __NR_mlock              237
+#define __NR_munlock            238
+#define __NR_mlockall           239
+#define __NR_munlockall         240
+#define __NR_sched_setparam     241
+#define __NR_sched_getparam     242
+#define __NR_sched_setscheduler 243
+#define __NR_sched_getscheduler 244
+#define __NR_sched_yield        245
+#define __NR_sched_get_priority_max 246
+#define __NR_sched_get_priority_min 247
+#define __NR_sched_rr_get_interval  248
+#define __NR_nanosleep          249
+#define __NR_mremap             250
+#define __NR__sysctl            251
+#define __NR_getsid             252
+#define __NR_fdatasync          253
+#define __NR_nfsservctl         254
+#define __NR_sync_file_range   255
+#define __NR_clock_settime     256
+#define __NR_clock_gettime     257
+#define __NR_clock_getres      258
+#define __NR_clock_nanosleep   259
+#define __NR_sched_getaffinity 260
+#define __NR_sched_setaffinity 261
+#define __NR_timer_settime     262
+#define __NR_timer_gettime     263
+#define __NR_timer_getoverrun  264
+#define __NR_timer_delete      265
+#define __NR_timer_create      266
+/* #define __NR_vserver                267 Reserved for VSERVER */
+#define __NR_io_setup          268
+#define __NR_io_destroy                269
+#define __NR_io_submit         270
+#define __NR_io_cancel         271
+#define __NR_io_getevents      272
+#define __NR_mq_open           273
+#define __NR_mq_unlink         274
+#define __NR_mq_timedsend      275
+#define __NR_mq_timedreceive   276
+#define __NR_mq_notify         277
+#define __NR_mq_getsetattr     278
+#define __NR_waitid            279
+#define __NR_tee               280
+#define __NR_add_key           281
+#define __NR_request_key       282
+#define __NR_keyctl            283
+#define __NR_openat            284
+#define __NR_mkdirat           285
+#define __NR_mknodat           286
+#define __NR_fchownat          287
+#define __NR_futimesat         288
+#define __NR_fstatat64         289
+#define __NR_unlinkat          290
+#define __NR_renameat          291
+#define __NR_linkat            292
+#define __NR_symlinkat         293
+#define __NR_readlinkat                294
+#define __NR_fchmodat          295
+#define __NR_faccessat         296
+#define __NR_pselect6          297
+#define __NR_ppoll             298
+#define __NR_unshare           299
+#define __NR_set_robust_list   300
+#define __NR_get_robust_list   301
+#define __NR_migrate_pages     302
+#define __NR_mbind             303
+#define __NR_get_mempolicy     304
+#define __NR_set_mempolicy     305
+#define __NR_kexec_load                306
+#define __NR_move_pages                307
+#define __NR_getcpu            308
+#define __NR_epoll_pwait       309
+#define __NR_utimensat         310
+#define __NR_signalfd          311
+#define __NR_timerfd_create    312
+#define __NR_eventfd           313
+#define __NR_fallocate         314
+#define __NR_timerfd_settime   315
+#define __NR_timerfd_gettime   316
+
+#define NR_SYSCALLS            317
+
+/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
+ * it never had the plain ones and there is no value to adding those
+ * old versions into the syscall table.
+ */
+#define __IGNORE_setresuid
+#define __IGNORE_getresuid
+#define __IGNORE_setresgid
+#define __IGNORE_getresgid
+
+#ifdef __KERNEL__
+#define __ARCH_WANT_IPC_PARSE_VERSION
+#define __ARCH_WANT_OLD_READDIR
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_SGETMASK
+#define __ARCH_WANT_SYS_SIGNAL
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
+
+#endif /* __KERNEL__ */
+#endif /* _SPARC_UNISTD_H */
diff --git a/include/asm-sparc/unistd_64.h b/include/asm-sparc/unistd_64.h
new file mode 100644 (file)
index 0000000..13be445
--- /dev/null
@@ -0,0 +1,373 @@
+#ifndef _SPARC64_UNISTD_H
+#define _SPARC64_UNISTD_H
+
+/*
+ * System calls under the Sparc.
+ *
+ * Don't be scared by the ugly clobbers, it is the only way I can
+ * think of right now to force the arguments into fixed registers
+ * before the trap into the system call with gcc 'asm' statements.
+ *
+ * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
+ *
+ * SunOS compatibility based upon preliminary work which is:
+ *
+ * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
+ */
+
+#define __NR_restart_syscall      0 /* Linux Specific                             */
+#define __NR_exit                 1 /* Common                                      */
+#define __NR_fork                 2 /* Common                                      */
+#define __NR_read                 3 /* Common                                      */
+#define __NR_write                4 /* Common                                      */
+#define __NR_open                 5 /* Common                                      */
+#define __NR_close                6 /* Common                                      */
+#define __NR_wait4                7 /* Common                                      */
+#define __NR_creat                8 /* Common                                      */
+#define __NR_link                 9 /* Common                                      */
+#define __NR_unlink              10 /* Common                                      */
+#define __NR_execv               11 /* SunOS Specific                              */
+#define __NR_chdir               12 /* Common                                      */
+#define __NR_chown              13 /* Common                                      */
+#define __NR_mknod               14 /* Common                                      */
+#define __NR_chmod               15 /* Common                                      */
+#define __NR_lchown              16 /* Common                                      */
+#define __NR_brk                 17 /* Common                                      */
+#define __NR_perfctr             18 /* Performance counter operations              */
+#define __NR_lseek               19 /* Common                                      */
+#define __NR_getpid              20 /* Common                                      */
+#define __NR_capget             21 /* Linux Specific                              */
+#define __NR_capset             22 /* Linux Specific                              */
+#define __NR_setuid              23 /* Implemented via setreuid in SunOS           */
+#define __NR_getuid              24 /* Common                                      */
+#define __NR_vmsplice           25 /* ENOSYS under SunOS                          */
+#define __NR_ptrace              26 /* Common                                      */
+#define __NR_alarm               27 /* Implemented via setitimer in SunOS          */
+#define __NR_sigaltstack        28 /* Common                                      */
+#define __NR_pause               29 /* Is sigblock(0)->sigpause() in SunOS         */
+#define __NR_utime               30 /* Implemented via utimes() under SunOS        */
+/* #define __NR_lchown32         31    Linux sparc32 specific                      */
+/* #define __NR_fchown32         32    Linux sparc32 specific                      */
+#define __NR_access              33 /* Common                                      */
+#define __NR_nice                34 /* Implemented via get/setpriority() in SunOS  */
+/* #define __NR_chown32          35    Linux sparc32 specific                      */
+#define __NR_sync                36 /* Common                                      */
+#define __NR_kill                37 /* Common                                      */
+#define __NR_stat                38 /* Common                                      */
+#define __NR_sendfile           39 /* Linux Specific                              */
+#define __NR_lstat               40 /* Common                                      */
+#define __NR_dup                 41 /* Common                                      */
+#define __NR_pipe                42 /* Common                                      */
+#define __NR_times               43 /* Implemented via getrusage() in SunOS        */
+/* #define __NR_getuid32         44    Linux sparc32 specific                      */
+#define __NR_umount2             45 /* Linux Specific                              */
+#define __NR_setgid              46 /* Implemented via setregid() in SunOS         */
+#define __NR_getgid              47 /* Common                                      */
+#define __NR_signal              48 /* Implemented via sigvec() in SunOS           */
+#define __NR_geteuid             49 /* SunOS calls getuid()                        */
+#define __NR_getegid             50 /* SunOS calls getgid()                        */
+#define __NR_acct                51 /* Common                                      */
+#define __NR_memory_ordering    52 /* Linux Specific                              */
+/* #define __NR_getgid32         53    Linux sparc32 specific                      */
+#define __NR_ioctl               54 /* Common                                      */
+#define __NR_reboot              55 /* Common                                      */
+/* #define __NR_mmap2           56    Linux sparc32 Specific                      */
+#define __NR_symlink             57 /* Common                                      */
+#define __NR_readlink            58 /* Common                                      */
+#define __NR_execve              59 /* Common                                      */
+#define __NR_umask               60 /* Common                                      */
+#define __NR_chroot              61 /* Common                                      */
+#define __NR_fstat               62 /* Common                                      */
+#define __NR_fstat64             63 /* Linux Specific                              */
+#define __NR_getpagesize         64 /* Common                                      */
+#define __NR_msync               65 /* Common in newer 1.3.x revs...               */
+#define __NR_vfork               66 /* Common                                      */
+#define __NR_pread64             67 /* Linux Specific                              */
+#define __NR_pwrite64            68 /* Linux Specific                              */
+/* #define __NR_geteuid32        69    Linux sparc32, sbrk under SunOS             */
+/* #define __NR_getegid32        70    Linux sparc32, sstk under SunOS             */
+#define __NR_mmap                71 /* Common                                      */
+/* #define __NR_setreuid32       72    Linux sparc32, vadvise under SunOS          */
+#define __NR_munmap              73 /* Common                                      */
+#define __NR_mprotect            74 /* Common                                      */
+#define __NR_madvise             75 /* Common                                      */
+#define __NR_vhangup             76 /* Common                                      */
+/* #define __NR_truncate64       77    Linux sparc32 Specific                     */
+#define __NR_mincore             78 /* Common                                      */
+#define __NR_getgroups           79 /* Common                                      */
+#define __NR_setgroups           80 /* Common                                      */
+#define __NR_getpgrp             81 /* Common                                      */
+/* #define __NR_setgroups32      82    Linux sparc32, setpgrp under SunOS          */
+#define __NR_setitimer           83 /* Common                                      */
+/* #define __NR_ftruncate64      84    Linux sparc32 Specific                     */
+#define __NR_swapon              85 /* Common                                      */
+#define __NR_getitimer           86 /* Common                                      */
+/* #define __NR_setuid32         87    Linux sparc32, gethostname under SunOS      */
+#define __NR_sethostname         88 /* Common                                      */
+/* #define __NR_setgid32         89    Linux sparc32, getdtablesize under SunOS    */
+#define __NR_dup2                90 /* Common                                      */
+/* #define __NR_setfsuid32       91    Linux sparc32, getdopt under SunOS          */
+#define __NR_fcntl               92 /* Common                                      */
+#define __NR_select              93 /* Common                                      */
+/* #define __NR_setfsgid32       94    Linux sparc32, setdopt under SunOS          */
+#define __NR_fsync               95 /* Common                                      */
+#define __NR_setpriority         96 /* Common                                      */
+#define __NR_socket              97 /* Common                                      */
+#define __NR_connect             98 /* Common                                      */
+#define __NR_accept              99 /* Common                                      */
+#define __NR_getpriority        100 /* Common                                      */
+#define __NR_rt_sigreturn       101 /* Linux Specific                              */
+#define __NR_rt_sigaction       102 /* Linux Specific                              */
+#define __NR_rt_sigprocmask     103 /* Linux Specific                              */
+#define __NR_rt_sigpending      104 /* Linux Specific                              */
+#define __NR_rt_sigtimedwait    105 /* Linux Specific                              */
+#define __NR_rt_sigqueueinfo    106 /* Linux Specific                              */
+#define __NR_rt_sigsuspend      107 /* Linux Specific                              */
+#define __NR_setresuid          108 /* Linux Specific, sigvec under SunOS         */
+#define __NR_getresuid          109 /* Linux Specific, sigblock under SunOS       */
+#define __NR_setresgid          110 /* Linux Specific, sigsetmask under SunOS     */
+#define __NR_getresgid          111 /* Linux Specific, sigpause under SunOS       */
+/* #define __NR_setregid32       75    Linux sparc32, sigstack under SunOS         */
+#define __NR_recvmsg            113 /* Common                                      */
+#define __NR_sendmsg            114 /* Common                                      */
+/* #define __NR_getgroups32     115    Linux sparc32, vtrace under SunOS           */
+#define __NR_gettimeofday       116 /* Common                                      */
+#define __NR_getrusage          117 /* Common                                      */
+#define __NR_getsockopt         118 /* Common                                      */
+#define __NR_getcwd            119 /* Linux Specific                              */
+#define __NR_readv              120 /* Common                                      */
+#define __NR_writev             121 /* Common                                      */
+#define __NR_settimeofday       122 /* Common                                      */
+#define __NR_fchown             123 /* Common                                      */
+#define __NR_fchmod             124 /* Common                                      */
+#define __NR_recvfrom           125 /* Common                                      */
+#define __NR_setreuid           126 /* Common                                      */
+#define __NR_setregid           127 /* Common                                      */
+#define __NR_rename             128 /* Common                                      */
+#define __NR_truncate           129 /* Common                                      */
+#define __NR_ftruncate          130 /* Common                                      */
+#define __NR_flock              131 /* Common                                      */
+#define __NR_lstat64           132 /* Linux Specific                              */
+#define __NR_sendto             133 /* Common                                      */
+#define __NR_shutdown           134 /* Common                                      */
+#define __NR_socketpair         135 /* Common                                      */
+#define __NR_mkdir              136 /* Common                                      */
+#define __NR_rmdir              137 /* Common                                      */
+#define __NR_utimes             138 /* SunOS Specific                              */
+#define __NR_stat64            139 /* Linux Specific                              */
+#define __NR_sendfile64         140 /* adjtime under SunOS                         */
+#define __NR_getpeername        141 /* Common                                      */
+#define __NR_futex              142 /* gethostid under SunOS                       */
+#define __NR_gettid             143 /* ENOSYS under SunOS                          */
+#define __NR_getrlimit         144 /* Common                                      */
+#define __NR_setrlimit          145 /* Common                                      */
+#define __NR_pivot_root                146 /* Linux Specific, killpg under SunOS          */
+#define __NR_prctl             147 /* ENOSYS under SunOS                          */
+#define __NR_pciconfig_read    148 /* ENOSYS under SunOS                          */
+#define __NR_pciconfig_write   149 /* ENOSYS under SunOS                          */
+#define __NR_getsockname        150 /* Common                                      */
+#define __NR_inotify_init       151 /* Linux specific                              */
+#define __NR_inotify_add_watch  152 /* Linux specific                              */
+#define __NR_poll               153 /* Common                                      */
+#define __NR_getdents64                154 /* Linux specific                              */
+/* #define __NR_fcntl64         155    Linux sparc32 Specific                      */
+#define __NR_inotify_rm_watch   156 /* Linux specific                             */
+#define __NR_statfs             157 /* Common                                      */
+#define __NR_fstatfs            158 /* Common                                      */
+#define __NR_umount             159 /* Common                                      */
+#define __NR_sched_set_affinity 160 /* Linux specific, async_daemon under SunOS    */
+#define __NR_sched_get_affinity 161 /* Linux specific, getfh under SunOS           */
+#define __NR_getdomainname      162 /* SunOS Specific                              */
+#define __NR_setdomainname      163 /* Common                                      */
+#define __NR_utrap_install     164 /* SYSV ABI/v9 required                        */
+#define __NR_quotactl           165 /* Common                                      */
+#define __NR_set_tid_address    166 /* Linux specific, exportfs under SunOS        */
+#define __NR_mount              167 /* Common                                      */
+#define __NR_ustat              168 /* Common                                      */
+#define __NR_setxattr           169 /* SunOS: semsys                               */
+#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
+#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
+#define __NR_getxattr           172 /* SunOS: auditsys                             */
+#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
+#define __NR_getdents           174 /* Common                                      */
+#define __NR_setsid             175 /* Common                                      */
+#define __NR_fchdir             176 /* Common                                      */
+#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
+#define __NR_listxattr          178 /* SunOS: vpixsys                              */
+#define __NR_llistxattr         179 /* SunOS: aioread                              */
+#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
+#define __NR_removexattr        181 /* SunOS: aiowait                              */
+#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
+#define __NR_sigpending         183 /* Common                                      */
+#define __NR_query_module      184 /* Linux Specific                              */
+#define __NR_setpgid            185 /* Common                                      */
+#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
+#define __NR_tkill              187 /* SunOS: fpathconf                            */
+#define __NR_exit_group                188 /* Linux specific, sysconf undef SunOS         */
+#define __NR_uname              189 /* Linux Specific                              */
+#define __NR_init_module        190 /* Linux Specific                              */
+#define __NR_personality        191 /* Linux Specific                              */
+#define __NR_remap_file_pages   192 /* Linux Specific                              */
+#define __NR_epoll_create       193 /* Linux Specific                              */
+#define __NR_epoll_ctl          194 /* Linux Specific                              */
+#define __NR_epoll_wait         195 /* Linux Specific                              */
+#define __NR_ioprio_set         196 /* Linux Specific                              */
+#define __NR_getppid            197 /* Linux Specific                              */
+#define __NR_sigaction          198 /* Linux Specific                              */
+#define __NR_sgetmask           199 /* Linux Specific                              */
+#define __NR_ssetmask           200 /* Linux Specific                              */
+#define __NR_sigsuspend         201 /* Linux Specific                              */
+#define __NR_oldlstat           202 /* Linux Specific                              */
+#define __NR_uselib             203 /* Linux Specific                              */
+#define __NR_readdir            204 /* Linux Specific                              */
+#define __NR_readahead          205 /* Linux Specific                              */
+#define __NR_socketcall         206 /* Linux Specific                              */
+#define __NR_syslog             207 /* Linux Specific                              */
+#define __NR_lookup_dcookie     208 /* Linux Specific                              */
+#define __NR_fadvise64          209 /* Linux Specific                              */
+#define __NR_fadvise64_64       210 /* Linux Specific                              */
+#define __NR_tgkill             211 /* Linux Specific                              */
+#define __NR_waitpid            212 /* Linux Specific                              */
+#define __NR_swapoff            213 /* Linux Specific                              */
+#define __NR_sysinfo            214 /* Linux Specific                              */
+#define __NR_ipc                215 /* Linux Specific                              */
+#define __NR_sigreturn          216 /* Linux Specific                              */
+#define __NR_clone              217 /* Linux Specific                              */
+#define __NR_ioprio_get         218 /* Linux Specific                              */
+#define __NR_adjtimex           219 /* Linux Specific                              */
+#define __NR_sigprocmask        220 /* Linux Specific                              */
+#define __NR_create_module      221 /* Linux Specific                              */
+#define __NR_delete_module      222 /* Linux Specific                              */
+#define __NR_get_kernel_syms    223 /* Linux Specific                              */
+#define __NR_getpgid            224 /* Linux Specific                              */
+#define __NR_bdflush            225 /* Linux Specific                              */
+#define __NR_sysfs              226 /* Linux Specific                              */
+#define __NR_afs_syscall        227 /* Linux Specific                              */
+#define __NR_setfsuid           228 /* Linux Specific                              */
+#define __NR_setfsgid           229 /* Linux Specific                              */
+#define __NR__newselect         230 /* Linux Specific                              */
+#ifdef __KERNEL__
+#define __NR_time              231 /* Linux sparc32                               */
+#endif
+#define __NR_splice             232 /* Linux Specific                              */
+#define __NR_stime              233 /* Linux Specific                              */
+#define __NR_statfs64           234 /* Linux Specific                              */
+#define __NR_fstatfs64          235 /* Linux Specific                              */
+#define __NR__llseek            236 /* Linux Specific                              */
+#define __NR_mlock              237
+#define __NR_munlock            238
+#define __NR_mlockall           239
+#define __NR_munlockall         240
+#define __NR_sched_setparam     241
+#define __NR_sched_getparam     242
+#define __NR_sched_setscheduler 243
+#define __NR_sched_getscheduler 244
+#define __NR_sched_yield        245
+#define __NR_sched_get_priority_max 246
+#define __NR_sched_get_priority_min 247
+#define __NR_sched_rr_get_interval  248
+#define __NR_nanosleep          249
+#define __NR_mremap             250
+#define __NR__sysctl            251
+#define __NR_getsid             252
+#define __NR_fdatasync          253
+#define __NR_nfsservctl         254
+#define __NR_sync_file_range   255
+#define __NR_clock_settime     256
+#define __NR_clock_gettime     257
+#define __NR_clock_getres      258
+#define __NR_clock_nanosleep   259
+#define __NR_sched_getaffinity 260
+#define __NR_sched_setaffinity 261
+#define __NR_timer_settime     262
+#define __NR_timer_gettime     263
+#define __NR_timer_getoverrun  264
+#define __NR_timer_delete      265
+#define __NR_timer_create      266
+/* #define __NR_vserver                267 Reserved for VSERVER */
+#define __NR_io_setup          268
+#define __NR_io_destroy                269
+#define __NR_io_submit         270
+#define __NR_io_cancel         271
+#define __NR_io_getevents      272
+#define __NR_mq_open           273
+#define __NR_mq_unlink         274
+#define __NR_mq_timedsend      275
+#define __NR_mq_timedreceive   276
+#define __NR_mq_notify         277
+#define __NR_mq_getsetattr     278
+#define __NR_waitid            279
+#define __NR_tee               280
+#define __NR_add_key           281
+#define __NR_request_key       282
+#define __NR_keyctl            283
+#define __NR_openat            284
+#define __NR_mkdirat           285
+#define __NR_mknodat           286
+#define __NR_fchownat          287
+#define __NR_futimesat         288
+#define __NR_fstatat64         289
+#define __NR_unlinkat          290
+#define __NR_renameat          291
+#define __NR_linkat            292
+#define __NR_symlinkat         293
+#define __NR_readlinkat                294
+#define __NR_fchmodat          295
+#define __NR_faccessat         296
+#define __NR_pselect6          297
+#define __NR_ppoll             298
+#define __NR_unshare           299
+#define __NR_set_robust_list   300
+#define __NR_get_robust_list   301
+#define __NR_migrate_pages     302
+#define __NR_mbind             303
+#define __NR_get_mempolicy     304
+#define __NR_set_mempolicy     305
+#define __NR_kexec_load                306
+#define __NR_move_pages                307
+#define __NR_getcpu            308
+#define __NR_epoll_pwait       309
+#define __NR_utimensat         310
+#define __NR_signalfd          311
+#define __NR_timerfd_create    312
+#define __NR_eventfd           313
+#define __NR_fallocate         314
+#define __NR_timerfd_settime   315
+#define __NR_timerfd_gettime   316
+
+#define NR_SYSCALLS            317
+
+#ifdef __KERNEL__
+#define __ARCH_WANT_IPC_PARSE_VERSION
+#define __ARCH_WANT_OLD_READDIR
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_SGETMASK
+#define __ARCH_WANT_SYS_SIGNAL
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_COMPAT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
+
+#endif /* __KERNEL__ */
+#endif /* _SPARC64_UNISTD_H */
diff --git a/include/asm-sparc/upa.h b/include/asm-sparc/upa.h
new file mode 100644 (file)
index 0000000..5b16332
--- /dev/null
@@ -0,0 +1,109 @@
+#ifndef _SPARC64_UPA_H
+#define _SPARC64_UPA_H
+
+#include <asm/asi.h>
+
+/* UPA level registers and defines. */
+
+/* UPA Config Register */
+#define UPA_CONFIG_RESV                0xffffffffc0000000 /* Reserved.                    */
+#define UPA_CONFIG_PCON                0x000000003fc00000 /* Depth of various sys queues. */
+#define UPA_CONFIG_MID         0x00000000003e0000 /* Module ID.                   */
+#define UPA_CONFIG_PCAP                0x000000000001ffff /* Port Capabilities.           */
+
+/* UPA Port ID Register */
+#define UPA_PORTID_FNP         0xff00000000000000 /* Hardcoded to 0xfc on ultra.  */
+#define UPA_PORTID_RESV                0x00fffff800000000 /* Reserved.                    */
+#define UPA_PORTID_ECCVALID     0x0000000400000000 /* Zero if mod can generate ECC */
+#define UPA_PORTID_ONEREAD      0x0000000200000000 /* Set if mod generates P_RASB  */
+#define UPA_PORTID_PINTRDQ      0x0000000180000000 /* # outstanding P_INT_REQ's    */
+#define UPA_PORTID_PREQDQ       0x000000007e000000 /* slave-wr's to mod supported  */
+#define UPA_PORTID_PREQRD       0x0000000001e00000 /* # incoming P_REQ's supported */
+#define UPA_PORTID_UPACAP       0x00000000001f0000 /* UPA capabilities of mod      */
+#define UPA_PORTID_ID           0x000000000000ffff /* Module Identification bits  */
+
+/* UPA I/O space accessors */
+#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
+static inline unsigned char _upa_readb(unsigned long addr)
+{
+       unsigned char ret;
+
+       __asm__ __volatile__("lduba\t[%1] %2, %0\t/* upa_readb */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+
+       return ret;
+}
+
+static inline unsigned short _upa_readw(unsigned long addr)
+{
+       unsigned short ret;
+
+       __asm__ __volatile__("lduha\t[%1] %2, %0\t/* upa_readw */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+
+       return ret;
+}
+
+static inline unsigned int _upa_readl(unsigned long addr)
+{
+       unsigned int ret;
+
+       __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* upa_readl */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+
+       return ret;
+}
+
+static inline unsigned long _upa_readq(unsigned long addr)
+{
+       unsigned long ret;
+
+       __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* upa_readq */"
+                            : "=r" (ret)
+                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+
+       return ret;
+}
+
+static inline void _upa_writeb(unsigned char b, unsigned long addr)
+{
+       __asm__ __volatile__("stba\t%0, [%1] %2\t/* upa_writeb */"
+                            : /* no outputs */
+                            : "r" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+}
+
+static inline void _upa_writew(unsigned short w, unsigned long addr)
+{
+       __asm__ __volatile__("stha\t%0, [%1] %2\t/* upa_writew */"
+                            : /* no outputs */
+                            : "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+}
+
+static inline void _upa_writel(unsigned int l, unsigned long addr)
+{
+       __asm__ __volatile__("stwa\t%0, [%1] %2\t/* upa_writel */"
+                            : /* no outputs */
+                            : "r" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+}
+
+static inline void _upa_writeq(unsigned long q, unsigned long addr)
+{
+       __asm__ __volatile__("stxa\t%0, [%1] %2\t/* upa_writeq */"
+                            : /* no outputs */
+                            : "r" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
+}
+
+#define upa_readb(__addr)              (_upa_readb((unsigned long)(__addr)))
+#define upa_readw(__addr)              (_upa_readw((unsigned long)(__addr)))
+#define upa_readl(__addr)              (_upa_readl((unsigned long)(__addr)))
+#define upa_readq(__addr)              (_upa_readq((unsigned long)(__addr)))
+#define upa_writeb(__b, __addr)                (_upa_writeb((__b), (unsigned long)(__addr)))
+#define upa_writew(__w, __addr)                (_upa_writew((__w), (unsigned long)(__addr)))
+#define upa_writel(__l, __addr)                (_upa_writel((__l), (unsigned long)(__addr)))
+#define upa_writeq(__q, __addr)                (_upa_writeq((__q), (unsigned long)(__addr)))
+#endif /* __KERNEL__ && !__ASSEMBLY__ */
+
+#endif /* !(_SPARC64_UPA_H) */
diff --git a/include/asm-sparc/utrap.h b/include/asm-sparc/utrap.h
new file mode 100644 (file)
index 0000000..9da37ba
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * include/asm-sparc64/utrap.h
+ *
+ * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#ifndef __ASM_SPARC64_UTRAP_H
+#define __ASM_SPARC64_UTRAP_H
+
+#define UT_INSTRUCTION_EXCEPTION               1
+#define UT_INSTRUCTION_ERROR                   2
+#define UT_INSTRUCTION_PROTECTION              3
+#define UT_ILLTRAP_INSTRUCTION                 4
+#define UT_ILLEGAL_INSTRUCTION                 5
+#define UT_PRIVILEGED_OPCODE                   6
+#define UT_FP_DISABLED                         7
+#define UT_FP_EXCEPTION_IEEE_754               8
+#define UT_FP_EXCEPTION_OTHER                  9
+#define UT_TAG_OVERVIEW                                10
+#define UT_DIVISION_BY_ZERO                    11
+#define UT_DATA_EXCEPTION                      12
+#define UT_DATA_ERROR                          13
+#define UT_DATA_PROTECTION                     14
+#define UT_MEM_ADDRESS_NOT_ALIGNED             15
+#define UT_PRIVILEGED_ACTION                   16
+#define UT_ASYNC_DATA_ERROR                    17
+#define UT_TRAP_INSTRUCTION_16                 18
+#define UT_TRAP_INSTRUCTION_17                 19
+#define UT_TRAP_INSTRUCTION_18                 20
+#define UT_TRAP_INSTRUCTION_19                 21
+#define UT_TRAP_INSTRUCTION_20                 22
+#define UT_TRAP_INSTRUCTION_21                 23
+#define UT_TRAP_INSTRUCTION_22                 24
+#define UT_TRAP_INSTRUCTION_23                 25
+#define UT_TRAP_INSTRUCTION_24                 26
+#define UT_TRAP_INSTRUCTION_25                 27
+#define UT_TRAP_INSTRUCTION_26                 28
+#define UT_TRAP_INSTRUCTION_27                 29
+#define UT_TRAP_INSTRUCTION_28                 30
+#define UT_TRAP_INSTRUCTION_29                 31
+#define UT_TRAP_INSTRUCTION_30                 32
+#define UT_TRAP_INSTRUCTION_31                 33
+
+#define        UTH_NOCHANGE                            (-1)
+
+#ifndef __ASSEMBLY__
+typedef int utrap_entry_t;
+typedef void *utrap_handler_t;
+#endif /* __ASSEMBLY__ */
+
+#endif /* !(__ASM_SPARC64_PROCESSOR_H) */
index f6ca4779056cc97402c0f10a5d328c6a71935aeb..a22fed5a3c6bef64d9b0d6eb75e9699e81754a68 100644 (file)
 #define IOBASE_VADDR           0xfe000000
 #define IOBASE_END             0xfe600000
 
-#define VMALLOC_START          0xfe600000
-
-/* XXX Alter this when I get around to fixing sun4c - Anton */
-#define VMALLOC_END            0xffc00000
-
 /*
  * On the sun4/4c we need a place
  * to reliably map locked down kernel data.  This includes the
diff --git a/include/asm-sparc/vio.h b/include/asm-sparc/vio.h
new file mode 100644 (file)
index 0000000..d4de32f
--- /dev/null
@@ -0,0 +1,406 @@
+#ifndef _SPARC64_VIO_H
+#define _SPARC64_VIO_H
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/timer.h>
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/list.h>
+#include <linux/log2.h>
+
+#include <asm/ldc.h>
+#include <asm/mdesc.h>
+
+struct vio_msg_tag {
+       u8                      type;
+#define VIO_TYPE_CTRL          0x01
+#define VIO_TYPE_DATA          0x02
+#define VIO_TYPE_ERR           0x04
+
+       u8                      stype;
+#define VIO_SUBTYPE_INFO       0x01
+#define VIO_SUBTYPE_ACK                0x02
+#define VIO_SUBTYPE_NACK       0x04
+
+       u16                     stype_env;
+#define VIO_VER_INFO           0x0001
+#define VIO_ATTR_INFO          0x0002
+#define VIO_DRING_REG          0x0003
+#define VIO_DRING_UNREG                0x0004
+#define VIO_RDX                        0x0005
+#define VIO_PKT_DATA           0x0040
+#define VIO_DESC_DATA          0x0041
+#define VIO_DRING_DATA         0x0042
+#define VNET_MCAST_INFO                0x0101
+
+       u32             sid;
+};
+
+struct vio_rdx {
+       struct vio_msg_tag      tag;
+       u64                     resv[6];
+};
+
+struct vio_ver_info {
+       struct vio_msg_tag      tag;
+       u16                     major;
+       u16                     minor;
+       u8                      dev_class;
+#define VDEV_NETWORK           0x01
+#define VDEV_NETWORK_SWITCH    0x02
+#define VDEV_DISK              0x03
+#define VDEV_DISK_SERVER       0x04
+
+       u8                      resv1[3];
+       u64                     resv2[5];
+};
+
+struct vio_dring_register {
+       struct vio_msg_tag      tag;
+       u64                     dring_ident;
+       u32                     num_descr;
+       u32                     descr_size;
+       u16                     options;
+#define VIO_TX_DRING           0x0001
+#define VIO_RX_DRING           0x0002
+       u16                     resv;
+       u32                     num_cookies;
+       struct ldc_trans_cookie cookies[0];
+};
+
+struct vio_dring_unregister {
+       struct vio_msg_tag      tag;
+       u64                     dring_ident;
+       u64                     resv[5];
+};
+
+/* Data transfer modes */
+#define VIO_PKT_MODE           0x01 /* Packet based transfer   */
+#define VIO_DESC_MODE          0x02 /* In-band descriptors     */
+#define VIO_DRING_MODE         0x03 /* Descriptor rings        */
+
+struct vio_dring_data {
+       struct vio_msg_tag      tag;
+       u64                     seq;
+       u64                     dring_ident;
+       u32                     start_idx;
+       u32                     end_idx;
+       u8                      state;
+#define VIO_DRING_ACTIVE       0x01
+#define VIO_DRING_STOPPED      0x02
+
+       u8                      __pad1;
+       u16                     __pad2;
+       u32                     __pad3;
+       u64                     __par4[2];
+};
+
+struct vio_dring_hdr {
+       u8                      state;
+#define VIO_DESC_FREE          0x01
+#define VIO_DESC_READY         0x02
+#define VIO_DESC_ACCEPTED      0x03
+#define VIO_DESC_DONE          0x04
+       u8                      ack;
+#define VIO_ACK_ENABLE         0x01
+#define VIO_ACK_DISABLE                0x00
+
+       u16                     __pad1;
+       u32                     __pad2;
+};
+
+/* VIO disk specific structures and defines */
+struct vio_disk_attr_info {
+       struct vio_msg_tag      tag;
+       u8                      xfer_mode;
+       u8                      vdisk_type;
+#define VD_DISK_TYPE_SLICE     0x01 /* Slice in block device   */
+#define VD_DISK_TYPE_DISK      0x02 /* Entire block device     */
+       u16                     resv1;
+       u32                     vdisk_block_size;
+       u64                     operations;
+       u64                     vdisk_size;
+       u64                     max_xfer_size;
+       u64                     resv2[2];
+};
+
+struct vio_disk_desc {
+       struct vio_dring_hdr    hdr;
+       u64                     req_id;
+       u8                      operation;
+#define VD_OP_BREAD            0x01 /* Block read                      */
+#define VD_OP_BWRITE           0x02 /* Block write                     */
+#define VD_OP_FLUSH            0x03 /* Flush disk contents             */
+#define VD_OP_GET_WCE          0x04 /* Get write-cache status          */
+#define VD_OP_SET_WCE          0x05 /* Enable/disable write-cache      */
+#define VD_OP_GET_VTOC         0x06 /* Get VTOC                        */
+#define VD_OP_SET_VTOC         0x07 /* Set VTOC                        */
+#define VD_OP_GET_DISKGEOM     0x08 /* Get disk geometry               */
+#define VD_OP_SET_DISKGEOM     0x09 /* Set disk geometry               */
+#define VD_OP_SCSICMD          0x0a /* SCSI control command            */
+#define VD_OP_GET_DEVID                0x0b /* Get device ID                   */
+#define VD_OP_GET_EFI          0x0c /* Get EFI                         */
+#define VD_OP_SET_EFI          0x0d /* Set EFI                         */
+       u8                      slice;
+       u16                     resv1;
+       u32                     status;
+       u64                     offset;
+       u64                     size;
+       u32                     ncookies;
+       u32                     resv2;
+       struct ldc_trans_cookie cookies[0];
+};
+
+#define VIO_DISK_VNAME_LEN     8
+#define VIO_DISK_ALABEL_LEN    128
+#define VIO_DISK_NUM_PART      8
+
+struct vio_disk_vtoc {
+       u8                      volume_name[VIO_DISK_VNAME_LEN];
+       u16                     sector_size;
+       u16                     num_partitions;
+       u8                      ascii_label[VIO_DISK_ALABEL_LEN];
+       struct {
+               u16             id;
+               u16             perm_flags;
+               u32             resv;
+               u64             start_block;
+               u64             num_blocks;
+       } partitions[VIO_DISK_NUM_PART];
+};
+
+struct vio_disk_geom {
+       u16                     num_cyl; /* Num data cylinders          */
+       u16                     alt_cyl; /* Num alternate cylinders     */
+       u16                     beg_cyl; /* Cyl off of fixed head area  */
+       u16                     num_hd;  /* Num heads                   */
+       u16                     num_sec; /* Num sectors                 */
+       u16                     ifact;   /* Interleave factor           */
+       u16                     apc;     /* Alts per cylinder (SCSI)    */
+       u16                     rpm;     /* Revolutions per minute      */
+       u16                     phy_cyl; /* Num physical cylinders      */
+       u16                     wr_skip; /* Num sects to skip, writes   */
+       u16                     rd_skip; /* Num sects to skip, writes   */
+};
+
+struct vio_disk_devid {
+       u16                     resv;
+       u16                     type;
+       u32                     len;
+       char                    id[0];
+};
+
+struct vio_disk_efi {
+       u64                     lba;
+       u64                     len;
+       char                    data[0];
+};
+
+/* VIO net specific structures and defines */
+struct vio_net_attr_info {
+       struct vio_msg_tag      tag;
+       u8                      xfer_mode;
+       u8                      addr_type;
+#define VNET_ADDR_ETHERMAC     0x01
+       u16                     ack_freq;
+       u32                     resv1;
+       u64                     addr;
+       u64                     mtu;
+       u64                     resv2[3];
+};
+
+#define VNET_NUM_MCAST         7
+
+struct vio_net_mcast_info {
+       struct vio_msg_tag      tag;
+       u8                      set;
+       u8                      count;
+       u8                      mcast_addr[VNET_NUM_MCAST * 6];
+       u32                     resv;
+};
+
+struct vio_net_desc {
+       struct vio_dring_hdr    hdr;
+       u32                     size;
+       u32                     ncookies;
+       struct ldc_trans_cookie cookies[0];
+};
+
+#define VIO_MAX_RING_COOKIES   24
+
+struct vio_dring_state {
+       u64                     ident;
+       void                    *base;
+       u64                     snd_nxt;
+       u64                     rcv_nxt;
+       u32                     entry_size;
+       u32                     num_entries;
+       u32                     prod;
+       u32                     cons;
+       u32                     pending;
+       int                     ncookies;
+       struct ldc_trans_cookie cookies[VIO_MAX_RING_COOKIES];
+};
+
+static inline void *vio_dring_cur(struct vio_dring_state *dr)
+{
+       return dr->base + (dr->entry_size * dr->prod);
+}
+
+static inline void *vio_dring_entry(struct vio_dring_state *dr,
+                                   unsigned int index)
+{
+       return dr->base + (dr->entry_size * index);
+}
+
+static inline u32 vio_dring_avail(struct vio_dring_state *dr,
+                                 unsigned int ring_size)
+{
+       BUILD_BUG_ON(!is_power_of_2(ring_size));
+
+       return (dr->pending -
+               ((dr->prod - dr->cons) & (ring_size - 1)));
+}
+
+#define VIO_MAX_TYPE_LEN       32
+#define VIO_MAX_COMPAT_LEN     64
+
+struct vio_dev {
+       u64                     mp;
+       struct device_node      *dp;
+
+       char                    type[VIO_MAX_TYPE_LEN];
+       char                    compat[VIO_MAX_COMPAT_LEN];
+       int                     compat_len;
+
+       u64                     dev_no;
+
+       unsigned long           channel_id;
+
+       unsigned int            tx_irq;
+       unsigned int            rx_irq;
+
+       struct device           dev;
+};
+
+struct vio_driver {
+       struct list_head                node;
+       const struct vio_device_id      *id_table;
+       int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
+       int (*remove)(struct vio_dev *dev);
+       void (*shutdown)(struct vio_dev *dev);
+       unsigned long                   driver_data;
+       struct device_driver            driver;
+};
+
+struct vio_version {
+       u16             major;
+       u16             minor;
+};
+
+struct vio_driver_state;
+struct vio_driver_ops {
+       int     (*send_attr)(struct vio_driver_state *vio);
+       int     (*handle_attr)(struct vio_driver_state *vio, void *pkt);
+       void    (*handshake_complete)(struct vio_driver_state *vio);
+};
+
+struct vio_completion {
+       struct completion       com;
+       int                     err;
+       int                     waiting_for;
+};
+
+struct vio_driver_state {
+       /* Protects VIO handshake and, optionally, driver private state.  */
+       spinlock_t              lock;
+
+       struct ldc_channel      *lp;
+
+       u32                     _peer_sid;
+       u32                     _local_sid;
+       struct vio_dring_state  drings[2];
+#define VIO_DRIVER_TX_RING     0
+#define VIO_DRIVER_RX_RING     1
+
+       u8                      hs_state;
+#define VIO_HS_INVALID         0x00
+#define VIO_HS_GOTVERS         0x01
+#define VIO_HS_GOT_ATTR                0x04
+#define VIO_HS_SENT_DREG       0x08
+#define VIO_HS_SENT_RDX                0x10
+#define VIO_HS_GOT_RDX_ACK     0x20
+#define VIO_HS_GOT_RDX         0x40
+#define VIO_HS_SENT_RDX_ACK    0x80
+#define VIO_HS_COMPLETE                (VIO_HS_GOT_RDX_ACK | VIO_HS_SENT_RDX_ACK)
+
+       u8                      dev_class;
+
+       u8                      dr_state;
+#define VIO_DR_STATE_TXREG     0x01
+#define VIO_DR_STATE_RXREG     0x02
+#define VIO_DR_STATE_TXREQ     0x10
+#define VIO_DR_STATE_RXREQ     0x20
+
+       u8                      debug;
+#define VIO_DEBUG_HS           0x01
+#define VIO_DEBUG_DATA         0x02
+
+       void                    *desc_buf;
+       unsigned int            desc_buf_len;
+
+       struct vio_completion   *cmp;
+
+       struct vio_dev          *vdev;
+
+       struct timer_list       timer;
+
+       struct vio_version      ver;
+
+       struct vio_version      *ver_table;
+       int                     ver_table_entries;
+
+       char                    *name;
+
+       struct vio_driver_ops   *ops;
+};
+
+#define viodbg(TYPE, f, a...) \
+do {   if (vio->debug & VIO_DEBUG_##TYPE) \
+               printk(KERN_INFO "vio: ID[%lu] " f, \
+                      vio->vdev->channel_id, ## a); \
+} while (0)
+
+extern int vio_register_driver(struct vio_driver *drv);
+extern void vio_unregister_driver(struct vio_driver *drv);
+
+static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
+{
+       return container_of(drv, struct vio_driver, driver);
+}
+
+static inline struct vio_dev *to_vio_dev(struct device *dev)
+{
+       return container_of(dev, struct vio_dev, dev);
+}
+
+extern int vio_ldc_send(struct vio_driver_state *vio, void *data, int len);
+extern void vio_link_state_change(struct vio_driver_state *vio, int event);
+extern void vio_conn_reset(struct vio_driver_state *vio);
+extern int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt);
+extern int vio_validate_sid(struct vio_driver_state *vio,
+                           struct vio_msg_tag *tp);
+extern u32 vio_send_sid(struct vio_driver_state *vio);
+extern int vio_ldc_alloc(struct vio_driver_state *vio,
+                        struct ldc_channel_config *base_cfg, void *event_arg);
+extern void vio_ldc_free(struct vio_driver_state *vio);
+extern int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev,
+                          u8 dev_class, struct vio_version *ver_table,
+                          int ver_table_size, struct vio_driver_ops *ops,
+                          char *name);
+
+extern void vio_port_up(struct vio_driver_state *vio);
+
+#endif /* _SPARC64_VIO_H */
diff --git a/include/asm-sparc/visasm.h b/include/asm-sparc/visasm.h
new file mode 100644 (file)
index 0000000..de797b9
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef _SPARC64_VISASM_H
+#define _SPARC64_VISASM_H
+
+/* visasm.h:  FPU saving macros for VIS routines
+ *
+ * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
+ */
+
+#include <asm/pstate.h>
+#include <asm/ptrace.h>
+
+/* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc */
+
+#define VISEntry                                       \
+       rd              %fprs, %o5;                     \
+       andcc           %o5, (FPRS_FEF|FPRS_DU), %g0;   \
+       be,pt           %icc, 297f;                     \
+        sethi          %hi(297f), %g7;                 \
+       sethi           %hi(VISenter), %g1;             \
+       jmpl            %g1 + %lo(VISenter), %g0;       \
+        or             %g7, %lo(297f), %g7;            \
+297:   wr              %g0, FPRS_FEF, %fprs;           \
+
+#define VISExit                                                \
+       wr              %g0, 0, %fprs;
+
+/* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc.
+ * Must preserve %o5 between VISEntryHalf and VISExitHalf */
+
+#define VISEntryHalf                                   \
+       rd              %fprs, %o5;                     \
+       andcc           %o5, FPRS_FEF, %g0;             \
+       be,pt           %icc, 297f;                     \
+        sethi          %hi(298f), %g7;                 \
+       sethi           %hi(VISenterhalf), %g1;         \
+       jmpl            %g1 + %lo(VISenterhalf), %g0;   \
+        or             %g7, %lo(298f), %g7;            \
+       clr             %o5;                            \
+297:   wr              %o5, FPRS_FEF, %fprs;           \
+298:
+
+#define VISExitHalf                                    \
+       wr              %o5, 0, %fprs;
+
+#ifndef __ASSEMBLY__
+static inline void save_and_clear_fpu(void) {
+       __asm__ __volatile__ (
+"              rd %%fprs, %%o5\n"
+"              andcc %%o5, %0, %%g0\n"
+"              be,pt %%icc, 299f\n"
+"               sethi %%hi(298f), %%g7\n"
+"              sethi %%hi(VISenter), %%g1\n"
+"              jmpl %%g1 + %%lo(VISenter), %%g0\n"
+"               or %%g7, %%lo(298f), %%g7\n"
+"      298:    wr %%g0, 0, %%fprs\n"
+"      299:\n"
+"              " : : "i" (FPRS_FEF|FPRS_DU) :
+               "o5", "g1", "g2", "g3", "g7", "cc");
+}
+#endif
+
+#endif /* _SPARC64_ASI_H */
diff --git a/include/asm-sparc/watchdog.h b/include/asm-sparc/watchdog.h
new file mode 100644 (file)
index 0000000..5baf2d3
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *
+ * watchdog - Driver interface for the hardware watchdog timers
+ * present on Sun Microsystems boardsets
+ *
+ * Copyright (c) 2000 Eric Brower <ebrower@usa.net>
+ *
+ */
+
+#ifndef _SPARC64_WATCHDOG_H
+#define _SPARC64_WATCHDOG_H
+
+#include <linux/watchdog.h>
+
+/* Solaris compatibility ioctls--
+ * Ref. <linux/watchdog.h> for standard linux watchdog ioctls
+ */
+#define WIOCSTART _IO (WATCHDOG_IOCTL_BASE, 10)                /* Start Timer          */
+#define WIOCSTOP  _IO (WATCHDOG_IOCTL_BASE, 11)                /* Stop Timer           */
+#define WIOCGSTAT _IOR(WATCHDOG_IOCTL_BASE, 12, int)/* Get Timer Status        */
+
+/* Status flags from WIOCGSTAT ioctl
+ */
+#define WD_FREERUN     0x01    /* timer is running, interrupts disabled        */
+#define WD_EXPIRED     0x02    /* timer has expired                                            */
+#define WD_RUNNING     0x04    /* timer is running, interrupts enabled         */
+#define WD_STOPPED     0x08    /* timer has not been started                           */
+#define WD_SERVICED 0x10       /* timer interrupt was serviced                         */
+
+#endif /* ifndef _SPARC64_WATCHDOG_H */
+
index f34b2cfa82069f760ae371f16f7e1060578daa12..35089a838c3f9713a68d6273bcc71f8fb52e0f03 100644 (file)
@@ -1,269 +1,8 @@
-/*
- * include/asm-sparc/xor.h
- *
- * Optimized RAID-5 checksumming functions for 32-bit Sparc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * You should have received a copy of the GNU General Public License
- * (for example /usr/src/linux/COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * High speed xor_block operation for RAID4/5 utilizing the
- * ldd/std SPARC instructions.
- *
- * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz)
- */
-
-static void
-sparc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
-{
-       int lines = bytes / (sizeof (long)) / 8;
-
-       do {
-               __asm__ __volatile__(
-                 "ldd [%0 + 0x00], %%g2\n\t"
-                 "ldd [%0 + 0x08], %%g4\n\t"
-                 "ldd [%0 + 0x10], %%o0\n\t"
-                 "ldd [%0 + 0x18], %%o2\n\t"
-                 "ldd [%1 + 0x00], %%o4\n\t"
-                 "ldd [%1 + 0x08], %%l0\n\t"
-                 "ldd [%1 + 0x10], %%l2\n\t"
-                 "ldd [%1 + 0x18], %%l4\n\t"
-                 "xor %%g2, %%o4, %%g2\n\t"
-                 "xor %%g3, %%o5, %%g3\n\t"
-                 "xor %%g4, %%l0, %%g4\n\t"
-                 "xor %%g5, %%l1, %%g5\n\t"
-                 "xor %%o0, %%l2, %%o0\n\t"
-                 "xor %%o1, %%l3, %%o1\n\t"
-                 "xor %%o2, %%l4, %%o2\n\t"
-                 "xor %%o3, %%l5, %%o3\n\t"
-                 "std %%g2, [%0 + 0x00]\n\t"
-                 "std %%g4, [%0 + 0x08]\n\t"
-                 "std %%o0, [%0 + 0x10]\n\t"
-                 "std %%o2, [%0 + 0x18]\n"
-               :
-               : "r" (p1), "r" (p2)
-               : "g2", "g3", "g4", "g5",
-                 "o0", "o1", "o2", "o3", "o4", "o5",
-                 "l0", "l1", "l2", "l3", "l4", "l5");
-               p1 += 8;
-               p2 += 8;
-       } while (--lines > 0);
-}
-
-static void
-sparc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-       unsigned long *p3)
-{
-       int lines = bytes / (sizeof (long)) / 8;
-
-       do {
-               __asm__ __volatile__(
-                 "ldd [%0 + 0x00], %%g2\n\t"
-                 "ldd [%0 + 0x08], %%g4\n\t"
-                 "ldd [%0 + 0x10], %%o0\n\t"
-                 "ldd [%0 + 0x18], %%o2\n\t"
-                 "ldd [%1 + 0x00], %%o4\n\t"
-                 "ldd [%1 + 0x08], %%l0\n\t"
-                 "ldd [%1 + 0x10], %%l2\n\t"
-                 "ldd [%1 + 0x18], %%l4\n\t"
-                 "xor %%g2, %%o4, %%g2\n\t"
-                 "xor %%g3, %%o5, %%g3\n\t"
-                 "ldd [%2 + 0x00], %%o4\n\t"
-                 "xor %%g4, %%l0, %%g4\n\t"
-                 "xor %%g5, %%l1, %%g5\n\t"
-                 "ldd [%2 + 0x08], %%l0\n\t"
-                 "xor %%o0, %%l2, %%o0\n\t"
-                 "xor %%o1, %%l3, %%o1\n\t"
-                 "ldd [%2 + 0x10], %%l2\n\t"
-                 "xor %%o2, %%l4, %%o2\n\t"
-                 "xor %%o3, %%l5, %%o3\n\t"
-                 "ldd [%2 + 0x18], %%l4\n\t"
-                 "xor %%g2, %%o4, %%g2\n\t"
-                 "xor %%g3, %%o5, %%g3\n\t"
-                 "xor %%g4, %%l0, %%g4\n\t"
-                 "xor %%g5, %%l1, %%g5\n\t"
-                 "xor %%o0, %%l2, %%o0\n\t"
-                 "xor %%o1, %%l3, %%o1\n\t"
-                 "xor %%o2, %%l4, %%o2\n\t"
-                 "xor %%o3, %%l5, %%o3\n\t"
-                 "std %%g2, [%0 + 0x00]\n\t"
-                 "std %%g4, [%0 + 0x08]\n\t"
-                 "std %%o0, [%0 + 0x10]\n\t"
-                 "std %%o2, [%0 + 0x18]\n"
-               :
-               : "r" (p1), "r" (p2), "r" (p3)
-               : "g2", "g3", "g4", "g5",
-                 "o0", "o1", "o2", "o3", "o4", "o5",
-                 "l0", "l1", "l2", "l3", "l4", "l5");
-               p1 += 8;
-               p2 += 8;
-               p3 += 8;
-       } while (--lines > 0);
-}
-
-static void
-sparc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-       unsigned long *p3, unsigned long *p4)
-{
-       int lines = bytes / (sizeof (long)) / 8;
-
-       do {
-               __asm__ __volatile__(
-                 "ldd [%0 + 0x00], %%g2\n\t"
-                 "ldd [%0 + 0x08], %%g4\n\t"
-                 "ldd [%0 + 0x10], %%o0\n\t"
-                 "ldd [%0 + 0x18], %%o2\n\t"
-                 "ldd [%1 + 0x00], %%o4\n\t"
-                 "ldd [%1 + 0x08], %%l0\n\t"
-                 "ldd [%1 + 0x10], %%l2\n\t"
-                 "ldd [%1 + 0x18], %%l4\n\t"
-                 "xor %%g2, %%o4, %%g2\n\t"
-                 "xor %%g3, %%o5, %%g3\n\t"
-                 "ldd [%2 + 0x00], %%o4\n\t"
-                 "xor %%g4, %%l0, %%g4\n\t"
-                 "xor %%g5, %%l1, %%g5\n\t"
-                 "ldd [%2 + 0x08], %%l0\n\t"
-                 "xor %%o0, %%l2, %%o0\n\t"
-                 "xor %%o1, %%l3, %%o1\n\t"
-                 "ldd [%2 + 0x10], %%l2\n\t"
-                 "xor %%o2, %%l4, %%o2\n\t"
-                 "xor %%o3, %%l5, %%o3\n\t"
-                 "ldd [%2 + 0x18], %%l4\n\t"
-                 "xor %%g2, %%o4, %%g2\n\t"
-                 "xor %%g3, %%o5, %%g3\n\t"
-                 "ldd [%3 + 0x00], %%o4\n\t"
-                 "xor %%g4, %%l0, %%g4\n\t"
-                 "xor %%g5, %%l1, %%g5\n\t"
-                 "ldd [%3 + 0x08], %%l0\n\t"
-                 "xor %%o0, %%l2, %%o0\n\t"
-                 "xor %%o1, %%l3, %%o1\n\t"
-                 "ldd [%3 + 0x10], %%l2\n\t"
-                 "xor %%o2, %%l4, %%o2\n\t"
-                 "xor %%o3, %%l5, %%o3\n\t"
-                 "ldd [%3 + 0x18], %%l4\n\t"
-                 "xor %%g2, %%o4, %%g2\n\t"
-                 "xor %%g3, %%o5, %%g3\n\t"
-                 "xor %%g4, %%l0, %%g4\n\t"
-                 "xor %%g5, %%l1, %%g5\n\t"
-                 "xor %%o0, %%l2, %%o0\n\t"
-                 "xor %%o1, %%l3, %%o1\n\t"
-                 "xor %%o2, %%l4, %%o2\n\t"
-                 "xor %%o3, %%l5, %%o3\n\t"
-                 "std %%g2, [%0 + 0x00]\n\t"
-                 "std %%g4, [%0 + 0x08]\n\t"
-                 "std %%o0, [%0 + 0x10]\n\t"
-                 "std %%o2, [%0 + 0x18]\n"
-               :
-               : "r" (p1), "r" (p2), "r" (p3), "r" (p4)
-               : "g2", "g3", "g4", "g5",
-                 "o0", "o1", "o2", "o3", "o4", "o5",
-                 "l0", "l1", "l2", "l3", "l4", "l5");
-               p1 += 8;
-               p2 += 8;
-               p3 += 8;
-               p4 += 8;
-       } while (--lines > 0);
-}
-
-static void
-sparc_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-       unsigned long *p3, unsigned long *p4, unsigned long *p5)
-{
-       int lines = bytes / (sizeof (long)) / 8;
-
-       do {
-               __asm__ __volatile__(
-                 "ldd [%0 + 0x00], %%g2\n\t"
-                 "ldd [%0 + 0x08], %%g4\n\t"
-                 "ldd [%0 + 0x10], %%o0\n\t"
-                 "ldd [%0 + 0x18], %%o2\n\t"
-                 "ldd [%1 + 0x00], %%o4\n\t"
-                 "ldd [%1 + 0x08], %%l0\n\t"
-                 "ldd [%1 + 0x10], %%l2\n\t"
-                 "ldd [%1 + 0x18], %%l4\n\t"
-                 "xor %%g2, %%o4, %%g2\n\t"
-                 "xor %%g3, %%o5, %%g3\n\t"
-                 "ldd [%2 + 0x00], %%o4\n\t"
-                 "xor %%g4, %%l0, %%g4\n\t"
-                 "xor %%g5, %%l1, %%g5\n\t"
-                 "ldd [%2 + 0x08], %%l0\n\t"
-                 "xor %%o0, %%l2, %%o0\n\t"
-                 "xor %%o1, %%l3, %%o1\n\t"
-                 "ldd [%2 + 0x10], %%l2\n\t"
-                 "xor %%o2, %%l4, %%o2\n\t"
-                 "xor %%o3, %%l5, %%o3\n\t"
-                 "ldd [%2 + 0x18], %%l4\n\t"
-                 "xor %%g2, %%o4, %%g2\n\t"
-                 "xor %%g3, %%o5, %%g3\n\t"
-                 "ldd [%3 + 0x00], %%o4\n\t"
-                 "xor %%g4, %%l0, %%g4\n\t"
-                 "xor %%g5, %%l1, %%g5\n\t"
-                 "ldd [%3 + 0x08], %%l0\n\t"
-                 "xor %%o0, %%l2, %%o0\n\t"
-                 "xor %%o1, %%l3, %%o1\n\t"
-                 "ldd [%3 + 0x10], %%l2\n\t"
-                 "xor %%o2, %%l4, %%o2\n\t"
-                 "xor %%o3, %%l5, %%o3\n\t"
-                 "ldd [%3 + 0x18], %%l4\n\t"
-                 "xor %%g2, %%o4, %%g2\n\t"
-                 "xor %%g3, %%o5, %%g3\n\t"
-                 "ldd [%4 + 0x00], %%o4\n\t"
-                 "xor %%g4, %%l0, %%g4\n\t"
-                 "xor %%g5, %%l1, %%g5\n\t"
-                 "ldd [%4 + 0x08], %%l0\n\t"
-                 "xor %%o0, %%l2, %%o0\n\t"
-                 "xor %%o1, %%l3, %%o1\n\t"
-                 "ldd [%4 + 0x10], %%l2\n\t"
-                 "xor %%o2, %%l4, %%o2\n\t"
-                 "xor %%o3, %%l5, %%o3\n\t"
-                 "ldd [%4 + 0x18], %%l4\n\t"
-                 "xor %%g2, %%o4, %%g2\n\t"
-                 "xor %%g3, %%o5, %%g3\n\t"
-                 "xor %%g4, %%l0, %%g4\n\t"
-                 "xor %%g5, %%l1, %%g5\n\t"
-                 "xor %%o0, %%l2, %%o0\n\t"
-                 "xor %%o1, %%l3, %%o1\n\t"
-                 "xor %%o2, %%l4, %%o2\n\t"
-                 "xor %%o3, %%l5, %%o3\n\t"
-                 "std %%g2, [%0 + 0x00]\n\t"
-                 "std %%g4, [%0 + 0x08]\n\t"
-                 "std %%o0, [%0 + 0x10]\n\t"
-                 "std %%o2, [%0 + 0x18]\n"
-               :
-               : "r" (p1), "r" (p2), "r" (p3), "r" (p4), "r" (p5)
-               : "g2", "g3", "g4", "g5",
-                 "o0", "o1", "o2", "o3", "o4", "o5",
-                 "l0", "l1", "l2", "l3", "l4", "l5");
-               p1 += 8;
-               p2 += 8;
-               p3 += 8;
-               p4 += 8;
-               p5 += 8;
-       } while (--lines > 0);
-}
-
-static struct xor_block_template xor_block_SPARC = {
-       .name   = "SPARC",
-       .do_2   = sparc_2,
-       .do_3   = sparc_3,
-       .do_4   = sparc_4,
-       .do_5   = sparc_5,
-};
-
-/* For grins, also test the generic routines.  */
-#include <asm-generic/xor.h>
-
-#undef XOR_TRY_TEMPLATES
-#define XOR_TRY_TEMPLATES                              \
-       do {                                            \
-               xor_speed(&xor_block_8regs);            \
-               xor_speed(&xor_block_32regs);           \
-               xor_speed(&xor_block_SPARC);            \
-       } while (0)
+#ifndef ___ASM_SPARC_XOR_H
+#define ___ASM_SPARC_XOR_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm-sparc/xor_64.h>
+#else
+#include <asm-sparc/xor_32.h>
+#endif
+#endif
diff --git a/include/asm-sparc/xor_32.h b/include/asm-sparc/xor_32.h
new file mode 100644 (file)
index 0000000..f34b2cf
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * include/asm-sparc/xor.h
+ *
+ * Optimized RAID-5 checksumming functions for 32-bit Sparc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * (for example /usr/src/linux/COPYING); if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * High speed xor_block operation for RAID4/5 utilizing the
+ * ldd/std SPARC instructions.
+ *
+ * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz)
+ */
+
+static void
+sparc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+{
+       int lines = bytes / (sizeof (long)) / 8;
+
+       do {
+               __asm__ __volatile__(
+                 "ldd [%0 + 0x00], %%g2\n\t"
+                 "ldd [%0 + 0x08], %%g4\n\t"
+                 "ldd [%0 + 0x10], %%o0\n\t"
+                 "ldd [%0 + 0x18], %%o2\n\t"
+                 "ldd [%1 + 0x00], %%o4\n\t"
+                 "ldd [%1 + 0x08], %%l0\n\t"
+                 "ldd [%1 + 0x10], %%l2\n\t"
+                 "ldd [%1 + 0x18], %%l4\n\t"
+                 "xor %%g2, %%o4, %%g2\n\t"
+                 "xor %%g3, %%o5, %%g3\n\t"
+                 "xor %%g4, %%l0, %%g4\n\t"
+                 "xor %%g5, %%l1, %%g5\n\t"
+                 "xor %%o0, %%l2, %%o0\n\t"
+                 "xor %%o1, %%l3, %%o1\n\t"
+                 "xor %%o2, %%l4, %%o2\n\t"
+                 "xor %%o3, %%l5, %%o3\n\t"
+                 "std %%g2, [%0 + 0x00]\n\t"
+                 "std %%g4, [%0 + 0x08]\n\t"
+                 "std %%o0, [%0 + 0x10]\n\t"
+                 "std %%o2, [%0 + 0x18]\n"
+               :
+               : "r" (p1), "r" (p2)
+               : "g2", "g3", "g4", "g5",
+                 "o0", "o1", "o2", "o3", "o4", "o5",
+                 "l0", "l1", "l2", "l3", "l4", "l5");
+               p1 += 8;
+               p2 += 8;
+       } while (--lines > 0);
+}
+
+static void
+sparc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+       unsigned long *p3)
+{
+       int lines = bytes / (sizeof (long)) / 8;
+
+       do {
+               __asm__ __volatile__(
+                 "ldd [%0 + 0x00], %%g2\n\t"
+                 "ldd [%0 + 0x08], %%g4\n\t"
+                 "ldd [%0 + 0x10], %%o0\n\t"
+                 "ldd [%0 + 0x18], %%o2\n\t"
+                 "ldd [%1 + 0x00], %%o4\n\t"
+                 "ldd [%1 + 0x08], %%l0\n\t"
+                 "ldd [%1 + 0x10], %%l2\n\t"
+                 "ldd [%1 + 0x18], %%l4\n\t"
+                 "xor %%g2, %%o4, %%g2\n\t"
+                 "xor %%g3, %%o5, %%g3\n\t"
+                 "ldd [%2 + 0x00], %%o4\n\t"
+                 "xor %%g4, %%l0, %%g4\n\t"
+                 "xor %%g5, %%l1, %%g5\n\t"
+                 "ldd [%2 + 0x08], %%l0\n\t"
+                 "xor %%o0, %%l2, %%o0\n\t"
+                 "xor %%o1, %%l3, %%o1\n\t"
+                 "ldd [%2 + 0x10], %%l2\n\t"
+                 "xor %%o2, %%l4, %%o2\n\t"
+                 "xor %%o3, %%l5, %%o3\n\t"
+                 "ldd [%2 + 0x18], %%l4\n\t"
+                 "xor %%g2, %%o4, %%g2\n\t"
+                 "xor %%g3, %%o5, %%g3\n\t"
+                 "xor %%g4, %%l0, %%g4\n\t"
+                 "xor %%g5, %%l1, %%g5\n\t"
+                 "xor %%o0, %%l2, %%o0\n\t"
+                 "xor %%o1, %%l3, %%o1\n\t"
+                 "xor %%o2, %%l4, %%o2\n\t"
+                 "xor %%o3, %%l5, %%o3\n\t"
+                 "std %%g2, [%0 + 0x00]\n\t"
+                 "std %%g4, [%0 + 0x08]\n\t"
+                 "std %%o0, [%0 + 0x10]\n\t"
+                 "std %%o2, [%0 + 0x18]\n"
+               :
+               : "r" (p1), "r" (p2), "r" (p3)
+               : "g2", "g3", "g4", "g5",
+                 "o0", "o1", "o2", "o3", "o4", "o5",
+                 "l0", "l1", "l2", "l3", "l4", "l5");
+               p1 += 8;
+               p2 += 8;
+               p3 += 8;
+       } while (--lines > 0);
+}
+
+static void
+sparc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+       unsigned long *p3, unsigned long *p4)
+{
+       int lines = bytes / (sizeof (long)) / 8;
+
+       do {
+               __asm__ __volatile__(
+                 "ldd [%0 + 0x00], %%g2\n\t"
+                 "ldd [%0 + 0x08], %%g4\n\t"
+                 "ldd [%0 + 0x10], %%o0\n\t"
+                 "ldd [%0 + 0x18], %%o2\n\t"
+                 "ldd [%1 + 0x00], %%o4\n\t"
+                 "ldd [%1 + 0x08], %%l0\n\t"
+                 "ldd [%1 + 0x10], %%l2\n\t"
+                 "ldd [%1 + 0x18], %%l4\n\t"
+                 "xor %%g2, %%o4, %%g2\n\t"
+                 "xor %%g3, %%o5, %%g3\n\t"
+                 "ldd [%2 + 0x00], %%o4\n\t"
+                 "xor %%g4, %%l0, %%g4\n\t"
+                 "xor %%g5, %%l1, %%g5\n\t"
+                 "ldd [%2 + 0x08], %%l0\n\t"
+                 "xor %%o0, %%l2, %%o0\n\t"
+                 "xor %%o1, %%l3, %%o1\n\t"
+                 "ldd [%2 + 0x10], %%l2\n\t"
+                 "xor %%o2, %%l4, %%o2\n\t"
+                 "xor %%o3, %%l5, %%o3\n\t"
+                 "ldd [%2 + 0x18], %%l4\n\t"
+                 "xor %%g2, %%o4, %%g2\n\t"
+                 "xor %%g3, %%o5, %%g3\n\t"
+                 "ldd [%3 + 0x00], %%o4\n\t"
+                 "xor %%g4, %%l0, %%g4\n\t"
+                 "xor %%g5, %%l1, %%g5\n\t"
+                 "ldd [%3 + 0x08], %%l0\n\t"
+                 "xor %%o0, %%l2, %%o0\n\t"
+                 "xor %%o1, %%l3, %%o1\n\t"
+                 "ldd [%3 + 0x10], %%l2\n\t"
+                 "xor %%o2, %%l4, %%o2\n\t"
+                 "xor %%o3, %%l5, %%o3\n\t"
+                 "ldd [%3 + 0x18], %%l4\n\t"
+                 "xor %%g2, %%o4, %%g2\n\t"
+                 "xor %%g3, %%o5, %%g3\n\t"
+                 "xor %%g4, %%l0, %%g4\n\t"
+                 "xor %%g5, %%l1, %%g5\n\t"
+                 "xor %%o0, %%l2, %%o0\n\t"
+                 "xor %%o1, %%l3, %%o1\n\t"
+                 "xor %%o2, %%l4, %%o2\n\t"
+                 "xor %%o3, %%l5, %%o3\n\t"
+                 "std %%g2, [%0 + 0x00]\n\t"
+                 "std %%g4, [%0 + 0x08]\n\t"
+                 "std %%o0, [%0 + 0x10]\n\t"
+                 "std %%o2, [%0 + 0x18]\n"
+               :
+               : "r" (p1), "r" (p2), "r" (p3), "r" (p4)
+               : "g2", "g3", "g4", "g5",
+                 "o0", "o1", "o2", "o3", "o4", "o5",
+                 "l0", "l1", "l2", "l3", "l4", "l5");
+               p1 += 8;
+               p2 += 8;
+               p3 += 8;
+               p4 += 8;
+       } while (--lines > 0);
+}
+
+static void
+sparc_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+       unsigned long *p3, unsigned long *p4, unsigned long *p5)
+{
+       int lines = bytes / (sizeof (long)) / 8;
+
+       do {
+               __asm__ __volatile__(
+                 "ldd [%0 + 0x00], %%g2\n\t"
+                 "ldd [%0 + 0x08], %%g4\n\t"
+                 "ldd [%0 + 0x10], %%o0\n\t"
+                 "ldd [%0 + 0x18], %%o2\n\t"
+                 "ldd [%1 + 0x00], %%o4\n\t"
+                 "ldd [%1 + 0x08], %%l0\n\t"
+                 "ldd [%1 + 0x10], %%l2\n\t"
+                 "ldd [%1 + 0x18], %%l4\n\t"
+                 "xor %%g2, %%o4, %%g2\n\t"
+                 "xor %%g3, %%o5, %%g3\n\t"
+                 "ldd [%2 + 0x00], %%o4\n\t"
+                 "xor %%g4, %%l0, %%g4\n\t"
+                 "xor %%g5, %%l1, %%g5\n\t"
+                 "ldd [%2 + 0x08], %%l0\n\t"
+                 "xor %%o0, %%l2, %%o0\n\t"
+                 "xor %%o1, %%l3, %%o1\n\t"
+                 "ldd [%2 + 0x10], %%l2\n\t"
+                 "xor %%o2, %%l4, %%o2\n\t"
+                 "xor %%o3, %%l5, %%o3\n\t"
+                 "ldd [%2 + 0x18], %%l4\n\t"
+                 "xor %%g2, %%o4, %%g2\n\t"
+                 "xor %%g3, %%o5, %%g3\n\t"
+                 "ldd [%3 + 0x00], %%o4\n\t"
+                 "xor %%g4, %%l0, %%g4\n\t"
+                 "xor %%g5, %%l1, %%g5\n\t"
+                 "ldd [%3 + 0x08], %%l0\n\t"
+                 "xor %%o0, %%l2, %%o0\n\t"
+                 "xor %%o1, %%l3, %%o1\n\t"
+                 "ldd [%3 + 0x10], %%l2\n\t"
+                 "xor %%o2, %%l4, %%o2\n\t"
+                 "xor %%o3, %%l5, %%o3\n\t"
+                 "ldd [%3 + 0x18], %%l4\n\t"
+                 "xor %%g2, %%o4, %%g2\n\t"
+                 "xor %%g3, %%o5, %%g3\n\t"
+                 "ldd [%4 + 0x00], %%o4\n\t"
+                 "xor %%g4, %%l0, %%g4\n\t"
+                 "xor %%g5, %%l1, %%g5\n\t"
+                 "ldd [%4 + 0x08], %%l0\n\t"
+                 "xor %%o0, %%l2, %%o0\n\t"
+                 "xor %%o1, %%l3, %%o1\n\t"
+                 "ldd [%4 + 0x10], %%l2\n\t"
+                 "xor %%o2, %%l4, %%o2\n\t"
+                 "xor %%o3, %%l5, %%o3\n\t"
+                 "ldd [%4 + 0x18], %%l4\n\t"
+                 "xor %%g2, %%o4, %%g2\n\t"
+                 "xor %%g3, %%o5, %%g3\n\t"
+                 "xor %%g4, %%l0, %%g4\n\t"
+                 "xor %%g5, %%l1, %%g5\n\t"
+                 "xor %%o0, %%l2, %%o0\n\t"
+                 "xor %%o1, %%l3, %%o1\n\t"
+                 "xor %%o2, %%l4, %%o2\n\t"
+                 "xor %%o3, %%l5, %%o3\n\t"
+                 "std %%g2, [%0 + 0x00]\n\t"
+                 "std %%g4, [%0 + 0x08]\n\t"
+                 "std %%o0, [%0 + 0x10]\n\t"
+                 "std %%o2, [%0 + 0x18]\n"
+               :
+               : "r" (p1), "r" (p2), "r" (p3), "r" (p4), "r" (p5)
+               : "g2", "g3", "g4", "g5",
+                 "o0", "o1", "o2", "o3", "o4", "o5",
+                 "l0", "l1", "l2", "l3", "l4", "l5");
+               p1 += 8;
+               p2 += 8;
+               p3 += 8;
+               p4 += 8;
+               p5 += 8;
+       } while (--lines > 0);
+}
+
+static struct xor_block_template xor_block_SPARC = {
+       .name   = "SPARC",
+       .do_2   = sparc_2,
+       .do_3   = sparc_3,
+       .do_4   = sparc_4,
+       .do_5   = sparc_5,
+};
+
+/* For grins, also test the generic routines.  */
+#include <asm-generic/xor.h>
+
+#undef XOR_TRY_TEMPLATES
+#define XOR_TRY_TEMPLATES                              \
+       do {                                            \
+               xor_speed(&xor_block_8regs);            \
+               xor_speed(&xor_block_32regs);           \
+               xor_speed(&xor_block_SPARC);            \
+       } while (0)
diff --git a/include/asm-sparc/xor_64.h b/include/asm-sparc/xor_64.h
new file mode 100644 (file)
index 0000000..a023388
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * include/asm-sparc64/xor.h
+ *
+ * High speed xor_block operation for RAID4/5 utilizing the
+ * UltraSparc Visual Instruction Set and Niagara block-init
+ * twin-load instructions.
+ *
+ * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 2006 David S. Miller <davem@davemloft.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, or (at your option)
+ * any later version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * (for example /usr/src/linux/COPYING); if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <asm/spitfire.h>
+
+extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *);
+extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *,
+                     unsigned long *);
+extern void xor_vis_4(unsigned long, unsigned long *, unsigned long *,
+                     unsigned long *, unsigned long *);
+extern void xor_vis_5(unsigned long, unsigned long *, unsigned long *,
+                     unsigned long *, unsigned long *, unsigned long *);
+
+/* XXX Ugh, write cheetah versions... -DaveM */
+
+static struct xor_block_template xor_block_VIS = {
+        .name  = "VIS",
+        .do_2  = xor_vis_2,
+        .do_3  = xor_vis_3,
+        .do_4  = xor_vis_4,
+        .do_5  = xor_vis_5,
+};
+
+extern void xor_niagara_2(unsigned long, unsigned long *, unsigned long *);
+extern void xor_niagara_3(unsigned long, unsigned long *, unsigned long *,
+                         unsigned long *);
+extern void xor_niagara_4(unsigned long, unsigned long *, unsigned long *,
+                         unsigned long *, unsigned long *);
+extern void xor_niagara_5(unsigned long, unsigned long *, unsigned long *,
+                         unsigned long *, unsigned long *, unsigned long *);
+
+static struct xor_block_template xor_block_niagara = {
+        .name  = "Niagara",
+        .do_2  = xor_niagara_2,
+        .do_3  = xor_niagara_3,
+        .do_4  = xor_niagara_4,
+        .do_5  = xor_niagara_5,
+};
+
+#undef XOR_TRY_TEMPLATES
+#define XOR_TRY_TEMPLATES                              \
+       do {                                            \
+               xor_speed(&xor_block_VIS);              \
+               xor_speed(&xor_block_niagara);          \
+       } while (0)
+
+/* For VIS for everything except Niagara.  */
+#define XOR_SELECT_TEMPLATE(FASTEST) \
+       ((tlb_type == hypervisor && \
+         (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || \
+          sun4v_chip_type == SUN4V_CHIP_NIAGARA2)) ? \
+        &xor_block_niagara : \
+        &xor_block_VIS)
index dce1cf9a931390d97f8046e2de5281676eccc42b..6cdaf9d33b386631df559a00e93851a44880c13f 100644 (file)
@@ -1,23 +1 @@
-include include/asm-generic/Kbuild.asm
-
-ALTARCH := sparc
-ARCHDEF := defined __sparc__ && defined __arch64__
-ALTARCHDEF := defined __sparc__ && !defined __arch64__
-
-header-y += apb.h
-header-y += asi.h
-header-y += bbc.h
-header-y += bpp.h
-header-y += display7seg.h
-header-y += envctrl.h
-header-y += openprom.h
-header-y += openpromio.h
-header-y += psrcompat.h
-header-y += pstate.h
-header-y += reg.h
-header-y += uctx.h
-header-y += utrap.h
-header-y += watchdog.h
-
-unifdef-y += fbio.h
-unifdef-y += perfctr.h
+# dummy file to avoid breaking make headers_install
index e9fcf0e781ea11cd1644dc9dc3e96aa6519fa0e6..eb8d4b3f516395d3311014f8f8cf7684fa747d14 100644 (file)
@@ -1,20 +1 @@
-#ifndef AGP_H
-#define AGP_H 1
-
-/* dummy for now */
-
-#define map_page_into_agp(page) 
-#define unmap_page_from_agp(page) 
-#define flush_agp_cache() mb()
-
-/* Convert a physical address to an address suitable for the GART. */
-#define phys_to_gart(x) (x)
-#define gart_to_phys(x) (x)
-
-/* GATT allocation. Returns/accepts GATT kernel virtual address. */
-#define alloc_gatt_pages(order)                \
-       ((char *)__get_free_pages(GFP_KERNEL, (order)))
-#define free_gatt_pages(table, order)  \
-       free_pages((unsigned long)(table), (order))
-
-#endif
+#include <asm-sparc/agp.h>
index 8f3b57db810f31d2d0d518d1c8611b6a15a8d7ef..5e236ca6e492c097225998c0a44ac1876017b1d2 100644 (file)
@@ -1,36 +1 @@
-/*
- * apb.h: Advanced PCI Bridge Configuration Registers and Bits
- *
- * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
- */
-
-#ifndef _SPARC64_APB_H
-#define _SPARC64_APB_H
-
-#define APB_TICK_REGISTER                      0xb0
-#define APB_INT_ACK                            0xb8
-#define APB_PRIMARY_MASTER_RETRY_LIMIT         0xc0
-#define APB_DMA_ASFR                           0xc8
-#define APB_DMA_AFAR                           0xd0
-#define APB_PIO_TARGET_RETRY_LIMIT             0xd8
-#define APB_PIO_TARGET_LATENCY_TIMER           0xd9
-#define APB_DMA_TARGET_RETRY_LIMIT             0xda
-#define APB_DMA_TARGET_LATENCY_TIMER           0xdb
-#define APB_SECONDARY_MASTER_RETRY_LIMIT       0xdc
-#define APB_SECONDARY_CONTROL                  0xdd
-#define APB_IO_ADDRESS_MAP                     0xde
-#define APB_MEM_ADDRESS_MAP                    0xdf
-
-#define APB_PCI_CONTROL_LOW                    0xe0
-#  define APB_PCI_CTL_LOW_ARB_PARK                     (1 << 21)
-#  define APB_PCI_CTL_LOW_ERRINT_EN                    (1 << 8)
-
-#define APB_PCI_CONTROL_HIGH                   0xe4
-#  define APB_PCI_CTL_HIGH_SERR                                (1 << 2)
-#  define APB_PCI_CTL_HIGH_ARBITER_EN                  (1 << 0)
-
-#define APB_PIO_ASFR                           0xe8
-#define APB_PIO_AFAR                           0xf0
-#define APB_DIAG_REGISTER                      0xf8
-
-#endif /* !(_SPARC64_APB_H) */
+#include <asm-sparc/apb.h>
index bc57c405e7d36bee6951ea070e7d29ce5eb57def..9b7110c516e8eaf0b8b16b72068fbb16ffd737b1 100644 (file)
@@ -1,160 +1 @@
-#ifndef _SPARC64_ASI_H
-#define _SPARC64_ASI_H
-
-/* asi.h:  Address Space Identifier values for the V9.
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-/* V9 Architecture mandary ASIs. */
-#define ASI_N                  0x04 /* Nucleus                         */
-#define ASI_NL                 0x0c /* Nucleus, little endian          */
-#define ASI_AIUP               0x10 /* Primary, user                   */
-#define ASI_AIUS               0x11 /* Secondary, user                 */
-#define ASI_AIUPL              0x18 /* Primary, user, little endian    */
-#define ASI_AIUSL              0x19 /* Secondary, user, little endian  */
-#define ASI_P                  0x80 /* Primary, implicit               */
-#define ASI_S                  0x81 /* Secondary, implicit             */
-#define ASI_PNF                        0x82 /* Primary, no fault               */
-#define ASI_SNF                        0x83 /* Secondary, no fault             */
-#define ASI_PL                 0x88 /* Primary, implicit, l-endian     */
-#define ASI_SL                 0x89 /* Secondary, implicit, l-endian   */
-#define ASI_PNFL               0x8a /* Primary, no fault, l-endian     */
-#define ASI_SNFL               0x8b /* Secondary, no fault, l-endian   */
-
-/* SpitFire and later extended ASIs.  The "(III)" marker designates
- * UltraSparc-III and later specific ASIs.  The "(CMT)" marker designates
- * Chip Multi Threading specific ASIs.  "(NG)" designates Niagara specific
- * ASIs, "(4V)" designates SUN4V specific ASIs.
- */
-#define ASI_PHYS_USE_EC                0x14 /* PADDR, E-cachable               */
-#define ASI_PHYS_BYPASS_EC_E   0x15 /* PADDR, E-bit                    */
-#define ASI_BLK_AIUP_4V                0x16 /* (4V) Prim, user, block ld/st    */
-#define ASI_BLK_AIUS_4V                0x17 /* (4V) Sec, user, block ld/st     */
-#define ASI_PHYS_USE_EC_L      0x1c /* PADDR, E-cachable, little endian*/
-#define ASI_PHYS_BYPASS_EC_E_L 0x1d /* PADDR, E-bit, little endian     */
-#define ASI_BLK_AIUP_L_4V      0x1e /* (4V) Prim, user, block, l-endian*/
-#define ASI_BLK_AIUS_L_4V      0x1f /* (4V) Sec, user, block, l-endian */
-#define ASI_SCRATCHPAD         0x20 /* (4V) Scratch Pad Registers      */
-#define ASI_MMU                        0x21 /* (4V) MMU Context Registers      */
-#define ASI_BLK_INIT_QUAD_LDD_AIUS 0x23 /* (NG) init-store, twin load,
-                                        * secondary, user
-                                        */
-#define ASI_NUCLEUS_QUAD_LDD   0x24 /* Cachable, qword load            */
-#define ASI_QUEUE              0x25 /* (4V) Interrupt Queue Registers  */
-#define ASI_QUAD_LDD_PHYS_4V   0x26 /* (4V) Physical, qword load       */
-#define ASI_NUCLEUS_QUAD_LDD_L 0x2c /* Cachable, qword load, l-endian  */
-#define ASI_QUAD_LDD_PHYS_L_4V 0x2e /* (4V) Phys, qword load, l-endian */
-#define ASI_PCACHE_DATA_STATUS 0x30 /* (III) PCache data stat RAM diag */
-#define ASI_PCACHE_DATA                0x31 /* (III) PCache data RAM diag      */
-#define ASI_PCACHE_TAG         0x32 /* (III) PCache tag RAM diag       */
-#define ASI_PCACHE_SNOOP_TAG   0x33 /* (III) PCache snoop tag RAM diag */
-#define ASI_QUAD_LDD_PHYS      0x34 /* (III+) PADDR, qword load        */
-#define ASI_WCACHE_VALID_BITS  0x38 /* (III) WCache Valid Bits diag    */
-#define ASI_WCACHE_DATA                0x39 /* (III) WCache data RAM diag      */
-#define ASI_WCACHE_TAG         0x3a /* (III) WCache tag RAM diag       */
-#define ASI_WCACHE_SNOOP_TAG   0x3b /* (III) WCache snoop tag RAM diag */
-#define ASI_QUAD_LDD_PHYS_L    0x3c /* (III+) PADDR, qw-load, l-endian */
-#define ASI_SRAM_FAST_INIT     0x40 /* (III+) Fast SRAM init           */
-#define ASI_CORE_AVAILABLE     0x41 /* (CMT) LP Available              */
-#define ASI_CORE_ENABLE_STAT   0x41 /* (CMT) LP Enable Status          */
-#define ASI_CORE_ENABLE                0x41 /* (CMT) LP Enable RW              */
-#define ASI_XIR_STEERING       0x41 /* (CMT) XIR Steering RW           */
-#define ASI_CORE_RUNNING_RW    0x41 /* (CMT) LP Running RW             */
-#define ASI_CORE_RUNNING_W1S   0x41 /* (CMT) LP Running Write-One Set  */
-#define ASI_CORE_RUNNING_W1C   0x41 /* (CMT) LP Running Write-One Clr  */
-#define ASI_CORE_RUNNING_STAT  0x41 /* (CMT) LP Running Status         */
-#define ASI_CMT_ERROR_STEERING 0x41 /* (CMT) Error Steering RW         */
-#define ASI_DCACHE_INVALIDATE  0x42 /* (III) DCache Invalidate diag    */
-#define ASI_DCACHE_UTAG                0x43 /* (III) DCache uTag diag          */
-#define ASI_DCACHE_SNOOP_TAG   0x44 /* (III) DCache snoop tag RAM diag */
-#define ASI_LSU_CONTROL                0x45 /* Load-store control unit         */
-#define ASI_DCU_CONTROL_REG    0x45 /* (III) DCache Unit Control reg   */
-#define ASI_DCACHE_DATA                0x46 /* DCache data-ram diag access     */
-#define ASI_DCACHE_TAG         0x47 /* Dcache tag/valid ram diag access*/
-#define ASI_INTR_DISPATCH_STAT 0x48 /* IRQ vector dispatch status      */
-#define ASI_INTR_RECEIVE       0x49 /* IRQ vector receive status       */
-#define ASI_UPA_CONFIG         0x4a /* UPA config space                */
-#define ASI_JBUS_CONFIG                0x4a /* (IIIi) JBUS Config Register     */
-#define ASI_SAFARI_CONFIG      0x4a /* (III) Safari Config Register    */
-#define ASI_SAFARI_ADDRESS     0x4a /* (III) Safari Address Register   */
-#define ASI_ESTATE_ERROR_EN    0x4b /* E-cache error enable space      */
-#define ASI_AFSR               0x4c /* Async fault status register     */
-#define ASI_AFAR               0x4d /* Async fault address register    */
-#define ASI_EC_TAG_DATA                0x4e /* E-cache tag/valid ram diag acc  */
-#define ASI_IMMU               0x50 /* Insn-MMU main register space    */
-#define ASI_IMMU_TSB_8KB_PTR   0x51 /* Insn-MMU 8KB TSB pointer reg    */
-#define ASI_IMMU_TSB_64KB_PTR  0x52 /* Insn-MMU 64KB TSB pointer reg   */
-#define ASI_ITLB_DATA_IN       0x54 /* Insn-MMU TLB data in reg        */
-#define ASI_ITLB_DATA_ACCESS   0x55 /* Insn-MMU TLB data access reg    */
-#define ASI_ITLB_TAG_READ      0x56 /* Insn-MMU TLB tag read reg       */
-#define ASI_IMMU_DEMAP         0x57 /* Insn-MMU TLB demap              */
-#define ASI_DMMU               0x58 /* Data-MMU main register space    */
-#define ASI_DMMU_TSB_8KB_PTR   0x59 /* Data-MMU 8KB TSB pointer reg    */
-#define ASI_DMMU_TSB_64KB_PTR  0x5a /* Data-MMU 16KB TSB pointer reg   */
-#define ASI_DMMU_TSB_DIRECT_PTR        0x5b /* Data-MMU TSB direct pointer reg */
-#define ASI_DTLB_DATA_IN       0x5c /* Data-MMU TLB data in reg        */
-#define ASI_DTLB_DATA_ACCESS   0x5d /* Data-MMU TLB data access reg    */
-#define ASI_DTLB_TAG_READ      0x5e /* Data-MMU TLB tag read reg       */
-#define ASI_DMMU_DEMAP         0x5f /* Data-MMU TLB demap              */
-#define ASI_IIU_INST_TRAP      0x60 /* (III) Instruction Breakpoint    */
-#define ASI_INTR_ID            0x63 /* (CMT) Interrupt ID register     */
-#define ASI_CORE_ID            0x63 /* (CMT) LP ID register            */
-#define ASI_CESR_ID            0x63 /* (CMT) CESR ID register          */
-#define ASI_IC_INSTR           0x66 /* Insn cache instrucion ram diag  */
-#define ASI_IC_TAG             0x67 /* Insn cache tag/valid ram diag   */
-#define ASI_IC_STAG            0x68 /* (III) Insn cache snoop tag ram  */
-#define ASI_IC_PRE_DECODE      0x6e /* Insn cache pre-decode ram diag  */
-#define ASI_IC_NEXT_FIELD      0x6f /* Insn cache next-field ram diag  */
-#define ASI_BRPRED_ARRAY       0x6f /* (III) Branch Prediction RAM diag*/
-#define ASI_BLK_AIUP           0x70 /* Primary, user, block load/store */
-#define ASI_BLK_AIUS           0x71 /* Secondary, user, block ld/st    */
-#define ASI_MCU_CTRL_REG       0x72 /* (III) Memory controller regs    */
-#define ASI_EC_DATA            0x74 /* (III) E-cache data staging reg  */
-#define ASI_EC_CTRL            0x75 /* (III) E-cache control reg       */
-#define ASI_EC_W               0x76 /* E-cache diag write access       */
-#define ASI_UDB_ERROR_W                0x77 /* External UDB error regs W       */
-#define ASI_UDB_CONTROL_W      0x77 /* External UDB control regs W     */
-#define ASI_INTR_W             0x77 /* IRQ vector dispatch write       */
-#define ASI_INTR_DATAN_W       0x77 /* (III) Out irq vector data reg N */
-#define ASI_INTR_DISPATCH_W    0x77 /* (III) Interrupt vector dispatch */
-#define ASI_BLK_AIUPL          0x78 /* Primary, user, little, blk ld/st*/
-#define ASI_BLK_AIUSL          0x79 /* Secondary, user, little, blk ld/st*/
-#define ASI_EC_R               0x7e /* E-cache diag read access        */
-#define ASI_UDBH_ERROR_R       0x7f /* External UDB error regs rd hi   */
-#define ASI_UDBL_ERROR_R       0x7f /* External UDB error regs rd low  */
-#define ASI_UDBH_CONTROL_R     0x7f /* External UDB control regs rd hi */
-#define ASI_UDBL_CONTROL_R     0x7f /* External UDB control regs rd low*/
-#define ASI_INTR_R             0x7f /* IRQ vector dispatch read        */
-#define ASI_INTR_DATAN_R       0x7f /* (III) In irq vector data reg N  */
-#define ASI_PST8_P             0xc0 /* Primary, 8 8-bit, partial       */
-#define ASI_PST8_S             0xc1 /* Secondary, 8 8-bit, partial     */
-#define ASI_PST16_P            0xc2 /* Primary, 4 16-bit, partial      */
-#define ASI_PST16_S            0xc3 /* Secondary, 4 16-bit, partial    */
-#define ASI_PST32_P            0xc4 /* Primary, 2 32-bit, partial      */
-#define ASI_PST32_S            0xc5 /* Secondary, 2 32-bit, partial    */
-#define ASI_PST8_PL            0xc8 /* Primary, 8 8-bit, partial, L    */
-#define ASI_PST8_SL            0xc9 /* Secondary, 8 8-bit, partial, L  */
-#define ASI_PST16_PL           0xca /* Primary, 4 16-bit, partial, L   */
-#define ASI_PST16_SL           0xcb /* Secondary, 4 16-bit, partial, L */
-#define ASI_PST32_PL           0xcc /* Primary, 2 32-bit, partial, L   */
-#define ASI_PST32_SL           0xcd /* Secondary, 2 32-bit, partial, L */
-#define ASI_FL8_P              0xd0 /* Primary, 1 8-bit, fpu ld/st     */
-#define ASI_FL8_S              0xd1 /* Secondary, 1 8-bit, fpu ld/st   */
-#define ASI_FL16_P             0xd2 /* Primary, 1 16-bit, fpu ld/st    */
-#define ASI_FL16_S             0xd3 /* Secondary, 1 16-bit, fpu ld/st  */
-#define ASI_FL8_PL             0xd8 /* Primary, 1 8-bit, fpu ld/st, L  */
-#define ASI_FL8_SL             0xd9 /* Secondary, 1 8-bit, fpu ld/st, L*/
-#define ASI_FL16_PL            0xda /* Primary, 1 16-bit, fpu ld/st, L */
-#define ASI_FL16_SL            0xdb /* Secondary, 1 16-bit, fpu ld/st,L*/
-#define ASI_BLK_COMMIT_P       0xe0 /* Primary, blk store commit       */
-#define ASI_BLK_COMMIT_S       0xe1 /* Secondary, blk store commit     */
-#define ASI_BLK_INIT_QUAD_LDD_P        0xe2 /* (NG) init-store, twin load,
-                                     * primary, implicit
-                                     */
-#define ASI_BLK_P              0xf0 /* Primary, blk ld/st              */
-#define ASI_BLK_S              0xf1 /* Secondary, blk ld/st            */
-#define ASI_BLK_PL             0xf8 /* Primary, blk ld/st, little      */
-#define ASI_BLK_SL             0xf9 /* Secondary, blk ld/st, little    */
-
-#endif /* _SPARC64_ASI_H */
+#include <asm-sparc/asi.h>
index 2c71ec4a3b180930f53bcbec979527d3f28d3f97..f5126826ba342e0b3bd0b1f62070c05317fe4dc5 100644 (file)
@@ -1,128 +1 @@
-/* atomic.h: Thankfully the V9 is at least reasonable for this
- *           stuff.
- *
- * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com)
- */
-
-#ifndef __ARCH_SPARC64_ATOMIC__
-#define __ARCH_SPARC64_ATOMIC__
-
-#include <linux/types.h>
-#include <asm/system.h>
-
-typedef struct { volatile int counter; } atomic_t;
-typedef struct { volatile __s64 counter; } atomic64_t;
-
-#define ATOMIC_INIT(i)         { (i) }
-#define ATOMIC64_INIT(i)       { (i) }
-
-#define atomic_read(v)         ((v)->counter)
-#define atomic64_read(v)       ((v)->counter)
-
-#define atomic_set(v, i)       (((v)->counter) = i)
-#define atomic64_set(v, i)     (((v)->counter) = i)
-
-extern void atomic_add(int, atomic_t *);
-extern void atomic64_add(int, atomic64_t *);
-extern void atomic_sub(int, atomic_t *);
-extern void atomic64_sub(int, atomic64_t *);
-
-extern int atomic_add_ret(int, atomic_t *);
-extern int atomic64_add_ret(int, atomic64_t *);
-extern int atomic_sub_ret(int, atomic_t *);
-extern int atomic64_sub_ret(int, atomic64_t *);
-
-#define atomic_dec_return(v) atomic_sub_ret(1, v)
-#define atomic64_dec_return(v) atomic64_sub_ret(1, v)
-
-#define atomic_inc_return(v) atomic_add_ret(1, v)
-#define atomic64_inc_return(v) atomic64_add_ret(1, v)
-
-#define atomic_sub_return(i, v) atomic_sub_ret(i, v)
-#define atomic64_sub_return(i, v) atomic64_sub_ret(i, v)
-
-#define atomic_add_return(i, v) atomic_add_ret(i, v)
-#define atomic64_add_return(i, v) atomic64_add_ret(i, v)
-
-/*
- * atomic_inc_and_test - increment and test
- * @v: pointer of type atomic_t
- *
- * Atomically increments @v by 1
- * and returns true if the result is zero, or false for all
- * other cases.
- */
-#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
-#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
-
-#define atomic_sub_and_test(i, v) (atomic_sub_ret(i, v) == 0)
-#define atomic64_sub_and_test(i, v) (atomic64_sub_ret(i, v) == 0)
-
-#define atomic_dec_and_test(v) (atomic_sub_ret(1, v) == 0)
-#define atomic64_dec_and_test(v) (atomic64_sub_ret(1, v) == 0)
-
-#define atomic_inc(v) atomic_add(1, v)
-#define atomic64_inc(v) atomic64_add(1, v)
-
-#define atomic_dec(v) atomic_sub(1, v)
-#define atomic64_dec(v) atomic64_sub(1, v)
-
-#define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0)
-#define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0)
-
-#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-
-static inline int atomic_add_unless(atomic_t *v, int a, int u)
-{
-       int c, old;
-       c = atomic_read(v);
-       for (;;) {
-               if (unlikely(c == (u)))
-                       break;
-               old = atomic_cmpxchg((v), c, c + (a));
-               if (likely(old == c))
-                       break;
-               c = old;
-       }
-       return c != (u);
-}
-
-#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
-
-#define atomic64_cmpxchg(v, o, n) \
-       ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
-#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
-
-static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
-{
-       long c, old;
-       c = atomic64_read(v);
-       for (;;) {
-               if (unlikely(c == (u)))
-                       break;
-               old = atomic64_cmpxchg((v), c, c + (a));
-               if (likely(old == c))
-                       break;
-               c = old;
-       }
-       return c != (u);
-}
-
-#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
-
-/* Atomic operations are already serializing */
-#ifdef CONFIG_SMP
-#define smp_mb__before_atomic_dec()    membar_storeload_loadload();
-#define smp_mb__after_atomic_dec()     membar_storeload_storestore();
-#define smp_mb__before_atomic_inc()    membar_storeload_loadload();
-#define smp_mb__after_atomic_inc()     membar_storeload_storestore();
-#else
-#define smp_mb__before_atomic_dec()    barrier()
-#define smp_mb__after_atomic_dec()     barrier()
-#define smp_mb__before_atomic_inc()    barrier()
-#define smp_mb__after_atomic_inc()     barrier()
-#endif
-
-#include <asm-generic/atomic.h>
-#endif /* !(__ARCH_SPARC64_ATOMIC__) */
+#include <asm-sparc/atomic.h>
index c4100494c7a5073016dd76064ac40029063ef9ca..46c9042f30b4d75c7f42387863a499c0659175a8 100644 (file)
@@ -1,100 +1 @@
-/*
- * auxio.h:  Definitions and code for the Auxiliary I/O registers.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- *
- * Refactoring for unified NCR/PCIO support 2002 Eric Brower (ebrower@usa.net)
- */
-#ifndef _SPARC64_AUXIO_H
-#define _SPARC64_AUXIO_H
-
-/* AUXIO implementations:
- * sbus-based NCR89C105 "Slavio"
- *     LED/Floppy (AUX1) register
- *     Power (AUX2) register
- *
- * ebus-based auxio on PCIO 
- *     LED Auxio Register
- *     Power Auxio Register
- *
- * Register definitions from NCR _NCR89C105 Chip Specification_
- * 
- * SLAVIO AUX1 @ 0x1900000
- * -------------------------------------------------
- * | (R) | (R) |  D  | (R) |  E  |  M  |  T  |  L  |
- * -------------------------------------------------
- * (R) - bit 7:6,4 are reserved and should be masked in s/w
- *  D  - Floppy Density Sense (1=high density) R/O
- *  E  - Link Test Enable, directly reflected on AT&T 7213 LTE pin
- *  M  - Monitor/Mouse Mux, directly reflected on MON_MSE_MUX pin
- *  T  - Terminal Count: sends TC pulse to 82077 floppy controller
- *  L  - System LED on front panel (0=off, 1=on) 
- */
-#define AUXIO_AUX1_MASK                0xc0 /* Mask bits               */
-#define AUXIO_AUX1_FDENS       0x20 /* Floppy Density Sense    */
-#define AUXIO_AUX1_LTE                 0x08 /* Link Test Enable        */
-#define AUXIO_AUX1_MMUX                0x04 /* Monitor/Mouse Mux       */
-#define AUXIO_AUX1_FTCNT       0x02 /* Terminal Count,         */
-#define AUXIO_AUX1_LED         0x01 /* System LED              */
-
-/* SLAVIO AUX2 @ 0x1910000
- * -------------------------------------------------
- * | (R) | (R) |  D  | (R) | (R) | (R) |  C  |  F  |
- * -------------------------------------------------
- * (R) - bits 7:6,4:2 are reserved and should be masked in s/w
- *  D  - Power Failure Detect (1=power fail)
- *  C  - Clear Power Failure Detect Int (1=clear)
- *  F  - Power Off (1=power off)
- */
-#define AUXIO_AUX2_MASK                0xdc /* Mask Bits               */
-#define AUXIO_AUX2_PFAILDET    0x20 /* Power Fail Detect       */
-#define AUXIO_AUX2_PFAILCLR    0x02 /* Clear Pwr Fail Det Intr */
-#define AUXIO_AUX2_PWR_OFF     0x01 /* Power Off               */
-
-/* Register definitions from Sun Microsystems _PCIO_ p/n 802-7837
- *
- * PCIO LED Auxio @ 0x726000
- * -------------------------------------------------
- * |             31:1 Unused                 | LED |
- * -------------------------------------------------
- * Bits 31:1 unused
- * LED - System LED on front panel (0=off, 1=on)
- */
-#define AUXIO_PCIO_LED         0x01 /* System LED              */ 
-
-/* PCIO Power Auxio @ 0x724000
- * -------------------------------------------------
- * |             31:2 Unused           | CPO | SPO |
- * -------------------------------------------------
- * Bits 31:2 unused
- * CPO - Courtesy Power Off (1=off)
- * SPO - System Power Off   (1=off)
- */
-#define AUXIO_PCIO_CPWR_OFF    0x02 /* Courtesy Power Off      */
-#define AUXIO_PCIO_SPWR_OFF    0x01 /* System Power Off        */
-
-#ifndef __ASSEMBLY__
-
-extern void __iomem *auxio_register;
-
-#define AUXIO_LTE_ON   1
-#define AUXIO_LTE_OFF  0
-
-/* auxio_set_lte - Set Link Test Enable (TPE Link Detect)
- *
- * on - AUXIO_LTE_ON or AUXIO_LTE_OFF
- */
-extern void auxio_set_lte(int on);
-
-#define AUXIO_LED_ON   1
-#define AUXIO_LED_OFF  0
-
-/* auxio_set_led - Set system front panel LED 
- *
- * on - AUXIO_LED_ON or AUXIO_LED_OFF
- */
-extern void auxio_set_led(int on);
-
-#endif /* ifndef __ASSEMBLY__ */ 
-
-#endif /* !(_SPARC64_AUXIO_H) */
+#include <asm-sparc/auxio.h>
index fa1fdf67e350e07d950107289f25bdf3c41a73b3..8ee26d947e0e73a8da975e9eacb746f1d26e8253 100644 (file)
@@ -1,31 +1 @@
-#ifndef _SPARC64_BACKOFF_H
-#define _SPARC64_BACKOFF_H
-
-#define BACKOFF_LIMIT  (4 * 1024)
-
-#ifdef CONFIG_SMP
-
-#define BACKOFF_SETUP(reg)     \
-       mov     1, reg
-
-#define BACKOFF_SPIN(reg, tmp, label)  \
-       mov     reg, tmp; \
-88:    brnz,pt tmp, 88b; \
-        sub    tmp, 1, tmp; \
-       set     BACKOFF_LIMIT, tmp; \
-       cmp     reg, tmp; \
-       bg,pn   %xcc, label; \
-        nop; \
-       ba,pt   %xcc, label; \
-        sllx   reg, 1, reg;
-
-#else
-
-#define BACKOFF_SETUP(reg)
-#define BACKOFF_SPIN(reg, tmp, label) \
-       ba,pt   %xcc, label; \
-        nop;
-
-#endif
-
-#endif /* _SPARC64_BACKOFF_H */
+#include <asm-sparc/backoff.h>
index 423a85800aaef06515eee56bb623ab83eda1d4ca..06e8b63065148179561f711f245d1af6af84fe1a 100644 (file)
@@ -1,225 +1 @@
-/*
- * bbc.h: Defines for BootBus Controller found on UltraSPARC-III
- *        systems.
- *
- * Copyright (C) 2000 David S. Miller (davem@redhat.com)
- */
-
-#ifndef _SPARC64_BBC_H
-#define _SPARC64_BBC_H
-
-/* Register sizes are indicated by "B" (Byte, 1-byte),
- * "H" (Half-word, 2 bytes), "W" (Word, 4 bytes) or
- * "Q" (Quad, 8 bytes) inside brackets.
- */
-
-#define BBC_AID                0x00    /* [B] Agent ID                 */
-#define BBC_DEVP       0x01    /* [B] Device Present           */
-#define BBC_ARB                0x02    /* [B] Arbitration              */
-#define BBC_QUIESCE    0x03    /* [B] Quiesce                  */
-#define BBC_WDACTION   0x04    /* [B] Watchdog Action          */
-#define BBC_SPG                0x06    /* [B] Soft POR Gen             */
-#define BBC_SXG                0x07    /* [B] Soft XIR Gen             */
-#define BBC_PSRC       0x08    /* [W] POR Source               */
-#define BBC_XSRC       0x0c    /* [B] XIR Source               */
-#define BBC_CSC                0x0d    /* [B] Clock Synthesizers Control*/
-#define BBC_ES_CTRL    0x0e    /* [H] Energy Star Control      */
-#define BBC_ES_ACT     0x10    /* [W] E* Assert Change Time    */
-#define BBC_ES_DACT    0x14    /* [B] E* De-Assert Change Time */
-#define BBC_ES_DABT    0x15    /* [B] E* De-Assert Bypass Time */
-#define BBC_ES_ABT     0x16    /* [H] E* Assert Bypass Time    */
-#define BBC_ES_PST     0x18    /* [W] E* PLL Settle Time       */
-#define BBC_ES_FSL     0x1c    /* [W] E* Frequency Switch Latency*/
-#define BBC_EBUST      0x20    /* [Q] EBUS Timing              */
-#define BBC_JTAG_CMD   0x28    /* [W] JTAG+ Command            */
-#define BBC_JTAG_CTRL  0x2c    /* [B] JTAG+ Control            */
-#define BBC_I2C_SEL    0x2d    /* [B] I2C Selection            */
-#define BBC_I2C_0_S1   0x2e    /* [B] I2C ctrlr-0 reg S1       */
-#define BBC_I2C_0_S0   0x2f    /* [B] I2C ctrlr-0 regs S0,S0',S2,S3*/
-#define BBC_I2C_1_S1   0x30    /* [B] I2C ctrlr-1 reg S1       */
-#define BBC_I2C_1_S0   0x31    /* [B] I2C ctrlr-1 regs S0,S0',S2,S3*/
-#define BBC_KBD_BEEP   0x32    /* [B] Keyboard Beep            */
-#define BBC_KBD_BCNT   0x34    /* [W] Keyboard Beep Counter    */
-
-#define BBC_REGS_SIZE  0x40
-
-/* There is a 2K scratch ram area at offset 0x80000 but I doubt
- * we will use it for anything.
- */
-
-/* Agent ID register.  This register shows the Safari Agent ID
- * for the processors.  The value returned depends upon which
- * cpu is reading the register.
- */
-#define BBC_AID_ID     0x07    /* Safari ID            */
-#define BBC_AID_RESV   0xf8    /* Reserved             */
-
-/* Device Present register.  One can determine which cpus are actually
- * present in the machine by interrogating this register.
- */
-#define BBC_DEVP_CPU0  0x01    /* Processor 0 present  */
-#define BBC_DEVP_CPU1  0x02    /* Processor 1 present  */
-#define BBC_DEVP_CPU2  0x04    /* Processor 2 present  */
-#define BBC_DEVP_CPU3  0x08    /* Processor 3 present  */
-#define BBC_DEVP_RESV  0xf0    /* Reserved             */
-
-/* Arbitration register.  This register is used to block access to
- * the BBC from a particular cpu.
- */
-#define BBC_ARB_CPU0   0x01    /* Enable cpu 0 BBC arbitratrion */
-#define BBC_ARB_CPU1   0x02    /* Enable cpu 1 BBC arbitratrion */
-#define BBC_ARB_CPU2   0x04    /* Enable cpu 2 BBC arbitratrion */
-#define BBC_ARB_CPU3   0x08    /* Enable cpu 3 BBC arbitratrion */
-#define BBC_ARB_RESV   0xf0    /* Reserved                      */
-
-/* Quiesce register.  Bus and BBC segments for cpus can be disabled
- * with this register, ie. for hot plugging.
- */
-#define BBC_QUIESCE_S02        0x01    /* Quiesce Safari segment for cpu 0 and 2 */
-#define BBC_QUIESCE_S13        0x02    /* Quiesce Safari segment for cpu 1 and 3 */
-#define BBC_QUIESCE_B02        0x04    /* Quiesce BBC segment for cpu 0 and 2    */
-#define BBC_QUIESCE_B13        0x08    /* Quiesce BBC segment for cpu 1 and 3    */
-#define BBC_QUIESCE_FD0 0x10   /* Disable Fatal_Error[0] reporting       */
-#define BBC_QUIESCE_FD1 0x20   /* Disable Fatal_Error[1] reporting       */
-#define BBC_QUIESCE_FD2 0x40   /* Disable Fatal_Error[2] reporting       */
-#define BBC_QUIESCE_FD3 0x80   /* Disable Fatal_Error[3] reporting       */
-
-/* Watchdog Action register.  When the watchdog device timer expires
- * a line is enabled to the BBC.  The action BBC takes when this line
- * is asserted can be controlled by this regiser.
- */
-#define BBC_WDACTION_RST  0x01 /* When set, watchdog causes system reset.
-                                * When clear, BBC ignores watchdog signal.
-                                */
-#define BBC_WDACTION_RESV 0xfe /* Reserved */
-
-/* Soft_POR_GEN register.  The POR (Power On Reset) signal may be asserted
- * for specific processors or all processors via this register.
- */
-#define BBC_SPG_CPU0   0x01 /* Assert POR for processor 0      */
-#define BBC_SPG_CPU1   0x02 /* Assert POR for processor 1      */
-#define BBC_SPG_CPU2   0x04 /* Assert POR for processor 2      */
-#define BBC_SPG_CPU3   0x08 /* Assert POR for processor 3      */
-#define BBC_SPG_CPUALL 0x10 /* Reset all processors and reset
-                             * the entire system.
-                             */
-#define BBC_SPG_RESV   0xe0 /* Reserved                        */
-
-/* Soft_XIR_GEN register.  The XIR (eXternally Initiated Reset) signal
- * may be asserted to specific processors via this register.
- */
-#define BBC_SXG_CPU0   0x01 /* Assert XIR for processor 0      */
-#define BBC_SXG_CPU1   0x02 /* Assert XIR for processor 1      */
-#define BBC_SXG_CPU2   0x04 /* Assert XIR for processor 2      */
-#define BBC_SXG_CPU3   0x08 /* Assert XIR for processor 3      */
-#define BBC_SXG_RESV   0xf0 /* Reserved                        */
-
-/* POR Source register.  One may identify the cause of the most recent
- * reset by reading this register.
- */
-#define BBC_PSRC_SPG0  0x0001 /* CPU 0 reset via BBC_SPG register      */
-#define BBC_PSRC_SPG1  0x0002 /* CPU 1 reset via BBC_SPG register      */
-#define BBC_PSRC_SPG2  0x0004 /* CPU 2 reset via BBC_SPG register      */
-#define BBC_PSRC_SPG3  0x0008 /* CPU 3 reset via BBC_SPG register      */
-#define BBC_PSRC_SPGSYS        0x0010 /* System reset via BBC_SPG register     */
-#define BBC_PSRC_JTAG  0x0020 /* System reset via JTAG+                */
-#define BBC_PSRC_BUTTON        0x0040 /* System reset via push-button dongle   */
-#define BBC_PSRC_PWRUP 0x0080 /* System reset via power-up             */
-#define BBC_PSRC_FE0   0x0100 /* CPU 0 reported Fatal_Error            */
-#define BBC_PSRC_FE1   0x0200 /* CPU 1 reported Fatal_Error            */
-#define BBC_PSRC_FE2   0x0400 /* CPU 2 reported Fatal_Error            */
-#define BBC_PSRC_FE3   0x0800 /* CPU 3 reported Fatal_Error            */
-#define BBC_PSRC_FE4   0x1000 /* Schizo reported Fatal_Error           */
-#define BBC_PSRC_FE5   0x2000 /* Safari device 5 reported Fatal_Error  */
-#define BBC_PSRC_FE6   0x4000 /* CPMS reported Fatal_Error             */
-#define BBC_PSRC_SYNTH 0x8000 /* System reset when on-board clock synthesizers
-                               * were updated.
-                               */
-#define BBC_PSRC_WDT   0x10000 /* System reset via Super I/O watchdog  */
-#define BBC_PSRC_RSC   0x20000 /* System reset via RSC remote monitoring
-                               * device
-                               */
-
-/* XIR Source register.  The source of an XIR event sent to a processor may
- * be determined via this register.
- */
-#define BBC_XSRC_SXG0  0x01    /* CPU 0 received XIR via Soft_XIR_GEN reg */
-#define BBC_XSRC_SXG1  0x02    /* CPU 1 received XIR via Soft_XIR_GEN reg */
-#define BBC_XSRC_SXG2  0x04    /* CPU 2 received XIR via Soft_XIR_GEN reg */
-#define BBC_XSRC_SXG3  0x08    /* CPU 3 received XIR via Soft_XIR_GEN reg */
-#define BBC_XSRC_JTAG  0x10    /* All CPUs received XIR via JTAG+         */
-#define BBC_XSRC_W_OR_B        0x20    /* All CPUs received XIR either because:
-                                * a) Super I/O watchdog fired, or
-                                * b) XIR push button was activated
-                                */
-#define BBC_XSRC_RESV  0xc0    /* Reserved                                */
-
-/* Clock Synthesizers Control register.  This register provides the big-bang
- * programming interface to the two clock synthesizers of the machine.
- */
-#define BBC_CSC_SLOAD  0x01    /* Directly connected to S_LOAD pins    */
-#define BBC_CSC_SDATA  0x02    /* Directly connected to S_DATA pins    */
-#define BBC_CSC_SCLOCK 0x04    /* Directly connected to S_CLOCK pins   */
-#define BBC_CSC_RESV   0x78    /* Reserved                             */
-#define BBC_CSC_RST    0x80    /* Generate system reset when S_LOAD==1 */
-
-/* Energy Star Control register.  This register is used to generate the
- * clock frequency change trigger to the main system devices (Schizo and
- * the processors).  The transition occurs when bits in this register
- * go from 0 to 1, only one bit must be set at once else no action
- * occurs.  Basically the sequence of events is:
- * a) Choose new frequency: full, 1/2 or 1/32
- * b) Program this desired frequency into the cpus and Schizo.
- * c) Set the same value in this register.
- * d) 16 system clocks later, clear this register.
- */
-#define BBC_ES_CTRL_1_1                0x01    /* Full frequency       */
-#define BBC_ES_CTRL_1_2                0x02    /* 1/2 frequency        */
-#define BBC_ES_CTRL_1_32       0x20    /* 1/32 frequency       */
-#define BBC_ES_RESV            0xdc    /* Reserved             */
-
-/* Energy Star Assert Change Time register.  This determines the number
- * of BBC clock cycles (which is half the system frequency) between
- * the detection of FREEZE_ACK being asserted and the assertion of
- * the CLK_CHANGE_L[2:0] signals.
- */
-#define BBC_ES_ACT_VAL 0xff
-
-/* Energy Star Assert Bypass Time register.  This determines the number
- * of BBC clock cycles (which is half the system frequency) between
- * the assertion of the CLK_CHANGE_L[2:0] signals and the assertion of
- * the ESTAR_PLL_BYPASS signal.
- */
-#define BBC_ES_ABT_VAL 0xffff
-
-/* Energy Star PLL Settle Time register.  This determines the number of
- * BBC clock cycles (which is half the system frequency) between the
- * de-assertion of CLK_CHANGE_L[2:0] and the de-assertion of the FREEZE_L
- * signal.
- */
-#define BBC_ES_PST_VAL 0xffffffff
-
-/* Energy Star Frequency Switch Latency register.  This is the number of
- * BBC clocks between the de-assertion of CLK_CHANGE_L[2:0] and the first
- * edge of the Safari clock at the new frequency.
- */
-#define BBC_ES_FSL_VAL 0xffffffff
-
-/* Keyboard Beep control register.  This is a simple enabler for the audio
- * beep sound.
- */
-#define BBC_KBD_BEEP_ENABLE    0x01 /* Enable beep     */
-#define BBC_KBD_BEEP_RESV      0xfe /* Reserved        */
-
-/* Keyboard Beep Counter register.  There is a free-running counter inside
- * the BBC which runs at half the system clock.  The bit set in this register
- * determines when the audio sound is generated.  So for example if bit
- * 10 is set, the audio beep will oscillate at 1/(2**12).  The keyboard beep
- * generator automatically selects a different bit to use if the system clock
- * is changed via Energy Star.
- */
-#define BBC_KBD_BCNT_BITS      0x0007fc00
-#define BBC_KBC_BCNT_RESV      0xfff803ff
-
-#endif /* _SPARC64_BBC_H */
-
+#include <asm-sparc/bbc.h>
index bb87b80802200090d8f1e7476bd735d6a23d1b3f..204404355bddce9d43474123f2653c22fca99693 100644 (file)
@@ -1,107 +1 @@
-/*
- * bitops.h: Bit string operations on the V9.
- *
- * Copyright 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef _SPARC64_BITOPS_H
-#define _SPARC64_BITOPS_H
-
-#ifndef _LINUX_BITOPS_H
-#error only <linux/bitops.h> can be included directly
-#endif
-
-#include <linux/compiler.h>
-#include <asm/byteorder.h>
-
-extern int test_and_set_bit(unsigned long nr, volatile unsigned long *addr);
-extern int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr);
-extern int test_and_change_bit(unsigned long nr, volatile unsigned long *addr);
-extern void set_bit(unsigned long nr, volatile unsigned long *addr);
-extern void clear_bit(unsigned long nr, volatile unsigned long *addr);
-extern void change_bit(unsigned long nr, volatile unsigned long *addr);
-
-#include <asm-generic/bitops/non-atomic.h>
-
-#ifdef CONFIG_SMP
-#define smp_mb__before_clear_bit()     membar_storeload_loadload()
-#define smp_mb__after_clear_bit()      membar_storeload_storestore()
-#else
-#define smp_mb__before_clear_bit()     barrier()
-#define smp_mb__after_clear_bit()      barrier()
-#endif
-
-#include <asm-generic/bitops/ffz.h>
-#include <asm-generic/bitops/__ffs.h>
-#include <asm-generic/bitops/fls.h>
-#include <asm-generic/bitops/__fls.h>
-#include <asm-generic/bitops/fls64.h>
-
-#ifdef __KERNEL__
-
-#include <asm-generic/bitops/sched.h>
-#include <asm-generic/bitops/ffs.h>
-
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
-
-#ifdef ULTRA_HAS_POPULATION_COUNT
-
-static inline unsigned int hweight64(unsigned long w)
-{
-       unsigned int res;
-
-       __asm__ ("popc %1,%0" : "=r" (res) : "r" (w));
-       return res;
-}
-
-static inline unsigned int hweight32(unsigned int w)
-{
-       unsigned int res;
-
-       __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff));
-       return res;
-}
-
-static inline unsigned int hweight16(unsigned int w)
-{
-       unsigned int res;
-
-       __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff));
-       return res;
-}
-
-static inline unsigned int hweight8(unsigned int w)
-{
-       unsigned int res;
-
-       __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff));
-       return res;
-}
-
-#else
-
-#include <asm-generic/bitops/hweight.h>
-
-#endif
-#include <asm-generic/bitops/lock.h>
-#endif /* __KERNEL__ */
-
-#include <asm-generic/bitops/find.h>
-
-#ifdef __KERNEL__
-
-#include <asm-generic/bitops/ext2-non-atomic.h>
-
-#define ext2_set_bit_atomic(lock,nr,addr) \
-       test_and_set_bit((nr) ^ 0x38,(unsigned long *)(addr))
-#define ext2_clear_bit_atomic(lock,nr,addr) \
-       test_and_clear_bit((nr) ^ 0x38,(unsigned long *)(addr))
-
-#include <asm-generic/bitops/minix.h>
-
-#endif /* __KERNEL__ */
-
-#endif /* defined(_SPARC64_BITOPS_H) */
+#include <asm-sparc/bitops.h>
index 122e4058dd9ec745ecc3645c402cc1fd0c674dae..cf5b6b3e8a552407a27c6c0aa8272200d02af7c6 100644 (file)
@@ -1,76 +1 @@
-#ifndef _SPARC64_CACHEFLUSH_H
-#define _SPARC64_CACHEFLUSH_H
-
-#include <asm/page.h>
-
-#ifndef __ASSEMBLY__
-
-#include <linux/mm.h>
-
-/* Cache flush operations. */
-
-/* These are the same regardless of whether this is an SMP kernel or not. */
-#define flush_cache_mm(__mm) \
-       do { if ((__mm) == current->mm) flushw_user(); } while(0)
-#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
-#define flush_cache_range(vma, start, end) \
-       flush_cache_mm((vma)->vm_mm)
-#define flush_cache_page(vma, page, pfn) \
-       flush_cache_mm((vma)->vm_mm)
-
-/* 
- * On spitfire, the icache doesn't snoop local stores and we don't
- * use block commit stores (which invalidate icache lines) during
- * module load, so we need this.
- */
-extern void flush_icache_range(unsigned long start, unsigned long end);
-extern void __flush_icache_page(unsigned long);
-
-extern void __flush_dcache_page(void *addr, int flush_icache);
-extern void flush_dcache_page_impl(struct page *page);
-#ifdef CONFIG_SMP
-extern void smp_flush_dcache_page_impl(struct page *page, int cpu);
-extern void flush_dcache_page_all(struct mm_struct *mm, struct page *page);
-#else
-#define smp_flush_dcache_page_impl(page,cpu) flush_dcache_page_impl(page)
-#define flush_dcache_page_all(mm,page) flush_dcache_page_impl(page)
-#endif
-
-extern void __flush_dcache_range(unsigned long start, unsigned long end);
-extern void flush_dcache_page(struct page *page);
-
-#define flush_icache_page(vma, pg)     do { } while(0)
-#define flush_icache_user_range(vma,pg,adr,len)        do { } while (0)
-
-extern void flush_ptrace_access(struct vm_area_struct *, struct page *,
-                               unsigned long uaddr, void *kaddr,
-                               unsigned long len, int write);
-
-#define copy_to_user_page(vma, page, vaddr, dst, src, len)             \
-       do {                                                            \
-               flush_cache_page(vma, vaddr, page_to_pfn(page));        \
-               memcpy(dst, src, len);                                  \
-               flush_ptrace_access(vma, page, vaddr, src, len, 0);     \
-       } while (0)
-
-#define copy_from_user_page(vma, page, vaddr, dst, src, len)           \
-       do {                                                            \
-               flush_cache_page(vma, vaddr, page_to_pfn(page));        \
-               memcpy(dst, src, len);                                  \
-               flush_ptrace_access(vma, page, vaddr, dst, len, 1);     \
-       } while (0)
-
-#define flush_dcache_mmap_lock(mapping)                do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)      do { } while (0)
-
-#define flush_cache_vmap(start, end)           do { } while (0)
-#define flush_cache_vunmap(start, end)         do { } while (0)
-
-#ifdef CONFIG_DEBUG_PAGEALLOC
-/* internal debugging function */
-void kernel_map_pages(struct page *page, int numpages, int enable);
-#endif
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* _SPARC64_CACHEFLUSH_H */
+#include <asm-sparc/cacheflush.h>
index 85c69b38220b946dc9618f24fa4d4172c9c7bbeb..aaab97562a39799d0fc9e5e7e0ddbff186b7846e 100644 (file)
@@ -1,241 +1 @@
-#ifndef _SPARC64_CHAFSR_H
-#define _SPARC64_CHAFSR_H
-
-/* Cheetah Asynchronous Fault Status register, ASI=0x4C VA<63:0>=0x0 */
-
-/* Comments indicate which processor variants on which the bit definition
- * is valid.  Codes are:
- * ch  -->     cheetah
- * ch+ -->     cheetah plus
- * jp  -->     jalapeno
- */
-
-/* All bits of this register except M_SYNDROME and E_SYNDROME are
- * read, write 1 to clear.  M_SYNDROME and E_SYNDROME are read-only.
- */
-
-/* Software bit set by linux trap handlers to indicate that the trap was
- * signalled at %tl >= 1.
- */
-#define CHAFSR_TL1             (1UL << 63UL) /* n/a */
-
-/* Unmapped error from system bus for prefetch queue or
- * store queue read operation
- */
-#define CHPAFSR_DTO            (1UL << 59UL) /* ch+ */
-
-/* Bus error from system bus for prefetch queue or store queue
- * read operation
- */
-#define CHPAFSR_DBERR          (1UL << 58UL) /* ch+ */
-
-/* Hardware corrected E-cache Tag ECC error */
-#define CHPAFSR_THCE           (1UL << 57UL) /* ch+ */
-/* System interface protocol error, hw timeout caused */
-#define JPAFSR_JETO            (1UL << 57UL) /* jp */
-
-/* SW handled correctable E-cache Tag ECC error */
-#define CHPAFSR_TSCE           (1UL << 56UL) /* ch+ */
-/* Parity error on system snoop results */
-#define JPAFSR_SCE             (1UL << 56UL) /* jp */
-
-/* Uncorrectable E-cache Tag ECC error */
-#define CHPAFSR_TUE            (1UL << 55UL) /* ch+ */
-/* System interface protocol error, illegal command detected */
-#define JPAFSR_JEIC            (1UL << 55UL) /* jp */
-
-/* Uncorrectable system bus data ECC error due to prefetch
- * or store fill request
- */
-#define CHPAFSR_DUE            (1UL << 54UL) /* ch+ */
-/* System interface protocol error, illegal ADTYPE detected */
-#define JPAFSR_JEIT            (1UL << 54UL) /* jp */
-
-/* Multiple errors of the same type have occurred.  This bit is set when
- * an uncorrectable error or a SW correctable error occurs and the status
- * bit to report that error is already set.  When multiple errors of
- * different types are indicated by setting multiple status bits.
- *
- * This bit is not set if multiple HW corrected errors with the same
- * status bit occur, only uncorrectable and SW correctable ones have
- * this behavior.
- *
- * This bit is not set when multiple ECC errors happen within a single
- * 64-byte system bus transaction.  Only the first ECC error in a 16-byte
- * subunit will be logged.  All errors in subsequent 16-byte subunits
- * from the same 64-byte transaction are ignored.
- */
-#define CHAFSR_ME              (1UL << 53UL) /* ch,ch+,jp */
-
-/* Privileged state error has occurred.  This is a capture of PSTATE.PRIV
- * at the time the error is detected.
- */
-#define CHAFSR_PRIV            (1UL << 52UL) /* ch,ch+,jp */
-
-/* The following bits 51 (CHAFSR_PERR) to 33 (CHAFSR_CE) are sticky error
- * bits and record the most recently detected errors.  Bits accumulate
- * errors that have been detected since the last write to clear the bit.
- */
-
-/* System interface protocol error.  The processor asserts its' ERROR
- * pin when this event occurs and it also logs a specific cause code
- * into a JTAG scannable flop.
- */
-#define CHAFSR_PERR            (1UL << 51UL) /* ch,ch+,jp */
-
-/* Internal processor error.  The processor asserts its' ERROR
- * pin when this event occurs and it also logs a specific cause code
- * into a JTAG scannable flop.
- */
-#define CHAFSR_IERR            (1UL << 50UL) /* ch,ch+,jp */
-
-/* System request parity error on incoming address */
-#define CHAFSR_ISAP            (1UL << 49UL) /* ch,ch+,jp */
-
-/* HW Corrected system bus MTAG ECC error */
-#define CHAFSR_EMC             (1UL << 48UL) /* ch,ch+ */
-/* Parity error on L2 cache tag SRAM */
-#define JPAFSR_ETP             (1UL << 48UL) /* jp */
-
-/* Uncorrectable system bus MTAG ECC error */
-#define CHAFSR_EMU             (1UL << 47UL) /* ch,ch+ */
-/* Out of range memory error has occurred */
-#define JPAFSR_OM              (1UL << 47UL) /* jp */
-
-/* HW Corrected system bus data ECC error for read of interrupt vector */
-#define CHAFSR_IVC             (1UL << 46UL) /* ch,ch+ */
-/* Error due to unsupported store */
-#define JPAFSR_UMS             (1UL << 46UL) /* jp */
-
-/* Uncorrectable system bus data ECC error for read of interrupt vector */
-#define CHAFSR_IVU             (1UL << 45UL) /* ch,ch+,jp */
-
-/* Unmapped error from system bus */
-#define CHAFSR_TO              (1UL << 44UL) /* ch,ch+,jp */
-
-/* Bus error response from system bus */
-#define CHAFSR_BERR            (1UL << 43UL) /* ch,ch+,jp */
-
-/* SW Correctable E-cache ECC error for instruction fetch or data access
- * other than block load.
- */
-#define CHAFSR_UCC             (1UL << 42UL) /* ch,ch+,jp */
-
-/* Uncorrectable E-cache ECC error for instruction fetch or data access
- * other than block load.
- */
-#define CHAFSR_UCU             (1UL << 41UL) /* ch,ch+,jp */
-
-/* Copyout HW Corrected ECC error */
-#define CHAFSR_CPC             (1UL << 40UL) /* ch,ch+,jp */
-
-/* Copyout Uncorrectable ECC error */
-#define CHAFSR_CPU             (1UL << 39UL) /* ch,ch+,jp */
-
-/* HW Corrected ECC error from E-cache for writeback */
-#define CHAFSR_WDC             (1UL << 38UL) /* ch,ch+,jp */
-
-/* Uncorrectable ECC error from E-cache for writeback */
-#define CHAFSR_WDU             (1UL << 37UL) /* ch,ch+,jp */
-
-/* HW Corrected ECC error from E-cache for store merge or block load */
-#define CHAFSR_EDC             (1UL << 36UL) /* ch,ch+,jp */
-
-/* Uncorrectable ECC error from E-cache for store merge or block load */
-#define CHAFSR_EDU             (1UL << 35UL) /* ch,ch+,jp */
-
-/* Uncorrectable system bus data ECC error for read of memory or I/O */
-#define CHAFSR_UE              (1UL << 34UL) /* ch,ch+,jp */
-
-/* HW Corrected system bus data ECC error for read of memory or I/O */
-#define CHAFSR_CE              (1UL << 33UL) /* ch,ch+,jp */
-
-/* Uncorrectable ECC error from remote cache/memory */
-#define JPAFSR_RUE             (1UL << 32UL) /* jp */
-
-/* Correctable ECC error from remote cache/memory */
-#define JPAFSR_RCE             (1UL << 31UL) /* jp */
-
-/* JBUS parity error on returned read data */
-#define JPAFSR_BP              (1UL << 30UL) /* jp */
-
-/* JBUS parity error on data for writeback or block store */
-#define JPAFSR_WBP             (1UL << 29UL) /* jp */
-
-/* Foreign read to DRAM incurring correctable ECC error */
-#define JPAFSR_FRC             (1UL << 28UL) /* jp */
-
-/* Foreign read to DRAM incurring uncorrectable ECC error */
-#define JPAFSR_FRU             (1UL << 27UL) /* jp */
-
-#define CHAFSR_ERRORS          (CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \
-                                CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \
-                                CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \
-                                CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \
-                                CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE)
-#define CHPAFSR_ERRORS         (CHPAFSR_DTO | CHPAFSR_DBERR | CHPAFSR_THCE | \
-                                CHPAFSR_TSCE | CHPAFSR_TUE | CHPAFSR_DUE | \
-                                CHAFSR_PERR | CHAFSR_IERR | CHAFSR_ISAP | CHAFSR_EMC | \
-                                CHAFSR_EMU | CHAFSR_IVC | CHAFSR_IVU | CHAFSR_TO | \
-                                CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | CHAFSR_CPC | \
-                                CHAFSR_CPU | CHAFSR_WDC | CHAFSR_WDU | CHAFSR_EDC | \
-                                CHAFSR_EDU | CHAFSR_UE | CHAFSR_CE)
-#define JPAFSR_ERRORS          (JPAFSR_JETO | JPAFSR_SCE | JPAFSR_JEIC | \
-                                JPAFSR_JEIT | CHAFSR_PERR | CHAFSR_IERR | \
-                                CHAFSR_ISAP | JPAFSR_ETP | JPAFSR_OM | \
-                                JPAFSR_UMS | CHAFSR_IVU | CHAFSR_TO | \
-                                CHAFSR_BERR | CHAFSR_UCC | CHAFSR_UCU | \
-                                CHAFSR_CPC | CHAFSR_CPU | CHAFSR_WDC | \
-                                CHAFSR_WDU | CHAFSR_EDC | CHAFSR_EDU | \
-                                CHAFSR_UE | CHAFSR_CE | JPAFSR_RUE | \
-                                JPAFSR_RCE | JPAFSR_BP | JPAFSR_WBP | \
-                                JPAFSR_FRC | JPAFSR_FRU)
-
-/* Active JBUS request signal when error occurred */
-#define JPAFSR_JBREQ           (0x7UL << 24UL) /* jp */
-#define JPAFSR_JBREQ_SHIFT     24UL
-
-/* L2 cache way information */
-#define JPAFSR_ETW             (0x3UL << 22UL) /* jp */
-#define JPAFSR_ETW_SHIFT       22UL
-
-/* System bus MTAG ECC syndrome.  This field captures the status of the
- * first occurrence of the highest-priority error according to the M_SYND
- * overwrite policy.  After the AFSR sticky bit, corresponding to the error
- * for which the M_SYND is reported, is cleared, the contents of the M_SYND
- * field will be unchanged by will be unfrozen for further error capture.
- */
-#define CHAFSR_M_SYNDROME      (0xfUL << 16UL) /* ch,ch+,jp */
-#define CHAFSR_M_SYNDROME_SHIFT        16UL
-
-/* Agenid Id of the foreign device causing the UE/CE errors */
-#define JPAFSR_AID             (0x1fUL << 9UL) /* jp */
-#define JPAFSR_AID_SHIFT       9UL
-
-/* System bus or E-cache data ECC syndrome.  This field captures the status
- * of the first occurrence of the highest-priority error according to the
- * E_SYND overwrite policy.  After the AFSR sticky bit, corresponding to the
- * error for which the E_SYND is reported, is cleare, the contents of the E_SYND
- * field will be unchanged but will be unfrozen for further error capture.
- */
-#define CHAFSR_E_SYNDROME      (0x1ffUL << 0UL) /* ch,ch+,jp */
-#define CHAFSR_E_SYNDROME_SHIFT        0UL
-
-/* The AFSR must be explicitly cleared by software, it is not cleared automatically
- * by a read.  Writes to bits <51:33> with bits set will clear the corresponding
- * bits in the AFSR.  Bits associated with disrupting traps must be cleared before
- * interrupts are re-enabled to prevent multiple traps for the same error.  I.e.
- * PSTATE.IE and AFSR bits control delivery of disrupting traps.
- *
- * Since there is only one AFAR, when multiple events have been logged by the
- * bits in the AFSR, at most one of these events will have its status captured
- * in the AFAR.  The highest priority of those event bits will get AFAR logging.
- * The AFAR will be unlocked and available to capture the address of another event
- * as soon as the one bit in AFSR that corresponds to the event logged in AFAR is
- * cleared.  For example, if AFSR.CE is detected, then AFSR.UE (which overwrites
- * the AFAR), and AFSR.UE is cleared by not AFSR.CE, then the AFAR will be unlocked
- * and ready for another event, even though AFSR.CE is still set.  The same rules
- * also apply to the M_SYNDROME and E_SYNDROME fields of the AFSR.
- */
-
-#endif /* _SPARC64_CHAFSR_H */
+#include <asm-sparc/chafsr.h>
index b290564c8ce0dd86bde1cf0cfa3f65ee8e148b6b..c3966c5e29d8a11c4fb302572b2e31872f7dd669 100644 (file)
@@ -1,167 +1 @@
-#ifndef __SPARC64_CHECKSUM_H
-#define __SPARC64_CHECKSUM_H
-
-/*  checksum.h:  IP/UDP/TCP checksum routines on the V9.
- *
- *  Copyright(C) 1995 Linus Torvalds
- *  Copyright(C) 1995 Miguel de Icaza
- *  Copyright(C) 1996 David S. Miller
- *  Copyright(C) 1996 Eddie C. Dost
- *  Copyright(C) 1997 Jakub Jelinek
- *
- * derived from:
- *     Alpha checksum c-code
- *      ix86 inline assembly
- *      RFC1071 Computing the Internet Checksum
- */
-
-#include <linux/in6.h>
-#include <asm/uaccess.h>
-
-/* computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-extern __wsum csum_partial(const void * buff, int len, __wsum sum);
-
-/* the same as csum_partial, but copies from user space while it
- * checksums
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-extern __wsum csum_partial_copy_nocheck(const void *src, void *dst,
-                                             int len, __wsum sum);
-
-extern long __csum_partial_copy_from_user(const void __user *src,
-                                         void *dst, int len,
-                                         __wsum sum);
-
-static inline __wsum
-csum_partial_copy_from_user(const void __user *src,
-                           void *dst, int len,
-                           __wsum sum, int *err)
-{
-       long ret = __csum_partial_copy_from_user(src, dst, len, sum);
-       if (ret < 0)
-               *err = -EFAULT;
-       return (__force __wsum) ret;
-}
-
-/* 
- *     Copy and checksum to user
- */
-#define HAVE_CSUM_COPY_USER
-extern long __csum_partial_copy_to_user(const void *src,
-                                       void __user *dst, int len,
-                                         __wsum sum);
-
-static inline __wsum
-csum_and_copy_to_user(const void *src,
-                     void __user *dst, int len,
-                     __wsum sum, int *err)
-{
-       long ret = __csum_partial_copy_to_user(src, dst, len, sum);
-       if (ret < 0)
-               *err = -EFAULT;
-       return (__force __wsum) ret;
-}
-
-/* ihl is always 5 or greater, almost always is 5, and iph is word aligned
- * the majority of the time.
- */
-extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
-
-/* Fold a partial checksum without adding pseudo headers. */
-static inline __sum16 csum_fold(__wsum sum)
-{
-       unsigned int tmp;
-
-       __asm__ __volatile__(
-"      addcc           %0, %1, %1\n"
-"      srl             %1, 16, %1\n"
-"      addc            %1, %%g0, %1\n"
-"      xnor            %%g0, %1, %0\n"
-       : "=&r" (sum), "=r" (tmp)
-       : "0" (sum), "1" ((__force u32)sum<<16)
-       : "cc");
-       return (__force __sum16)sum;
-}
-
-static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
-                                              unsigned int len,
-                                              unsigned short proto,
-                                              __wsum sum)
-{
-       __asm__ __volatile__(
-"      addcc           %1, %0, %0\n"
-"      addccc          %2, %0, %0\n"
-"      addccc          %3, %0, %0\n"
-"      addc            %0, %%g0, %0\n"
-       : "=r" (sum), "=r" (saddr)
-       : "r" (daddr), "r" (proto + len), "0" (sum), "1" (saddr)
-       : "cc");
-       return sum;
-}
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
-                                                  unsigned short len,
-                                                  unsigned short proto,
-                                                  __wsum sum)
-{
-       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
-}
-
-#define _HAVE_ARCH_IPV6_CSUM
-
-static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
-                                     const struct in6_addr *daddr,
-                                     __u32 len, unsigned short proto,
-                                     __wsum sum)
-{
-       __asm__ __volatile__ (
-"      addcc           %3, %4, %%g7\n"
-"      addccc          %5, %%g7, %%g7\n"
-"      lduw            [%2 + 0x0c], %%g2\n"
-"      lduw            [%2 + 0x08], %%g3\n"
-"      addccc          %%g2, %%g7, %%g7\n"
-"      lduw            [%2 + 0x04], %%g2\n"
-"      addccc          %%g3, %%g7, %%g7\n"
-"      lduw            [%2 + 0x00], %%g3\n"
-"      addccc          %%g2, %%g7, %%g7\n"
-"      lduw            [%1 + 0x0c], %%g2\n"
-"      addccc          %%g3, %%g7, %%g7\n"
-"      lduw            [%1 + 0x08], %%g3\n"
-"      addccc          %%g2, %%g7, %%g7\n"
-"      lduw            [%1 + 0x04], %%g2\n"
-"      addccc          %%g3, %%g7, %%g7\n"
-"      lduw            [%1 + 0x00], %%g3\n"
-"      addccc          %%g2, %%g7, %%g7\n"
-"      addccc          %%g3, %%g7, %0\n"
-"      addc            0, %0, %0\n"
-       : "=&r" (sum)
-       : "r" (saddr), "r" (daddr), "r"(htonl(len)),
-         "r"(htonl(proto)), "r"(sum)
-       : "g2", "g3", "g7", "cc");
-
-       return csum_fold(sum);
-}
-
-/* this routine is used for miscellaneous IP-like checksums, mainly in icmp.c */
-static inline __sum16 ip_compute_csum(const void *buff, int len)
-{
-       return csum_fold(csum_partial(buff, len, 0));
-}
-
-#endif /* !(__SPARC64_CHECKSUM_H) */
+#include <asm-sparc/checksum.h>
index 859b4a4b0d3033f25d32f2b1230b5b22d6561537..eb757b483b309ff4227af290c5a79708ad46977f 100644 (file)
@@ -1,183 +1 @@
-#ifndef _SPARC64_CHMCTRL_H
-#define _SPARC64_CHMCTRL_H
-
-/* Cheetah memory controller programmable registers. */
-#define CHMCTRL_TCTRL1         0x00 /* Memory Timing Control I         */
-#define CHMCTRL_TCTRL2         0x08 /* Memory Timing Control II        */
-#define CHMCTRL_TCTRL3         0x38 /* Memory Timing Control III       */
-#define CHMCTRL_TCTRL4         0x40 /* Memory Timing Control IV        */
-#define CHMCTRL_DECODE1                0x10 /* Memory Address Decode I         */
-#define CHMCTRL_DECODE2                0x18 /* Memory Address Decode II        */
-#define CHMCTRL_DECODE3                0x20 /* Memory Address Decode III       */
-#define CHMCTRL_DECODE4                0x28 /* Memory Address Decode IV        */
-#define CHMCTRL_MACTRL         0x30 /* Memory Address Control          */
-
-/* Memory Timing Control I */
-#define TCTRL1_SDRAMCTL_DLY    0xf000000000000000UL
-#define TCTRL1_SDRAMCTL_DLY_SHIFT     60
-#define TCTRL1_SDRAMCLK_DLY    0x0e00000000000000UL
-#define TCTRL1_SDRAMCLK_DLY_SHIFT     57
-#define TCTRL1_R               0x0100000000000000UL
-#define TCTRL1_R_SHIFT                       56
-#define TCTRL1_AUTORFR_CYCLE   0x00fe000000000000UL
-#define TCTRL1_AUTORFR_CYCLE_SHIFT    49
-#define TCTRL1_RD_WAIT         0x0001f00000000000UL
-#define TCTRL1_RD_WAIT_SHIFT         44
-#define TCTRL1_PC_CYCLE                0x00000fc000000000UL
-#define TCTRL1_PC_CYCLE_SHIFT        38
-#define TCTRL1_WR_MORE_RAS_PW  0x0000003f00000000UL
-#define TCTRL1_WR_MORE_RAS_PW_SHIFT   32
-#define TCTRL1_RD_MORE_RAW_PW  0x00000000fc000000UL
-#define TCTRL1_RD_MORE_RAS_PW_SHIFT   26
-#define TCTRL1_ACT_WR_DLY      0x0000000003f00000UL
-#define TCTRL1_ACT_WR_DLY_SHIFT              20
-#define TCTRL1_ACT_RD_DLY      0x00000000000fc000UL
-#define TCTRL1_ACT_RD_DLY_SHIFT              14
-#define TCTRL1_BANK_PRESENT    0x0000000000003000UL
-#define TCTRL1_BANK_PRESENT_SHIFT     12
-#define TCTRL1_RFR_INT         0x0000000000000ff8UL
-#define TCTRL1_RFR_INT_SHIFT         3
-#define TCTRL1_SET_MODE_REG    0x0000000000000004UL
-#define TCTRL1_SET_MODE_REG_SHIFT     2
-#define TCTRL1_RFR_ENABLE      0x0000000000000002UL
-#define TCTRL1_RFR_ENABLE_SHIFT              1
-#define TCTRL1_PRECHG_ALL      0x0000000000000001UL
-#define TCTRL1_PRECHG_ALL_SHIFT              0
-
-/* Memory Timing Control II */
-#define TCTRL2_WR_MSEL_DLY     0xfc00000000000000UL
-#define TCTRL2_WR_MSEL_DLY_SHIFT      58
-#define TCTRL2_RD_MSEL_DLY     0x03f0000000000000UL
-#define TCTRL2_RD_MSEL_DLY_SHIFT      52
-#define TCTRL2_WRDATA_THLD     0x000c000000000000UL
-#define TCTRL2_WRDATA_THLD_SHIFT      50
-#define TCTRL2_RDWR_RD_TI_DLY  0x0003f00000000000UL
-#define TCTRL2_RDWR_RD_TI_DLY_SHIFT   44
-#define TCTRL2_AUTOPRECHG_ENBL 0x0000080000000000UL
-#define TCTRL2_AUTOPRECHG_ENBL_SHIFT  43
-#define TCTRL2_RDWR_PI_MORE_DLY        0x000007c000000000UL
-#define TCTRL2_RDWR_PI_MORE_DLY_SHIFT 38
-#define TCTRL2_RDWR_1_DLY      0x0000003f00000000UL
-#define TCTRL2_RDWR_1_DLY_SHIFT       32
-#define TCTRL2_WRWR_PI_MORE_DLY        0x00000000f8000000UL
-#define TCTRL2_WRWR_PI_MORE_DLY_SHIFT 27
-#define TCTRL2_WRWR_1_DLY      0x0000000007e00000UL
-#define TCTRL2_WRWR_1_DLY_SHIFT       21
-#define TCTRL2_RDWR_RD_PI_MORE_DLY 0x00000000001f0000UL
-#define TCTRL2_RDWR_RD_PI_MORE_DLY_SHIFT 16
-#define TCTRL2_R               0x0000000000008000UL
-#define TCTRL2_R_SHIFT               15
-#define TCTRL2_SDRAM_MODE_REG_DATA 0x0000000000007fffUL
-#define TCTRL2_SDRAM_MODE_REG_DATA_SHIFT 0
-
-/* Memory Timing Control III */
-#define TCTRL3_SDRAM_CTL_DLY   0xf000000000000000UL
-#define TCTRL3_SDRAM_CTL_DLY_SHIFT    60
-#define TCTRL3_SDRAM_CLK_DLY   0x0e00000000000000UL
-#define TCTRL3_SDRAM_CLK_DLY_SHIFT    57
-#define TCTRL3_R               0x0100000000000000UL
-#define TCTRL3_R_SHIFT               56
-#define TCTRL3_AUTO_RFR_CYCLE  0x00fe000000000000UL
-#define TCTRL3_AUTO_RFR_CYCLE_SHIFT   49
-#define TCTRL3_RD_WAIT         0x0001f00000000000UL
-#define TCTRL3_RD_WAIT_SHIFT         44
-#define TCTRL3_PC_CYCLE                0x00000fc000000000UL
-#define TCTRL3_PC_CYCLE_SHIFT        38
-#define TCTRL3_WR_MORE_RAW_PW  0x0000003f00000000UL
-#define TCTRL3_WR_MORE_RAW_PW_SHIFT   32
-#define TCTRL3_RD_MORE_RAW_PW  0x00000000fc000000UL
-#define TCTRL3_RD_MORE_RAW_PW_SHIFT   26
-#define TCTRL3_ACT_WR_DLY      0x0000000003f00000UL
-#define TCTRL3_ACT_WR_DLY_SHIFT       20
-#define TCTRL3_ACT_RD_DLY      0x00000000000fc000UL
-#define TCTRL3_ACT_RD_DLY_SHIFT       14
-#define TCTRL3_BANK_PRESENT    0x0000000000003000UL
-#define TCTRL3_BANK_PRESENT_SHIFT     12
-#define TCTRL3_RFR_INT         0x0000000000000ff8UL
-#define TCTRL3_RFR_INT_SHIFT         3
-#define TCTRL3_SET_MODE_REG    0x0000000000000004UL
-#define TCTRL3_SET_MODE_REG_SHIFT     2
-#define TCTRL3_RFR_ENABLE      0x0000000000000002UL
-#define TCTRL3_RFR_ENABLE_SHIFT       1
-#define TCTRL3_PRECHG_ALL      0x0000000000000001UL
-#define TCTRL3_PRECHG_ALL_SHIFT              0
-
-/* Memory Timing Control IV */
-#define TCTRL4_WR_MSEL_DLY     0xfc00000000000000UL
-#define TCTRL4_WR_MSEL_DLY_SHIFT      58
-#define TCTRL4_RD_MSEL_DLY     0x03f0000000000000UL
-#define TCTRL4_RD_MSEL_DLY_SHIFT      52
-#define TCTRL4_WRDATA_THLD     0x000c000000000000UL
-#define TCTRL4_WRDATA_THLD_SHIFT      50
-#define TCTRL4_RDWR_RD_RI_DLY  0x0003f00000000000UL
-#define TCTRL4_RDWR_RD_RI_DLY_SHIFT   44
-#define TCTRL4_AUTO_PRECHG_ENBL        0x0000080000000000UL
-#define TCTRL4_AUTO_PRECHG_ENBL_SHIFT 43
-#define TCTRL4_RD_WR_PI_MORE_DLY 0x000007c000000000UL
-#define TCTRL4_RD_WR_PI_MORE_DLY_SHIFT 38
-#define TCTRL4_RD_WR_TI_DLY    0x0000003f00000000UL
-#define TCTRL4_RD_WR_TI_DLY_SHIFT     32
-#define TCTRL4_WR_WR_PI_MORE_DLY 0x00000000f8000000UL
-#define TCTRL4_WR_WR_PI_MORE_DLY_SHIFT 27
-#define TCTRL4_WR_WR_TI_DLY    0x0000000007e00000UL
-#define TCTRL4_WR_WR_TI_DLY_SHIFT     21
-#define TCTRL4_RDWR_RD_PI_MORE_DLY 0x00000000001f000UL0
-#define TCTRL4_RDWR_RD_PI_MORE_DLY_SHIFT 16
-#define TCTRL4_R               0x0000000000008000UL
-#define TCTRL4_R_SHIFT               15
-#define TCTRL4_SDRAM_MODE_REG_DATA 0x0000000000007fffUL
-#define TCTRL4_SDRAM_MODE_REG_DATA_SHIFT 0
-
-/* All 4 memory address decoding registers have the
- * same layout.
- */
-#define MEM_DECODE_VALID       0x8000000000000000UL /* Valid */
-#define MEM_DECODE_VALID_SHIFT       63
-#define MEM_DECODE_UK          0x001ffe0000000000UL /* Upper mask */
-#define MEM_DECODE_UK_SHIFT          41
-#define MEM_DECODE_UM          0x0000001ffff00000UL /* Upper match */
-#define MEM_DECODE_UM_SHIFT          20
-#define MEM_DECODE_LK          0x000000000003c000UL /* Lower mask */
-#define MEM_DECODE_LK_SHIFT          14
-#define MEM_DECODE_LM          0x0000000000000f00UL /* Lower match */
-#define MEM_DECODE_LM_SHIFT           8
-
-#define PA_UPPER_BITS          0x000007fffc000000UL
-#define PA_UPPER_BITS_SHIFT    26
-#define PA_LOWER_BITS          0x00000000000003c0UL
-#define PA_LOWER_BITS_SHIFT    6
-
-#define MACTRL_R0                       0x8000000000000000UL
-#define MACTRL_R0_SHIFT                         63
-#define MACTRL_ADDR_LE_PW                0x7000000000000000UL
-#define MACTRL_ADDR_LE_PW_SHIFT                 60
-#define MACTRL_CMD_PW                    0x0f00000000000000UL
-#define MACTRL_CMD_PW_SHIFT             56
-#define MACTRL_HALF_MODE_WR_MSEL_DLY     0x00fc000000000000UL
-#define MACTRL_HALF_MODE_WR_MSEL_DLY_SHIFT 50
-#define MACTRL_HALF_MODE_RD_MSEL_DLY     0x0003f00000000000UL
-#define MACTRL_HALF_MODE_RD_MSEL_DLY_SHIFT 44
-#define MACTRL_HALF_MODE_SDRAM_CTL_DLY   0x00000f0000000000UL
-#define MACTRL_HALF_MODE_SDRAM_CTL_DLY_SHIFT 40
-#define MACTRL_HALF_MODE_SDRAM_CLK_DLY   0x000000e000000000UL
-#define MACTRL_HALF_MODE_SDRAM_CLK_DLY_SHIFT 37
-#define MACTRL_R1                        0x0000001000000000UL
-#define MACTRL_R1_SHIFT                      36
-#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B3 0x0000000f00000000UL
-#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B3_SHIFT 32
-#define MACTRL_ENC_INTLV_B3              0x00000000f8000000UL
-#define MACTRL_ENC_INTLV_B3_SHIFT              27
-#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B2 0x0000000007800000UL
-#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B2_SHIFT 23
-#define MACTRL_ENC_INTLV_B2              0x00000000007c0000UL
-#define MACTRL_ENC_INTLV_B2_SHIFT              18
-#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B1 0x000000000003c000UL
-#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B1_SHIFT 14
-#define MACTRL_ENC_INTLV_B1              0x0000000000003e00UL
-#define MACTRL_ENC_INTLV_B1_SHIFT               9
-#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B0 0x00000000000001e0UL
-#define MACTRL_BANKSEL_N_ROWADDR_SIZE_B0_SHIFT  5
-#define MACTRL_ENC_INTLV_B0              0x000000000000001fUL
-#define MACTRL_ENC_INTLV_B0_SHIFT               0
-
-#endif /* _SPARC64_CHMCTRL_H */
+#include <asm-sparc/chmctrl.h>
index 870db5928577c1595118b256254e596e4ec2e985..b19b445cb8102bdf6999949c357012e68eb476d8 100644 (file)
@@ -1,59 +1 @@
-#ifndef _SPARC64_CMT_H
-#define _SPARC64_CMT_H
-
-/* cmt.h: Chip Multi-Threading register definitions
- *
- * Copyright (C) 2004 David S. Miller (davem@redhat.com)
- */
-
-/* ASI_CORE_ID - private */
-#define LP_ID          0x0000000000000010UL
-#define  LP_ID_MAX     0x00000000003f0000UL
-#define  LP_ID_ID      0x000000000000003fUL
-
-/* ASI_INTR_ID - private */
-#define LP_INTR_ID     0x0000000000000000UL
-#define  LP_INTR_ID_ID 0x00000000000003ffUL
-
-/* ASI_CESR_ID - private */
-#define CESR_ID                0x0000000000000040UL
-#define  CESR_ID_ID    0x00000000000000ffUL
-
-/* ASI_CORE_AVAILABLE - shared */
-#define LP_AVAIL       0x0000000000000000UL
-#define  LP_AVAIL_1    0x0000000000000002UL
-#define  LP_AVAIL_0    0x0000000000000001UL
-
-/* ASI_CORE_ENABLE_STATUS - shared */
-#define LP_ENAB_STAT   0x0000000000000010UL
-#define  LP_ENAB_STAT_1        0x0000000000000002UL
-#define  LP_ENAB_STAT_0        0x0000000000000001UL
-
-/* ASI_CORE_ENABLE - shared */
-#define LP_ENAB                0x0000000000000020UL
-#define  LP_ENAB_1     0x0000000000000002UL
-#define  LP_ENAB_0     0x0000000000000001UL
-
-/* ASI_CORE_RUNNING - shared */
-#define LP_RUNNING_RW  0x0000000000000050UL
-#define LP_RUNNING_W1S 0x0000000000000060UL
-#define LP_RUNNING_W1C 0x0000000000000068UL
-#define  LP_RUNNING_1  0x0000000000000002UL
-#define  LP_RUNNING_0  0x0000000000000001UL
-
-/* ASI_CORE_RUNNING_STAT - shared */
-#define LP_RUN_STAT    0x0000000000000058UL
-#define  LP_RUN_STAT_1 0x0000000000000002UL
-#define  LP_RUN_STAT_0 0x0000000000000001UL
-
-/* ASI_XIR_STEERING - shared */
-#define LP_XIR_STEER   0x0000000000000030UL
-#define  LP_XIR_STEER_1        0x0000000000000002UL
-#define  LP_XIR_STEER_0        0x0000000000000001UL
-
-/* ASI_CMT_ERROR_STEERING - shared */
-#define CMT_ER_STEER   0x0000000000000040UL
-#define  CMT_ER_STEER_1        0x0000000000000002UL
-#define  CMT_ER_STEER_0        0x0000000000000001UL
-
-#endif /* _SPARC64_CMT_H */
+#include <asm-sparc/cmt.h>
index f260b58f5ce9d34ac224d2781bf4e0ac277849d4..8c155d221952e79f7f9141332440bbcf15612920 100644 (file)
@@ -1,243 +1 @@
-#ifndef _ASM_SPARC64_COMPAT_H
-#define _ASM_SPARC64_COMPAT_H
-/*
- * Architecture specific compatibility types
- */
-#include <linux/types.h>
-
-#define COMPAT_USER_HZ 100
-
-typedef u32            compat_size_t;
-typedef s32            compat_ssize_t;
-typedef s32            compat_time_t;
-typedef s32            compat_clock_t;
-typedef s32            compat_pid_t;
-typedef u16            __compat_uid_t;
-typedef u16            __compat_gid_t;
-typedef u32            __compat_uid32_t;
-typedef u32            __compat_gid32_t;
-typedef u16            compat_mode_t;
-typedef u32            compat_ino_t;
-typedef u16            compat_dev_t;
-typedef s32            compat_off_t;
-typedef s64            compat_loff_t;
-typedef s16            compat_nlink_t;
-typedef u16            compat_ipc_pid_t;
-typedef s32            compat_daddr_t;
-typedef u32            compat_caddr_t;
-typedef __kernel_fsid_t        compat_fsid_t;
-typedef s32            compat_key_t;
-typedef s32            compat_timer_t;
-
-typedef s32            compat_int_t;
-typedef s32            compat_long_t;
-typedef s64            compat_s64;
-typedef u32            compat_uint_t;
-typedef u32            compat_ulong_t;
-typedef u64            compat_u64;
-
-struct compat_timespec {
-       compat_time_t   tv_sec;
-       s32             tv_nsec;
-};
-
-struct compat_timeval {
-       compat_time_t   tv_sec;
-       s32             tv_usec;
-};
-
-struct compat_stat {
-       compat_dev_t    st_dev;
-       compat_ino_t    st_ino;
-       compat_mode_t   st_mode;
-       compat_nlink_t  st_nlink;
-       __compat_uid_t  st_uid;
-       __compat_gid_t  st_gid;
-       compat_dev_t    st_rdev;
-       compat_off_t    st_size;
-       compat_time_t   st_atime;
-       compat_ulong_t  st_atime_nsec;
-       compat_time_t   st_mtime;
-       compat_ulong_t  st_mtime_nsec;
-       compat_time_t   st_ctime;
-       compat_ulong_t  st_ctime_nsec;
-       compat_off_t    st_blksize;
-       compat_off_t    st_blocks;
-       u32             __unused4[2];
-};
-
-struct compat_stat64 {
-       unsigned long long      st_dev;
-
-       unsigned long long      st_ino;
-
-       unsigned int    st_mode;
-       unsigned int    st_nlink;
-
-       unsigned int    st_uid;
-       unsigned int    st_gid;
-
-       unsigned long long      st_rdev;
-
-       unsigned char   __pad3[8];
-
-       long long       st_size;
-       unsigned int    st_blksize;
-
-       unsigned char   __pad4[8];
-       unsigned int    st_blocks;
-
-       unsigned int    st_atime;
-       unsigned int    st_atime_nsec;
-
-       unsigned int    st_mtime;
-       unsigned int    st_mtime_nsec;
-
-       unsigned int    st_ctime;
-       unsigned int    st_ctime_nsec;
-
-       unsigned int    __unused4;
-       unsigned int    __unused5;
-};
-
-struct compat_flock {
-       short           l_type;
-       short           l_whence;
-       compat_off_t    l_start;
-       compat_off_t    l_len;
-       compat_pid_t    l_pid;
-       short           __unused;
-};
-
-#define F_GETLK64      12
-#define F_SETLK64      13
-#define F_SETLKW64     14
-
-struct compat_flock64 {
-       short           l_type;
-       short           l_whence;
-       compat_loff_t   l_start;
-       compat_loff_t   l_len;
-       compat_pid_t    l_pid;
-       short           __unused;
-};
-
-struct compat_statfs {
-       int             f_type;
-       int             f_bsize;
-       int             f_blocks;
-       int             f_bfree;
-       int             f_bavail;
-       int             f_files;
-       int             f_ffree;
-       compat_fsid_t   f_fsid;
-       int             f_namelen;      /* SunOS ignores this field. */
-       int             f_frsize;
-       int             f_spare[5];
-};
-
-#define COMPAT_RLIM_INFINITY 0x7fffffff
-
-typedef u32            compat_old_sigset_t;
-
-#define _COMPAT_NSIG           64
-#define _COMPAT_NSIG_BPW       32
-
-typedef u32            compat_sigset_word;
-
-#define COMPAT_OFF_T_MAX       0x7fffffff
-#define COMPAT_LOFF_T_MAX      0x7fffffffffffffffL
-
-/*
- * A pointer passed in from user mode. This should not
- * be used for syscall parameters, just declare them
- * as pointers because the syscall entry code will have
- * appropriately converted them already.
- */
-typedef        u32             compat_uptr_t;
-
-static inline void __user *compat_ptr(compat_uptr_t uptr)
-{
-       return (void __user *)(unsigned long)uptr;
-}
-
-static inline compat_uptr_t ptr_to_compat(void __user *uptr)
-{
-       return (u32)(unsigned long)uptr;
-}
-
-static inline void __user *compat_alloc_user_space(long len)
-{
-       struct pt_regs *regs = current_thread_info()->kregs;
-       unsigned long usp = regs->u_regs[UREG_I6];
-
-       if (!(test_thread_flag(TIF_32BIT)))
-               usp += STACK_BIAS;
-       else
-               usp &= 0xffffffffUL;
-
-       usp -= len;
-       usp &= ~0x7UL;
-
-       return (void __user *) usp;
-}
-
-struct compat_ipc64_perm {
-       compat_key_t key;
-       __compat_uid32_t uid;
-       __compat_gid32_t gid;
-       __compat_uid32_t cuid;
-       __compat_gid32_t cgid;
-       unsigned short __pad1;
-       compat_mode_t mode;
-       unsigned short __pad2;
-       unsigned short seq;
-       unsigned long __unused1;        /* yes they really are 64bit pads */
-       unsigned long __unused2;
-};
-
-struct compat_semid64_ds {
-       struct compat_ipc64_perm sem_perm;
-       unsigned int    __pad1;
-       compat_time_t   sem_otime;
-       unsigned int    __pad2;
-       compat_time_t   sem_ctime;
-       u32             sem_nsems;
-       u32             __unused1;
-       u32             __unused2;
-};
-
-struct compat_msqid64_ds {
-       struct compat_ipc64_perm msg_perm;
-       unsigned int    __pad1;
-       compat_time_t   msg_stime;
-       unsigned int    __pad2;
-       compat_time_t   msg_rtime;
-       unsigned int    __pad3;
-       compat_time_t   msg_ctime;
-       unsigned int    msg_cbytes;
-       unsigned int    msg_qnum;
-       unsigned int    msg_qbytes;
-       compat_pid_t    msg_lspid;
-       compat_pid_t    msg_lrpid;
-       unsigned int    __unused1;
-       unsigned int    __unused2;
-};
-
-struct compat_shmid64_ds {
-       struct compat_ipc64_perm shm_perm;
-       unsigned int    __pad1;
-       compat_time_t   shm_atime;
-       unsigned int    __pad2;
-       compat_time_t   shm_dtime;
-       unsigned int    __pad3;
-       compat_time_t   shm_ctime;
-       compat_size_t   shm_segsz;
-       compat_pid_t    shm_cpid;
-       compat_pid_t    shm_lpid;
-       unsigned int    shm_nattch;
-       unsigned int    __unused1;
-       unsigned int    __unused2;
-};
-
-#endif /* _ASM_SPARC64_COMPAT_H */
+#include <asm-sparc/compat.h>
index b759eab9b51c1e05ecc414bfbf2a21486fe6e179..7187dcc8cac75dc4fb9c8b8bc8e5094fefcafba3 100644 (file)
@@ -1,29 +1 @@
-#ifndef _COMPAT_SIGNAL_H
-#define _COMPAT_SIGNAL_H
-
-#include <linux/compat.h>
-#include <asm/signal.h>
-
-#ifdef CONFIG_COMPAT
-struct __new_sigaction32 {
-       unsigned                sa_handler;
-       unsigned int            sa_flags;
-       unsigned                sa_restorer;     /* not used by Linux/SPARC yet */
-       compat_sigset_t         sa_mask;
-};
-
-struct __old_sigaction32 {
-       unsigned                sa_handler;
-       compat_old_sigset_t     sa_mask;
-       unsigned int            sa_flags;
-       unsigned                sa_restorer;     /* not used by Linux/SPARC yet */
-};
-
-typedef struct sigaltstack32 {
-       u32                     ss_sp;
-       int                     ss_flags;
-       compat_size_t           ss_size;
-} stack_t32;
-#endif
-
-#endif /* !(_COMPAT_SIGNAL_H) */
+#include <asm-sparc/compat_signal.h>
index 532975ecfe10c1b6720f48bf177632901f8cdb94..3220e134a579d2543e202edd9e2040e97a928800 100644 (file)
@@ -1,240 +1 @@
-/* cpudata.h: Per-cpu parameters.
- *
- * Copyright (C) 2003, 2005, 2006 David S. Miller (davem@davemloft.net)
- */
-
-#ifndef _SPARC64_CPUDATA_H
-#define _SPARC64_CPUDATA_H
-
-#include <asm/hypervisor.h>
-#include <asm/asi.h>
-
-#ifndef __ASSEMBLY__
-
-#include <linux/percpu.h>
-#include <linux/threads.h>
-
-typedef struct {
-       /* Dcache line 1 */
-       unsigned int    __softirq_pending; /* must be 1st, see rtrap.S */
-       unsigned int    __pad0;
-       unsigned long   clock_tick;     /* %tick's per second */
-       unsigned long   __pad;
-       unsigned int    __pad1;
-       unsigned int    __pad2;
-
-       /* Dcache line 2, rarely used */
-       unsigned int    dcache_size;
-       unsigned int    dcache_line_size;
-       unsigned int    icache_size;
-       unsigned int    icache_line_size;
-       unsigned int    ecache_size;
-       unsigned int    ecache_line_size;
-       int             core_id;
-       int             proc_id;
-} cpuinfo_sparc;
-
-DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
-#define cpu_data(__cpu)                per_cpu(__cpu_data, (__cpu))
-#define local_cpu_data()       __get_cpu_var(__cpu_data)
-
-/* Trap handling code needs to get at a few critical values upon
- * trap entry and to process TSB misses.  These cannot be in the
- * per_cpu() area as we really need to lock them into the TLB and
- * thus make them part of the main kernel image.  As a result we
- * try to make this as small as possible.
- *
- * This is padded out and aligned to 64-bytes to avoid false sharing
- * on SMP.
- */
-
-/* If you modify the size of this structure, please update
- * TRAP_BLOCK_SZ_SHIFT below.
- */
-struct thread_info;
-struct trap_per_cpu {
-/* D-cache line 1: Basic thread information, cpu and device mondo queues */
-       struct thread_info      *thread;
-       unsigned long           pgd_paddr;
-       unsigned long           cpu_mondo_pa;
-       unsigned long           dev_mondo_pa;
-
-/* D-cache line 2: Error Mondo Queue and kernel buffer pointers */
-       unsigned long           resum_mondo_pa;
-       unsigned long           resum_kernel_buf_pa;
-       unsigned long           nonresum_mondo_pa;
-       unsigned long           nonresum_kernel_buf_pa;
-
-/* Dcache lines 3, 4, 5, and 6: Hypervisor Fault Status */
-       struct hv_fault_status  fault_info;
-
-/* Dcache line 7: Physical addresses of CPU send mondo block and CPU list.  */
-       unsigned long           cpu_mondo_block_pa;
-       unsigned long           cpu_list_pa;
-       unsigned long           tsb_huge;
-       unsigned long           tsb_huge_temp;
-
-/* Dcache line 8: IRQ work list, and keep trap_block a power-of-2 in size.  */
-       unsigned long           irq_worklist_pa;
-       unsigned int            cpu_mondo_qmask;
-       unsigned int            dev_mondo_qmask;
-       unsigned int            resum_qmask;
-       unsigned int            nonresum_qmask;
-       void                    *hdesc;
-} __attribute__((aligned(64)));
-extern struct trap_per_cpu trap_block[NR_CPUS];
-extern void init_cur_cpu_trap(struct thread_info *);
-extern void setup_tba(void);
-extern int ncpus_probed;
-extern void __init cpu_probe(void);
-extern const struct seq_operations cpuinfo_op;
-
-extern unsigned long real_hard_smp_processor_id(void);
-
-struct cpuid_patch_entry {
-       unsigned int    addr;
-       unsigned int    cheetah_safari[4];
-       unsigned int    cheetah_jbus[4];
-       unsigned int    starfire[4];
-       unsigned int    sun4v[4];
-};
-extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end;
-
-struct sun4v_1insn_patch_entry {
-       unsigned int    addr;
-       unsigned int    insn;
-};
-extern struct sun4v_1insn_patch_entry __sun4v_1insn_patch,
-       __sun4v_1insn_patch_end;
-
-struct sun4v_2insn_patch_entry {
-       unsigned int    addr;
-       unsigned int    insns[2];
-};
-extern struct sun4v_2insn_patch_entry __sun4v_2insn_patch,
-       __sun4v_2insn_patch_end;
-
-#endif /* !(__ASSEMBLY__) */
-
-#define TRAP_PER_CPU_THREAD            0x00
-#define TRAP_PER_CPU_PGD_PADDR         0x08
-#define TRAP_PER_CPU_CPU_MONDO_PA      0x10
-#define TRAP_PER_CPU_DEV_MONDO_PA      0x18
-#define TRAP_PER_CPU_RESUM_MONDO_PA    0x20
-#define TRAP_PER_CPU_RESUM_KBUF_PA     0x28
-#define TRAP_PER_CPU_NONRESUM_MONDO_PA 0x30
-#define TRAP_PER_CPU_NONRESUM_KBUF_PA  0x38
-#define TRAP_PER_CPU_FAULT_INFO                0x40
-#define TRAP_PER_CPU_CPU_MONDO_BLOCK_PA        0xc0
-#define TRAP_PER_CPU_CPU_LIST_PA       0xc8
-#define TRAP_PER_CPU_TSB_HUGE          0xd0
-#define TRAP_PER_CPU_TSB_HUGE_TEMP     0xd8
-#define TRAP_PER_CPU_IRQ_WORKLIST_PA   0xe0
-#define TRAP_PER_CPU_CPU_MONDO_QMASK   0xe8
-#define TRAP_PER_CPU_DEV_MONDO_QMASK   0xec
-#define TRAP_PER_CPU_RESUM_QMASK       0xf0
-#define TRAP_PER_CPU_NONRESUM_QMASK    0xf4
-
-#define TRAP_BLOCK_SZ_SHIFT            8
-
-#include <asm/scratchpad.h>
-
-#define __GET_CPUID(REG)                               \
-       /* Spitfire implementation (default). */        \
-661:   ldxa            [%g0] ASI_UPA_CONFIG, REG;      \
-       srlx            REG, 17, REG;                   \
-        and            REG, 0x1f, REG;                 \
-       nop;                                            \
-       .section        .cpuid_patch, "ax";             \
-       /* Instruction location. */                     \
-       .word           661b;                           \
-       /* Cheetah Safari implementation. */            \
-       ldxa            [%g0] ASI_SAFARI_CONFIG, REG;   \
-       srlx            REG, 17, REG;                   \
-       and             REG, 0x3ff, REG;                \
-       nop;                                            \
-       /* Cheetah JBUS implementation. */              \
-       ldxa            [%g0] ASI_JBUS_CONFIG, REG;     \
-       srlx            REG, 17, REG;                   \
-       and             REG, 0x1f, REG;                 \
-       nop;                                            \
-       /* Starfire implementation. */                  \
-       sethi           %hi(0x1fff40000d0 >> 9), REG;   \
-       sllx            REG, 9, REG;                    \
-       or              REG, 0xd0, REG;                 \
-       lduwa           [REG] ASI_PHYS_BYPASS_EC_E, REG;\
-       /* sun4v implementation. */                     \
-       mov             SCRATCHPAD_CPUID, REG;          \
-       ldxa            [REG] ASI_SCRATCHPAD, REG;      \
-       nop;                                            \
-       nop;                                            \
-       .previous;
-
-#ifdef CONFIG_SMP
-
-#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP)                \
-       __GET_CPUID(TMP)                        \
-       sethi   %hi(trap_block), DEST;          \
-       sllx    TMP, TRAP_BLOCK_SZ_SHIFT, TMP;  \
-       or      DEST, %lo(trap_block), DEST;    \
-       add     DEST, TMP, DEST;                \
-
-/* Clobbers TMP, current address space PGD phys address into DEST.  */
-#define TRAP_LOAD_PGD_PHYS(DEST, TMP)          \
-       TRAP_LOAD_TRAP_BLOCK(DEST, TMP)         \
-       ldx     [DEST + TRAP_PER_CPU_PGD_PADDR], DEST;
-
-/* Clobbers TMP, loads local processor's IRQ work area into DEST.  */
-#define TRAP_LOAD_IRQ_WORK_PA(DEST, TMP)       \
-       TRAP_LOAD_TRAP_BLOCK(DEST, TMP)         \
-       add     DEST, TRAP_PER_CPU_IRQ_WORKLIST_PA, DEST;
-
-/* Clobbers TMP, loads DEST with current thread info pointer.  */
-#define TRAP_LOAD_THREAD_REG(DEST, TMP)                \
-       TRAP_LOAD_TRAP_BLOCK(DEST, TMP)         \
-       ldx     [DEST + TRAP_PER_CPU_THREAD], DEST;
-
-/* Given the current thread info pointer in THR, load the per-cpu
- * area base of the current processor into DEST.  REG1, REG2, and REG3 are
- * clobbered.
- *
- * You absolutely cannot use DEST as a temporary in this code.  The
- * reason is that traps can happen during execution, and return from
- * trap will load the fully resolved DEST per-cpu base.  This can corrupt
- * the calculations done by the macro mid-stream.
- */
-#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) \
-       lduh    [THR + TI_CPU], REG1;                   \
-       sethi   %hi(__per_cpu_shift), REG3;             \
-       sethi   %hi(__per_cpu_base), REG2;              \
-       ldx     [REG3 + %lo(__per_cpu_shift)], REG3;    \
-       ldx     [REG2 + %lo(__per_cpu_base)], REG2;     \
-       sllx    REG1, REG3, REG3;                       \
-       add     REG3, REG2, DEST;
-
-#else
-
-#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP)                \
-       sethi   %hi(trap_block), DEST;          \
-       or      DEST, %lo(trap_block), DEST;    \
-
-/* Uniprocessor versions, we know the cpuid is zero.  */
-#define TRAP_LOAD_PGD_PHYS(DEST, TMP)          \
-       TRAP_LOAD_TRAP_BLOCK(DEST, TMP)         \
-       ldx     [DEST + TRAP_PER_CPU_PGD_PADDR], DEST;
-
-/* Clobbers TMP, loads local processor's IRQ work area into DEST.  */
-#define TRAP_LOAD_IRQ_WORK_PA(DEST, TMP)       \
-       TRAP_LOAD_TRAP_BLOCK(DEST, TMP)         \
-       add     DEST, TRAP_PER_CPU_IRQ_WORKLIST_PA, DEST;
-
-#define TRAP_LOAD_THREAD_REG(DEST, TMP)                \
-       TRAP_LOAD_TRAP_BLOCK(DEST, TMP)         \
-       ldx     [DEST + TRAP_PER_CPU_THREAD], DEST;
-
-/* No per-cpu areas on uniprocessor, so no need to load DEST.  */
-#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3)
-
-#endif /* !(CONFIG_SMP) */
-
-#endif /* _SPARC64_CPUDATA_H */
+#include <asm-sparc/cpudata.h>
index 620c9ba642e94bc2e432f9ef9098e551268d0e92..d67613b1f5fe5400788d8cce9533edb9bfc64e0d 100644 (file)
@@ -1,14 +1 @@
-#ifndef _SPARC64_DCR_H
-#define _SPARC64_DCR_H
-
-/* UltraSparc-III/III+ Dispatch Control Register, ASR 0x12 */
-#define DCR_DPE                0x0000000000001000 /* III+: D$ Parity Error Enable      */
-#define DCR_OBS                0x0000000000000fc0 /* Observability Bus Controls        */
-#define DCR_BPE                0x0000000000000020 /* Branch Predict Enable             */
-#define DCR_RPE                0x0000000000000010 /* Return Address Prediction Enable  */
-#define DCR_SI         0x0000000000000008 /* Single Instruction Disable        */
-#define DCR_IPE                0x0000000000000004 /* III+: I$ Parity Error Enable      */
-#define DCR_IFPOE      0x0000000000000002 /* IRQ FP Operation Enable           */
-#define DCR_MS         0x0000000000000001 /* Multi-Scalar dispatch             */
-
-#endif /* _SPARC64_DCR_H */
+#include <asm-sparc/dcr.h>
index 0f704e106a1b97e07a8d4ea3d5ee8d27a9f9b945..28853f4968d1159dba626b1c9f6846eb7a02f8d4 100644 (file)
@@ -1,27 +1 @@
-#ifndef _SPARC64_DCU_H
-#define _SPARC64_DCU_H
-
-#include <linux/const.h>
-
-/* UltraSparc-III Data Cache Unit Control Register */
-#define DCU_CP _AC(0x0002000000000000,UL) /* Phys Cache Enable w/o mmu */
-#define DCU_CV _AC(0x0001000000000000,UL) /* Virt Cache Enable w/o mmu */
-#define DCU_ME _AC(0x0000800000000000,UL) /* NC-store Merging Enable   */
-#define DCU_RE _AC(0x0000400000000000,UL) /* RAW bypass Enable         */
-#define DCU_PE _AC(0x0000200000000000,UL) /* PCache Enable             */
-#define DCU_HPE        _AC(0x0000100000000000,UL) /* HW prefetch Enable        */
-#define DCU_SPE        _AC(0x0000080000000000,UL) /* SW prefetch Enable        */
-#define DCU_SL _AC(0x0000040000000000,UL) /* Secondary ld-steering Enab*/
-#define DCU_WE _AC(0x0000020000000000,UL) /* WCache enable             */
-#define DCU_PM _AC(0x000001fe00000000,UL) /* PA Watchpoint Byte Mask   */
-#define DCU_VM _AC(0x00000001fe000000,UL) /* VA Watchpoint Byte Mask   */
-#define DCU_PR _AC(0x0000000001000000,UL) /* PA Watchpoint Read Enable */
-#define DCU_PW _AC(0x0000000000800000,UL) /* PA Watchpoint Write Enable*/
-#define DCU_VR _AC(0x0000000000400000,UL) /* VA Watchpoint Read Enable */
-#define DCU_VW _AC(0x0000000000200000,UL) /* VA Watchpoint Write Enable*/
-#define DCU_DM _AC(0x0000000000000008,UL) /* DMMU Enable               */
-#define DCU_IM _AC(0x0000000000000004,UL) /* IMMU Enable               */
-#define DCU_DC _AC(0x0000000000000002,UL) /* Data Cache Enable         */
-#define DCU_IC _AC(0x0000000000000001,UL) /* Instruction Cache Enable  */
-
-#endif /* _SPARC64_DCU_H */
+#include <asm-sparc/dcu.h>
index a77aa622d7622cfd17d69568b3ca3f59b9250d13..33dc5589d841aa17fefee7ea22ef7e27473874ee 100644 (file)
@@ -1,17 +1 @@
-/* delay.h: Linux delay routines on sparc64.
- *
- * Copyright (C) 1996, 2004, 2007 David S. Miller (davem@davemloft.net).
- */
-
-#ifndef _SPARC64_DELAY_H
-#define _SPARC64_DELAY_H
-
-#ifndef __ASSEMBLY__
-
-extern void __delay(unsigned long loops);
-extern void udelay(unsigned long usecs);
-#define mdelay(n)      udelay((n) * 1000)
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* _SPARC64_DELAY_H */
+#include <asm-sparc/delay.h>
index c066a8964eab1e8c6b2b012a22300cc9792f1f4a..e74f046b41def69ba12754d72b6e8be1072ef5d1 100644 (file)
@@ -1,79 +1 @@
-/*
- *
- * display7seg - Driver interface for the 7-segment display
- * present on Sun Microsystems CP1400 and CP1500
- *
- * Copyright (c) 2000 Eric Brower <ebrower@usa.net>
- *
- */
-
-#ifndef __display7seg_h__
-#define __display7seg_h__
-
-#define D7S_IOC        'p'
-
-#define D7SIOCRD _IOR(D7S_IOC, 0x45, int)      /* Read device state    */
-#define D7SIOCWR _IOW(D7S_IOC, 0x46, int)      /* Write device state   */
-#define D7SIOCTM _IO (D7S_IOC, 0x47)           /* Translate mode (FLIP)*/
-
-/*
- * ioctl flag definitions
- *
- * POINT       - Toggle decimal point  (0=absent 1=present)
- * ALARM       - Toggle alarm LED              (0=green  1=red)
- * FLIP                - Toggle inverted mode  (0=normal 1=flipped) 
- * bits 0-4    - Character displayed   (see definitions below)
- *
- * Display segments are defined as follows, 
- * subject to D7S_FLIP register state:
- *
- *    a
- *   ---
- * f|   |b
- *   -g-
- * e|   |c
- *   ---
- *    d
- */
-
-#define D7S_POINT      (1 << 7)        /* Decimal point*/
-#define D7S_ALARM      (1 << 6)        /* Alarm LED    */
-#define D7S_FLIP       (1 << 5)        /* Flip display */
-
-#define D7S_0          0x00            /* Numerals 0-9 */
-#define D7S_1          0x01
-#define D7S_2          0x02
-#define D7S_3          0x03
-#define D7S_4          0x04
-#define D7S_5          0x05
-#define D7S_6          0x06
-#define D7S_7          0x07
-#define D7S_8          0x08
-#define D7S_9          0x09
-#define D7S_A          0x0A            /* Letters A-F, H, L, P */
-#define D7S_B          0x0B
-#define D7S_C          0x0C
-#define D7S_D          0x0D
-#define D7S_E          0x0E
-#define D7S_F          0x0F
-#define D7S_H          0x10
-#define D7S_E2         0x11
-#define D7S_L          0x12
-#define D7S_P          0x13
-#define D7S_SEGA       0x14            /* Individual segments */
-#define D7S_SEGB       0x15
-#define D7S_SEGC       0x16
-#define D7S_SEGD       0x17
-#define D7S_SEGE       0x18
-#define D7S_SEGF       0x19
-#define D7S_SEGG       0x1A
-#define D7S_SEGABFG 0x1B               /* Segment groupings */
-#define D7S_SEGCDEG    0x1C
-#define D7S_SEGBCEF 0x1D
-#define D7S_SEGADG     0x1E
-#define D7S_BLANK      0x1F            /* Clear all segments */
-
-#define D7S_MIN_VAL    0x0
-#define D7S_MAX_VAL    0x1F
-
-#endif /* ifndef __display7seg_h__ */
+#include <asm-sparc/display7seg.h>
index 38cbec76a33f1c04bd14948786891e90185c9277..380b7b63147ff60c8ca3dab52a0530ab10db076b 100644 (file)
@@ -1,154 +1 @@
-#ifndef _ASM_SPARC64_DMA_MAPPING_H
-#define _ASM_SPARC64_DMA_MAPPING_H
-
-#include <linux/scatterlist.h>
-#include <linux/mm.h>
-
-#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
-
-struct dma_ops {
-       void *(*alloc_coherent)(struct device *dev, size_t size,
-                               dma_addr_t *dma_handle, gfp_t flag);
-       void (*free_coherent)(struct device *dev, size_t size,
-                             void *cpu_addr, dma_addr_t dma_handle);
-       dma_addr_t (*map_single)(struct device *dev, void *cpu_addr,
-                                size_t size,
-                                enum dma_data_direction direction);
-       void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
-                            size_t size,
-                            enum dma_data_direction direction);
-       int (*map_sg)(struct device *dev, struct scatterlist *sg, int nents,
-                     enum dma_data_direction direction);
-       void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
-                        int nhwentries,
-                        enum dma_data_direction direction);
-       void (*sync_single_for_cpu)(struct device *dev,
-                                   dma_addr_t dma_handle, size_t size,
-                                   enum dma_data_direction direction);
-       void (*sync_sg_for_cpu)(struct device *dev, struct scatterlist *sg,
-                               int nelems,
-                               enum dma_data_direction direction);
-};
-extern const struct dma_ops *dma_ops;
-
-extern int dma_supported(struct device *dev, u64 mask);
-extern int dma_set_mask(struct device *dev, u64 dma_mask);
-
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-                                      dma_addr_t *dma_handle, gfp_t flag)
-{
-       return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
-}
-
-static inline void dma_free_coherent(struct device *dev, size_t size,
-                                    void *cpu_addr, dma_addr_t dma_handle)
-{
-       dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
-}
-
-static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
-                                       size_t size,
-                                       enum dma_data_direction direction)
-{
-       return dma_ops->map_single(dev, cpu_addr, size, direction);
-}
-
-static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
-                                   size_t size,
-                                   enum dma_data_direction direction)
-{
-       dma_ops->unmap_single(dev, dma_addr, size, direction);
-}
-
-static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
-                                     unsigned long offset, size_t size,
-                                     enum dma_data_direction direction)
-{
-       return dma_ops->map_single(dev, page_address(page) + offset,
-                                  size, direction);
-}
-
-static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
-                                 size_t size,
-                                 enum dma_data_direction direction)
-{
-       dma_ops->unmap_single(dev, dma_address, size, direction);
-}
-
-static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
-                            int nents, enum dma_data_direction direction)
-{
-       return dma_ops->map_sg(dev, sg, nents, direction);
-}
-
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-                               int nents, enum dma_data_direction direction)
-{
-       dma_ops->unmap_sg(dev, sg, nents, direction);
-}
-
-static inline void dma_sync_single_for_cpu(struct device *dev,
-                                          dma_addr_t dma_handle, size_t size,
-                                          enum dma_data_direction direction)
-{
-       dma_ops->sync_single_for_cpu(dev, dma_handle, size, direction);
-}
-
-static inline void dma_sync_single_for_device(struct device *dev,
-                                             dma_addr_t dma_handle,
-                                             size_t size,
-                                             enum dma_data_direction direction)
-{
-       /* No flushing needed to sync cpu writes to the device.  */
-}
-
-static inline void dma_sync_single_range_for_cpu(struct device *dev,
-                                                dma_addr_t dma_handle,
-                                                unsigned long offset,
-                                                size_t size,
-                                                enum dma_data_direction direction)
-{
-       dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction);
-}
-
-static inline void dma_sync_single_range_for_device(struct device *dev,
-                                                   dma_addr_t dma_handle,
-                                                   unsigned long offset,
-                                                   size_t size,
-                                                   enum dma_data_direction direction)
-{
-       /* No flushing needed to sync cpu writes to the device.  */
-}
-
-
-static inline void dma_sync_sg_for_cpu(struct device *dev,
-                                      struct scatterlist *sg, int nelems,
-                                      enum dma_data_direction direction)
-{
-       dma_ops->sync_sg_for_cpu(dev, sg, nelems, direction);
-}
-
-static inline void dma_sync_sg_for_device(struct device *dev,
-                                         struct scatterlist *sg, int nelems,
-                                         enum dma_data_direction direction)
-{
-       /* No flushing needed to sync cpu writes to the device.  */
-}
-
-static inline int dma_mapping_error(dma_addr_t dma_addr)
-{
-       return (dma_addr == DMA_ERROR_CODE);
-}
-
-static inline int dma_get_cache_alignment(void)
-{
-       /* no easy way to get cache size on all processors, so return
-        * the maximum possible, to be safe */
-       return (1 << INTERNODE_CACHE_SHIFT);
-}
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-#define dma_is_consistent(d, h)        (1)
-
-#endif /* _ASM_SPARC64_DMA_MAPPING_H */
+#include <asm-sparc/dma-mapping.h>
index 9d4c024bd3b3874f0091c4c3e83cd4392006110f..2e36248e6b59dd8f06fbb6fba18ea7a2c0a2d1a9 100644 (file)
@@ -1,205 +1 @@
-/*
- * include/asm-sparc64/dma.h
- *
- * Copyright 1996 (C) David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef _ASM_SPARC64_DMA_H
-#define _ASM_SPARC64_DMA_H
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-
-#include <asm/sbus.h>
-#include <asm/delay.h>
-#include <asm/oplib.h>
-
-/* These are irrelevant for Sparc DMA, but we leave it in so that
- * things can compile.
- */
-#define MAX_DMA_CHANNELS 8
-#define DMA_MODE_READ    1
-#define DMA_MODE_WRITE   2
-#define MAX_DMA_ADDRESS  (~0UL)
-
-/* Useful constants */
-#define SIZE_16MB      (16*1024*1024)
-#define SIZE_64K       (64*1024)
-
-/* SBUS DMA controller reg offsets */
-#define DMA_CSR                0x00UL          /* rw  DMA control/status register    0x00   */
-#define DMA_ADDR       0x04UL          /* rw  DMA transfer address register  0x04   */
-#define DMA_COUNT      0x08UL          /* rw  DMA transfer count register    0x08   */
-#define DMA_TEST       0x0cUL          /* rw  DMA test/debug register        0x0c   */
-
-/* DVMA chip revisions */
-enum dvma_rev {
-       dvmarev0,
-       dvmaesc1,
-       dvmarev1,
-       dvmarev2,
-       dvmarev3,
-       dvmarevplus,
-       dvmahme
-};
-
-#define DMA_HASCOUNT(rev)  ((rev)==dvmaesc1)
-
-/* Linux DMA information structure, filled during probe. */
-struct sbus_dma {
-       struct sbus_dma *next;
-       struct sbus_dev *sdev;
-       void __iomem *regs;
-
-       /* Status, misc info */
-       int node;                /* Prom node for this DMA device */
-       int running;             /* Are we doing DMA now? */
-       int allocated;           /* Are we "owned" by anyone yet? */
-
-       /* Transfer information. */
-       u32 addr;                /* Start address of current transfer */
-       int nbytes;              /* Size of current transfer */
-       int realbytes;           /* For splitting up large transfers, etc. */
-
-       /* DMA revision */
-       enum dvma_rev revision;
-};
-
-extern struct sbus_dma *dma_chain;
-
-/* Broken hardware... */
-#define DMA_ISBROKEN(dma)    ((dma)->revision == dvmarev1)
-#define DMA_ISESC1(dma)      ((dma)->revision == dvmaesc1)
-
-/* Main routines in dma.c */
-extern void dvma_init(struct sbus_bus *);
-
-/* Fields in the cond_reg register */
-/* First, the version identification bits */
-#define DMA_DEVICE_ID    0xf0000000        /* Device identification bits */
-#define DMA_VERS0        0x00000000        /* Sunray DMA version */
-#define DMA_ESCV1        0x40000000        /* DMA ESC Version 1 */
-#define DMA_VERS1        0x80000000        /* DMA rev 1 */
-#define DMA_VERS2        0xa0000000        /* DMA rev 2 */
-#define DMA_VERHME       0xb0000000        /* DMA hme gate array */
-#define DMA_VERSPLUS     0x90000000        /* DMA rev 1 PLUS */
-
-#define DMA_HNDL_INTR    0x00000001        /* An IRQ needs to be handled */
-#define DMA_HNDL_ERROR   0x00000002        /* We need to take an error */
-#define DMA_FIFO_ISDRAIN 0x0000000c        /* The DMA FIFO is draining */
-#define DMA_INT_ENAB     0x00000010        /* Turn on interrupts */
-#define DMA_FIFO_INV     0x00000020        /* Invalidate the FIFO */
-#define DMA_ACC_SZ_ERR   0x00000040        /* The access size was bad */
-#define DMA_FIFO_STDRAIN 0x00000040        /* DMA_VERS1 Drain the FIFO */
-#define DMA_RST_SCSI     0x00000080        /* Reset the SCSI controller */
-#define DMA_RST_ENET     DMA_RST_SCSI      /* Reset the ENET controller */
-#define DMA_ST_WRITE     0x00000100        /* write from device to memory */
-#define DMA_ENABLE       0x00000200        /* Fire up DMA, handle requests */
-#define DMA_PEND_READ    0x00000400        /* DMA_VERS1/0/PLUS Pending Read */
-#define DMA_ESC_BURST    0x00000800        /* 1=16byte 0=32byte */
-#define DMA_READ_AHEAD   0x00001800        /* DMA read ahead partial longword */
-#define DMA_DSBL_RD_DRN  0x00001000        /* No EC drain on slave reads */
-#define DMA_BCNT_ENAB    0x00002000        /* If on, use the byte counter */
-#define DMA_TERM_CNTR    0x00004000        /* Terminal counter */
-#define DMA_SCSI_SBUS64  0x00008000        /* HME: Enable 64-bit SBUS mode. */
-#define DMA_CSR_DISAB    0x00010000        /* No FIFO drains during csr */
-#define DMA_SCSI_DISAB   0x00020000        /* No FIFO drains during reg */
-#define DMA_DSBL_WR_INV  0x00020000        /* No EC inval. on slave writes */
-#define DMA_ADD_ENABLE   0x00040000        /* Special ESC DVMA optimization */
-#define DMA_E_BURSTS    0x000c0000        /* ENET: SBUS r/w burst mask */
-#define DMA_E_BURST32   0x00040000        /* ENET: SBUS 32 byte r/w burst */
-#define DMA_E_BURST16   0x00000000        /* ENET: SBUS 16 byte r/w burst */
-#define DMA_BRST_SZ      0x000c0000        /* SCSI: SBUS r/w burst size */
-#define DMA_BRST64       0x000c0000        /* SCSI: 64byte bursts (HME on UltraSparc only) */
-#define DMA_BRST32       0x00040000        /* SCSI: 32byte bursts */
-#define DMA_BRST16       0x00000000        /* SCSI: 16byte bursts */
-#define DMA_BRST0        0x00080000        /* SCSI: no bursts (non-HME gate arrays) */
-#define DMA_ADDR_DISAB   0x00100000        /* No FIFO drains during addr */
-#define DMA_2CLKS        0x00200000        /* Each transfer = 2 clock ticks */
-#define DMA_3CLKS        0x00400000        /* Each transfer = 3 clock ticks */
-#define DMA_EN_ENETAUI   DMA_3CLKS         /* Put lance into AUI-cable mode */
-#define DMA_CNTR_DISAB   0x00800000        /* No IRQ when DMA_TERM_CNTR set */
-#define DMA_AUTO_NADDR   0x01000000        /* Use "auto nxt addr" feature */
-#define DMA_SCSI_ON      0x02000000        /* Enable SCSI dma */
-#define DMA_PARITY_OFF   0x02000000        /* HME: disable parity checking */
-#define DMA_LOADED_ADDR  0x04000000        /* Address has been loaded */
-#define DMA_LOADED_NADDR 0x08000000        /* Next address has been loaded */
-#define DMA_RESET_FAS366 0x08000000        /* HME: Assert RESET to FAS366 */
-
-/* Values describing the burst-size property from the PROM */
-#define DMA_BURST1       0x01
-#define DMA_BURST2       0x02
-#define DMA_BURST4       0x04
-#define DMA_BURST8       0x08
-#define DMA_BURST16      0x10
-#define DMA_BURST32      0x20
-#define DMA_BURST64      0x40
-#define DMA_BURSTBITS    0x7f
-
-/* Determine highest possible final transfer address given a base */
-#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL))
-
-/* Yes, I hack a lot of elisp in my spare time... */
-#define DMA_ERROR_P(regs)  ((sbus_readl((regs) + DMA_CSR) & DMA_HNDL_ERROR))
-#define DMA_IRQ_P(regs)    ((sbus_readl((regs) + DMA_CSR)) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))
-#define DMA_WRITE_P(regs)  ((sbus_readl((regs) + DMA_CSR) & DMA_ST_WRITE))
-#define DMA_OFF(__regs)                \
-do {   u32 tmp = sbus_readl((__regs) + DMA_CSR); \
-       tmp &= ~DMA_ENABLE; \
-       sbus_writel(tmp, (__regs) + DMA_CSR); \
-} while(0)
-#define DMA_INTSOFF(__regs)    \
-do {   u32 tmp = sbus_readl((__regs) + DMA_CSR); \
-       tmp &= ~DMA_INT_ENAB; \
-       sbus_writel(tmp, (__regs) + DMA_CSR); \
-} while(0)
-#define DMA_INTSON(__regs)     \
-do {   u32 tmp = sbus_readl((__regs) + DMA_CSR); \
-       tmp |= DMA_INT_ENAB; \
-       sbus_writel(tmp, (__regs) + DMA_CSR); \
-} while(0)
-#define DMA_PUNTFIFO(__regs)   \
-do {   u32 tmp = sbus_readl((__regs) + DMA_CSR); \
-       tmp |= DMA_FIFO_INV; \
-       sbus_writel(tmp, (__regs) + DMA_CSR); \
-} while(0)
-#define DMA_SETSTART(__regs, __addr)   \
-       sbus_writel((u32)(__addr), (__regs) + DMA_ADDR);
-#define DMA_BEGINDMA_W(__regs) \
-do {   u32 tmp = sbus_readl((__regs) + DMA_CSR); \
-       tmp |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB); \
-       sbus_writel(tmp, (__regs) + DMA_CSR); \
-} while(0)
-#define DMA_BEGINDMA_R(__regs) \
-do {   u32 tmp = sbus_readl((__regs) + DMA_CSR); \
-       tmp |= (DMA_ENABLE|DMA_INT_ENAB); \
-       tmp &= ~DMA_ST_WRITE; \
-       sbus_writel(tmp, (__regs) + DMA_CSR); \
-} while(0)
-
-/* For certain DMA chips, we need to disable ints upon irq entry
- * and turn them back on when we are done.  So in any ESP interrupt
- * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT
- * when leaving the handler.  You have been warned...
- */
-#define DMA_IRQ_ENTRY(dma, dregs) do { \
-        if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \
-   } while (0)
-
-#define DMA_IRQ_EXIT(dma, dregs) do { \
-       if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \
-   } while(0)
-
-#define for_each_dvma(dma) \
-        for((dma) = dma_chain; (dma); (dma) = (dma)->next)
-
-/* From PCI */
-
-#ifdef CONFIG_PCI
-extern int isa_dma_bridge_buggy;
-#else
-#define isa_dma_bridge_buggy   (0)
-#endif
-
-#endif /* !(_ASM_SPARC64_DMA_H) */
+#include <asm-sparc/dma.h>
index fcc62b97ced520c5b369d791cd7fd2368f664048..d7d476158bd5b18b7dbd116676ea78d872b581ae 100644 (file)
@@ -1,94 +1 @@
-/*
- * ebus.h: PCI to Ebus pseudo driver software state.
- *
- * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
- * Copyright (C) 1999 David S. Miller (davem@redhat.com)
- */
-
-#ifndef __SPARC64_EBUS_H
-#define __SPARC64_EBUS_H
-
-#include <asm/oplib.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
-
-struct linux_ebus_child {
-       struct linux_ebus_child         *next;
-       struct linux_ebus_device        *parent;
-       struct linux_ebus               *bus;
-       struct device_node              *prom_node;
-       struct resource                  resource[PROMREG_MAX];
-       int                              num_addrs;
-       unsigned int                     irqs[PROMINTR_MAX];
-       int                              num_irqs;
-};
-
-struct linux_ebus_device {
-       struct of_device                ofdev;
-       struct linux_ebus_device        *next;
-       struct linux_ebus_child         *children;
-       struct linux_ebus               *bus;
-       struct device_node              *prom_node;
-       struct resource                  resource[PROMREG_MAX];
-       int                              num_addrs;
-       unsigned int                     irqs[PROMINTR_MAX];
-       int                              num_irqs;
-};
-#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev)
-
-struct linux_ebus {
-       struct of_device                ofdev;
-       struct linux_ebus               *next;
-       struct linux_ebus_device        *devices;
-       struct pci_dev                  *self;
-       int                              index;
-       int                              is_rio;
-       struct device_node              *prom_node;
-};
-#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev)
-
-struct ebus_dma_info {
-       spinlock_t      lock;
-       void __iomem    *regs;
-
-       unsigned int    flags;
-#define EBUS_DMA_FLAG_USE_EBDMA_HANDLER                0x00000001
-#define EBUS_DMA_FLAG_TCI_DISABLE              0x00000002
-
-       /* These are only valid is EBUS_DMA_FLAG_USE_EBDMA_HANDLER is
-        * set.
-        */
-       void (*callback)(struct ebus_dma_info *p, int event, void *cookie);
-       void *client_cookie;
-       unsigned int    irq;
-#define EBUS_DMA_EVENT_ERROR   1
-#define EBUS_DMA_EVENT_DMA     2
-#define EBUS_DMA_EVENT_DEVICE  4
-
-       unsigned char   name[64];
-};
-
-extern int ebus_dma_register(struct ebus_dma_info *p);
-extern int ebus_dma_irq_enable(struct ebus_dma_info *p, int on);
-extern void ebus_dma_unregister(struct ebus_dma_info *p);
-extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr,
-                           size_t len);
-extern void ebus_dma_prepare(struct ebus_dma_info *p, int write);
-extern unsigned int ebus_dma_residue(struct ebus_dma_info *p);
-extern unsigned int ebus_dma_addr(struct ebus_dma_info *p);
-extern void ebus_dma_enable(struct ebus_dma_info *p, int on);
-
-extern struct linux_ebus               *ebus_chain;
-
-extern void ebus_init(void);
-
-#define for_each_ebus(bus)                                             \
-        for((bus) = ebus_chain; (bus); (bus) = (bus)->next)
-
-#define for_each_ebusdev(dev, bus)                                     \
-        for((dev) = (bus)->devices; (dev); (dev) = (dev)->next)
-
-#define for_each_edevchild(dev, child)                                 \
-        for((child) = (dev)->children; (child); (child) = (child)->next)
-
-#endif /* !(__SPARC64_EBUS_H) */
+#include <asm-sparc/ebus.h>
index 0818a1308f4e7a252b213d07a0025f5e70c72dca..f256d9472c8283c3b7193f68f088ee94995b714f 100644 (file)
@@ -1,217 +1 @@
-#ifndef __ASM_SPARC64_ELF_H
-#define __ASM_SPARC64_ELF_H
-
-/*
- * ELF register definitions..
- */
-
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-#include <asm/spitfire.h>
-
-/*
- * Sparc section types
- */
-#define STT_REGISTER           13
-
-/*
- * Sparc ELF relocation types
- */
-#define        R_SPARC_NONE            0
-#define        R_SPARC_8               1
-#define        R_SPARC_16              2
-#define        R_SPARC_32              3
-#define        R_SPARC_DISP8           4
-#define        R_SPARC_DISP16          5
-#define        R_SPARC_DISP32          6
-#define        R_SPARC_WDISP30         7
-#define        R_SPARC_WDISP22         8
-#define        R_SPARC_HI22            9
-#define        R_SPARC_22              10
-#define        R_SPARC_13              11
-#define        R_SPARC_LO10            12
-#define        R_SPARC_GOT10           13
-#define        R_SPARC_GOT13           14
-#define        R_SPARC_GOT22           15
-#define        R_SPARC_PC10            16
-#define        R_SPARC_PC22            17
-#define        R_SPARC_WPLT30          18
-#define        R_SPARC_COPY            19
-#define        R_SPARC_GLOB_DAT        20
-#define        R_SPARC_JMP_SLOT        21
-#define        R_SPARC_RELATIVE        22
-#define        R_SPARC_UA32            23
-#define R_SPARC_PLT32          24
-#define R_SPARC_HIPLT22                25
-#define R_SPARC_LOPLT10                26
-#define R_SPARC_PCPLT32                27
-#define R_SPARC_PCPLT22                28
-#define R_SPARC_PCPLT10                29
-#define R_SPARC_10             30
-#define R_SPARC_11             31
-#define R_SPARC_64             32
-#define R_SPARC_OLO10          33
-#define R_SPARC_WDISP16                40
-#define R_SPARC_WDISP19                41
-#define R_SPARC_7              43
-#define R_SPARC_5              44
-#define R_SPARC_6              45
-
-/* Bits present in AT_HWCAP, primarily for Sparc32.  */
-
-#define HWCAP_SPARC_FLUSH       1    /* CPU supports flush instruction. */
-#define HWCAP_SPARC_STBAR       2
-#define HWCAP_SPARC_SWAP        4
-#define HWCAP_SPARC_MULDIV      8
-#define HWCAP_SPARC_V9         16
-#define HWCAP_SPARC_ULTRA3     32
-#define HWCAP_SPARC_BLKINIT    64
-#define HWCAP_SPARC_N2         128
-
-#define CORE_DUMP_USE_REGSET
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_ARCH               EM_SPARCV9
-#define ELF_CLASS              ELFCLASS64
-#define ELF_DATA               ELFDATA2MSB
-
-/* Format of 64-bit elf_gregset_t is:
- *     G0 --> G7
- *     O0 --> O7
- *     L0 --> L7
- *     I0 --> I7
- *     TSTATE
- *     TPC
- *     TNPC
- *     Y
- */
-typedef unsigned long elf_greg_t;
-#define ELF_NGREG 36
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct {
-       unsigned long   pr_regs[32];
-       unsigned long   pr_fsr;
-       unsigned long   pr_gsr;
-       unsigned long   pr_fprs;
-} elf_fpregset_t;
-
-/* Format of 32-bit elf_gregset_t is:
- *     G0 --> G7
- *     O0 --> O7
- *     L0 --> L7
- *     I0 --> I7
- *     PSR, PC, nPC, Y, WIM, TBR
- */
-typedef unsigned int compat_elf_greg_t;
-#define COMPAT_ELF_NGREG 38
-typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
-
-typedef struct {
-       union {
-               unsigned int    pr_regs[32];
-               unsigned long   pr_dregs[16];
-       } pr_fr;
-       unsigned int __unused;
-       unsigned int    pr_fsr;
-       unsigned char   pr_qcnt;
-       unsigned char   pr_q_entrysize;
-       unsigned char   pr_en;
-       unsigned int    pr_q[64];
-} compat_elf_fpregset_t;
-
-/* UltraSparc extensions.  Still unused, but will be eventually.  */
-typedef struct {
-       unsigned int pr_type;
-       unsigned int pr_align;
-       union {
-               struct {
-                       union {
-                               unsigned int    pr_regs[32];
-                               unsigned long   pr_dregs[16];
-                               long double     pr_qregs[8];
-                       } pr_xfr;
-               } pr_v8p;
-               unsigned int    pr_xfsr;
-               unsigned int    pr_fprs;
-               unsigned int    pr_xg[8];
-               unsigned int    pr_xo[8];
-               unsigned long   pr_tstate;
-               unsigned int    pr_filler[8];
-       } pr_un;
-} elf_xregset_t;
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x)              ((x)->e_machine == ELF_ARCH)
-#define compat_elf_check_arch(x)       ((x)->e_machine == EM_SPARC || \
-                                        (x)->e_machine == EM_SPARC32PLUS)
-#define compat_start_thread            start_thread32
-
-#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE      PAGE_SIZE
-
-/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
-   use of this is to invoke "./ld.so someprog" to test out a new version of
-   the loader.  We need to make sure that it is out of the way of the program
-   that it will "exec", and that there is sufficient room for the brk.  */
-
-#define ELF_ET_DYN_BASE                0x0000010000000000UL
-#define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
-
-
-/* This yields a mask that user programs can use to figure out what
-   instruction set this cpu supports.  */
-
-/* On Ultra, we support all of the v8 capabilities. */
-static inline unsigned int sparc64_elf_hwcap(void)
-{
-       unsigned int cap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR |
-                           HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV |
-                           HWCAP_SPARC_V9);
-
-       if (tlb_type == cheetah || tlb_type == cheetah_plus)
-               cap |= HWCAP_SPARC_ULTRA3;
-       else if (tlb_type == hypervisor) {
-               if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 ||
-                   sun4v_chip_type == SUN4V_CHIP_NIAGARA2)
-                       cap |= HWCAP_SPARC_BLKINIT;
-               if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2)
-                       cap |= HWCAP_SPARC_N2;
-       }
-
-       return cap;
-}
-
-#define ELF_HWCAP      sparc64_elf_hwcap();
-
-/* This yields a string that ld.so will use to load implementation
-   specific libraries for optimization.  This is more specific in
-   intent than poking at uname or /proc/cpuinfo.  */
-
-#define ELF_PLATFORM   (NULL)
-
-#define SET_PERSONALITY(ex, ibcs2)                     \
-do {   unsigned long new_flags = current_thread_info()->flags; \
-       new_flags &= _TIF_32BIT;                        \
-       if ((ex).e_ident[EI_CLASS] == ELFCLASS32)       \
-               new_flags |= _TIF_32BIT;                \
-       else                                            \
-               new_flags &= ~_TIF_32BIT;               \
-       if ((current_thread_info()->flags & _TIF_32BIT) \
-           != new_flags)                               \
-               set_thread_flag(TIF_ABI_PENDING);       \
-       else                                            \
-               clear_thread_flag(TIF_ABI_PENDING);     \
-       /* flush_thread will update pgd cache */        \
-       if (ibcs2)                                      \
-               set_personality(PER_SVR4);              \
-       else if (current->personality != PER_LINUX32)   \
-               set_personality(PER_LINUX);             \
-} while (0)
-
-#endif /* !(__ASM_SPARC64_ELF_H) */
+#include <asm-sparc/elf.h>
index a5668a082b143bc354cb2479524a10130a70f5a5..a2cc0ca334bae470bbcf5748aac594d76693b32c 100644 (file)
@@ -1,103 +1 @@
-/*
- *
- * envctrl.h: Definitions for access to the i2c environment
- *            monitoring on Ultrasparc systems.
- *
- * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
- * Copyright (C) 2000  Vinh Truong  (vinh.truong@eng.sun.com)
- * VT - Add all ioctl commands and environment status definitions 
- * VT - Add application note 
- */
-#ifndef _SPARC64_ENVCTRL_H
-#define _SPARC64_ENVCTRL_H 1
-
-#include <linux/ioctl.h>
-
-/* Application note:
- *
- * The driver supports 4 operations: open(), close(), ioctl(), read()
- * The device name is /dev/envctrl.
- * Below is sample usage:
- *
- *     fd = open("/dev/envtrl", O_RDONLY);
- *     if (ioctl(fd, ENVCTRL_READ_SHUTDOWN_TEMPERATURE, 0) < 0)
- *             printf("error\n");
- *     ret = read(fd, buf, 10);
- *     close(fd);
- *
- * Notice in the case of cpu voltage and temperature, the default is
- * cpu0.  If we need to know the info of cpu1, cpu2, cpu3, we need to
- * pass in cpu number in ioctl() last parameter.  For example, to
- * get the voltage of cpu2:
- *
- *     ioctlbuf[0] = 2;
- *     if (ioctl(fd, ENVCTRL_READ_CPU_VOLTAGE, ioctlbuf) < 0)
- *             printf("error\n");
- *     ret = read(fd, buf, 10);
- *
- * All the return values are in ascii.  So check read return value
- * and do appropriate conversions in your application.
- */
-
-/* IOCTL commands */
-
-/* Note: these commands reflect possible monitor features.
- * Some boards choose to support some of the features only.
- */
-#define ENVCTRL_RD_CPU_TEMPERATURE     _IOR('p', 0x40, int)
-#define ENVCTRL_RD_CPU_VOLTAGE         _IOR('p', 0x41, int)
-#define ENVCTRL_RD_FAN_STATUS          _IOR('p', 0x42, int)
-#define ENVCTRL_RD_WARNING_TEMPERATURE _IOR('p', 0x43, int)
-#define ENVCTRL_RD_SHUTDOWN_TEMPERATURE        _IOR('p', 0x44, int)
-#define ENVCTRL_RD_VOLTAGE_STATUS      _IOR('p', 0x45, int)
-#define ENVCTRL_RD_SCSI_TEMPERATURE    _IOR('p', 0x46, int)
-#define ENVCTRL_RD_ETHERNET_TEMPERATURE        _IOR('p', 0x47, int)
-#define ENVCTRL_RD_MTHRBD_TEMPERATURE  _IOR('p', 0x48, int)
-
-#define ENVCTRL_RD_GLOBALADDRESS       _IOR('p', 0x49, int)
-
-/* Read return values for a voltage status request. */
-#define ENVCTRL_VOLTAGE_POWERSUPPLY_GOOD       0x01
-#define ENVCTRL_VOLTAGE_BAD                    0x02
-#define ENVCTRL_POWERSUPPLY_BAD                        0x03
-#define ENVCTRL_VOLTAGE_POWERSUPPLY_BAD                0x04
-
-/* Read return values for a fan status request.
- * A failure match means either the fan fails or
- * the fan is not connected.  Some boards have optional
- * connectors to connect extra fans.
- *
- * There are maximum 8 monitor fans.  Some are cpu fans
- * some are system fans.  The mask below only indicates
- * fan by order number.
- * Below is a sample application:
- *
- *     if (ioctl(fd, ENVCTRL_READ_FAN_STATUS, 0) < 0) {
- *             printf("ioctl fan failed\n");
- *     }
- *     if (read(fd, rslt, 1) <= 0) {
- *             printf("error or fan not monitored\n");
- *     } else {
- *             if (rslt[0] == ENVCTRL_ALL_FANS_GOOD) {
- *                     printf("all fans good\n");
- *     } else if (rslt[0] == ENVCTRL_ALL_FANS_BAD) {
- *             printf("all fans bad\n");
- *     } else {
- *             if (rslt[0] & ENVCTRL_FAN0_FAILURE_MASK) {
- *                     printf("fan 0 failed or not connected\n");
- *     }
- *     ......
- */  
-
-#define ENVCTRL_ALL_FANS_GOOD                  0x00
-#define ENVCTRL_FAN0_FAILURE_MASK              0x01
-#define ENVCTRL_FAN1_FAILURE_MASK              0x02
-#define ENVCTRL_FAN2_FAILURE_MASK              0x04
-#define ENVCTRL_FAN3_FAILURE_MASK              0x08
-#define ENVCTRL_FAN4_FAILURE_MASK              0x10
-#define ENVCTRL_FAN5_FAILURE_MASK              0x20
-#define ENVCTRL_FAN6_FAILURE_MASK              0x40
-#define ENVCTRL_FAN7_FAILURE_MASK              0x80
-#define ENVCTRL_ALL_FANS_BAD                   0xFF
-
-#endif /* !(_SPARC64_ENVCTRL_H) */
+#include <asm-sparc/envctrl.h>
index 520c08560d1b1bfcbaf6c35b4c07e87a143c4799..bedd0ef5f19cdbbec9b986f6fab41d1e77f47c67 100644 (file)
@@ -1,49 +1 @@
-#ifndef _SPARC64_ESTATE_H
-#define _SPARC64_ESTATE_H
-
-/* UltraSPARC-III E-cache Error Enable */
-#define ESTATE_ERROR_FMT       0x0000000000040000 /* Force MTAG ECC            */
-#define ESTATE_ERROR_FMESS     0x000000000003c000 /* Forced MTAG ECC val       */
-#define ESTATE_ERROR_FMD       0x0000000000002000 /* Force DATA ECC            */
-#define ESTATE_ERROR_FDECC     0x0000000000001ff0 /* Forced DATA ECC val       */
-#define ESTATE_ERROR_UCEEN     0x0000000000000008 /* See below                 */
-#define ESTATE_ERROR_NCEEN     0x0000000000000002 /* See below                 */
-#define ESTATE_ERROR_CEEN      0x0000000000000001 /* See below                 */
-
-/* UCEEN enables the fast_ECC_error trap for: 1) software correctable E-cache
- * errors 2) uncorrectable E-cache errors.  Such events only occur on reads
- * of the E-cache by the local processor for: 1) data loads 2) instruction
- * fetches 3) atomic operations.  Such events _cannot_ occur for: 1) merge
- * 2) writeback 2) copyout.  The AFSR bits associated with these traps are
- * UCC and UCU.
- */
-
-/* NCEEN enables instruction_access_error, data_access_error, and ECC_error traps
- * for uncorrectable ECC errors and system errors.
- *
- * Uncorrectable system bus data error or MTAG ECC error, system bus TimeOUT,
- * or system bus BusERR:
- * 1) As the result of an instruction fetch, will generate instruction_access_error
- * 2) As the result of a load etc. will generate data_access_error.
- * 3) As the result of store merge completion, writeback, or copyout will
- *    generate a disrupting ECC_error trap.
- * 4) As the result of such errors on instruction vector fetch can generate any
- *    of the 3 trap types.
- *
- * The AFSR bits associated with these traps are EMU, EDU, WDU, CPU, IVU, UE,
- * BERR, and TO.
- */
-
-/* CEEN enables the ECC_error trap for hardware corrected ECC errors.  System bus
- * reads resulting in a hardware corrected data or MTAG ECC error will generate an
- * ECC_error disrupting trap with this bit enabled.
- *
- * This same trap will also be generated when a hardware corrected ECC error results
- * during store merge, writeback, and copyout operations.
- */
-
-/* In general, if the trap enable bits above are disabled the AFSR bits will still
- * log the events even though the trap will not be generated by the processor.
- */
-
-#endif /* _SPARC64_ESTATE_H */
+#include <asm-sparc/estate.h>
index b9215a0907d3f429352edd0298dbc12dffbb8dca..c17edf8c7bc4df69f053eb1f3ea10fa1e6adb428 100644 (file)
@@ -1,330 +1 @@
-#ifndef __LINUX_FBIO_H
-#define __LINUX_FBIO_H
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-/* Constants used for fbio SunOS compatibility */
-/* (C) 1996 Miguel de Icaza */
-
-/* Frame buffer types */
-#define FBTYPE_NOTYPE           -1
-#define FBTYPE_SUN1BW           0   /* mono */
-#define FBTYPE_SUN1COLOR        1 
-#define FBTYPE_SUN2BW           2 
-#define FBTYPE_SUN2COLOR        3 
-#define FBTYPE_SUN2GP           4 
-#define FBTYPE_SUN5COLOR        5 
-#define FBTYPE_SUN3COLOR        6 
-#define FBTYPE_MEMCOLOR         7 
-#define FBTYPE_SUN4COLOR        8 
-#define FBTYPE_NOTSUN1          9 
-#define FBTYPE_NOTSUN2          10
-#define FBTYPE_NOTSUN3          11
-#define FBTYPE_SUNFAST_COLOR    12  /* cg6 */
-#define FBTYPE_SUNROP_COLOR     13
-#define FBTYPE_SUNFB_VIDEO      14
-#define FBTYPE_SUNGIFB          15
-#define FBTYPE_SUNGPLAS         16
-#define FBTYPE_SUNGP3           17
-#define FBTYPE_SUNGT            18
-#define FBTYPE_SUNLEO           19      /* zx Leo card */
-#define FBTYPE_MDICOLOR         20      /* cg14 */
-#define FBTYPE_TCXCOLOR                21      /* SUNW,tcx card */
-
-#define FBTYPE_LASTPLUSONE      21     /* This is not last + 1 in fact... */
-
-/* Does not seem to be listed in the Sun file either */
-#define FBTYPE_CREATOR          22
-#define FBTYPE_PCI_IGA1682     23
-#define FBTYPE_P9100COLOR      24
-
-#define FBTYPE_PCI_GENERIC     1000
-#define FBTYPE_PCI_MACH64      1001
-
-/* fbio ioctls */
-/* Returned by FBIOGTYPE */
-struct  fbtype {
-        int     fb_type;        /* fb type, see above */
-        int     fb_height;      /* pixels */
-        int     fb_width;       /* pixels */
-        int     fb_depth;
-        int     fb_cmsize;      /* color map entries */
-        int     fb_size;        /* fb size in bytes */
-};
-#define FBIOGTYPE _IOR('F', 0, struct fbtype)
-
-struct  fbcmap {
-        int             index;          /* first element (0 origin) */
-        int             count;
-        unsigned char   __user *red;
-        unsigned char   __user *green;
-        unsigned char   __user *blue;
-};
-
-#ifdef __KERNEL__
-#define FBIOPUTCMAP_SPARC _IOW('F', 3, struct fbcmap)
-#define FBIOGETCMAP_SPARC _IOW('F', 4, struct fbcmap)
-#else
-#define FBIOPUTCMAP _IOW('F', 3, struct fbcmap)
-#define FBIOGETCMAP _IOW('F', 4, struct fbcmap)
-#endif
-
-/* # of device specific values */
-#define FB_ATTR_NDEVSPECIFIC    8
-/* # of possible emulations */
-#define FB_ATTR_NEMUTYPES       4
-struct fbsattr {
-        int     flags;
-        int     emu_type;      /* -1 if none */
-        int     dev_specific[FB_ATTR_NDEVSPECIFIC];
-};
-struct fbgattr {
-        int     real_type;     /* real frame buffer type */
-        int     owner;         /* unknown */
-        struct fbtype fbtype;  /* real frame buffer fbtype */
-        struct fbsattr sattr;   
-        int     emu_types[FB_ATTR_NEMUTYPES]; /* supported emulations */
-};
-#define FBIOSATTR  _IOW('F', 5, struct fbgattr) /* Unsupported: */
-#define FBIOGATTR  _IOR('F', 6, struct fbgattr)        /* supported */
-
-#define FBIOSVIDEO _IOW('F', 7, int)
-#define FBIOGVIDEO _IOR('F', 8, int)
-
-struct fbcursor {
-        short set;              /* what to set, choose from the list above */
-        short enable;           /* cursor on/off */
-        struct fbcurpos pos;    /* cursor position */
-        struct fbcurpos hot;    /* cursor hot spot */
-        struct fbcmap cmap;     /* color map info */
-        struct fbcurpos size;   /* cursor bit map size */
-        char __user *image;     /* cursor image bits */
-        char __user *mask;      /* cursor mask bits */
-};
-
-/* set/get cursor attributes/shape */
-#define FBIOSCURSOR     _IOW('F', 24, struct fbcursor)
-#define FBIOGCURSOR     _IOWR('F', 25, struct fbcursor)
-/* set/get cursor position */
-#define FBIOSCURPOS     _IOW('F', 26, struct fbcurpos)
-#define FBIOGCURPOS     _IOW('F', 27, struct fbcurpos)
-/* get max cursor size */
-#define FBIOGCURMAX     _IOR('F', 28, struct fbcurpos)
-
-/* wid manipulation */
-struct fb_wid_alloc {
-#define FB_WID_SHARED_8                0
-#define FB_WID_SHARED_24       1
-#define FB_WID_DBL_8           2
-#define FB_WID_DBL_24          3
-       __u32   wa_type;
-       __s32   wa_index;       /* Set on return */
-       __u32   wa_count;       
-};
-struct fb_wid_item {
-       __u32   wi_type;
-       __s32   wi_index;
-       __u32   wi_attrs;
-       __u32   wi_values[32];
-};
-struct fb_wid_list {
-       __u32   wl_flags;
-       __u32   wl_count;
-       struct fb_wid_item      *wl_list;
-};
-
-#define FBIO_WID_ALLOC _IOWR('F', 30, struct fb_wid_alloc)
-#define FBIO_WID_FREE  _IOW('F', 31, struct fb_wid_alloc)
-#define FBIO_WID_PUT   _IOW('F', 32, struct fb_wid_list)
-#define FBIO_WID_GET   _IOWR('F', 33, struct fb_wid_list)
-
-/* Creator ioctls */
-#define FFB_IOCTL      ('F'<<8)
-#define FFB_SYS_INFO           (FFB_IOCTL|80)
-#define FFB_CLUTREAD           (FFB_IOCTL|81)
-#define FFB_CLUTPOST           (FFB_IOCTL|82)
-#define FFB_SETDIAGMODE                (FFB_IOCTL|83)
-#define FFB_GETMONITORID       (FFB_IOCTL|84)
-#define FFB_GETVIDEOMODE       (FFB_IOCTL|85)
-#define FFB_SETVIDEOMODE       (FFB_IOCTL|86)
-#define FFB_SETSERVER          (FFB_IOCTL|87)
-#define FFB_SETOVCTL           (FFB_IOCTL|88)
-#define FFB_GETOVCTL           (FFB_IOCTL|89)
-#define FFB_GETSAXNUM          (FFB_IOCTL|90)
-#define FFB_FBDEBUG            (FFB_IOCTL|91)
-
-/* Cg14 ioctls */
-#define MDI_IOCTL          ('M'<<8)
-#define MDI_RESET          (MDI_IOCTL|1)
-#define MDI_GET_CFGINFO    (MDI_IOCTL|2)
-#define MDI_SET_PIXELMODE  (MDI_IOCTL|3)
-#    define MDI_32_PIX     32
-#    define MDI_16_PIX     16
-#    define MDI_8_PIX      8
-
-struct mdi_cfginfo {
-       int     mdi_ncluts;     /* Number of implemented CLUTs in this MDI */
-        int     mdi_type;       /* FBTYPE name */
-        int     mdi_height;     /* height */
-        int     mdi_width;      /* widht */
-        int     mdi_size;       /* available ram */
-        int     mdi_mode;       /* 8bpp, 16bpp or 32bpp */
-        int     mdi_pixfreq;    /* pixel clock (from PROM) */
-};
-
-/* SparcLinux specific ioctl for the MDI, should be replaced for
- * the SET_XLUT/SET_CLUTn ioctls instead
- */
-#define MDI_CLEAR_XLUT       (MDI_IOCTL|9)
-
-/* leo & ffb ioctls */
-struct fb_clut_alloc {
-       __u32   clutid; /* Set on return */
-       __u32   flag;
-       __u32   index;
-};
-
-struct fb_clut {
-#define FB_CLUT_WAIT   0x00000001      /* Not yet implemented */
-       __u32   flag;
-       __u32   clutid;
-       __u32   offset;
-       __u32   count;
-       char *  red;
-       char *  green;
-       char *  blue;
-};
-
-struct fb_clut32 {
-       __u32   flag;
-       __u32   clutid;
-       __u32   offset;
-       __u32   count;
-       __u32   red;
-       __u32   green;
-       __u32   blue;
-};
-
-#define LEO_CLUTALLOC  _IOWR('L', 53, struct fb_clut_alloc)
-#define LEO_CLUTFREE   _IOW('L', 54, struct fb_clut_alloc)
-#define LEO_CLUTREAD   _IOW('L', 55, struct fb_clut)
-#define LEO_CLUTPOST   _IOW('L', 56, struct fb_clut)
-#define LEO_SETGAMMA   _IOW('L', 68, int) /* Not yet implemented */
-#define LEO_GETGAMMA   _IOR('L', 69, int) /* Not yet implemented */
-
-#ifdef __KERNEL__
-/* Addresses on the fd of a cgsix that are mappable */
-#define CG6_FBC    0x70000000
-#define CG6_TEC    0x70001000
-#define CG6_BTREGS 0x70002000
-#define CG6_FHC    0x70004000
-#define CG6_THC    0x70005000
-#define CG6_ROM    0x70006000
-#define CG6_RAM    0x70016000
-#define CG6_DHC    0x80000000
-
-#define CG3_MMAP_OFFSET 0x4000000
-
-/* Addresses on the fd of a tcx that are mappable */
-#define TCX_RAM8BIT            0x00000000
-#define TCX_RAM24BIT                   0x01000000
-#define TCX_UNK3               0x10000000
-#define TCX_UNK4               0x20000000
-#define TCX_CONTROLPLANE       0x28000000
-#define TCX_UNK6               0x30000000
-#define TCX_UNK7               0x38000000
-#define TCX_TEC                0x70000000
-#define TCX_BTREGS             0x70002000
-#define TCX_THC                0x70004000
-#define TCX_DHC                0x70008000
-#define TCX_ALT                        0x7000a000
-#define TCX_SYNC               0x7000e000
-#define TCX_UNK2               0x70010000
-
-/* CG14 definitions */
-
-/* Offsets into the OBIO space: */
-#define CG14_REGS        0       /* registers */
-#define CG14_CURSORREGS  0x1000  /* cursor registers */
-#define CG14_DACREGS     0x2000  /* DAC registers */
-#define CG14_XLUT        0x3000  /* X Look Up Table -- ??? */
-#define CG14_CLUT1       0x4000  /* Color Look Up Table */
-#define CG14_CLUT2       0x5000  /* Color Look Up Table */
-#define CG14_CLUT3       0x6000  /* Color Look Up Table */
-#define CG14_AUTO       0xf000
-
-#endif /* KERNEL */
-
-/* These are exported to userland for applications to use */
-/* Mappable offsets for the cg14: control registers */
-#define MDI_DIRECT_MAP 0x10000000
-#define MDI_CTLREG_MAP 0x20000000
-#define MDI_CURSOR_MAP 0x30000000
-#define MDI_SHDW_VRT_MAP 0x40000000
-
-/* Mappable offsets for the cg14: frame buffer resolutions */
-/* 32 bits */
-#define MDI_CHUNKY_XBGR_MAP 0x50000000
-#define MDI_CHUNKY_BGR_MAP 0x60000000
-
-/* 16 bits */
-#define MDI_PLANAR_X16_MAP 0x70000000
-#define MDI_PLANAR_C16_MAP 0x80000000
-
-/* 8 bit is done as CG3 MMAP offset */
-/* 32 bits, planar */
-#define MDI_PLANAR_X32_MAP 0x90000000
-#define MDI_PLANAR_B32_MAP 0xa0000000
-#define MDI_PLANAR_G32_MAP 0xb0000000
-#define MDI_PLANAR_R32_MAP 0xc0000000
-
-/* Mappable offsets on leo */
-#define LEO_SS0_MAP            0x00000000
-#define LEO_LC_SS0_USR_MAP     0x00800000
-#define LEO_LD_SS0_MAP         0x00801000
-#define LEO_LX_CURSOR_MAP      0x00802000
-#define LEO_SS1_MAP            0x00803000
-#define LEO_LC_SS1_USR_MAP     0x01003000
-#define LEO_LD_SS1_MAP         0x01004000
-#define LEO_UNK_MAP            0x01005000
-#define LEO_LX_KRN_MAP         0x01006000
-#define LEO_LC_SS0_KRN_MAP     0x01007000
-#define LEO_LC_SS1_KRN_MAP     0x01008000
-#define LEO_LD_GBL_MAP         0x01009000
-#define LEO_UNK2_MAP           0x0100a000
-
-#ifdef __KERNEL__
-struct  fbcmap32 {
-       int             index;          /* first element (0 origin) */
-       int             count;
-       u32             red;
-       u32             green;
-       u32             blue;
-};
-
-#define FBIOPUTCMAP32  _IOW('F', 3, struct fbcmap32)
-#define FBIOGETCMAP32  _IOW('F', 4, struct fbcmap32)
-
-struct fbcursor32 {
-       short set;              /* what to set, choose from the list above */
-       short enable;           /* cursor on/off */
-       struct fbcurpos pos;    /* cursor position */
-       struct fbcurpos hot;    /* cursor hot spot */
-       struct fbcmap32 cmap;   /* color map info */
-       struct fbcurpos size;   /* cursor bit map size */
-       u32     image;          /* cursor image bits */
-       u32     mask;           /* cursor mask bits */
-};
-
-#define FBIOSCURSOR32  _IOW('F', 24, struct fbcursor32)
-#define FBIOGCURSOR32  _IOW('F', 25, struct fbcursor32)
-#endif
-
-#endif /* __LINUX_FBIO_H */
+#include <asm-sparc/fbio.h>
index 8a09ca7aa2f22854ebde88908fddf5c6726d91b4..8b1beae48cd1a9ea3f69a7236cb30fda3261cc6d 100644 (file)
@@ -1,35 +1 @@
-#ifndef _SPARC64_FCNTL_H
-#define _SPARC64_FCNTL_H
-
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
-   located on an ext2 file system */
-#define O_NDELAY       0x0004
-#define O_APPEND       0x0008
-#define FASYNC         0x0040  /* fcntl, for BSD compatibility */
-#define O_CREAT                0x0200  /* not fcntl */
-#define O_TRUNC                0x0400  /* not fcntl */
-#define O_EXCL         0x0800  /* not fcntl */
-#define O_SYNC         0x2000
-#define O_NONBLOCK     0x4000
-#define O_NOCTTY       0x8000  /* not fcntl */
-#define O_LARGEFILE    0x40000
-#define O_DIRECT        0x100000 /* direct disk access hint */
-#define O_NOATIME      0x200000
-#define O_CLOEXEC      0x400000
-
-#define F_GETOWN       5       /*  for sockets. */
-#define F_SETOWN       6       /*  for sockets. */
-#define F_GETLK                7
-#define F_SETLK                8
-#define F_SETLKW       9
-
-/* for posix fcntl() and lockf() */
-#define F_RDLCK                1
-#define F_WRLCK                2
-#define F_UNLCK                3
-
-#define __ARCH_FLOCK_PAD       short __unused;
-
-#include <asm-generic/fcntl.h>
-
-#endif /* !(_SPARC64_FCNTL_H) */
+#include <asm-sparc/fcntl.h>
index ddffcdfbc984afa7a8e75c17756cf163af13e03a..73eb04c19c47f8314228a96213f02e73559e6cd7 100644 (file)
@@ -1,131 +1 @@
-/*
- * fhc.h: Structures for central/fhc pseudo driver on Sunfire/Starfire/Wildfire.
- *
- * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com)
- */
-
-#ifndef _SPARC64_FHC_H
-#define _SPARC64_FHC_H
-
-#include <linux/timer.h>
-
-#include <asm/oplib.h>
-#include <asm/prom.h>
-#include <asm/upa.h>
-
-struct linux_fhc;
-
-/* Clock board register offsets. */
-#define CLOCK_CTRL     0x00UL  /* Main control */
-#define CLOCK_STAT1    0x10UL  /* Status one */
-#define CLOCK_STAT2    0x20UL  /* Status two */
-#define CLOCK_PWRSTAT  0x30UL  /* Power status */
-#define CLOCK_PWRPRES  0x40UL  /* Power presence */
-#define CLOCK_TEMP     0x50UL  /* Temperature */
-#define CLOCK_IRQDIAG  0x60UL  /* IRQ diagnostics */
-#define CLOCK_PWRSTAT2 0x70UL  /* Power status two */
-
-#define CLOCK_CTRL_LLED                0x04    /* Left LED, 0 == on */
-#define CLOCK_CTRL_MLED                0x02    /* Mid LED, 1 == on */
-#define CLOCK_CTRL_RLED                0x01    /* RIght LED, 1 == on */
-
-struct linux_central {
-       struct linux_fhc                *child;
-       unsigned long                   cfreg;
-       unsigned long                   clkregs;
-       unsigned long                   clkver;
-       int                             slots;
-       struct device_node              *prom_node;
-
-       struct linux_prom_ranges        central_ranges[PROMREG_MAX];
-       int                             num_central_ranges;
-};
-
-/* Firehose controller register offsets */
-struct fhc_regs {
-       unsigned long                   pregs;  /* FHC internal regs */
-#define FHC_PREGS_ID   0x00UL  /* FHC ID */
-#define  FHC_ID_VERS           0xf0000000 /* Version of this FHC               */
-#define  FHC_ID_PARTID         0x0ffff000 /* Part ID code (0x0f9f == FHC)      */
-#define  FHC_ID_MANUF          0x0000007e /* Manufacturer (0x3e == SUN's JEDEC)*/
-#define  FHC_ID_RESV           0x00000001 /* Read as one                       */
-#define FHC_PREGS_RCS  0x10UL  /* FHC Reset Control/Status Register */
-#define  FHC_RCS_POR           0x80000000 /* Last reset was a power cycle      */
-#define  FHC_RCS_SPOR          0x40000000 /* Last reset was sw power on reset  */
-#define  FHC_RCS_SXIR          0x20000000 /* Last reset was sw XIR reset       */
-#define  FHC_RCS_BPOR          0x10000000 /* Last reset was due to POR button  */
-#define  FHC_RCS_BXIR          0x08000000 /* Last reset was due to XIR button  */
-#define  FHC_RCS_WEVENT                0x04000000 /* CPU reset was due to wakeup event */
-#define  FHC_RCS_CFATAL                0x02000000 /* Centerplane Fatal Error signalled */
-#define  FHC_RCS_FENAB         0x01000000 /* Fatal errors elicit system reset  */
-#define FHC_PREGS_CTRL 0x20UL  /* FHC Control Register */
-#define  FHC_CONTROL_ICS       0x00100000 /* Ignore Centerplane Signals        */
-#define  FHC_CONTROL_FRST      0x00080000 /* Fatal Error Reset Enable          */
-#define  FHC_CONTROL_LFAT      0x00040000 /* AC/DC signalled a local error     */
-#define  FHC_CONTROL_SLINE     0x00010000 /* Firmware Synchronization Line     */
-#define  FHC_CONTROL_DCD       0x00008000 /* DC-->DC Converter Disable         */
-#define  FHC_CONTROL_POFF      0x00004000 /* AC/DC Controller PLL Disable      */
-#define  FHC_CONTROL_FOFF      0x00002000 /* FHC Controller PLL Disable        */
-#define  FHC_CONTROL_AOFF      0x00001000 /* CPU A SRAM/SBD Low Power Mode     */
-#define  FHC_CONTROL_BOFF      0x00000800 /* CPU B SRAM/SBD Low Power Mode     */
-#define  FHC_CONTROL_PSOFF     0x00000400 /* Turns off this FHC's power supply */
-#define  FHC_CONTROL_IXIST     0x00000200 /* 0=FHC tells clock board it exists */
-#define  FHC_CONTROL_XMSTR     0x00000100 /* 1=Causes this FHC to be XIR master*/
-#define  FHC_CONTROL_LLED      0x00000040 /* 0=Left LED ON                     */
-#define  FHC_CONTROL_MLED      0x00000020 /* 1=Middle LED ON                   */
-#define  FHC_CONTROL_RLED      0x00000010 /* 1=Right LED                       */
-#define  FHC_CONTROL_BPINS     0x00000003 /* Spare Bidirectional Pins          */
-#define FHC_PREGS_BSR  0x30UL  /* FHC Board Status Register */
-#define  FHC_BSR_DA64          0x00040000 /* Port A: 0=128bit 1=64bit data path */
-#define  FHC_BSR_DB64          0x00020000 /* Port B: 0=128bit 1=64bit data path */
-#define  FHC_BSR_BID           0x0001e000 /* Board ID                           */
-#define  FHC_BSR_SA            0x00001c00 /* Port A UPA Speed (from the pins)   */
-#define  FHC_BSR_SB            0x00000380 /* Port B UPA Speed (from the pins)   */
-#define  FHC_BSR_NDIAG         0x00000040 /* Not in Diag Mode                   */
-#define  FHC_BSR_NTBED         0x00000020 /* Not in TestBED Mode                */
-#define  FHC_BSR_NIA           0x0000001c /* Jumper, bit 18 in PROM space       */
-#define  FHC_BSR_SI            0x00000001 /* Spare input pin value              */
-#define FHC_PREGS_ECC  0x40UL  /* FHC ECC Control Register (16 bits) */
-#define FHC_PREGS_JCTRL        0xf0UL  /* FHC JTAG Control Register */
-#define  FHC_JTAG_CTRL_MENAB   0x80000000 /* Indicates this is JTAG Master      */
-#define  FHC_JTAG_CTRL_MNONE   0x40000000 /* Indicates no JTAG Master present   */
-#define FHC_PREGS_JCMD 0x100UL /* FHC JTAG Command Register */
-       unsigned long                   ireg;   /* FHC IGN reg */
-#define FHC_IREG_IGN   0x00UL  /* This FHC's IGN */
-       unsigned long                   ffregs; /* FHC fanfail regs */
-#define FHC_FFREGS_IMAP        0x00UL  /* FHC Fanfail IMAP */
-#define FHC_FFREGS_ICLR        0x10UL  /* FHC Fanfail ICLR */
-       unsigned long                   sregs;  /* FHC system regs */
-#define FHC_SREGS_IMAP 0x00UL  /* FHC System IMAP */
-#define FHC_SREGS_ICLR 0x10UL  /* FHC System ICLR */
-       unsigned long                   uregs;  /* FHC uart regs */
-#define FHC_UREGS_IMAP 0x00UL  /* FHC Uart IMAP */
-#define FHC_UREGS_ICLR 0x10UL  /* FHC Uart ICLR */
-       unsigned long                   tregs;  /* FHC TOD regs */
-#define FHC_TREGS_IMAP 0x00UL  /* FHC TOD IMAP */
-#define FHC_TREGS_ICLR 0x10UL  /* FHC TOD ICLR */
-};
-
-struct linux_fhc {
-       struct linux_fhc                *next;
-       struct linux_central            *parent;        /* NULL if not central FHC */
-       struct fhc_regs                 fhc_regs;
-       int                             board;
-       int                             jtag_master;
-       struct device_node              *prom_node;
-
-       struct linux_prom_ranges        fhc_ranges[PROMREG_MAX];
-       int                             num_fhc_ranges;
-};
-
-extern struct linux_central *central_bus;
-
-extern void apply_central_ranges(struct linux_central *central, 
-                                struct linux_prom_registers *regs,
-                                int nregs);
-
-extern void apply_fhc_ranges(struct linux_fhc *fhc, 
-                            struct linux_prom_registers *regs,
-                            int nregs);
-
-#endif /* !(_SPARC64_FHC_H) */
+#include <asm-sparc/fhc.h>
index ca19f80a9b7d96bab4494525abb248cd88e3c7a1..214878114436d5735558511b1a00ae0e753bc32d 100644 (file)
@@ -1,782 +1 @@
-/* floppy.h: Sparc specific parts of the Floppy driver.
- *
- * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net)
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *
- * Ultra/PCI support added: Sep 1997  Eddie C. Dost  (ecd@skynet.be)
- */
-
-#ifndef __ASM_SPARC64_FLOPPY_H
-#define __ASM_SPARC64_FLOPPY_H
-
-#include <linux/init.h>
-#include <linux/pci.h>
-
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/idprom.h>
-#include <asm/oplib.h>
-#include <asm/auxio.h>
-#include <asm/sbus.h>
-#include <asm/irq.h>
-
-
-/*
- * Define this to enable exchanging drive 0 and 1 if only drive 1 is
- * probed on PCI machines.
- */
-#undef PCI_FDC_SWAP_DRIVES
-
-
-/* References:
- * 1) Netbsd Sun floppy driver.
- * 2) NCR 82077 controller manual
- * 3) Intel 82077 controller manual
- */
-struct sun_flpy_controller {
-       volatile unsigned char status1_82077; /* Auxiliary Status reg. 1 */
-       volatile unsigned char status2_82077; /* Auxiliary Status reg. 2 */
-       volatile unsigned char dor_82077;     /* Digital Output reg. */
-       volatile unsigned char tapectl_82077; /* Tape Control reg */
-       volatile unsigned char status_82077;  /* Main Status Register. */
-#define drs_82077              status_82077   /* Digital Rate Select reg. */
-       volatile unsigned char data_82077;    /* Data fifo. */
-       volatile unsigned char ___unused;
-       volatile unsigned char dir_82077;     /* Digital Input reg. */
-#define dcr_82077              dir_82077      /* Config Control reg. */
-};
-
-/* 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 sbus_dev *floppy_sdev = NULL;
-
-struct sun_floppy_ops {
-       unsigned char   (*fd_inb) (unsigned long port);
-       void            (*fd_outb) (unsigned char value, unsigned long port);
-       void            (*fd_enable_dma) (void);
-       void            (*fd_disable_dma) (void);
-       void            (*fd_set_dma_mode) (int);
-       void            (*fd_set_dma_addr) (char *);
-       void            (*fd_set_dma_count) (int);
-       unsigned int    (*get_dma_residue) (void);
-       int             (*fd_request_irq) (void);
-       void            (*fd_free_irq) (void);
-       int             (*fd_eject) (int);
-};
-
-static struct sun_floppy_ops sun_fdops;
-
-#define fd_inb(port)              sun_fdops.fd_inb(port)
-#define fd_outb(value,port)       sun_fdops.fd_outb(value,port)
-#define fd_enable_dma()           sun_fdops.fd_enable_dma()
-#define fd_disable_dma()          sun_fdops.fd_disable_dma()
-#define fd_request_dma()          (0) /* nothing... */
-#define fd_free_dma()             /* nothing... */
-#define fd_clear_dma_ff()         /* nothing... */
-#define fd_set_dma_mode(mode)     sun_fdops.fd_set_dma_mode(mode)
-#define fd_set_dma_addr(addr)     sun_fdops.fd_set_dma_addr(addr)
-#define fd_set_dma_count(count)   sun_fdops.fd_set_dma_count(count)
-#define get_dma_residue(x)        sun_fdops.get_dma_residue()
-#define fd_cacheflush(addr, size) /* nothing... */
-#define fd_request_irq()          sun_fdops.fd_request_irq()
-#define fd_free_irq()             sun_fdops.fd_free_irq()
-#define fd_eject(drive)           sun_fdops.fd_eject(drive)
-
-/* Super paranoid... */
-#undef HAVE_DISABLE_HLT
-
-static int sun_floppy_types[2] = { 0, 0 };
-
-/* Here is where we catch the floppy driver trying to initialize,
- * therefore this is where we call the PROM device tree probing
- * routine etc. on the Sparc.
- */
-#define FLOPPY0_TYPE           sun_floppy_init()
-#define FLOPPY1_TYPE           sun_floppy_types[1]
-
-#define FDC1                   ((unsigned long)sun_fdc)
-
-#define N_FDC    1
-#define N_DRIVE  8
-
-/* No 64k boundary crossing problems on the Sparc. */
-#define CROSS_64KB(a,s) (0)
-
-static unsigned char sun_82077_fd_inb(unsigned long port)
-{
-       udelay(5);
-       switch(port & 7) {
-       default:
-               printk("floppy: Asked to read unknown port %lx\n", port);
-               panic("floppy: Port bolixed.");
-       case 4: /* FD_STATUS */
-               return sbus_readb(&sun_fdc->status_82077) & ~STATUS_DMA;
-       case 5: /* FD_DATA */
-               return sbus_readb(&sun_fdc->data_82077);
-       case 7: /* FD_DIR */
-               /* XXX: Is DCL on 0x80 in sun4m? */
-               return sbus_readb(&sun_fdc->dir_82077);
-       };
-       panic("sun_82072_fd_inb: How did I get here?");
-}
-
-static void sun_82077_fd_outb(unsigned char value, unsigned long port)
-{
-       udelay(5);
-       switch(port & 7) {
-       default:
-               printk("floppy: Asked to write to unknown port %lx\n", port);
-               panic("floppy: Port bolixed.");
-       case 2: /* FD_DOR */
-               /* Happily, the 82077 has a real DOR register. */
-               sbus_writeb(value, &sun_fdc->dor_82077);
-               break;
-       case 5: /* FD_DATA */
-               sbus_writeb(value, &sun_fdc->data_82077);
-               break;
-       case 7: /* FD_DCR */
-               sbus_writeb(value, &sun_fdc->dcr_82077);
-               break;
-       case 4: /* FD_STATUS */
-               sbus_writeb(value, &sun_fdc->status_82077);
-               break;
-       };
-       return;
-}
-
-/* For pseudo-dma (Sun floppy drives have no real DMA available to
- * them so we must eat the data fifo bytes directly ourselves) we have
- * three state variables.  doing_pdma tells our inline low-level
- * assembly floppy interrupt entry point whether it should sit and eat
- * bytes from the fifo or just transfer control up to the higher level
- * floppy interrupt c-code.  I tried very hard but I could not get the
- * pseudo-dma to work in c-code without getting many overruns and
- * underruns.  If non-zero, doing_pdma encodes the direction of
- * the transfer for debugging.  1=read 2=write
- */
-unsigned char *pdma_vaddr;
-unsigned long pdma_size;
-volatile int doing_pdma = 0;
-
-/* This is software state */
-char *pdma_base = NULL;
-unsigned long pdma_areasize;
-
-/* Common routines to all controller types on the Sparc. */
-static void sun_fd_disable_dma(void)
-{
-       doing_pdma = 0;
-       if (pdma_base) {
-               mmu_unlockarea(pdma_base, pdma_areasize);
-               pdma_base = NULL;
-       }
-}
-
-static void sun_fd_set_dma_mode(int mode)
-{
-       switch(mode) {
-       case DMA_MODE_READ:
-               doing_pdma = 1;
-               break;
-       case DMA_MODE_WRITE:
-               doing_pdma = 2;
-               break;
-       default:
-               printk("Unknown dma mode %d\n", mode);
-               panic("floppy: Giving up...");
-       }
-}
-
-static void sun_fd_set_dma_addr(char *buffer)
-{
-       pdma_vaddr = buffer;
-}
-
-static void sun_fd_set_dma_count(int length)
-{
-       pdma_size = length;
-}
-
-static void sun_fd_enable_dma(void)
-{
-       pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
-       pdma_base = pdma_vaddr;
-       pdma_areasize = pdma_size;
-}
-
-irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie)
-{
-       if (likely(doing_pdma)) {
-               void __iomem *stat = (void __iomem *) fdc_status;
-               unsigned char *vaddr = pdma_vaddr;
-               unsigned long size = pdma_size;
-               u8 val;
-
-               while (size) {
-                       val = readb(stat);
-                       if (unlikely(!(val & 0x80))) {
-                               pdma_vaddr = vaddr;
-                               pdma_size = size;
-                               return IRQ_HANDLED;
-                       }
-                       if (unlikely(!(val & 0x20))) {
-                               pdma_vaddr = vaddr;
-                               pdma_size = size;
-                               doing_pdma = 0;
-                               goto main_interrupt;
-                       }
-                       if (val & 0x40) {
-                               /* read */
-                               *vaddr++ = readb(stat + 1);
-                       } else {
-                               unsigned char data = *vaddr++;
-
-                               /* write */
-                               writeb(data, stat + 1);
-                       }
-                       size--;
-               }
-
-               pdma_vaddr = vaddr;
-               pdma_size = size;
-
-               /* Send Terminal Count pulse to floppy controller. */
-               val = readb(auxio_register);
-               val |= AUXIO_AUX1_FTCNT;
-               writeb(val, auxio_register);
-               val &= ~AUXIO_AUX1_FTCNT;
-               writeb(val, auxio_register);
-
-               doing_pdma = 0;
-       }
-
-main_interrupt:
-       return floppy_interrupt(irq, dev_cookie);
-}
-
-static int sun_fd_request_irq(void)
-{
-       static int once = 0;
-       int error;
-
-       if(!once) {
-               once = 1;
-
-               error = request_irq(FLOPPY_IRQ, sparc_floppy_irq, 
-                                   IRQF_DISABLED, "floppy", NULL);
-
-               return ((error == 0) ? 0 : -1);
-       }
-       return 0;
-}
-
-static void sun_fd_free_irq(void)
-{
-}
-
-static unsigned int sun_get_dma_residue(void)
-{
-       /* XXX This isn't really correct. XXX */
-       return 0;
-}
-
-static int sun_fd_eject(int drive)
-{
-       set_dor(0x00, 0xff, 0x90);
-       udelay(500);
-       set_dor(0x00, 0x6f, 0x00);
-       udelay(500);
-       return 0;
-}
-
-#ifdef CONFIG_PCI
-#include <asm/ebus.h>
-#include <asm/ns87303.h>
-
-static struct ebus_dma_info sun_pci_fd_ebus_dma;
-static struct pci_dev *sun_pci_ebus_dev;
-static int sun_pci_broken_drive = -1;
-
-struct sun_pci_dma_op {
-       unsigned int    addr;
-       int             len;
-       int             direction;
-       char            *buf;
-};
-static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
-static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
-
-extern irqreturn_t floppy_interrupt(int irq, void *dev_id);
-
-static unsigned char sun_pci_fd_inb(unsigned long port)
-{
-       udelay(5);
-       return inb(port);
-}
-
-static void sun_pci_fd_outb(unsigned char val, unsigned long port)
-{
-       udelay(5);
-       outb(val, port);
-}
-
-static void sun_pci_fd_broken_outb(unsigned char val, unsigned long port)
-{
-       udelay(5);
-       /*
-        * XXX: Due to SUN's broken floppy connector on AX and AXi
-        *      we need to turn on MOTOR_0 also, if the floppy is
-        *      jumpered to DS1 (like most PC floppies are). I hope
-        *      this does not hurt correct hardware like the AXmp.
-        *      (Eddie, Sep 12 1998).
-        */
-       if (port == ((unsigned long)sun_fdc) + 2) {
-               if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x20)) {
-                       val |= 0x10;
-               }
-       }
-       outb(val, port);
-}
-
-#ifdef PCI_FDC_SWAP_DRIVES
-static void sun_pci_fd_lde_broken_outb(unsigned char val, unsigned long port)
-{
-       udelay(5);
-       /*
-        * XXX: Due to SUN's broken floppy connector on AX and AXi
-        *      we need to turn on MOTOR_0 also, if the floppy is
-        *      jumpered to DS1 (like most PC floppies are). I hope
-        *      this does not hurt correct hardware like the AXmp.
-        *      (Eddie, Sep 12 1998).
-        */
-       if (port == ((unsigned long)sun_fdc) + 2) {
-               if (((val & 0x03) == sun_pci_broken_drive) && (val & 0x10)) {
-                       val &= ~(0x03);
-                       val |= 0x21;
-               }
-       }
-       outb(val, port);
-}
-#endif /* PCI_FDC_SWAP_DRIVES */
-
-static void sun_pci_fd_enable_dma(void)
-{
-       BUG_ON((NULL == sun_pci_dma_pending.buf)        ||
-           (0    == sun_pci_dma_pending.len)   ||
-           (0    == sun_pci_dma_pending.direction));
-
-       sun_pci_dma_current.buf = sun_pci_dma_pending.buf;
-       sun_pci_dma_current.len = sun_pci_dma_pending.len;
-       sun_pci_dma_current.direction = sun_pci_dma_pending.direction;
-
-       sun_pci_dma_pending.buf  = NULL;
-       sun_pci_dma_pending.len  = 0;
-       sun_pci_dma_pending.direction = 0;
-       sun_pci_dma_pending.addr = -1U;
-
-       sun_pci_dma_current.addr = 
-               pci_map_single(sun_pci_ebus_dev,
-                              sun_pci_dma_current.buf,
-                              sun_pci_dma_current.len,
-                              sun_pci_dma_current.direction);
-
-       ebus_dma_enable(&sun_pci_fd_ebus_dma, 1);
-
-       if (ebus_dma_request(&sun_pci_fd_ebus_dma,
-                            sun_pci_dma_current.addr,
-                            sun_pci_dma_current.len))
-               BUG();
-}
-
-static void sun_pci_fd_disable_dma(void)
-{
-       ebus_dma_enable(&sun_pci_fd_ebus_dma, 0);
-       if (sun_pci_dma_current.addr != -1U)
-               pci_unmap_single(sun_pci_ebus_dev,
-                                sun_pci_dma_current.addr,
-                                sun_pci_dma_current.len,
-                                sun_pci_dma_current.direction);
-       sun_pci_dma_current.addr = -1U;
-}
-
-static void sun_pci_fd_set_dma_mode(int mode)
-{
-       if (mode == DMA_MODE_WRITE)
-               sun_pci_dma_pending.direction = PCI_DMA_TODEVICE;
-       else
-               sun_pci_dma_pending.direction = PCI_DMA_FROMDEVICE;
-
-       ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE);
-}
-
-static void sun_pci_fd_set_dma_count(int length)
-{
-       sun_pci_dma_pending.len = length;
-}
-
-static void sun_pci_fd_set_dma_addr(char *buffer)
-{
-       sun_pci_dma_pending.buf = buffer;
-}
-
-static unsigned int sun_pci_get_dma_residue(void)
-{
-       return ebus_dma_residue(&sun_pci_fd_ebus_dma);
-}
-
-static int sun_pci_fd_request_irq(void)
-{
-       return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1);
-}
-
-static void sun_pci_fd_free_irq(void)
-{
-       ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0);
-}
-
-static int sun_pci_fd_eject(int drive)
-{
-       return -EINVAL;
-}
-
-void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie)
-{
-       floppy_interrupt(0, NULL);
-}
-
-/*
- * Floppy probing, we'd like to use /dev/fd0 for a single Floppy on PCI,
- * even if this is configured using DS1, thus looks like /dev/fd1 with
- * the cabling used in Ultras.
- */
-#define DOR    (port + 2)
-#define MSR    (port + 4)
-#define FIFO   (port + 5)
-
-static void sun_pci_fd_out_byte(unsigned long port, unsigned char val,
-                               unsigned long reg)
-{
-       unsigned char status;
-       int timeout = 1000;
-
-       while (!((status = inb(MSR)) & 0x80) && --timeout)
-               udelay(100);
-       outb(val, reg);
-}
-
-static unsigned char sun_pci_fd_sensei(unsigned long port)
-{
-       unsigned char result[2] = { 0x70, 0x00 };
-       unsigned char status;
-       int i = 0;
-
-       sun_pci_fd_out_byte(port, 0x08, FIFO);
-       do {
-               int timeout = 1000;
-
-               while (!((status = inb(MSR)) & 0x80) && --timeout)
-                       udelay(100);
-
-               if (!timeout)
-                       break;
-
-               if ((status & 0xf0) == 0xd0)
-                       result[i++] = inb(FIFO);
-               else
-                       break;
-       } while (i < 2);
-
-       return result[0];
-}
-
-static void sun_pci_fd_reset(unsigned long port)
-{
-       unsigned char mask = 0x00;
-       unsigned char status;
-       int timeout = 10000;
-
-       outb(0x80, MSR);
-       do {
-               status = sun_pci_fd_sensei(port);
-               if ((status & 0xc0) == 0xc0)
-                       mask |= 1 << (status & 0x03);
-               else
-                       udelay(100);
-       } while ((mask != 0x0f) && --timeout);
-}
-
-static int sun_pci_fd_test_drive(unsigned long port, int drive)
-{
-       unsigned char status, data;
-       int timeout = 1000;
-       int ready;
-
-       sun_pci_fd_reset(port);
-
-       data = (0x10 << drive) | 0x0c | drive;
-       sun_pci_fd_out_byte(port, data, DOR);
-
-       sun_pci_fd_out_byte(port, 0x07, FIFO);
-       sun_pci_fd_out_byte(port, drive & 0x03, FIFO);
-
-       do {
-               udelay(100);
-               status = sun_pci_fd_sensei(port);
-       } while (((status & 0xc0) == 0x80) && --timeout);
-
-       if (!timeout)
-               ready = 0;
-       else
-               ready = (status & 0x10) ? 0 : 1;
-
-       sun_pci_fd_reset(port);
-       return ready;
-}
-#undef FIFO
-#undef MSR
-#undef DOR
-
-#endif /* CONFIG_PCI */
-
-#ifdef CONFIG_PCI
-static int __init ebus_fdthree_p(struct linux_ebus_device *edev)
-{
-       if (!strcmp(edev->prom_node->name, "fdthree"))
-               return 1;
-       if (!strcmp(edev->prom_node->name, "floppy")) {
-               const char *compat;
-
-               compat = of_get_property(edev->prom_node,
-                                        "compatible", NULL);
-               if (compat && !strcmp(compat, "fdthree"))
-                       return 1;
-       }
-       return 0;
-}
-#endif
-
-static unsigned long __init sun_floppy_init(void)
-{
-       char state[128];
-       struct sbus_bus *bus;
-       struct sbus_dev *sdev = NULL;
-       static int initialized = 0;
-
-       if (initialized)
-               return sun_floppy_types[0];
-       initialized = 1;
-
-       for_all_sbusdev (sdev, bus) {
-               if (!strcmp(sdev->prom_name, "SUNW,fdtwo")) 
-                       break;
-       }
-       if(sdev) {
-               floppy_sdev = sdev;
-               FLOPPY_IRQ = sdev->irqs[0];
-       } else {
-#ifdef CONFIG_PCI
-               struct linux_ebus *ebus;
-               struct linux_ebus_device *edev = NULL;
-               unsigned long config = 0;
-               void __iomem *auxio_reg;
-               const char *state_prop;
-
-               for_each_ebus(ebus) {
-                       for_each_ebusdev(edev, ebus) {
-                               if (ebus_fdthree_p(edev))
-                                       goto ebus_done;
-                       }
-               }
-       ebus_done:
-               if (!edev)
-                       return 0;
-
-               state_prop = of_get_property(edev->prom_node, "status", NULL);
-               if (state_prop && !strncmp(state_prop, "disabled", 8))
-                       return 0;
-                       
-               FLOPPY_IRQ = edev->irqs[0];
-
-               /* Make sure the high density bit is set, some systems
-                * (most notably Ultra5/Ultra10) come up with it clear.
-                */
-               auxio_reg = (void __iomem *) edev->resource[2].start;
-               writel(readl(auxio_reg)|0x2, auxio_reg);
-
-               sun_pci_ebus_dev = ebus->self;
-
-               spin_lock_init(&sun_pci_fd_ebus_dma.lock);
-
-               /* XXX ioremap */
-               sun_pci_fd_ebus_dma.regs = (void __iomem *)
-                       edev->resource[1].start;
-               if (!sun_pci_fd_ebus_dma.regs)
-                       return 0;
-
-               sun_pci_fd_ebus_dma.flags = (EBUS_DMA_FLAG_USE_EBDMA_HANDLER |
-                                            EBUS_DMA_FLAG_TCI_DISABLE);
-               sun_pci_fd_ebus_dma.callback = sun_pci_fd_dma_callback;
-               sun_pci_fd_ebus_dma.client_cookie = NULL;
-               sun_pci_fd_ebus_dma.irq = FLOPPY_IRQ;
-               strcpy(sun_pci_fd_ebus_dma.name, "floppy");
-               if (ebus_dma_register(&sun_pci_fd_ebus_dma))
-                       return 0;
-
-               /* XXX ioremap */
-               sun_fdc = (struct sun_flpy_controller *)edev->resource[0].start;
-
-               sun_fdops.fd_inb = sun_pci_fd_inb;
-               sun_fdops.fd_outb = sun_pci_fd_outb;
-
-               can_use_virtual_dma = use_virtual_dma = 0;
-               sun_fdops.fd_enable_dma = sun_pci_fd_enable_dma;
-               sun_fdops.fd_disable_dma = sun_pci_fd_disable_dma;
-               sun_fdops.fd_set_dma_mode = sun_pci_fd_set_dma_mode;
-               sun_fdops.fd_set_dma_addr = sun_pci_fd_set_dma_addr;
-               sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;
-               sun_fdops.get_dma_residue = sun_pci_get_dma_residue;
-
-               sun_fdops.fd_request_irq = sun_pci_fd_request_irq;
-               sun_fdops.fd_free_irq = sun_pci_fd_free_irq;
-
-               sun_fdops.fd_eject = sun_pci_fd_eject;
-
-               fdc_status = (unsigned long) &sun_fdc->status_82077;
-
-               /*
-                * XXX: Find out on which machines this is really needed.
-                */
-               if (1) {
-                       sun_pci_broken_drive = 1;
-                       sun_fdops.fd_outb = sun_pci_fd_broken_outb;
-               }
-
-               allowed_drive_mask = 0;
-               if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 0))
-                       sun_floppy_types[0] = 4;
-               if (sun_pci_fd_test_drive((unsigned long)sun_fdc, 1))
-                       sun_floppy_types[1] = 4;
-
-               /*
-                * Find NS87303 SuperIO config registers (through ecpp).
-                */
-               for_each_ebus(ebus) {
-                       for_each_ebusdev(edev, ebus) {
-                               if (!strcmp(edev->prom_node->name, "ecpp")) {
-                                       config = edev->resource[1].start;
-                                       goto config_done;
-                               }
-                       }
-               }
-       config_done:
-
-               /*
-                * Sanity check, is this really the NS87303?
-                */
-               switch (config & 0x3ff) {
-               case 0x02e:
-               case 0x15c:
-               case 0x26e:
-               case 0x398:
-                       break;
-               default:
-                       config = 0;
-               }
-
-               if (!config)
-                       return sun_floppy_types[0];
-
-               /* Enable PC-AT mode. */
-               ns87303_modify(config, ASC, 0, 0xc0);
-
-#ifdef PCI_FDC_SWAP_DRIVES
-               /*
-                * If only Floppy 1 is present, swap drives.
-                */
-               if (!sun_floppy_types[0] && sun_floppy_types[1]) {
-                       /*
-                        * Set the drive exchange bit in FCR on NS87303,
-                        * make sure other bits are sane before doing so.
-                        */
-                       ns87303_modify(config, FER, FER_EDM, 0);
-                       ns87303_modify(config, ASC, ASC_DRV2_SEL, 0);
-                       ns87303_modify(config, FCR, 0, FCR_LDE);
-
-                       config = sun_floppy_types[0];
-                       sun_floppy_types[0] = sun_floppy_types[1];
-                       sun_floppy_types[1] = config;
-
-                       if (sun_pci_broken_drive != -1) {
-                               sun_pci_broken_drive = 1 - sun_pci_broken_drive;
-                               sun_fdops.fd_outb = sun_pci_fd_lde_broken_outb;
-                       }
-               }
-#endif /* PCI_FDC_SWAP_DRIVES */
-
-               return sun_floppy_types[0];
-#else
-               return 0;
-#endif
-       }
-       prom_getproperty(sdev->prom_node, "status", state, sizeof(state));
-       if(!strncmp(state, "disabled", 8))
-               return 0;
-
-       /*
-        * We cannot do sbus_ioremap here: it does request_region,
-        * which the generic floppy driver tries to do once again.
-        * But we must use the sdev resource values as they have
-        * had parent ranges applied.
-        */
-       sun_fdc = (struct sun_flpy_controller *)
-               (sdev->resource[0].start +
-                ((sdev->resource[0].flags & 0x1ffUL) << 32UL));
-
-       /* Last minute sanity check... */
-       if(sbus_readb(&sun_fdc->status1_82077) == 0xff) {
-               sun_fdc = (struct sun_flpy_controller *)-1;
-               return 0;
-       }
-
-        sun_fdops.fd_inb = sun_82077_fd_inb;
-        sun_fdops.fd_outb = sun_82077_fd_outb;
-
-       can_use_virtual_dma = use_virtual_dma = 1;
-       sun_fdops.fd_enable_dma = sun_fd_enable_dma;
-       sun_fdops.fd_disable_dma = sun_fd_disable_dma;
-       sun_fdops.fd_set_dma_mode = sun_fd_set_dma_mode;
-       sun_fdops.fd_set_dma_addr = sun_fd_set_dma_addr;
-       sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
-       sun_fdops.get_dma_residue = sun_get_dma_residue;
-
-       sun_fdops.fd_request_irq = sun_fd_request_irq;
-       sun_fdops.fd_free_irq = sun_fd_free_irq;
-
-       sun_fdops.fd_eject = sun_fd_eject;
-
-        fdc_status = (unsigned long) &sun_fdc->status_82077;
-
-       /* Success... */
-       allowed_drive_mask = 0x01;
-       sun_floppy_types[0] = 4;
-       sun_floppy_types[1] = 0;
-
-       return sun_floppy_types[0];
-}
-
-#define EXTRA_FLOPPY_PARAMS
-
-static DEFINE_SPINLOCK(dma_spin_lock);
-
-#define claim_dma_lock() \
-({     unsigned long flags; \
-       spin_lock_irqsave(&dma_spin_lock, flags); \
-       flags; \
-})
-
-#define release_dma_lock(__flags) \
-       spin_unlock_irqrestore(&dma_spin_lock, __flags);
-
-#endif /* !(__ASM_SPARC64_FLOPPY_H) */
+#include <asm-sparc/floppy.h>
index cc463fec806fc4c7e6cbdb5197b92233d52c4c84..30d6d0f68bc3bc43e109a8842ae4f6685f5c1de0 100644 (file)
@@ -1,33 +1 @@
-/* fpumacro.h: FPU related macros.
- *
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef _SPARC64_FPUMACRO_H
-#define _SPARC64_FPUMACRO_H
-
-#include <asm/asi.h>
-#include <asm/visasm.h>
-
-struct fpustate {
-       u32     regs[64];
-};
-
-#define FPUSTATE (struct fpustate *)(current_thread_info()->fpregs)
-
-static inline unsigned long fprs_read(void)
-{
-       unsigned long retval;
-
-       __asm__ __volatile__("rd %%fprs, %0" : "=r" (retval));
-
-       return retval;
-}
-
-static inline void fprs_write(unsigned long val)
-{
-       __asm__ __volatile__("wr %0, 0x0, %%fprs" : : "r" (val));
-}
-
-#endif /* !(_SPARC64_FPUMACRO_H) */
+#include <asm-sparc/fpumacro.h>
index d8378935ae90918149a3099b46b38e11f5aa7d42..1ceb0bb2fe53ea6094dafe377bb74e8aae77a9eb 100644 (file)
@@ -1,110 +1 @@
-#ifndef _SPARC64_FUTEX_H
-#define _SPARC64_FUTEX_H
-
-#include <linux/futex.h>
-#include <linux/uaccess.h>
-#include <asm/errno.h>
-#include <asm/system.h>
-
-#define __futex_cas_op(insn, ret, oldval, uaddr, oparg)        \
-       __asm__ __volatile__(                           \
-       "\n1:   lduwa   [%3] %%asi, %2\n"               \
-       "       " insn "\n"                             \
-       "2:     casa    [%3] %%asi, %2, %1\n"           \
-       "       cmp     %2, %1\n"                       \
-       "       bne,pn  %%icc, 1b\n"                    \
-       "        mov    0, %0\n"                        \
-       "3:\n"                                          \
-       "       .section .fixup,#alloc,#execinstr\n"    \
-       "       .align  4\n"                            \
-       "4:     sethi   %%hi(3b), %0\n"                 \
-       "       jmpl    %0 + %%lo(3b), %%g0\n"          \
-       "        mov    %5, %0\n"                       \
-       "       .previous\n"                            \
-       "       .section __ex_table,\"a\"\n"            \
-       "       .align  4\n"                            \
-       "       .word   1b, 4b\n"                       \
-       "       .word   2b, 4b\n"                       \
-       "       .previous\n"                            \
-       : "=&r" (ret), "=&r" (oldval), "=&r" (tem)      \
-       : "r" (uaddr), "r" (oparg), "i" (-EFAULT)       \
-       : "memory")
-
-static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
-{
-       int op = (encoded_op >> 28) & 7;
-       int cmp = (encoded_op >> 24) & 15;
-       int oparg = (encoded_op << 8) >> 20;
-       int cmparg = (encoded_op << 20) >> 20;
-       int oldval = 0, ret, tem;
-
-       if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(int))))
-               return -EFAULT;
-       if (unlikely((((unsigned long) uaddr) & 0x3UL)))
-               return -EINVAL;
-
-       if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-               oparg = 1 << oparg;
-
-       pagefault_disable();
-
-       switch (op) {
-       case FUTEX_OP_SET:
-               __futex_cas_op("mov\t%4, %1", ret, oldval, uaddr, oparg);
-               break;
-       case FUTEX_OP_ADD:
-               __futex_cas_op("add\t%2, %4, %1", ret, oldval, uaddr, oparg);
-               break;
-       case FUTEX_OP_OR:
-               __futex_cas_op("or\t%2, %4, %1", ret, oldval, uaddr, oparg);
-               break;
-       case FUTEX_OP_ANDN:
-               __futex_cas_op("and\t%2, %4, %1", ret, oldval, uaddr, oparg);
-               break;
-       case FUTEX_OP_XOR:
-               __futex_cas_op("xor\t%2, %4, %1", ret, oldval, uaddr, oparg);
-               break;
-       default:
-               ret = -ENOSYS;
-       }
-
-       pagefault_enable();
-
-       if (!ret) {
-               switch (cmp) {
-               case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-               case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-               case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-               case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-               case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-               case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-               default: ret = -ENOSYS;
-               }
-       }
-       return ret;
-}
-
-static inline int
-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
-{
-       __asm__ __volatile__(
-       "\n1:   casa    [%3] %%asi, %2, %0\n"
-       "2:\n"
-       "       .section .fixup,#alloc,#execinstr\n"
-       "       .align  4\n"
-       "3:     sethi   %%hi(2b), %0\n"
-       "       jmpl    %0 + %%lo(2b), %%g0\n"
-       "        mov    %4, %0\n"
-       "       .previous\n"
-       "       .section __ex_table,\"a\"\n"
-       "       .align  4\n"
-       "       .word   1b, 3b\n"
-       "       .previous\n"
-       : "=r" (newval)
-       : "0" (newval), "r" (oldval), "r" (uaddr), "i" (-EFAULT)
-       : "memory");
-
-       return newval;
-}
-
-#endif /* !(_SPARC64_FUTEX_H) */
+#include <asm-sparc/futex.h>
index 7c29fd1a87aa4289e78bb7297a4ce41c133cce63..63dca3db11f33fe91870cbe970b10793fd4c0b8b 100644 (file)
@@ -1,19 +1 @@
-/* hardirq.h: 64-bit Sparc hard IRQ support.
- *
- * Copyright (C) 1997, 1998, 2005 David S. Miller (davem@davemloft.net)
- */
-
-#ifndef __SPARC64_HARDIRQ_H
-#define __SPARC64_HARDIRQ_H
-
-#include <asm/cpudata.h>
-
-#define __ARCH_IRQ_STAT
-#define local_softirq_pending() \
-       (local_cpu_data().__softirq_pending)
-
-void ack_bad_irq(unsigned int irq);
-
-#define HARDIRQ_BITS   8
-
-#endif /* !(__SPARC64_HARDIRQ_H) */
+#include <asm-sparc/hardirq.h>
index 10e9dabc4c41337c9f4a1dfc970aa22e9e24436f..2254c09e53f9d0e09f7ee66542d171a571f671f9 100644 (file)
@@ -1,76 +1 @@
-#ifndef _SPARC64_HEAD_H
-#define _SPARC64_HEAD_H
-
-#include <asm/pstate.h>
-
-       /* wrpr %g0, val, %gl */
-#define SET_GL(val)    \
-       .word   0xa1902000 | val
-
-       /* rdpr %gl, %gN */
-#define GET_GL_GLOBAL(N)       \
-       .word   0x81540000 | (N << 25)
-
-#define KERNBASE       0x400000
-
-#define        PTREGS_OFF      (STACK_BIAS + STACKFRAME_SZ)
-
-#define __CHEETAH_ID   0x003e0014
-#define __JALAPENO_ID  0x003e0016
-#define __SERRANO_ID   0x003e0022
-
-#define CHEETAH_MANUF          0x003e
-#define CHEETAH_IMPL           0x0014 /* Ultra-III   */
-#define CHEETAH_PLUS_IMPL      0x0015 /* Ultra-III+  */
-#define JALAPENO_IMPL          0x0016 /* Ultra-IIIi  */
-#define JAGUAR_IMPL            0x0018 /* Ultra-IV    */
-#define PANTHER_IMPL           0x0019 /* Ultra-IV+   */
-#define SERRANO_IMPL           0x0022 /* Ultra-IIIi+ */
-
-#define BRANCH_IF_SUN4V(tmp1,label)            \
-       sethi   %hi(is_sun4v), %tmp1;           \
-       lduw    [%tmp1 + %lo(is_sun4v)], %tmp1; \
-       brnz,pn %tmp1, label;                   \
-        nop
-
-#define BRANCH_IF_CHEETAH_BASE(tmp1,tmp2,label)        \
-       rdpr    %ver, %tmp1;                    \
-       sethi   %hi(__CHEETAH_ID), %tmp2;       \
-       srlx    %tmp1, 32, %tmp1;               \
-       or      %tmp2, %lo(__CHEETAH_ID), %tmp2;\
-       cmp     %tmp1, %tmp2;                   \
-       be,pn   %icc, label;                    \
-        nop;
-
-#define BRANCH_IF_JALAPENO(tmp1,tmp2,label)    \
-       rdpr    %ver, %tmp1;                    \
-       sethi   %hi(__JALAPENO_ID), %tmp2;      \
-       srlx    %tmp1, 32, %tmp1;               \
-       or      %tmp2, %lo(__JALAPENO_ID), %tmp2;\
-       cmp     %tmp1, %tmp2;                   \
-       be,pn   %icc, label;                    \
-        nop;
-
-#define BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(tmp1,tmp2,label)    \
-       rdpr    %ver, %tmp1;                    \
-       srlx    %tmp1, (32 + 16), %tmp2;        \
-       cmp     %tmp2, CHEETAH_MANUF;           \
-       bne,pt  %xcc, 99f;                      \
-        sllx   %tmp1, 16, %tmp1;               \
-       srlx    %tmp1, (32 + 16), %tmp2;        \
-       cmp     %tmp2, CHEETAH_PLUS_IMPL;       \
-       bgeu,pt %xcc, label;                    \
-99:     nop;
-
-#define BRANCH_IF_ANY_CHEETAH(tmp1,tmp2,label) \
-       rdpr    %ver, %tmp1;                    \
-       srlx    %tmp1, (32 + 16), %tmp2;        \
-       cmp     %tmp2, CHEETAH_MANUF;           \
-       bne,pt  %xcc, 99f;                      \
-        sllx   %tmp1, 16, %tmp1;               \
-       srlx    %tmp1, (32 + 16), %tmp2;        \
-       cmp     %tmp2, CHEETAH_IMPL;            \
-       bgeu,pt %xcc, label;                    \
-99:     nop;
-
-#endif /* !(_SPARC64_HEAD_H) */
+#include <asm-sparc/head.h>
index 412af58926a0af752854dffdc113bc5dac04ae3a..21d8f0a9c2430324ace1b235e1f19576c9724862 100644 (file)
@@ -1,84 +1 @@
-#ifndef _ASM_SPARC64_HUGETLB_H
-#define _ASM_SPARC64_HUGETLB_H
-
-#include <asm/page.h>
-
-
-void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
-                    pte_t *ptep, pte_t pte);
-
-pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
-                             pte_t *ptep);
-
-void hugetlb_prefault_arch_hook(struct mm_struct *mm);
-
-static inline int is_hugepage_only_range(struct mm_struct *mm,
-                                        unsigned long addr,
-                                        unsigned long len) {
-       return 0;
-}
-
-/*
- * If the arch doesn't supply something else, assume that hugepage
- * size aligned regions are ok without further preparation.
- */
-static inline int prepare_hugepage_range(unsigned long addr, unsigned long len)
-{
-       if (len & ~HPAGE_MASK)
-               return -EINVAL;
-       if (addr & ~HPAGE_MASK)
-               return -EINVAL;
-       return 0;
-}
-
-static inline void hugetlb_free_pgd_range(struct mmu_gather **tlb,
-                                         unsigned long addr, unsigned long end,
-                                         unsigned long floor,
-                                         unsigned long ceiling)
-{
-       free_pgd_range(tlb, addr, end, floor, ceiling);
-}
-
-static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
-                                        unsigned long addr, pte_t *ptep)
-{
-}
-
-static inline int huge_pte_none(pte_t pte)
-{
-       return pte_none(pte);
-}
-
-static inline pte_t huge_pte_wrprotect(pte_t pte)
-{
-       return pte_wrprotect(pte);
-}
-
-static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
-                                          unsigned long addr, pte_t *ptep)
-{
-       ptep_set_wrprotect(mm, addr, ptep);
-}
-
-static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
-                                            unsigned long addr, pte_t *ptep,
-                                            pte_t pte, int dirty)
-{
-       return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
-}
-
-static inline pte_t huge_ptep_get(pte_t *ptep)
-{
-       return *ptep;
-}
-
-static inline int arch_prepare_hugepage(struct page *page)
-{
-       return 0;
-}
-
-static inline void arch_release_hugepage(struct page *page)
-{
-}
-
-#endif /* _ASM_SPARC64_HUGETLB_H */
+#include <asm-sparc/hugetlb.h>
index b2b9b947b3a41ba997298cb57de74c7aee81a318..fb46bfe934a7705da836a5886d9d04c4bad408cb 100644 (file)
@@ -1,37 +1 @@
-#ifndef _SPARC64_HVTRAP_H
-#define _SPARC64_HVTRAP_H
-
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-
-struct hvtramp_mapping {
-       __u64           vaddr;
-       __u64           tte;
-};
-
-struct hvtramp_descr {
-       __u32                   cpu;
-       __u32                   num_mappings;
-       __u64                   fault_info_va;
-       __u64                   fault_info_pa;
-       __u64                   thread_reg;
-       struct hvtramp_mapping  maps[1];
-};
-
-extern void hv_cpu_startup(unsigned long hvdescr_pa);
-
-#endif
-
-#define HVTRAMP_DESCR_CPU              0x00
-#define HVTRAMP_DESCR_NUM_MAPPINGS     0x04
-#define HVTRAMP_DESCR_FAULT_INFO_VA    0x08
-#define HVTRAMP_DESCR_FAULT_INFO_PA    0x10
-#define HVTRAMP_DESCR_THREAD_REG       0x18
-#define HVTRAMP_DESCR_MAPS             0x20
-
-#define HVTRAMP_MAPPING_VADDR          0x00
-#define HVTRAMP_MAPPING_TTE            0x08
-#define HVTRAMP_MAPPING_SIZE           0x10
-
-#endif /* _SPARC64_HVTRAP_H */
+#include <asm-sparc/hvtramp.h>
index 8e44a8360829ea5776677c8f87a8c065d6198059..16920a291f51af412f59b4343caf71b8a8c106b8 100644 (file)
@@ -1,4 +1 @@
-#ifndef __ASM_SPARC64_HW_IRQ_H
-#define __ASM_SPARC64_HW_IRQ_H
-
-#endif
+#include <asm-sparc/hw_irq.h>
index 3ad45dff52f87f3732d0a38c30cbc017f97edb70..fe7e51a9e429ee125c5027607b8c438e636f4327 100644 (file)
@@ -1,2945 +1 @@
-#ifndef _SPARC64_HYPERVISOR_H
-#define _SPARC64_HYPERVISOR_H
-
-/* Sun4v hypervisor interfaces and defines.
- *
- * Hypervisor calls are made via traps to software traps number 0x80
- * and above.  Registers %o0 to %o5 serve as argument, status, and
- * return value registers.
- *
- * There are two kinds of these traps.  First there are the normal
- * "fast traps" which use software trap 0x80 and encode the function
- * to invoke by number in register %o5.  Argument and return value
- * handling is as follows:
- *
- * -----------------------------------------------
- * |  %o5  | function number |     undefined     |
- * |  %o0  |   argument 0    |   return status   |
- * |  %o1  |   argument 1    |   return value 1  |
- * |  %o2  |   argument 2    |   return value 2  |
- * |  %o3  |   argument 3    |   return value 3  |
- * |  %o4  |   argument 4    |   return value 4  |
- * -----------------------------------------------
- *
- * The second type are "hyper-fast traps" which encode the function
- * number in the software trap number itself.  So these use trap
- * numbers > 0x80.  The register usage for hyper-fast traps is as
- * follows:
- *
- * -----------------------------------------------
- * |  %o0  |   argument 0    |   return status   |
- * |  %o1  |   argument 1    |   return value 1  |
- * |  %o2  |   argument 2    |   return value 2  |
- * |  %o3  |   argument 3    |   return value 3  |
- * |  %o4  |   argument 4    |   return value 4  |
- * -----------------------------------------------
- *
- * Registers providing explicit arguments to the hypervisor calls
- * are volatile across the call.  Upon return their values are
- * undefined unless explicitly specified as containing a particular
- * return value by the specific call.  The return status is always
- * returned in register %o0, zero indicates a successful execution of
- * the hypervisor call and other values indicate an error status as
- * defined below.  So, for example, if a hyper-fast trap takes
- * arguments 0, 1, and 2, then %o0, %o1, and %o2 are volatile across
- * the call and %o3, %o4, and %o5 would be preserved.
- *
- * If the hypervisor trap is invalid, or the fast trap function number
- * is invalid, HV_EBADTRAP will be returned in %o0.  Also, all 64-bits
- * of the argument and return values are significant.
- */
-
-/* Trap numbers.  */
-#define HV_FAST_TRAP           0x80
-#define HV_MMU_MAP_ADDR_TRAP   0x83
-#define HV_MMU_UNMAP_ADDR_TRAP 0x84
-#define HV_TTRACE_ADDENTRY_TRAP        0x85
-#define HV_CORE_TRAP           0xff
-
-/* Error codes.  */
-#define HV_EOK                         0  /* Successful return            */
-#define HV_ENOCPU                      1  /* Invalid CPU id               */
-#define HV_ENORADDR                    2  /* Invalid real address         */
-#define HV_ENOINTR                     3  /* Invalid interrupt id         */
-#define HV_EBADPGSZ                    4  /* Invalid pagesize encoding    */
-#define HV_EBADTSB                     5  /* Invalid TSB description      */
-#define HV_EINVAL                      6  /* Invalid argument             */
-#define HV_EBADTRAP                    7  /* Invalid function number      */
-#define HV_EBADALIGN                   8  /* Invalid address alignment    */
-#define HV_EWOULDBLOCK                 9  /* Cannot complete w/o blocking */
-#define HV_ENOACCESS                   10 /* No access to resource        */
-#define HV_EIO                         11 /* I/O error                    */
-#define HV_ECPUERROR                   12 /* CPU in error state           */
-#define HV_ENOTSUPPORTED               13 /* Function not supported       */
-#define HV_ENOMAP                      14 /* No mapping found             */
-#define HV_ETOOMANY                    15 /* Too many items specified     */
-#define HV_ECHANNEL                    16 /* Invalid LDC channel          */
-#define HV_EBUSY                       17 /* Resource busy                */
-
-/* mach_exit()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MACH_EXIT
- * ARG0:       exit code
- * ERRORS:     This service does not return.
- *
- * Stop all CPUs in the virtual domain and place them into the stopped
- * state.  The 64-bit exit code may be passed to a service entity as
- * the domain's exit status.  On systems without a service entity, the
- * domain will undergo a reset, and the boot firmware will be
- * reloaded.
- *
- * This function will never return to the guest that invokes it.
- *
- * Note: By convention an exit code of zero denotes a successful exit by
- *       the guest code.  A non-zero exit code denotes a guest specific
- *       error indication.
- *
- */
-#define HV_FAST_MACH_EXIT              0x00
-
-#ifndef __ASSEMBLY__
-extern void sun4v_mach_exit(unsigned long exit_code);
-#endif
-
-/* Domain services.  */
-
-/* mach_desc()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MACH_DESC
- * ARG0:       buffer
- * ARG1:       length
- * RET0:       status
- * RET1:       length
- * ERRORS:     HV_EBADALIGN    Buffer is badly aligned
- *             HV_ENORADDR     Buffer is to an illegal real address.
- *             HV_EINVAL       Buffer length is too small for complete
- *                             machine description.
- *
- * Copy the most current machine description into the buffer indicated
- * by the real address in ARG0.  The buffer provided must be 16 byte
- * aligned.  Upon success or HV_EINVAL, this service returns the
- * actual size of the machine description in the RET1 return value.
- *
- * Note: A method of determining the appropriate buffer size for the
- *       machine description is to first call this service with a buffer
- *       length of 0 bytes.
- */
-#define HV_FAST_MACH_DESC              0x01
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_mach_desc(unsigned long buffer_pa,
-                                    unsigned long buf_len,
-                                    unsigned long *real_buf_len);
-#endif
-
-/* mach_sir()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MACH_SIR
- * ERRORS:     This service does not return.
- *
- * Perform a software initiated reset of the virtual machine domain.
- * All CPUs are captured as soon as possible, all hardware devices are
- * returned to the entry default state, and the domain is restarted at
- * the SIR (trap type 0x04) real trap table (RTBA) entry point on one
- * of the CPUs.  The single CPU restarted is selected as determined by
- * platform specific policy.  Memory is preserved across this
- * operation.
- */
-#define HV_FAST_MACH_SIR               0x02
-
-#ifndef __ASSEMBLY__
-extern void sun4v_mach_sir(void);
-#endif
-
-/* mach_set_watchdog()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MACH_SET_WATCHDOG
- * ARG0:       timeout in milliseconds
- * RET0:       status
- * RET1:       time remaining in milliseconds
- *
- * A guest uses this API to set a watchdog timer.  Once the gues has set
- * the timer, it must call the timer service again either to disable or
- * postpone the expiration.  If the timer expires before being reset or
- * disabled, then the hypervisor take a platform specific action leading
- * to guest termination within a bounded time period.  The platform action
- * may include recovery actions such as reporting the expiration to a
- * Service Processor, and/or automatically restarting the gues.
- *
- * The 'timeout' parameter is specified in milliseconds, however the
- * implementated granularity is given by the 'watchdog-resolution'
- * property in the 'platform' node of the guest's machine description.
- * The largest allowed timeout value is specified by the
- * 'watchdog-max-timeout' property of the 'platform' node.
- *
- * If the 'timeout' argument is not zero, the watchdog timer is set to
- * expire after a minimum of 'timeout' milliseconds.
- *
- * If the 'timeout' argument is zero, the watchdog timer is disabled.
- *
- * If the 'timeout' value exceeds the value of the 'max-watchdog-timeout'
- * property, the hypervisor leaves the watchdog timer state unchanged,
- * and returns a status of EINVAL.
- *
- * The 'time remaining' return value is valid regardless of whether the
- * return status is EOK or EINVAL.  A non-zero return value indicates the
- * number of milliseconds that were remaining until the timer was to expire.
- * If less than one millisecond remains, the return value is '1'.  If the
- * watchdog timer was disabled at the time of the call, the return value is
- * zero.
- *
- * If the hypervisor cannot support the exact timeout value requested, but
- * can support a larger timeout value, the hypervisor may round the actual
- * timeout to a value larger than the requested timeout, consequently the
- * 'time remaining' return value may be larger than the previously requested
- * timeout value.
- *
- * Any guest OS debugger should be aware that the watchdog service may be in
- * use.  Consequently, it is recommended that the watchdog service is
- * disabled upon debugger entry (e.g. reaching a breakpoint), and then
- * re-enabled upon returning to normal execution.  The API has been designed
- * with this in mind, and the 'time remaining' result of the disable call may
- * be used directly as the timeout argument of the re-enable call.
- */
-#define HV_FAST_MACH_SET_WATCHDOG      0x05
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_mach_set_watchdog(unsigned long timeout,
-                                            unsigned long *orig_timeout);
-#endif
-
-/* CPU services.
- *
- * CPUs represent devices that can execute software threads.  A single
- * chip that contains multiple cores or strands is represented as
- * multiple CPUs with unique CPU identifiers.  CPUs are exported to
- * OBP via the machine description (and to the OS via the OBP device
- * tree).  CPUs are always in one of three states: stopped, running,
- * or error.
- *
- * A CPU ID is a pre-assigned 16-bit value that uniquely identifies a
- * CPU within a logical domain.  Operations that are to be performed
- * on multiple CPUs specify them via a CPU list.  A CPU list is an
- * array in real memory, of which each 16-bit word is a CPU ID.  CPU
- * lists are passed through the API as two arguments.  The first is
- * the number of entries (16-bit words) in the CPU list, and the
- * second is the (real address) pointer to the CPU ID list.
- */
-
-/* cpu_start()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CPU_START
- * ARG0:       CPU ID
- * ARG1:       PC
- * ARG2:       RTBA
- * ARG3:       target ARG0
- * RET0:       status
- * ERRORS:     ENOCPU          Invalid CPU ID
- *             EINVAL          Target CPU ID is not in the stopped state
- *             ENORADDR        Invalid PC or RTBA real address
- *             EBADALIGN       Unaligned PC or unaligned RTBA
- *             EWOULDBLOCK     Starting resources are not available
- *
- * Start CPU with given CPU ID with PC in %pc and with a real trap
- * base address value of RTBA.  The indicated CPU must be in the
- * stopped state.  The supplied RTBA must be aligned on a 256 byte
- * boundary.  On successful completion, the specified CPU will be in
- * the running state and will be supplied with "target ARG0" in %o0
- * and RTBA in %tba.
- */
-#define HV_FAST_CPU_START              0x10
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_cpu_start(unsigned long cpuid,
-                                    unsigned long pc,
-                                    unsigned long rtba,
-                                    unsigned long arg0);
-#endif
-
-/* cpu_stop()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CPU_STOP
- * ARG0:       CPU ID
- * RET0:       status
- * ERRORS:     ENOCPU          Invalid CPU ID
- *             EINVAL          Target CPU ID is the current cpu
- *             EINVAL          Target CPU ID is not in the running state
- *             EWOULDBLOCK     Stopping resources are not available
- *             ENOTSUPPORTED   Not supported on this platform
- *
- * The specified CPU is stopped.  The indicated CPU must be in the
- * running state.  On completion, it will be in the stopped state.  It
- * is not legal to stop the current CPU.
- *
- * Note: As this service cannot be used to stop the current cpu, this service
- *       may not be used to stop the last running CPU in a domain.  To stop
- *       and exit a running domain, a guest must use the mach_exit() service.
- */
-#define HV_FAST_CPU_STOP               0x11
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_cpu_stop(unsigned long cpuid);
-#endif
-
-/* cpu_yield()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CPU_YIELD
- * RET0:       status
- * ERRORS:     No possible error.
- *
- * Suspend execution on the current CPU.  Execution will resume when
- * an interrupt (device, %stick_compare, or cross-call) is targeted to
- * the CPU.  On some CPUs, this API may be used by the hypervisor to
- * save power by disabling hardware strands.
- */
-#define HV_FAST_CPU_YIELD              0x12
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_cpu_yield(void);
-#endif
-
-/* cpu_qconf()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CPU_QCONF
- * ARG0:       queue
- * ARG1:       base real address
- * ARG2:       number of entries
- * RET0:       status
- * ERRORS:     ENORADDR        Invalid base real address
- *             EINVAL          Invalid queue or number of entries is less
- *                             than 2 or too large.
- *             EBADALIGN       Base real address is not correctly aligned
- *                             for size.
- *
- * Configure the given queue to be placed at the given base real
- * address, with the given number of entries.  The number of entries
- * must be a power of 2.  The base real address must be aligned
- * exactly to match the queue size.  Each queue entry is 64 bytes
- * long, so for example a 32 entry queue must be aligned on a 2048
- * byte real address boundary.
- *
- * The specified queue is unconfigured if the number of entries is given
- * as zero.
- *
- * For the current version of this API service, the argument queue is defined
- * as follows:
- *
- *     queue           description
- *     -----           -------------------------
- *     0x3c            cpu mondo queue
- *     0x3d            device mondo queue
- *     0x3e            resumable error queue
- *     0x3f            non-resumable error queue
- *
- * Note: The maximum number of entries for each queue for a specific cpu may
- *       be determined from the machine description.
- */
-#define HV_FAST_CPU_QCONF              0x14
-#define  HV_CPU_QUEUE_CPU_MONDO                 0x3c
-#define  HV_CPU_QUEUE_DEVICE_MONDO      0x3d
-#define  HV_CPU_QUEUE_RES_ERROR                 0x3e
-#define  HV_CPU_QUEUE_NONRES_ERROR      0x3f
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_cpu_qconf(unsigned long type,
-                                    unsigned long queue_paddr,
-                                    unsigned long num_queue_entries);
-#endif
-
-/* cpu_qinfo()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CPU_QINFO
- * ARG0:       queue
- * RET0:       status
- * RET1:       base real address
- * RET1:       number of entries
- * ERRORS:     EINVAL          Invalid queue
- *
- * Return the configuration info for the given queue.  The base real
- * address and number of entries of the defined queue are returned.
- * The queue argument values are the same as for cpu_qconf() above.
- *
- * If the specified queue is a valid queue number, but no queue has
- * been defined, the number of entries will be set to zero and the
- * base real address returned is undefined.
- */
-#define HV_FAST_CPU_QINFO              0x15
-
-/* cpu_mondo_send()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CPU_MONDO_SEND
- * ARG0-1:     CPU list
- * ARG2:       data real address
- * RET0:       status
- * ERRORS:     EBADALIGN       Mondo data is not 64-byte aligned or CPU list
- *                             is not 2-byte aligned.
- *             ENORADDR        Invalid data mondo address, or invalid cpu list
- *                             address.
- *             ENOCPU          Invalid cpu in CPU list
- *             EWOULDBLOCK     Some or all of the listed CPUs did not receive
- *                             the mondo
- *             ECPUERROR       One or more of the listed CPUs are in error
- *                             state, use HV_FAST_CPU_STATE to see which ones
- *             EINVAL          CPU list includes caller's CPU ID
- *
- * Send a mondo interrupt to the CPUs in the given CPU list with the
- * 64-bytes at the given data real address.  The data must be 64-byte
- * aligned.  The mondo data will be delivered to the cpu_mondo queues
- * of the recipient CPUs.
- *
- * In all cases, error or not, the CPUs in the CPU list to which the
- * mondo has been successfully delivered will be indicated by having
- * their entry in CPU list updated with the value 0xffff.
- */
-#define HV_FAST_CPU_MONDO_SEND         0x42
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_cpu_mondo_send(unsigned long cpu_count, unsigned long cpu_list_pa, unsigned long mondo_block_pa);
-#endif
-
-/* cpu_myid()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CPU_MYID
- * RET0:       status
- * RET1:       CPU ID
- * ERRORS:     No errors defined.
- *
- * Return the hypervisor ID handle for the current CPU.  Use by a
- * virtual CPU to discover it's own identity.
- */
-#define HV_FAST_CPU_MYID               0x16
-
-/* cpu_state()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CPU_STATE
- * ARG0:       CPU ID
- * RET0:       status
- * RET1:       state
- * ERRORS:     ENOCPU          Invalid CPU ID
- *
- * Retrieve the current state of the CPU with the given CPU ID.
- */
-#define HV_FAST_CPU_STATE              0x17
-#define  HV_CPU_STATE_STOPPED           0x01
-#define  HV_CPU_STATE_RUNNING           0x02
-#define  HV_CPU_STATE_ERROR             0x03
-
-#ifndef __ASSEMBLY__
-extern long sun4v_cpu_state(unsigned long cpuid);
-#endif
-
-/* cpu_set_rtba()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CPU_SET_RTBA
- * ARG0:       RTBA
- * RET0:       status
- * RET1:       previous RTBA
- * ERRORS:     ENORADDR        Invalid RTBA real address
- *             EBADALIGN       RTBA is incorrectly aligned for a trap table
- *
- * Set the real trap base address of the local cpu to the given RTBA.
- * The supplied RTBA must be aligned on a 256 byte boundary.  Upon
- * success the previous value of the RTBA is returned in RET1.
- *
- * Note: This service does not affect %tba
- */
-#define HV_FAST_CPU_SET_RTBA           0x18
-
-/* cpu_set_rtba()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CPU_GET_RTBA
- * RET0:       status
- * RET1:       previous RTBA
- * ERRORS:     No possible error.
- *
- * Returns the current value of RTBA in RET1.
- */
-#define HV_FAST_CPU_GET_RTBA           0x19
-
-/* MMU services.
- *
- * Layout of a TSB description for mmu_tsb_ctx{,non}0() calls.
- */
-#ifndef __ASSEMBLY__
-struct hv_tsb_descr {
-       unsigned short          pgsz_idx;
-       unsigned short          assoc;
-       unsigned int            num_ttes;       /* in TTEs */
-       unsigned int            ctx_idx;
-       unsigned int            pgsz_mask;
-       unsigned long           tsb_base;
-       unsigned long           resv;
-};
-#endif
-#define HV_TSB_DESCR_PGSZ_IDX_OFFSET   0x00
-#define HV_TSB_DESCR_ASSOC_OFFSET      0x02
-#define HV_TSB_DESCR_NUM_TTES_OFFSET   0x04
-#define HV_TSB_DESCR_CTX_IDX_OFFSET    0x08
-#define HV_TSB_DESCR_PGSZ_MASK_OFFSET  0x0c
-#define HV_TSB_DESCR_TSB_BASE_OFFSET   0x10
-#define HV_TSB_DESCR_RESV_OFFSET       0x18
-
-/* Page size bitmask.  */
-#define HV_PGSZ_MASK_8K                        (1 << 0)
-#define HV_PGSZ_MASK_64K               (1 << 1)
-#define HV_PGSZ_MASK_512K              (1 << 2)
-#define HV_PGSZ_MASK_4MB               (1 << 3)
-#define HV_PGSZ_MASK_32MB              (1 << 4)
-#define HV_PGSZ_MASK_256MB             (1 << 5)
-#define HV_PGSZ_MASK_2GB               (1 << 6)
-#define HV_PGSZ_MASK_16GB              (1 << 7)
-
-/* Page size index.  The value given in the TSB descriptor must correspond
- * to the smallest page size specified in the pgsz_mask page size bitmask.
- */
-#define HV_PGSZ_IDX_8K                 0
-#define HV_PGSZ_IDX_64K                        1
-#define HV_PGSZ_IDX_512K               2
-#define HV_PGSZ_IDX_4MB                        3
-#define HV_PGSZ_IDX_32MB               4
-#define HV_PGSZ_IDX_256MB              5
-#define HV_PGSZ_IDX_2GB                        6
-#define HV_PGSZ_IDX_16GB               7
-
-/* MMU fault status area.
- *
- * MMU related faults have their status and fault address information
- * placed into a memory region made available by privileged code.  Each
- * virtual processor must make a mmu_fault_area_conf() call to tell the
- * hypervisor where that processor's fault status should be stored.
- *
- * The fault status block is a multiple of 64-bytes and must be aligned
- * on a 64-byte boundary.
- */
-#ifndef __ASSEMBLY__
-struct hv_fault_status {
-       unsigned long           i_fault_type;
-       unsigned long           i_fault_addr;
-       unsigned long           i_fault_ctx;
-       unsigned long           i_reserved[5];
-       unsigned long           d_fault_type;
-       unsigned long           d_fault_addr;
-       unsigned long           d_fault_ctx;
-       unsigned long           d_reserved[5];
-};
-#endif
-#define HV_FAULT_I_TYPE_OFFSET 0x00
-#define HV_FAULT_I_ADDR_OFFSET 0x08
-#define HV_FAULT_I_CTX_OFFSET  0x10
-#define HV_FAULT_D_TYPE_OFFSET 0x40
-#define HV_FAULT_D_ADDR_OFFSET 0x48
-#define HV_FAULT_D_CTX_OFFSET  0x50
-
-#define HV_FAULT_TYPE_FAST_MISS        1
-#define HV_FAULT_TYPE_FAST_PROT        2
-#define HV_FAULT_TYPE_MMU_MISS 3
-#define HV_FAULT_TYPE_INV_RA   4
-#define HV_FAULT_TYPE_PRIV_VIOL        5
-#define HV_FAULT_TYPE_PROT_VIOL        6
-#define HV_FAULT_TYPE_NFO      7
-#define HV_FAULT_TYPE_NFO_SEFF 8
-#define HV_FAULT_TYPE_INV_VA   9
-#define HV_FAULT_TYPE_INV_ASI  10
-#define HV_FAULT_TYPE_NC_ATOMIC        11
-#define HV_FAULT_TYPE_PRIV_ACT 12
-#define HV_FAULT_TYPE_RESV1    13
-#define HV_FAULT_TYPE_UNALIGNED        14
-#define HV_FAULT_TYPE_INV_PGSZ 15
-/* Values 16 --> -2 are reserved.  */
-#define HV_FAULT_TYPE_MULTIPLE -1
-
-/* Flags argument for mmu_{map,unmap}_addr(), mmu_demap_{page,context,all}(),
- * and mmu_{map,unmap}_perm_addr().
- */
-#define HV_MMU_DMMU                    0x01
-#define HV_MMU_IMMU                    0x02
-#define HV_MMU_ALL                     (HV_MMU_DMMU | HV_MMU_IMMU)
-
-/* mmu_map_addr()
- * TRAP:       HV_MMU_MAP_ADDR_TRAP
- * ARG0:       virtual address
- * ARG1:       mmu context
- * ARG2:       TTE
- * ARG3:       flags (HV_MMU_{IMMU,DMMU})
- * ERRORS:     EINVAL          Invalid virtual address, mmu context, or flags
- *             EBADPGSZ        Invalid page size value
- *             ENORADDR        Invalid real address in TTE
- *
- * Create a non-permanent mapping using the given TTE, virtual
- * address, and mmu context.  The flags argument determines which
- * (data, or instruction, or both) TLB the mapping gets loaded into.
- *
- * The behavior is undefined if the valid bit is clear in the TTE.
- *
- * Note: This API call is for privileged code to specify temporary translation
- *       mappings without the need to create and manage a TSB.
- */
-
-/* mmu_unmap_addr()
- * TRAP:       HV_MMU_UNMAP_ADDR_TRAP
- * ARG0:       virtual address
- * ARG1:       mmu context
- * ARG2:       flags (HV_MMU_{IMMU,DMMU})
- * ERRORS:     EINVAL          Invalid virtual address, mmu context, or flags
- *
- * Demaps the given virtual address in the given mmu context on this
- * CPU.  This function is intended to be used to demap pages mapped
- * with mmu_map_addr.  This service is equivalent to invoking
- * mmu_demap_page() with only the current CPU in the CPU list. The
- * flags argument determines which (data, or instruction, or both) TLB
- * the mapping gets unmapped from.
- *
- * Attempting to perform an unmap operation for a previously defined
- * permanent mapping will have undefined results.
- */
-
-/* mmu_tsb_ctx0()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMU_TSB_CTX0
- * ARG0:       number of TSB descriptions
- * ARG1:       TSB descriptions pointer
- * RET0:       status
- * ERRORS:     ENORADDR                Invalid TSB descriptions pointer or
- *                                     TSB base within a descriptor
- *             EBADALIGN               TSB descriptions pointer is not aligned
- *                                     to an 8-byte boundary, or TSB base
- *                                     within a descriptor is not aligned for
- *                                     the given TSB size
- *             EBADPGSZ                Invalid page size in a TSB descriptor
- *             EBADTSB                 Invalid associativity or size in a TSB
- *                                     descriptor
- *             EINVAL                  Invalid number of TSB descriptions, or
- *                                     invalid context index in a TSB
- *                                     descriptor, or index page size not
- *                                     equal to smallest page size in page
- *                                     size bitmask field.
- *
- * Configures the TSBs for the current CPU for virtual addresses with
- * context zero.  The TSB descriptions pointer is a pointer to an
- * array of the given number of TSB descriptions.
- *
- * Note: The maximum number of TSBs available to a virtual CPU is given by the
- *       mmu-max-#tsbs property of the cpu's corresponding "cpu" node in the
- *       machine description.
- */
-#define HV_FAST_MMU_TSB_CTX0           0x20
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_mmu_tsb_ctx0(unsigned long num_descriptions,
-                                       unsigned long tsb_desc_ra);
-#endif
-
-/* mmu_tsb_ctxnon0()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMU_TSB_CTXNON0
- * ARG0:       number of TSB descriptions
- * ARG1:       TSB descriptions pointer
- * RET0:       status
- * ERRORS:     Same as for mmu_tsb_ctx0() above.
- *
- * Configures the TSBs for the current CPU for virtual addresses with
- * non-zero contexts.  The TSB descriptions pointer is a pointer to an
- * array of the given number of TSB descriptions.
- *
- * Note: A maximum of 16 TSBs may be specified in the TSB description list.
- */
-#define HV_FAST_MMU_TSB_CTXNON0                0x21
-
-/* mmu_demap_page()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMU_DEMAP_PAGE
- * ARG0:       reserved, must be zero
- * ARG1:       reserved, must be zero
- * ARG2:       virtual address
- * ARG3:       mmu context
- * ARG4:       flags (HV_MMU_{IMMU,DMMU})
- * RET0:       status
- * ERRORS:     EINVAL                  Invalid virutal address, context, or
- *                                     flags value
- *             ENOTSUPPORTED           ARG0 or ARG1 is non-zero
- *
- * Demaps any page mapping of the given virtual address in the given
- * mmu context for the current virtual CPU.  Any virtually tagged
- * caches are guaranteed to be kept consistent.  The flags argument
- * determines which TLB (instruction, or data, or both) participate in
- * the operation.
- *
- * ARG0 and ARG1 are both reserved and must be set to zero.
- */
-#define HV_FAST_MMU_DEMAP_PAGE         0x22
-
-/* mmu_demap_ctx()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMU_DEMAP_CTX
- * ARG0:       reserved, must be zero
- * ARG1:       reserved, must be zero
- * ARG2:       mmu context
- * ARG3:       flags (HV_MMU_{IMMU,DMMU})
- * RET0:       status
- * ERRORS:     EINVAL                  Invalid context or flags value
- *             ENOTSUPPORTED           ARG0 or ARG1 is non-zero
- *
- * Demaps all non-permanent virtual page mappings previously specified
- * for the given context for the current virtual CPU.  Any virtual
- * tagged caches are guaranteed to be kept consistent.  The flags
- * argument determines which TLB (instruction, or data, or both)
- * participate in the operation.
- *
- * ARG0 and ARG1 are both reserved and must be set to zero.
- */
-#define HV_FAST_MMU_DEMAP_CTX          0x23
-
-/* mmu_demap_all()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMU_DEMAP_ALL
- * ARG0:       reserved, must be zero
- * ARG1:       reserved, must be zero
- * ARG2:       flags (HV_MMU_{IMMU,DMMU})
- * RET0:       status
- * ERRORS:     EINVAL                  Invalid flags value
- *             ENOTSUPPORTED           ARG0 or ARG1 is non-zero
- *
- * Demaps all non-permanent virtual page mappings previously specified
- * for the current virtual CPU.  Any virtual tagged caches are
- * guaranteed to be kept consistent.  The flags argument determines
- * which TLB (instruction, or data, or both) participate in the
- * operation.
- *
- * ARG0 and ARG1 are both reserved and must be set to zero.
- */
-#define HV_FAST_MMU_DEMAP_ALL          0x24
-
-#ifndef __ASSEMBLY__
-extern void sun4v_mmu_demap_all(void);
-#endif
-
-/* mmu_map_perm_addr()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMU_MAP_PERM_ADDR
- * ARG0:       virtual address
- * ARG1:       reserved, must be zero
- * ARG2:       TTE
- * ARG3:       flags (HV_MMU_{IMMU,DMMU})
- * RET0:       status
- * ERRORS:     EINVAL                  Invalid virutal address or flags value
- *             EBADPGSZ                Invalid page size value
- *             ENORADDR                Invalid real address in TTE
- *             ETOOMANY                Too many mappings (max of 8 reached)
- *
- * Create a permanent mapping using the given TTE and virtual address
- * for context 0 on the calling virtual CPU.  A maximum of 8 such
- * permanent mappings may be specified by privileged code.  Mappings
- * may be removed with mmu_unmap_perm_addr().
- *
- * The behavior is undefined if a TTE with the valid bit clear is given.
- *
- * Note: This call is used to specify address space mappings for which
- *       privileged code does not expect to receive misses.  For example,
- *       this mechanism can be used to map kernel nucleus code and data.
- */
-#define HV_FAST_MMU_MAP_PERM_ADDR      0x25
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_mmu_map_perm_addr(unsigned long vaddr,
-                                            unsigned long set_to_zero,
-                                            unsigned long tte,
-                                            unsigned long flags);
-#endif
-
-/* mmu_fault_area_conf()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMU_FAULT_AREA_CONF
- * ARG0:       real address
- * RET0:       status
- * RET1:       previous mmu fault area real address
- * ERRORS:     ENORADDR                Invalid real address
- *             EBADALIGN               Invalid alignment for fault area
- *
- * Configure the MMU fault status area for the calling CPU.  A 64-byte
- * aligned real address specifies where MMU fault status information
- * is placed.  The return value is the previously specified area, or 0
- * for the first invocation.  Specifying a fault area at real address
- * 0 is not allowed.
- */
-#define HV_FAST_MMU_FAULT_AREA_CONF    0x26
-
-/* mmu_enable()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMU_ENABLE
- * ARG0:       enable flag
- * ARG1:       return target address
- * RET0:       status
- * ERRORS:     ENORADDR                Invalid real address when disabling
- *                                     translation.
- *             EBADALIGN               The return target address is not
- *                                     aligned to an instruction.
- *             EINVAL                  The enable flag request the current
- *                                     operating mode (e.g. disable if already
- *                                     disabled)
- *
- * Enable or disable virtual address translation for the calling CPU
- * within the virtual machine domain.  If the enable flag is zero,
- * translation is disabled, any non-zero value will enable
- * translation.
- *
- * When this function returns, the newly selected translation mode
- * will be active.  If the mmu is being enabled, then the return
- * target address is a virtual address else it is a real address.
- *
- * Upon successful completion, control will be returned to the given
- * return target address (ie. the cpu will jump to that address).  On
- * failure, the previous mmu mode remains and the trap simply returns
- * as normal with the appropriate error code in RET0.
- */
-#define HV_FAST_MMU_ENABLE             0x27
-
-/* mmu_unmap_perm_addr()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMU_UNMAP_PERM_ADDR
- * ARG0:       virtual address
- * ARG1:       reserved, must be zero
- * ARG2:       flags (HV_MMU_{IMMU,DMMU})
- * RET0:       status
- * ERRORS:     EINVAL                  Invalid virutal address or flags value
- *             ENOMAP                  Specified mapping was not found
- *
- * Demaps any permanent page mapping (established via
- * mmu_map_perm_addr()) at the given virtual address for context 0 on
- * the current virtual CPU.  Any virtual tagged caches are guaranteed
- * to be kept consistent.
- */
-#define HV_FAST_MMU_UNMAP_PERM_ADDR    0x28
-
-/* mmu_tsb_ctx0_info()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMU_TSB_CTX0_INFO
- * ARG0:       max TSBs
- * ARG1:       buffer pointer
- * RET0:       status
- * RET1:       number of TSBs
- * ERRORS:     EINVAL                  Supplied buffer is too small
- *             EBADALIGN               The buffer pointer is badly aligned
- *             ENORADDR                Invalid real address for buffer pointer
- *
- * Return the TSB configuration as previous defined by mmu_tsb_ctx0()
- * into the provided buffer.  The size of the buffer is given in ARG1
- * in terms of the number of TSB description entries.
- *
- * Upon return, RET1 always contains the number of TSB descriptions
- * previously configured.  If zero TSBs were configured, EOK is
- * returned with RET1 containing 0.
- */
-#define HV_FAST_MMU_TSB_CTX0_INFO      0x29
-
-/* mmu_tsb_ctxnon0_info()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMU_TSB_CTXNON0_INFO
- * ARG0:       max TSBs
- * ARG1:       buffer pointer
- * RET0:       status
- * RET1:       number of TSBs
- * ERRORS:     EINVAL                  Supplied buffer is too small
- *             EBADALIGN               The buffer pointer is badly aligned
- *             ENORADDR                Invalid real address for buffer pointer
- *
- * Return the TSB configuration as previous defined by
- * mmu_tsb_ctxnon0() into the provided buffer.  The size of the buffer
- * is given in ARG1 in terms of the number of TSB description entries.
- *
- * Upon return, RET1 always contains the number of TSB descriptions
- * previously configured.  If zero TSBs were configured, EOK is
- * returned with RET1 containing 0.
- */
-#define HV_FAST_MMU_TSB_CTXNON0_INFO   0x2a
-
-/* mmu_fault_area_info()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMU_FAULT_AREA_INFO
- * RET0:       status
- * RET1:       fault area real address
- * ERRORS:     No errors defined.
- *
- * Return the currently defined MMU fault status area for the current
- * CPU.  The real address of the fault status area is returned in
- * RET1, or 0 is returned in RET1 if no fault status area is defined.
- *
- * Note: mmu_fault_area_conf() may be called with the return value (RET1)
- *       from this service if there is a need to save and restore the fault
- *      area for a cpu.
- */
-#define HV_FAST_MMU_FAULT_AREA_INFO    0x2b
-
-/* Cache and Memory services. */
-
-/* mem_scrub()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MEM_SCRUB
- * ARG0:       real address
- * ARG1:       length
- * RET0:       status
- * RET1:       length scrubbed
- * ERRORS:     ENORADDR        Invalid real address
- *             EBADALIGN       Start address or length are not correctly
- *                             aligned
- *             EINVAL          Length is zero
- *
- * Zero the memory contents in the range real address to real address
- * plus length minus 1.  Also, valid ECC will be generated for that
- * memory address range.  Scrubbing is started at the given real
- * address, but may not scrub the entire given length.  The actual
- * length scrubbed will be returned in RET1.
- *
- * The real address and length must be aligned on an 8K boundary, or
- * contain the start address and length from a sun4v error report.
- *
- * Note: There are two uses for this function.  The first use is to block clear
- *       and initialize memory and the second is to scrub an u ncorrectable
- *       error reported via a resumable or non-resumable trap.  The second
- *       use requires the arguments to be equal to the real address and length
- *       provided in a sun4v memory error report.
- */
-#define HV_FAST_MEM_SCRUB              0x31
-
-/* mem_sync()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MEM_SYNC
- * ARG0:       real address
- * ARG1:       length
- * RET0:       status
- * RET1:       length synced
- * ERRORS:     ENORADDR        Invalid real address
- *             EBADALIGN       Start address or length are not correctly
- *                             aligned
- *             EINVAL          Length is zero
- *
- * Force the next access within the real address to real address plus
- * length minus 1 to be fetches from main system memory.  Less than
- * the given length may be synced, the actual amount synced is
- * returned in RET1.  The real address and length must be aligned on
- * an 8K boundary.
- */
-#define HV_FAST_MEM_SYNC               0x32
-
-/* Time of day services.
- *
- * The hypervisor maintains the time of day on a per-domain basis.
- * Changing the time of day in one domain does not affect the time of
- * day on any other domain.
- *
- * Time is described by a single unsigned 64-bit word which is the
- * number of seconds since the UNIX Epoch (00:00:00 UTC, January 1,
- * 1970).
- */
-
-/* tod_get()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_TOD_GET
- * RET0:       status
- * RET1:       TOD
- * ERRORS:     EWOULDBLOCK     TOD resource is temporarily unavailable
- *             ENOTSUPPORTED   If TOD not supported on this platform
- *
- * Return the current time of day.  May block if TOD access is
- * temporarily not possible.
- */
-#define HV_FAST_TOD_GET                        0x50
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_tod_get(unsigned long *time);
-#endif
-
-/* tod_set()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_TOD_SET
- * ARG0:       TOD
- * RET0:       status
- * ERRORS:     EWOULDBLOCK     TOD resource is temporarily unavailable
- *             ENOTSUPPORTED   If TOD not supported on this platform
- *
- * The current time of day is set to the value specified in ARG0.  May
- * block if TOD access is temporarily not possible.
- */
-#define HV_FAST_TOD_SET                        0x51
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_tod_set(unsigned long time);
-#endif
-
-/* Console services */
-
-/* con_getchar()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CONS_GETCHAR
- * RET0:       status
- * RET1:       character
- * ERRORS:     EWOULDBLOCK     No character available.
- *
- * Returns a character from the console device.  If no character is
- * available then an EWOULDBLOCK error is returned.  If a character is
- * available, then the returned status is EOK and the character value
- * is in RET1.
- *
- * A virtual BREAK is represented by the 64-bit value -1.
- *
- * A virtual HUP signal is represented by the 64-bit value -2.
- */
-#define HV_FAST_CONS_GETCHAR           0x60
-
-/* con_putchar()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CONS_PUTCHAR
- * ARG0:       character
- * RET0:       status
- * ERRORS:     EINVAL          Illegal character
- *             EWOULDBLOCK     Output buffer currently full, would block
- *
- * Send a character to the console device.  Only character values
- * between 0 and 255 may be used.  Values outside this range are
- * invalid except for the 64-bit value -1 which is used to send a
- * virtual BREAK.
- */
-#define HV_FAST_CONS_PUTCHAR           0x61
-
-/* con_read()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CONS_READ
- * ARG0:       buffer real address
- * ARG1:       buffer size in bytes
- * RET0:       status
- * RET1:       bytes read or BREAK or HUP
- * ERRORS:     EWOULDBLOCK     No character available.
- *
- * Reads characters into a buffer from the console device.  If no
- * character is available then an EWOULDBLOCK error is returned.
- * If a character is available, then the returned status is EOK
- * and the number of bytes read into the given buffer is provided
- * in RET1.
- *
- * A virtual BREAK is represented by the 64-bit RET1 value -1.
- *
- * A virtual HUP signal is represented by the 64-bit RET1 value -2.
- *
- * If BREAK or HUP are indicated, no bytes were read into buffer.
- */
-#define HV_FAST_CONS_READ              0x62
-
-/* con_write()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_CONS_WRITE
- * ARG0:       buffer real address
- * ARG1:       buffer size in bytes
- * RET0:       status
- * RET1:       bytes written
- * ERRORS:     EWOULDBLOCK     Output buffer currently full, would block
- *
- * Send a characters in buffer to the console device.  Breaks must be
- * sent using con_putchar().
- */
-#define HV_FAST_CONS_WRITE             0x63
-
-#ifndef __ASSEMBLY__
-extern long sun4v_con_getchar(long *status);
-extern long sun4v_con_putchar(long c);
-extern long sun4v_con_read(unsigned long buffer,
-                          unsigned long size,
-                          unsigned long *bytes_read);
-extern unsigned long sun4v_con_write(unsigned long buffer,
-                                    unsigned long size,
-                                    unsigned long *bytes_written);
-#endif
-
-/* mach_set_soft_state()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MACH_SET_SOFT_STATE
- * ARG0:       software state
- * ARG1:       software state description pointer
- * RET0:       status
- * ERRORS:     EINVAL          software state not valid or software state
- *                             description is not NULL terminated
- *             ENORADDR        software state description pointer is not a
- *                             valid real address
- *             EBADALIGNED     software state description is not correctly
- *                             aligned
- *
- * This allows the guest to report it's soft state to the hypervisor.  There
- * are two primary components to this state.  The first part states whether
- * the guest software is running or not.  The second containts optional
- * details specific to the software.
- *
- * The software state argument is defined below in HV_SOFT_STATE_*, and
- * indicates whether the guest is operating normally or in a transitional
- * state.
- *
- * The software state description argument is a real address of a data buffer
- * of size 32-bytes aligned on a 32-byte boundary.  It is treated as a NULL
- * terminated 7-bit ASCII string of up to 31 characters not including the
- * NULL termination.
- */
-#define HV_FAST_MACH_SET_SOFT_STATE    0x70
-#define  HV_SOFT_STATE_NORMAL           0x01
-#define  HV_SOFT_STATE_TRANSITION       0x02
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_mach_set_soft_state(unsigned long soft_state,
-                                              unsigned long msg_string_ra);
-#endif
-
-/* mach_get_soft_state()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MACH_GET_SOFT_STATE
- * ARG0:       software state description pointer
- * RET0:       status
- * RET1:       software state
- * ERRORS:     ENORADDR        software state description pointer is not a
- *                             valid real address
- *             EBADALIGNED     software state description is not correctly
- *                             aligned
- *
- * Retrieve the current value of the guest's software state.  The rules
- * for the software state pointer are the same as for mach_set_soft_state()
- * above.
- */
-#define HV_FAST_MACH_GET_SOFT_STATE    0x71
-
-/* svc_send()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_SVC_SEND
- * ARG0:       service ID
- * ARG1:       buffer real address
- * ARG2:       buffer size
- * RET0:       STATUS
- * RET1:       sent_bytes
- *
- * Be careful, all output registers are clobbered by this operation,
- * so for example it is not possible to save away a value in %o4
- * across the trap.
- */
-#define HV_FAST_SVC_SEND               0x80
-
-/* svc_recv()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_SVC_RECV
- * ARG0:       service ID
- * ARG1:       buffer real address
- * ARG2:       buffer size
- * RET0:       STATUS
- * RET1:       recv_bytes
- *
- * Be careful, all output registers are clobbered by this operation,
- * so for example it is not possible to save away a value in %o4
- * across the trap.
- */
-#define HV_FAST_SVC_RECV               0x81
-
-/* svc_getstatus()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_SVC_GETSTATUS
- * ARG0:       service ID
- * RET0:       STATUS
- * RET1:       status bits
- */
-#define HV_FAST_SVC_GETSTATUS          0x82
-
-/* svc_setstatus()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_SVC_SETSTATUS
- * ARG0:       service ID
- * ARG1:       bits to set
- * RET0:       STATUS
- */
-#define HV_FAST_SVC_SETSTATUS          0x83
-
-/* svc_clrstatus()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_SVC_CLRSTATUS
- * ARG0:       service ID
- * ARG1:       bits to clear
- * RET0:       STATUS
- */
-#define HV_FAST_SVC_CLRSTATUS          0x84
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_svc_send(unsigned long svc_id,
-                                   unsigned long buffer,
-                                   unsigned long buffer_size,
-                                   unsigned long *sent_bytes);
-extern unsigned long sun4v_svc_recv(unsigned long svc_id,
-                                   unsigned long buffer,
-                                   unsigned long buffer_size,
-                                   unsigned long *recv_bytes);
-extern unsigned long sun4v_svc_getstatus(unsigned long svc_id,
-                                        unsigned long *status_bits);
-extern unsigned long sun4v_svc_setstatus(unsigned long svc_id,
-                                        unsigned long status_bits);
-extern unsigned long sun4v_svc_clrstatus(unsigned long svc_id,
-                                        unsigned long status_bits);
-#endif
-
-/* Trap trace services.
- *
- * The hypervisor provides a trap tracing capability for privileged
- * code running on each virtual CPU.  Privileged code provides a
- * round-robin trap trace queue within which the hypervisor writes
- * 64-byte entries detailing hyperprivileged traps taken n behalf of
- * privileged code.  This is provided as a debugging capability for
- * privileged code.
- *
- * The trap trace control structure is 64-bytes long and placed at the
- * start (offset 0) of the trap trace buffer, and is described as
- * follows:
- */
-#ifndef __ASSEMBLY__
-struct hv_trap_trace_control {
-       unsigned long           head_offset;
-       unsigned long           tail_offset;
-       unsigned long           __reserved[0x30 / sizeof(unsigned long)];
-};
-#endif
-#define HV_TRAP_TRACE_CTRL_HEAD_OFFSET 0x00
-#define HV_TRAP_TRACE_CTRL_TAIL_OFFSET 0x08
-
-/* The head offset is the offset of the most recently completed entry
- * in the trap-trace buffer.  The tail offset is the offset of the
- * next entry to be written.  The control structure is owned and
- * modified by the hypervisor.  A guest may not modify the control
- * structure contents.  Attempts to do so will result in undefined
- * behavior for the guest.
- *
- * Each trap trace buffer entry is layed out as follows:
- */
-#ifndef __ASSEMBLY__
-struct hv_trap_trace_entry {
-       unsigned char   type;           /* Hypervisor or guest entry?   */
-       unsigned char   hpstate;        /* Hyper-privileged state       */
-       unsigned char   tl;             /* Trap level                   */
-       unsigned char   gl;             /* Global register level        */
-       unsigned short  tt;             /* Trap type                    */
-       unsigned short  tag;            /* Extended trap identifier     */
-       unsigned long   tstate;         /* Trap state                   */
-       unsigned long   tick;           /* Tick                         */
-       unsigned long   tpc;            /* Trap PC                      */
-       unsigned long   f1;             /* Entry specific               */
-       unsigned long   f2;             /* Entry specific               */
-       unsigned long   f3;             /* Entry specific               */
-       unsigned long   f4;             /* Entry specific               */
-};
-#endif
-#define HV_TRAP_TRACE_ENTRY_TYPE       0x00
-#define HV_TRAP_TRACE_ENTRY_HPSTATE    0x01
-#define HV_TRAP_TRACE_ENTRY_TL         0x02
-#define HV_TRAP_TRACE_ENTRY_GL         0x03
-#define HV_TRAP_TRACE_ENTRY_TT         0x04
-#define HV_TRAP_TRACE_ENTRY_TAG                0x06
-#define HV_TRAP_TRACE_ENTRY_TSTATE     0x08
-#define HV_TRAP_TRACE_ENTRY_TICK       0x10
-#define HV_TRAP_TRACE_ENTRY_TPC                0x18
-#define HV_TRAP_TRACE_ENTRY_F1         0x20
-#define HV_TRAP_TRACE_ENTRY_F2         0x28
-#define HV_TRAP_TRACE_ENTRY_F3         0x30
-#define HV_TRAP_TRACE_ENTRY_F4         0x38
-
-/* The type field is encoded as follows.  */
-#define HV_TRAP_TYPE_UNDEF             0x00 /* Entry content undefined     */
-#define HV_TRAP_TYPE_HV                        0x01 /* Hypervisor trap entry       */
-#define HV_TRAP_TYPE_GUEST             0xff /* Added via ttrace_addentry() */
-
-/* ttrace_buf_conf()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_TTRACE_BUF_CONF
- * ARG0:       real address
- * ARG1:       number of entries
- * RET0:       status
- * RET1:       number of entries
- * ERRORS:     ENORADDR        Invalid real address
- *             EINVAL          Size is too small
- *             EBADALIGN       Real address not aligned on 64-byte boundary
- *
- * Requests hypervisor trap tracing and declares a virtual CPU's trap
- * trace buffer to the hypervisor.  The real address supplies the real
- * base address of the trap trace queue and must be 64-byte aligned.
- * Specifying a value of 0 for the number of entries disables trap
- * tracing for the calling virtual CPU.  The buffer allocated must be
- * sized for a power of two number of 64-byte trap trace entries plus
- * an initial 64-byte control structure.
- * 
- * This may be invoked any number of times so that a virtual CPU may
- * relocate a trap trace buffer or create "snapshots" of information.
- *
- * If the real address is illegal or badly aligned, then trap tracing
- * is disabled and an error is returned.
- *
- * Upon failure with EINVAL, this service call returns in RET1 the
- * minimum number of buffer entries required.  Upon other failures
- * RET1 is undefined.
- */
-#define HV_FAST_TTRACE_BUF_CONF                0x90
-
-/* ttrace_buf_info()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_TTRACE_BUF_INFO
- * RET0:       status
- * RET1:       real address
- * RET2:       size
- * ERRORS:     None defined.
- *
- * Returns the size and location of the previously declared trap-trace
- * buffer.  In the event that no buffer was previously defined, or the
- * buffer is disabled, this call will return a size of zero bytes.
- */
-#define HV_FAST_TTRACE_BUF_INFO                0x91
-
-/* ttrace_enable()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_TTRACE_ENABLE
- * ARG0:       enable
- * RET0:       status
- * RET1:       previous enable state
- * ERRORS:     EINVAL          No trap trace buffer currently defined
- *
- * Enable or disable trap tracing, and return the previous enabled
- * state in RET1.  Future systems may define various flags for the
- * enable argument (ARG0), for the moment a guest should pass
- * "(uint64_t) -1" to enable, and "(uint64_t) 0" to disable all
- * tracing - which will ensure future compatability.
- */
-#define HV_FAST_TTRACE_ENABLE          0x92
-
-/* ttrace_freeze()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_TTRACE_FREEZE
- * ARG0:       freeze
- * RET0:       status
- * RET1:       previous freeze state
- * ERRORS:     EINVAL          No trap trace buffer currently defined
- *
- * Freeze or unfreeze trap tracing, returning the previous freeze
- * state in RET1.  A guest should pass a non-zero value to freeze and
- * a zero value to unfreeze all tracing.  The returned previous state
- * is 0 for not frozen and 1 for frozen.
- */
-#define HV_FAST_TTRACE_FREEZE          0x93
-
-/* ttrace_addentry()
- * TRAP:       HV_TTRACE_ADDENTRY_TRAP
- * ARG0:       tag (16-bits)
- * ARG1:       data word 0
- * ARG2:       data word 1
- * ARG3:       data word 2
- * ARG4:       data word 3
- * RET0:       status
- * ERRORS:     EINVAL          No trap trace buffer currently defined
- *
- * Add an entry to the trap trace buffer.  Upon return only ARG0/RET0
- * is modified - none of the other registers holding arguments are
- * volatile across this hypervisor service.
- */
-
-/* Core dump services.
- *
- * Since the hypervisor viraulizes and thus obscures a lot of the
- * physical machine layout and state, traditional OS crash dumps can
- * be difficult to diagnose especially when the problem is a
- * configuration error of some sort.
- *
- * The dump services provide an opaque buffer into which the
- * hypervisor can place it's internal state in order to assist in
- * debugging such situations.  The contents are opaque and extremely
- * platform and hypervisor implementation specific.  The guest, during
- * a core dump, requests that the hypervisor update any information in
- * the dump buffer in preparation to being dumped as part of the
- * domain's memory image.
- */
-
-/* dump_buf_update()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_DUMP_BUF_UPDATE
- * ARG0:       real address
- * ARG1:       size
- * RET0:       status
- * RET1:       required size of dump buffer
- * ERRORS:     ENORADDR        Invalid real address
- *             EBADALIGN       Real address is not aligned on a 64-byte
- *                             boundary
- *             EINVAL          Size is non-zero but less than minimum size
- *                             required
- *             ENOTSUPPORTED   Operation not supported on current logical
- *                             domain
- *
- * Declare a domain dump buffer to the hypervisor.  The real address
- * provided for the domain dump buffer must be 64-byte aligned.  The
- * size specifies the size of the dump buffer and may be larger than
- * the minimum size specified in the machine description.  The
- * hypervisor will fill the dump buffer with opaque data.
- *
- * Note: A guest may elect to include dump buffer contents as part of a crash
- *       dump to assist with debugging.  This function may be called any number
- *       of times so that a guest may relocate a dump buffer, or create
- *       "snapshots" of any dump-buffer information.  Each call to
- *       dump_buf_update() atomically declares the new dump buffer to the
- *       hypervisor.
- *
- * A specified size of 0 unconfigures the dump buffer.  If the real
- * address is illegal or badly aligned, then any currently active dump
- * buffer is disabled and an error is returned.
- *
- * In the event that the call fails with EINVAL, RET1 contains the
- * minimum size requires by the hypervisor for a valid dump buffer.
- */
-#define HV_FAST_DUMP_BUF_UPDATE                0x94
-
-/* dump_buf_info()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_DUMP_BUF_INFO
- * RET0:       status
- * RET1:       real address of current dump buffer
- * RET2:       size of current dump buffer
- * ERRORS:     No errors defined.
- *
- * Return the currently configures dump buffer description.  A
- * returned size of 0 bytes indicates an undefined dump buffer.  In
- * this case the return address in RET1 is undefined.
- */
-#define HV_FAST_DUMP_BUF_INFO          0x95
-
-/* Device interrupt services.
- *
- * Device interrupts are allocated to system bus bridges by the hypervisor,
- * and described to OBP in the machine description.  OBP then describes
- * these interrupts to the OS via properties in the device tree.
- *
- * Terminology:
- *
- *     cpuid           Unique opaque value which represents a target cpu.
- *
- *     devhandle       Device handle.  It uniquely identifies a device, and
- *                     consistes of the lower 28-bits of the hi-cell of the
- *                     first entry of the device's "reg" property in the
- *                     OBP device tree.
- *
- *     devino          Device interrupt number.  Specifies the relative
- *                     interrupt number within the device.  The unique
- *                     combination of devhandle and devino are used to
- *                     identify a specific device interrupt.
- *
- *                     Note: The devino value is the same as the values in the
- *                           "interrupts" property or "interrupt-map" property
- *                           in the OBP device tree for that device.
- *
- *     sysino          System interrupt number.  A 64-bit unsigned interger
- *                     representing a unique interrupt within a virtual
- *                     machine.
- *
- *     intr_state      A flag representing the interrupt state for a given
- *                     sysino.  The state values are defined below.
- *
- *     intr_enabled    A flag representing the 'enabled' state for a given
- *                     sysino.  The enable values are defined below.
- */
-
-#define HV_INTR_STATE_IDLE             0 /* Nothing pending */
-#define HV_INTR_STATE_RECEIVED         1 /* Interrupt received by hardware */
-#define HV_INTR_STATE_DELIVERED                2 /* Interrupt delivered to queue */
-
-#define HV_INTR_DISABLED               0 /* sysino not enabled */
-#define HV_INTR_ENABLED                        1 /* sysino enabled */
-
-/* intr_devino_to_sysino()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_INTR_DEVINO2SYSINO
- * ARG0:       devhandle
- * ARG1:       devino
- * RET0:       status
- * RET1:       sysino
- * ERRORS:     EINVAL          Invalid devhandle/devino
- *
- * Converts a device specific interrupt number of the given
- * devhandle/devino into a system specific ino (sysino).
- */
-#define HV_FAST_INTR_DEVINO2SYSINO     0xa0
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_devino_to_sysino(unsigned long devhandle,
-                                           unsigned long devino);
-#endif
-
-/* intr_getenabled()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_INTR_GETENABLED
- * ARG0:       sysino
- * RET0:       status
- * RET1:       intr_enabled (HV_INTR_{DISABLED,ENABLED})
- * ERRORS:     EINVAL          Invalid sysino
- *
- * Returns interrupt enabled state in RET1 for the interrupt defined
- * by the given sysino.
- */
-#define HV_FAST_INTR_GETENABLED                0xa1
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_intr_getenabled(unsigned long sysino);
-#endif
-
-/* intr_setenabled()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_INTR_SETENABLED
- * ARG0:       sysino
- * ARG1:       intr_enabled (HV_INTR_{DISABLED,ENABLED})
- * RET0:       status
- * ERRORS:     EINVAL          Invalid sysino or intr_enabled value
- *
- * Set the 'enabled' state of the interrupt sysino.
- */
-#define HV_FAST_INTR_SETENABLED                0xa2
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_intr_setenabled(unsigned long sysino, unsigned long intr_enabled);
-#endif
-
-/* intr_getstate()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_INTR_GETSTATE
- * ARG0:       sysino
- * RET0:       status
- * RET1:       intr_state (HV_INTR_STATE_*)
- * ERRORS:     EINVAL          Invalid sysino
- *
- * Returns current state of the interrupt defined by the given sysino.
- */
-#define HV_FAST_INTR_GETSTATE          0xa3
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_intr_getstate(unsigned long sysino);
-#endif
-
-/* intr_setstate()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_INTR_SETSTATE
- * ARG0:       sysino
- * ARG1:       intr_state (HV_INTR_STATE_*)
- * RET0:       status
- * ERRORS:     EINVAL          Invalid sysino or intr_state value
- *
- * Sets the current state of the interrupt described by the given sysino
- * value.
- *
- * Note: Setting the state to HV_INTR_STATE_IDLE clears any pending
- *       interrupt for sysino.
- */
-#define HV_FAST_INTR_SETSTATE          0xa4
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_intr_setstate(unsigned long sysino, unsigned long intr_state);
-#endif
-
-/* intr_gettarget()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_INTR_GETTARGET
- * ARG0:       sysino
- * RET0:       status
- * RET1:       cpuid
- * ERRORS:     EINVAL          Invalid sysino
- *
- * Returns CPU that is the current target of the interrupt defined by
- * the given sysino.  The CPU value returned is undefined if the target
- * has not been set via intr_settarget().
- */
-#define HV_FAST_INTR_GETTARGET         0xa5
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_intr_gettarget(unsigned long sysino);
-#endif
-
-/* intr_settarget()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_INTR_SETTARGET
- * ARG0:       sysino
- * ARG1:       cpuid
- * RET0:       status
- * ERRORS:     EINVAL          Invalid sysino
- *             ENOCPU          Invalid cpuid
- *
- * Set the target CPU for the interrupt defined by the given sysino.
- */
-#define HV_FAST_INTR_SETTARGET         0xa6
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_intr_settarget(unsigned long sysino, unsigned long cpuid);
-#endif
-
-/* vintr_get_cookie()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_VINTR_GET_COOKIE
- * ARG0:       device handle
- * ARG1:       device ino
- * RET0:       status
- * RET1:       cookie
- */
-#define HV_FAST_VINTR_GET_COOKIE       0xa7
-
-/* vintr_set_cookie()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_VINTR_SET_COOKIE
- * ARG0:       device handle
- * ARG1:       device ino
- * ARG2:       cookie
- * RET0:       status
- */
-#define HV_FAST_VINTR_SET_COOKIE       0xa8
-
-/* vintr_get_valid()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_VINTR_GET_VALID
- * ARG0:       device handle
- * ARG1:       device ino
- * RET0:       status
- * RET1:       valid state
- */
-#define HV_FAST_VINTR_GET_VALID                0xa9
-
-/* vintr_set_valid()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_VINTR_SET_VALID
- * ARG0:       device handle
- * ARG1:       device ino
- * ARG2:       valid state
- * RET0:       status
- */
-#define HV_FAST_VINTR_SET_VALID                0xaa
-
-/* vintr_get_state()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_VINTR_GET_STATE
- * ARG0:       device handle
- * ARG1:       device ino
- * RET0:       status
- * RET1:       state
- */
-#define HV_FAST_VINTR_GET_STATE                0xab
-
-/* vintr_set_state()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_VINTR_SET_STATE
- * ARG0:       device handle
- * ARG1:       device ino
- * ARG2:       state
- * RET0:       status
- */
-#define HV_FAST_VINTR_SET_STATE                0xac
-
-/* vintr_get_target()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_VINTR_GET_TARGET
- * ARG0:       device handle
- * ARG1:       device ino
- * RET0:       status
- * RET1:       cpuid
- */
-#define HV_FAST_VINTR_GET_TARGET       0xad
-
-/* vintr_set_target()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_VINTR_SET_TARGET
- * ARG0:       device handle
- * ARG1:       device ino
- * ARG2:       cpuid
- * RET0:       status
- */
-#define HV_FAST_VINTR_SET_TARGET       0xae
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_vintr_get_cookie(unsigned long dev_handle,
-                                           unsigned long dev_ino,
-                                           unsigned long *cookie);
-extern unsigned long sun4v_vintr_set_cookie(unsigned long dev_handle,
-                                           unsigned long dev_ino,
-                                           unsigned long cookie);
-extern unsigned long sun4v_vintr_get_valid(unsigned long dev_handle,
-                                          unsigned long dev_ino,
-                                          unsigned long *valid);
-extern unsigned long sun4v_vintr_set_valid(unsigned long dev_handle,
-                                          unsigned long dev_ino,
-                                          unsigned long valid);
-extern unsigned long sun4v_vintr_get_state(unsigned long dev_handle,
-                                          unsigned long dev_ino,
-                                          unsigned long *state);
-extern unsigned long sun4v_vintr_set_state(unsigned long dev_handle,
-                                          unsigned long dev_ino,
-                                          unsigned long state);
-extern unsigned long sun4v_vintr_get_target(unsigned long dev_handle,
-                                           unsigned long dev_ino,
-                                           unsigned long *cpuid);
-extern unsigned long sun4v_vintr_set_target(unsigned long dev_handle,
-                                           unsigned long dev_ino,
-                                           unsigned long cpuid);
-#endif
-
-/* PCI IO services.
- *
- * See the terminology descriptions in the device interrupt services
- * section above as those apply here too.  Here are terminology
- * definitions specific to these PCI IO services:
- *
- *     tsbnum          TSB number.  Indentifies which io-tsb is used.
- *                     For this version of the specification, tsbnum
- *                     must be zero.
- *
- *     tsbindex        TSB index.  Identifies which entry in the TSB
- *                     is used.  The first entry is zero.
- *
- *     tsbid           A 64-bit aligned data structure which contains
- *                     a tsbnum and a tsbindex.  Bits 63:32 contain the
- *                     tsbnum and bits 31:00 contain the tsbindex.
- *
- *                     Use the HV_PCI_TSBID() macro to construct such
- *                     values.
- *
- *     io_attributes   IO attributes for IOMMU mappings.  One of more
- *                     of the attritbute bits are stores in a 64-bit
- *                     value.  The values are defined below.
- *
- *     r_addr          64-bit real address
- *
- *     pci_device      PCI device address.  A PCI device address identifies
- *                     a specific device on a specific PCI bus segment.
- *                     A PCI device address ia a 32-bit unsigned integer
- *                     with the following format:
- *
- *                             00000000.bbbbbbbb.dddddfff.00000000
- *
- *                     Use the HV_PCI_DEVICE_BUILD() macro to construct
- *                     such values.
- *
- *     pci_config_offset
- *                     PCI configureation space offset.  For conventional
- *                     PCI a value between 0 and 255.  For extended
- *                     configuration space, a value between 0 and 4095.
- *
- *                     Note: For PCI configuration space accesses, the offset
- *                           must be aligned to the access size.
- *
- *     error_flag      A return value which specifies if the action succeeded
- *                     or failed.  0 means no error, non-0 means some error
- *                     occurred while performing the service.
- *
- *     io_sync_direction
- *                     Direction definition for pci_dma_sync(), defined
- *                     below in HV_PCI_SYNC_*.
- *
- *     io_page_list    A list of io_page_addresses, an io_page_address is
- *                     a real address.
- *
- *     io_page_list_p  A pointer to an io_page_list.
- *
- *     "size based byte swap" - Some functions do size based byte swapping
- *                              which allows sw to access pointers and
- *                              counters in native form when the processor
- *                              operates in a different endianness than the
- *                              IO bus.  Size-based byte swapping converts a
- *                              multi-byte field between big-endian and
- *                              little-endian format.
- */
-
-#define HV_PCI_MAP_ATTR_READ           0x01
-#define HV_PCI_MAP_ATTR_WRITE          0x02
-
-#define HV_PCI_DEVICE_BUILD(b,d,f)     \
-       ((((b) & 0xff) << 16) | \
-        (((d) & 0x1f) << 11) | \
-        (((f) & 0x07) <<  8))
-
-#define HV_PCI_TSBID(__tsb_num, __tsb_index) \
-       ((((u64)(__tsb_num)) << 32UL) | ((u64)(__tsb_index)))
-
-#define HV_PCI_SYNC_FOR_DEVICE         0x01
-#define HV_PCI_SYNC_FOR_CPU            0x02
-
-/* pci_iommu_map()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_IOMMU_MAP
- * ARG0:       devhandle
- * ARG1:       tsbid
- * ARG2:       #ttes
- * ARG3:       io_attributes
- * ARG4:       io_page_list_p
- * RET0:       status
- * RET1:       #ttes mapped
- * ERRORS:     EINVAL          Invalid devhandle/tsbnum/tsbindex/io_attributes
- *             EBADALIGN       Improperly aligned real address
- *             ENORADDR        Invalid real address
- *
- * Create IOMMU mappings in the sun4v device defined by the given
- * devhandle.  The mappings are created in the TSB defined by the
- * tsbnum component of the given tsbid.  The first mapping is created
- * in the TSB i ndex defined by the tsbindex component of the given tsbid.
- * The call creates up to #ttes mappings, the first one at tsbnum, tsbindex,
- * the second at tsbnum, tsbindex + 1, etc.
- *
- * All mappings are created with the attributes defined by the io_attributes
- * argument.  The page mapping addresses are described in the io_page_list
- * defined by the given io_page_list_p, which is a pointer to the io_page_list.
- * The first entry in the io_page_list is the address for the first iotte, the
- * 2nd for the 2nd iotte, and so on.
- *
- * Each io_page_address in the io_page_list must be appropriately aligned.
- * #ttes must be greater than zero.  For this version of the spec, the tsbnum
- * component of the given tsbid must be zero.
- *
- * Returns the actual number of mappings creates, which may be less than
- * or equal to the argument #ttes.  If the function returns a value which
- * is less than the #ttes, the caller may continus to call the function with
- * an updated tsbid, #ttes, io_page_list_p arguments until all pages are
- * mapped.
- *
- * Note: This function does not imply an iotte cache flush.  The guest must
- *       demap an entry before re-mapping it.
- */
-#define HV_FAST_PCI_IOMMU_MAP          0xb0
-
-/* pci_iommu_demap()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_IOMMU_DEMAP
- * ARG0:       devhandle
- * ARG1:       tsbid
- * ARG2:       #ttes
- * RET0:       status
- * RET1:       #ttes demapped
- * ERRORS:     EINVAL          Invalid devhandle/tsbnum/tsbindex
- *
- * Demap and flush IOMMU mappings in the device defined by the given
- * devhandle.  Demaps up to #ttes entries in the TSB defined by the tsbnum
- * component of the given tsbid, starting at the TSB index defined by the
- * tsbindex component of the given tsbid.
- *
- * For this version of the spec, the tsbnum of the given tsbid must be zero.
- * #ttes must be greater than zero.
- *
- * Returns the actual number of ttes demapped, which may be less than or equal
- * to the argument #ttes.  If #ttes demapped is less than #ttes, the caller
- * may continue to call this function with updated tsbid and #ttes arguments
- * until all pages are demapped.
- *
- * Note: Entries do not have to be mapped to be demapped.  A demap of an
- *       unmapped page will flush the entry from the tte cache.
- */
-#define HV_FAST_PCI_IOMMU_DEMAP                0xb1
-
-/* pci_iommu_getmap()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_IOMMU_GETMAP
- * ARG0:       devhandle
- * ARG1:       tsbid
- * RET0:       status
- * RET1:       io_attributes
- * RET2:       real address
- * ERRORS:     EINVAL          Invalid devhandle/tsbnum/tsbindex
- *             ENOMAP          Mapping is not valid, no translation exists
- *
- * Read and return the mapping in the device described by the given devhandle
- * and tsbid.  If successful, the io_attributes shall be returned in RET1
- * and the page address of the mapping shall be returned in RET2.
- *
- * For this version of the spec, the tsbnum component of the given tsbid
- * must be zero.
- */
-#define HV_FAST_PCI_IOMMU_GETMAP       0xb2
-
-/* pci_iommu_getbypass()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_IOMMU_GETBYPASS
- * ARG0:       devhandle
- * ARG1:       real address
- * ARG2:       io_attributes
- * RET0:       status
- * RET1:       io_addr
- * ERRORS:     EINVAL          Invalid devhandle/io_attributes
- *             ENORADDR        Invalid real address
- *             ENOTSUPPORTED   Function not supported in this implementation.
- *
- * Create a "special" mapping in the device described by the given devhandle,
- * for the given real address and attributes.  Return the IO address in RET1
- * if successful.
- */
-#define HV_FAST_PCI_IOMMU_GETBYPASS    0xb3
-
-/* pci_config_get()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_CONFIG_GET
- * ARG0:       devhandle
- * ARG1:       pci_device
- * ARG2:       pci_config_offset
- * ARG3:       size
- * RET0:       status
- * RET1:       error_flag
- * RET2:       data
- * ERRORS:     EINVAL          Invalid devhandle/pci_device/offset/size
- *             EBADALIGN       pci_config_offset not size aligned
- *             ENOACCESS       Access to this offset is not permitted
- *
- * Read PCI configuration space for the adapter described by the given
- * devhandle.  Read size (1, 2, or 4) bytes of data from the given
- * pci_device, at pci_config_offset from the beginning of the device's
- * configuration space.  If there was no error, RET1 is set to zero and
- * RET2 is set to the data read.  Insignificant bits in RET2 are not
- * guarenteed to have any specific value and therefore must be ignored.
- *
- * The data returned in RET2 is size based byte swapped.
- *
- * If an error occurs during the read, set RET1 to a non-zero value.  The
- * given pci_config_offset must be 'size' aligned.
- */
-#define HV_FAST_PCI_CONFIG_GET         0xb4
-
-/* pci_config_put()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_CONFIG_PUT
- * ARG0:       devhandle
- * ARG1:       pci_device
- * ARG2:       pci_config_offset
- * ARG3:       size
- * ARG4:       data
- * RET0:       status
- * RET1:       error_flag
- * ERRORS:     EINVAL          Invalid devhandle/pci_device/offset/size
- *             EBADALIGN       pci_config_offset not size aligned
- *             ENOACCESS       Access to this offset is not permitted
- *
- * Write PCI configuration space for the adapter described by the given
- * devhandle.  Write size (1, 2, or 4) bytes of data in a single operation,
- * at pci_config_offset from the beginning of the device's configuration
- * space.  The data argument contains the data to be written to configuration
- * space.  Prior to writing, the data is size based byte swapped.
- *
- * If an error occurs during the write access, do not generate an error
- * report, do set RET1 to a non-zero value.  Otherwise RET1 is zero.
- * The given pci_config_offset must be 'size' aligned.
- *
- * This function is permitted to read from offset zero in the configuration
- * space described by the given pci_device if necessary to ensure that the
- * write access to config space completes.
- */
-#define HV_FAST_PCI_CONFIG_PUT         0xb5
-
-/* pci_peek()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_PEEK
- * ARG0:       devhandle
- * ARG1:       real address
- * ARG2:       size
- * RET0:       status
- * RET1:       error_flag
- * RET2:       data
- * ERRORS:     EINVAL          Invalid devhandle or size
- *             EBADALIGN       Improperly aligned real address
- *             ENORADDR        Bad real address
- *             ENOACCESS       Guest access prohibited
- *
- * Attempt to read the IO address given by the given devhandle, real address,
- * and size.  Size must be 1, 2, 4, or 8.  The read is performed as a single
- * access operation using the given size.  If an error occurs when reading
- * from the given location, do not generate an error report, but return a
- * non-zero value in RET1.  If the read was successful, return zero in RET1
- * and return the actual data read in RET2.  The data returned is size based
- * byte swapped.
- *
- * Non-significant bits in RET2 are not guarenteed to have any specific value
- * and therefore must be ignored.  If RET1 is returned as non-zero, the data 
- * value is not guarenteed to have any specific value and should be ignored.
- *
- * The caller must have permission to read from the given devhandle, real
- * address, which must be an IO address.  The argument real address must be a
- * size aligned address.
- *
- * The hypervisor implementation of this function must block access to any
- * IO address that the guest does not have explicit permission to access.
- */
-#define HV_FAST_PCI_PEEK               0xb6
-
-/* pci_poke()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_POKE
- * ARG0:       devhandle
- * ARG1:       real address
- * ARG2:       size
- * ARG3:       data
- * ARG4:       pci_device
- * RET0:       status
- * RET1:       error_flag
- * ERRORS:     EINVAL          Invalid devhandle, size, or pci_device
- *             EBADALIGN       Improperly aligned real address
- *             ENORADDR        Bad real address
- *             ENOACCESS       Guest access prohibited
- *             ENOTSUPPORTED   Function is not supported by implementation
- *
- * Attempt to write data to the IO address given by the given devhandle,
- * real address, and size.  Size must be 1, 2, 4, or 8.  The write is
- * performed as a single access operation using the given size. Prior to
- * writing the data is size based swapped.
- *
- * If an error occurs when writing to the given location, do not generate an
- * error report, but return a non-zero value in RET1.  If the write was
- * successful, return zero in RET1.
- *
- * pci_device describes the configuration address of the device being
- * written to.  The implementation may safely read from offset 0 with
- * the configuration space of the device described by devhandle and
- * pci_device in order to guarantee that the write portion of the operation
- * completes
- *
- * Any error that occurs due to the read shall be reported using the normal
- * error reporting mechanisms .. the read error is not suppressed.
- *
- * The caller must have permission to write to the given devhandle, real
- * address, which must be an IO address.  The argument real address must be a
- * size aligned address.  The caller must have permission to read from
- * the given devhandle, pci_device cofiguration space offset 0.
- *
- * The hypervisor implementation of this function must block access to any
- * IO address that the guest does not have explicit permission to access.
- */
-#define HV_FAST_PCI_POKE               0xb7
-
-/* pci_dma_sync()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_DMA_SYNC
- * ARG0:       devhandle
- * ARG1:       real address
- * ARG2:       size
- * ARG3:       io_sync_direction
- * RET0:       status
- * RET1:       #synced
- * ERRORS:     EINVAL          Invalid devhandle or io_sync_direction
- *             ENORADDR        Bad real address
- *
- * Synchronize a memory region described by the given real address and size,
- * for the device defined by the given devhandle using the direction(s)
- * defined by the given io_sync_direction.  The argument size is the size of
- * the memory region in bytes.
- *
- * Return the actual number of bytes synchronized in the return value #synced,
- * which may be less than or equal to the argument size.  If the return
- * value #synced is less than size, the caller must continue to call this
- * function with updated real address and size arguments until the entire
- * memory region is synchronized.
- */
-#define HV_FAST_PCI_DMA_SYNC           0xb8
-
-/* PCI MSI services.  */
-
-#define HV_MSITYPE_MSI32               0x00
-#define HV_MSITYPE_MSI64               0x01
-
-#define HV_MSIQSTATE_IDLE              0x00
-#define HV_MSIQSTATE_ERROR             0x01
-
-#define HV_MSIQ_INVALID                        0x00
-#define HV_MSIQ_VALID                  0x01
-
-#define HV_MSISTATE_IDLE               0x00
-#define HV_MSISTATE_DELIVERED          0x01
-
-#define HV_MSIVALID_INVALID            0x00
-#define HV_MSIVALID_VALID              0x01
-
-#define HV_PCIE_MSGTYPE_PME_MSG                0x18
-#define HV_PCIE_MSGTYPE_PME_ACK_MSG    0x1b
-#define HV_PCIE_MSGTYPE_CORR_MSG       0x30
-#define HV_PCIE_MSGTYPE_NONFATAL_MSG   0x31
-#define HV_PCIE_MSGTYPE_FATAL_MSG      0x33
-
-#define HV_MSG_INVALID                 0x00
-#define HV_MSG_VALID                   0x01
-
-/* pci_msiq_conf()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSIQ_CONF
- * ARG0:       devhandle
- * ARG1:       msiqid
- * ARG2:       real address
- * ARG3:       number of entries
- * RET0:       status
- * ERRORS:     EINVAL          Invalid devhandle, msiqid or nentries
- *             EBADALIGN       Improperly aligned real address
- *             ENORADDR        Bad real address
- *
- * Configure the MSI queue given by the devhandle and msiqid arguments,
- * and to be placed at the given real address and be of the given
- * number of entries.  The real address must be aligned exactly to match
- * the queue size.  Each queue entry is 64-bytes long, so f.e. a 32 entry
- * queue must be aligned on a 2048 byte real address boundary.  The MSI-EQ
- * Head and Tail are initialized so that the MSI-EQ is 'empty'.
- *
- * Implementation Note: Certain implementations have fixed sized queues.  In
- *                      that case, number of entries must contain the correct
- *                      value.
- */
-#define HV_FAST_PCI_MSIQ_CONF          0xc0
-
-/* pci_msiq_info()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSIQ_INFO
- * ARG0:       devhandle
- * ARG1:       msiqid
- * RET0:       status
- * RET1:       real address
- * RET2:       number of entries
- * ERRORS:     EINVAL          Invalid devhandle or msiqid
- *
- * Return the configuration information for the MSI queue described
- * by the given devhandle and msiqid.  The base address of the queue
- * is returned in ARG1 and the number of entries is returned in ARG2.
- * If the queue is unconfigured, the real address is undefined and the
- * number of entries will be returned as zero.
- */
-#define HV_FAST_PCI_MSIQ_INFO          0xc1
-
-/* pci_msiq_getvalid()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSIQ_GETVALID
- * ARG0:       devhandle
- * ARG1:       msiqid
- * RET0:       status
- * RET1:       msiqvalid       (HV_MSIQ_VALID or HV_MSIQ_INVALID)
- * ERRORS:     EINVAL          Invalid devhandle or msiqid
- *
- * Get the valid state of the MSI-EQ described by the given devhandle and
- * msiqid.
- */
-#define HV_FAST_PCI_MSIQ_GETVALID      0xc2
-
-/* pci_msiq_setvalid()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSIQ_SETVALID
- * ARG0:       devhandle
- * ARG1:       msiqid
- * ARG2:       msiqvalid       (HV_MSIQ_VALID or HV_MSIQ_INVALID)
- * RET0:       status
- * ERRORS:     EINVAL          Invalid devhandle or msiqid or msiqvalid
- *                             value or MSI EQ is uninitialized
- *
- * Set the valid state of the MSI-EQ described by the given devhandle and
- * msiqid to the given msiqvalid.
- */
-#define HV_FAST_PCI_MSIQ_SETVALID      0xc3
-
-/* pci_msiq_getstate()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSIQ_GETSTATE
- * ARG0:       devhandle
- * ARG1:       msiqid
- * RET0:       status
- * RET1:       msiqstate       (HV_MSIQSTATE_IDLE or HV_MSIQSTATE_ERROR)
- * ERRORS:     EINVAL          Invalid devhandle or msiqid
- *
- * Get the state of the MSI-EQ described by the given devhandle and
- * msiqid.
- */
-#define HV_FAST_PCI_MSIQ_GETSTATE      0xc4
-
-/* pci_msiq_getvalid()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSIQ_GETVALID
- * ARG0:       devhandle
- * ARG1:       msiqid
- * ARG2:       msiqstate       (HV_MSIQSTATE_IDLE or HV_MSIQSTATE_ERROR)
- * RET0:       status
- * ERRORS:     EINVAL          Invalid devhandle or msiqid or msiqstate
- *                             value or MSI EQ is uninitialized
- *
- * Set the state of the MSI-EQ described by the given devhandle and
- * msiqid to the given msiqvalid.
- */
-#define HV_FAST_PCI_MSIQ_SETSTATE      0xc5
-
-/* pci_msiq_gethead()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSIQ_GETHEAD
- * ARG0:       devhandle
- * ARG1:       msiqid
- * RET0:       status
- * RET1:       msiqhead
- * ERRORS:     EINVAL          Invalid devhandle or msiqid
- *
- * Get the current MSI EQ queue head for the MSI-EQ described by the
- * given devhandle and msiqid.
- */
-#define HV_FAST_PCI_MSIQ_GETHEAD       0xc6
-
-/* pci_msiq_sethead()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSIQ_SETHEAD
- * ARG0:       devhandle
- * ARG1:       msiqid
- * ARG2:       msiqhead
- * RET0:       status
- * ERRORS:     EINVAL          Invalid devhandle or msiqid or msiqhead,
- *                             or MSI EQ is uninitialized
- *
- * Set the current MSI EQ queue head for the MSI-EQ described by the
- * given devhandle and msiqid.
- */
-#define HV_FAST_PCI_MSIQ_SETHEAD       0xc7
-
-/* pci_msiq_gettail()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSIQ_GETTAIL
- * ARG0:       devhandle
- * ARG1:       msiqid
- * RET0:       status
- * RET1:       msiqtail
- * ERRORS:     EINVAL          Invalid devhandle or msiqid
- *
- * Get the current MSI EQ queue tail for the MSI-EQ described by the
- * given devhandle and msiqid.
- */
-#define HV_FAST_PCI_MSIQ_GETTAIL       0xc8
-
-/* pci_msi_getvalid()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSI_GETVALID
- * ARG0:       devhandle
- * ARG1:       msinum
- * RET0:       status
- * RET1:       msivalidstate
- * ERRORS:     EINVAL          Invalid devhandle or msinum
- *
- * Get the current valid/enabled state for the MSI defined by the
- * given devhandle and msinum.
- */
-#define HV_FAST_PCI_MSI_GETVALID       0xc9
-
-/* pci_msi_setvalid()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSI_SETVALID
- * ARG0:       devhandle
- * ARG1:       msinum
- * ARG2:       msivalidstate
- * RET0:       status
- * ERRORS:     EINVAL          Invalid devhandle or msinum or msivalidstate
- *
- * Set the current valid/enabled state for the MSI defined by the
- * given devhandle and msinum.
- */
-#define HV_FAST_PCI_MSI_SETVALID       0xca
-
-/* pci_msi_getmsiq()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSI_GETMSIQ
- * ARG0:       devhandle
- * ARG1:       msinum
- * RET0:       status
- * RET1:       msiqid
- * ERRORS:     EINVAL          Invalid devhandle or msinum or MSI is unbound
- *
- * Get the MSI EQ that the MSI defined by the given devhandle and
- * msinum is bound to.
- */
-#define HV_FAST_PCI_MSI_GETMSIQ                0xcb
-
-/* pci_msi_setmsiq()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSI_SETMSIQ
- * ARG0:       devhandle
- * ARG1:       msinum
- * ARG2:       msitype
- * ARG3:       msiqid
- * RET0:       status
- * ERRORS:     EINVAL          Invalid devhandle or msinum or msiqid
- *
- * Set the MSI EQ that the MSI defined by the given devhandle and
- * msinum is bound to.
- */
-#define HV_FAST_PCI_MSI_SETMSIQ                0xcc
-
-/* pci_msi_getstate()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSI_GETSTATE
- * ARG0:       devhandle
- * ARG1:       msinum
- * RET0:       status
- * RET1:       msistate
- * ERRORS:     EINVAL          Invalid devhandle or msinum
- *
- * Get the state of the MSI defined by the given devhandle and msinum.
- * If not initialized, return HV_MSISTATE_IDLE.
- */
-#define HV_FAST_PCI_MSI_GETSTATE       0xcd
-
-/* pci_msi_setstate()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSI_SETSTATE
- * ARG0:       devhandle
- * ARG1:       msinum
- * ARG2:       msistate
- * RET0:       status
- * ERRORS:     EINVAL          Invalid devhandle or msinum or msistate
- *
- * Set the state of the MSI defined by the given devhandle and msinum.
- */
-#define HV_FAST_PCI_MSI_SETSTATE       0xce
-
-/* pci_msg_getmsiq()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSG_GETMSIQ
- * ARG0:       devhandle
- * ARG1:       msgtype
- * RET0:       status
- * RET1:       msiqid
- * ERRORS:     EINVAL          Invalid devhandle or msgtype
- *
- * Get the MSI EQ of the MSG defined by the given devhandle and msgtype.
- */
-#define HV_FAST_PCI_MSG_GETMSIQ                0xd0
-
-/* pci_msg_setmsiq()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSG_SETMSIQ
- * ARG0:       devhandle
- * ARG1:       msgtype
- * ARG2:       msiqid
- * RET0:       status
- * ERRORS:     EINVAL          Invalid devhandle, msgtype, or msiqid
- *
- * Set the MSI EQ of the MSG defined by the given devhandle and msgtype.
- */
-#define HV_FAST_PCI_MSG_SETMSIQ                0xd1
-
-/* pci_msg_getvalid()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSG_GETVALID
- * ARG0:       devhandle
- * ARG1:       msgtype
- * RET0:       status
- * RET1:       msgvalidstate
- * ERRORS:     EINVAL          Invalid devhandle or msgtype
- *
- * Get the valid/enabled state of the MSG defined by the given
- * devhandle and msgtype.
- */
-#define HV_FAST_PCI_MSG_GETVALID       0xd2
-
-/* pci_msg_setvalid()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_PCI_MSG_SETVALID
- * ARG0:       devhandle
- * ARG1:       msgtype
- * ARG2:       msgvalidstate
- * RET0:       status
- * ERRORS:     EINVAL          Invalid devhandle or msgtype or msgvalidstate
- *
- * Set the valid/enabled state of the MSG defined by the given
- * devhandle and msgtype.
- */
-#define HV_FAST_PCI_MSG_SETVALID       0xd3
-
-/* Logical Domain Channel services.  */
-
-#define LDC_CHANNEL_DOWN               0
-#define LDC_CHANNEL_UP                 1
-#define LDC_CHANNEL_RESETTING          2
-
-/* ldc_tx_qconf()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_TX_QCONF
- * ARG0:       channel ID
- * ARG1:       real address base of queue
- * ARG2:       num entries in queue
- * RET0:       status
- *
- * Configure transmit queue for the LDC endpoint specified by the
- * given channel ID, to be placed at the given real address, and
- * be of the given num entries.  Num entries must be a power of two.
- * The real address base of the queue must be aligned on the queue
- * size.  Each queue entry is 64-bytes, so for example, a 32 entry
- * queue must be aligned on a 2048 byte real address boundary.
- *
- * Upon configuration of a valid transmit queue the head and tail
- * pointers are set to a hypervisor specific identical value indicating
- * that the queue initially is empty.
- *
- * The endpoint's transmit queue is un-configured if num entries is zero.
- *
- * The maximum number of entries for each queue for a specific cpu may be
- * determined from the machine description.  A transmit queue may be
- * specified even in the event that the LDC is down (peer endpoint has no
- * receive queue specified).  Transmission will begin as soon as the peer
- * endpoint defines a receive queue.
- *
- * It is recommended that a guest wait for a transmit queue to empty prior
- * to reconfiguring it, or un-configuring it.  Re or un-configuring of a
- * non-empty transmit queue behaves exactly as defined above, however it
- * is undefined as to how many of the pending entries in the original queue
- * will be delivered prior to the re-configuration taking effect.
- * Furthermore, as the queue configuration causes a reset of the head and
- * tail pointers there is no way for a guest to determine how many entries
- * have been sent after the configuration operation.
- */
-#define HV_FAST_LDC_TX_QCONF           0xe0
-
-/* ldc_tx_qinfo()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_TX_QINFO
- * ARG0:       channel ID
- * RET0:       status
- * RET1:       real address base of queue
- * RET2:       num entries in queue
- *
- * Return the configuration info for the transmit queue of LDC endpoint
- * defined by the given channel ID.  The real address is the currently
- * defined real address base of the defined queue, and num entries is the
- * size of the queue in terms of number of entries.
- *
- * If the specified channel ID is a valid endpoint number, but no transmit
- * queue has been defined this service will return success, but with num
- * entries set to zero and the real address will have an undefined value.
- */
-#define HV_FAST_LDC_TX_QINFO           0xe1
-
-/* ldc_tx_get_state()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_TX_GET_STATE
- * ARG0:       channel ID
- * RET0:       status
- * RET1:       head offset
- * RET2:       tail offset
- * RET3:       channel state
- *
- * Return the transmit state, and the head and tail queue pointers, for
- * the transmit queue of the LDC endpoint defined by the given channel ID.
- * The head and tail values are the byte offset of the head and tail
- * positions of the transmit queue for the specified endpoint.
- */
-#define HV_FAST_LDC_TX_GET_STATE       0xe2
-
-/* ldc_tx_set_qtail()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_TX_SET_QTAIL
- * ARG0:       channel ID
- * ARG1:       tail offset
- * RET0:       status
- *
- * Update the tail pointer for the transmit queue associated with the LDC
- * endpoint defined by the given channel ID.  The tail offset specified
- * must be aligned on a 64 byte boundary, and calculated so as to increase
- * the number of pending entries on the transmit queue.  Any attempt to
- * decrease the number of pending transmit queue entires is considered
- * an invalid tail offset and will result in an EINVAL error.
- *
- * Since the tail of the transmit queue may not be moved backwards, the
- * transmit queue may be flushed by configuring a new transmit queue,
- * whereupon the hypervisor will configure the initial transmit head and
- * tail pointers to be equal.
- */
-#define HV_FAST_LDC_TX_SET_QTAIL       0xe3
-
-/* ldc_rx_qconf()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_RX_QCONF
- * ARG0:       channel ID
- * ARG1:       real address base of queue
- * ARG2:       num entries in queue
- * RET0:       status
- *
- * Configure receive queue for the LDC endpoint specified by the
- * given channel ID, to be placed at the given real address, and
- * be of the given num entries.  Num entries must be a power of two.
- * The real address base of the queue must be aligned on the queue
- * size.  Each queue entry is 64-bytes, so for example, a 32 entry
- * queue must be aligned on a 2048 byte real address boundary.
- *
- * The endpoint's transmit queue is un-configured if num entries is zero.
- *
- * If a valid receive queue is specified for a local endpoint the LDC is
- * in the up state for the purpose of transmission to this endpoint.
- *
- * The maximum number of entries for each queue for a specific cpu may be
- * determined from the machine description.
- *
- * As receive queue configuration causes a reset of the queue's head and
- * tail pointers there is no way for a gues to determine how many entries
- * have been received between a preceeding ldc_get_rx_state() API call
- * and the completion of the configuration operation.  It should be noted
- * that datagram delivery is not guarenteed via domain channels anyway,
- * and therefore any higher protocol should be resilient to datagram
- * loss if necessary.  However, to overcome this specific race potential
- * it is recommended, for example, that a higher level protocol be employed
- * to ensure either retransmission, or ensure that no datagrams are pending
- * on the peer endpoint's transmit queue prior to the configuration process.
- */
-#define HV_FAST_LDC_RX_QCONF           0xe4
-
-/* ldc_rx_qinfo()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_RX_QINFO
- * ARG0:       channel ID
- * RET0:       status
- * RET1:       real address base of queue
- * RET2:       num entries in queue
- *
- * Return the configuration info for the receive queue of LDC endpoint
- * defined by the given channel ID.  The real address is the currently
- * defined real address base of the defined queue, and num entries is the
- * size of the queue in terms of number of entries.
- *
- * If the specified channel ID is a valid endpoint number, but no receive
- * queue has been defined this service will return success, but with num
- * entries set to zero and the real address will have an undefined value.
- */
-#define HV_FAST_LDC_RX_QINFO           0xe5
-
-/* ldc_rx_get_state()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_RX_GET_STATE
- * ARG0:       channel ID
- * RET0:       status
- * RET1:       head offset
- * RET2:       tail offset
- * RET3:       channel state
- *
- * Return the receive state, and the head and tail queue pointers, for
- * the receive queue of the LDC endpoint defined by the given channel ID.
- * The head and tail values are the byte offset of the head and tail
- * positions of the receive queue for the specified endpoint.
- */
-#define HV_FAST_LDC_RX_GET_STATE       0xe6
-
-/* ldc_rx_set_qhead()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_RX_SET_QHEAD
- * ARG0:       channel ID
- * ARG1:       head offset
- * RET0:       status
- *
- * Update the head pointer for the receive queue associated with the LDC
- * endpoint defined by the given channel ID.  The head offset specified
- * must be aligned on a 64 byte boundary, and calculated so as to decrease
- * the number of pending entries on the receive queue.  Any attempt to
- * increase the number of pending receive queue entires is considered
- * an invalid head offset and will result in an EINVAL error.
- *
- * The receive queue may be flushed by setting the head offset equal
- * to the current tail offset.
- */
-#define HV_FAST_LDC_RX_SET_QHEAD       0xe7
-
-/* LDC Map Table Entry.  Each slot is defined by a translation table
- * entry, as specified by the LDC_MTE_* bits below, and a 64-bit
- * hypervisor invalidation cookie.
- */
-#define LDC_MTE_PADDR  0x0fffffffffffe000 /* pa[55:13]          */
-#define LDC_MTE_COPY_W 0x0000000000000400 /* copy write access  */
-#define LDC_MTE_COPY_R 0x0000000000000200 /* copy read access   */
-#define LDC_MTE_IOMMU_W        0x0000000000000100 /* IOMMU write access */
-#define LDC_MTE_IOMMU_R        0x0000000000000080 /* IOMMU read access  */
-#define LDC_MTE_EXEC   0x0000000000000040 /* execute            */
-#define LDC_MTE_WRITE  0x0000000000000020 /* read               */
-#define LDC_MTE_READ   0x0000000000000010 /* write              */
-#define LDC_MTE_SZALL  0x000000000000000f /* page size bits     */
-#define LDC_MTE_SZ16GB 0x0000000000000007 /* 16GB page          */
-#define LDC_MTE_SZ2GB  0x0000000000000006 /* 2GB page           */
-#define LDC_MTE_SZ256MB        0x0000000000000005 /* 256MB page         */
-#define LDC_MTE_SZ32MB 0x0000000000000004 /* 32MB page          */
-#define LDC_MTE_SZ4MB  0x0000000000000003 /* 4MB page           */
-#define LDC_MTE_SZ512K 0x0000000000000002 /* 512K page          */
-#define LDC_MTE_SZ64K  0x0000000000000001 /* 64K page           */
-#define LDC_MTE_SZ8K   0x0000000000000000 /* 8K page            */
-
-#ifndef __ASSEMBLY__
-struct ldc_mtable_entry {
-       unsigned long   mte;
-       unsigned long   cookie;
-};
-#endif
-
-/* ldc_set_map_table()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_SET_MAP_TABLE
- * ARG0:       channel ID
- * ARG1:       table real address
- * ARG2:       num entries
- * RET0:       status
- *
- * Register the MTE table at the given table real address, with the
- * specified num entries, for the LDC indicated by the given channel
- * ID.
- */
-#define HV_FAST_LDC_SET_MAP_TABLE      0xea
-
-/* ldc_get_map_table()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_GET_MAP_TABLE
- * ARG0:       channel ID
- * RET0:       status
- * RET1:       table real address
- * RET2:       num entries
- *
- * Return the configuration of the current mapping table registered
- * for the given channel ID.
- */
-#define HV_FAST_LDC_GET_MAP_TABLE      0xeb
-
-#define LDC_COPY_IN    0
-#define LDC_COPY_OUT   1
-
-/* ldc_copy()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_COPY
- * ARG0:       channel ID
- * ARG1:       LDC_COPY_* direction code
- * ARG2:       target real address
- * ARG3:       local real address
- * ARG4:       length in bytes
- * RET0:       status
- * RET1:       actual length in bytes
- */
-#define HV_FAST_LDC_COPY               0xec
-
-#define LDC_MEM_READ   1
-#define LDC_MEM_WRITE  2
-#define LDC_MEM_EXEC   4
-
-/* ldc_mapin()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_MAPIN
- * ARG0:       channel ID
- * ARG1:       cookie
- * RET0:       status
- * RET1:       real address
- * RET2:       LDC_MEM_* permissions
- */
-#define HV_FAST_LDC_MAPIN              0xed
-
-/* ldc_unmap()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_UNMAP
- * ARG0:       real address
- * RET0:       status
- */
-#define HV_FAST_LDC_UNMAP              0xee
-
-/* ldc_revoke()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_LDC_REVOKE
- * ARG0:       channel ID
- * ARG1:       cookie
- * ARG2:       ldc_mtable_entry cookie
- * RET0:       status
- */
-#define HV_FAST_LDC_REVOKE             0xef
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_ldc_tx_qconf(unsigned long channel,
-                                       unsigned long ra,
-                                       unsigned long num_entries);
-extern unsigned long sun4v_ldc_tx_qinfo(unsigned long channel,
-                                       unsigned long *ra,
-                                       unsigned long *num_entries);
-extern unsigned long sun4v_ldc_tx_get_state(unsigned long channel,
-                                           unsigned long *head_off,
-                                           unsigned long *tail_off,
-                                           unsigned long *chan_state);
-extern unsigned long sun4v_ldc_tx_set_qtail(unsigned long channel,
-                                           unsigned long tail_off);
-extern unsigned long sun4v_ldc_rx_qconf(unsigned long channel,
-                                       unsigned long ra,
-                                       unsigned long num_entries);
-extern unsigned long sun4v_ldc_rx_qinfo(unsigned long channel,
-                                       unsigned long *ra,
-                                       unsigned long *num_entries);
-extern unsigned long sun4v_ldc_rx_get_state(unsigned long channel,
-                                           unsigned long *head_off,
-                                           unsigned long *tail_off,
-                                           unsigned long *chan_state);
-extern unsigned long sun4v_ldc_rx_set_qhead(unsigned long channel,
-                                           unsigned long head_off);
-extern unsigned long sun4v_ldc_set_map_table(unsigned long channel,
-                                            unsigned long ra,
-                                            unsigned long num_entries);
-extern unsigned long sun4v_ldc_get_map_table(unsigned long channel,
-                                            unsigned long *ra,
-                                            unsigned long *num_entries);
-extern unsigned long sun4v_ldc_copy(unsigned long channel,
-                                   unsigned long dir_code,
-                                   unsigned long tgt_raddr,
-                                   unsigned long lcl_raddr,
-                                   unsigned long len,
-                                   unsigned long *actual_len);
-extern unsigned long sun4v_ldc_mapin(unsigned long channel,
-                                    unsigned long cookie,
-                                    unsigned long *ra,
-                                    unsigned long *perm);
-extern unsigned long sun4v_ldc_unmap(unsigned long ra);
-extern unsigned long sun4v_ldc_revoke(unsigned long channel,
-                                     unsigned long cookie,
-                                     unsigned long mte_cookie);
-#endif
-
-/* Performance counter services.  */
-
-#define HV_PERF_JBUS_PERF_CTRL_REG     0x00
-#define HV_PERF_JBUS_PERF_CNT_REG      0x01
-#define HV_PERF_DRAM_PERF_CTRL_REG_0   0x02
-#define HV_PERF_DRAM_PERF_CNT_REG_0    0x03
-#define HV_PERF_DRAM_PERF_CTRL_REG_1   0x04
-#define HV_PERF_DRAM_PERF_CNT_REG_1    0x05
-#define HV_PERF_DRAM_PERF_CTRL_REG_2   0x06
-#define HV_PERF_DRAM_PERF_CNT_REG_2    0x07
-#define HV_PERF_DRAM_PERF_CTRL_REG_3   0x08
-#define HV_PERF_DRAM_PERF_CNT_REG_3    0x09
-
-/* get_perfreg()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_GET_PERFREG
- * ARG0:       performance reg number
- * RET0:       status
- * RET1:       performance reg value
- * ERRORS:     EINVAL          Invalid performance register number
- *             ENOACCESS       No access allowed to performance counters
- *
- * Read the value of the given DRAM/JBUS performance counter/control register.
- */
-#define HV_FAST_GET_PERFREG            0x100
-
-/* set_perfreg()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_SET_PERFREG
- * ARG0:       performance reg number
- * ARG1:       performance reg value
- * RET0:       status
- * ERRORS:     EINVAL          Invalid performance register number
- *             ENOACCESS       No access allowed to performance counters
- *
- * Write the given performance reg value to the given DRAM/JBUS
- * performance counter/control register.
- */
-#define HV_FAST_SET_PERFREG            0x101
-
-/* MMU statistics services.
- *
- * The hypervisor maintains MMU statistics and privileged code provides
- * a buffer where these statistics can be collected.  It is continually
- * updated once configured.  The layout is as follows:
- */
-#ifndef __ASSEMBLY__
-struct hv_mmu_statistics {
-       unsigned long immu_tsb_hits_ctx0_8k_tte;
-       unsigned long immu_tsb_ticks_ctx0_8k_tte;
-       unsigned long immu_tsb_hits_ctx0_64k_tte;
-       unsigned long immu_tsb_ticks_ctx0_64k_tte;
-       unsigned long __reserved1[2];
-       unsigned long immu_tsb_hits_ctx0_4mb_tte;
-       unsigned long immu_tsb_ticks_ctx0_4mb_tte;
-       unsigned long __reserved2[2];
-       unsigned long immu_tsb_hits_ctx0_256mb_tte;
-       unsigned long immu_tsb_ticks_ctx0_256mb_tte;
-       unsigned long __reserved3[4];
-       unsigned long immu_tsb_hits_ctxnon0_8k_tte;
-       unsigned long immu_tsb_ticks_ctxnon0_8k_tte;
-       unsigned long immu_tsb_hits_ctxnon0_64k_tte;
-       unsigned long immu_tsb_ticks_ctxnon0_64k_tte;
-       unsigned long __reserved4[2];
-       unsigned long immu_tsb_hits_ctxnon0_4mb_tte;
-       unsigned long immu_tsb_ticks_ctxnon0_4mb_tte;
-       unsigned long __reserved5[2];
-       unsigned long immu_tsb_hits_ctxnon0_256mb_tte;
-       unsigned long immu_tsb_ticks_ctxnon0_256mb_tte;
-       unsigned long __reserved6[4];
-       unsigned long dmmu_tsb_hits_ctx0_8k_tte;
-       unsigned long dmmu_tsb_ticks_ctx0_8k_tte;
-       unsigned long dmmu_tsb_hits_ctx0_64k_tte;
-       unsigned long dmmu_tsb_ticks_ctx0_64k_tte;
-       unsigned long __reserved7[2];
-       unsigned long dmmu_tsb_hits_ctx0_4mb_tte;
-       unsigned long dmmu_tsb_ticks_ctx0_4mb_tte;
-       unsigned long __reserved8[2];
-       unsigned long dmmu_tsb_hits_ctx0_256mb_tte;
-       unsigned long dmmu_tsb_ticks_ctx0_256mb_tte;
-       unsigned long __reserved9[4];
-       unsigned long dmmu_tsb_hits_ctxnon0_8k_tte;
-       unsigned long dmmu_tsb_ticks_ctxnon0_8k_tte;
-       unsigned long dmmu_tsb_hits_ctxnon0_64k_tte;
-       unsigned long dmmu_tsb_ticks_ctxnon0_64k_tte;
-       unsigned long __reserved10[2];
-       unsigned long dmmu_tsb_hits_ctxnon0_4mb_tte;
-       unsigned long dmmu_tsb_ticks_ctxnon0_4mb_tte;
-       unsigned long __reserved11[2];
-       unsigned long dmmu_tsb_hits_ctxnon0_256mb_tte;
-       unsigned long dmmu_tsb_ticks_ctxnon0_256mb_tte;
-       unsigned long __reserved12[4];
-};
-#endif
-
-/* mmustat_conf()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMUSTAT_CONF
- * ARG0:       real address
- * RET0:       status
- * RET1:       real address
- * ERRORS:     ENORADDR        Invalid real address
- *             EBADALIGN       Real address not aligned on 64-byte boundary
- *             EBADTRAP        API not supported on this processor
- *
- * Enable MMU statistic gathering using the buffer at the given real
- * address on the current virtual CPU.  The new buffer real address
- * is given in ARG1, and the previously specified buffer real address
- * is returned in RET1, or is returned as zero for the first invocation.
- *
- * If the passed in real address argument is zero, this will disable
- * MMU statistic collection on the current virtual CPU.  If an error is
- * returned then no statistics are collected.
- *
- * The buffer contents should be initialized to all zeros before being
- * given to the hypervisor or else the statistics will be meaningless.
- */
-#define HV_FAST_MMUSTAT_CONF           0x102
-
-/* mmustat_info()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_MMUSTAT_INFO
- * RET0:       status
- * RET1:       real address
- * ERRORS:     EBADTRAP        API not supported on this processor
- *
- * Return the current state and real address of the currently configured
- * MMU statistics buffer on the current virtual CPU.
- */
-#define HV_FAST_MMUSTAT_INFO           0x103
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_mmustat_conf(unsigned long ra, unsigned long *orig_ra);
-extern unsigned long sun4v_mmustat_info(unsigned long *ra);
-#endif
-
-/* NCS crypto services  */
-
-/* ncs_request() sub-function numbers */
-#define HV_NCS_QCONF                   0x01
-#define HV_NCS_QTAIL_UPDATE            0x02
-
-#ifndef __ASSEMBLY__
-struct hv_ncs_queue_entry {
-       /* MAU Control Register */
-       unsigned long   mau_control;
-#define MAU_CONTROL_INV_PARITY 0x0000000000002000
-#define MAU_CONTROL_STRAND     0x0000000000001800
-#define MAU_CONTROL_BUSY       0x0000000000000400
-#define MAU_CONTROL_INT                0x0000000000000200
-#define MAU_CONTROL_OP         0x00000000000001c0
-#define MAU_CONTROL_OP_SHIFT   6
-#define MAU_OP_LOAD_MA_MEMORY  0x0
-#define MAU_OP_STORE_MA_MEMORY 0x1
-#define MAU_OP_MODULAR_MULT    0x2
-#define MAU_OP_MODULAR_REDUCE  0x3
-#define MAU_OP_MODULAR_EXP_LOOP        0x4
-#define MAU_CONTROL_LEN                0x000000000000003f
-#define MAU_CONTROL_LEN_SHIFT  0
-
-       /* Real address of bytes to load or store bytes
-        * into/out-of the MAU.
-        */
-       unsigned long   mau_mpa;
-
-       /* Modular Arithmetic MA Offset Register.  */
-       unsigned long   mau_ma;
-
-       /* Modular Arithmetic N Prime Register.  */
-       unsigned long   mau_np;
-};
-
-struct hv_ncs_qconf_arg {
-       unsigned long   mid;      /* MAU ID, 1 per core on Niagara */
-       unsigned long   base;     /* Real address base of queue */
-       unsigned long   end;      /* Real address end of queue */
-       unsigned long   num_ents; /* Number of entries in queue */
-};
-
-struct hv_ncs_qtail_update_arg {
-       unsigned long   mid;      /* MAU ID, 1 per core on Niagara */
-       unsigned long   tail;     /* New tail index to use */
-       unsigned long   syncflag; /* only SYNCFLAG_SYNC is implemented */
-#define HV_NCS_SYNCFLAG_SYNC   0x00
-#define HV_NCS_SYNCFLAG_ASYNC  0x01
-};
-#endif
-
-/* ncs_request()
- * TRAP:       HV_FAST_TRAP
- * FUNCTION:   HV_FAST_NCS_REQUEST
- * ARG0:       NCS sub-function
- * ARG1:       sub-function argument real address
- * ARG2:       size in bytes of sub-function argument
- * RET0:       status
- *
- * The MAU chip of the Niagara processor is not directly accessible
- * to privileged code, instead it is programmed indirectly via this
- * hypervisor API.
- *
- * The interfaces defines a queue of MAU operations to perform.
- * Privileged code registers a queue with the hypervisor by invoking
- * this HVAPI with the HV_NCS_QCONF sub-function, which defines the
- * base, end, and number of entries of the queue.  Each queue entry
- * contains a MAU register struct block.
- *
- * The privileged code then proceeds to add entries to the queue and
- * then invoke the HV_NCS_QTAIL_UPDATE sub-function.  Since only
- * synchronous operations are supported by the current hypervisor,
- * HV_NCS_QTAIL_UPDATE will run all the pending queue entries to
- * completion and return HV_EOK, or return an error code.
- *
- * The real address of the sub-function argument must be aligned on at
- * least an 8-byte boundary.
- *
- * The tail argument of HV_NCS_QTAIL_UPDATE is an index, not a byte
- * offset, into the queue and must be less than or equal the 'num_ents'
- * argument given in the HV_NCS_QCONF call.
- */
-#define HV_FAST_NCS_REQUEST            0x110
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_ncs_request(unsigned long request,
-                                      unsigned long arg_ra,
-                                      unsigned long arg_size);
-#endif
-
-#define HV_FAST_FIRE_GET_PERFREG       0x120
-#define HV_FAST_FIRE_SET_PERFREG       0x121
-
-/* Function numbers for HV_CORE_TRAP.  */
-#define HV_CORE_SET_VER                        0x00
-#define HV_CORE_PUTCHAR                        0x01
-#define HV_CORE_EXIT                   0x02
-#define HV_CORE_GET_VER                        0x03
-
-/* Hypervisor API groups for use with HV_CORE_SET_VER and
- * HV_CORE_GET_VER.
- */
-#define HV_GRP_SUN4V                   0x0000
-#define HV_GRP_CORE                    0x0001
-#define HV_GRP_INTR                    0x0002
-#define HV_GRP_SOFT_STATE              0x0003
-#define HV_GRP_PCI                     0x0100
-#define HV_GRP_LDOM                    0x0101
-#define HV_GRP_SVC_CHAN                        0x0102
-#define HV_GRP_NCS                     0x0103
-#define HV_GRP_NIAG_PERF               0x0200
-#define HV_GRP_FIRE_PERF               0x0201
-#define HV_GRP_DIAG                    0x0300
-
-#ifndef __ASSEMBLY__
-extern unsigned long sun4v_get_version(unsigned long group,
-                                      unsigned long *major,
-                                      unsigned long *minor);
-extern unsigned long sun4v_set_version(unsigned long group,
-                                      unsigned long major,
-                                      unsigned long minor,
-                                      unsigned long *actual_minor);
-
-extern int sun4v_hvapi_register(unsigned long group, unsigned long major,
-                               unsigned long *minor);
-extern void sun4v_hvapi_unregister(unsigned long group);
-extern int sun4v_hvapi_get(unsigned long group,
-                          unsigned long *major,
-                          unsigned long *minor);
-extern void sun4v_hvapi_init(void);
-#endif
-
-#endif /* !(_SPARC64_HYPERVISOR_H) */
+#include <asm-sparc/hypervisor.h>
index 1282676da1cdbe6975bd2f376d326d0f7d987a08..7125317a428d3495cca83290a826d2340ff29a84 100644 (file)
@@ -1,118 +1 @@
-/*
- * ide.h: Ultra/PCI specific IDE glue.
- *
- * Copyright (C) 1997  David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1998  Eddie C. Dost   (ecd@skynet.be)
- */
-
-#ifndef _SPARC64_IDE_H
-#define _SPARC64_IDE_H
-
-#ifdef __KERNEL__
-
-#include <asm/pgalloc.h>
-#include <asm/io.h>
-#include <asm/spitfire.h>
-#include <asm/cacheflush.h>
-#include <asm/page.h>
-
-#ifndef MAX_HWIFS
-# ifdef CONFIG_BLK_DEV_IDEPCI
-#define MAX_HWIFS      10
-# else
-#define MAX_HWIFS      2
-# endif
-#endif
-
-#define __ide_insl(data_reg, buffer, wcount) \
-       __ide_insw(data_reg, buffer, (wcount)<<1)
-#define __ide_outsl(data_reg, buffer, wcount) \
-       __ide_outsw(data_reg, buffer, (wcount)<<1)
-
-/* On sparc64, I/O ports and MMIO registers are accessed identically.  */
-#define __ide_mm_insw  __ide_insw
-#define __ide_mm_insl  __ide_insl
-#define __ide_mm_outsw __ide_outsw
-#define __ide_mm_outsl __ide_outsl
-
-static inline unsigned int inw_be(void __iomem *addr)
-{
-       unsigned int ret;
-
-       __asm__ __volatile__("lduha [%1] %2, %0"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-
-       return ret;
-}
-
-static inline void __ide_insw(void __iomem *port, void *dst, u32 count)
-{
-#ifdef DCACHE_ALIASING_POSSIBLE
-       unsigned long end = (unsigned long)dst + (count << 1);
-#endif
-       u16 *ps = dst;
-       u32 *pi;
-
-       if(((u64)ps) & 0x2) {
-               *ps++ = inw_be(port);
-               count--;
-       }
-       pi = (u32 *)ps;
-       while(count >= 2) {
-               u32 w;
-
-               w  = inw_be(port) << 16;
-               w |= inw_be(port);
-               *pi++ = w;
-               count -= 2;
-       }
-       ps = (u16 *)pi;
-       if(count)
-               *ps++ = inw_be(port);
-
-#ifdef DCACHE_ALIASING_POSSIBLE
-       __flush_dcache_range((unsigned long)dst, end);
-#endif
-}
-
-static inline void outw_be(unsigned short w, void __iomem *addr)
-{
-       __asm__ __volatile__("stha %0, [%1] %2"
-                            : /* no outputs */
-                            : "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-}
-
-static inline void __ide_outsw(void __iomem *port, void *src, u32 count)
-{
-#ifdef DCACHE_ALIASING_POSSIBLE
-       unsigned long end = (unsigned long)src + (count << 1);
-#endif
-       const u16 *ps = src;
-       const u32 *pi;
-
-       if(((u64)src) & 0x2) {
-               outw_be(*ps++, port);
-               count--;
-       }
-       pi = (const u32 *)ps;
-       while(count >= 2) {
-               u32 w;
-
-               w = *pi++;
-               outw_be((w >> 16), port);
-               outw_be(w, port);
-               count -= 2;
-       }
-       ps = (const u16 *)pi;
-       if(count)
-               outw_be(*ps, port);
-
-#ifdef DCACHE_ALIASING_POSSIBLE
-       __flush_dcache_range((unsigned long)src, end);
-#endif
-}
-
-#endif /* __KERNEL__ */
-
-#endif /* _SPARC64_IDE_H */
+#include <asm-sparc/ide.h>
index a363fa0a112a5e9c4c7e7bf4819c27d6900b2bbf..c22f9c30bc78efac79c69ba49647c95ba598716b 100644 (file)
@@ -1,25 +1 @@
-/*
- * idprom.h: Macros and defines for idprom routines
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef _SPARC64_IDPROM_H
-#define _SPARC64_IDPROM_H
-
-#include <linux/types.h>
-
-struct idprom {
-       u8              id_format;      /* Format identifier (always 0x01) */
-       u8              id_machtype;    /* Machine type */
-       u8              id_ethaddr[6];  /* Hardware ethernet address */
-       s32             id_date;        /* Date of manufacture */
-       u32             id_sernum:24;   /* Unique serial number */
-       u8              id_cksum;       /* Checksum - xor of the data bytes */
-       u8              reserved[16];
-};
-
-extern struct idprom *idprom;
-extern void idprom_init(void);
-
-#endif /* !(_SPARC_IDPROM_H) */
+#include <asm-sparc/idprom.h>
index 206077dedc2ad98a2dc8d52088d64c3f6c5ff2de..f7225015b3db0f489dd02e07bf540cfc5a88df5b 100644 (file)
@@ -1,15 +1 @@
-#ifndef _SPARC64_INTR_QUEUE_H
-#define _SPARC64_INTR_QUEUE_H
-
-/* Sun4v interrupt queue registers, accessed via ASI_QUEUE.  */
-
-#define INTRQ_CPU_MONDO_HEAD     0x3c0 /* CPU mondo head                 */
-#define INTRQ_CPU_MONDO_TAIL     0x3c8 /* CPU mondo tail                 */
-#define INTRQ_DEVICE_MONDO_HEAD          0x3d0 /* Device mondo head              */
-#define INTRQ_DEVICE_MONDO_TAIL          0x3d8 /* Device mondo tail              */
-#define INTRQ_RESUM_MONDO_HEAD   0x3e0 /* Resumable error mondo head     */
-#define INTRQ_RESUM_MONDO_TAIL   0x3e8 /* Resumable error mondo tail     */
-#define INTRQ_NONRESUM_MONDO_HEAD 0x3f0 /* Non-resumable error mondo head */
-#define INTRQ_NONRESUM_MONDO_TAIL 0x3f8 /* Non-resumable error mondo head */
-
-#endif /* !(_SPARC64_INTR_QUEUE_H) */
+#include <asm-sparc/intr_queue.h>
index 3158960f3eb56ec5d183cf4c8fd97921dff3ccb4..25ff258dfd33dd8e48a33c7ddd948ec06118b91c 100644 (file)
@@ -1,511 +1 @@
-#ifndef __SPARC64_IO_H
-#define __SPARC64_IO_H
-
-#include <linux/kernel.h>
-#include <linux/compiler.h>
-#include <linux/types.h>
-
-#include <asm/page.h>      /* IO address mapping routines need this */
-#include <asm/system.h>
-#include <asm/asi.h>
-
-/* PC crapola... */
-#define __SLOW_DOWN_IO do { } while (0)
-#define SLOW_DOWN_IO   do { } while (0)
-
-/* BIO layer definitions. */
-extern unsigned long kern_base, kern_size;
-#define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
-#define BIO_VMERGE_BOUNDARY    8192
-
-static inline u8 _inb(unsigned long addr)
-{
-       u8 ret;
-
-       __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_inb */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-
-       return ret;
-}
-
-static inline u16 _inw(unsigned long addr)
-{
-       u16 ret;
-
-       __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_inw */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-
-       return ret;
-}
-
-static inline u32 _inl(unsigned long addr)
-{
-       u32 ret;
-
-       __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_inl */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-
-       return ret;
-}
-
-static inline void _outb(u8 b, unsigned long addr)
-{
-       __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */"
-                            : /* no outputs */
-                            : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-}
-
-static inline void _outw(u16 w, unsigned long addr)
-{
-       __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */"
-                            : /* no outputs */
-                            : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-}
-
-static inline void _outl(u32 l, unsigned long addr)
-{
-       __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */"
-                            : /* no outputs */
-                            : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-}
-
-#define inb(__addr)            (_inb((unsigned long)(__addr)))
-#define inw(__addr)            (_inw((unsigned long)(__addr)))
-#define inl(__addr)            (_inl((unsigned long)(__addr)))
-#define outb(__b, __addr)      (_outb((u8)(__b), (unsigned long)(__addr)))
-#define outw(__w, __addr)      (_outw((u16)(__w), (unsigned long)(__addr)))
-#define outl(__l, __addr)      (_outl((u32)(__l), (unsigned long)(__addr)))
-
-#define inb_p(__addr)          inb(__addr)
-#define outb_p(__b, __addr)    outb(__b, __addr)
-#define inw_p(__addr)          inw(__addr)
-#define outw_p(__w, __addr)    outw(__w, __addr)
-#define inl_p(__addr)          inl(__addr)
-#define outl_p(__l, __addr)    outl(__l, __addr)
-
-extern void outsb(unsigned long, const void *, unsigned long);
-extern void outsw(unsigned long, const void *, unsigned long);
-extern void outsl(unsigned long, const void *, unsigned long);
-extern void insb(unsigned long, void *, unsigned long);
-extern void insw(unsigned long, void *, unsigned long);
-extern void insl(unsigned long, void *, unsigned long);
-
-static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count)
-{
-       insb((unsigned long __force)port, buf, count);
-}
-static inline void ioread16_rep(void __iomem *port, void *buf, unsigned long count)
-{
-       insw((unsigned long __force)port, buf, count);
-}
-
-static inline void ioread32_rep(void __iomem *port, void *buf, unsigned long count)
-{
-       insl((unsigned long __force)port, buf, count);
-}
-
-static inline void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count)
-{
-       outsb((unsigned long __force)port, buf, count);
-}
-
-static inline void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count)
-{
-       outsw((unsigned long __force)port, buf, count);
-}
-
-static inline void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count)
-{
-       outsl((unsigned long __force)port, buf, count);
-}
-
-/* Memory functions, same as I/O accesses on Ultra. */
-static inline u8 _readb(const volatile void __iomem *addr)
-{      u8 ret;
-
-       __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-       return ret;
-}
-
-static inline u16 _readw(const volatile void __iomem *addr)
-{      u16 ret;
-
-       __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-
-       return ret;
-}
-
-static inline u32 _readl(const volatile void __iomem *addr)
-{      u32 ret;
-
-       __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-
-       return ret;
-}
-
-static inline u64 _readq(const volatile void __iomem *addr)
-{      u64 ret;
-
-       __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_readq */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-
-       return ret;
-}
-
-static inline void _writeb(u8 b, volatile void __iomem *addr)
-{
-       __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */"
-                            : /* no outputs */
-                            : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-}
-
-static inline void _writew(u16 w, volatile void __iomem *addr)
-{
-       __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */"
-                            : /* no outputs */
-                            : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-}
-
-static inline void _writel(u32 l, volatile void __iomem *addr)
-{
-       __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */"
-                            : /* no outputs */
-                            : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-}
-
-static inline void _writeq(u64 q, volatile void __iomem *addr)
-{
-       __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_writeq */"
-                            : /* no outputs */
-                            : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)
-                            : "memory");
-}
-
-#define readb(__addr)          _readb(__addr)
-#define readw(__addr)          _readw(__addr)
-#define readl(__addr)          _readl(__addr)
-#define readq(__addr)          _readq(__addr)
-#define readb_relaxed(__addr)  _readb(__addr)
-#define readw_relaxed(__addr)  _readw(__addr)
-#define readl_relaxed(__addr)  _readl(__addr)
-#define readq_relaxed(__addr)  _readq(__addr)
-#define writeb(__b, __addr)    _writeb(__b, __addr)
-#define writew(__w, __addr)    _writew(__w, __addr)
-#define writel(__l, __addr)    _writel(__l, __addr)
-#define writeq(__q, __addr)    _writeq(__q, __addr)
-
-/* Now versions without byte-swapping. */
-static inline u8 _raw_readb(unsigned long addr)
-{
-       u8 ret;
-
-       __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-
-       return ret;
-}
-
-static inline u16 _raw_readw(unsigned long addr)
-{
-       u16 ret;
-
-       __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-
-       return ret;
-}
-
-static inline u32 _raw_readl(unsigned long addr)
-{
-       u32 ret;
-
-       __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-
-       return ret;
-}
-
-static inline u64 _raw_readq(unsigned long addr)
-{
-       u64 ret;
-
-       __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_raw_readq */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-
-       return ret;
-}
-
-static inline void _raw_writeb(u8 b, unsigned long addr)
-{
-       __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */"
-                            : /* no outputs */
-                            : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-}
-
-static inline void _raw_writew(u16 w, unsigned long addr)
-{
-       __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */"
-                            : /* no outputs */
-                            : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-}
-
-static inline void _raw_writel(u32 l, unsigned long addr)
-{
-       __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */"
-                            : /* no outputs */
-                            : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-}
-
-static inline void _raw_writeq(u64 q, unsigned long addr)
-{
-       __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */"
-                            : /* no outputs */
-                            : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-}
-
-#define __raw_readb(__addr)            (_raw_readb((unsigned long)(__addr)))
-#define __raw_readw(__addr)            (_raw_readw((unsigned long)(__addr)))
-#define __raw_readl(__addr)            (_raw_readl((unsigned long)(__addr)))
-#define __raw_readq(__addr)            (_raw_readq((unsigned long)(__addr)))
-#define __raw_writeb(__b, __addr)      (_raw_writeb((u8)(__b), (unsigned long)(__addr)))
-#define __raw_writew(__w, __addr)      (_raw_writew((u16)(__w), (unsigned long)(__addr)))
-#define __raw_writel(__l, __addr)      (_raw_writel((u32)(__l), (unsigned long)(__addr)))
-#define __raw_writeq(__q, __addr)      (_raw_writeq((u64)(__q), (unsigned long)(__addr)))
-
-/* Valid I/O Space regions are anywhere, because each PCI bus supported
- * can live in an arbitrary area of the physical address range.
- */
-#define IO_SPACE_LIMIT 0xffffffffffffffffUL
-
-/* Now, SBUS variants, only difference from PCI is that we do
- * not use little-endian ASIs.
- */
-static inline u8 _sbus_readb(const volatile void __iomem *addr)
-{
-       u8 ret;
-
-       __asm__ __volatile__("lduba\t[%1] %2, %0\t/* sbus_readb */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
-                            : "memory");
-
-       return ret;
-}
-
-static inline u16 _sbus_readw(const volatile void __iomem *addr)
-{
-       u16 ret;
-
-       __asm__ __volatile__("lduha\t[%1] %2, %0\t/* sbus_readw */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
-                            : "memory");
-
-       return ret;
-}
-
-static inline u32 _sbus_readl(const volatile void __iomem *addr)
-{
-       u32 ret;
-
-       __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* sbus_readl */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
-                            : "memory");
-
-       return ret;
-}
-
-static inline u64 _sbus_readq(const volatile void __iomem *addr)
-{
-       u64 ret;
-
-       __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* sbus_readq */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
-                            : "memory");
-
-       return ret;
-}
-
-static inline void _sbus_writeb(u8 b, volatile void __iomem *addr)
-{
-       __asm__ __volatile__("stba\t%r0, [%1] %2\t/* sbus_writeb */"
-                            : /* no outputs */
-                            : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
-                            : "memory");
-}
-
-static inline void _sbus_writew(u16 w, volatile void __iomem *addr)
-{
-       __asm__ __volatile__("stha\t%r0, [%1] %2\t/* sbus_writew */"
-                            : /* no outputs */
-                            : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
-                            : "memory");
-}
-
-static inline void _sbus_writel(u32 l, volatile void __iomem *addr)
-{
-       __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* sbus_writel */"
-                            : /* no outputs */
-                            : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
-                            : "memory");
-}
-
-static inline void _sbus_writeq(u64 l, volatile void __iomem *addr)
-{
-       __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* sbus_writeq */"
-                            : /* no outputs */
-                            : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)
-                            : "memory");
-}
-
-#define sbus_readb(__addr)             _sbus_readb(__addr)
-#define sbus_readw(__addr)             _sbus_readw(__addr)
-#define sbus_readl(__addr)             _sbus_readl(__addr)
-#define sbus_readq(__addr)             _sbus_readq(__addr)
-#define sbus_writeb(__b, __addr)       _sbus_writeb(__b, __addr)
-#define sbus_writew(__w, __addr)       _sbus_writew(__w, __addr)
-#define sbus_writel(__l, __addr)       _sbus_writel(__l, __addr)
-#define sbus_writeq(__l, __addr)       _sbus_writeq(__l, __addr)
-
-static inline void _sbus_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
-{
-       while(n--) {
-               sbus_writeb(c, dst);
-               dst++;
-       }
-}
-
-#define sbus_memset_io(d,c,sz) _sbus_memset_io(d,c,sz)
-
-static inline void
-_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n)
-{
-       volatile void __iomem *d = dst;
-
-       while (n--) {
-               writeb(c, d);
-               d++;
-       }
-}
-
-#define memset_io(d,c,sz)      _memset_io(d,c,sz)
-
-static inline void
-_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n)
-{
-       char *d = dst;
-
-       while (n--) {
-               char tmp = readb(src);
-               *d++ = tmp;
-               src++;
-       }
-}
-
-#define memcpy_fromio(d,s,sz)  _memcpy_fromio(d,s,sz)
-
-static inline void 
-_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
-{
-       const char *s = src;
-       volatile void __iomem *d = dst;
-
-       while (n--) {
-               char tmp = *s++;
-               writeb(tmp, d);
-               d++;
-       }
-}
-
-#define memcpy_toio(d,s,sz)    _memcpy_toio(d,s,sz)
-
-#define mmiowb()
-
-#ifdef __KERNEL__
-
-/* On sparc64 we have the whole physical IO address space accessible
- * using physically addressed loads and stores, so this does nothing.
- */
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
-{
-       return (void __iomem *)offset;
-}
-
-#define ioremap_nocache(X,Y)           ioremap((X),(Y))
-
-static inline void iounmap(volatile void __iomem *addr)
-{
-}
-
-#define ioread8(X)                     readb(X)
-#define ioread16(X)                    readw(X)
-#define ioread32(X)                    readl(X)
-#define iowrite8(val,X)                        writeb(val,X)
-#define iowrite16(val,X)               writew(val,X)
-#define iowrite32(val,X)               writel(val,X)
-
-/* Create a virtual mapping cookie for an IO port range */
-extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
-extern void ioport_unmap(void __iomem *);
-
-/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
-struct pci_dev;
-extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
-extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
-
-/* Similarly for SBUS. */
-#define sbus_ioremap(__res, __offset, __size, __name) \
-({     unsigned long __ret; \
-       __ret  = (__res)->start + (((__res)->flags & 0x1ffUL) << 32UL); \
-       __ret += (unsigned long) (__offset); \
-       if (! request_region((__ret), (__size), (__name))) \
-               __ret = 0UL; \
-       (void __iomem *) __ret; \
-})
-
-#define sbus_iounmap(__addr, __size)   \
-       release_region((unsigned long)(__addr), (__size))
-
-/*
- * Convert a physical pointer to a virtual kernel pointer for /dev/mem
- * access
- */
-#define xlate_dev_mem_ptr(p)   __va(p)
-
-/*
- * Convert a virtual cached pointer to an uncached pointer
- */
-#define xlate_dev_kmem_ptr(p)  p
-
-#endif
-
-#endif /* !(__SPARC64_IO_H) */
+#include <asm-sparc/io.h>
index d634c21b47247b135b2e6de5568b5e6b22da262e..18fc5623ff51e091e727d92fd08dba27376eb074 100644 (file)
@@ -1,67 +1 @@
-#ifndef _SPARC64_IOCTL_H
-#define _SPARC64_IOCTL_H
-
-/*
- * Our DIR and SIZE overlap in order to simulteneously provide
- * a non-zero _IOC_NONE (for binary compatibility) and
- * 14 bits of size as on i386. Here's the layout:
- *
- *   0xE0000000   DIR
- *   0x80000000     DIR = WRITE
- *   0x40000000     DIR = READ
- *   0x20000000     DIR = NONE
- *   0x3FFF0000   SIZE (overlaps NONE bit)
- *   0x0000FF00   TYPE
- *   0x000000FF   NR (CMD)
- */
-
-#define _IOC_NRBITS      8
-#define _IOC_TYPEBITS    8
-#define _IOC_SIZEBITS   13     /* Actually 14, see below. */
-#define _IOC_DIRBITS     3
-
-#define _IOC_NRMASK      ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK    ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK    ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_XSIZEMASK   ((1 << (_IOC_SIZEBITS+1))-1)
-#define _IOC_DIRMASK     ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT     0
-#define _IOC_TYPESHIFT   (_IOC_NRSHIFT + _IOC_NRBITS)
-#define _IOC_SIZESHIFT   (_IOC_TYPESHIFT + _IOC_TYPEBITS)
-#define _IOC_DIRSHIFT    (_IOC_SIZESHIFT + _IOC_SIZEBITS)
-
-#define _IOC_NONE        1U
-#define _IOC_READ        2U
-#define _IOC_WRITE       4U
-
-#define _IOC(dir,type,nr,size) \
-        (((dir)  << _IOC_DIRSHIFT) | \
-         ((type) << _IOC_TYPESHIFT) | \
-         ((nr)   << _IOC_NRSHIFT) | \
-         ((size) << _IOC_SIZESHIFT))
-
-#define _IO(type,nr)        _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)  _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)  _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* Used to decode ioctl numbers in drivers despite the leading underscore... */
-#define _IOC_DIR(nr)    \
- ( (((((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) & (_IOC_WRITE|_IOC_READ)) != 0)?   \
-                            (((nr) >> _IOC_DIRSHIFT) & (_IOC_WRITE|_IOC_READ)):  \
-                            (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) )
-#define _IOC_TYPE(nr)       (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)         (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)   \
- ((((((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) & (_IOC_WRITE|_IOC_READ)) == 0)?    \
-                         0: (((nr) >> _IOC_SIZESHIFT) & _IOC_XSIZEMASK))
-
-/* ...and for the PCMCIA and sound. */
-#define IOC_IN          (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT         (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT       ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK    (_IOC_XSIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT   (_IOC_SIZESHIFT)
-
-#endif /* !(_SPARC64_IOCTL_H) */
+#include <asm-sparc/ioctl.h>
index 94d1b75e512b1d94fa199b715d59a7968adad04a..dcd5540ec10314a36ff9fdc49f972101da6d15e4 100644 (file)
@@ -1,136 +1 @@
-#ifndef _ASM_SPARC64_IOCTLS_H
-#define _ASM_SPARC64_IOCTLS_H
-
-#include <asm/ioctl.h>
-
-/* Big T */
-#define TCGETA         _IOR('T', 1, struct termio)
-#define TCSETA         _IOW('T', 2, struct termio)
-#define TCSETAW                _IOW('T', 3, struct termio)
-#define TCSETAF                _IOW('T', 4, struct termio)
-#define TCSBRK         _IO('T', 5)
-#define TCXONC         _IO('T', 6)
-#define TCFLSH         _IO('T', 7)
-#define TCGETS         _IOR('T', 8, struct termios)
-#define TCSETS         _IOW('T', 9, struct termios)
-#define TCSETSW                _IOW('T', 10, struct termios)
-#define TCSETSF                _IOW('T', 11, struct termios)
-#define TCGETS2                _IOR('T', 12, struct termios2)
-#define TCSETS2                _IOW('T', 13, struct termios2)
-#define TCSETSW2       _IOW('T', 14, struct termios2)
-#define TCSETSF2       _IOW('T', 15, struct termios2)
-
-/* Note that all the ioctls that are not available in Linux have a 
- * double underscore on the front to: a) avoid some programs to
- * think we support some ioctls under Linux (autoconfiguration stuff)
- */
-/* Little t */
-#define TIOCGETD       _IOR('t', 0, int)
-#define TIOCSETD       _IOW('t', 1, int)
-#define __TIOCHPCL        _IO('t', 2) /* SunOS Specific */
-#define __TIOCMODG        _IOR('t', 3, int) /* SunOS Specific */
-#define __TIOCMODS        _IOW('t', 4, int) /* SunOS Specific */
-#define __TIOCGETP        _IOR('t', 8, struct sgttyb) /* SunOS Specific */
-#define __TIOCSETP        _IOW('t', 9, struct sgttyb) /* SunOS Specific */
-#define __TIOCSETN        _IOW('t', 10, struct sgttyb) /* SunOS Specific */
-#define TIOCEXCL       _IO('t', 13)
-#define TIOCNXCL       _IO('t', 14)
-#define __TIOCFLUSH       _IOW('t', 16, int) /* SunOS Specific */
-#define __TIOCSETC        _IOW('t', 17, struct tchars) /* SunOS Specific */
-#define __TIOCGETC        _IOR('t', 18, struct tchars) /* SunOS Specific */
-#define __TIOCTCNTL       _IOW('t', 32, int) /* SunOS Specific */
-#define __TIOCSIGNAL      _IOW('t', 33, int) /* SunOS Specific */
-#define __TIOCSETX        _IOW('t', 34, int) /* SunOS Specific */
-#define __TIOCGETX        _IOR('t', 35, int) /* SunOS Specific */
-#define TIOCCONS       _IO('t', 36)
-#define TIOCGSOFTCAR   _IOR('t', 100, int)
-#define TIOCSSOFTCAR   _IOW('t', 101, int)
-#define __TIOCUCNTL       _IOW('t', 102, int) /* SunOS Specific */
-#define TIOCSWINSZ     _IOW('t', 103, struct winsize)
-#define TIOCGWINSZ     _IOR('t', 104, struct winsize)
-#define __TIOCREMOTE      _IOW('t', 105, int) /* SunOS Specific */
-#define TIOCMGET       _IOR('t', 106, int)
-#define TIOCMBIC       _IOW('t', 107, int)
-#define TIOCMBIS       _IOW('t', 108, int)
-#define TIOCMSET       _IOW('t', 109, int)
-#define TIOCSTART       _IO('t', 110)
-#define TIOCSTOP        _IO('t', 111)
-#define TIOCPKT                _IOW('t', 112, int)
-#define TIOCNOTTY      _IO('t', 113)
-#define TIOCSTI                _IOW('t', 114, char)
-#define TIOCOUTQ       _IOR('t', 115, int)
-#define __TIOCGLTC        _IOR('t', 116, struct ltchars) /* SunOS Specific */
-#define __TIOCSLTC        _IOW('t', 117, struct ltchars) /* SunOS Specific */
-/* 118 is the non-posix setpgrp tty ioctl */
-/* 119 is the non-posix getpgrp tty ioctl */
-#define __TIOCCDTR        _IO('t', 120) /* SunOS Specific */
-#define __TIOCSDTR        _IO('t', 121) /* SunOS Specific */
-#define TIOCCBRK        _IO('t', 122)
-#define TIOCSBRK        _IO('t', 123)
-#define __TIOCLGET        _IOW('t', 124, int) /* SunOS Specific */
-#define __TIOCLSET        _IOW('t', 125, int) /* SunOS Specific */
-#define __TIOCLBIC        _IOW('t', 126, int) /* SunOS Specific */
-#define __TIOCLBIS        _IOW('t', 127, int) /* SunOS Specific */
-#define __TIOCISPACE      _IOR('t', 128, int) /* SunOS Specific */
-#define __TIOCISIZE       _IOR('t', 129, int) /* SunOS Specific */
-#define TIOCSPGRP      _IOW('t', 130, int)
-#define TIOCGPGRP      _IOR('t', 131, int)
-#define TIOCSCTTY      _IO('t', 132)
-#define TIOCGSID       _IOR('t', 133, int)
-/* Get minor device of a pty master's FD -- Solaris equiv is ISPTM */
-#define TIOCGPTN       _IOR('t', 134, unsigned int) /* Get Pty Number */
-#define TIOCSPTLCK     _IOW('t', 135, int) /* Lock/unlock PTY */
-
-/* Little f */
-#define FIOCLEX                _IO('f', 1)
-#define FIONCLEX       _IO('f', 2)
-#define FIOASYNC       _IOW('f', 125, int)
-#define FIONBIO                _IOW('f', 126, int)
-#define FIONREAD       _IOR('f', 127, int)
-#define TIOCINQ                FIONREAD
-#define FIOQSIZE       _IOR('f', 128, loff_t)
-
-/* SCARY Rutgers local SunOS kernel hackery, perhaps I will support it
- * someday.  This is completely bogus, I know...
- */
-#define __TCGETSTAT       _IO('T', 200) /* Rutgers specific */
-#define __TCSETSTAT       _IO('T', 201) /* Rutgers specific */
-
-/* Linux specific, no SunOS equivalent. */
-#define TIOCLINUX      0x541C
-#define TIOCGSERIAL    0x541E
-#define TIOCSSERIAL    0x541F
-#define TCSBRKP                0x5425
-#define TIOCSERCONFIG  0x5453
-#define TIOCSERGWILD   0x5454
-#define TIOCSERSWILD   0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR   0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-#define TIOCMIWAIT     0x545C /* Wait for change on serial input line(s) */
-#define TIOCGICOUNT    0x545D /* Read serial port inline interrupt counts */
-
-/* Kernel definitions */
-#ifdef __KERNEL__
-#define TIOCGETC __TIOCGETC
-#define TIOCGETP __TIOCGETP
-#define TIOCGLTC __TIOCGLTC
-#define TIOCSLTC __TIOCSLTC
-#define TIOCSETP __TIOCSETP
-#define TIOCSETN __TIOCSETN
-#define TIOCSETC __TIOCSETC
-#endif
-
-/* Used for packet mode */
-#define TIOCPKT_DATA            0
-#define TIOCPKT_FLUSHREAD       1
-#define TIOCPKT_FLUSHWRITE      2
-#define TIOCPKT_STOP            4
-#define TIOCPKT_START           8
-#define TIOCPKT_NOSTOP         16
-#define TIOCPKT_DOSTOP         32
-
-#endif /* !(_ASM_SPARC64_IOCTLS_H) */
+#include <asm-sparc/ioctls.h>
index d7b9afcba08bf433c87d8569f0169d1eaec68343..76252bb85e979efb24f3624335f2e290a82e70ad 100644 (file)
@@ -1,62 +1 @@
-/* iommu.h: Definitions for the sun5 IOMMU.
- *
- * Copyright (C) 1996, 1999, 2007 David S. Miller (davem@davemloft.net)
- */
-#ifndef _SPARC64_IOMMU_H
-#define _SPARC64_IOMMU_H
-
-/* The format of an iopte in the page tables. */
-#define IOPTE_VALID   0x8000000000000000UL
-#define IOPTE_64K     0x2000000000000000UL
-#define IOPTE_STBUF   0x1000000000000000UL
-#define IOPTE_INTRA   0x0800000000000000UL
-#define IOPTE_CONTEXT 0x07ff800000000000UL
-#define IOPTE_PAGE    0x00007fffffffe000UL
-#define IOPTE_CACHE   0x0000000000000010UL
-#define IOPTE_WRITE   0x0000000000000002UL
-
-#define IOMMU_NUM_CTXS 4096
-
-struct iommu_arena {
-       unsigned long   *map;
-       unsigned int    hint;
-       unsigned int    limit;
-};
-
-struct iommu {
-       spinlock_t              lock;
-       struct iommu_arena      arena;
-       void                    (*flush_all)(struct iommu *);
-       iopte_t                 *page_table;
-       u32                     page_table_map_base;
-       unsigned long           iommu_control;
-       unsigned long           iommu_tsbbase;
-       unsigned long           iommu_flush;
-       unsigned long           iommu_flushinv;
-       unsigned long           iommu_tags;
-       unsigned long           iommu_ctxflush;
-       unsigned long           write_complete_reg;
-       unsigned long           dummy_page;
-       unsigned long           dummy_page_pa;
-       unsigned long           ctx_lowest_free;
-       DECLARE_BITMAP(ctx_bitmap, IOMMU_NUM_CTXS);
-       u32                     dma_addr_mask;
-};
-
-struct strbuf {
-       int                     strbuf_enabled;
-       unsigned long           strbuf_control;
-       unsigned long           strbuf_pflush;
-       unsigned long           strbuf_fsync;
-       unsigned long           strbuf_ctxflush;
-       unsigned long           strbuf_ctxmatch_base;
-       unsigned long           strbuf_flushflag_pa;
-       volatile unsigned long *strbuf_flushflag;
-       volatile unsigned long  __flushflag_buf[(64+(64-1)) / sizeof(long)];
-};
-
-extern int iommu_table_init(struct iommu *iommu, int tsbsize,
-                           u32 dma_offset, u32 dma_addr_mask,
-                           int numa_node);
-
-#endif /* !(_SPARC64_IOMMU_H) */
+#include <asm-sparc/iommu.h>
index 9c5bf1bc423f02f6018ec228410318db1bd250b2..41dfaf1149b5bd88ca56bdfead1c105be1f69405 100644 (file)
@@ -1,28 +1 @@
-#ifndef _SPARC64_IPCBUF_H
-#define _SPARC64_IPCBUF_H
-
-/* 
- * The ipc64_perm structure for sparc64 architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 32-bit seq
- * - 2 miscellaneous 64-bit values
- */
-
-struct ipc64_perm
-{
-       __kernel_key_t  key;
-       __kernel_uid_t  uid;
-       __kernel_gid_t  gid;
-       __kernel_uid_t  cuid;
-       __kernel_gid_t  cgid;
-       __kernel_mode_t mode; 
-       unsigned short  __pad1;
-       unsigned short  seq;
-       unsigned long   __unused1;
-       unsigned long   __unused2;
-};
-
-#endif /* _SPARC64_IPCBUF_H */
+#include <asm-sparc/ipcbuf.h>
index 0bb9bf531745e8caf587135f3cf3063f31d24a4c..b2102e65947cd6fcfe3d6e10799843e2f2a4540e 100644 (file)
@@ -1,93 +1 @@
-/* irq.h: IRQ registers on the 64-bit Sparc.
- *
- * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
- * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
- */
-
-#ifndef _SPARC64_IRQ_H
-#define _SPARC64_IRQ_H
-
-#include <linux/linkage.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <asm/pil.h>
-#include <asm/ptrace.h>
-
-/* IMAP/ICLR register defines */
-#define IMAP_VALID             0x80000000UL    /* IRQ Enabled          */
-#define IMAP_TID_UPA           0x7c000000UL    /* UPA TargetID         */
-#define IMAP_TID_JBUS          0x7c000000UL    /* JBUS TargetID        */
-#define IMAP_TID_SHIFT         26
-#define IMAP_AID_SAFARI                0x7c000000UL    /* Safari AgentID       */
-#define IMAP_AID_SHIFT         26
-#define IMAP_NID_SAFARI                0x03e00000UL    /* Safari NodeID        */
-#define IMAP_NID_SHIFT         21
-#define IMAP_IGN               0x000007c0UL    /* IRQ Group Number     */
-#define IMAP_INO               0x0000003fUL    /* IRQ Number           */
-#define IMAP_INR               0x000007ffUL    /* Full interrupt number*/
-
-#define ICLR_IDLE              0x00000000UL    /* Idle state           */
-#define ICLR_TRANSMIT          0x00000001UL    /* Transmit state       */
-#define ICLR_PENDING           0x00000003UL    /* Pending state        */
-
-/* The largest number of unique interrupt sources we support.
- * If this needs to ever be larger than 255, you need to change
- * the type of ino_bucket->virt_irq as appropriate.
- *
- * ino_bucket->virt_irq allocation is made during {sun4v_,}build_irq().
- */
-#define NR_IRQS    255
-
-extern void irq_install_pre_handler(int virt_irq,
-                                   void (*func)(unsigned int, void *, void *),
-                                   void *arg1, void *arg2);
-#define irq_canonicalize(irq)  (irq)
-extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap);
-extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino);
-extern unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino);
-extern unsigned int sun4v_build_msi(u32 devhandle, unsigned int *virt_irq_p,
-                                   unsigned int msi_devino_start,
-                                   unsigned int msi_devino_end);
-extern void sun4v_destroy_msi(unsigned int virt_irq);
-extern unsigned int sun4u_build_msi(u32 portid, unsigned int *virt_irq_p,
-                                   unsigned int msi_devino_start,
-                                   unsigned int msi_devino_end,
-                                   unsigned long imap_base,
-                                   unsigned long iclr_base);
-extern void sun4u_destroy_msi(unsigned int virt_irq);
-extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);
-
-extern unsigned char virt_irq_alloc(unsigned int dev_handle,
-                                   unsigned int dev_ino);
-#ifdef CONFIG_PCI_MSI
-extern void virt_irq_free(unsigned int virt_irq);
-#endif
-
-extern void __init init_IRQ(void);
-extern void fixup_irqs(void);
-
-static inline void set_softint(unsigned long bits)
-{
-       __asm__ __volatile__("wr        %0, 0x0, %%set_softint"
-                            : /* No outputs */
-                            : "r" (bits));
-}
-
-static inline void clear_softint(unsigned long bits)
-{
-       __asm__ __volatile__("wr        %0, 0x0, %%clear_softint"
-                            : /* No outputs */
-                            : "r" (bits));
-}
-
-static inline unsigned long get_softint(void)
-{
-       unsigned long retval;
-
-       __asm__ __volatile__("rd        %%softint, %0"
-                            : "=r" (retval));
-       return retval;
-}
-
-#endif
+#include <asm-sparc/irq.h>
index 3dd9c0b702704abfe23c0b8085f0fd84dcd3f5d5..1e2b8a1e745ae5748dd42eb63a38d73f75368a04 100644 (file)
@@ -1 +1 @@
-#include <asm-generic/irq_regs.h>
+#include <asm-sparc/irq_regs.h>
index 024fc54d068205befa262d80582d6dc591f34fe6..27b091fc3fa09582b1cb189e796f65152c422ffd 100644 (file)
@@ -1,89 +1 @@
-/*
- * include/asm-sparc64/irqflags.h
- *
- * IRQ flags handling
- *
- * This file gets included from lowlevel asm headers too, to provide
- * wrapped versions of the local_irq_*() APIs, based on the
- * raw_local_irq_*() functions from the lowlevel headers.
- */
-#ifndef _ASM_IRQFLAGS_H
-#define _ASM_IRQFLAGS_H
-
-#ifndef __ASSEMBLY__
-
-static inline unsigned long __raw_local_save_flags(void)
-{
-       unsigned long flags;
-
-       __asm__ __volatile__(
-               "rdpr   %%pil, %0"
-               : "=r" (flags)
-       );
-
-       return flags;
-}
-
-#define raw_local_save_flags(flags) \
-               do { (flags) = __raw_local_save_flags(); } while (0)
-
-static inline void raw_local_irq_restore(unsigned long flags)
-{
-       __asm__ __volatile__(
-               "wrpr   %0, %%pil"
-               : /* no output */
-               : "r" (flags)
-               : "memory"
-       );
-}
-
-static inline void raw_local_irq_disable(void)
-{
-       __asm__ __volatile__(
-               "wrpr   15, %%pil"
-               : /* no outputs */
-               : /* no inputs */
-               : "memory"
-       );
-}
-
-static inline void raw_local_irq_enable(void)
-{
-       __asm__ __volatile__(
-               "wrpr   0, %%pil"
-               : /* no outputs */
-               : /* no inputs */
-               : "memory"
-       );
-}
-
-static inline int raw_irqs_disabled_flags(unsigned long flags)
-{
-       return (flags > 0);
-}
-
-static inline int raw_irqs_disabled(void)
-{
-       unsigned long flags = __raw_local_save_flags();
-
-       return raw_irqs_disabled_flags(flags);
-}
-
-/*
- * For spinlocks, etc:
- */
-static inline unsigned long __raw_local_irq_save(void)
-{
-       unsigned long flags = __raw_local_save_flags();
-
-       raw_local_irq_disable();
-
-       return flags;
-}
-
-#define raw_local_irq_save(flags) \
-               do { (flags) = __raw_local_irq_save(); } while (0)
-
-#endif /* (__ASSEMBLY__) */
-
-#endif /* !(_ASM_IRQFLAGS_H) */
+#include <asm-sparc/irqflags.h>
index f905b773235a2f977db3383559629d4fbd3e4fda..78cfd5d2749b62a37a5d0628bfe5b7c27483d2ec 100644 (file)
@@ -1,19 +1 @@
-#ifndef _SPARC64_KDEBUG_H
-#define _SPARC64_KDEBUG_H
-
-struct pt_regs;
-
-extern void bad_trap(struct pt_regs *, long);
-
-/* Grossly misnamed. */
-enum die_val {
-       DIE_OOPS = 1,
-       DIE_DEBUG,      /* ta 0x70 */
-       DIE_DEBUG_2,    /* ta 0x71 */
-       DIE_DIE,
-       DIE_TRAP,
-       DIE_TRAP_TL1,
-       DIE_CALL,
-};
-
-#endif
+#include <asm-sparc/kdebug.h>
index 34c1d3d9a3b0cb30ae0d19502d88a6ee82069977..276530cf5395e5a4d5e46e4c7d7cdd98d135e5e7 100644 (file)
@@ -1,25 +1 @@
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-/* Dummy header just to define km_type.  None of this
- * is actually used on sparc64.  -DaveM
- */
-
-enum km_type {
-       KM_BOUNCE_READ,
-       KM_SKB_SUNRPC_DATA,
-       KM_SKB_DATA_SOFTIRQ,
-       KM_USER0,
-       KM_USER1,
-       KM_BIO_SRC_IRQ,
-       KM_BIO_DST_IRQ,
-       KM_PTE0,
-       KM_PTE1,
-       KM_IRQ0,
-       KM_IRQ1,
-       KM_SOFTIRQ0,
-       KM_SOFTIRQ1,
-       KM_TYPE_NR
-};
-
-#endif
+#include <asm-sparc/kmap_types.h>
index 5879d71afdaa799b2bd18f038ee390e680390c4c..c55e43e4d2a4adcfd1fc1140a5e2aab5c75e1ca3 100644 (file)
@@ -1,49 +1 @@
-#ifndef _SPARC64_KPROBES_H
-#define _SPARC64_KPROBES_H
-
-#include <linux/types.h>
-#include <linux/percpu.h>
-
-typedef u32 kprobe_opcode_t;
-
-#define BREAKPOINT_INSTRUCTION   0x91d02070 /* ta 0x70 */
-#define BREAKPOINT_INSTRUCTION_2 0x91d02071 /* ta 0x71 */
-#define MAX_INSN_SIZE 2
-
-#define kretprobe_blacklist_size 0
-
-#define arch_remove_kprobe(p)  do {} while (0)
-
-#define flush_insn_slot(p)             \
-do {   flushi(&(p)->ainsn.insn[0]);    \
-       flushi(&(p)->ainsn.insn[1]);    \
-} while (0)
-
-void kretprobe_trampoline(void);
-
-/* Architecture specific copy of original instruction*/
-struct arch_specific_insn {
-       /* copy of the original instruction */
-       kprobe_opcode_t insn[MAX_INSN_SIZE];
-};
-
-struct prev_kprobe {
-       struct kprobe *kp;
-       unsigned long status;
-       unsigned long orig_tnpc;
-       unsigned long orig_tstate_pil;
-};
-
-/* per-cpu kprobe control block */
-struct kprobe_ctlblk {
-       unsigned long kprobe_status;
-       unsigned long kprobe_orig_tnpc;
-       unsigned long kprobe_orig_tstate_pil;
-       struct pt_regs jprobe_saved_regs;
-       struct prev_kprobe prev_kprobe;
-};
-
-extern int kprobe_exceptions_notify(struct notifier_block *self,
-                                   unsigned long val, void *data);
-extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
-#endif /* _SPARC64_KPROBES_H */
+#include <asm-sparc/kprobes.h>
index 380537a77bf921c903bfd02ade55d3e048240d81..53564ad86b15aabd8c029628b94232aa7b3f0bc9 100644 (file)
@@ -1,6 +1 @@
-#ifndef __LINUX_KVM_SPARC64_H
-#define __LINUX_KVM_SPARC64_H
-
-/* sparc64 does not support KVM */
-
-#endif
+#include <asm-sparc/kvm.h>
index bdb524a7b814171b98a42c15ad140bbf45b76d28..40f3f231c4575b3c3fcc2f20b45417dcb35a4a9d 100644 (file)
@@ -1,138 +1 @@
-#ifndef _SPARC64_LDC_H
-#define _SPARC64_LDC_H
-
-#include <asm/hypervisor.h>
-
-extern int ldom_domaining_enabled;
-extern void ldom_set_var(const char *var, const char *value);
-extern void ldom_reboot(const char *boot_command);
-extern void ldom_power_off(void);
-
-/* The event handler will be evoked when link state changes
- * or data becomes available on the receive side.
- *
- * For non-RAW links, if the LDC_EVENT_RESET event arrives the
- * driver should reset all of it's internal state and reinvoke
- * ldc_connect() to try and bring the link up again.
- *
- * For RAW links, ldc_connect() is not used.  Instead the driver
- * just waits for the LDC_EVENT_UP event.
- */
-struct ldc_channel_config {
-       void (*event)(void *arg, int event);
-
-       u32                     mtu;
-       unsigned int            rx_irq;
-       unsigned int            tx_irq;
-       u8                      mode;
-#define LDC_MODE_RAW           0x00
-#define LDC_MODE_UNRELIABLE    0x01
-#define LDC_MODE_RESERVED      0x02
-#define LDC_MODE_STREAM                0x03
-
-       u8                      debug;
-#define LDC_DEBUG_HS           0x01
-#define LDC_DEBUG_STATE                0x02
-#define LDC_DEBUG_RX           0x04
-#define LDC_DEBUG_TX           0x08
-#define LDC_DEBUG_DATA         0x10
-};
-
-#define LDC_EVENT_RESET                0x01
-#define LDC_EVENT_UP           0x02
-#define LDC_EVENT_DATA_READY   0x04
-
-#define LDC_STATE_INVALID      0x00
-#define LDC_STATE_INIT         0x01
-#define LDC_STATE_BOUND                0x02
-#define LDC_STATE_READY                0x03
-#define LDC_STATE_CONNECTED    0x04
-
-struct ldc_channel;
-
-/* Allocate state for a channel.  */
-extern struct ldc_channel *ldc_alloc(unsigned long id,
-                                    const struct ldc_channel_config *cfgp,
-                                    void *event_arg);
-
-/* Shut down and free state for a channel.  */
-extern void ldc_free(struct ldc_channel *lp);
-
-/* Register TX and RX queues of the link with the hypervisor.  */
-extern int ldc_bind(struct ldc_channel *lp, const char *name);
-
-/* For non-RAW protocols we need to complete a handshake before
- * communication can proceed.  ldc_connect() does that, if the
- * handshake completes successfully, an LDC_EVENT_UP event will
- * be sent up to the driver.
- */
-extern int ldc_connect(struct ldc_channel *lp);
-extern int ldc_disconnect(struct ldc_channel *lp);
-
-extern int ldc_state(struct ldc_channel *lp);
-
-/* Read and write operations.  Only valid when the link is up.  */
-extern int ldc_write(struct ldc_channel *lp, const void *buf,
-                    unsigned int size);
-extern int ldc_read(struct ldc_channel *lp, void *buf, unsigned int size);
-
-#define LDC_MAP_SHADOW 0x01
-#define LDC_MAP_DIRECT 0x02
-#define LDC_MAP_IO     0x04
-#define LDC_MAP_R      0x08
-#define LDC_MAP_W      0x10
-#define LDC_MAP_X      0x20
-#define LDC_MAP_RW     (LDC_MAP_R | LDC_MAP_W)
-#define LDC_MAP_RWX    (LDC_MAP_R | LDC_MAP_W | LDC_MAP_X)
-#define LDC_MAP_ALL    0x03f
-
-struct ldc_trans_cookie {
-       u64                     cookie_addr;
-       u64                     cookie_size;
-};
-
-struct scatterlist;
-extern int ldc_map_sg(struct ldc_channel *lp,
-                     struct scatterlist *sg, int num_sg,
-                     struct ldc_trans_cookie *cookies, int ncookies,
-                     unsigned int map_perm);
-
-extern int ldc_map_single(struct ldc_channel *lp,
-                         void *buf, unsigned int len,
-                         struct ldc_trans_cookie *cookies, int ncookies,
-                         unsigned int map_perm);
-
-extern void ldc_unmap(struct ldc_channel *lp, struct ldc_trans_cookie *cookies,
-                     int ncookies);
-
-extern int ldc_copy(struct ldc_channel *lp, int copy_dir,
-                   void *buf, unsigned int len, unsigned long offset,
-                   struct ldc_trans_cookie *cookies, int ncookies);
-
-static inline int ldc_get_dring_entry(struct ldc_channel *lp,
-                                     void *buf, unsigned int len,
-                                     unsigned long offset,
-                                     struct ldc_trans_cookie *cookies,
-                                     int ncookies)
-{
-       return ldc_copy(lp, LDC_COPY_IN, buf, len, offset, cookies, ncookies);
-}
-
-static inline int ldc_put_dring_entry(struct ldc_channel *lp,
-                                     void *buf, unsigned int len,
-                                     unsigned long offset,
-                                     struct ldc_trans_cookie *cookies,
-                                     int ncookies)
-{
-       return ldc_copy(lp, LDC_COPY_OUT, buf, len, offset, cookies, ncookies);
-}
-
-extern void *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len,
-                                struct ldc_trans_cookie *cookies,
-                                int *ncookies, unsigned int map_perm);
-
-extern void ldc_free_exp_dring(struct ldc_channel *lp, void *buf,
-                              unsigned int len,
-                              struct ldc_trans_cookie *cookies, int ncookies);
-
-#endif /* _SPARC64_LDC_H */
+#include <asm-sparc/ldc.h>
index 291c2d01c44f29dad20f7623783b8bad362eaddf..3ea4fd13f193ce82e837fd0f138112e1cc4c2bb6 100644 (file)
@@ -1,6 +1 @@
-#ifndef __ASM_LINKAGE_H
-#define __ASM_LINKAGE_H
-
-/* Nothing to see here... */
-
-#endif
+#include <asm-sparc/linkage.h>
index 6a352cbcf52069e4a33fa91b0d44affebe631ede..3d04981701e2ebfd92b07d23e86ad5dc6a24242f 100644 (file)
@@ -1,10 +1 @@
-#ifndef _SPARC64_LMB_H
-#define _SPARC64_LMB_H
-
-#include <asm/oplib.h>
-
-#define LMB_DBG(fmt...) prom_printf(fmt)
-
-#define LMB_REAL_LIMIT 0
-
-#endif /* !(_SPARC64_LMB_H) */
+#include <asm-sparc/lmb.h>
index 7190f8de90a0ba485791d1a5620640b6c4eb4c9b..4e3d8b128a5887904d796020a3891d23e33eef22 100644 (file)
@@ -1,19 +1 @@
-#ifndef _SPARC64_LSU_H
-#define _SPARC64_LSU_H
-
-#include <linux/const.h>
-
-/* LSU Control Register */
-#define LSU_CONTROL_PM _AC(0x000001fe00000000,UL) /* Phys-watchpoint byte mask*/
-#define LSU_CONTROL_VM _AC(0x00000001fe000000,UL) /* Virt-watchpoint byte mask*/
-#define LSU_CONTROL_PR _AC(0x0000000001000000,UL) /* Phys-rd watchpoint enable*/
-#define LSU_CONTROL_PW _AC(0x0000000000800000,UL) /* Phys-wr watchpoint enable*/
-#define LSU_CONTROL_VR _AC(0x0000000000400000,UL) /* Virt-rd watchpoint enable*/
-#define LSU_CONTROL_VW _AC(0x0000000000200000,UL) /* Virt-wr watchpoint enable*/
-#define LSU_CONTROL_FM _AC(0x00000000000ffff0,UL) /* Parity mask enables.     */
-#define LSU_CONTROL_DM _AC(0x0000000000000008,UL) /* Data MMU enable.         */
-#define LSU_CONTROL_IM _AC(0x0000000000000004,UL) /* Instruction MMU enable.  */
-#define LSU_CONTROL_DC _AC(0x0000000000000002,UL) /* Data cache enable.       */
-#define LSU_CONTROL_IC _AC(0x0000000000000001,UL) /* Instruction cache enable.*/
-
-#endif /* !(_SPARC64_LSU_H) */
+#include <asm-sparc/lsu.h>
index e9c0fcc25c6f44e2c729cda84994949b32606bb0..97842e6ed1c2f895294cc86eff7cf384325466cf 100644 (file)
@@ -1,34 +1 @@
-/*
- * Machine dependent access functions for RTC registers.
- */
-#ifndef __ASM_SPARC64_MC146818RTC_H
-#define __ASM_SPARC64_MC146818RTC_H
-
-#include <asm/io.h>
-
-#ifndef RTC_PORT
-#ifdef CONFIG_PCI
-extern unsigned long ds1287_regs;
-#else
-#define ds1287_regs (0UL)
-#endif
-#define RTC_PORT(x)    (ds1287_regs + (x))
-#define RTC_ALWAYS_BCD 0
-#endif
-
-/*
- * The yet supported machines all access the RTC index register via
- * an ISA port access but the way to access the date register differs ...
- */
-#define CMOS_READ(addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-inb_p(RTC_PORT(1)); \
-})
-#define CMOS_WRITE(val, addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-outb_p((val),RTC_PORT(1)); \
-})
-
-#define RTC_IRQ 8
-
-#endif /* __ASM_SPARC64_MC146818RTC_H */
+#include <asm-sparc/mc146818rtc.h>
index 1acc7272e537bca1bfe095ea24e518b32d837a9b..165a193472862a0f37307e33164b2a4b3ab1d0dd 100644 (file)
@@ -1,78 +1 @@
-#ifndef _SPARC64_MDESC_H
-#define _SPARC64_MDESC_H
-
-#include <linux/types.h>
-#include <linux/cpumask.h>
-#include <asm/prom.h>
-
-struct mdesc_handle;
-
-/* Machine description operations are to be surrounded by grab and
- * release calls.  The mdesc_handle returned from the grab is
- * the first argument to all of the operational calls that work
- * on mdescs.
- */
-extern struct mdesc_handle *mdesc_grab(void);
-extern void mdesc_release(struct mdesc_handle *);
-
-#define MDESC_NODE_NULL                (~(u64)0)
-
-extern u64 mdesc_node_by_name(struct mdesc_handle *handle,
-                             u64 from_node, const char *name);
-#define mdesc_for_each_node_by_name(__hdl, __node, __name) \
-       for (__node = mdesc_node_by_name(__hdl, MDESC_NODE_NULL, __name); \
-            (__node) != MDESC_NODE_NULL; \
-            __node = mdesc_node_by_name(__hdl, __node, __name))
-
-/* Access to property values returned from mdesc_get_property() are
- * only valid inside of a mdesc_grab()/mdesc_release() sequence.
- * Once mdesc_release() is called, the memory backed up by these
- * pointers may reference freed up memory.
- *
- * Therefore callers must make copies of any property values
- * they need.
- *
- * These same rules apply to mdesc_node_name().
- */
-extern const void *mdesc_get_property(struct mdesc_handle *handle,
-                                     u64 node, const char *name, int *lenp);
-extern const char *mdesc_node_name(struct mdesc_handle *hp, u64 node);
-
-/* MD arc iteration, the standard sequence is:
- *
- *     unsigned long arc;
- *     mdesc_for_each_arc(arc, handle, node, MDESC_ARC_TYPE_{FWD,BACK}) {
- *             unsigned long target = mdesc_arc_target(handle, arc);
- *             ...
- *     }
- */
-
-#define MDESC_ARC_TYPE_FWD     "fwd"
-#define MDESC_ARC_TYPE_BACK    "back"
-
-extern u64 mdesc_next_arc(struct mdesc_handle *handle, u64 from,
-                         const char *arc_type);
-#define mdesc_for_each_arc(__arc, __hdl, __node, __type) \
-       for (__arc = mdesc_next_arc(__hdl, __node, __type); \
-            (__arc) != MDESC_NODE_NULL; \
-            __arc = mdesc_next_arc(__hdl, __arc, __type))
-
-extern u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc);
-
-extern void mdesc_update(void);
-
-struct mdesc_notifier_client {
-       void (*add)(struct mdesc_handle *handle, u64 node);
-       void (*remove)(struct mdesc_handle *handle, u64 node);
-
-       const char                      *node_name;
-       struct mdesc_notifier_client    *next;
-};
-
-extern void mdesc_register_notifier(struct mdesc_notifier_client *client);
-
-extern void mdesc_fill_in_cpu_data(cpumask_t mask);
-
-extern void sun4v_mdesc_init(void);
-
-#endif
+#include <asm-sparc/mdesc.h>
index d2ae67cd1bdcfca0c5cb4a11f257b5b7d93d6b6d..17ddb1724f51676be68be0c3738fa6a4ef9ed14b 100644 (file)
@@ -1,31 +1 @@
-#ifndef __SPARC64_MMAN_H__
-#define __SPARC64_MMAN_H__
-
-#include <asm-generic/mman.h>
-
-/* SunOS'ified... */
-
-#define MAP_RENAME      MAP_ANONYMOUS   /* In SunOS terminology */
-#define MAP_NORESERVE   0x40            /* don't reserve swap pages */
-#define MAP_INHERIT     0x80            /* SunOS doesn't do this, but... */
-#define MAP_LOCKED      0x100           /* lock the mapping */
-#define _MAP_NEW        0x80000000      /* Binary compatibility is fun... */
-
-#define MAP_GROWSDOWN  0x0200          /* stack-like segment */
-#define MAP_DENYWRITE  0x0800          /* ETXTBSY */
-#define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
-
-#define MCL_CURRENT     0x2000          /* lock all currently mapped pages */
-#define MCL_FUTURE      0x4000          /* lock all additions to address space */
-
-#define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
-#define MAP_NONBLOCK   0x10000         /* do not block on IO */
-
-#ifdef __KERNEL__
-#ifndef __ASSEMBLY__
-#define arch_mmap_check(addr,len,flags)        sparc64_mmap_check(addr,len)
-int sparc64_mmap_check(unsigned long addr, unsigned long len);
-#endif
-#endif
-
-#endif /* __SPARC64_MMAN_H__ */
+#include <asm-sparc/mman.h>
index 8abc58f0f9d707b0f79d438b2c238643843539e5..e677a64d8db151d370df81049fcded2c6a960dce 100644 (file)
@@ -1,127 +1 @@
-#ifndef __MMU_H
-#define __MMU_H
-
-#include <linux/const.h>
-#include <asm/page.h>
-#include <asm/hypervisor.h>
-
-#define CTX_NR_BITS            13
-
-#define TAG_CONTEXT_BITS       ((_AC(1,UL) << CTX_NR_BITS) - _AC(1,UL))
-
-/* UltraSPARC-III+ and later have a feature whereby you can
- * select what page size the various Data-TLB instances in the
- * chip.  In order to gracefully support this, we put the version
- * field in a spot outside of the areas of the context register
- * where this parameter is specified.
- */
-#define CTX_VERSION_SHIFT      22
-#define CTX_VERSION_MASK       ((~0UL) << CTX_VERSION_SHIFT)
-
-#define CTX_PGSZ_8KB           _AC(0x0,UL)
-#define CTX_PGSZ_64KB          _AC(0x1,UL)
-#define CTX_PGSZ_512KB         _AC(0x2,UL)
-#define CTX_PGSZ_4MB           _AC(0x3,UL)
-#define CTX_PGSZ_BITS          _AC(0x7,UL)
-#define CTX_PGSZ0_NUC_SHIFT    61
-#define CTX_PGSZ1_NUC_SHIFT    58
-#define CTX_PGSZ0_SHIFT                16
-#define CTX_PGSZ1_SHIFT                19
-#define CTX_PGSZ_MASK          ((CTX_PGSZ_BITS << CTX_PGSZ0_SHIFT) | \
-                                (CTX_PGSZ_BITS << CTX_PGSZ1_SHIFT))
-
-#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
-#define CTX_PGSZ_BASE  CTX_PGSZ_8KB
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
-#define CTX_PGSZ_BASE  CTX_PGSZ_64KB
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_512KB)
-#define CTX_PGSZ_BASE  CTX_PGSZ_512KB
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_4MB)
-#define CTX_PGSZ_BASE  CTX_PGSZ_4MB
-#else
-#error No page size specified in kernel configuration
-#endif
-
-#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
-#define CTX_PGSZ_HUGE          CTX_PGSZ_4MB
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
-#define CTX_PGSZ_HUGE          CTX_PGSZ_512KB
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
-#define CTX_PGSZ_HUGE          CTX_PGSZ_64KB
-#endif
-
-#define CTX_PGSZ_KERN  CTX_PGSZ_4MB
-
-/* Thus, when running on UltraSPARC-III+ and later, we use the following
- * PRIMARY_CONTEXT register values for the kernel context.
- */
-#define CTX_CHEETAH_PLUS_NUC \
-       ((CTX_PGSZ_KERN << CTX_PGSZ0_NUC_SHIFT) | \
-        (CTX_PGSZ_BASE << CTX_PGSZ1_NUC_SHIFT))
-
-#define CTX_CHEETAH_PLUS_CTX0 \
-       ((CTX_PGSZ_KERN << CTX_PGSZ0_SHIFT) | \
-        (CTX_PGSZ_BASE << CTX_PGSZ1_SHIFT))
-
-/* If you want "the TLB context number" use CTX_NR_MASK.  If you
- * want "the bits I program into the context registers" use
- * CTX_HW_MASK.
- */
-#define CTX_NR_MASK            TAG_CONTEXT_BITS
-#define CTX_HW_MASK            (CTX_NR_MASK | CTX_PGSZ_MASK)
-
-#define CTX_FIRST_VERSION      ((_AC(1,UL) << CTX_VERSION_SHIFT) + _AC(1,UL))
-#define CTX_VALID(__ctx)       \
-        (!(((__ctx.sparc64_ctx_val) ^ tlb_context_cache) & CTX_VERSION_MASK))
-#define CTX_HWBITS(__ctx)      ((__ctx.sparc64_ctx_val) & CTX_HW_MASK)
-#define CTX_NRBITS(__ctx)      ((__ctx.sparc64_ctx_val) & CTX_NR_MASK)
-
-#ifndef __ASSEMBLY__
-
-#define TSB_ENTRY_ALIGNMENT    16
-
-struct tsb {
-       unsigned long tag;
-       unsigned long pte;
-} __attribute__((aligned(TSB_ENTRY_ALIGNMENT)));
-
-extern void __tsb_insert(unsigned long ent, unsigned long tag, unsigned long pte);
-extern void tsb_flush(unsigned long ent, unsigned long tag);
-extern void tsb_init(struct tsb *tsb, unsigned long size);
-
-struct tsb_config {
-       struct tsb              *tsb;
-       unsigned long           tsb_rss_limit;
-       unsigned long           tsb_nentries;
-       unsigned long           tsb_reg_val;
-       unsigned long           tsb_map_vaddr;
-       unsigned long           tsb_map_pte;
-};
-
-#define MM_TSB_BASE    0
-
-#ifdef CONFIG_HUGETLB_PAGE
-#define MM_TSB_HUGE    1
-#define MM_NUM_TSBS    2
-#else
-#define MM_NUM_TSBS    1
-#endif
-
-typedef struct {
-       spinlock_t              lock;
-       unsigned long           sparc64_ctx_val;
-       unsigned long           huge_pte_count;
-       struct tsb_config       tsb_block[MM_NUM_TSBS];
-       struct hv_tsb_descr     tsb_descr[MM_NUM_TSBS];
-} mm_context_t;
-
-#endif /* !__ASSEMBLY__ */
-
-#define TSB_CONFIG_TSB         0x00
-#define TSB_CONFIG_RSS_LIMIT   0x08
-#define TSB_CONFIG_NENTRIES    0x10
-#define TSB_CONFIG_REG_VAL     0x18
-#define TSB_CONFIG_MAP_VADDR   0x20
-#define TSB_CONFIG_MAP_PTE     0x28
-
-#endif /* __MMU_H */
+#include <asm-sparc/mmu.h>
index 5693ab4826067056873803b6324b437e6275453f..877fee94bd4e626092679c172a811f88a8738c77 100644 (file)
@@ -1,155 +1 @@
-#ifndef __SPARC64_MMU_CONTEXT_H
-#define __SPARC64_MMU_CONTEXT_H
-
-/* Derived heavily from Linus's Alpha/AXP ASN code... */
-
-#ifndef __ASSEMBLY__
-
-#include <linux/spinlock.h>
-#include <asm/system.h>
-#include <asm/spitfire.h>
-#include <asm-generic/mm_hooks.h>
-
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-{
-}
-
-extern spinlock_t ctx_alloc_lock;
-extern unsigned long tlb_context_cache;
-extern unsigned long mmu_context_bmap[];
-
-extern void get_new_mmu_context(struct mm_struct *mm);
-#ifdef CONFIG_SMP
-extern void smp_new_mmu_context_version(void);
-#else
-#define smp_new_mmu_context_version() do { } while (0)
-#endif
-
-extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
-extern void destroy_context(struct mm_struct *mm);
-
-extern void __tsb_context_switch(unsigned long pgd_pa,
-                                struct tsb_config *tsb_base,
-                                struct tsb_config *tsb_huge,
-                                unsigned long tsb_descr_pa);
-
-static inline void tsb_context_switch(struct mm_struct *mm)
-{
-       __tsb_context_switch(__pa(mm->pgd),
-                            &mm->context.tsb_block[0],
-#ifdef CONFIG_HUGETLB_PAGE
-                            (mm->context.tsb_block[1].tsb ?
-                             &mm->context.tsb_block[1] :
-                             NULL)
-#else
-                            NULL
-#endif
-                            , __pa(&mm->context.tsb_descr[0]));
-}
-
-extern void tsb_grow(struct mm_struct *mm, unsigned long tsb_index, unsigned long mm_rss);
-#ifdef CONFIG_SMP
-extern void smp_tsb_sync(struct mm_struct *mm);
-#else
-#define smp_tsb_sync(__mm) do { } while (0)
-#endif
-
-/* Set MMU context in the actual hardware. */
-#define load_secondary_context(__mm) \
-       __asm__ __volatile__( \
-       "\n661: stxa            %0, [%1] %2\n" \
-       "       .section        .sun4v_1insn_patch, \"ax\"\n" \
-       "       .word           661b\n" \
-       "       stxa            %0, [%1] %3\n" \
-       "       .previous\n" \
-       "       flush           %%g6\n" \
-       : /* No outputs */ \
-       : "r" (CTX_HWBITS((__mm)->context)), \
-         "r" (SECONDARY_CONTEXT), "i" (ASI_DMMU), "i" (ASI_MMU))
-
-extern void __flush_tlb_mm(unsigned long, unsigned long);
-
-/* Switch the current MM context.  Interrupts are disabled.  */
-static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk)
-{
-       unsigned long ctx_valid, flags;
-       int cpu;
-
-       if (unlikely(mm == &init_mm))
-               return;
-
-       spin_lock_irqsave(&mm->context.lock, flags);
-       ctx_valid = CTX_VALID(mm->context);
-       if (!ctx_valid)
-               get_new_mmu_context(mm);
-
-       /* We have to be extremely careful here or else we will miss
-        * a TSB grow if we switch back and forth between a kernel
-        * thread and an address space which has it's TSB size increased
-        * on another processor.
-        *
-        * It is possible to play some games in order to optimize the
-        * switch, but the safest thing to do is to unconditionally
-        * perform the secondary context load and the TSB context switch.
-        *
-        * For reference the bad case is, for address space "A":
-        *
-        *              CPU 0                   CPU 1
-        *      run address space A
-        *      set cpu0's bits in cpu_vm_mask
-        *      switch to kernel thread, borrow
-        *      address space A via entry_lazy_tlb
-        *                                      run address space A
-        *                                      set cpu1's bit in cpu_vm_mask
-        *                                      flush_tlb_pending()
-        *                                      reset cpu_vm_mask to just cpu1
-        *                                      TSB grow
-        *      run address space A
-        *      context was valid, so skip
-        *      TSB context switch
-        *
-        * At that point cpu0 continues to use a stale TSB, the one from
-        * before the TSB grow performed on cpu1.  cpu1 did not cross-call
-        * cpu0 to update it's TSB because at that point the cpu_vm_mask
-        * only had cpu1 set in it.
-        */
-       load_secondary_context(mm);
-       tsb_context_switch(mm);
-
-       /* Any time a processor runs a context on an address space
-        * for the first time, we must flush that context out of the
-        * local TLB.
-        */
-       cpu = smp_processor_id();
-       if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) {
-               cpu_set(cpu, mm->cpu_vm_mask);
-               __flush_tlb_mm(CTX_HWBITS(mm->context),
-                              SECONDARY_CONTEXT);
-       }
-       spin_unlock_irqrestore(&mm->context.lock, flags);
-}
-
-#define deactivate_mm(tsk,mm)  do { } while (0)
-
-/* Activate a new MM instance for the current task. */
-static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm)
-{
-       unsigned long flags;
-       int cpu;
-
-       spin_lock_irqsave(&mm->context.lock, flags);
-       if (!CTX_VALID(mm->context))
-               get_new_mmu_context(mm);
-       cpu = smp_processor_id();
-       if (!cpu_isset(cpu, mm->cpu_vm_mask))
-               cpu_set(cpu, mm->cpu_vm_mask);
-
-       load_secondary_context(mm);
-       __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT);
-       tsb_context_switch(mm);
-       spin_unlock_irqrestore(&mm->context.lock, flags);
-}
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(__SPARC64_MMU_CONTEXT_H) */
+#include <asm-sparc/mmu_context.h>
index ebf5986c12edd563ffda723e639a3436e03ccaad..43a710f7892a6ed98fd9e8efcc3ece2f88079d63 100644 (file)
@@ -1,17 +1 @@
-#ifndef _SPARC64_MMZONE_H
-#define _SPARC64_MMZONE_H
-
-#ifdef CONFIG_NEED_MULTIPLE_NODES
-
-extern struct pglist_data *node_data[];
-
-#define NODE_DATA(nid)         (node_data[nid])
-#define node_start_pfn(nid)    (NODE_DATA(nid)->node_start_pfn)
-#define node_end_pfn(nid)      (NODE_DATA(nid)->node_end_pfn)
-
-extern int numa_cpu_lookup_table[];
-extern cpumask_t numa_cpumask_lookup_table[];
-
-#endif /* CONFIG_NEED_MULTIPLE_NODES */
-
-#endif /* _SPARC64_MMZONE_H */
+#include <asm-sparc/mmzone.h>
index 3d77ba465783048ae363fdadd82cbec42ca55dad..a9606db55e4a263629fa6da7d3c360c12650f885 100644 (file)
@@ -1,7 +1 @@
-#ifndef _ASM_SPARC64_MODULE_H
-#define _ASM_SPARC64_MODULE_H
-struct mod_arch_specific { };
-#define Elf_Shdr Elf64_Shdr
-#define Elf_Sym Elf64_Sym
-#define Elf_Ehdr Elf64_Ehdr
-#endif /* _ASM_SPARC64_MODULE_H */
+#include <asm-sparc/module.h>
index c5652de2ace203ae53c2fec604db79478bfae64a..95a752f7e875013cc63cce09b0fa048836882287 100644 (file)
@@ -1,143 +1 @@
-/* mostek.h:  Describes the various Mostek time of day clock registers.
- *
- * Copyright (C) 1995 David S. Miller (davem@davemloft.net)
- * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
- */
-
-#ifndef _SPARC64_MOSTEK_H
-#define _SPARC64_MOSTEK_H
-
-#include <asm/idprom.h>
-
-/*       M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ)
- *
- *                             Data
- * Address                                                 Function
- *        Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0
- *   7ff  -     -     -     -    -     -     -     -       Year 00-99
- *   7fe  0     0     0     -    -     -     -     -      Month 01-12
- *   7fd  0     0     -     -    -     -     -     -       Date 01-31
- *   7fc  0     FT    0     0    0     -     -     -        Day 01-07
- *   7fb  KS    0     -     -    -     -     -     -      Hours 00-23
- *   7fa  0     -     -     -    -     -     -     -    Minutes 00-59
- *   7f9  ST    -     -     -    -     -     -     -    Seconds 00-59
- *   7f8  W     R     S     -    -     -     -     -    Control
- *
- *   * ST is STOP BIT
- *   * W is WRITE BIT
- *   * R is READ BIT
- *   * S is SIGN BIT
- *   * FT is FREQ TEST BIT
- *   * KS is KICK START BIT
- */
-
-/* The Mostek 48t02 real time clock and NVRAM chip. The registers
- * other than the control register are in binary coded decimal. Some
- * control bits also live outside the control register.
- *
- * We now deal with physical addresses for I/O to the chip. -DaveM
- */
-static inline u8 mostek_read(void __iomem *addr)
-{
-       u8 ret;
-
-       __asm__ __volatile__("lduba     [%1] %2, %0"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-       return ret;
-}
-
-static inline void mostek_write(void __iomem *addr, u8 val)
-{
-       __asm__ __volatile__("stba      %0, [%1] %2"
-                            : /* no outputs */
-                            : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-}
-
-#define MOSTEK_EEPROM          0x0000UL
-#define MOSTEK_IDPROM          0x07d8UL
-#define MOSTEK_CREG            0x07f8UL
-#define MOSTEK_SEC             0x07f9UL
-#define MOSTEK_MIN             0x07faUL
-#define MOSTEK_HOUR            0x07fbUL
-#define MOSTEK_DOW             0x07fcUL
-#define MOSTEK_DOM             0x07fdUL
-#define MOSTEK_MONTH           0x07feUL
-#define MOSTEK_YEAR            0x07ffUL
-
-extern spinlock_t mostek_lock;
-extern void __iomem *mstk48t02_regs;
-
-/* Control register values. */
-#define        MSTK_CREG_WRITE 0x80    /* Must set this before placing values. */
-#define        MSTK_CREG_READ  0x40    /* Stop updates to allow a clean read. */
-#define        MSTK_CREG_SIGN  0x20    /* Slow/speed clock in calibration mode. */
-
-/* Control bits that live in the other registers. */
-#define        MSTK_STOP       0x80    /* Stop the clock oscillator. (sec) */
-#define        MSTK_KICK_START 0x80    /* Kick start the clock chip. (hour) */
-#define MSTK_FREQ_TEST 0x40    /* Frequency test mode. (day) */
-
-#define MSTK_YEAR_ZERO       1968   /* If year reg has zero, it is 1968. */
-#define MSTK_CVT_YEAR(yr)  ((yr) + MSTK_YEAR_ZERO)
-
-/* Masks that define how much space each value takes up. */
-#define        MSTK_SEC_MASK   0x7f
-#define        MSTK_MIN_MASK   0x7f
-#define        MSTK_HOUR_MASK  0x3f
-#define        MSTK_DOW_MASK   0x07
-#define        MSTK_DOM_MASK   0x3f
-#define        MSTK_MONTH_MASK 0x1f
-#define        MSTK_YEAR_MASK  0xffU
-
-/* Binary coded decimal conversion macros. */
-#define MSTK_REGVAL_TO_DECIMAL(x)  (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
-#define MSTK_DECIMAL_TO_REGVAL(x)  ((((x) / 0x0A) << 0x04) + ((x) % 0x0A))
-
-/* Generic register set and get macros for internal use. */
-#define MSTK_GET(regs,name)    \
-       (MSTK_REGVAL_TO_DECIMAL(mostek_read(regs + MOSTEK_ ## name) & MSTK_ ## name ## _MASK))
-#define MSTK_SET(regs,name,value) \
-do {   u8 __val = mostek_read(regs + MOSTEK_ ## name); \
-       __val &= ~(MSTK_ ## name ## _MASK); \
-       __val |= (MSTK_DECIMAL_TO_REGVAL(value) & \
-                 (MSTK_ ## name ## _MASK)); \
-       mostek_write(regs + MOSTEK_ ## name, __val); \
-} while(0)
-
-/* Macros to make register access easier on our fingers. These give you
- * the decimal value of the register requested if applicable. You pass
- * the a pointer to a 'struct mostek48t02'.
- */
-#define        MSTK_REG_CREG(regs)     (mostek_read((regs) + MOSTEK_CREG))
-#define        MSTK_REG_SEC(regs)      MSTK_GET(regs,SEC)
-#define        MSTK_REG_MIN(regs)      MSTK_GET(regs,MIN)
-#define        MSTK_REG_HOUR(regs)     MSTK_GET(regs,HOUR)
-#define        MSTK_REG_DOW(regs)      MSTK_GET(regs,DOW)
-#define        MSTK_REG_DOM(regs)      MSTK_GET(regs,DOM)
-#define        MSTK_REG_MONTH(regs)    MSTK_GET(regs,MONTH)
-#define        MSTK_REG_YEAR(regs)     MSTK_GET(regs,YEAR)
-
-#define        MSTK_SET_REG_SEC(regs,value)    MSTK_SET(regs,SEC,value)
-#define        MSTK_SET_REG_MIN(regs,value)    MSTK_SET(regs,MIN,value)
-#define        MSTK_SET_REG_HOUR(regs,value)   MSTK_SET(regs,HOUR,value)
-#define        MSTK_SET_REG_DOW(regs,value)    MSTK_SET(regs,DOW,value)
-#define        MSTK_SET_REG_DOM(regs,value)    MSTK_SET(regs,DOM,value)
-#define        MSTK_SET_REG_MONTH(regs,value)  MSTK_SET(regs,MONTH,value)
-#define        MSTK_SET_REG_YEAR(regs,value)   MSTK_SET(regs,YEAR,value)
-
-
-/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the
- * same (basically) layout of the 48t02 chip except for the extra
- * NVRAM on board (8 KB against the 48t02's 2 KB).
- */
-#define MOSTEK_48T08_OFFSET    0x0000UL        /* Lower NVRAM portions */
-#define MOSTEK_48T08_48T02     0x1800UL        /* Offset to 48T02 chip */
-
-/* SUN5 systems usually have 48t59 model clock chipsets.  But we keep the older
- * clock chip definitions around just in case.
- */
-#define MOSTEK_48T59_OFFSET    0x0000UL        /* Lower NVRAM portions */
-#define MOSTEK_48T59_48T02     0x1800UL        /* Offset to 48T02 chip */
-
-#endif /* !(_SPARC64_MOSTEK_H) */
+#include <asm-sparc/mostek.h>
index 55c101bd0e7db1935a1f639d2250ca4e4daaaf54..5b33cc9d9bfb1bf75f1180099a922be0c962a0cb 100644 (file)
@@ -1,27 +1 @@
-#ifndef _SPARC64_MSGBUF_H
-#define _SPARC64_MSGBUF_H
-
-/* 
- * The msqid64_ds structure for sparc64 architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 2 miscellaneous 64-bit values
- */
-
-struct msqid64_ds {
-       struct ipc64_perm msg_perm;
-       __kernel_time_t msg_stime;      /* last msgsnd time */
-       __kernel_time_t msg_rtime;      /* last msgrcv time */
-       __kernel_time_t msg_ctime;      /* last change time */
-       unsigned long  msg_cbytes;      /* current number of bytes on queue */
-       unsigned long  msg_qnum;        /* number of messages in queue */
-       unsigned long  msg_qbytes;      /* max number of bytes on queue */
-       __kernel_pid_t msg_lspid;       /* pid of last msgsnd */
-       __kernel_pid_t msg_lrpid;       /* last receive pid */
-       unsigned long  __unused1;
-       unsigned long  __unused2;
-};
-
-#endif /* _SPARC64_MSGBUF_H */
+#include <asm-sparc/msgbuf.h>
index 458c1f7fbc1808d48982aa0c5fe89bfe3df2098c..c0c0f8f260d60eede782c466b2027522395ebbed 100644 (file)
@@ -1,9 +1 @@
-/*
- * Pull in the generic implementation for the mutex fastpath.
- *
- * TODO: implement optimized primitives instead, or leave the generic
- * implementation in place, or pick the atomic_xchg() based generic
- * implementation. (see asm-generic/mutex-xchg.h for details)
- */
-
-#include <asm-generic/mutex-dec.h>
+#include <asm-sparc/mutex.h>
index cbc1b4c06891e998530b7352f6e824c46e6775fe..1344a910ba2f71edd899f7564635562ce1f585ab 100644 (file)
@@ -1,13 +1 @@
-/*
- * linux/include/asm-sparc64/namei.h
- *
- * Routines to handle famous /usr/gnemul/s*.
- * Included from linux/fs/namei.c
- */
-
-#ifndef __SPARC64_NAMEI_H
-#define __SPARC64_NAMEI_H
-
-#define __emul_prefix() NULL
-
-#endif /* __SPARC64_NAMEI_H */
+#include <asm-sparc/namei.h>
index 686defe6aaa0cbe2ef0078ae4c70c668f814780a..5f369d4df3dbf27e3d7b257075aed5175cf6ee4d 100644 (file)
@@ -1,118 +1 @@
-/* ns87303.h: Configuration Register Description for the
- *            National Semiconductor PC87303 (SuperIO).
- *
- * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
- */
-
-#ifndef _SPARC_NS87303_H
-#define _SPARC_NS87303_H 1
-
-/*
- * Control Register Index Values
- */
-#define FER    0x00
-#define FAR    0x01
-#define PTR    0x02
-#define FCR    0x03
-#define PCR    0x04
-#define KRR    0x05
-#define PMC    0x06
-#define TUP    0x07
-#define SID    0x08
-#define ASC    0x09
-#define CS0CF0 0x0a
-#define CS0CF1 0x0b
-#define CS1CF0 0x0c
-#define CS1CF1 0x0d
-
-/* Function Enable Register (FER) bits */
-#define FER_EDM                0x10    /* Encoded Drive and Motor pin information   */
-
-/* Function Address Register (FAR) bits */
-#define FAR_LPT_MASK   0x03
-#define FAR_LPTB       0x00
-#define FAR_LPTA       0x01
-#define FAR_LPTC       0x02
-
-/* Power and Test Register (PTR) bits */
-#define PTR_LPTB_IRQ7  0x08
-#define PTR_LEVEL_IRQ  0x80    /* When not ECP/EPP: Use level IRQ           */
-#define PTR_LPT_REG_DIR        0x80    /* When ECP/EPP: LPT CTR controlls direction */
-                               /*               of the parallel port        */
-
-/* Function Control Register (FCR) bits */
-#define FCR_LDE                0x10    /* Logical Drive Exchange                    */
-#define FCR_ZWS_ENA    0x20    /* Enable short host read/write in ECP/EPP   */
-
-/* Printer Control Register (PCR) bits */
-#define PCR_EPP_ENABLE 0x01
-#define PCR_EPP_IEEE   0x02    /* Enable EPP Version 1.9 (IEEE 1284)        */
-#define PCR_ECP_ENABLE 0x04
-#define PCR_ECP_CLK_ENA        0x08    /* If 0 ECP Clock is stopped on Power down   */
-#define PCR_IRQ_POLAR  0x20    /* If 0 IRQ is level high or negative pulse, */
-                               /* if 1 polarity is inverted                 */
-#define PCR_IRQ_ODRAIN 0x40    /* If 1, IRQ is open drain                   */
-
-/* Tape UARTs and Parallel Port Config Register (TUP) bits */
-#define TUP_EPP_TIMO   0x02    /* Enable EPP timeout IRQ                    */
-
-/* Advanced SuperIO Config Register (ASC) bits */
-#define ASC_LPT_IRQ7   0x01    /* Always use IRQ7 for LPT                  */
-#define ASC_DRV2_SEL   0x02    /* Logical Drive Exchange controlled by TDR  */
-
-#define FER_RESERVED   0x00
-#define FAR_RESERVED   0x00
-#define PTR_RESERVED   0x73
-#define FCR_RESERVED   0xc4
-#define PCR_RESERVED   0x10
-#define KRR_RESERVED   0x00
-#define PMC_RESERVED   0x98
-#define TUP_RESERVED   0xfb
-#define SIP_RESERVED   0x00
-#define ASC_RESERVED   0x18
-#define CS0CF0_RESERVED        0x00
-#define CS0CF1_RESERVED        0x08
-#define CS1CF0_RESERVED        0x00
-#define CS1CF1_RESERVED        0x08
-
-#ifdef __KERNEL__
-
-#include <linux/spinlock.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-
-extern spinlock_t ns87303_lock;
-
-static inline int ns87303_modify(unsigned long port, unsigned int index,
-                                    unsigned char clr, unsigned char set)
-{
-       static unsigned char reserved[] = {
-               FER_RESERVED, FAR_RESERVED, PTR_RESERVED, FCR_RESERVED,
-               PCR_RESERVED, KRR_RESERVED, PMC_RESERVED, TUP_RESERVED,
-               SIP_RESERVED, ASC_RESERVED, CS0CF0_RESERVED, CS0CF1_RESERVED,
-               CS1CF0_RESERVED, CS1CF1_RESERVED
-       };
-       unsigned long flags;
-       unsigned char value;
-
-       if (index > 0x0d)
-               return -EINVAL;
-
-       spin_lock_irqsave(&ns87303_lock, flags);
-
-       outb(index, port);
-       value = inb(port + 1);
-       value &= ~(reserved[index] | clr);
-       value |= set;
-       outb(value, port + 1);
-       outb(value, port + 1);
-
-       spin_unlock_irqrestore(&ns87303_lock, flags);
-
-       return 0;
-}
-
-#endif /* __KERNEL__ */
-
-#endif /* !(_SPARC_NS87303_H) */
+#include <asm-sparc/ns87303.h>
index 78aa032b674c42bb7a4e1f02aaa6d243d298d13f..f7c427b8bc61a20ed183cbf59c9b8a7aa1da8a69 100644 (file)
@@ -1,25 +1 @@
-#ifndef _ASM_SPARC64_OF_PLATFORM_H
-#define _ASM_SPARC64_OF_PLATFORM_H
-/*
- *    Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
- *                      <benh@kernel.crashing.org>
- *    Modified for Sparc by merging parts of asm-sparc/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.
- *
- */
-
-/* This is just here during the transition */
-#include <linux/of_platform.h>
-
-extern struct bus_type isa_bus_type;
-extern struct bus_type ebus_bus_type;
-extern struct bus_type sbus_bus_type;
-
-#define of_bus_type    of_platform_bus_type    /* for compatibility */
-
-#endif /* _ASM_SPARC64_OF_PLATFORM_H */
+#include <asm-sparc/of_platform.h>
index b69e4a8c9170a75ae05486fee8106cc06334011a..acf4b234fae381f1934d6e45113bd978ba94a327 100644 (file)
@@ -1,280 +1 @@
-#ifndef __SPARC64_OPENPROM_H
-#define __SPARC64_OPENPROM_H
-
-/* openprom.h:  Prom structures and defines for access to the OPENBOOT
- *              prom routines and data areas.
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef __ASSEMBLY__
-/* V0 prom device operations. */
-struct linux_dev_v0_funcs {
-       int (*v0_devopen)(char *device_str);
-       int (*v0_devclose)(int dev_desc);
-       int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
-       int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
-       int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf);
-       int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf);
-       int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
-       int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
-       int (*v0_seekdev)(int dev_desc, long logical_offst, int from);
-};
-
-/* V2 and later prom device operations. */
-struct linux_dev_v2_funcs {
-       int (*v2_inst2pkg)(int d);      /* Convert ihandle to phandle */
-       char * (*v2_dumb_mem_alloc)(char *va, unsigned sz);
-       void (*v2_dumb_mem_free)(char *va, unsigned sz);
-
-       /* To map devices into virtual I/O space. */
-       char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz);
-       void (*v2_dumb_munmap)(char *virta, unsigned size);
-
-       int (*v2_dev_open)(char *devpath);
-       void (*v2_dev_close)(int d);
-       int (*v2_dev_read)(int d, char *buf, int nbytes);
-       int (*v2_dev_write)(int d, char *buf, int nbytes);
-       int (*v2_dev_seek)(int d, int hi, int lo);
-
-       /* Never issued (multistage load support) */
-       void (*v2_wheee2)(void);
-       void (*v2_wheee3)(void);
-};
-
-struct linux_mlist_v0 {
-       struct linux_mlist_v0 *theres_more;
-       unsigned start_adr;
-       unsigned num_bytes;
-};
-
-struct linux_mem_v0 {
-       struct linux_mlist_v0 **v0_totphys;
-       struct linux_mlist_v0 **v0_prommap;
-       struct linux_mlist_v0 **v0_available; /* What we can use */
-};
-
-/* Arguments sent to the kernel from the boot prompt. */
-struct linux_arguments_v0 {
-       char *argv[8];
-       char args[100];
-       char boot_dev[2];
-       int boot_dev_ctrl;
-       int boot_dev_unit;
-       int dev_partition;
-       char *kernel_file_name;
-       void *aieee1;           /* XXX */
-};
-
-/* V2 and up boot things. */
-struct linux_bootargs_v2 {
-       char **bootpath;
-       char **bootargs;
-       int *fd_stdin;
-       int *fd_stdout;
-};
-
-/* The top level PROM vector. */
-struct linux_romvec {
-       /* Version numbers. */
-       unsigned int pv_magic_cookie;
-       unsigned int pv_romvers;
-       unsigned int pv_plugin_revision;
-       unsigned int pv_printrev;
-
-       /* Version 0 memory descriptors. */
-       struct linux_mem_v0 pv_v0mem;
-
-       /* Node operations. */
-       struct linux_nodeops *pv_nodeops;
-
-       char **pv_bootstr;
-       struct linux_dev_v0_funcs pv_v0devops;
-
-       char *pv_stdin;
-       char *pv_stdout;
-#define        PROMDEV_KBD     0               /* input from keyboard */
-#define        PROMDEV_SCREEN  0               /* output to screen */
-#define        PROMDEV_TTYA    1               /* in/out to ttya */
-#define        PROMDEV_TTYB    2               /* in/out to ttyb */
-
-       /* Blocking getchar/putchar.  NOT REENTRANT! (grr) */
-       int (*pv_getchar)(void);
-       void (*pv_putchar)(int ch);
-
-       /* Non-blocking variants. */
-       int (*pv_nbgetchar)(void);
-       int (*pv_nbputchar)(int ch);
-
-       void (*pv_putstr)(char *str, int len);
-
-       /* Miscellany. */
-       void (*pv_reboot)(char *bootstr);
-       void (*pv_printf)(__const__ char *fmt, ...);
-       void (*pv_abort)(void);
-       __volatile__ int *pv_ticks;
-       void (*pv_halt)(void);
-       void (**pv_synchook)(void);
-
-       /* Evaluate a forth string, not different proto for V0 and V2->up. */
-       union {
-               void (*v0_eval)(int len, char *str);
-               void (*v2_eval)(char *str);
-       } pv_fortheval;
-
-       struct linux_arguments_v0 **pv_v0bootargs;
-
-       /* Get ether address. */
-       unsigned int (*pv_enaddr)(int d, char *enaddr);
-
-       struct linux_bootargs_v2 pv_v2bootargs;
-       struct linux_dev_v2_funcs pv_v2devops;
-
-       int filler[15];
-
-       /* This one is sun4c/sun4 only. */
-       void (*pv_setctxt)(int ctxt, char *va, int pmeg);
-
-       /* Prom version 3 Multiprocessor routines. This stuff is crazy.
-        * No joke. Calling these when there is only one cpu probably
-        * crashes the machine, have to test this. :-)
-        */
-
-       /* v3_cpustart() will start the cpu 'whichcpu' in mmu-context
-        * 'thiscontext' executing at address 'prog_counter'
-        */
-       int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr,
-                          int thiscontext, char *prog_counter);
-
-       /* v3_cpustop() will cause cpu 'whichcpu' to stop executing
-        * until a resume cpu call is made.
-        */
-       int (*v3_cpustop)(unsigned int whichcpu);
-
-       /* v3_cpuidle() will idle cpu 'whichcpu' until a stop or
-        * resume cpu call is made.
-        */
-       int (*v3_cpuidle)(unsigned int whichcpu);
-
-       /* v3_cpuresume() will resume processor 'whichcpu' executing
-        * starting with whatever 'pc' and 'npc' were left at the
-        * last 'idle' or 'stop' call.
-        */
-       int (*v3_cpuresume)(unsigned int whichcpu);
-};
-
-/* Routines for traversing the prom device tree. */
-struct linux_nodeops {
-       int (*no_nextnode)(int node);
-       int (*no_child)(int node);
-       int (*no_proplen)(int node, char *name);
-       int (*no_getprop)(int node, char *name, char *val);
-       int (*no_setprop)(int node, char *name, char *val, int len);
-       char * (*no_nextprop)(int node, char *name);
-};
-
-/* More fun PROM structures for device probing. */
-#define PROMREG_MAX     24
-#define PROMVADDR_MAX   16
-#define PROMINTR_MAX    32
-
-struct linux_prom_registers {
-       unsigned which_io;      /* hi part of physical address                  */
-       unsigned phys_addr;     /* The physical address of this register        */
-       int reg_size;           /* How many bytes does this register take up?   */
-};
-
-struct linux_prom64_registers {
-       unsigned long phys_addr;
-       unsigned long reg_size;
-};
-
-struct linux_prom_irqs {
-       int pri;    /* IRQ priority */
-       int vector; /* This is foobar, what does it do? */
-};
-
-/* Element of the "ranges" vector */
-struct linux_prom_ranges {
-       unsigned int ot_child_space;
-       unsigned int ot_child_base;             /* Bus feels this */
-       unsigned int ot_parent_space;
-       unsigned int ot_parent_base;            /* CPU looks from here */
-       unsigned int or_size;
-};
-
-struct linux_prom64_ranges {
-       unsigned long ot_child_base;            /* Bus feels this */
-       unsigned long ot_parent_base;           /* CPU looks from here */
-       unsigned long or_size;
-};
-
-/* Ranges and reg properties are a bit different for PCI. */
-struct linux_prom_pci_registers {
-       unsigned int phys_hi;
-       unsigned int phys_mid;
-       unsigned int phys_lo;
-
-       unsigned int size_hi;
-       unsigned int size_lo;
-};
-
-struct linux_prom_pci_ranges {
-       unsigned int child_phys_hi;     /* Only certain bits are encoded here. */
-       unsigned int child_phys_mid;
-       unsigned int child_phys_lo;
-
-       unsigned int parent_phys_hi;
-       unsigned int parent_phys_lo;
-
-       unsigned int size_hi;
-       unsigned int size_lo;
-};
-
-struct linux_prom_pci_intmap {
-       unsigned int phys_hi;
-       unsigned int phys_mid;
-       unsigned int phys_lo;
-
-       unsigned int interrupt;
-
-       int          cnode;
-       unsigned int cinterrupt;
-};
-
-struct linux_prom_pci_intmask {
-       unsigned int phys_hi;
-       unsigned int phys_mid;
-       unsigned int phys_lo;
-       unsigned int interrupt;
-};
-
-struct linux_prom_ebus_ranges {
-       unsigned int child_phys_hi;
-       unsigned int child_phys_lo;
-
-       unsigned int parent_phys_hi;
-       unsigned int parent_phys_mid;
-       unsigned int parent_phys_lo;
-
-       unsigned int size;
-};
-
-struct linux_prom_ebus_intmap {
-       unsigned int phys_hi;
-       unsigned int phys_lo;
-
-       unsigned int interrupt;
-
-       int          cnode;
-       unsigned int cinterrupt;
-};
-
-struct linux_prom_ebus_intmask {
-       unsigned int phys_hi;
-       unsigned int phys_lo;
-       unsigned int interrupt;
-};
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(__SPARC64_OPENPROM_H) */
+#include <asm-sparc/openprom.h>
index 847ce2326ad5fb93144105d1e154ff9868997d0f..122fabda21f1ebecad8f621899788639cf3e4a83 100644 (file)
@@ -1,69 +1 @@
-#ifndef        _SPARC64_OPENPROMIO_H
-#define        _SPARC64_OPENPROMIO_H
-
-#include <linux/compiler.h>
-#include <linux/ioctl.h>
-#include <linux/types.h>
-
-/*
- * SunOS and Solaris /dev/openprom definitions. The ioctl values
- * were chosen to be exactly equal to the SunOS equivalents.
- */
-
-struct openpromio
-{
-       u_int   oprom_size;             /* Actual size of the oprom_array. */
-       char    oprom_array[1];         /* Holds property names and values. */
-};
-
-#define        OPROMMAXPARAM   4096            /* Maximum size of oprom_array. */
-
-#define        OPROMGETOPT             0x20004F01
-#define        OPROMSETOPT             0x20004F02
-#define        OPROMNXTOPT             0x20004F03
-#define        OPROMSETOPT2            0x20004F04
-#define        OPROMNEXT               0x20004F05
-#define        OPROMCHILD              0x20004F06
-#define        OPROMGETPROP            0x20004F07
-#define        OPROMNXTPROP            0x20004F08
-#define        OPROMU2P                0x20004F09
-#define        OPROMGETCONS            0x20004F0A
-#define        OPROMGETFBNAME          0x20004F0B
-#define        OPROMGETBOOTARGS        0x20004F0C
-/* Linux extensions */                         /* Arguments in oprom_array: */
-#define OPROMSETCUR            0x20004FF0      /* int node - Sets current node */
-#define OPROMPCI2NODE          0x20004FF1      /* int pci_bus, pci_devfn - Sets current node to PCI device's node */
-#define OPROMPATH2NODE         0x20004FF2      /* char path[] - Set current node from fully qualified PROM path */
-
-/*
- * Return values from OPROMGETCONS:
- */
-
-#define OPROMCONS_NOT_WSCONS    0
-#define OPROMCONS_STDIN_IS_KBD  0x1     /* stdin device is kbd */
-#define OPROMCONS_STDOUT_IS_FB  0x2     /* stdout is a framebuffer */
-#define OPROMCONS_OPENPROM      0x4     /* supports openboot */
-
-
-/*
- *  NetBSD/OpenBSD /dev/openprom definitions.
- */
-
-struct opiocdesc
-{
-       int     op_nodeid;              /* PROM Node ID (value-result) */
-       int     op_namelen;             /* Length of op_name. */
-       char    __user *op_name;        /* Pointer to the property name. */
-       int     op_buflen;              /* Length of op_buf (value-result) */
-       char    __user *op_buf;         /* Pointer to buffer. */
-};
-
-#define        OPIOCGET        _IOWR('O', 1, struct opiocdesc)
-#define        OPIOCSET        _IOW('O', 2, struct opiocdesc)
-#define        OPIOCNEXTPROP   _IOWR('O', 3, struct opiocdesc)
-#define        OPIOCGETOPTNODE _IOR('O', 4, int)
-#define        OPIOCGETNEXT    _IOWR('O', 5, int)
-#define        OPIOCGETCHILD   _IOWR('O', 6, int)
-
-#endif /* _SPARC64_OPENPROMIO_H */
-
+#include <asm-sparc/openpromio.h>
index 55c5bb27e4da241cc1eae429f0ca36d1fb103dea..d93e44e63510e17ffc3f44f8a472fd03b556895f 100644 (file)
@@ -1,322 +1 @@
-/* oplib.h:  Describes the interface and available routines in the
- *           Linux Prom library.
- *
- * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#ifndef __SPARC64_OPLIB_H
-#define __SPARC64_OPLIB_H
-
-#include <asm/openprom.h>
-
-/* OBP version string. */
-extern char prom_version[];
-
-/* Root node of the prom device tree, this stays constant after
- * initialization is complete.
- */
-extern int prom_root_node;
-
-/* PROM stdin and stdout */
-extern int prom_stdin, prom_stdout;
-
-/* /chosen node of the prom device tree, this stays constant after
- * initialization is complete.
- */
-extern int prom_chosen_node;
-
-/* Helper values and strings in arch/sparc64/kernel/head.S */
-extern const char prom_peer_name[];
-extern const char prom_compatible_name[];
-extern const char prom_root_compatible[];
-extern const char prom_cpu_compatible[];
-extern const char prom_finddev_name[];
-extern const char prom_chosen_path[];
-extern const char prom_cpu_path[];
-extern const char prom_getprop_name[];
-extern const char prom_mmu_name[];
-extern const char prom_callmethod_name[];
-extern const char prom_translate_name[];
-extern const char prom_map_name[];
-extern const char prom_unmap_name[];
-extern int prom_mmu_ihandle_cache;
-extern unsigned int prom_boot_mapped_pc;
-extern unsigned int prom_boot_mapping_mode;
-extern unsigned long prom_boot_mapping_phys_high, prom_boot_mapping_phys_low;
-
-struct linux_mlist_p1275 {
-       struct linux_mlist_p1275 *theres_more;
-       unsigned long start_adr;
-       unsigned long num_bytes;
-};
-
-struct linux_mem_p1275 {
-       struct linux_mlist_p1275 **p1275_totphys;
-       struct linux_mlist_p1275 **p1275_prommap;
-       struct linux_mlist_p1275 **p1275_available; /* What we can use */
-};
-
-/* The functions... */
-
-/* You must call prom_init() before using any of the library services,
- * preferably as early as possible.  Pass it the romvec pointer.
- */
-extern void prom_init(void *cif_handler, void *cif_stack);
-
-/* Boot argument acquisition, returns the boot command line string. */
-extern char *prom_getbootargs(void);
-
-/* Device utilities. */
-
-/* Device operations. */
-
-/* Open the device described by the passed string.  Note, that the format
- * of the string is different on V0 vs. V2->higher proms.  The caller must
- * know what he/she is doing!  Returns the device descriptor, an int.
- */
-extern int prom_devopen(const char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
-                     unsigned int seek_lowval);
-
-/* Miscellaneous routines, don't really fit in any category per se. */
-
-/* Reboot the machine with the command line passed. */
-extern void prom_reboot(const char *boot_command);
-
-/* Evaluate the forth string passed. */
-extern void prom_feval(const char *forth_string);
-
-/* Enter the prom, with possibility of continuation with the 'go'
- * command in newer proms.
- */
-extern void prom_cmdline(void);
-
-/* Enter the prom, with no chance of continuation for the stand-alone
- * which calls this.
- */
-extern void prom_halt(void) __attribute__ ((noreturn));
-
-/* Halt and power-off the machine. */
-extern void prom_halt_power_off(void) __attribute__ ((noreturn));
-
-/* Set the PROM 'sync' callback function to the passed function pointer.
- * When the user gives the 'sync' command at the prom prompt while the
- * kernel is still active, the prom will call this routine.
- *
- */
-typedef int (*callback_func_t)(long *cmd);
-extern void prom_setcallback(callback_func_t func_ptr);
-
-/* Acquire the IDPROM of the root node in the prom device tree.  This
- * gets passed a buffer where you would like it stuffed.  The return value
- * is the format type of this idprom or 0xff on error.
- */
-extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
-
-/* Character operations to/from the console.... */
-
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
-/* Blocking get character from console. */
-extern char prom_getchar(void);
-
-/* Blocking put character to console. */
-extern void prom_putchar(char character);
-
-/* Prom's internal routines, don't use in kernel/boot code. */
-extern void prom_printf(const char *fmt, ...);
-extern void prom_write(const char *buf, unsigned int len);
-
-/* Multiprocessor operations... */
-#ifdef CONFIG_SMP
-/* Start the CPU with the given device tree node at the passed program
- * counter with the given arg passed in via register %o0.
- */
-extern void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg);
-
-/* Start the CPU with the given cpu ID at the passed program
- * counter with the given arg passed in via register %o0.
- */
-extern void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg);
-
-/* Stop the CPU with the given cpu ID.  */
-extern void prom_stopcpu_cpuid(int cpuid);
-
-/* Stop the current CPU. */
-extern void prom_stopself(void);
-
-/* Idle the current CPU. */
-extern void prom_idleself(void);
-
-/* Resume the CPU with the passed device tree node. */
-extern void prom_resumecpu(int cpunode);
-#endif
-
-/* Power management interfaces. */
-
-/* Put the current CPU to sleep. */
-extern void prom_sleepself(void);
-
-/* Put the entire system to sleep. */
-extern int prom_sleepsystem(void);
-
-/* Initiate a wakeup event. */
-extern int prom_wakeupsystem(void);
-
-/* MMU and memory related OBP interfaces. */
-
-/* Get unique string identifying SIMM at given physical address. */
-extern int prom_getunumber(int syndrome_code,
-                          unsigned long phys_addr,
-                          char *buf, int buflen);
-
-/* Retain physical memory to the caller across soft resets. */
-extern unsigned long prom_retain(const char *name,
-                                unsigned long pa_low, unsigned long pa_high,
-                                long size, long align);
-
-/* Load explicit I/D TLB entries into the calling processor. */
-extern long prom_itlb_load(unsigned long index,
-                          unsigned long tte_data,
-                          unsigned long vaddr);
-
-extern long prom_dtlb_load(unsigned long index,
-                          unsigned long tte_data,
-                          unsigned long vaddr);
-
-/* Map/Unmap client program address ranges.  First the format of
- * the mapping mode argument.
- */
-#define PROM_MAP_WRITE 0x0001 /* Writable */
-#define PROM_MAP_READ  0x0002 /* Readable - sw */
-#define PROM_MAP_EXEC  0x0004 /* Executable - sw */
-#define PROM_MAP_LOCKED        0x0010 /* Locked, use i/dtlb load calls for this instead */
-#define PROM_MAP_CACHED        0x0020 /* Cacheable in both L1 and L2 caches */
-#define PROM_MAP_SE    0x0040 /* Side-Effects */
-#define PROM_MAP_GLOB  0x0080 /* Global */
-#define PROM_MAP_IE    0x0100 /* Invert-Endianness */
-#define PROM_MAP_DEFAULT (PROM_MAP_WRITE | PROM_MAP_READ | PROM_MAP_EXEC | PROM_MAP_CACHED)
-
-extern int prom_map(int mode, unsigned long size,
-                   unsigned long vaddr, unsigned long paddr);
-extern void prom_unmap(unsigned long size, unsigned long vaddr);
-
-
-/* PROM device tree traversal functions... */
-
-#ifdef PROMLIB_INTERNAL
-
-/* Internal version of prom_getchild. */
-extern int __prom_getchild(int parent_node);
-
-/* Internal version of prom_getsibling. */
-extern int __prom_getsibling(int node);
-
-#endif
-
-/* Get the child node of the given node, or zero if no child exists. */
-extern int prom_getchild(int parent_node);
-
-/* Get the next sibling node of the given node, or zero if no further
- * siblings exist.
- */
-extern int prom_getsibling(int node);
-
-/* Get the length, at the passed node, of the given property type.
- * Returns -1 on error (ie. no such property at this node).
- */
-extern int prom_getproplen(int thisnode, const char *property);
-
-/* Fetch the requested property using the given buffer.  Returns
- * the number of bytes the prom put into your buffer or -1 on error.
- */
-extern int prom_getproperty(int thisnode, const char *property,
-                           char *prop_buffer, int propbuf_size);
-
-/* Acquire an integer property. */
-extern int prom_getint(int node, const char *property);
-
-/* Acquire an integer property, with a default value. */
-extern int prom_getintdefault(int node, const char *property, int defval);
-
-/* Acquire a boolean property, 0=FALSE 1=TRUE. */
-extern int prom_getbool(int node, const char *prop);
-
-/* Acquire a string property, null string on error. */
-extern void prom_getstring(int node, const char *prop, char *buf, int bufsize);
-
-/* Does the passed node have the given "name"? YES=1 NO=0 */
-extern int prom_nodematch(int thisnode, const char *name);
-
-/* Search all siblings starting at the passed node for "name" matching
- * the given string.  Returns the node on success, zero on failure.
- */
-extern int prom_searchsiblings(int node_start, const char *name);
-
-/* Return the first property type, as a string, for the given node.
- * Returns a null string on error. Buffer should be at least 32B long.
- */
-extern char *prom_firstprop(int node, char *buffer);
-
-/* Returns the next property after the passed property for the given
- * node.  Returns null string on failure. Buffer should be at least 32B long.
- */
-extern char *prom_nextprop(int node, const char *prev_property, char *buffer);
-
-/* Returns 1 if the specified node has given property. */
-extern int prom_node_has_property(int node, const char *property);
-
-/* Returns phandle of the path specified */
-extern int prom_finddevice(const char *name);
-
-/* Set the indicated property at the given node with the passed value.
- * Returns the number of bytes of your value that the prom took.
- */
-extern int prom_setprop(int node, const char *prop_name, char *prop_value,
-                       int value_size);
-                       
-extern int prom_pathtoinode(const char *path);
-extern int prom_inst2pkg(int);
-extern int prom_service_exists(const char *service_name);
-extern void prom_sun4v_guest_soft_state(void);
-
-extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
-
-/* Client interface level routines. */
-extern long p1275_cmd(const char *, long, ...);
-
-#if 0
-#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x))
-#else
-#define P1275_SIZE(x) x
-#endif
-
-/* We support at most 16 input and 1 output argument */
-#define P1275_ARG_NUMBER               0
-#define P1275_ARG_IN_STRING            1
-#define P1275_ARG_OUT_BUF              2
-#define P1275_ARG_OUT_32B              3
-#define P1275_ARG_IN_FUNCTION          4
-#define P1275_ARG_IN_BUF               5
-#define P1275_ARG_IN_64B               6
-
-#define P1275_IN(x) ((x) & 0xf)
-#define P1275_OUT(x) (((x) << 4) & 0xf0)
-#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o))
-#define P1275_ARG(n,x) ((x) << ((n)*3 + 8))
-
-#endif /* !(__SPARC64_OPLIB_H) */
+#include <asm-sparc/oplib.h>
index 93f0881b766e2ad4ff39462f945cce7290cb840f..f46c1fb53028f1b4ecc939b3c68c954fcab33de6 100644 (file)
@@ -1,142 +1 @@
-#ifndef _SPARC64_PAGE_H
-#define _SPARC64_PAGE_H
-
-#include <linux/const.h>
-
-#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
-#define PAGE_SHIFT   13
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
-#define PAGE_SHIFT   16
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_512KB)
-#define PAGE_SHIFT   19
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_4MB)
-#define PAGE_SHIFT   22
-#else
-#error No page size specified in kernel configuration
-#endif
-
-#define PAGE_SIZE    (_AC(1,UL) << PAGE_SHIFT)
-#define PAGE_MASK    (~(PAGE_SIZE-1))
-
-/* Flushing for D-cache alias handling is only needed if
- * the page size is smaller than 16K.
- */
-#if PAGE_SHIFT < 14
-#define DCACHE_ALIASING_POSSIBLE
-#endif
-
-#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
-#define HPAGE_SHIFT            22
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
-#define HPAGE_SHIFT            19
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
-#define HPAGE_SHIFT            16
-#endif
-
-#ifdef CONFIG_HUGETLB_PAGE
-#define HPAGE_SIZE             (_AC(1,UL) << HPAGE_SHIFT)
-#define HPAGE_MASK             (~(HPAGE_SIZE - 1UL))
-#define HUGETLB_PAGE_ORDER     (HPAGE_SHIFT - PAGE_SHIFT)
-#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-#endif
-
-#ifndef __ASSEMBLY__
-
-extern void _clear_page(void *page);
-#define clear_page(X)  _clear_page((void *)(X))
-struct page;
-extern void clear_user_page(void *addr, unsigned long vaddr, struct page *page);
-#define copy_page(X,Y) memcpy((void *)(X), (void *)(Y), PAGE_SIZE)
-extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *topage);
-
-/* Unlike sparc32, sparc64's parameter passing API is more
- * sane in that structures which as small enough are passed
- * in registers instead of on the stack.  Thus, setting
- * STRICT_MM_TYPECHECKS does not generate worse code so
- * let's enable it to get the type checking.
- */
-
-#define STRICT_MM_TYPECHECKS
-
-#ifdef STRICT_MM_TYPECHECKS
-/* These are used to make use of C type-checking.. */
-typedef struct { unsigned long pte; } pte_t;
-typedef struct { unsigned long iopte; } iopte_t;
-typedef struct { unsigned int pmd; } pmd_t;
-typedef struct { unsigned int pgd; } pgd_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
-
-#define pte_val(x)     ((x).pte)
-#define iopte_val(x)   ((x).iopte)
-#define pmd_val(x)      ((x).pmd)
-#define pgd_val(x)     ((x).pgd)
-#define pgprot_val(x)  ((x).pgprot)
-
-#define __pte(x)       ((pte_t) { (x) } )
-#define __iopte(x)     ((iopte_t) { (x) } )
-#define __pmd(x)        ((pmd_t) { (x) } )
-#define __pgd(x)       ((pgd_t) { (x) } )
-#define __pgprot(x)    ((pgprot_t) { (x) } )
-
-#else
-/* .. while these make it easier on the compiler */
-typedef unsigned long pte_t;
-typedef unsigned long iopte_t;
-typedef unsigned int pmd_t;
-typedef unsigned int pgd_t;
-typedef unsigned long pgprot_t;
-
-#define pte_val(x)     (x)
-#define iopte_val(x)   (x)
-#define pmd_val(x)      (x)
-#define pgd_val(x)     (x)
-#define pgprot_val(x)  (x)
-
-#define __pte(x)       (x)
-#define __iopte(x)     (x)
-#define __pmd(x)        (x)
-#define __pgd(x)       (x)
-#define __pgprot(x)    (x)
-
-#endif /* (STRICT_MM_TYPECHECKS) */
-
-typedef struct page *pgtable_t;
-
-#define TASK_UNMAPPED_BASE     (test_thread_flag(TIF_32BIT) ? \
-                                (_AC(0x0000000070000000,UL)) : \
-                                (_AC(0xfffff80000000000,UL) + (1UL << 32UL)))
-
-#include <asm-generic/memory_model.h>
-
-#endif /* !(__ASSEMBLY__) */
-
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
-/* We used to stick this into a hard-coded global register (%g4)
- * but that does not make sense anymore.
- */
-#define PAGE_OFFSET            _AC(0xFFFFF80000000000,UL)
-
-#ifndef __ASSEMBLY__
-
-#define __pa(x)                        ((unsigned long)(x) - PAGE_OFFSET)
-#define __va(x)                        ((void *)((unsigned long) (x) + PAGE_OFFSET))
-
-#define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
-
-#define virt_to_page(kaddr)    pfn_to_page(__pa(kaddr)>>PAGE_SHIFT)
-
-#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
-
-#define virt_to_phys __pa
-#define phys_to_virt __va
-
-#endif /* !(__ASSEMBLY__) */
-
-#define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
-                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-#include <asm-generic/page.h>
-
-#endif /* _SPARC64_PAGE_H */
+#include <asm-sparc/page.h>
index f0125cf5a9df7dac55b4ffdb25b150befb6ab048..40c6dc1108220a8d6fd1a9cfcb3278fcda139c52 100644 (file)
@@ -1,23 +1 @@
-#ifndef _ASMSPARC64_PARAM_H
-#define _ASMSPARC64_PARAM_H
-
-
-#ifdef __KERNEL__
-# define HZ            CONFIG_HZ       /* Internal kernel timer frequency */
-# define USER_HZ       100     /* .. some user interfaces are in "ticks" */
-# define CLOCKS_PER_SEC (USER_HZ)
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE  8192    /* Thanks for sun4's we carry baggage... */
-
-#ifndef NOGROUP
-#define NOGROUP                (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64      /* max length of hostname */
-
-#endif /* _ASMSPARC64_PARAM_H */
+#include <asm-sparc/param.h>
index e9555b246c8d0ea909cfa5c9811b844688f42ca2..b4e4ca812eb6253f0aeb899afc78ee2886bc4479 100644 (file)
@@ -1,246 +1 @@
-/* parport.h: sparc64 specific parport initialization and dma.
- *
- * Copyright (C) 1999  Eddie C. Dost  (ecd@skynet.be)
- */
-
-#ifndef _ASM_SPARC64_PARPORT_H
-#define _ASM_SPARC64_PARPORT_H 1
-
-#include <asm/ebus.h>
-#include <asm/ns87303.h>
-#include <asm/of_device.h>
-#include <asm/prom.h>
-
-#define PARPORT_PC_MAX_PORTS   PARPORT_MAX
-
-/*
- * While sparc64 doesn't have an ISA DMA API, we provide something that looks
- * close enough to make parport_pc happy
- */
-#define HAS_DMA
-
-static DEFINE_SPINLOCK(dma_spin_lock);
-
-#define claim_dma_lock() \
-({     unsigned long flags; \
-       spin_lock_irqsave(&dma_spin_lock, flags); \
-       flags; \
-})
-
-#define release_dma_lock(__flags) \
-       spin_unlock_irqrestore(&dma_spin_lock, __flags);
-
-static struct sparc_ebus_info {
-       struct ebus_dma_info info;
-       unsigned int addr;
-       unsigned int count;
-       int lock;
-
-       struct parport *port;
-} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS];
-
-static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS);
-
-static inline int request_dma(unsigned int dmanr, const char *device_id)
-{
-       if (dmanr >= PARPORT_PC_MAX_PORTS)
-               return -EINVAL;
-       if (xchg(&sparc_ebus_dmas[dmanr].lock, 1) != 0)
-               return -EBUSY;
-       return 0;
-}
-
-static inline void free_dma(unsigned int dmanr)
-{
-       if (dmanr >= PARPORT_PC_MAX_PORTS) {
-               printk(KERN_WARNING "Trying to free DMA%d\n", dmanr);
-               return;
-       }
-       if (xchg(&sparc_ebus_dmas[dmanr].lock, 0) == 0) {
-               printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr);
-               return;
-       }       
-}
-
-static inline void enable_dma(unsigned int dmanr)
-{
-       ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);
-
-       if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info,
-                            sparc_ebus_dmas[dmanr].addr,
-                            sparc_ebus_dmas[dmanr].count))
-               BUG();
-}
-
-static inline void disable_dma(unsigned int dmanr)
-{
-       ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0);
-}
-
-static inline void clear_dma_ff(unsigned int dmanr)
-{
-       /* nothing */
-}
-
-static inline void set_dma_mode(unsigned int dmanr, char mode)
-{
-       ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE));
-}
-
-static inline void set_dma_addr(unsigned int dmanr, unsigned int addr)
-{
-       sparc_ebus_dmas[dmanr].addr = addr;
-}
-
-static inline void set_dma_count(unsigned int dmanr, unsigned int count)
-{
-       sparc_ebus_dmas[dmanr].count = count;
-}
-
-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)
-{
-       unsigned long base = op->resource[0].start;
-       unsigned long config = op->resource[1].start;
-       unsigned long d_base = op->resource[2].start;
-       unsigned long d_len;
-       struct device_node *parent;
-       struct parport *p;
-       int slot, err;
-
-       parent = op->node->parent;
-       if (!strcmp(parent->name, "dma")) {
-               p = parport_pc_probe_port(base, base + 0x400,
-                                         op->irqs[0], PARPORT_DMA_NOFIFO,
-                                         op->dev.parent->parent);
-               if (!p)
-                       return -ENOMEM;
-               dev_set_drvdata(&op->dev, p);
-               return 0;
-       }
-
-       for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) {
-               if (!test_and_set_bit(slot, dma_slot_map))
-                       break;
-       }
-       err = -ENODEV;
-       if (slot >= PARPORT_PC_MAX_PORTS)
-               goto out_err;
-
-       spin_lock_init(&sparc_ebus_dmas[slot].info.lock);
-
-       d_len = (op->resource[2].end - d_base) + 1UL;
-       sparc_ebus_dmas[slot].info.regs =
-               of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA");
-
-       if (!sparc_ebus_dmas[slot].info.regs)
-               goto out_clear_map;
-
-       sparc_ebus_dmas[slot].info.flags = 0;
-       sparc_ebus_dmas[slot].info.callback = NULL;
-       sparc_ebus_dmas[slot].info.client_cookie = NULL;
-       sparc_ebus_dmas[slot].info.irq = 0xdeadbeef;
-       strcpy(sparc_ebus_dmas[slot].info.name, "parport");
-       if (ebus_dma_register(&sparc_ebus_dmas[slot].info))
-               goto out_unmap_regs;
-
-       ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1);
-
-       /* Configure IRQ to Push Pull, Level Low */
-       /* Enable ECP, set bit 2 of the CTR first */
-       outb(0x04, base + 0x02);
-       ns87303_modify(config, PCR,
-                      PCR_EPP_ENABLE |
-                      PCR_IRQ_ODRAIN,
-                      PCR_ECP_ENABLE |
-                      PCR_ECP_CLK_ENA |
-                      PCR_IRQ_POLAR);
-
-       /* CTR bit 5 controls direction of port */
-       ns87303_modify(config, PTR,
-                      0, PTR_LPT_REG_DIR);
-
-       p = parport_pc_probe_port(base, base + 0x400,
-                                 op->irqs[0],
-                                 slot,
-                                 op->dev.parent);
-       err = -ENOMEM;
-       if (!p)
-               goto out_disable_irq;
-
-       dev_set_drvdata(&op->dev, p);
-
-       return 0;
-
-out_disable_irq:
-       ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
-       ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
-
-out_unmap_regs:
-       of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len);
-
-out_clear_map:
-       clear_bit(slot, dma_slot_map);
-
-out_err:
-       return err;
-}
-
-static int __devexit ecpp_remove(struct of_device *op)
-{
-       struct parport *p = dev_get_drvdata(&op->dev);
-       int slot = p->dma;
-
-       parport_pc_unregister_port(p);
-
-       if (slot != PARPORT_DMA_NOFIFO) {
-               unsigned long d_base = op->resource[2].start;
-               unsigned long d_len;
-
-               d_len = (op->resource[2].end - d_base) + 1UL;
-
-               ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
-               ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
-               of_iounmap(&op->resource[2],
-                          sparc_ebus_dmas[slot].info.regs,
-                          d_len);
-               clear_bit(slot, dma_slot_map);
-       }
-
-       return 0;
-}
-
-static struct of_device_id ecpp_match[] = {
-       {
-               .name = "ecpp",
-       },
-       {
-               .name = "parallel",
-               .compatible = "ecpp",
-       },
-       {
-               .name = "parallel",
-               .compatible = "ns87317-ecpp",
-       },
-       {},
-};
-
-static struct of_platform_driver ecpp_driver = {
-       .name                   = "ecpp",
-       .match_table            = ecpp_match,
-       .probe                  = ecpp_probe,
-       .remove                 = __devexit_p(ecpp_remove),
-};
-
-static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
-{
-       of_register_driver(&ecpp_driver, &of_bus_type);
-
-       return 0;
-}
-
-#endif /* !(_ASM_SPARC64_PARPORT_H */
+#include <asm-sparc/parport.h>
index f59f2571295b69e8304ba406d54d17d7e6260b49..da54c4d1f39cb5bfa1b6ff364facaa608cb2a5e4 100644 (file)
@@ -1,209 +1 @@
-#ifndef __SPARC64_PCI_H
-#define __SPARC64_PCI_H
-
-#ifdef __KERNEL__
-
-#include <linux/dma-mapping.h>
-
-/* Can be used to override the logic in pci_scan_bus for skipping
- * already-configured bus numbers - to be used for buggy BIOSes
- * or architectures with incomplete PCI setup by the loader.
- */
-#define pcibios_assign_all_busses()    0
-#define pcibios_scan_all_fns(a, b)     0
-
-#define PCIBIOS_MIN_IO         0UL
-#define PCIBIOS_MIN_MEM                0UL
-
-#define PCI_IRQ_NONE           0xffffffff
-
-#define PCI_CACHE_LINE_BYTES   64
-
-static inline void pcibios_set_master(struct pci_dev *dev)
-{
-       /* No special bus mastering setup handling */
-}
-
-static inline void pcibios_penalize_isa_irq(int irq, int active)
-{
-       /* We don't do dynamic PCI IRQ allocation */
-}
-
-/* The PCI address space does not equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS    (0)
-
-static inline void *pci_alloc_consistent(struct pci_dev *pdev, size_t size,
-                                        dma_addr_t *dma_handle)
-{
-       return dma_alloc_coherent(&pdev->dev, size, dma_handle, GFP_ATOMIC);
-}
-
-static inline void pci_free_consistent(struct pci_dev *pdev, size_t size,
-                                      void *vaddr, dma_addr_t dma_handle)
-{
-       return dma_free_coherent(&pdev->dev, size, vaddr, dma_handle);
-}
-
-static inline dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr,
-                                       size_t size, int direction)
-{
-       return dma_map_single(&pdev->dev, ptr, size,
-                             (enum dma_data_direction) direction);
-}
-
-static inline void pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr,
-                                   size_t size, int direction)
-{
-       dma_unmap_single(&pdev->dev, dma_addr, size,
-                        (enum dma_data_direction) direction);
-}
-
-#define pci_map_page(dev, page, off, size, dir) \
-       pci_map_single(dev, (page_address(page) + (off)), size, dir)
-#define pci_unmap_page(dev,addr,sz,dir) \
-       pci_unmap_single(dev,addr,sz,dir)
-
-/* pci_unmap_{single,page} is not a nop, thus... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)      \
-       dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)                \
-       __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME)                 \
-       ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)                \
-       (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME)                   \
-       ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL)          \
-       (((PTR)->LEN_NAME) = (VAL))
-
-static inline int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg,
-                            int nents, int direction)
-{
-       return dma_map_sg(&pdev->dev, sg, nents,
-                         (enum dma_data_direction) direction);
-}
-
-static inline void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg,
-                               int nents, int direction)
-{
-       dma_unmap_sg(&pdev->dev, sg, nents,
-                    (enum dma_data_direction) direction);
-}
-
-static inline void pci_dma_sync_single_for_cpu(struct pci_dev *pdev,
-                                              dma_addr_t dma_handle,
-                                              size_t size, int direction)
-{
-       dma_sync_single_for_cpu(&pdev->dev, dma_handle, size,
-                               (enum dma_data_direction) direction);
-}
-
-static inline void pci_dma_sync_single_for_device(struct pci_dev *pdev,
-                                                 dma_addr_t dma_handle,
-                                                 size_t size, int direction)
-{
-       /* No flushing needed to sync cpu writes to the device.  */
-}
-
-static inline void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev,
-                                          struct scatterlist *sg,
-                                          int nents, int direction)
-{
-       dma_sync_sg_for_cpu(&pdev->dev, sg, nents,
-                           (enum dma_data_direction) direction);
-}
-
-static inline void pci_dma_sync_sg_for_device(struct pci_dev *pdev,
-                                             struct scatterlist *sg,
-                                             int nelems, int direction)
-{
-       /* No flushing needed to sync cpu writes to the device.  */
-}
-
-/* Return whether the given PCI device DMA address mask can
- * be supported properly.  For example, if your device can
- * only drive the low 24-bits during PCI bus mastering, then
- * you would pass 0x00ffffff as the mask to this function.
- */
-extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask);
-
-/* PCI IOMMU mapping bypass support. */
-
-/* PCI 64-bit addressing works for all slots on all controller
- * types on sparc64.  However, it requires that the device
- * can drive enough of the 64 bits.
- */
-#define PCI64_REQUIRED_MASK    (~(dma64_addr_t)0)
-#define PCI64_ADDR_BASE                0xfffc000000000000UL
-
-static inline int pci_dma_mapping_error(dma_addr_t dma_addr)
-{
-       return dma_mapping_error(dma_addr);
-}
-
-#ifdef CONFIG_PCI
-static inline void pci_dma_burst_advice(struct pci_dev *pdev,
-                                       enum pci_dma_burst_strategy *strat,
-                                       unsigned long *strategy_parameter)
-{
-       unsigned long cacheline_size;
-       u8 byte;
-
-       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
-       if (byte == 0)
-               cacheline_size = 1024;
-       else
-               cacheline_size = (int) byte * 4;
-
-       *strat = PCI_DMA_BURST_BOUNDARY;
-       *strategy_parameter = cacheline_size;
-}
-#endif
-
-/* Return the index of the PCI controller for device PDEV. */
-
-extern int pci_domain_nr(struct pci_bus *bus);
-static inline int pci_proc_domain(struct pci_bus *bus)
-{
-       return 1;
-}
-
-/* Platform support for /proc/bus/pci/X/Y mmap()s. */
-
-#define HAVE_PCI_MMAP
-#define HAVE_ARCH_PCI_GET_UNMAPPED_AREA
-#define get_pci_unmapped_area get_fb_unmapped_area
-
-extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
-                              enum pci_mmap_state mmap_state,
-                              int write_combine);
-
-extern void
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-                       struct resource *res);
-
-extern void
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-                       struct pci_bus_region *region);
-
-extern struct resource *pcibios_select_root(struct pci_dev *, struct resource *);
-
-static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
-{
-       return PCI_IRQ_NONE;
-}
-
-struct device_node;
-extern struct device_node *pci_device_to_OF_node(struct pci_dev *pdev);
-
-#define HAVE_ARCH_PCI_RESOURCE_TO_USER
-extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
-                                const struct resource *rsrc,
-                                resource_size_t *start, resource_size_t *end);
-#endif /* __KERNEL__ */
-
-#endif /* __SPARC64_PCI_H */
+#include <asm-sparc/pci.h>
index bee64593023e2f34d0be046dcddd47d5e3167e60..292729bb350f890f4549cb821fd20169127af528 100644 (file)
@@ -1,28 +1 @@
-#ifndef __ARCH_SPARC64_PERCPU__
-#define __ARCH_SPARC64_PERCPU__
-
-#include <linux/compiler.h>
-
-register unsigned long __local_per_cpu_offset asm("g5");
-
-#ifdef CONFIG_SMP
-
-extern void real_setup_per_cpu_areas(void);
-
-extern unsigned long __per_cpu_base;
-extern unsigned long __per_cpu_shift;
-#define __per_cpu_offset(__cpu) \
-       (__per_cpu_base + ((unsigned long)(__cpu) << __per_cpu_shift))
-#define per_cpu_offset(x) (__per_cpu_offset(x))
-
-#define __my_cpu_offset __local_per_cpu_offset
-
-#else /* ! SMP */
-
-#define real_setup_per_cpu_areas()             do { } while (0)
-
-#endif /* SMP */
-
-#include <asm-generic/percpu.h>
-
-#endif /* __ARCH_SPARC64_PERCPU__ */
+#include <asm-sparc/percpu.h>
index 836873002b7515cc92a727447d4b13775ee5202d..52073a9f8e306748531b6bdc9bbe6378181b36ee 100644 (file)
@@ -1,173 +1 @@
-/*----------------------------------------
-  PERFORMANCE INSTRUMENTATION  
-  Guillaume Thouvenin           08/10/98
-  David S. Miller               10/06/98
-  ---------------------------------------*/
-#ifndef PERF_COUNTER_API
-#define PERF_COUNTER_API
-
-/* sys_perfctr() interface.  First arg is operation code
- * from enumeration below.  The meaning of further arguments
- * are determined by the operation code.
- *
- * int sys_perfctr(int opcode, unsigned long arg0,
- *                 unsigned long arg1, unsigned long arg2)
- *
- * Pointers which are passed by the user are pointers to 64-bit
- * integers.
- *
- * Once enabled, performance counter state is retained until the
- * process either exits or performs an exec.  That is, performance
- * counters remain enabled for fork/clone children.
- */
-enum perfctr_opcode {
-       /* Enable UltraSparc performance counters, ARG0 is pointer
-        * to 64-bit accumulator for D0 counter in PIC, ARG1 is pointer
-        * to 64-bit accumulator for D1 counter.  ARG2 is a pointer to
-        * the initial PCR register value to use.
-        */
-       PERFCTR_ON,
-
-       /* Disable UltraSparc performance counters.  The PCR is written
-        * with zero and the user counter accumulator pointers and
-        * working PCR register value are forgotten.
-        */
-       PERFCTR_OFF,
-
-       /* Add current D0 and D1 PIC values into user pointers given
-        * in PERFCTR_ON operation.  The PIC is cleared before returning.
-        */
-       PERFCTR_READ,
-
-       /* Clear the PIC register. */
-       PERFCTR_CLRPIC,
-
-       /* Begin using a new PCR value, the pointer to which is passed
-        * in ARG0.  The PIC is also cleared after the new PCR value is
-        * written.
-        */
-       PERFCTR_SETPCR,
-
-       /* Store in pointer given in ARG0 the current PCR register value
-        * being used.
-        */
-       PERFCTR_GETPCR
-};
-
-/* I don't want the kernel's namespace to be polluted with this
- * stuff when this file is included.  --DaveM
- */
-#ifndef __KERNEL__
-
-#define  PRIV 0x00000001
-#define  SYS  0x00000002
-#define  USR  0x00000004
-
-/* Pic.S0 Selection Bit Field Encoding, Ultra-I/II  */
-#define  CYCLE_CNT            0x00000000
-#define  INSTR_CNT            0x00000010
-#define  DISPATCH0_IC_MISS    0x00000020
-#define  DISPATCH0_STOREBUF   0x00000030
-#define  IC_REF               0x00000080
-#define  DC_RD                0x00000090
-#define  DC_WR                0x000000A0
-#define  LOAD_USE             0x000000B0
-#define  EC_REF               0x000000C0
-#define  EC_WRITE_HIT_RDO     0x000000D0
-#define  EC_SNOOP_INV         0x000000E0
-#define  EC_RD_HIT            0x000000F0
-
-/* Pic.S0 Selection Bit Field Encoding, Ultra-III  */
-#define  US3_CYCLE_CNT         0x00000000
-#define  US3_INSTR_CNT         0x00000010
-#define  US3_DISPATCH0_IC_MISS 0x00000020
-#define  US3_DISPATCH0_BR_TGT  0x00000030
-#define  US3_DISPATCH0_2ND_BR  0x00000040
-#define  US3_RSTALL_STOREQ     0x00000050
-#define  US3_RSTALL_IU_USE     0x00000060
-#define  US3_IC_REF            0x00000080
-#define  US3_DC_RD             0x00000090
-#define  US3_DC_WR             0x000000a0
-#define  US3_EC_REF            0x000000c0
-#define  US3_EC_WR_HIT_RTO     0x000000d0
-#define  US3_EC_SNOOP_INV      0x000000e0
-#define  US3_EC_RD_MISS                0x000000f0
-#define  US3_PC_PORT0_RD       0x00000100
-#define  US3_SI_SNOOP          0x00000110
-#define  US3_SI_CIQ_FLOW       0x00000120
-#define  US3_SI_OWNED          0x00000130
-#define  US3_SW_COUNT_0                0x00000140
-#define  US3_IU_BR_MISS_TAKEN  0x00000150
-#define  US3_IU_BR_COUNT_TAKEN 0x00000160
-#define  US3_DISP_RS_MISPRED   0x00000170
-#define  US3_FA_PIPE_COMPL     0x00000180
-#define  US3_MC_READS_0                0x00000200
-#define  US3_MC_READS_1                0x00000210
-#define  US3_MC_READS_2                0x00000220
-#define  US3_MC_READS_3                0x00000230
-#define  US3_MC_STALLS_0       0x00000240
-#define  US3_MC_STALLS_2       0x00000250
-
-/* Pic.S1 Selection Bit Field Encoding, Ultra-I/II  */
-#define  CYCLE_CNT_D1         0x00000000
-#define  INSTR_CNT_D1         0x00000800
-#define  DISPATCH0_IC_MISPRED 0x00001000
-#define  DISPATCH0_FP_USE     0x00001800
-#define  IC_HIT               0x00004000
-#define  DC_RD_HIT            0x00004800
-#define  DC_WR_HIT            0x00005000
-#define  LOAD_USE_RAW         0x00005800
-#define  EC_HIT               0x00006000
-#define  EC_WB                0x00006800
-#define  EC_SNOOP_CB          0x00007000
-#define  EC_IT_HIT            0x00007800
-
-/* Pic.S1 Selection Bit Field Encoding, Ultra-III  */
-#define  US3_CYCLE_CNT_D1      0x00000000
-#define  US3_INSTR_CNT_D1      0x00000800
-#define  US3_DISPATCH0_MISPRED 0x00001000
-#define  US3_IC_MISS_CANCELLED 0x00001800
-#define  US3_RE_ENDIAN_MISS    0x00002000
-#define  US3_RE_FPU_BYPASS     0x00002800
-#define  US3_RE_DC_MISS                0x00003000
-#define  US3_RE_EC_MISS                0x00003800
-#define  US3_IC_MISS           0x00004000
-#define  US3_DC_RD_MISS                0x00004800
-#define  US3_DC_WR_MISS                0x00005000
-#define  US3_RSTALL_FP_USE     0x00005800
-#define  US3_EC_MISSES         0x00006000
-#define  US3_EC_WB             0x00006800
-#define  US3_EC_SNOOP_CB       0x00007000
-#define  US3_EC_IC_MISS                0x00007800
-#define  US3_RE_PC_MISS                0x00008000
-#define  US3_ITLB_MISS         0x00008800
-#define  US3_DTLB_MISS         0x00009000
-#define  US3_WC_MISS           0x00009800
-#define  US3_WC_SNOOP_CB       0x0000a000
-#define  US3_WC_SCRUBBED       0x0000a800
-#define  US3_WC_WB_WO_READ     0x0000b000
-#define  US3_PC_SOFT_HIT       0x0000c000
-#define  US3_PC_SNOOP_INV      0x0000c800
-#define  US3_PC_HARD_HIT       0x0000d000
-#define  US3_PC_PORT1_RD       0x0000d800
-#define  US3_SW_COUNT_1                0x0000e000
-#define  US3_IU_STAT_BR_MIS_UNTAKEN    0x0000e800
-#define  US3_IU_STAT_BR_COUNT_UNTAKEN  0x0000f000
-#define  US3_PC_MS_MISSES      0x0000f800
-#define  US3_MC_WRITES_0       0x00010800
-#define  US3_MC_WRITES_1       0x00011000
-#define  US3_MC_WRITES_2       0x00011800
-#define  US3_MC_WRITES_3       0x00012000
-#define  US3_MC_STALLS_1       0x00012800
-#define  US3_MC_STALLS_3       0x00013000
-#define  US3_RE_RAW_MISS       0x00013800
-#define  US3_FM_PIPE_COMPLETION        0x00014000
-
-struct vcounter_struct {
-  unsigned long long vcnt0;
-  unsigned long long vcnt1;
-};
-
-#endif /* !(__KERNEL__) */
-
-#endif /* !(PERF_COUNTER_API) */
+#include <asm-sparc/perfctr.h>
index 326de104d0145fa2a40f6abdb3762ca35609ca65..bec31641011c1595ac7d0f78f5b9e2e2313b2380 100644 (file)
@@ -1,81 +1 @@
-#ifndef _SPARC64_PGALLOC_H
-#define _SPARC64_PGALLOC_H
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/quicklist.h>
-
-#include <asm/spitfire.h>
-#include <asm/cpudata.h>
-#include <asm/cacheflush.h>
-#include <asm/page.h>
-
-/* Page table allocation/freeing. */
-
-static inline pgd_t *pgd_alloc(struct mm_struct *mm)
-{
-       return quicklist_alloc(0, GFP_KERNEL, NULL);
-}
-
-static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
-       quicklist_free(0, NULL, pgd);
-}
-
-#define pud_populate(MM, PUD, PMD)     pud_set(PUD, PMD)
-
-static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
-       return quicklist_alloc(0, GFP_KERNEL, NULL);
-}
-
-static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
-{
-       quicklist_free(0, NULL, pmd);
-}
-
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-                                         unsigned long address)
-{
-       return quicklist_alloc(0, GFP_KERNEL, NULL);
-}
-
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
-                                       unsigned long address)
-{
-       struct page *page;
-       void *pg;
-
-       pg = quicklist_alloc(0, GFP_KERNEL, NULL);
-       if (!pg)
-               return NULL;
-       page = virt_to_page(pg);
-       pgtable_page_ctor(page);
-       return page;
-}
-               
-static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
-{
-       quicklist_free(0, NULL, pte);
-}
-
-static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
-{
-       pgtable_page_dtor(ptepage);
-       quicklist_free_page(0, NULL, ptepage);
-}
-
-
-#define pmd_populate_kernel(MM, PMD, PTE)      pmd_set(PMD, PTE)
-#define pmd_populate(MM,PMD,PTE_PAGE)          \
-       pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE))
-#define pmd_pgtable(pmd) pmd_page(pmd)
-
-static inline void check_pgt_cache(void)
-{
-       quicklist_trim(0, NULL, 25, 16);
-}
-
-#endif /* _SPARC64_PGALLOC_H */
+#include <asm-sparc/pgalloc.h>
index b87017747b5d62bab55eaaaf5ab17981325a332e..9decbd99aefff9b59f1ff1c007eb83af3dd1783c 100644 (file)
@@ -1,781 +1 @@
-/*
- * pgtable.h: SpitFire page table operations.
- *
- * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
- * Copyright 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#ifndef _SPARC64_PGTABLE_H
-#define _SPARC64_PGTABLE_H
-
-/* This file contains the functions and defines necessary to modify and use
- * the SpitFire page tables.
- */
-
-#include <asm-generic/pgtable-nopud.h>
-
-#include <linux/compiler.h>
-#include <linux/const.h>
-#include <asm/types.h>
-#include <asm/spitfire.h>
-#include <asm/asi.h>
-#include <asm/system.h>
-#include <asm/page.h>
-#include <asm/processor.h>
-
-/* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB).
- * The page copy blockops can use 0x6000000 to 0x8000000.
- * The TSB is mapped in the 0x8000000 to 0xa000000 range.
- * The PROM resides in an area spanning 0xf0000000 to 0x100000000.
- * The vmalloc area spans 0x100000000 to 0x200000000.
- * Since modules need to be in the lowest 32-bits of the address space,
- * we place them right before the OBP area from 0x10000000 to 0xf0000000.
- * There is a single static kernel PMD which maps from 0x0 to address
- * 0x400000000.
- */
-#define        TLBTEMP_BASE            _AC(0x0000000006000000,UL)
-#define        TSBMAP_BASE             _AC(0x0000000008000000,UL)
-#define MODULES_VADDR          _AC(0x0000000010000000,UL)
-#define MODULES_LEN            _AC(0x00000000e0000000,UL)
-#define MODULES_END            _AC(0x00000000f0000000,UL)
-#define LOW_OBP_ADDRESS                _AC(0x00000000f0000000,UL)
-#define HI_OBP_ADDRESS         _AC(0x0000000100000000,UL)
-#define VMALLOC_START          _AC(0x0000000100000000,UL)
-#define VMALLOC_END            _AC(0x0000000200000000,UL)
-#define VMEMMAP_BASE           _AC(0x0000000200000000,UL)
-
-#define vmemmap                        ((struct page *)VMEMMAP_BASE)
-
-/* XXX All of this needs to be rethought so we can take advantage
- * XXX cheetah's full 64-bit virtual address space, ie. no more hole
- * XXX in the middle like on spitfire. -DaveM
- */
-/*
- * Given a virtual address, the lowest PAGE_SHIFT bits determine offset
- * into the page; the next higher PAGE_SHIFT-3 bits determine the pte#
- * in the proper pagetable (the -3 is from the 8 byte ptes, and each page
- * table is a single page long). The next higher PMD_BITS determine pmd# 
- * in the proper pmdtable (where we must have PMD_BITS <= (PAGE_SHIFT-2) 
- * since the pmd entries are 4 bytes, and each pmd page is a single page 
- * long). Finally, the higher few bits determine pgde#.
- */
-
-/* PMD_SHIFT determines the size of the area a second-level page
- * table can map
- */
-#define PMD_SHIFT      (PAGE_SHIFT + (PAGE_SHIFT-3))
-#define PMD_SIZE       (_AC(1,UL) << PMD_SHIFT)
-#define PMD_MASK       (~(PMD_SIZE-1))
-#define PMD_BITS       (PAGE_SHIFT - 2)
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT    (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS)
-#define PGDIR_SIZE     (_AC(1,UL) << PGDIR_SHIFT)
-#define PGDIR_MASK     (~(PGDIR_SIZE-1))
-#define PGDIR_BITS     (PAGE_SHIFT - 2)
-
-#ifndef __ASSEMBLY__
-
-#include <linux/sched.h>
-
-/* Entries per page directory level. */
-#define PTRS_PER_PTE   (1UL << (PAGE_SHIFT-3))
-#define PTRS_PER_PMD   (1UL << PMD_BITS)
-#define PTRS_PER_PGD   (1UL << PGDIR_BITS)
-
-/* Kernel has a separate 44bit address space. */
-#define FIRST_USER_ADDRESS     0
-
-#define pte_ERROR(e)   __builtin_trap()
-#define pmd_ERROR(e)   __builtin_trap()
-#define pgd_ERROR(e)   __builtin_trap()
-
-#endif /* !(__ASSEMBLY__) */
-
-/* PTE bits which are the same in SUN4U and SUN4V format.  */
-#define _PAGE_VALID      _AC(0x8000000000000000,UL) /* Valid TTE            */
-#define _PAGE_R                  _AC(0x8000000000000000,UL) /* Keep ref bit uptodate*/
-
-/* SUN4U pte bits... */
-#define _PAGE_SZ4MB_4U   _AC(0x6000000000000000,UL) /* 4MB Page             */
-#define _PAGE_SZ512K_4U          _AC(0x4000000000000000,UL) /* 512K Page            */
-#define _PAGE_SZ64K_4U   _AC(0x2000000000000000,UL) /* 64K Page             */
-#define _PAGE_SZ8K_4U    _AC(0x0000000000000000,UL) /* 8K Page              */
-#define _PAGE_NFO_4U     _AC(0x1000000000000000,UL) /* No Fault Only        */
-#define _PAGE_IE_4U      _AC(0x0800000000000000,UL) /* Invert Endianness    */
-#define _PAGE_SOFT2_4U   _AC(0x07FC000000000000,UL) /* Software bits, set 2 */
-#define _PAGE_RES1_4U    _AC(0x0002000000000000,UL) /* Reserved             */
-#define _PAGE_SZ32MB_4U          _AC(0x0001000000000000,UL) /* (Panther) 32MB page  */
-#define _PAGE_SZ256MB_4U  _AC(0x2001000000000000,UL) /* (Panther) 256MB page */
-#define _PAGE_SZALL_4U   _AC(0x6001000000000000,UL) /* All pgsz bits        */
-#define _PAGE_SN_4U      _AC(0x0000800000000000,UL) /* (Cheetah) Snoop      */
-#define _PAGE_RES2_4U    _AC(0x0000780000000000,UL) /* Reserved             */
-#define _PAGE_PADDR_4U   _AC(0x000007FFFFFFE000,UL) /* (Cheetah) pa[42:13]  */
-#define _PAGE_SOFT_4U    _AC(0x0000000000001F80,UL) /* Software bits:       */
-#define _PAGE_EXEC_4U    _AC(0x0000000000001000,UL) /* Executable SW bit    */
-#define _PAGE_MODIFIED_4U _AC(0x0000000000000800,UL) /* Modified (dirty)     */
-#define _PAGE_FILE_4U    _AC(0x0000000000000800,UL) /* Pagecache page       */
-#define _PAGE_ACCESSED_4U _AC(0x0000000000000400,UL) /* Accessed (ref'd)     */
-#define _PAGE_READ_4U    _AC(0x0000000000000200,UL) /* Readable SW Bit      */
-#define _PAGE_WRITE_4U   _AC(0x0000000000000100,UL) /* Writable SW Bit      */
-#define _PAGE_PRESENT_4U  _AC(0x0000000000000080,UL) /* Present              */
-#define _PAGE_L_4U       _AC(0x0000000000000040,UL) /* Locked TTE           */
-#define _PAGE_CP_4U      _AC(0x0000000000000020,UL) /* Cacheable in P-Cache */
-#define _PAGE_CV_4U      _AC(0x0000000000000010,UL) /* Cacheable in V-Cache */
-#define _PAGE_E_4U       _AC(0x0000000000000008,UL) /* side-Effect          */
-#define _PAGE_P_4U       _AC(0x0000000000000004,UL) /* Privileged Page      */
-#define _PAGE_W_4U       _AC(0x0000000000000002,UL) /* Writable             */
-
-/* SUN4V pte bits... */
-#define _PAGE_NFO_4V     _AC(0x4000000000000000,UL) /* No Fault Only        */
-#define _PAGE_SOFT2_4V   _AC(0x3F00000000000000,UL) /* Software bits, set 2 */
-#define _PAGE_MODIFIED_4V _AC(0x2000000000000000,UL) /* Modified (dirty)     */
-#define _PAGE_ACCESSED_4V _AC(0x1000000000000000,UL) /* Accessed (ref'd)     */
-#define _PAGE_READ_4V    _AC(0x0800000000000000,UL) /* Readable SW Bit      */
-#define _PAGE_WRITE_4V   _AC(0x0400000000000000,UL) /* Writable SW Bit      */
-#define _PAGE_PADDR_4V   _AC(0x00FFFFFFFFFFE000,UL) /* paddr[55:13]         */
-#define _PAGE_IE_4V      _AC(0x0000000000001000,UL) /* Invert Endianness    */
-#define _PAGE_E_4V       _AC(0x0000000000000800,UL) /* side-Effect          */
-#define _PAGE_CP_4V      _AC(0x0000000000000400,UL) /* Cacheable in P-Cache */
-#define _PAGE_CV_4V      _AC(0x0000000000000200,UL) /* Cacheable in V-Cache */
-#define _PAGE_P_4V       _AC(0x0000000000000100,UL) /* Privileged Page      */
-#define _PAGE_EXEC_4V    _AC(0x0000000000000080,UL) /* Executable Page      */
-#define _PAGE_W_4V       _AC(0x0000000000000040,UL) /* Writable             */
-#define _PAGE_SOFT_4V    _AC(0x0000000000000030,UL) /* Software bits        */
-#define _PAGE_FILE_4V    _AC(0x0000000000000020,UL) /* Pagecache page       */
-#define _PAGE_PRESENT_4V  _AC(0x0000000000000010,UL) /* Present              */
-#define _PAGE_RESV_4V    _AC(0x0000000000000008,UL) /* Reserved             */
-#define _PAGE_SZ16GB_4V          _AC(0x0000000000000007,UL) /* 16GB Page            */
-#define _PAGE_SZ2GB_4V   _AC(0x0000000000000006,UL) /* 2GB Page             */
-#define _PAGE_SZ256MB_4V  _AC(0x0000000000000005,UL) /* 256MB Page           */
-#define _PAGE_SZ32MB_4V          _AC(0x0000000000000004,UL) /* 32MB Page            */
-#define _PAGE_SZ4MB_4V   _AC(0x0000000000000003,UL) /* 4MB Page             */
-#define _PAGE_SZ512K_4V          _AC(0x0000000000000002,UL) /* 512K Page            */
-#define _PAGE_SZ64K_4V   _AC(0x0000000000000001,UL) /* 64K Page             */
-#define _PAGE_SZ8K_4V    _AC(0x0000000000000000,UL) /* 8K Page              */
-#define _PAGE_SZALL_4V   _AC(0x0000000000000007,UL) /* All pgsz bits        */
-
-#if PAGE_SHIFT == 13
-#define _PAGE_SZBITS_4U        _PAGE_SZ8K_4U
-#define _PAGE_SZBITS_4V        _PAGE_SZ8K_4V
-#elif PAGE_SHIFT == 16
-#define _PAGE_SZBITS_4U        _PAGE_SZ64K_4U
-#define _PAGE_SZBITS_4V        _PAGE_SZ64K_4V
-#elif PAGE_SHIFT == 19
-#define _PAGE_SZBITS_4U        _PAGE_SZ512K_4U
-#define _PAGE_SZBITS_4V        _PAGE_SZ512K_4V
-#elif PAGE_SHIFT == 22
-#define _PAGE_SZBITS_4U        _PAGE_SZ4MB_4U
-#define _PAGE_SZBITS_4V        _PAGE_SZ4MB_4V
-#else
-#error Wrong PAGE_SHIFT specified
-#endif
-
-#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
-#define _PAGE_SZHUGE_4U        _PAGE_SZ4MB_4U
-#define _PAGE_SZHUGE_4V        _PAGE_SZ4MB_4V
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
-#define _PAGE_SZHUGE_4U        _PAGE_SZ512K_4U
-#define _PAGE_SZHUGE_4V        _PAGE_SZ512K_4V
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
-#define _PAGE_SZHUGE_4U        _PAGE_SZ64K_4U
-#define _PAGE_SZHUGE_4V        _PAGE_SZ64K_4V
-#endif
-
-/* These are actually filled in at boot time by sun4{u,v}_pgprot_init() */
-#define __P000 __pgprot(0)
-#define __P001 __pgprot(0)
-#define __P010 __pgprot(0)
-#define __P011 __pgprot(0)
-#define __P100 __pgprot(0)
-#define __P101 __pgprot(0)
-#define __P110 __pgprot(0)
-#define __P111 __pgprot(0)
-
-#define __S000 __pgprot(0)
-#define __S001 __pgprot(0)
-#define __S010 __pgprot(0)
-#define __S011 __pgprot(0)
-#define __S100 __pgprot(0)
-#define __S101 __pgprot(0)
-#define __S110 __pgprot(0)
-#define __S111 __pgprot(0)
-
-#ifndef __ASSEMBLY__
-
-extern pte_t mk_pte_io(unsigned long, pgprot_t, int, unsigned long);
-
-extern unsigned long pte_sz_bits(unsigned long size);
-
-extern pgprot_t PAGE_KERNEL;
-extern pgprot_t PAGE_KERNEL_LOCKED;
-extern pgprot_t PAGE_COPY;
-extern pgprot_t PAGE_SHARED;
-
-/* XXX This uglyness is for the atyfb driver's sparc mmap() support. XXX */
-extern unsigned long _PAGE_IE;
-extern unsigned long _PAGE_E;
-extern unsigned long _PAGE_CACHE;
-
-extern unsigned long pg_iobits;
-extern unsigned long _PAGE_ALL_SZ_BITS;
-extern unsigned long _PAGE_SZBITS;
-
-extern struct page *mem_map_zero;
-#define ZERO_PAGE(vaddr)       (mem_map_zero)
-
-/* PFNs are real physical page numbers.  However, mem_map only begins to record
- * per-page information starting at pfn_base.  This is to handle systems where
- * the first physical page in the machine is at some huge physical address,
- * such as 4GB.   This is common on a partitioned E10000, for example.
- */
-static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
-{
-       unsigned long paddr = pfn << PAGE_SHIFT;
-       unsigned long sz_bits;
-
-       sz_bits = 0UL;
-       if (_PAGE_SZBITS_4U != 0UL || _PAGE_SZBITS_4V != 0UL) {
-               __asm__ __volatile__(
-               "\n661: sethi           %%uhi(%1), %0\n"
-               "       sllx            %0, 32, %0\n"
-               "       .section        .sun4v_2insn_patch, \"ax\"\n"
-               "       .word           661b\n"
-               "       mov             %2, %0\n"
-               "       nop\n"
-               "       .previous\n"
-               : "=r" (sz_bits)
-               : "i" (_PAGE_SZBITS_4U), "i" (_PAGE_SZBITS_4V));
-       }
-       return __pte(paddr | sz_bits | pgprot_val(prot));
-}
-#define mk_pte(page, pgprot)   pfn_pte(page_to_pfn(page), (pgprot))
-
-/* This one can be done with two shifts.  */
-static inline unsigned long pte_pfn(pte_t pte)
-{
-       unsigned long ret;
-
-       __asm__ __volatile__(
-       "\n661: sllx            %1, %2, %0\n"
-       "       srlx            %0, %3, %0\n"
-       "       .section        .sun4v_2insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       sllx            %1, %4, %0\n"
-       "       srlx            %0, %5, %0\n"
-       "       .previous\n"
-       : "=r" (ret)
-       : "r" (pte_val(pte)),
-         "i" (21), "i" (21 + PAGE_SHIFT),
-         "i" (8), "i" (8 + PAGE_SHIFT));
-
-       return ret;
-}
-#define pte_page(x) pfn_to_page(pte_pfn(x))
-
-static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
-{
-       unsigned long mask, tmp;
-
-       /* SUN4U: 0x600307ffffffecb8 (negated == 0x9ffcf80000001347)
-        * SUN4V: 0x30ffffffffffee17 (negated == 0xcf000000000011e8)
-        *
-        * Even if we use negation tricks the result is still a 6
-        * instruction sequence, so don't try to play fancy and just
-        * do the most straightforward implementation.
-        *
-        * Note: We encode this into 3 sun4v 2-insn patch sequences.
-        */
-
-       __asm__ __volatile__(
-       "\n661: sethi           %%uhi(%2), %1\n"
-       "       sethi           %%hi(%2), %0\n"
-       "\n662: or              %1, %%ulo(%2), %1\n"
-       "       or              %0, %%lo(%2), %0\n"
-       "\n663: sllx            %1, 32, %1\n"
-       "       or              %0, %1, %0\n"
-       "       .section        .sun4v_2insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       sethi           %%uhi(%3), %1\n"
-       "       sethi           %%hi(%3), %0\n"
-       "       .word           662b\n"
-       "       or              %1, %%ulo(%3), %1\n"
-       "       or              %0, %%lo(%3), %0\n"
-       "       .word           663b\n"
-       "       sllx            %1, 32, %1\n"
-       "       or              %0, %1, %0\n"
-       "       .previous\n"
-       : "=r" (mask), "=r" (tmp)
-       : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
-              _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U |
-              _PAGE_SZBITS_4U),
-         "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
-              _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V |
-              _PAGE_SZBITS_4V));
-
-       return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
-}
-
-static inline pte_t pgoff_to_pte(unsigned long off)
-{
-       off <<= PAGE_SHIFT;
-
-       __asm__ __volatile__(
-       "\n661: or              %0, %2, %0\n"
-       "       .section        .sun4v_1insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       or              %0, %3, %0\n"
-       "       .previous\n"
-       : "=r" (off)
-       : "0" (off), "i" (_PAGE_FILE_4U), "i" (_PAGE_FILE_4V));
-
-       return __pte(off);
-}
-
-static inline pgprot_t pgprot_noncached(pgprot_t prot)
-{
-       unsigned long val = pgprot_val(prot);
-
-       __asm__ __volatile__(
-       "\n661: andn            %0, %2, %0\n"
-       "       or              %0, %3, %0\n"
-       "       .section        .sun4v_2insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       andn            %0, %4, %0\n"
-       "       or              %0, %5, %0\n"
-       "       .previous\n"
-       : "=r" (val)
-       : "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U),
-                    "i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V));
-
-       return __pgprot(val);
-}
-/* Various pieces of code check for platform support by ifdef testing
- * on "pgprot_noncached".  That's broken and should be fixed, but for
- * now...
- */
-#define pgprot_noncached pgprot_noncached
-
-#ifdef CONFIG_HUGETLB_PAGE
-static inline pte_t pte_mkhuge(pte_t pte)
-{
-       unsigned long mask;
-
-       __asm__ __volatile__(
-       "\n661: sethi           %%uhi(%1), %0\n"
-       "       sllx            %0, 32, %0\n"
-       "       .section        .sun4v_2insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       mov             %2, %0\n"
-       "       nop\n"
-       "       .previous\n"
-       : "=r" (mask)
-       : "i" (_PAGE_SZHUGE_4U), "i" (_PAGE_SZHUGE_4V));
-
-       return __pte(pte_val(pte) | mask);
-}
-#endif
-
-static inline pte_t pte_mkdirty(pte_t pte)
-{
-       unsigned long val = pte_val(pte), tmp;
-
-       __asm__ __volatile__(
-       "\n661: or              %0, %3, %0\n"
-       "       nop\n"
-       "\n662: nop\n"
-       "       nop\n"
-       "       .section        .sun4v_2insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       sethi           %%uhi(%4), %1\n"
-       "       sllx            %1, 32, %1\n"
-       "       .word           662b\n"
-       "       or              %1, %%lo(%4), %1\n"
-       "       or              %0, %1, %0\n"
-       "       .previous\n"
-       : "=r" (val), "=r" (tmp)
-       : "0" (val), "i" (_PAGE_MODIFIED_4U | _PAGE_W_4U),
-         "i" (_PAGE_MODIFIED_4V | _PAGE_W_4V));
-
-       return __pte(val);
-}
-
-static inline pte_t pte_mkclean(pte_t pte)
-{
-       unsigned long val = pte_val(pte), tmp;
-
-       __asm__ __volatile__(
-       "\n661: andn            %0, %3, %0\n"
-       "       nop\n"
-       "\n662: nop\n"
-       "       nop\n"
-       "       .section        .sun4v_2insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       sethi           %%uhi(%4), %1\n"
-       "       sllx            %1, 32, %1\n"
-       "       .word           662b\n"
-       "       or              %1, %%lo(%4), %1\n"
-       "       andn            %0, %1, %0\n"
-       "       .previous\n"
-       : "=r" (val), "=r" (tmp)
-       : "0" (val), "i" (_PAGE_MODIFIED_4U | _PAGE_W_4U),
-         "i" (_PAGE_MODIFIED_4V | _PAGE_W_4V));
-
-       return __pte(val);
-}
-
-static inline pte_t pte_mkwrite(pte_t pte)
-{
-       unsigned long val = pte_val(pte), mask;
-
-       __asm__ __volatile__(
-       "\n661: mov             %1, %0\n"
-       "       nop\n"
-       "       .section        .sun4v_2insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       sethi           %%uhi(%2), %0\n"
-       "       sllx            %0, 32, %0\n"
-       "       .previous\n"
-       : "=r" (mask)
-       : "i" (_PAGE_WRITE_4U), "i" (_PAGE_WRITE_4V));
-
-       return __pte(val | mask);
-}
-
-static inline pte_t pte_wrprotect(pte_t pte)
-{
-       unsigned long val = pte_val(pte), tmp;
-
-       __asm__ __volatile__(
-       "\n661: andn            %0, %3, %0\n"
-       "       nop\n"
-       "\n662: nop\n"
-       "       nop\n"
-       "       .section        .sun4v_2insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       sethi           %%uhi(%4), %1\n"
-       "       sllx            %1, 32, %1\n"
-       "       .word           662b\n"
-       "       or              %1, %%lo(%4), %1\n"
-       "       andn            %0, %1, %0\n"
-       "       .previous\n"
-       : "=r" (val), "=r" (tmp)
-       : "0" (val), "i" (_PAGE_WRITE_4U | _PAGE_W_4U),
-         "i" (_PAGE_WRITE_4V | _PAGE_W_4V));
-
-       return __pte(val);
-}
-
-static inline pte_t pte_mkold(pte_t pte)
-{
-       unsigned long mask;
-
-       __asm__ __volatile__(
-       "\n661: mov             %1, %0\n"
-       "       nop\n"
-       "       .section        .sun4v_2insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       sethi           %%uhi(%2), %0\n"
-       "       sllx            %0, 32, %0\n"
-       "       .previous\n"
-       : "=r" (mask)
-       : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V));
-
-       mask |= _PAGE_R;
-
-       return __pte(pte_val(pte) & ~mask);
-}
-
-static inline pte_t pte_mkyoung(pte_t pte)
-{
-       unsigned long mask;
-
-       __asm__ __volatile__(
-       "\n661: mov             %1, %0\n"
-       "       nop\n"
-       "       .section        .sun4v_2insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       sethi           %%uhi(%2), %0\n"
-       "       sllx            %0, 32, %0\n"
-       "       .previous\n"
-       : "=r" (mask)
-       : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V));
-
-       mask |= _PAGE_R;
-
-       return __pte(pte_val(pte) | mask);
-}
-
-static inline pte_t pte_mkspecial(pte_t pte)
-{
-       return pte;
-}
-
-static inline unsigned long pte_young(pte_t pte)
-{
-       unsigned long mask;
-
-       __asm__ __volatile__(
-       "\n661: mov             %1, %0\n"
-       "       nop\n"
-       "       .section        .sun4v_2insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       sethi           %%uhi(%2), %0\n"
-       "       sllx            %0, 32, %0\n"
-       "       .previous\n"
-       : "=r" (mask)
-       : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V));
-
-       return (pte_val(pte) & mask);
-}
-
-static inline unsigned long pte_dirty(pte_t pte)
-{
-       unsigned long mask;
-
-       __asm__ __volatile__(
-       "\n661: mov             %1, %0\n"
-       "       nop\n"
-       "       .section        .sun4v_2insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       sethi           %%uhi(%2), %0\n"
-       "       sllx            %0, 32, %0\n"
-       "       .previous\n"
-       : "=r" (mask)
-       : "i" (_PAGE_MODIFIED_4U), "i" (_PAGE_MODIFIED_4V));
-
-       return (pte_val(pte) & mask);
-}
-
-static inline unsigned long pte_write(pte_t pte)
-{
-       unsigned long mask;
-
-       __asm__ __volatile__(
-       "\n661: mov             %1, %0\n"
-       "       nop\n"
-       "       .section        .sun4v_2insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       sethi           %%uhi(%2), %0\n"
-       "       sllx            %0, 32, %0\n"
-       "       .previous\n"
-       : "=r" (mask)
-       : "i" (_PAGE_WRITE_4U), "i" (_PAGE_WRITE_4V));
-
-       return (pte_val(pte) & mask);
-}
-
-static inline unsigned long pte_exec(pte_t pte)
-{
-       unsigned long mask;
-
-       __asm__ __volatile__(
-       "\n661: sethi           %%hi(%1), %0\n"
-       "       .section        .sun4v_1insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       mov             %2, %0\n"
-       "       .previous\n"
-       : "=r" (mask)
-       : "i" (_PAGE_EXEC_4U), "i" (_PAGE_EXEC_4V));
-
-       return (pte_val(pte) & mask);
-}
-
-static inline unsigned long pte_file(pte_t pte)
-{
-       unsigned long val = pte_val(pte);
-
-       __asm__ __volatile__(
-       "\n661: and             %0, %2, %0\n"
-       "       .section        .sun4v_1insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       and             %0, %3, %0\n"
-       "       .previous\n"
-       : "=r" (val)
-       : "0" (val), "i" (_PAGE_FILE_4U), "i" (_PAGE_FILE_4V));
-
-       return val;
-}
-
-static inline unsigned long pte_present(pte_t pte)
-{
-       unsigned long val = pte_val(pte);
-
-       __asm__ __volatile__(
-       "\n661: and             %0, %2, %0\n"
-       "       .section        .sun4v_1insn_patch, \"ax\"\n"
-       "       .word           661b\n"
-       "       and             %0, %3, %0\n"
-       "       .previous\n"
-       : "=r" (val)
-       : "0" (val), "i" (_PAGE_PRESENT_4U), "i" (_PAGE_PRESENT_4V));
-
-       return val;
-}
-
-static inline int pte_special(pte_t pte)
-{
-       return 0;
-}
-
-#define pmd_set(pmdp, ptep)    \
-       (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL))
-#define pud_set(pudp, pmdp)    \
-       (pud_val(*(pudp)) = (__pa((unsigned long) (pmdp)) >> 11UL))
-#define __pmd_page(pmd)                \
-       ((unsigned long) __va((((unsigned long)pmd_val(pmd))<<11UL)))
-#define pmd_page(pmd)                  virt_to_page((void *)__pmd_page(pmd))
-#define pud_page_vaddr(pud)            \
-       ((unsigned long) __va((((unsigned long)pud_val(pud))<<11UL)))
-#define pud_page(pud)                  virt_to_page((void *)pud_page_vaddr(pud))
-#define pmd_none(pmd)                  (!pmd_val(pmd))
-#define pmd_bad(pmd)                   (0)
-#define pmd_present(pmd)               (pmd_val(pmd) != 0U)
-#define pmd_clear(pmdp)                        (pmd_val(*(pmdp)) = 0U)
-#define pud_none(pud)                  (!pud_val(pud))
-#define pud_bad(pud)                   (0)
-#define pud_present(pud)               (pud_val(pud) != 0U)
-#define pud_clear(pudp)                        (pud_val(*(pudp)) = 0U)
-
-/* Same in both SUN4V and SUN4U.  */
-#define pte_none(pte)                  (!pte_val(pte))
-
-/* to find an entry in a page-table-directory. */
-#define pgd_index(address)     (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
-#define pgd_offset(mm, address)        ((mm)->pgd + pgd_index(address))
-
-/* to find an entry in a kernel page-table-directory */
-#define pgd_offset_k(address) pgd_offset(&init_mm, address)
-
-/* Find an entry in the second-level page table.. */
-#define pmd_offset(pudp, address)      \
-       ((pmd_t *) pud_page_vaddr(*(pudp)) + \
-        (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)))
-
-/* Find an entry in the third-level page table.. */
-#define pte_index(dir, address)        \
-       ((pte_t *) __pmd_page(*(dir)) + \
-        ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
-#define pte_offset_kernel              pte_index
-#define pte_offset_map                 pte_index
-#define pte_offset_map_nested          pte_index
-#define pte_unmap(pte)                 do { } while (0)
-#define pte_unmap_nested(pte)          do { } while (0)
-
-/* Actual page table PTE updates.  */
-extern void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig);
-
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
-{
-       pte_t orig = *ptep;
-
-       *ptep = pte;
-
-       /* It is more efficient to let flush_tlb_kernel_range()
-        * handle init_mm tlb flushes.
-        *
-        * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
-        *             and SUN4V pte layout, so this inline test is fine.
-        */
-       if (likely(mm != &init_mm) && (pte_val(orig) & _PAGE_VALID))
-               tlb_batch_add(mm, addr, ptep, orig);
-}
-
-#define pte_clear(mm,addr,ptep)                \
-       set_pte_at((mm), (addr), (ptep), __pte(0UL))
-
-#ifdef DCACHE_ALIASING_POSSIBLE
-#define __HAVE_ARCH_MOVE_PTE
-#define move_pte(pte, prot, old_addr, new_addr)                                \
-({                                                                     \
-       pte_t newpte = (pte);                                           \
-       if (tlb_type != hypervisor && pte_present(pte)) {               \
-               unsigned long this_pfn = pte_pfn(pte);                  \
-                                                                       \
-               if (pfn_valid(this_pfn) &&                              \
-                   (((old_addr) ^ (new_addr)) & (1 << 13)))            \
-                       flush_dcache_page_all(current->mm,              \
-                                             pfn_to_page(this_pfn));   \
-       }                                                               \
-       newpte;                                                         \
-})
-#endif
-
-extern pgd_t swapper_pg_dir[2048];
-extern pmd_t swapper_low_pmd_dir[2048];
-
-extern void paging_init(void);
-extern unsigned long find_ecache_flush_span(unsigned long size);
-
-/* These do nothing with the way I have things setup. */
-#define mmu_lockarea(vaddr, len)               (vaddr)
-#define mmu_unlockarea(vaddr, len)             do { } while(0)
-
-struct vm_area_struct;
-extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
-
-/* Encode and de-code a swap entry */
-#define __swp_type(entry)      (((entry).val >> PAGE_SHIFT) & 0xffUL)
-#define __swp_offset(entry)    ((entry).val >> (PAGE_SHIFT + 8UL))
-#define __swp_entry(type, offset)      \
-       ( (swp_entry_t) \
-         { \
-               (((long)(type) << PAGE_SHIFT) | \
-                 ((long)(offset) << (PAGE_SHIFT + 8UL))) \
-         } )
-#define __pte_to_swp_entry(pte)                ((swp_entry_t) { pte_val(pte) })
-#define __swp_entry_to_pte(x)          ((pte_t) { (x).val })
-
-/* File offset in PTE support. */
-extern unsigned long pte_file(pte_t);
-#define pte_to_pgoff(pte)      (pte_val(pte) >> PAGE_SHIFT)
-extern pte_t pgoff_to_pte(unsigned long);
-#define PTE_FILE_MAX_BITS      (64UL - PAGE_SHIFT - 1UL)
-
-extern unsigned long *sparc64_valid_addr_bitmap;
-
-/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
-#define kern_addr_valid(addr)  \
-       (test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap))
-
-extern int page_in_phys_avail(unsigned long paddr);
-
-extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
-                              unsigned long pfn,
-                              unsigned long size, pgprot_t prot);
-
-/*
- * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
- * its high 4 bits.  These macros/functions put it there or get it from there.
- */
-#define MK_IOSPACE_PFN(space, pfn)     (pfn | (space << (BITS_PER_LONG - 4)))
-#define GET_IOSPACE(pfn)               (pfn >> (BITS_PER_LONG - 4))
-#define GET_PFN(pfn)                   (pfn & 0x0fffffffffffffffUL)
-
-#include <asm-generic/pgtable.h>
-
-/* We provide our own get_unmapped_area to cope with VA holes and
- * SHM area cache aliasing for userland.
- */
-#define HAVE_ARCH_UNMAPPED_AREA
-#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
-
-/* We provide a special get_unmapped_area for framebuffer mmaps to try and use
- * the largest alignment possible such that larget PTEs can be used.
- */
-extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long,
-                                         unsigned long, unsigned long,
-                                         unsigned long);
-#define HAVE_ARCH_FB_UNMAPPED_AREA
-
-extern void pgtable_cache_init(void);
-extern void sun4v_register_fault_status(void);
-extern void sun4v_ktsb_register(void);
-extern void __init cheetah_ecache_flush_init(void);
-extern void sun4v_patch_tlb_handlers(void);
-
-extern unsigned long cmdline_memory_size;
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(_SPARC64_PGTABLE_H) */
+#include <asm-sparc/pgtable.h>
index eaac842d88c39fc646614ee9fd6e1cc6eaee3555..d805f33f1e0fba9d729eb229225bf3b57a548dc9 100644 (file)
@@ -1,21 +1 @@
-#ifndef _SPARC64_PIL_H
-#define _SPARC64_PIL_H
-
-/* To avoid some locking problems, we hard allocate certain PILs
- * for SMP cross call messages that must do a etrap/rtrap.
- *
- * A local_irq_disable() does not block the cross call delivery, so
- * when SMP locking is an issue we reschedule the event into a PIL
- * interrupt which is blocked by local_irq_disable().
- *
- * In fact any XCALL which has to etrap/rtrap has a problem because
- * it is difficult to prevent rtrap from running BH's, and that would
- * need to be done if the XCALL arrived while %pil==15.
- */
-#define PIL_SMP_CALL_FUNC      1
-#define PIL_SMP_RECEIVE_SIGNAL 2
-#define PIL_SMP_CAPTURE                3
-#define PIL_SMP_CTX_NEW_VERSION        4
-#define PIL_DEVICE_IRQ         5
-
-#endif /* !(_SPARC64_PIL_H) */
+#include <asm-sparc/pil.h>
index ebeeb3816c40397bfdd66e03126c1bf13dbdc8ff..8e2f31b4641ac6bc6082ea3a5c0787863658395c 100644 (file)
@@ -1,12 +1 @@
-#ifndef __SPARC64_POLL_H
-#define __SPARC64_POLL_H
-
-#define POLLWRNORM     POLLOUT
-#define POLLWRBAND     256
-#define POLLMSG                512
-#define POLLREMOVE     1024
-#define POLLRDHUP       2048
-
-#include <asm-generic/poll.h>
-
-#endif
+#include <asm-sparc/poll.h>
index 4eaaa0196636ebd91c5a8255cd38d611fc8a4502..8cee99200232c9d277f857988db654abb277cdf6 100644 (file)
@@ -1,122 +1 @@
-#ifndef __ARCH_SPARC64_POSIX_TYPES_H
-#define __ARCH_SPARC64_POSIX_TYPES_H
-
-/*
- * This file is generally used by user-level software, so you need to
- * be a little careful about namespace pollution etc.  Also, we cannot
- * assume GCC is being used.
- */
-
-typedef unsigned long          __kernel_size_t;
-typedef long                   __kernel_ssize_t;
-typedef long                   __kernel_ptrdiff_t;
-typedef long                   __kernel_time_t;
-typedef long                   __kernel_clock_t;
-typedef int                    __kernel_pid_t;
-typedef int                    __kernel_ipc_pid_t;
-typedef unsigned int           __kernel_uid_t;
-typedef unsigned int           __kernel_gid_t;
-typedef unsigned long          __kernel_ino_t;
-typedef unsigned int           __kernel_mode_t;
-typedef unsigned short         __kernel_umode_t;
-typedef unsigned int           __kernel_nlink_t;
-typedef int                    __kernel_daddr_t;
-typedef long                   __kernel_off_t;
-typedef char *                 __kernel_caddr_t;
-typedef unsigned short        __kernel_uid16_t;
-typedef unsigned short        __kernel_gid16_t;
-typedef int                    __kernel_clockid_t;
-typedef int                    __kernel_timer_t;
-
-typedef unsigned short                __kernel_old_uid_t;
-typedef unsigned short         __kernel_old_gid_t;
-typedef __kernel_uid_t        __kernel_uid32_t;
-typedef __kernel_gid_t        __kernel_gid32_t;
-
-typedef unsigned int          __kernel_old_dev_t;
-
-/* Note this piece of asymmetry from the v9 ABI.  */
-typedef int                   __kernel_suseconds_t;
-
-#ifdef __GNUC__
-typedef long long              __kernel_loff_t;
-#endif
-
-typedef struct {
-       int     val[2];
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__)
-
-#undef __FD_SET
-static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-       unsigned long _tmp = fd / __NFDBITS;
-       unsigned long _rem = fd % __NFDBITS;
-       fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-       unsigned long _tmp = fd / __NFDBITS;
-       unsigned long _rem = fd % __NFDBITS;
-       fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static inline int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
-{ 
-       unsigned long _tmp = fd / __NFDBITS;
-       unsigned long _rem = fd % __NFDBITS;
-       return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant cases (8 or 32 longs,
- * for 256 and 1024-bit fd_sets respectively)
- */
-#undef __FD_ZERO
-static inline void __FD_ZERO(__kernel_fd_set *p)
-{
-       unsigned long *tmp = p->fds_bits;
-       int i;
-
-       if (__builtin_constant_p(__FDSET_LONGS)) {
-               switch (__FDSET_LONGS) {
-                       case 32:
-                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-                         tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
-                         tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
-                         tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0;
-                         tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0;
-                         tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0;
-                         tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0;
-                         return;
-                       case 16:
-                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-                         tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
-                         tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
-                         return;
-                       case 8:
-                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-                         return;
-                       case 4:
-                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-                         return;
-               }
-       }
-       i = __FDSET_LONGS;
-       while (i) {
-               i--;
-               *tmp = 0;
-               tmp++;
-       }
-}
-
-#endif /* defined(__KERNEL__) */
-
-#endif /* !(__ARCH_SPARC64_POSIX_TYPES_H) */
+#include <asm-sparc/posix_types.h>
index 26b4e5255761876cb8028b5edf71e5eb7f3684a7..21de6cc182ebe4b1837e36f78cd06c7756afc004 100644 (file)
@@ -1,237 +1 @@
-/*
- * include/asm-sparc64/processor.h
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef __ASM_SPARC64_PROCESSOR_H
-#define __ASM_SPARC64_PROCESSOR_H
-
-/*
- * Sparc64 implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ void *pc; __asm__("rd %%pc, %0" : "=r" (pc)); pc; })
-
-#include <asm/asi.h>
-#include <asm/pstate.h>
-#include <asm/ptrace.h>
-#include <asm/page.h>
-
-/* The sparc has no problems with write protection */
-#define wp_works_ok 1
-#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
-
-/*
- * User lives in his very own context, and cannot reference us. Note
- * that TASK_SIZE is a misnomer, it really gives maximum user virtual 
- * address that the kernel will allocate out.
- *
- * XXX No longer using virtual page tables, kill this upper limit...
- */
-#define VA_BITS                44
-#ifndef __ASSEMBLY__
-#define VPTE_SIZE      (1UL << (VA_BITS - PAGE_SHIFT + 3))
-#else
-#define VPTE_SIZE      (1 << (VA_BITS - PAGE_SHIFT + 3))
-#endif
-
-#define TASK_SIZE      ((unsigned long)-VPTE_SIZE)
-#define TASK_SIZE_OF(tsk) \
-       (test_tsk_thread_flag(tsk,TIF_32BIT) ? \
-        (1UL << 32UL) : TASK_SIZE)
-#ifdef __KERNEL__
-
-#define STACK_TOP32    ((1UL << 32UL) - PAGE_SIZE)
-#define STACK_TOP64    (0x0000080000000000UL - (1UL << 32UL))
-
-#define STACK_TOP      (test_thread_flag(TIF_32BIT) ? \
-                        STACK_TOP32 : STACK_TOP64)
-
-#define STACK_TOP_MAX  STACK_TOP64
-
-#endif
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
-       unsigned char seg;
-} mm_segment_t;
-
-/* The Sparc processor specific thread struct. */
-/* XXX This should die, everything can go into thread_info now. */
-struct thread_struct {
-#ifdef CONFIG_DEBUG_SPINLOCK
-       /* How many spinlocks held by this thread.
-        * Used with spin lock debugging to catch tasks
-        * sleeping illegally with locks held.
-        */
-       int smp_lock_count;
-       unsigned int smp_lock_pc;
-#else
-       int dummy; /* f'in gcc bug... */
-#endif
-};
-
-#endif /* !(__ASSEMBLY__) */
-
-#ifndef CONFIG_DEBUG_SPINLOCK
-#define INIT_THREAD  {                 \
-       0,                              \
-}
-#else /* CONFIG_DEBUG_SPINLOCK */
-#define INIT_THREAD  {                                 \
-/* smp_lock_count, smp_lock_pc, */                     \
-   0,             0,                                   \
-}
-#endif /* !(CONFIG_DEBUG_SPINLOCK) */
-
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-
-/* Return saved PC of a blocked thread. */
-struct task_struct;
-extern unsigned long thread_saved_pc(struct task_struct *);
-
-/* On Uniprocessor, even in RMO processes see TSO semantics */
-#ifdef CONFIG_SMP
-#define TSTATE_INITIAL_MM      TSTATE_TSO
-#else
-#define TSTATE_INITIAL_MM      TSTATE_RMO
-#endif
-
-/* Do necessary setup to start up a newly executed thread. */
-#define start_thread(regs, pc, sp) \
-do { \
-       unsigned long __asi = ASI_PNF; \
-       regs->tstate = (regs->tstate & (TSTATE_CWP)) | (TSTATE_INITIAL_MM|TSTATE_IE) | (__asi << 24UL); \
-       regs->tpc = ((pc & (~3)) - 4); \
-       regs->tnpc = regs->tpc + 4; \
-       regs->y = 0; \
-       set_thread_wstate(1 << 3); \
-       if (current_thread_info()->utraps) { \
-               if (*(current_thread_info()->utraps) < 2) \
-                       kfree(current_thread_info()->utraps); \
-               else \
-                       (*(current_thread_info()->utraps))--; \
-               current_thread_info()->utraps = NULL; \
-       } \
-       __asm__ __volatile__( \
-       "stx            %%g0, [%0 + %2 + 0x00]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x08]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x10]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x18]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x20]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x28]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x30]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x38]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x40]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x48]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x50]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x58]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x60]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x68]\n\t" \
-       "stx            %1,   [%0 + %2 + 0x70]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x78]\n\t" \
-       "wrpr           %%g0, (1 << 3), %%wstate\n\t" \
-       : \
-       : "r" (regs), "r" (sp - sizeof(struct reg_window) - STACK_BIAS), \
-         "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \
-} while (0)
-
-#define start_thread32(regs, pc, sp) \
-do { \
-       unsigned long __asi = ASI_PNF; \
-       pc &= 0x00000000ffffffffUL; \
-       sp &= 0x00000000ffffffffUL; \
-       regs->tstate = (regs->tstate & (TSTATE_CWP))|(TSTATE_INITIAL_MM|TSTATE_IE|TSTATE_AM) | (__asi << 24UL); \
-       regs->tpc = ((pc & (~3)) - 4); \
-       regs->tnpc = regs->tpc + 4; \
-       regs->y = 0; \
-       set_thread_wstate(2 << 3); \
-       if (current_thread_info()->utraps) { \
-               if (*(current_thread_info()->utraps) < 2) \
-                       kfree(current_thread_info()->utraps); \
-               else \
-                       (*(current_thread_info()->utraps))--; \
-               current_thread_info()->utraps = NULL; \
-       } \
-       __asm__ __volatile__( \
-       "stx            %%g0, [%0 + %2 + 0x00]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x08]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x10]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x18]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x20]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x28]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x30]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x38]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x40]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x48]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x50]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x58]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x60]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x68]\n\t" \
-       "stx            %1,   [%0 + %2 + 0x70]\n\t" \
-       "stx            %%g0, [%0 + %2 + 0x78]\n\t" \
-       "wrpr           %%g0, (2 << 3), %%wstate\n\t" \
-       : \
-       : "r" (regs), "r" (sp - sizeof(struct reg_window32)), \
-         "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \
-} while (0)
-
-/* Free all resources held by a thread. */
-#define release_thread(tsk)            do { } while (0)
-
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk)   do { } while (0)
-
-extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
-extern unsigned long get_wchan(struct task_struct *task);
-
-#define task_pt_regs(tsk) (task_thread_info(tsk)->kregs)
-#define KSTK_EIP(tsk)  (task_pt_regs(tsk)->tpc)
-#define KSTK_ESP(tsk)  (task_pt_regs(tsk)->u_regs[UREG_FP])
-
-#define cpu_relax()    barrier()
-
-/* Prefetch support.  This is tuned for UltraSPARC-III and later.
- * UltraSPARC-I will treat these as nops, and UltraSPARC-II has
- * a shallower prefetch queue than later chips.
- */
-#define ARCH_HAS_PREFETCH
-#define ARCH_HAS_PREFETCHW
-#define ARCH_HAS_SPINLOCK_PREFETCH
-
-static inline void prefetch(const void *x)
-{
-       /* We do not use the read prefetch mnemonic because that
-        * prefetches into the prefetch-cache which only is accessible
-        * by floating point operations in UltraSPARC-III and later.
-        * By contrast, "#one_write" prefetches into the L2 cache
-        * in shared state.
-        */
-       __asm__ __volatile__("prefetch [%0], #one_write"
-                            : /* no outputs */
-                            : "r" (x));
-}
-
-static inline void prefetchw(const void *x)
-{
-       /* The most optimal prefetch to use for writes is
-        * "#n_writes".  This brings the cacheline into the
-        * L2 cache in "owned" state.
-        */
-       __asm__ __volatile__("prefetch [%0], #n_writes"
-                            : /* no outputs */
-                            : "r" (x));
-}
-
-#define spin_lock_prefetch(x)  prefetchw(x)
-
-#define HAVE_ARCH_PICK_MMAP_LAYOUT
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(__ASM_SPARC64_PROCESSOR_H) */
+#include <asm-sparc/processor.h>
index 44b6327dbbf5ac7c7daa54f6ab1d4e8c05fdbc3a..587846f48358ab987c4d319d049044410fe69352 100644 (file)
@@ -1,45 +1 @@
-#ifndef _SPARC64_PSRCOMPAT_H
-#define _SPARC64_PSRCOMPAT_H
-
-#include <asm/pstate.h>
-
-/* Old 32-bit PSR fields for the compatibility conversion code. */
-#define PSR_CWP     0x0000001f         /* current window pointer     */
-#define PSR_ET      0x00000020         /* enable traps field         */
-#define PSR_PS      0x00000040         /* previous privilege level   */
-#define PSR_S       0x00000080         /* current privilege level    */
-#define PSR_PIL     0x00000f00         /* processor interrupt level  */
-#define PSR_EF      0x00001000         /* enable floating point      */
-#define PSR_EC      0x00002000         /* enable co-processor        */
-#define PSR_SYSCALL 0x00004000         /* inside of a syscall        */
-#define PSR_LE      0x00008000         /* SuperSparcII little-endian */
-#define PSR_ICC     0x00f00000         /* integer condition codes    */
-#define PSR_C       0x00100000         /* carry bit                  */
-#define PSR_V       0x00200000         /* overflow bit               */
-#define PSR_Z       0x00400000         /* zero bit                   */
-#define PSR_N       0x00800000         /* negative bit               */
-#define PSR_VERS    0x0f000000         /* cpu-version field          */
-#define PSR_IMPL    0xf0000000         /* cpu-implementation field   */
-
-#define PSR_V8PLUS  0xff000000         /* fake impl/ver, meaning a 64bit CPU is present */
-#define PSR_XCC            0x000f0000         /* if PSR_V8PLUS, this is %xcc */
-
-static inline unsigned int tstate_to_psr(unsigned long tstate)
-{
-       return ((tstate & TSTATE_CWP)                   |
-               PSR_S                                   |
-               ((tstate & TSTATE_ICC) >> 12)           |
-               ((tstate & TSTATE_XCC) >> 20)           |
-               ((tstate & TSTATE_SYSCALL) ? PSR_SYSCALL : 0) |
-               PSR_V8PLUS);
-}
-
-static inline unsigned long psr_to_tstate_icc(unsigned int psr)
-{
-       unsigned long tstate = ((unsigned long)(psr & PSR_ICC)) << 12;
-       if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS)
-               tstate |= ((unsigned long)(psr & PSR_XCC)) << 20;
-       return tstate;
-}
-
-#endif /* !(_SPARC64_PSRCOMPAT_H) */
+#include <asm-sparc/psrcompat.h>
index a26a53777bb06b51fccd5d8add777039be1dfcf5..3ccf0be25360208441f50433474ee8d72d75f114 100644 (file)
@@ -1,91 +1 @@
-#ifndef _SPARC64_PSTATE_H
-#define _SPARC64_PSTATE_H
-
-#include <linux/const.h>
-
-/* The V9 PSTATE Register (with SpitFire extensions).
- *
- * -----------------------------------------------------------------------
- * | Resv | IG | MG | CLE | TLE |  MM  | RED | PEF | AM | PRIV | IE | AG |
- * -----------------------------------------------------------------------
- *  63  12  11   10    9     8    7   6   5     4     3     2     1    0
- */
-#define PSTATE_IG   _AC(0x0000000000000800,UL) /* Interrupt Globals.   */
-#define PSTATE_MG   _AC(0x0000000000000400,UL) /* MMU Globals.         */
-#define PSTATE_CLE  _AC(0x0000000000000200,UL) /* Current Little Endian.*/
-#define PSTATE_TLE  _AC(0x0000000000000100,UL) /* Trap Little Endian.  */
-#define PSTATE_MM   _AC(0x00000000000000c0,UL) /* Memory Model.                */
-#define PSTATE_TSO  _AC(0x0000000000000000,UL) /* MM: TotalStoreOrder  */
-#define PSTATE_PSO  _AC(0x0000000000000040,UL) /* MM: PartialStoreOrder        */
-#define PSTATE_RMO  _AC(0x0000000000000080,UL) /* MM: RelaxedMemoryOrder*/
-#define PSTATE_RED  _AC(0x0000000000000020,UL) /* Reset Error Debug.   */
-#define PSTATE_PEF  _AC(0x0000000000000010,UL) /* Floating Point Enable.*/
-#define PSTATE_AM   _AC(0x0000000000000008,UL) /* Address Mask.                */
-#define PSTATE_PRIV _AC(0x0000000000000004,UL) /* Privilege.           */
-#define PSTATE_IE   _AC(0x0000000000000002,UL) /* Interrupt Enable.    */
-#define PSTATE_AG   _AC(0x0000000000000001,UL) /* Alternate Globals.   */
-
-/* The V9 TSTATE Register (with SpitFire and Linux extensions).
- *
- * ---------------------------------------------------------------------
- * |  Resv |  GL  |  CCR  |  ASI  |  %pil  |  PSTATE  |  Resv  |  CWP  |
- * ---------------------------------------------------------------------
- *  63   43 42  40 39   32 31   24 23    20 19       8 7      5 4     0
- */
-#define TSTATE_GL      _AC(0x0000070000000000,UL) /* Global reg level  */
-#define TSTATE_CCR     _AC(0x000000ff00000000,UL) /* Condition Codes.  */
-#define TSTATE_XCC     _AC(0x000000f000000000,UL) /* Condition Codes.  */
-#define TSTATE_XNEG    _AC(0x0000008000000000,UL) /* %xcc Negative.    */
-#define TSTATE_XZERO   _AC(0x0000004000000000,UL) /* %xcc Zero.        */
-#define TSTATE_XOVFL   _AC(0x0000002000000000,UL) /* %xcc Overflow.    */
-#define TSTATE_XCARRY  _AC(0x0000001000000000,UL) /* %xcc Carry.       */
-#define TSTATE_ICC     _AC(0x0000000f00000000,UL) /* Condition Codes.  */
-#define TSTATE_INEG    _AC(0x0000000800000000,UL) /* %icc Negative.    */
-#define TSTATE_IZERO   _AC(0x0000000400000000,UL) /* %icc Zero.        */
-#define TSTATE_IOVFL   _AC(0x0000000200000000,UL) /* %icc Overflow.    */
-#define TSTATE_ICARRY  _AC(0x0000000100000000,UL) /* %icc Carry.       */
-#define TSTATE_ASI     _AC(0x00000000ff000000,UL) /* AddrSpace ID.     */
-#define TSTATE_PIL     _AC(0x0000000000f00000,UL) /* %pil (Linux traps)*/
-#define TSTATE_PSTATE  _AC(0x00000000000fff00,UL) /* PSTATE.           */
-#define TSTATE_IG      _AC(0x0000000000080000,UL) /* Interrupt Globals.*/
-#define TSTATE_MG      _AC(0x0000000000040000,UL) /* MMU Globals.      */
-#define TSTATE_CLE     _AC(0x0000000000020000,UL) /* CurrLittleEndian. */
-#define TSTATE_TLE     _AC(0x0000000000010000,UL) /* TrapLittleEndian. */
-#define TSTATE_MM      _AC(0x000000000000c000,UL) /* Memory Model.     */
-#define TSTATE_TSO     _AC(0x0000000000000000,UL) /* MM: TSO           */
-#define TSTATE_PSO     _AC(0x0000000000004000,UL) /* MM: PSO           */
-#define TSTATE_RMO     _AC(0x0000000000008000,UL) /* MM: RMO           */
-#define TSTATE_RED     _AC(0x0000000000002000,UL) /* Reset Error Debug.*/
-#define TSTATE_PEF     _AC(0x0000000000001000,UL) /* FPU Enable.       */
-#define TSTATE_AM      _AC(0x0000000000000800,UL) /* Address Mask.     */
-#define TSTATE_PRIV    _AC(0x0000000000000400,UL) /* Privilege.        */
-#define TSTATE_IE      _AC(0x0000000000000200,UL) /* Interrupt Enable. */
-#define TSTATE_AG      _AC(0x0000000000000100,UL) /* Alternate Globals.*/
-#define TSTATE_SYSCALL _AC(0x0000000000000020,UL) /* in syscall trap   */
-#define TSTATE_CWP     _AC(0x000000000000001f,UL) /* Curr Win-Pointer. */
-
-/* Floating-Point Registers State Register.
- *
- * --------------------------------
- * |  Resv  |  FEF  |  DU  |  DL  |
- * --------------------------------
- *  63     3    2       1      0
- */
-#define FPRS_FEF       _AC(0x0000000000000004,UL) /* FPU Enable.       */
-#define FPRS_DU                _AC(0x0000000000000002,UL) /* Dirty Upper.      */
-#define FPRS_DL                _AC(0x0000000000000001,UL) /* Dirty Lower.      */
-
-/* Version Register.
- *
- * ------------------------------------------------------
- * | MANUF | IMPL | MASK | Resv | MAXTL | Resv | MAXWIN |
- * ------------------------------------------------------
- *  63   48 47  32 31  24 23  16 15    8 7    5 4      0
- */
-#define VERS_MANUF     _AC(0xffff000000000000,UL) /* Manufacturer.     */
-#define VERS_IMPL      _AC(0x0000ffff00000000,UL) /* Implementation.   */
-#define VERS_MASK      _AC(0x00000000ff000000,UL) /* Mask Set Revision.*/
-#define VERS_MAXTL     _AC(0x000000000000ff00,UL) /* Max Trap Level.   */
-#define VERS_MAXWIN    _AC(0x000000000000001f,UL) /* Max RegWindow Idx.*/
-
-#endif /* !(_SPARC64_PSTATE_H) */
+#include <asm-sparc/pstate.h>
index b163da79bb6d276a0d8128094f5de5fc74e2d026..1a55b9fb3b0c9b4ca09a78544c0b18fbbdc007f4 100644 (file)
@@ -1,346 +1 @@
-#ifndef _SPARC64_PTRACE_H
-#define _SPARC64_PTRACE_H
-
-#include <asm/pstate.h>
-
-/* This struct defines the way the registers are stored on the 
- * stack during a system call and basically all traps.
- */
-
-/* This magic value must have the low 9 bits clear,
- * as that is where we encode the %tt value, see below.
- */
-#define PT_REGS_MAGIC 0x57ac6c00
-
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-
-struct pt_regs {
-       unsigned long u_regs[16]; /* globals and ins */
-       unsigned long tstate;
-       unsigned long tpc;
-       unsigned long tnpc;
-       unsigned int y;
-
-       /* We encode a magic number, PT_REGS_MAGIC, along
-        * with the %tt (trap type) register value at trap
-        * entry time.  The magic number allows us to identify
-        * accurately a trap stack frame in the stack
-        * unwinder, and the %tt value allows us to test
-        * things like "in a system call" etc. for an arbitray
-        * process.
-        *
-        * The PT_REGS_MAGIC is choosen such that it can be
-        * loaded completely using just a sethi instruction.
-        */
-       unsigned int magic;
-};
-
-static inline int pt_regs_trap_type(struct pt_regs *regs)
-{
-       return regs->magic & 0x1ff;
-}
-
-static inline bool pt_regs_is_syscall(struct pt_regs *regs)
-{
-       return (regs->tstate & TSTATE_SYSCALL);
-}
-
-static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
-{
-       return (regs->tstate &= ~TSTATE_SYSCALL);
-}
-
-struct pt_regs32 {
-       unsigned int psr;
-       unsigned int pc;
-       unsigned int npc;
-       unsigned int y;
-       unsigned int u_regs[16]; /* globals and ins */
-};
-
-#define UREG_G0        0
-#define UREG_G1        1
-#define UREG_G2        2
-#define UREG_G3        3
-#define UREG_G4        4
-#define UREG_G5        5
-#define UREG_G6        6
-#define UREG_G7        7
-#define UREG_I0        8
-#define UREG_I1        9
-#define UREG_I2        10
-#define UREG_I3        11
-#define UREG_I4        12
-#define UREG_I5        13
-#define UREG_I6        14
-#define UREG_I7        15
-#define UREG_FP        UREG_I6
-#define UREG_RETPC     UREG_I7
-
-/* A V9 register window */
-struct reg_window {
-       unsigned long locals[8];
-       unsigned long ins[8];
-};
-
-/* A 32-bit register window. */
-struct reg_window32 {
-       unsigned int locals[8];
-       unsigned int ins[8];
-};
-
-/* A V9 Sparc stack frame */
-struct sparc_stackf {
-       unsigned long locals[8];
-        unsigned long ins[6];
-       struct sparc_stackf *fp;
-       unsigned long callers_pc;
-       char *structptr;
-       unsigned long xargs[6];
-       unsigned long xxargs[1];
-};     
-
-/* A 32-bit Sparc stack frame */
-struct sparc_stackf32 {
-       unsigned int locals[8];
-        unsigned int ins[6];
-       unsigned int fp;
-       unsigned int callers_pc;
-       unsigned int structptr;
-       unsigned int xargs[6];
-       unsigned int xxargs[1];
-};     
-
-struct sparc_trapf {
-       unsigned long locals[8];
-       unsigned long ins[8];
-       unsigned long _unused;
-       struct pt_regs *regs;
-};
-
-#define TRACEREG_SZ    sizeof(struct pt_regs)
-#define STACKFRAME_SZ  sizeof(struct sparc_stackf)
-
-#define TRACEREG32_SZ  sizeof(struct pt_regs32)
-#define STACKFRAME32_SZ        sizeof(struct sparc_stackf32)
-
-#ifdef __KERNEL__
-
-struct global_reg_snapshot {
-       unsigned long           tstate;
-       unsigned long           tpc;
-       unsigned long           tnpc;
-       unsigned long           o7;
-       unsigned long           i7;
-       struct thread_info      *thread;
-       unsigned long           pad1;
-       unsigned long           pad2;
-};
-
-#define __ARCH_WANT_COMPAT_SYS_PTRACE
-
-#define force_successful_syscall_return()          \
-do {   current_thread_info()->syscall_noerror = 1; \
-} while (0)
-#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
-#define instruction_pointer(regs) ((regs)->tpc)
-#define regs_return_value(regs) ((regs)->u_regs[UREG_I0])
-#ifdef CONFIG_SMP
-extern unsigned long profile_pc(struct pt_regs *);
-#else
-#define profile_pc(regs) instruction_pointer(regs)
-#endif
-extern void show_regs(struct pt_regs *);
-extern void __show_regs(struct pt_regs *);
-#endif
-
-#else /* __ASSEMBLY__ */
-/* For assembly code. */
-#define TRACEREG_SZ            0xa0
-#define STACKFRAME_SZ          0xc0
-
-#define TRACEREG32_SZ          0x50
-#define STACKFRAME32_SZ                0x60
-#endif
-
-#ifdef __KERNEL__
-#define STACK_BIAS             2047
-#endif
-
-/* These are for pt_regs. */
-#define PT_V9_G0     0x00
-#define PT_V9_G1     0x08
-#define PT_V9_G2     0x10
-#define PT_V9_G3     0x18
-#define PT_V9_G4     0x20
-#define PT_V9_G5     0x28
-#define PT_V9_G6     0x30
-#define PT_V9_G7     0x38
-#define PT_V9_I0     0x40
-#define PT_V9_I1     0x48
-#define PT_V9_I2     0x50
-#define PT_V9_I3     0x58
-#define PT_V9_I4     0x60
-#define PT_V9_I5     0x68
-#define PT_V9_I6     0x70
-#define PT_V9_FP     PT_V9_I6
-#define PT_V9_I7     0x78
-#define PT_V9_TSTATE 0x80
-#define PT_V9_TPC    0x88
-#define PT_V9_TNPC   0x90
-#define PT_V9_Y      0x98
-#define PT_V9_MAGIC  0x9c
-#define PT_TSTATE      PT_V9_TSTATE
-#define PT_TPC         PT_V9_TPC
-#define PT_TNPC                PT_V9_TNPC
-
-/* These for pt_regs32. */
-#define PT_PSR    0x0
-#define PT_PC     0x4
-#define PT_NPC    0x8
-#define PT_Y      0xc
-#define PT_G0     0x10
-#define PT_WIM    PT_G0
-#define PT_G1     0x14
-#define PT_G2     0x18
-#define PT_G3     0x1c
-#define PT_G4     0x20
-#define PT_G5     0x24
-#define PT_G6     0x28
-#define PT_G7     0x2c
-#define PT_I0     0x30
-#define PT_I1     0x34
-#define PT_I2     0x38
-#define PT_I3     0x3c
-#define PT_I4     0x40
-#define PT_I5     0x44
-#define PT_I6     0x48
-#define PT_FP     PT_I6
-#define PT_I7     0x4c
-
-/* Reg_window offsets */
-#define RW_V9_L0     0x00
-#define RW_V9_L1     0x08
-#define RW_V9_L2     0x10
-#define RW_V9_L3     0x18
-#define RW_V9_L4     0x20
-#define RW_V9_L5     0x28
-#define RW_V9_L6     0x30
-#define RW_V9_L7     0x38
-#define RW_V9_I0     0x40
-#define RW_V9_I1     0x48
-#define RW_V9_I2     0x50
-#define RW_V9_I3     0x58
-#define RW_V9_I4     0x60
-#define RW_V9_I5     0x68
-#define RW_V9_I6     0x70
-#define RW_V9_I7     0x78
-
-#define RW_L0     0x00
-#define RW_L1     0x04
-#define RW_L2     0x08
-#define RW_L3     0x0c
-#define RW_L4     0x10
-#define RW_L5     0x14
-#define RW_L6     0x18
-#define RW_L7     0x1c
-#define RW_I0     0x20
-#define RW_I1     0x24
-#define RW_I2     0x28
-#define RW_I3     0x2c
-#define RW_I4     0x30
-#define RW_I5     0x34
-#define RW_I6     0x38
-#define RW_I7     0x3c
-
-/* Stack_frame offsets */
-#define SF_V9_L0     0x00
-#define SF_V9_L1     0x08
-#define SF_V9_L2     0x10
-#define SF_V9_L3     0x18
-#define SF_V9_L4     0x20
-#define SF_V9_L5     0x28
-#define SF_V9_L6     0x30
-#define SF_V9_L7     0x38
-#define SF_V9_I0     0x40
-#define SF_V9_I1     0x48
-#define SF_V9_I2     0x50
-#define SF_V9_I3     0x58
-#define SF_V9_I4     0x60
-#define SF_V9_I5     0x68
-#define SF_V9_FP     0x70
-#define SF_V9_PC     0x78
-#define SF_V9_RETP   0x80
-#define SF_V9_XARG0  0x88
-#define SF_V9_XARG1  0x90
-#define SF_V9_XARG2  0x98
-#define SF_V9_XARG3  0xa0
-#define SF_V9_XARG4  0xa8
-#define SF_V9_XARG5  0xb0
-#define SF_V9_XXARG  0xb8
-
-#define SF_L0     0x00
-#define SF_L1     0x04
-#define SF_L2     0x08
-#define SF_L3     0x0c
-#define SF_L4     0x10
-#define SF_L5     0x14
-#define SF_L6     0x18
-#define SF_L7     0x1c
-#define SF_I0     0x20
-#define SF_I1     0x24
-#define SF_I2     0x28
-#define SF_I3     0x2c
-#define SF_I4     0x30
-#define SF_I5     0x34
-#define SF_FP     0x38
-#define SF_PC     0x3c
-#define SF_RETP   0x40
-#define SF_XARG0  0x44
-#define SF_XARG1  0x48
-#define SF_XARG2  0x4c
-#define SF_XARG3  0x50
-#define SF_XARG4  0x54
-#define SF_XARG5  0x58
-#define SF_XXARG  0x5c
-
-#ifdef __KERNEL__
-
-/* global_reg_snapshot offsets */
-#define GR_SNAP_TSTATE 0x00
-#define GR_SNAP_TPC    0x08
-#define GR_SNAP_TNPC   0x10
-#define GR_SNAP_O7     0x18
-#define GR_SNAP_I7     0x20
-#define GR_SNAP_THREAD 0x28
-#define GR_SNAP_PAD1   0x30
-#define GR_SNAP_PAD2   0x38
-
-#endif  /*  __KERNEL__  */
-
-/* Stuff for the ptrace system call */
-#define PTRACE_SPARC_DETACH       11
-#define PTRACE_GETREGS            12
-#define PTRACE_SETREGS            13
-#define PTRACE_GETFPREGS          14
-#define PTRACE_SETFPREGS          15
-#define PTRACE_READDATA           16
-#define PTRACE_WRITEDATA          17
-#define PTRACE_READTEXT           18
-#define PTRACE_WRITETEXT          19
-#define PTRACE_GETFPAREGS         20
-#define PTRACE_SETFPAREGS         21
-
-/* There are for debugging 64-bit processes, either from a 32 or 64 bit
- * parent.  Thus their complements are for debugging 32-bit processes only.
- */
-
-#define PTRACE_GETREGS64         22
-#define PTRACE_SETREGS64         23
-/* PTRACE_SYSCALL is 24 */
-#define PTRACE_GETFPREGS64       25
-#define PTRACE_SETFPREGS64       26
-
-#endif /* !(_SPARC64_PTRACE_H) */
+#include <asm-sparc/ptrace.h>
index 3f3f43f5be5e0af489a6d06c3f6b9dfa0466e970..0d72eb811cc8ff4b963380e00785f49acc55c169 100644 (file)
@@ -1,6 +1 @@
-#ifndef _SPARC64_REBOOT_H
-#define _SPARC64_REBOOT_H
-
-extern void machine_alt_power_off(void);
-
-#endif /* _SPARC64_REBOOT_H */
+#include <asm-sparc/reboot.h>
index 77aa4804a60dfb5f4ba709c97d90abbaa1992039..495bab27da0788d4b9f669b7040dd88dd2711adb 100644 (file)
@@ -1,56 +1 @@
-/*
- * linux/asm-sparc64/reg.h
- * Layout of the registers as expected by gdb on the Sparc
- * we should replace the user.h definitions with those in
- * this file, we don't even use the other 
- * -miguel
- *
- * The names of the structures, constants and aliases in this file
- * have the same names as the sunos ones, some programs rely on these
- * names (gdb for example).
- *
- */
-
-#ifndef __SPARC64_REG_H
-#define __SPARC64_REG_H
-
-struct regs {
-        unsigned long r_g1;
-        unsigned long r_g2;
-        unsigned long r_g3;
-        unsigned long r_g4;
-        unsigned long r_g5;
-        unsigned long r_g6;
-        unsigned long r_g7;
-        unsigned long r_o0;
-        unsigned long r_o1;
-        unsigned long r_o2;
-        unsigned long r_o3;
-        unsigned long r_o4;
-        unsigned long r_o5;
-        unsigned long r_o6;
-        unsigned long r_o7;
-        unsigned long __pad;
-        unsigned long r_tstate;
-        unsigned long r_tpc;
-        unsigned long r_tnpc;
-        unsigned int  r_y;
-        unsigned int  r_fprs;
-};
-
-#define FPU_REGS_TYPE unsigned int
-#define FPU_FSR_TYPE unsigned long
-
-struct fp_status {
-        unsigned long fpu_fr[32];
-        unsigned long Fpu_fsr;
-};
-
-struct fpu {
-       struct fp_status f_fpstatus;
-};
-
-#define fpu_regs  f_fpstatus.fpu_fr
-#define fpu_fsr   f_fpstatus.Fpu_fsr
-
-#endif /* __SPARC64_REG_H */
+#include <asm-sparc/reg.h>
index 4f08fb5e4ca428b664dbc2c7cd52e975777ab3c1..46e3bc0de476c2afd5cf4ef18eeba5ae1a162cb7 100644 (file)
@@ -1,19 +1 @@
-/*
- * resource.h: Resource definitions.
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef _SPARC64_RESOURCE_H
-#define _SPARC64_RESOURCE_H
-
-/*
- * These two resource limit IDs have a Sparc/Linux-specific ordering,
- * the rest comes from the generic header:
- */
-#define RLIMIT_NOFILE          6       /* max number of open files */
-#define RLIMIT_NPROC           7       /* max number of processes */
-
-#include <asm-generic/resource.h>
-
-#endif /* !(_SPARC64_RESOURCE_H) */
+#include <asm-sparc/resource.h>
index f9ecb1fe2ecd130affc9b1850de5b51aabbd348c..e49a9685aead12c8f7186a56e380364dcb37c090 100644 (file)
@@ -1,26 +1 @@
-/*
- * rtc.h: Definitions for access to the Mostek real time clock
- *
- * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
- */
-
-#ifndef _RTC_H
-#define _RTC_H
-
-#include <linux/ioctl.h>
-
-struct rtc_time
-{
-       int     sec;    /* Seconds (0-59) */
-       int     min;    /* Minutes (0-59) */
-       int     hour;   /* Hour (0-23) */
-       int     dow;    /* Day of the week (1-7) */
-       int     dom;    /* Day of the month (1-31) */
-       int     month;  /* Month of year (1-12) */
-       int     year;   /* Year (0-99) */
-};
-
-#define RTCGET _IOR('p', 20, struct rtc_time)
-#define RTCSET _IOW('p', 21, struct rtc_time)
-
-#endif
+#include <asm-sparc/rtc.h>
index a303c9d64d845989e313a326f4c5e92f283148a5..2a1de315c86a253443df9d56b1c548aa67c3be5e 100644 (file)
@@ -1,12 +1 @@
-/* rwsem-const.h: RW semaphore counter constants.  */
-#ifndef _SPARC64_RWSEM_CONST_H
-#define _SPARC64_RWSEM_CONST_H
-
-#define RWSEM_UNLOCKED_VALUE           0x00000000
-#define RWSEM_ACTIVE_BIAS              0x00000001
-#define RWSEM_ACTIVE_MASK              0x0000ffff
-#define RWSEM_WAITING_BIAS             0xffff0000
-#define RWSEM_ACTIVE_READ_BIAS         RWSEM_ACTIVE_BIAS
-#define RWSEM_ACTIVE_WRITE_BIAS                (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
-
-#endif /* _SPARC64_RWSEM_CONST_H */
+#include <asm-sparc/rwsem-const.h>
index 1dc129ac2feb0aab36a2111c419647e851db7359..6943c56ed087f1007912a0a5980972ba0cb8bf33 100644 (file)
@@ -1,84 +1 @@
-/*
- * rwsem.h: R/W semaphores implemented using CAS
- *
- * Written by David S. Miller (davem@redhat.com), 2001.
- * Derived from asm-i386/rwsem.h
- */
-#ifndef _SPARC64_RWSEM_H
-#define _SPARC64_RWSEM_H
-
-#ifndef _LINUX_RWSEM_H
-#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
-#endif
-
-#ifdef __KERNEL__
-
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <asm/rwsem-const.h>
-
-struct rwsem_waiter;
-
-struct rw_semaphore {
-       signed int count;
-       spinlock_t              wait_lock;
-       struct list_head        wait_list;
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-       struct lockdep_map      dep_map;
-#endif
-};
-
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname }
-#else
-# define __RWSEM_DEP_MAP_INIT(lockname)
-#endif
-
-#define __RWSEM_INITIALIZER(name) \
-{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) \
-  __RWSEM_DEP_MAP_INIT(name) }
-
-#define DECLARE_RWSEM(name) \
-       struct rw_semaphore name = __RWSEM_INITIALIZER(name)
-
-extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
-                        struct lock_class_key *key);
-
-#define init_rwsem(sem)                                                \
-do {                                                           \
-       static struct lock_class_key __key;                     \
-                                                               \
-       __init_rwsem((sem), #sem, &__key);                      \
-} while (0)
-
-extern void __down_read(struct rw_semaphore *sem);
-extern int __down_read_trylock(struct rw_semaphore *sem);
-extern void __down_write(struct rw_semaphore *sem);
-extern int __down_write_trylock(struct rw_semaphore *sem);
-extern void __up_read(struct rw_semaphore *sem);
-extern void __up_write(struct rw_semaphore *sem);
-extern void __downgrade_write(struct rw_semaphore *sem);
-
-static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
-{
-       __down_write(sem);
-}
-
-static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
-{
-       return atomic_add_return(delta, (atomic_t *)(&sem->count));
-}
-
-static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
-{
-       atomic_add(delta, (atomic_t *)(&sem->count));
-}
-
-static inline int rwsem_is_locked(struct rw_semaphore *sem)
-{
-       return (sem->count != 0);
-}
-
-#endif /* __KERNEL__ */
-
-#endif /* _SPARC64_RWSEM_H */
+#include <asm-sparc/rwsem.h>
index 24a04a55cf85d4d60950f5f4dd4efbf7b15f2148..0cab0e89b874ed99a2b2d20cb7d5e953be99266a 100644 (file)
@@ -1,190 +1 @@
-/* sbus.h: Defines for the Sun SBus.
- *
- * Copyright (C) 1996, 1999, 2007 David S. Miller (davem@davemloft.net)
- */
-
-#ifndef _SPARC64_SBUS_H
-#define _SPARC64_SBUS_H
-
-#include <linux/dma-mapping.h>
-#include <linux/ioport.h>
-
-#include <asm/oplib.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
-#include <asm/iommu.h>
-#include <asm/scatterlist.h>
-
-/* We scan which devices are on the SBus using the PROM node device
- * tree.  SBus devices are described in two different ways.  You can
- * either get an absolute address at which to access the device, or
- * you can get a SBus 'slot' number and an offset within that slot.
- */
-
-/* The base address at which to calculate device OBIO addresses. */
-#define SUN_SBUS_BVADDR        0x00000000
-#define SBUS_OFF_MASK          0x0fffffff
-
-/* These routines are used to calculate device address from slot
- * numbers + offsets, and vice versa.
- */
-
-static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset)
-{
-  return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<28)+(offset));
-}
-
-static inline int sbus_dev_slot(unsigned long dev_addr)
-{
-  return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>28);
-}
-
-struct sbus_bus;
-
-/* Linux SBUS device tables */
-struct sbus_dev {
-       struct of_device        ofdev;
-       struct sbus_bus         *bus;
-       struct sbus_dev         *next;
-       struct sbus_dev         *child;
-       struct sbus_dev         *parent;
-       int prom_node;  
-       char prom_name[64];
-       int slot;
-
-       struct resource resource[PROMREG_MAX];
-
-       struct linux_prom_registers reg_addrs[PROMREG_MAX];
-       int num_registers;
-
-       struct linux_prom_ranges device_ranges[PROMREG_MAX];
-       int num_device_ranges;
-
-       unsigned int irqs[4];
-       int num_irqs;
-};
-#define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev)
-
-/* This struct describes the SBus(s) found on this machine. */
-struct sbus_bus {
-       struct of_device        ofdev;
-       struct sbus_dev         *devices;       /* Tree of SBUS devices */
-       struct sbus_bus         *next;          /* Next SBUS in system  */
-       int                     prom_node;      /* OBP node of SBUS     */
-       char                    prom_name[64];  /* Usually "sbus" or "sbi" */
-       int                     clock_freq;
-
-       struct linux_prom_ranges sbus_ranges[PROMREG_MAX];
-       int num_sbus_ranges;
-
-       int portid;
-};
-#define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev)
-
-extern struct sbus_bus *sbus_root;
-
-/* Device probing routines could find these handy */
-#define for_each_sbus(bus) \
-        for((bus) = sbus_root; (bus); (bus)=(bus)->next)
-
-#define for_each_sbusdev(device, bus) \
-        for((device) = (bus)->devices; (device); (device)=(device)->next)
-        
-#define for_all_sbusdev(device, bus) \
-       for ((bus) = sbus_root; (bus); (bus) = (bus)->next) \
-               for ((device) = (bus)->devices; (device); (device) = (device)->next)
-
-/* Driver DVMA interfaces. */
-#define sbus_can_dma_64bit(sdev)       (1)
-#define sbus_can_burst64(sdev)         (1)
-extern void sbus_set_sbus64(struct sbus_dev *, int);
-extern void sbus_fill_device_irq(struct sbus_dev *);
-
-static inline void *sbus_alloc_consistent(struct sbus_dev *sdev , size_t size,
-                                         dma_addr_t *dma_handle)
-{
-       return dma_alloc_coherent(&sdev->ofdev.dev, size,
-                                 dma_handle, GFP_ATOMIC);
-}
-
-static inline void sbus_free_consistent(struct sbus_dev *sdev, size_t size,
-                                       void *vaddr, dma_addr_t dma_handle)
-{
-       return dma_free_coherent(&sdev->ofdev.dev, size, vaddr, dma_handle);
-}
-
-#define SBUS_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL
-#define SBUS_DMA_TODEVICE      DMA_TO_DEVICE
-#define SBUS_DMA_FROMDEVICE    DMA_FROM_DEVICE
-#define        SBUS_DMA_NONE           DMA_NONE
-
-/* All the rest use streaming mode mappings. */
-static inline dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr,
-                                        size_t size, int direction)
-{
-       return dma_map_single(&sdev->ofdev.dev, ptr, size,
-                             (enum dma_data_direction) direction);
-}
-
-static inline void sbus_unmap_single(struct sbus_dev *sdev,
-                                    dma_addr_t dma_addr, size_t size,
-                                    int direction)
-{
-       dma_unmap_single(&sdev->ofdev.dev, dma_addr, size,
-                        (enum dma_data_direction) direction);
-}
-
-static inline int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg,
-                             int nents, int direction)
-{
-       return dma_map_sg(&sdev->ofdev.dev, sg, nents,
-                         (enum dma_data_direction) direction);
-}
-
-static inline void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg,
-                                int nents, int direction)
-{
-       dma_unmap_sg(&sdev->ofdev.dev, sg, nents,
-                    (enum dma_data_direction) direction);
-}
-
-/* Finally, allow explicit synchronization of streamable mappings. */
-static inline void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev,
-                                               dma_addr_t dma_handle,
-                                               size_t size, int direction)
-{
-       dma_sync_single_for_cpu(&sdev->ofdev.dev, dma_handle, size,
-                               (enum dma_data_direction) direction);
-}
-#define sbus_dma_sync_single sbus_dma_sync_single_for_cpu
-
-static inline void sbus_dma_sync_single_for_device(struct sbus_dev *sdev,
-                                                  dma_addr_t dma_handle,
-                                                  size_t size, int direction)
-{
-       /* No flushing needed to sync cpu writes to the device.  */
-}
-
-static inline void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev,
-                                           struct scatterlist *sg,
-                                           int nents, int direction)
-{
-       dma_sync_sg_for_cpu(&sdev->ofdev.dev, sg, nents,
-                           (enum dma_data_direction) direction);
-}
-#define sbus_dma_sync_sg sbus_dma_sync_sg_for_cpu
-
-static inline void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev,
-                                              struct scatterlist *sg,
-                                              int nents, int direction)
-{
-       /* No flushing needed to sync cpu writes to the device.  */
-}
-
-extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *);
-extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *);
-extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *);
-extern int sbus_arch_preinit(void);
-extern void sbus_arch_postinit(void);
-
-#endif /* !(_SPARC64_SBUS_H) */
+#include <asm-sparc/sbus.h>
index 81bd058f9382e50bd9e257d50296d604a5e94cf3..b7fef95953ca33e9230bbf033696ee6d126977db 100644 (file)
@@ -1,27 +1 @@
-#ifndef _SPARC64_SCATTERLIST_H
-#define _SPARC64_SCATTERLIST_H
-
-#include <asm/page.h>
-#include <asm/types.h>
-
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
-       unsigned long   sg_magic;
-#endif
-       unsigned long   page_link;
-       unsigned int    offset;
-
-       unsigned int    length;
-
-       dma_addr_t      dma_address;
-       __u32           dma_length;
-};
-
-#define sg_dma_address(sg)     ((sg)->dma_address)
-#define sg_dma_len(sg)         ((sg)->dma_length)
-
-#define ISA_DMA_THRESHOLD      (~0UL)
-
-#define ARCH_HAS_SG_CHAIN
-
-#endif /* !(_SPARC64_SCATTERLIST_H) */
+#include <asm-sparc/scatterlist.h>
index 5e8b01fb334353422534b410707bc631effc0fdf..23675f6a915aa87c92229be934a2eaa8d9877880 100644 (file)
@@ -1,14 +1 @@
-#ifndef _SPARC64_SCRATCHPAD_H
-#define _SPARC64_SCRATCHPAD_H
-
-/* Sun4v scratchpad registers, accessed via ASI_SCRATCHPAD.  */
-
-#define SCRATCHPAD_MMU_MISS    0x00 /* Shared with OBP - set by OBP        */
-#define SCRATCHPAD_CPUID       0x08 /* Shared with OBP - set by hypervisor */
-#define SCRATCHPAD_UTSBREG1    0x10
-#define SCRATCHPAD_UTSBREG2    0x18
-       /* 0x20 and 0x28, hypervisor only... */
-#define SCRATCHPAD_UNUSED1     0x30
-#define SCRATCHPAD_UNUSED2     0x38 /* Reserved for OBP                    */
-
-#endif /* !(_SPARC64_SCRATCHPAD_H) */
+#include <asm-sparc/scratchpad.h>
index 7fcd9968192bc0b26b1fe7d1c67a1e3f08b5359c..f22f02a08a61a830032b2c2b709942b49277d72d 100644 (file)
@@ -1,21 +1 @@
-#ifndef _ASM_SECCOMP_H
-
-#include <linux/thread_info.h> /* already defines TIF_32BIT */
-
-#ifndef TIF_32BIT
-#error "unexpected TIF_32BIT on sparc64"
-#endif
-
-#include <linux/unistd.h>
-
-#define __NR_seccomp_read __NR_read
-#define __NR_seccomp_write __NR_write
-#define __NR_seccomp_exit __NR_exit
-#define __NR_seccomp_sigreturn __NR_rt_sigreturn
-
-#define __NR_seccomp_read_32 __NR_read
-#define __NR_seccomp_write_32 __NR_write
-#define __NR_seccomp_exit_32 __NR_exit
-#define __NR_seccomp_sigreturn_32 __NR_sigreturn
-
-#endif /* _ASM_SECCOMP_H */
+#include <asm-sparc/seccomp.h>
index 3f4b9fdc28d02b334d774ae269ffd8624d03d13b..721496f8b2be5f4476259e2b75e1738e6f8aa8e9 100644 (file)
@@ -1,9 +1 @@
-#ifndef _SPARC64_SECTIONS_H
-#define _SPARC64_SECTIONS_H
-
-/* nothing to see, move along */
-#include <asm-generic/sections.h>
-
-extern char _start[];
-
-#endif
+#include <asm-sparc/sections.h>
index d9b2034ed1d2ecd24bf648b333c8ad68e0d878d5..39362afde5fe2c977b3300f51317f4b04be13a8f 100644 (file)
@@ -1 +1 @@
-#include <linux/semaphore.h>
+#include <asm-sparc/semaphore.h>
index 99f04e4e288cab63b6dd9e590ab221ec1f330c84..c55b952141365a4cfbb4ae524e4b600b13cd67a9 100644 (file)
@@ -1,22 +1 @@
-#ifndef _SPARC64_SEMBUF_H
-#define _SPARC64_SEMBUF_H
-
-/* 
- * The semid64_ds structure for sparc64 architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 2 miscellaneous 64-bit values
- */
-
-struct semid64_ds {
-       struct ipc64_perm sem_perm;             /* permissions .. see ipc.h */
-       __kernel_time_t sem_otime;              /* last semop time */
-       __kernel_time_t sem_ctime;              /* last change time */
-       unsigned long   sem_nsems;              /* no. of semaphores in array */
-       unsigned long   __unused1;
-       unsigned long   __unused2;
-};
-
-#endif /* _SPARC64_SEMBUF_H */
+#include <asm-sparc/sembuf.h>
index 5053df3cec400182b322ac805f0527aa53529742..7143d06b2c55f0e3473f9a50eff7c17944c3db97 100644 (file)
@@ -1,10 +1 @@
-/*
- *     Just a place holder. 
- */
-
-#ifndef _SPARC64_SETUP_H
-#define _SPARC64_SETUP_H
-
-#define COMMAND_LINE_SIZE      2048
-
-#endif /* _SPARC64_SETUP_H */
+#include <asm-sparc/setup.h>
index e96137b04a4f6ef75c29ef567acabd1d02101a57..8036fc377a4de13e3af5b9a3f507ca0456f8e4d5 100644 (file)
@@ -1,82 +1 @@
-#ifndef _SPARC64_SFAFSR_H
-#define _SPARC64_SFAFSR_H
-
-#include <linux/const.h>
-
-/* Spitfire Asynchronous Fault Status register, ASI=0x4C VA<63:0>=0x0 */
-
-#define SFAFSR_ME              (_AC(1,UL) << SFAFSR_ME_SHIFT)
-#define SFAFSR_ME_SHIFT                32
-#define SFAFSR_PRIV            (_AC(1,UL) << SFAFSR_PRIV_SHIFT)
-#define SFAFSR_PRIV_SHIFT      31
-#define SFAFSR_ISAP            (_AC(1,UL) << SFAFSR_ISAP_SHIFT)
-#define SFAFSR_ISAP_SHIFT      30
-#define SFAFSR_ETP             (_AC(1,UL) << SFAFSR_ETP_SHIFT)
-#define SFAFSR_ETP_SHIFT       29
-#define SFAFSR_IVUE            (_AC(1,UL) << SFAFSR_IVUE_SHIFT)
-#define SFAFSR_IVUE_SHIFT      28
-#define SFAFSR_TO              (_AC(1,UL) << SFAFSR_TO_SHIFT)
-#define SFAFSR_TO_SHIFT                27
-#define SFAFSR_BERR            (_AC(1,UL) << SFAFSR_BERR_SHIFT)
-#define SFAFSR_BERR_SHIFT      26
-#define SFAFSR_LDP             (_AC(1,UL) << SFAFSR_LDP_SHIFT)
-#define SFAFSR_LDP_SHIFT       25
-#define SFAFSR_CP              (_AC(1,UL) << SFAFSR_CP_SHIFT)
-#define SFAFSR_CP_SHIFT                24
-#define SFAFSR_WP              (_AC(1,UL) << SFAFSR_WP_SHIFT)
-#define SFAFSR_WP_SHIFT                23
-#define SFAFSR_EDP             (_AC(1,UL) << SFAFSR_EDP_SHIFT)
-#define SFAFSR_EDP_SHIFT       22
-#define SFAFSR_UE              (_AC(1,UL) << SFAFSR_UE_SHIFT)
-#define SFAFSR_UE_SHIFT                21
-#define SFAFSR_CE              (_AC(1,UL) << SFAFSR_CE_SHIFT)
-#define SFAFSR_CE_SHIFT                20
-#define SFAFSR_ETS             (_AC(0xf,UL) << SFAFSR_ETS_SHIFT)
-#define SFAFSR_ETS_SHIFT       16
-#define SFAFSR_PSYND           (_AC(0xffff,UL) << SFAFSR_PSYND_SHIFT)
-#define SFAFSR_PSYND_SHIFT     0
-
-/* UDB Error Register, ASI=0x7f VA<63:0>=0x0(High),0x18(Low) for read
- *                     ASI=0x77 VA<63:0>=0x0(High),0x18(Low) for write
- */
-
-#define UDBE_UE                        (_AC(1,UL) << 9)
-#define UDBE_CE                        (_AC(1,UL) << 8)
-#define UDBE_E_SYNDR           (_AC(0xff,UL) << 0)
-
-/* The trap handlers for asynchronous errors encode the AFSR and
- * other pieces of information into a 64-bit argument for C code
- * encoded as follows:
- *
- * -----------------------------------------------
- * |  UDB_H  |  UDB_L  | TL>1  |  TT  |   AFSR   |
- * -----------------------------------------------
- *  63     54 53     44    42   41  33 32       0
- *
- * The AFAR is passed in unchanged.
- */
-#define SFSTAT_UDBH_MASK       (_AC(0x3ff,UL) << SFSTAT_UDBH_SHIFT)
-#define SFSTAT_UDBH_SHIFT      54
-#define SFSTAT_UDBL_MASK       (_AC(0x3ff,UL) << SFSTAT_UDBH_SHIFT)
-#define SFSTAT_UDBL_SHIFT      44
-#define SFSTAT_TL_GT_ONE       (_AC(1,UL) << SFSTAT_TL_GT_ONE_SHIFT)
-#define SFSTAT_TL_GT_ONE_SHIFT 42
-#define SFSTAT_TRAP_TYPE       (_AC(0x1FF,UL) << SFSTAT_TRAP_TYPE_SHIFT)
-#define SFSTAT_TRAP_TYPE_SHIFT 33
-#define SFSTAT_AFSR_MASK       (_AC(0x1ffffffff,UL) << SFSTAT_AFSR_SHIFT)
-#define SFSTAT_AFSR_SHIFT      0
-
-/* ESTATE Error Enable Register, ASI=0x4b VA<63:0>=0x0 */
-#define ESTATE_ERR_CE          0x1 /* Correctable errors                    */
-#define ESTATE_ERR_NCE         0x2 /* TO, BERR, LDP, ETP, EDP, WP, UE, IVUE */
-#define ESTATE_ERR_ISAP                0x4 /* System address parity error           */
-#define ESTATE_ERR_ALL         (ESTATE_ERR_CE | \
-                                ESTATE_ERR_NCE | \
-                                ESTATE_ERR_ISAP)
-
-/* The various trap types that report using the above state. */
-#define TRAP_TYPE_IAE          0x09 /* Instruction Access Error             */
-#define TRAP_TYPE_DAE          0x32 /* Data Access Error                    */
-#define TRAP_TYPE_CEE          0x63 /* Correctable ECC Error                */
-
-#endif /* _SPARC64_SFAFSR_H */
+#include <asm-sparc/sfafsr.h>
index c9331b02d9c85df91a829906c1dfa5b1c79af04e..7bbc4fecdc7d5d50430f25851b58f6382177b4c4 100644 (file)
@@ -1,93 +1 @@
-/* Machine-dependent software floating-point definitions.
-   Sparc64 kernel version.
-   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Richard Henderson (rth@cygnus.com),
-                 Jakub Jelinek (jj@ultra.linux.cz) and
-                 David S. Miller (davem@redhat.com).
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If
-   not, write to the Free Software Foundation, Inc.,
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#ifndef _SFP_MACHINE_H
-#define _SFP_MACHINE_H
-   
-#define _FP_W_TYPE_SIZE                64
-#define _FP_W_TYPE             unsigned long
-#define _FP_WS_TYPE            signed long
-#define _FP_I_TYPE             long
-
-#define _FP_MUL_MEAT_S(R,X,Y)                                  \
-  _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
-#define _FP_MUL_MEAT_D(R,X,Y)                                  \
-  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_Q(R,X,Y)                                  \
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
-#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
-#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 1) - 1)
-#define _FP_NANFRAC_D          ((_FP_QNANBIT_D << 1) - 1)
-#define _FP_NANFRAC_Q          ((_FP_QNANBIT_Q << 1) - 1), -1
-#define _FP_NANSIGN_S          0
-#define _FP_NANSIGN_D          0
-#define _FP_NANSIGN_Q          0
-
-#define _FP_KEEPNANFRACP 1
-
-/* If one NaN is signaling and the other is not,
- * we choose that one, otherwise we choose X.
- */
-/* For _Qp_* and _Q_*, this should prefer X, for
- * CPU instruction emulation this should prefer Y.
- * (see SPAMv9 B.2.2 section).
- */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
-  do {                                                         \
-    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)         \
-       && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))     \
-      {                                                                \
-       R##_s = X##_s;                                          \
-       _FP_FRAC_COPY_##wc(R,X);                                \
-      }                                                                \
-    else                                                       \
-      {                                                                \
-       R##_s = Y##_s;                                          \
-       _FP_FRAC_COPY_##wc(R,Y);                                \
-      }                                                                \
-    R##_c = FP_CLS_NAN;                                                \
-  } while (0)
-
-/* Obtain the current rounding mode. */
-#ifndef FP_ROUNDMODE
-#define FP_ROUNDMODE   ((current_thread_info()->xfsr[0] >> 30) & 0x3)
-#endif
-
-/* Exception flags. */
-#define FP_EX_INVALID          (1 << 4)
-#define FP_EX_OVERFLOW         (1 << 3)
-#define FP_EX_UNDERFLOW                (1 << 2)
-#define FP_EX_DIVZERO          (1 << 1)
-#define FP_EX_INEXACT          (1 << 0)
-
-#define FP_HANDLE_EXCEPTIONS return _fex
-
-#define FP_INHIBIT_RESULTS ((current_thread_info()->xfsr[0] >> 23) & _fex)
-
-#define FP_TRAPPING_EXCEPTIONS ((current_thread_info()->xfsr[0] >> 23) & 0x1f)
-
-#endif
+#include <asm-sparc/sfp-machine.h>
index 61c2ef42eba3d6c33728e787257eb9679331cb40..0c54a2d68681b432a27d8b195fa8591573d5b432 100644 (file)
@@ -1,38 +1 @@
-#ifndef _SPARC64_SHMBUF_H
-#define _SPARC64_SHMBUF_H
-
-/* 
- * The shmid64_ds structure for sparc64 architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 2 miscellaneous 64-bit values
- */
-
-struct shmid64_ds {
-       struct ipc64_perm       shm_perm;       /* operation perms */
-       __kernel_time_t         shm_atime;      /* last attach time */
-       __kernel_time_t         shm_dtime;      /* last detach time */
-       __kernel_time_t         shm_ctime;      /* last change time */
-       size_t                  shm_segsz;      /* size of segment (bytes) */
-       __kernel_pid_t          shm_cpid;       /* pid of creator */
-       __kernel_pid_t          shm_lpid;       /* pid of last operator */
-       unsigned long           shm_nattch;     /* no. of current attaches */
-       unsigned long           __unused1;
-       unsigned long           __unused2;
-};
-
-struct shminfo64 {
-       unsigned long   shmmax;
-       unsigned long   shmmin;
-       unsigned long   shmmni;
-       unsigned long   shmseg;
-       unsigned long   shmall;
-       unsigned long   __unused1;
-       unsigned long   __unused2;
-       unsigned long   __unused3;
-       unsigned long   __unused4;
-};
-
-#endif /* _SPARC64_SHMBUF_H */
+#include <asm-sparc/shmbuf.h>
index 1ed0d6701a9b651221aa847c4b4ad5aed3feef47..5fa3a9b05e7fc7f4c9c56ff5e9682e6f9fefe786 100644 (file)
@@ -1,10 +1 @@
-#ifndef _ASMSPARC64_SHMPARAM_H
-#define _ASMSPARC64_SHMPARAM_H
-
-#include <asm/spitfire.h>
-
-#define __ARCH_FORCE_SHMLBA    1
-/* attach addr a multiple of this */
-#define        SHMLBA  ((PAGE_SIZE > L1DCACHE_SIZE) ? PAGE_SIZE : L1DCACHE_SIZE)
-
-#endif /* _ASMSPARC64_SHMPARAM_H */
+#include <asm-sparc/shmparam.h>
index 1c868d680cfc1d3d5f0a5c73463fb7021f222440..5b16dcce44f249b4c64db49915d5e15820028be4 100644 (file)
@@ -1,87 +1 @@
-#ifndef __SPARC64_SIGCONTEXT_H
-#define __SPARC64_SIGCONTEXT_H
-
-#ifdef __KERNEL__
-#include <asm/ptrace.h>
-#endif
-
-#ifndef __ASSEMBLY__
-
-#ifdef __KERNEL__
-
-#define __SUNOS_MAXWIN   31
-
-/* This is what SunOS does, so shall I unless we use new 32bit signals or rt signals. */
-struct sigcontext32 {
-       int sigc_onstack;      /* state to restore */
-       int sigc_mask;         /* sigmask to restore */
-       int sigc_sp;           /* stack pointer */
-       int sigc_pc;           /* program counter */
-       int sigc_npc;          /* next program counter */
-       int sigc_psr;          /* for condition codes etc */
-       int sigc_g1;           /* User uses these two registers */
-       int sigc_o0;           /* within the trampoline code. */
-
-       /* Now comes information regarding the users window set
-        * at the time of the signal.
-        */
-       int sigc_oswins;       /* outstanding windows */
-
-       /* stack ptrs for each regwin buf */
-       unsigned sigc_spbuf[__SUNOS_MAXWIN];
-
-       /* Windows to restore after signal */
-       struct reg_window32 sigc_wbuf[__SUNOS_MAXWIN];
-};
-
-#endif
-
-#ifdef __KERNEL__
-
-/* This is what we use for 32bit new non-rt signals. */
-
-typedef struct {
-       struct {
-               unsigned int psr;
-               unsigned int pc;
-               unsigned int npc;
-               unsigned int y;
-               unsigned int u_regs[16]; /* globals and ins */
-       }                       si_regs;
-       int                     si_mask;
-} __siginfo32_t;
-
-#endif
-
-typedef struct {
-       unsigned   int si_float_regs [64];
-       unsigned   long si_fsr;
-       unsigned   long si_gsr;
-       unsigned   long si_fprs;
-} __siginfo_fpu_t;
-
-/* This is what SunOS doesn't, so we have to write this alone
-   and do it properly. */
-struct sigcontext {
-       /* The size of this array has to match SI_MAX_SIZE from siginfo.h */
-       char                    sigc_info[128];
-       struct {
-               unsigned long   u_regs[16]; /* globals and ins */
-               unsigned long   tstate;
-               unsigned long   tpc;
-               unsigned long   tnpc;
-               unsigned int    y;
-               unsigned int    fprs;
-       }                       sigc_regs;
-       __siginfo_fpu_t *       sigc_fpu_save;
-       struct {
-               void    *       ss_sp;
-               int             ss_flags;
-               unsigned long   ss_size;
-       }                       sigc_stack;
-       unsigned long           sigc_mask;
-};
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(__SPARC64_SIGCONTEXT_H) */
+#include <asm-sparc/sigcontext.h>
index c96e6c30f8b0580c1738b722ea441f3f69fd4a1f..8ffd6ebabc7aae851a7323abae895cbe9d5a08ba 100644 (file)
@@ -1,32 +1 @@
-#ifndef _SPARC64_SIGINFO_H
-#define _SPARC64_SIGINFO_H
-
-#define SI_PAD_SIZE32  ((SI_MAX_SIZE/sizeof(int)) - 3)
-
-#define __ARCH_SI_PREAMBLE_SIZE        (4 * sizeof(int))
-#define __ARCH_SI_TRAPNO
-#define __ARCH_SI_BAND_T int
-
-#include <asm-generic/siginfo.h>
-
-#ifdef __KERNEL__
-
-#include <linux/compat.h>
-
-#ifdef CONFIG_COMPAT
-
-struct compat_siginfo;
-
-#endif /* CONFIG_COMPAT */
-
-#endif /* __KERNEL__ */
-
-#define SI_NOINFO      32767           /* no information in siginfo_t */
-
-/*
- * SIGEMT si_codes
- */
-#define EMT_TAGOVF     (__SI_FAULT|1)  /* tag overflow */
-#define NSIGEMT                1
-
-#endif
+#include <asm-sparc/siginfo.h>
index 2a7c7934ac0ae3206ee8d1daecbbcd7ae7906683..79705e5d49c34c2bd56690f1884d809bffc31866 100644 (file)
@@ -1,194 +1 @@
-#ifndef _ASMSPARC64_SIGNAL_H
-#define _ASMSPARC64_SIGNAL_H
-
-#include <asm/sigcontext.h>
-
-#ifdef __KERNEL__
-#ifndef __ASSEMBLY__
-#include <linux/personality.h>
-#include <linux/types.h>
-#endif
-#endif
-
-/* On the Sparc the signal handlers get passed a 'sub-signal' code
- * for certain signal types, which we document here.
- */
-#define SIGHUP          1
-#define SIGINT          2
-#define SIGQUIT                 3
-#define SIGILL          4
-#define    SUBSIG_STACK       0
-#define    SUBSIG_ILLINST     2
-#define    SUBSIG_PRIVINST    3
-#define    SUBSIG_BADTRAP(t)  (0x80 + (t))
-
-#define SIGTRAP                 5
-#define SIGABRT                 6
-#define SIGIOT          6
-
-#define SIGEMT           7
-#define    SUBSIG_TAG    10
-
-#define SIGFPE          8
-#define    SUBSIG_FPDISABLED     0x400
-#define    SUBSIG_FPERROR        0x404
-#define    SUBSIG_FPINTOVFL      0x001
-#define    SUBSIG_FPSTSIG        0x002
-#define    SUBSIG_IDIVZERO       0x014
-#define    SUBSIG_FPINEXACT      0x0c4
-#define    SUBSIG_FPDIVZERO      0x0c8
-#define    SUBSIG_FPUNFLOW       0x0cc
-#define    SUBSIG_FPOPERROR      0x0d0
-#define    SUBSIG_FPOVFLOW       0x0d4
-
-#define SIGKILL                 9
-#define SIGBUS          10
-#define    SUBSIG_BUSTIMEOUT    1
-#define    SUBSIG_ALIGNMENT     2
-#define    SUBSIG_MISCERROR     5
-
-#define SIGSEGV                11
-#define    SUBSIG_NOMAPPING     3
-#define    SUBSIG_PROTECTION    4
-#define    SUBSIG_SEGERROR      5
-
-#define SIGSYS         12
-
-#define SIGPIPE                13
-#define SIGALRM                14
-#define SIGTERM                15
-#define SIGURG          16
-
-/* SunOS values which deviate from the Linux/i386 ones */
-#define SIGSTOP                17
-#define SIGTSTP                18
-#define SIGCONT                19
-#define SIGCHLD                20
-#define SIGTTIN                21
-#define SIGTTOU                22
-#define SIGIO          23
-#define SIGPOLL                SIGIO   /* SysV name for SIGIO */
-#define SIGXCPU                24
-#define SIGXFSZ                25
-#define SIGVTALRM      26
-#define SIGPROF                27
-#define SIGWINCH       28
-#define SIGLOST                29
-#define SIGPWR         SIGLOST
-#define SIGUSR1                30
-#define SIGUSR2                31
-
-/* Most things should be clean enough to redefine this at will, if care
-   is taken to make libc match.  */
-
-#define __OLD_NSIG     32
-#define __NEW_NSIG      64
-#define _NSIG_BPW      64
-#define _NSIG_WORDS    (__NEW_NSIG / _NSIG_BPW)
-
-#define SIGRTMIN       32
-#define SIGRTMAX       __NEW_NSIG
-
-#if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
-#define _NSIG                  __NEW_NSIG
-#define __new_sigset_t         sigset_t
-#define __new_sigaction                sigaction
-#define __new_sigaction32      sigaction32
-#define __old_sigset_t         old_sigset_t
-#define __old_sigaction                old_sigaction
-#define __old_sigaction32      old_sigaction32
-#else
-#define _NSIG                  __OLD_NSIG
-#define NSIG                   _NSIG
-#define __old_sigset_t         sigset_t
-#define __old_sigaction                sigaction
-#define __old_sigaction32      sigaction32
-#endif
-
-#ifndef __ASSEMBLY__
-
-typedef unsigned long __old_sigset_t;            /* at least 32 bits */
-
-typedef struct {
-       unsigned long sig[_NSIG_WORDS];
-} __new_sigset_t;
-
-/* A SunOS sigstack */
-struct sigstack {
-       /* XXX 32-bit pointers pinhead XXX */
-       char *the_stack;
-       int   cur_status;
-};
-
-/* Sigvec flags */
-#define _SV_SSTACK    1u    /* This signal handler should use sig-stack */
-#define _SV_INTR      2u    /* Sig return should not restart system call */
-#define _SV_RESET     4u    /* Set handler to SIG_DFL upon taken signal */
-#define _SV_IGNCHILD  8u    /* Do not send SIGCHLD */
-
-/*
- * sa_flags values: SA_STACK is not currently supported, but will allow the
- * usage of signal stacks by using the (now obsolete) sa_restorer field in
- * the sigaction structure as a stack pointer. This is now possible due to
- * the changes in signal handling. LBT 010493.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- */
-#define SA_NOCLDSTOP   _SV_IGNCHILD
-#define SA_STACK       _SV_SSTACK
-#define SA_ONSTACK     _SV_SSTACK
-#define SA_RESTART     _SV_INTR
-#define SA_ONESHOT     _SV_RESET
-#define SA_NOMASK      0x20u
-#define SA_NOCLDWAIT    0x100u
-#define SA_SIGINFO      0x200u
-
-
-#define SIG_BLOCK          0x01        /* for blocking signals */
-#define SIG_UNBLOCK        0x02        /* for unblocking signals */
-#define SIG_SETMASK        0x04        /* for setting the signal mask */
-
-/* 
- * sigaltstack controls
- */
-#define SS_ONSTACK     1
-#define SS_DISABLE     2
-
-#define MINSIGSTKSZ    4096
-#define SIGSTKSZ       16384
-
-#include <asm-generic/signal.h>
-
-struct __new_sigaction {
-       __sighandler_t          sa_handler;
-       unsigned long           sa_flags;
-       __sigrestore_t          sa_restorer;  /* not used by Linux/SPARC yet */
-       __new_sigset_t          sa_mask;
-};
-
-struct __old_sigaction {
-       __sighandler_t          sa_handler;
-       __old_sigset_t          sa_mask;
-       unsigned long           sa_flags;
-       void                    (*sa_restorer)(void);     /* not used by Linux/SPARC yet */
-};
-
-typedef struct sigaltstack {
-       void                    __user *ss_sp;
-       int                     ss_flags;
-       size_t                  ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
-
-struct k_sigaction {
-       struct __new_sigaction  sa;
-       void __user             *ka_restorer;
-};
-
-#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-
-#endif /* !(__KERNEL__) */
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(_ASMSPARC64_SIGNAL_H) */
+#include <asm-sparc/signal.h>
index cd0311b2e19dbf63173cde102650b19bea84ddc8..5095a2cbea5215ce26e084583a7829e773d9f5fd 100644 (file)
@@ -1,64 +1 @@
-/* smp.h: Sparc64 specific SMP stuff.
- *
- * Copyright (C) 1996, 2008 David S. Miller (davem@davemloft.net)
- */
-
-#ifndef _SPARC64_SMP_H
-#define _SPARC64_SMP_H
-
-#include <linux/threads.h>
-#include <asm/asi.h>
-#include <asm/starfire.h>
-#include <asm/spitfire.h>
-
-#ifndef __ASSEMBLY__
-
-#include <linux/cpumask.h>
-#include <linux/cache.h>
-
-#endif /* !(__ASSEMBLY__) */
-
-#ifdef CONFIG_SMP
-
-#ifndef __ASSEMBLY__
-
-/*
- *     Private routines/data
- */
-#include <linux/bitops.h>
-#include <asm/atomic.h>
-#include <asm/percpu.h>
-
-DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
-extern cpumask_t cpu_core_map[NR_CPUS];
-extern int sparc64_multi_core;
-
-/*
- *     General functions that each host system must provide.
- */
-
-extern int hard_smp_processor_id(void);
-#define raw_smp_processor_id() (current_thread_info()->cpu)
-
-extern void smp_fill_in_sib_core_maps(void);
-extern void cpu_play_dead(void);
-
-extern void smp_fetch_global_regs(void);
-
-#ifdef CONFIG_HOTPLUG_CPU
-extern int __cpu_disable(void);
-extern void __cpu_die(unsigned int cpu);
-#endif
-
-#endif /* !(__ASSEMBLY__) */
-
-#else
-
-#define hard_smp_processor_id()                0
-#define smp_fill_in_sib_core_maps() do { } while (0)
-#define smp_fetch_global_regs() do { } while (0)
-
-#endif /* !(CONFIG_SMP) */
-
-#endif /* !(_SPARC64_SMP_H) */
+#include <asm-sparc/smp.h>
index 5af688f56716f5e100905fdf6b6394c5f962b85a..13e0d5d94bb34bad3973156ca5c09d1ca85f081a 100644 (file)
@@ -1,57 +1 @@
-#ifndef _ASM_SOCKET_H
-#define _ASM_SOCKET_H
-
-#include <asm/sockios.h>
-
-/* For setsockopt(2) */
-#define SOL_SOCKET     0xffff
-
-#define SO_DEBUG       0x0001
-#define SO_PASSCRED    0x0002
-#define SO_REUSEADDR   0x0004
-#define SO_KEEPALIVE   0x0008
-#define SO_DONTROUTE   0x0010
-#define SO_BROADCAST   0x0020
-#define SO_PEERCRED    0x0040
-#define SO_LINGER      0x0080
-#define SO_OOBINLINE   0x0100
-/* To add :#define SO_REUSEPORT 0x0200 */
-#define SO_BSDCOMPAT    0x0400
-#define SO_RCVLOWAT     0x0800
-#define SO_SNDLOWAT     0x1000
-#define SO_RCVTIMEO     0x2000
-#define SO_SNDTIMEO     0x4000
-#define SO_ACCEPTCONN  0x8000
-
-#define SO_SNDBUF      0x1001
-#define SO_RCVBUF      0x1002
-#define SO_SNDBUFFORCE 0x100a
-#define SO_RCVBUFFORCE 0x100b
-#define SO_ERROR       0x1007
-#define SO_TYPE                0x1008
-
-/* Linux specific, keep the same. */
-#define SO_NO_CHECK    0x000b
-#define SO_PRIORITY    0x000c
-
-#define SO_BINDTODEVICE 0x000d
-
-#define SO_ATTACH_FILTER       0x001a
-#define SO_DETACH_FILTER        0x001b
-
-#define SO_PEERNAME            0x001c
-#define SO_TIMESTAMP           0x001d
-#define SCM_TIMESTAMP          SO_TIMESTAMP
-
-#define SO_PEERSEC             0x001e
-#define SO_PASSSEC             0x001f
-#define SO_TIMESTAMPNS         0x0021
-#define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
-
-/* Security levels - as per NRL IPv6 - don't actually do anything */
-#define SO_SECURITY_AUTHENTICATION             0x5001
-#define SO_SECURITY_ENCRYPTION_TRANSPORT       0x5002
-#define SO_SECURITY_ENCRYPTION_NETWORK         0x5004
-
-#define SO_MARK                        0x0022
-#endif /* _ASM_SOCKET_H */
+#include <asm-sparc/socket.h>
index c7d9900638d0da5ffd762a46f88a2c130e201a26..2cb4b641482cd9b96c55dc4b3819dfba7b05379d 100644 (file)
@@ -1,14 +1 @@
-#ifndef _ASM_SPARC64_SOCKIOS_H
-#define _ASM_SPARC64_SOCKIOS_H
-
-/* Socket-level I/O control calls. */
-#define FIOSETOWN      0x8901
-#define SIOCSPGRP      0x8902
-#define FIOGETOWN      0x8903
-#define SIOCGPGRP      0x8904
-#define SIOCATMARK     0x8905
-#define SIOCGSTAMP     0x8906          /* Get stamp (timeval) */
-#define SIOCGSTAMPNS   0x8907          /* Get stamp (timespec) */
-
-#endif /* !(_ASM_SPARC64_SOCKIOS_H) */
-
+#include <asm-sparc/sockios.h>
index b99d4e4b6d284a6a93d6d9450de4f3da2e446b61..e681f22a97ae666b59f0fabbcfa7b867e160c0dc 100644 (file)
@@ -1,12 +1 @@
-#ifndef _SPARC64_SPARSEMEM_H
-#define _SPARC64_SPARSEMEM_H
-
-#ifdef __KERNEL__
-
-#define SECTION_SIZE_BITS       30
-#define MAX_PHYSADDR_BITS       42
-#define MAX_PHYSMEM_BITS        42
-
-#endif /* !(__KERNEL__) */
-
-#endif /* !(_SPARC64_SPARSEMEM_H) */
+#include <asm-sparc/sparsemem.h>
index 0006fe9f8c7a03cab556cec5119ad5c016608e74..0115b8156eb8d57b7140f65679901bd254edd055 100644 (file)
@@ -1,250 +1 @@
-/* spinlock.h: 64-bit Sparc spinlock support.
- *
- * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef __SPARC64_SPINLOCK_H
-#define __SPARC64_SPINLOCK_H
-
-#include <linux/threads.h>     /* For NR_CPUS */
-
-#ifndef __ASSEMBLY__
-
-/* To get debugging spinlocks which detect and catch
- * deadlock situations, set CONFIG_DEBUG_SPINLOCK
- * and rebuild your kernel.
- */
-
-/* All of these locking primitives are expected to work properly
- * even in an RMO memory model, which currently is what the kernel
- * runs in.
- *
- * There is another issue.  Because we play games to save cycles
- * in the non-contention case, we need to be extra careful about
- * branch targets into the "spinning" code.  They live in their
- * own section, but the newer V9 branches have a shorter range
- * than the traditional 32-bit sparc branch variants.  The rule
- * is that the branches that go into and out of the spinner sections
- * must be pre-V9 branches.
- */
-
-#define __raw_spin_is_locked(lp)       ((lp)->lock != 0)
-
-#define __raw_spin_unlock_wait(lp)     \
-       do {    rmb();                  \
-       } while((lp)->lock)
-
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
-{
-       unsigned long tmp;
-
-       __asm__ __volatile__(
-"1:    ldstub          [%1], %0\n"
-"      membar          #StoreLoad | #StoreStore\n"
-"      brnz,pn         %0, 2f\n"
-"       nop\n"
-"      .subsection     2\n"
-"2:    ldub            [%1], %0\n"
-"      membar          #LoadLoad\n"
-"      brnz,pt         %0, 2b\n"
-"       nop\n"
-"      ba,a,pt         %%xcc, 1b\n"
-"      .previous"
-       : "=&r" (tmp)
-       : "r" (lock)
-       : "memory");
-}
-
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
-{
-       unsigned long result;
-
-       __asm__ __volatile__(
-"      ldstub          [%1], %0\n"
-"      membar          #StoreLoad | #StoreStore"
-       : "=r" (result)
-       : "r" (lock)
-       : "memory");
-
-       return (result == 0UL);
-}
-
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
-{
-       __asm__ __volatile__(
-"      membar          #StoreStore | #LoadStore\n"
-"      stb             %%g0, [%0]"
-       : /* No outputs */
-       : "r" (lock)
-       : "memory");
-}
-
-static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
-{
-       unsigned long tmp1, tmp2;
-
-       __asm__ __volatile__(
-"1:    ldstub          [%2], %0\n"
-"      membar          #StoreLoad | #StoreStore\n"
-"      brnz,pn         %0, 2f\n"
-"       nop\n"
-"      .subsection     2\n"
-"2:    rdpr            %%pil, %1\n"
-"      wrpr            %3, %%pil\n"
-"3:    ldub            [%2], %0\n"
-"      membar          #LoadLoad\n"
-"      brnz,pt         %0, 3b\n"
-"       nop\n"
-"      ba,pt           %%xcc, 1b\n"
-"       wrpr           %1, %%pil\n"
-"      .previous"
-       : "=&r" (tmp1), "=&r" (tmp2)
-       : "r"(lock), "r"(flags)
-       : "memory");
-}
-
-/* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */
-
-static void inline __read_lock(raw_rwlock_t *lock)
-{
-       unsigned long tmp1, tmp2;
-
-       __asm__ __volatile__ (
-"1:    ldsw            [%2], %0\n"
-"      brlz,pn         %0, 2f\n"
-"4:     add            %0, 1, %1\n"
-"      cas             [%2], %0, %1\n"
-"      cmp             %0, %1\n"
-"      membar          #StoreLoad | #StoreStore\n"
-"      bne,pn          %%icc, 1b\n"
-"       nop\n"
-"      .subsection     2\n"
-"2:    ldsw            [%2], %0\n"
-"      membar          #LoadLoad\n"
-"      brlz,pt         %0, 2b\n"
-"       nop\n"
-"      ba,a,pt         %%xcc, 4b\n"
-"      .previous"
-       : "=&r" (tmp1), "=&r" (tmp2)
-       : "r" (lock)
-       : "memory");
-}
-
-static int inline __read_trylock(raw_rwlock_t *lock)
-{
-       int tmp1, tmp2;
-
-       __asm__ __volatile__ (
-"1:    ldsw            [%2], %0\n"
-"      brlz,a,pn       %0, 2f\n"
-"       mov            0, %0\n"
-"      add             %0, 1, %1\n"
-"      cas             [%2], %0, %1\n"
-"      cmp             %0, %1\n"
-"      membar          #StoreLoad | #StoreStore\n"
-"      bne,pn          %%icc, 1b\n"
-"       mov            1, %0\n"
-"2:"
-       : "=&r" (tmp1), "=&r" (tmp2)
-       : "r" (lock)
-       : "memory");
-
-       return tmp1;
-}
-
-static void inline __read_unlock(raw_rwlock_t *lock)
-{
-       unsigned long tmp1, tmp2;
-
-       __asm__ __volatile__(
-"      membar  #StoreLoad | #LoadLoad\n"
-"1:    lduw    [%2], %0\n"
-"      sub     %0, 1, %1\n"
-"      cas     [%2], %0, %1\n"
-"      cmp     %0, %1\n"
-"      bne,pn  %%xcc, 1b\n"
-"       nop"
-       : "=&r" (tmp1), "=&r" (tmp2)
-       : "r" (lock)
-       : "memory");
-}
-
-static void inline __write_lock(raw_rwlock_t *lock)
-{
-       unsigned long mask, tmp1, tmp2;
-
-       mask = 0x80000000UL;
-
-       __asm__ __volatile__(
-"1:    lduw            [%2], %0\n"
-"      brnz,pn         %0, 2f\n"
-"4:     or             %0, %3, %1\n"
-"      cas             [%2], %0, %1\n"
-"      cmp             %0, %1\n"
-"      membar          #StoreLoad | #StoreStore\n"
-"      bne,pn          %%icc, 1b\n"
-"       nop\n"
-"      .subsection     2\n"
-"2:    lduw            [%2], %0\n"
-"      membar          #LoadLoad\n"
-"      brnz,pt         %0, 2b\n"
-"       nop\n"
-"      ba,a,pt         %%xcc, 4b\n"
-"      .previous"
-       : "=&r" (tmp1), "=&r" (tmp2)
-       : "r" (lock), "r" (mask)
-       : "memory");
-}
-
-static void inline __write_unlock(raw_rwlock_t *lock)
-{
-       __asm__ __volatile__(
-"      membar          #LoadStore | #StoreStore\n"
-"      stw             %%g0, [%0]"
-       : /* no outputs */
-       : "r" (lock)
-       : "memory");
-}
-
-static int inline __write_trylock(raw_rwlock_t *lock)
-{
-       unsigned long mask, tmp1, tmp2, result;
-
-       mask = 0x80000000UL;
-
-       __asm__ __volatile__(
-"      mov             0, %2\n"
-"1:    lduw            [%3], %0\n"
-"      brnz,pn         %0, 2f\n"
-"       or             %0, %4, %1\n"
-"      cas             [%3], %0, %1\n"
-"      cmp             %0, %1\n"
-"      membar          #StoreLoad | #StoreStore\n"
-"      bne,pn          %%icc, 1b\n"
-"       nop\n"
-"      mov             1, %2\n"
-"2:"
-       : "=&r" (tmp1), "=&r" (tmp2), "=&r" (result)
-       : "r" (lock), "r" (mask)
-       : "memory");
-
-       return result;
-}
-
-#define __raw_read_lock(p)     __read_lock(p)
-#define __raw_read_trylock(p)  __read_trylock(p)
-#define __raw_read_unlock(p)   __read_unlock(p)
-#define __raw_write_lock(p)    __write_lock(p)
-#define __raw_write_unlock(p)  __write_unlock(p)
-#define __raw_write_trylock(p) __write_trylock(p)
-
-#define __raw_read_can_lock(rw)                (!((rw)->lock & 0x80000000UL))
-#define __raw_write_can_lock(rw)       (!(rw)->lock)
-
-#define _raw_spin_relax(lock)  cpu_relax()
-#define _raw_read_relax(lock)  cpu_relax()
-#define _raw_write_relax(lock) cpu_relax()
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(__SPARC64_SPINLOCK_H) */
+#include <asm-sparc/spinlock.h>
index e128112a0d7c811fe1e2b131249ec4f627e95aff..48d81c8734b5a9cb98c68ce300050733d1adda4a 100644 (file)
@@ -1,20 +1 @@
-#ifndef __SPARC64_SPINLOCK_TYPES_H
-#define __SPARC64_SPINLOCK_TYPES_H
-
-#ifndef __LINUX_SPINLOCK_TYPES_H
-# error "please don't include this file directly"
-#endif
-
-typedef struct {
-       volatile unsigned char lock;
-} raw_spinlock_t;
-
-#define __RAW_SPIN_LOCK_UNLOCKED       { 0 }
-
-typedef struct {
-       volatile unsigned int lock;
-} raw_rwlock_t;
-
-#define __RAW_RW_LOCK_UNLOCKED         { 0 }
-
-#endif
+#include <asm-sparc/spinlock_types.h>
index 985ea7e319927d2e7906c13956cd95dc5354289e..4430d2fbb0dcccbd15fc003182f49fa019f98730 100644 (file)
@@ -1,342 +1 @@
-/* spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations.
- *
- * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
- */
-
-#ifndef _SPARC64_SPITFIRE_H
-#define _SPARC64_SPITFIRE_H
-
-#include <asm/asi.h>
-
-/* The following register addresses are accessible via ASI_DMMU
- * and ASI_IMMU, that is there is a distinct and unique copy of
- * each these registers for each TLB.
- */
-#define TSB_TAG_TARGET         0x0000000000000000 /* All chips                         */
-#define TLB_SFSR               0x0000000000000018 /* All chips                         */
-#define TSB_REG                        0x0000000000000028 /* All chips                         */
-#define TLB_TAG_ACCESS         0x0000000000000030 /* All chips                         */
-#define VIRT_WATCHPOINT                0x0000000000000038 /* All chips                         */
-#define PHYS_WATCHPOINT                0x0000000000000040 /* All chips                         */
-#define TSB_EXTENSION_P                0x0000000000000048 /* Ultra-III and later               */
-#define TSB_EXTENSION_S                0x0000000000000050 /* Ultra-III and later, D-TLB only   */
-#define TSB_EXTENSION_N                0x0000000000000058 /* Ultra-III and later               */
-#define TLB_TAG_ACCESS_EXT     0x0000000000000060 /* Ultra-III+ and later              */
-
-/* These registers only exist as one entity, and are accessed
- * via ASI_DMMU only.
- */
-#define PRIMARY_CONTEXT                0x0000000000000008
-#define SECONDARY_CONTEXT      0x0000000000000010
-#define DMMU_SFAR              0x0000000000000020
-#define VIRT_WATCHPOINT                0x0000000000000038
-#define PHYS_WATCHPOINT                0x0000000000000040
-
-#define SPITFIRE_HIGHEST_LOCKED_TLBENT (64 - 1)
-#define CHEETAH_HIGHEST_LOCKED_TLBENT  (16 - 1)
-
-#define L1DCACHE_SIZE          0x4000
-
-#define SUN4V_CHIP_INVALID     0x00
-#define SUN4V_CHIP_NIAGARA1    0x01
-#define SUN4V_CHIP_NIAGARA2    0x02
-#define SUN4V_CHIP_UNKNOWN     0xff
-
-#ifndef __ASSEMBLY__
-
-enum ultra_tlb_layout {
-       spitfire = 0,
-       cheetah = 1,
-       cheetah_plus = 2,
-       hypervisor = 3,
-};
-
-extern enum ultra_tlb_layout tlb_type;
-
-extern int sun4v_chip_type;
-
-extern int cheetah_pcache_forced_on;
-extern void cheetah_enable_pcache(void);
-
-#define sparc64_highest_locked_tlbent()        \
-       (tlb_type == spitfire ? \
-        SPITFIRE_HIGHEST_LOCKED_TLBENT : \
-        CHEETAH_HIGHEST_LOCKED_TLBENT)
-
-extern int num_kernel_image_mappings;
-
-/* The data cache is write through, so this just invalidates the
- * specified line.
- */
-static inline void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag)
-{
-       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
-                            "membar    #Sync"
-                            : /* No outputs */
-                            : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG));
-}
-
-/* The instruction cache lines are flushed with this, but note that
- * this does not flush the pipeline.  It is possible for a line to
- * get flushed but stale instructions to still be in the pipeline,
- * a flush instruction (to any address) is sufficient to handle
- * this issue after the line is invalidated.
- */
-static inline void spitfire_put_icache_tag(unsigned long addr, unsigned long tag)
-{
-       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
-                            "membar    #Sync"
-                            : /* No outputs */
-                            : "r" (tag), "r" (addr), "i" (ASI_IC_TAG));
-}
-
-static inline unsigned long spitfire_get_dtlb_data(int entry)
-{
-       unsigned long data;
-
-       __asm__ __volatile__("ldxa      [%1] %2, %0"
-                            : "=r" (data)
-                            : "r" (entry << 3), "i" (ASI_DTLB_DATA_ACCESS));
-
-       /* Clear TTE diag bits. */
-       data &= ~0x0003fe0000000000UL;
-
-       return data;
-}
-
-static inline unsigned long spitfire_get_dtlb_tag(int entry)
-{
-       unsigned long tag;
-
-       __asm__ __volatile__("ldxa      [%1] %2, %0"
-                            : "=r" (tag)
-                            : "r" (entry << 3), "i" (ASI_DTLB_TAG_READ));
-       return tag;
-}
-
-static inline void spitfire_put_dtlb_data(int entry, unsigned long data)
-{
-       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
-                            "membar    #Sync"
-                            : /* No outputs */
-                            : "r" (data), "r" (entry << 3),
-                              "i" (ASI_DTLB_DATA_ACCESS));
-}
-
-static inline unsigned long spitfire_get_itlb_data(int entry)
-{
-       unsigned long data;
-
-       __asm__ __volatile__("ldxa      [%1] %2, %0"
-                            : "=r" (data)
-                            : "r" (entry << 3), "i" (ASI_ITLB_DATA_ACCESS));
-
-       /* Clear TTE diag bits. */
-       data &= ~0x0003fe0000000000UL;
-
-       return data;
-}
-
-static inline unsigned long spitfire_get_itlb_tag(int entry)
-{
-       unsigned long tag;
-
-       __asm__ __volatile__("ldxa      [%1] %2, %0"
-                            : "=r" (tag)
-                            : "r" (entry << 3), "i" (ASI_ITLB_TAG_READ));
-       return tag;
-}
-
-static inline void spitfire_put_itlb_data(int entry, unsigned long data)
-{
-       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
-                            "membar    #Sync"
-                            : /* No outputs */
-                            : "r" (data), "r" (entry << 3),
-                              "i" (ASI_ITLB_DATA_ACCESS));
-}
-
-static inline void spitfire_flush_dtlb_nucleus_page(unsigned long page)
-{
-       __asm__ __volatile__("stxa      %%g0, [%0] %1\n\t"
-                            "membar    #Sync"
-                            : /* No outputs */
-                            : "r" (page | 0x20), "i" (ASI_DMMU_DEMAP));
-}
-
-static inline void spitfire_flush_itlb_nucleus_page(unsigned long page)
-{
-       __asm__ __volatile__("stxa      %%g0, [%0] %1\n\t"
-                            "membar    #Sync"
-                            : /* No outputs */
-                            : "r" (page | 0x20), "i" (ASI_IMMU_DEMAP));
-}
-
-/* Cheetah has "all non-locked" tlb flushes. */
-static inline void cheetah_flush_dtlb_all(void)
-{
-       __asm__ __volatile__("stxa      %%g0, [%0] %1\n\t"
-                            "membar    #Sync"
-                            : /* No outputs */
-                            : "r" (0x80), "i" (ASI_DMMU_DEMAP));
-}
-
-static inline void cheetah_flush_itlb_all(void)
-{
-       __asm__ __volatile__("stxa      %%g0, [%0] %1\n\t"
-                            "membar    #Sync"
-                            : /* No outputs */
-                            : "r" (0x80), "i" (ASI_IMMU_DEMAP));
-}
-
-/* Cheetah has a 4-tlb layout so direct access is a bit different.
- * The first two TLBs are fully assosciative, hold 16 entries, and are
- * used only for locked and >8K sized translations.  One exists for
- * data accesses and one for instruction accesses.
- *
- * The third TLB is for data accesses to 8K non-locked translations, is
- * 2 way assosciative, and holds 512 entries.  The fourth TLB is for
- * instruction accesses to 8K non-locked translations, is 2 way
- * assosciative, and holds 128 entries.
- *
- * Cheetah has some bug where bogus data can be returned from
- * ASI_{D,I}TLB_DATA_ACCESS loads, doing the load twice fixes
- * the problem for me. -DaveM
- */
-static inline unsigned long cheetah_get_ldtlb_data(int entry)
-{
-       unsigned long data;
-
-       __asm__ __volatile__("ldxa      [%1] %2, %%g0\n\t"
-                            "ldxa      [%1] %2, %0"
-                            : "=r" (data)
-                            : "r" ((0 << 16) | (entry << 3)),
-                            "i" (ASI_DTLB_DATA_ACCESS));
-
-       return data;
-}
-
-static inline unsigned long cheetah_get_litlb_data(int entry)
-{
-       unsigned long data;
-
-       __asm__ __volatile__("ldxa      [%1] %2, %%g0\n\t"
-                            "ldxa      [%1] %2, %0"
-                            : "=r" (data)
-                            : "r" ((0 << 16) | (entry << 3)),
-                            "i" (ASI_ITLB_DATA_ACCESS));
-
-       return data;
-}
-
-static inline unsigned long cheetah_get_ldtlb_tag(int entry)
-{
-       unsigned long tag;
-
-       __asm__ __volatile__("ldxa      [%1] %2, %0"
-                            : "=r" (tag)
-                            : "r" ((0 << 16) | (entry << 3)),
-                            "i" (ASI_DTLB_TAG_READ));
-
-       return tag;
-}
-
-static inline unsigned long cheetah_get_litlb_tag(int entry)
-{
-       unsigned long tag;
-
-       __asm__ __volatile__("ldxa      [%1] %2, %0"
-                            : "=r" (tag)
-                            : "r" ((0 << 16) | (entry << 3)),
-                            "i" (ASI_ITLB_TAG_READ));
-
-       return tag;
-}
-
-static inline void cheetah_put_ldtlb_data(int entry, unsigned long data)
-{
-       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
-                            "membar    #Sync"
-                            : /* No outputs */
-                            : "r" (data),
-                              "r" ((0 << 16) | (entry << 3)),
-                              "i" (ASI_DTLB_DATA_ACCESS));
-}
-
-static inline void cheetah_put_litlb_data(int entry, unsigned long data)
-{
-       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
-                            "membar    #Sync"
-                            : /* No outputs */
-                            : "r" (data),
-                              "r" ((0 << 16) | (entry << 3)),
-                              "i" (ASI_ITLB_DATA_ACCESS));
-}
-
-static inline unsigned long cheetah_get_dtlb_data(int entry, int tlb)
-{
-       unsigned long data;
-
-       __asm__ __volatile__("ldxa      [%1] %2, %%g0\n\t"
-                            "ldxa      [%1] %2, %0"
-                            : "=r" (data)
-                            : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_DATA_ACCESS));
-
-       return data;
-}
-
-static inline unsigned long cheetah_get_dtlb_tag(int entry, int tlb)
-{
-       unsigned long tag;
-
-       __asm__ __volatile__("ldxa      [%1] %2, %0"
-                            : "=r" (tag)
-                            : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_TAG_READ));
-       return tag;
-}
-
-static inline void cheetah_put_dtlb_data(int entry, unsigned long data, int tlb)
-{
-       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
-                            "membar    #Sync"
-                            : /* No outputs */
-                            : "r" (data),
-                              "r" ((tlb << 16) | (entry << 3)),
-                              "i" (ASI_DTLB_DATA_ACCESS));
-}
-
-static inline unsigned long cheetah_get_itlb_data(int entry)
-{
-       unsigned long data;
-
-       __asm__ __volatile__("ldxa      [%1] %2, %%g0\n\t"
-                            "ldxa      [%1] %2, %0"
-                            : "=r" (data)
-                            : "r" ((2 << 16) | (entry << 3)),
-                               "i" (ASI_ITLB_DATA_ACCESS));
-
-       return data;
-}
-
-static inline unsigned long cheetah_get_itlb_tag(int entry)
-{
-       unsigned long tag;
-
-       __asm__ __volatile__("ldxa      [%1] %2, %0"
-                            : "=r" (tag)
-                            : "r" ((2 << 16) | (entry << 3)), "i" (ASI_ITLB_TAG_READ));
-       return tag;
-}
-
-static inline void cheetah_put_itlb_data(int entry, unsigned long data)
-{
-       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
-                            "membar    #Sync"
-                            : /* No outputs */
-                            : "r" (data), "r" ((2 << 16) | (entry << 3)),
-                              "i" (ASI_ITLB_DATA_ACCESS));
-}
-
-#endif /* !(__ASSEMBLY__) */
-
-#endif /* !(_SPARC64_SPITFIRE_H) */
+#include <asm-sparc/spitfire.h>
index a7c35dbcb2814d29120f546a2a529ca73e1a56c0..97720ce2fd4345af713dda94d22e1befece3c462 100644 (file)
@@ -1,13 +1 @@
-#ifndef _SPARC64_SSTATE_H
-#define _SPARC64_SSTATE_H
-
-extern void sstate_booting(void);
-extern void sstate_running(void);
-extern void sstate_halt(void);
-extern void sstate_poweroff(void);
-extern void sstate_panic(void);
-extern void sstate_reboot(void);
-
-extern void sun4v_sstate_init(void);
-
-#endif /* _SPARC64_SSTATE_H */
+#include <asm-sparc/sstate.h>
index 6cee39adf6d6156155582754324b295090a85df3..adc9b92c0ef1467df49c46bc63b586fdc024e061 100644 (file)
@@ -1,6 +1 @@
-#ifndef _SPARC64_STACKTRACE_H
-#define _SPARC64_STACKTRACE_H
-
-extern void stack_trace_flush(void);
-
-#endif /* _SPARC64_STACKTRACE_H */
+#include <asm-sparc/stacktrace.h>
index 07bafd31e33cd0f9a7d4dfc997202d84a6dd0c59..db97daa3bed489722293896eead48566f3aa51e9 100644 (file)
@@ -1,21 +1 @@
-/*
- * starfire.h: Group all starfire specific code together.
- *
- * Copyright (C) 2000 Anton Blanchard (anton@samba.org)
- */
-
-#ifndef _SPARC64_STARFIRE_H
-#define _SPARC64_STARFIRE_H
-
-#ifndef __ASSEMBLY__
-
-extern int this_is_starfire;
-
-extern void check_if_starfire(void);
-extern void starfire_cpu_setup(void);
-extern int starfire_hard_smp_processor_id(void);
-extern void starfire_hookup(int);
-extern unsigned int starfire_translate(unsigned long imap, unsigned int upaid);
-
-#endif
-#endif
+#include <asm-sparc/starfire.h>
index 9650fdea847f88a0863934ef199d54c6a81df2ca..b108a866256b80bca60ec9943e460dbefa6e169c 100644 (file)
@@ -1,47 +1 @@
-#ifndef _SPARC64_STAT_H
-#define _SPARC64_STAT_H
-
-#include <linux/types.h>
-
-struct stat {
-       unsigned   st_dev;
-       ino_t   st_ino;
-       mode_t  st_mode;
-       short   st_nlink;
-       uid_t   st_uid;
-       gid_t   st_gid;
-       unsigned   st_rdev;
-       off_t   st_size;
-       time_t  st_atime;
-       time_t  st_mtime;
-       time_t  st_ctime;
-       off_t   st_blksize;
-       off_t   st_blocks;
-       unsigned long  __unused4[2];
-};
-
-struct stat64 {
-       unsigned long   st_dev;
-       unsigned long   st_ino;
-       unsigned long   st_nlink;
-
-       unsigned int    st_mode;
-       unsigned int    st_uid;
-       unsigned int    st_gid;
-       unsigned int    __pad0;
-
-       unsigned long   st_rdev;
-       long            st_size;
-       long            st_blksize;
-       long            st_blocks;
-
-       unsigned long   st_atime;
-       unsigned long   st_atime_nsec;
-       unsigned long   st_mtime;
-       unsigned long   st_mtime_nsec;
-       unsigned long   st_ctime;
-       unsigned long   st_ctime_nsec;
-       long            __unused[3];
-};
-
-#endif
+#include <asm-sparc/stat.h>
index 79b3c890a5faac3f2d71182ce4b26c7c63c2cd3a..5503d6a4c67ee558ccecbe59383d01710d79156b 100644 (file)
@@ -1,54 +1 @@
-#ifndef _SPARC64_STATFS_H
-#define _SPARC64_STATFS_H
-
-#ifndef __KERNEL_STRICT_NAMES
-
-#include <linux/types.h>
-
-typedef __kernel_fsid_t        fsid_t;
-
-#endif
-
-struct statfs {
-       long f_type;
-       long f_bsize;
-       long f_blocks;
-       long f_bfree;
-       long f_bavail;
-       long f_files;
-       long f_ffree;
-       __kernel_fsid_t f_fsid;
-       long f_namelen;
-       long f_frsize;
-       long f_spare[5];
-};
-
-struct statfs64 {
-       long f_type;
-       long f_bsize;
-       long f_blocks;
-       long f_bfree;
-       long f_bavail;
-       long f_files;
-       long f_ffree;
-       __kernel_fsid_t f_fsid;
-       long f_namelen;
-       long f_frsize;
-       long f_spare[5];
-};
-
-struct compat_statfs64 {
-       __u32 f_type;
-       __u32 f_bsize;
-       __u64 f_blocks;
-       __u64 f_bfree;
-       __u64 f_bavail;
-       __u64 f_files;
-       __u64 f_ffree;
-       __kernel_fsid_t f_fsid;
-       __u32 f_namelen;
-       __u32 f_frsize;
-       __u32 f_spare[5];
-};
-
-#endif
+#include <asm-sparc/statfs.h>
index 43161f2d17eb7c61939290fb77606aae13034c76..5018cd8b6ad0415a183f23dcc7d33f0a5d428575 100644 (file)
@@ -1,83 +1 @@
-/*
- * string.h: External definitions for optimized assembly string
- *           routines for the Linux Kernel.
- *
- * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996,1997,1999 Jakub Jelinek (jakub@redhat.com)
- */
-
-#ifndef __SPARC64_STRING_H__
-#define __SPARC64_STRING_H__
-
-/* Really, userland/ksyms should not see any of this stuff. */
-
-#ifdef __KERNEL__
-
-#include <asm/asi.h>
-
-extern void *__memset(void *,int,__kernel_size_t);
-
-#ifndef EXPORT_SYMTAB_STROPS
-
-/* First the mem*() things. */
-#define __HAVE_ARCH_MEMMOVE
-extern void *memmove(void *, const void *, __kernel_size_t);
-
-#define __HAVE_ARCH_MEMCPY
-extern void *memcpy(void *, const void *, __kernel_size_t);
-
-#define __HAVE_ARCH_MEMSET
-extern void *__builtin_memset(void *,int,__kernel_size_t);
-
-static inline void *__constant_memset(void *s, int c, __kernel_size_t count)
-{
-       extern __kernel_size_t __bzero(void *, __kernel_size_t);
-
-       if (!c) {
-               __bzero(s, count);
-               return s;
-       } else
-               return __memset(s, c, count);
-}
-
-#undef memset
-#define memset(s, c, count) \
-((__builtin_constant_p(count) && (count) <= 32) ? \
- __builtin_memset((s), (c), (count)) : \
- (__builtin_constant_p(c) ? \
-  __constant_memset((s), (c), (count)) : \
-  __memset((s), (c), (count))))
-
-#define __HAVE_ARCH_MEMSCAN
-
-#undef memscan
-#define memscan(__arg0, __char, __arg2)                                        \
-({                                                                     \
-       extern void *__memscan_zero(void *, size_t);                    \
-       extern void *__memscan_generic(void *, int, size_t);            \
-       void *__retval, *__addr = (__arg0);                             \
-       size_t __size = (__arg2);                                       \
-                                                                       \
-       if(__builtin_constant_p(__char) && !(__char))                   \
-               __retval = __memscan_zero(__addr, __size);              \
-       else                                                            \
-               __retval = __memscan_generic(__addr, (__char), __size); \
-                                                                       \
-       __retval;                                                       \
-})
-
-#define __HAVE_ARCH_MEMCMP
-extern int memcmp(const void *,const void *,__kernel_size_t);
-
-/* Now the str*() stuff... */
-#define __HAVE_ARCH_STRLEN
-extern __kernel_size_t strlen(const char *);
-
-#define __HAVE_ARCH_STRNCMP
-extern int strncmp(const char *, const char *, __kernel_size_t);
-
-#endif /* !EXPORT_SYMTAB_STROPS */
-
-#endif /* __KERNEL__ */
-
-#endif /* !(__SPARC64_STRING_H__) */
+#include <asm-sparc/string.h>
index 8e171b7a9f4fff2912190f9e02ec380027e3eae1..9632be290eb55b02aa33ac4cad9ed5d7dd0b45a7 100644 (file)
@@ -1,80 +1 @@
-/*
- * include/asm-sparc64/sunbpp.h
- */
-
-#ifndef _ASM_SPARC64_SUNBPP_H
-#define _ASM_SPARC64_SUNBPP_H
-
-struct bpp_regs {
-  /* DMA registers */
-  __volatile__ __u32 p_csr;            /* DMA Control/Status Register */
-  __volatile__ __u32 p_addr;           /* Address Register */
-  __volatile__ __u32 p_bcnt;           /* Byte Count Register */
-  __volatile__ __u32 p_tst_csr;                /* Test Control/Status (DMA2 only) */
-  /* Parallel Port registers */
-  __volatile__ __u16 p_hcr;            /* Hardware Configuration Register */
-  __volatile__ __u16 p_ocr;            /* Operation Configuration Register */
-  __volatile__ __u8 p_dr;              /* Parallel Data Register */
-  __volatile__ __u8 p_tcr;             /* Transfer Control Register */
-  __volatile__ __u8 p_or;              /* Output Register */
-  __volatile__ __u8 p_ir;              /* Input Register */
-  __volatile__ __u16 p_icr;            /* Interrupt Control Register */
-};
-
-/* P_HCR. Time is in increments of SBus clock. */
-#define P_HCR_TEST      0x8000      /* Allows buried counters to be read */
-#define P_HCR_DSW       0x7f00      /* Data strobe width (in ticks) */
-#define P_HCR_DDS       0x007f      /* Data setup before strobe (in ticks) */
-
-/* P_OCR. */
-#define P_OCR_MEM_CLR   0x8000
-#define P_OCR_DATA_SRC  0x4000      /* )                  */
-#define P_OCR_DS_DSEL   0x2000      /* )  Bidirectional      */
-#define P_OCR_BUSY_DSEL 0x1000      /* )    selects            */
-#define P_OCR_ACK_DSEL  0x0800      /* )                  */
-#define P_OCR_EN_DIAG   0x0400
-#define P_OCR_BUSY_OP   0x0200      /* Busy operation */
-#define P_OCR_ACK_OP    0x0100      /* Ack operation */
-#define P_OCR_SRST      0x0080      /* Reset state machines. Not selfcleaning. */
-#define P_OCR_IDLE      0x0008      /* PP data transfer state machine is idle */
-#define P_OCR_V_ILCK    0x0002      /* Versatec faded. Zebra only. */
-#define P_OCR_EN_VER    0x0001      /* Enable Versatec (0 - enable). Zebra only. */
-
-/* P_TCR */
-#define P_TCR_DIR       0x08
-#define P_TCR_BUSY      0x04
-#define P_TCR_ACK       0x02
-#define P_TCR_DS        0x01        /* Strobe */
-
-/* P_OR */
-#define P_OR_V3         0x20        /* )                 */
-#define P_OR_V2         0x10        /* ) on Zebra only   */
-#define P_OR_V1         0x08        /* )                 */
-#define P_OR_INIT       0x04
-#define P_OR_AFXN       0x02        /* Auto Feed */
-#define P_OR_SLCT_IN    0x01
-
-/* P_IR */
-#define P_IR_PE         0x04
-#define P_IR_SLCT       0x02
-#define P_IR_ERR        0x01
-
-/* P_ICR */
-#define P_DS_IRQ        0x8000      /* RW1  */
-#define P_ACK_IRQ       0x4000      /* RW1  */
-#define P_BUSY_IRQ      0x2000      /* RW1  */
-#define P_PE_IRQ        0x1000      /* RW1  */
-#define P_SLCT_IRQ      0x0800      /* RW1  */
-#define P_ERR_IRQ       0x0400      /* RW1  */
-#define P_DS_IRQ_EN     0x0200      /* RW   Always on rising edge */
-#define P_ACK_IRQ_EN    0x0100      /* RW   Always on rising edge */
-#define P_BUSY_IRP      0x0080      /* RW   1= rising edge */
-#define P_BUSY_IRQ_EN   0x0040      /* RW   */
-#define P_PE_IRP        0x0020      /* RW   1= rising edge */
-#define P_PE_IRQ_EN     0x0010      /* RW   */
-#define P_SLCT_IRP      0x0008      /* RW   1= rising edge */
-#define P_SLCT_IRQ_EN   0x0004      /* RW   */
-#define P_ERR_IRP       0x0002      /* RW1  1= rising edge */
-#define P_ERR_IRQ_EN    0x0001      /* RW   */
-
-#endif /* !(_ASM_SPARC64_SUNBPP_H) */
+#include <asm-sparc/sunbpp.h>
index 45a43f637a1480291f6a85ef532c8717bb30046d..3477b16e30cacf926d6acc6caa7e76676220b4af 100644 (file)
@@ -1,13 +1 @@
-#ifndef _SPARC64_SYSCALLS_H
-#define _SPARC64_SYSCALLS_H
-
-struct pt_regs;
-
-extern asmlinkage long sparc_do_fork(unsigned long clone_flags,
-                                    unsigned long stack_start,
-                                    struct pt_regs *regs,
-                                    unsigned long stack_size);
-
-extern asmlinkage int sparc_execve(struct pt_regs *regs);
-
-#endif /* _SPARC64_SYSCALLS_H */
+#include <asm-sparc/syscalls.h>
index 6897ac31be4100baf733c45043294a36d4ed66bb..be2603c2e527d94dc4c3810b038a72671f24184c 100644 (file)
@@ -1,355 +1 @@
-#ifndef __SPARC64_SYSTEM_H
-#define __SPARC64_SYSTEM_H
-
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-#include <asm/visasm.h>
-
-#ifndef __ASSEMBLY__
-
-#include <linux/irqflags.h>
-#include <asm-generic/cmpxchg-local.h>
-
-/*
- * Sparc (general) CPU types
- */
-enum sparc_cpu {
-  sun4        = 0x00,
-  sun4c       = 0x01,
-  sun4m       = 0x02,
-  sun4d       = 0x03,
-  sun4e       = 0x04,
-  sun4u       = 0x05, /* V8 ploos ploos */
-  sun_unknown = 0x06,
-  ap1000      = 0x07, /* almost a sun4m */
-};
-                  
-#define sparc_cpu_model sun4u
-
-/* This cannot ever be a sun4c nor sun4 :) That's just history. */
-#define ARCH_SUN4C_SUN4 0
-#define ARCH_SUN4 0
-
-extern char reboot_command[];
-
-/* These are here in an effort to more fully work around Spitfire Errata
- * #51.  Essentially, if a memory barrier occurs soon after a mispredicted
- * branch, the chip can stop executing instructions until a trap occurs.
- * Therefore, if interrupts are disabled, the chip can hang forever.
- *
- * It used to be believed that the memory barrier had to be right in the
- * delay slot, but a case has been traced recently wherein the memory barrier
- * was one instruction after the branch delay slot and the chip still hung.
- * The offending sequence was the following in sym_wakeup_done() of the
- * sym53c8xx_2 driver:
- *
- *     call    sym_ccb_from_dsa, 0
- *      movge  %icc, 0, %l0
- *     brz,pn  %o0, .LL1303
- *      mov    %o0, %l2
- *     membar  #LoadLoad
- *
- * The branch has to be mispredicted for the bug to occur.  Therefore, we put
- * the memory barrier explicitly into a "branch always, predicted taken"
- * delay slot to avoid the problem case.
- */
-#define membar_safe(type) \
-do {   __asm__ __volatile__("ba,pt     %%xcc, 1f\n\t" \
-                            " membar   " type "\n" \
-                            "1:\n" \
-                            : : : "memory"); \
-} while (0)
-
-#define mb()   \
-       membar_safe("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad")
-#define rmb()  \
-       membar_safe("#LoadLoad")
-#define wmb()  \
-       membar_safe("#StoreStore")
-#define membar_storeload() \
-       membar_safe("#StoreLoad")
-#define membar_storeload_storestore() \
-       membar_safe("#StoreLoad | #StoreStore")
-#define membar_storeload_loadload() \
-       membar_safe("#StoreLoad | #LoadLoad")
-#define membar_storestore_loadstore() \
-       membar_safe("#StoreStore | #LoadStore")
-
-#endif
-
-#define nop()          __asm__ __volatile__ ("nop")
-
-#define read_barrier_depends()         do { } while(0)
-#define set_mb(__var, __value) \
-       do { __var = __value; membar_storeload_storestore(); } while(0)
-
-#ifdef CONFIG_SMP
-#define smp_mb()       mb()
-#define smp_rmb()      rmb()
-#define smp_wmb()      wmb()
-#define smp_read_barrier_depends()     read_barrier_depends()
-#else
-#define smp_mb()       __asm__ __volatile__("":::"memory")
-#define smp_rmb()      __asm__ __volatile__("":::"memory")
-#define smp_wmb()      __asm__ __volatile__("":::"memory")
-#define smp_read_barrier_depends()     do { } while(0)
-#endif
-
-#define flushi(addr)   __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory")
-
-#define flushw_all()   __asm__ __volatile__("flushw")
-
-/* Performance counter register access. */
-#define read_pcr(__p)  __asm__ __volatile__("rd        %%pcr, %0" : "=r" (__p))
-#define write_pcr(__p) __asm__ __volatile__("wr        %0, 0x0, %%pcr" : : "r" (__p))
-#define read_pic(__p)  __asm__ __volatile__("rd %%pic, %0" : "=r" (__p))
-
-/* Blackbird errata workaround.  See commentary in
- * arch/sparc64/kernel/smp.c:smp_percpu_timer_interrupt()
- * for more information.
- */
-#define reset_pic()                                                    \
-       __asm__ __volatile__("ba,pt     %xcc, 99f\n\t"          \
-                            ".align    64\n"                   \
-                         "99:wr        %g0, 0x0, %pic\n\t"     \
-                            "rd        %pic, %g0")
-
-#ifndef __ASSEMBLY__
-
-extern void sun_do_break(void);
-extern int stop_a_enabled;
-
-extern void fault_in_user_windows(void);
-extern void synchronize_user_stack(void);
-
-extern void __flushw_user(void);
-#define flushw_user() __flushw_user()
-
-#define flush_user_windows flushw_user
-#define flush_register_windows flushw_all
-
-/* Don't hold the runqueue lock over context switch */
-#define __ARCH_WANT_UNLOCKED_CTXSW
-#define prepare_arch_switch(next)              \
-do {                                           \
-       flushw_all();                           \
-} while (0)
-
-       /* See what happens when you design the chip correctly?
-        *
-        * We tell gcc we clobber all non-fixed-usage registers except
-        * for l0/l1.  It will use one for 'next' and the other to hold
-        * the output value of 'last'.  'next' is not referenced again
-        * past the invocation of switch_to in the scheduler, so we need
-        * not preserve it's value.  Hairy, but it lets us remove 2 loads
-        * and 2 stores in this critical code path.  -DaveM
-        */
-#define switch_to(prev, next, last)                                    \
-do {   if (test_thread_flag(TIF_PERFCTR)) {                            \
-               unsigned long __tmp;                                    \
-               read_pcr(__tmp);                                        \
-               current_thread_info()->pcr_reg = __tmp;                 \
-               read_pic(__tmp);                                        \
-               current_thread_info()->kernel_cntd0 += (unsigned int)(__tmp);\
-               current_thread_info()->kernel_cntd1 += ((__tmp) >> 32); \
-       }                                                               \
-       flush_tlb_pending();                                            \
-       save_and_clear_fpu();                                           \
-       /* If you are tempted to conditionalize the following */        \
-       /* so that ASI is only written if it changes, think again. */   \
-       __asm__ __volatile__("wr %%g0, %0, %%asi"                       \
-       : : "r" (__thread_flag_byte_ptr(task_thread_info(next))[TI_FLAG_BYTE_CURRENT_DS]));\
-       trap_block[current_thread_info()->cpu].thread =                 \
-               task_thread_info(next);                                 \
-       __asm__ __volatile__(                                           \
-       "mov    %%g4, %%g7\n\t"                                         \
-       "stx    %%i6, [%%sp + 2047 + 0x70]\n\t"                         \
-       "stx    %%i7, [%%sp + 2047 + 0x78]\n\t"                         \
-       "rdpr   %%wstate, %%o5\n\t"                                     \
-       "stx    %%o6, [%%g6 + %6]\n\t"                                  \
-       "stb    %%o5, [%%g6 + %5]\n\t"                                  \
-       "rdpr   %%cwp, %%o5\n\t"                                        \
-       "stb    %%o5, [%%g6 + %8]\n\t"                                  \
-       "mov    %4, %%g6\n\t"                                           \
-       "ldub   [%4 + %8], %%g1\n\t"                                    \
-       "wrpr   %%g1, %%cwp\n\t"                                        \
-       "ldx    [%%g6 + %6], %%o6\n\t"                                  \
-       "ldub   [%%g6 + %5], %%o5\n\t"                                  \
-       "ldub   [%%g6 + %7], %%o7\n\t"                                  \
-       "wrpr   %%o5, 0x0, %%wstate\n\t"                                \
-       "ldx    [%%sp + 2047 + 0x70], %%i6\n\t"                         \
-       "ldx    [%%sp + 2047 + 0x78], %%i7\n\t"                         \
-       "ldx    [%%g6 + %9], %%g4\n\t"                                  \
-       "brz,pt %%o7, switch_to_pc\n\t"                                 \
-       " mov   %%g7, %0\n\t"                                           \
-       "sethi  %%hi(ret_from_syscall), %%g1\n\t"                       \
-       "jmpl   %%g1 + %%lo(ret_from_syscall), %%g0\n\t"                \
-       " nop\n\t"                                                      \
-       ".globl switch_to_pc\n\t"                                       \
-       "switch_to_pc:\n\t"                                             \
-       : "=&r" (last), "=r" (current), "=r" (current_thread_info_reg), \
-         "=r" (__local_per_cpu_offset)                                 \
-       : "0" (task_thread_info(next)),                                 \
-         "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_NEW_CHILD),            \
-         "i" (TI_CWP), "i" (TI_TASK)                                   \
-       : "cc",                                                         \
-               "g1", "g2", "g3",                   "g7",               \
-               "l1", "l2", "l3", "l4", "l5", "l6", "l7",               \
-         "i0", "i1", "i2", "i3", "i4", "i5",                           \
-         "o0", "o1", "o2", "o3", "o4", "o5",       "o7");              \
-       /* If you fuck with this, update ret_from_syscall code too. */  \
-       if (test_thread_flag(TIF_PERFCTR)) {                            \
-               write_pcr(current_thread_info()->pcr_reg);              \
-               reset_pic();                                            \
-       }                                                               \
-} while(0)
-
-static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val)
-{
-       unsigned long tmp1, tmp2;
-
-       __asm__ __volatile__(
-"      membar          #StoreLoad | #LoadLoad\n"
-"      mov             %0, %1\n"
-"1:    lduw            [%4], %2\n"
-"      cas             [%4], %2, %0\n"
-"      cmp             %2, %0\n"
-"      bne,a,pn        %%icc, 1b\n"
-"       mov            %1, %0\n"
-"      membar          #StoreLoad | #StoreStore\n"
-       : "=&r" (val), "=&r" (tmp1), "=&r" (tmp2)
-       : "0" (val), "r" (m)
-       : "cc", "memory");
-       return val;
-}
-
-static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long val)
-{
-       unsigned long tmp1, tmp2;
-
-       __asm__ __volatile__(
-"      membar          #StoreLoad | #LoadLoad\n"
-"      mov             %0, %1\n"
-"1:    ldx             [%4], %2\n"
-"      casx            [%4], %2, %0\n"
-"      cmp             %2, %0\n"
-"      bne,a,pn        %%xcc, 1b\n"
-"       mov            %1, %0\n"
-"      membar          #StoreLoad | #StoreStore\n"
-       : "=&r" (val), "=&r" (tmp1), "=&r" (tmp2)
-       : "0" (val), "r" (m)
-       : "cc", "memory");
-       return val;
-}
-
-#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-
-extern void __xchg_called_with_bad_pointer(void);
-
-static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
-                                      int size)
-{
-       switch (size) {
-       case 4:
-               return xchg32(ptr, x);
-       case 8:
-               return xchg64(ptr, x);
-       };
-       __xchg_called_with_bad_pointer();
-       return x;
-}
-
-extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noreturn));
-
-/* 
- * Atomic compare and exchange.  Compare OLD with MEM, if identical,
- * store NEW in MEM.  Return the initial value in MEM.  Success is
- * indicated by comparing RETURN with OLD.
- */
-
-#define __HAVE_ARCH_CMPXCHG 1
-
-static inline unsigned long
-__cmpxchg_u32(volatile int *m, int old, int new)
-{
-       __asm__ __volatile__("membar #StoreLoad | #LoadLoad\n"
-                            "cas [%2], %3, %0\n\t"
-                            "membar #StoreLoad | #StoreStore"
-                            : "=&r" (new)
-                            : "0" (new), "r" (m), "r" (old)
-                            : "memory");
-
-       return new;
-}
-
-static inline unsigned long
-__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
-{
-       __asm__ __volatile__("membar #StoreLoad | #LoadLoad\n"
-                            "casx [%2], %3, %0\n\t"
-                            "membar #StoreLoad | #StoreStore"
-                            : "=&r" (new)
-                            : "0" (new), "r" (m), "r" (old)
-                            : "memory");
-
-       return new;
-}
-
-/* This function doesn't exist, so you'll get a linker error
-   if something tries to do an invalid cmpxchg().  */
-extern void __cmpxchg_called_with_bad_pointer(void);
-
-static inline unsigned long
-__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
-{
-       switch (size) {
-               case 4:
-                       return __cmpxchg_u32(ptr, old, new);
-               case 8:
-                       return __cmpxchg_u64(ptr, old, new);
-       }
-       __cmpxchg_called_with_bad_pointer();
-       return old;
-}
-
-#define cmpxchg(ptr,o,n)                                                \
-  ({                                                                    \
-     __typeof__(*(ptr)) _o_ = (o);                                      \
-     __typeof__(*(ptr)) _n_ = (n);                                      \
-     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,          \
-                                   (unsigned long)_n_, sizeof(*(ptr))); \
-  })
-
-/*
- * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
- * them available.
- */
-
-static inline unsigned long __cmpxchg_local(volatile void *ptr,
-                                     unsigned long old,
-                                     unsigned long new, int size)
-{
-       switch (size) {
-       case 4:
-       case 8: return __cmpxchg(ptr, old, new, size);
-       default:
-               return __cmpxchg_local_generic(ptr, old, new, size);
-       }
-
-       return old;
-}
-
-#define cmpxchg_local(ptr, o, n)                                       \
-       ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
-                       (unsigned long)(n), sizeof(*(ptr))))
-#define cmpxchg64_local(ptr, o, n)                                     \
-  ({                                                                   \
-       BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
-       cmpxchg_local((ptr), (o), (n));                                 \
-  })
-
-#endif /* !(__ASSEMBLY__) */
-
-#define arch_align_stack(x) (x)
-
-#endif /* !(__SPARC64_SYSTEM_H) */
+#include <asm-sparc/system.h>
index ebe31c152f16f2c46e592dbd2f1c8fe257d99437..e03f97592c708fa35e9bec54588fe82e405558c5 100644 (file)
@@ -1,260 +1 @@
-#ifndef _SPARC64_TERMBITS_H
-#define _SPARC64_TERMBITS_H
-
-#include <linux/posix_types.h>
-
-typedef unsigned char   cc_t;
-typedef unsigned int    speed_t;
-typedef unsigned int    tcflag_t;
-
-#define NCC 8
-struct termio {
-       unsigned short c_iflag;         /* input mode flags */
-       unsigned short c_oflag;         /* output mode flags */
-       unsigned short c_cflag;         /* control mode flags */
-       unsigned short c_lflag;         /* local mode flags */
-       unsigned char c_line;           /* line discipline */
-       unsigned char c_cc[NCC];        /* control characters */
-};
-
-#define NCCS 17
-struct termios {
-       tcflag_t c_iflag;               /* input mode flags */
-       tcflag_t c_oflag;               /* output mode flags */
-       tcflag_t c_cflag;               /* control mode flags */
-       tcflag_t c_lflag;               /* local mode flags */
-       cc_t c_line;                    /* line discipline */
-       cc_t c_cc[NCCS];                /* control characters */
-#ifdef __KERNEL__
-#define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t))
-       cc_t _x_cc[2];                  /* We need them to hold vmin/vtime */
-#endif
-};
-
-struct termios2 {
-       tcflag_t c_iflag;               /* input mode flags */
-       tcflag_t c_oflag;               /* output mode flags */
-       tcflag_t c_cflag;               /* control mode flags */
-       tcflag_t c_lflag;               /* local mode flags */
-       cc_t c_line;                    /* line discipline */
-       cc_t c_cc[NCCS];                /* control characters */
-       cc_t _x_cc[2];                  /* padding to match ktermios */
-       speed_t c_ispeed;               /* input speed */
-       speed_t c_ospeed;               /* output speed */
-};
-
-struct ktermios {
-       tcflag_t c_iflag;               /* input mode flags */
-       tcflag_t c_oflag;               /* output mode flags */
-       tcflag_t c_cflag;               /* control mode flags */
-       tcflag_t c_lflag;               /* local mode flags */
-       cc_t c_line;                    /* line discipline */
-       cc_t c_cc[NCCS];                /* control characters */
-       cc_t _x_cc[2];                  /* We need them to hold vmin/vtime */
-       speed_t c_ispeed;               /* input speed */
-       speed_t c_ospeed;               /* output speed */
-};
-
-/* c_cc characters */
-#define VINTR    0
-#define VQUIT    1
-#define VERASE   2
-#define VKILL    3
-#define VEOF     4
-#define VEOL     5
-#define VEOL2    6
-#define VSWTC    7
-#define VSTART   8
-#define VSTOP    9
-
-
-
-#define VSUSP    10
-#define VDSUSP   11  /* SunOS POSIX nicety I do believe... */
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE  14
-#define VLNEXT   15
-
-/* Kernel keeps vmin/vtime separated, user apps assume vmin/vtime is
- * shared with eof/eol
- */
-#ifdef __KERNEL__
-#define VMIN     16
-#define VTIME    17
-#else
-#define VMIN     VEOF
-#define VTIME    VEOL
-#endif
-
-/* c_iflag bits */
-#define IGNBRK 0x00000001
-#define BRKINT 0x00000002
-#define IGNPAR 0x00000004
-#define PARMRK 0x00000008
-#define INPCK  0x00000010
-#define ISTRIP 0x00000020
-#define INLCR  0x00000040
-#define IGNCR  0x00000080
-#define ICRNL  0x00000100
-#define IUCLC  0x00000200
-#define IXON   0x00000400
-#define IXANY  0x00000800
-#define IXOFF  0x00001000
-#define IMAXBEL        0x00002000
-#define IUTF8  0x00004000
-
-/* c_oflag bits */
-#define OPOST  0x00000001
-#define OLCUC  0x00000002
-#define ONLCR  0x00000004
-#define OCRNL  0x00000008
-#define ONOCR  0x00000010
-#define ONLRET 0x00000020
-#define OFILL  0x00000040
-#define OFDEL  0x00000080
-#define NLDLY  0x00000100
-#define   NL0  0x00000000
-#define   NL1  0x00000100
-#define CRDLY  0x00000600
-#define   CR0  0x00000000
-#define   CR1  0x00000200
-#define   CR2  0x00000400
-#define   CR3  0x00000600
-#define TABDLY 0x00001800
-#define   TAB0 0x00000000
-#define   TAB1 0x00000800
-#define   TAB2 0x00001000
-#define   TAB3 0x00001800
-#define   XTABS        0x00001800
-#define BSDLY  0x00002000
-#define   BS0  0x00000000
-#define   BS1  0x00002000
-#define VTDLY  0x00004000
-#define   VT0  0x00000000
-#define   VT1  0x00004000
-#define FFDLY  0x00008000
-#define   FF0  0x00000000
-#define   FF1  0x00008000
-#define PAGEOUT 0x00010000  /* SUNOS specific */
-#define WRAP    0x00020000  /* SUNOS specific */
-
-/* c_cflag bit meaning */
-#define CBAUD    0x0000100f
-#define  B0      0x00000000   /* hang up */
-#define  B50     0x00000001
-#define  B75     0x00000002
-#define  B110    0x00000003
-#define  B134    0x00000004
-#define  B150    0x00000005
-#define  B200    0x00000006
-#define  B300    0x00000007
-#define  B600    0x00000008
-#define  B1200   0x00000009
-#define  B1800   0x0000000a
-#define  B2400   0x0000000b
-#define  B4800   0x0000000c
-#define  B9600   0x0000000d
-#define  B19200          0x0000000e
-#define  B38400          0x0000000f
-#define EXTA      B19200
-#define EXTB      B38400
-#define  CSIZE    0x00000030
-#define   CS5    0x00000000
-#define   CS6    0x00000010
-#define   CS7    0x00000020
-#define   CS8    0x00000030
-#define CSTOPB   0x00000040
-#define CREAD    0x00000080
-#define PARENB   0x00000100
-#define PARODD   0x00000200
-#define HUPCL    0x00000400
-#define CLOCAL   0x00000800
-#define CBAUDEX   0x00001000
-#define  BOTHER   0x00001000
-#define  B57600   0x00001001
-#define  B115200  0x00001002
-#define  B230400  0x00001003
-#define  B460800  0x00001004
-/* This is what we can do with the Zilogs. */
-#define  B76800   0x00001005
-/* This is what we can do with the SAB82532. */
-#define  B153600  0x00001006
-#define  B307200  0x00001007
-#define  B614400  0x00001008
-#define  B921600  0x00001009
-/* And these are the rest... */
-#define  B500000  0x0000100a
-#define  B576000  0x0000100b
-#define B1000000  0x0000100c
-#define B1152000  0x0000100d
-#define B1500000  0x0000100e
-#define B2000000  0x0000100f
-/* These have totally bogus values and nobody uses them
-   so far. Later on we'd have to use say 0x10000x and
-   adjust CBAUD constant and drivers accordingly.
-#define B2500000  0x00001010
-#define B3000000  0x00001011
-#define B3500000  0x00001012
-#define B4000000  0x00001013  */
-#define CIBAUD   0x100f0000  /* input baud rate (not used) */
-#define CMSPAR    0x40000000  /* mark or space (stick) parity */
-#define CRTSCTS          0x80000000  /* flow control */
-
-#define IBSHIFT          16            /* Shift from CBAUD to CIBAUD */
-
-/* c_lflag bits */
-#define ISIG   0x00000001
-#define ICANON 0x00000002
-#define XCASE  0x00000004
-#define ECHO   0x00000008
-#define ECHOE  0x00000010
-#define ECHOK  0x00000020
-#define ECHONL 0x00000040
-#define NOFLSH 0x00000080
-#define TOSTOP 0x00000100
-#define ECHOCTL        0x00000200
-#define ECHOPRT        0x00000400
-#define ECHOKE 0x00000800
-#define DEFECHO 0x00001000  /* SUNOS thing, what is it? */
-#define FLUSHO 0x00002000
-#define PENDIN 0x00004000
-#define IEXTEN 0x00008000
-
-/* modem lines */
-#define TIOCM_LE       0x001
-#define TIOCM_DTR      0x002
-#define TIOCM_RTS      0x004
-#define TIOCM_ST       0x008
-#define TIOCM_SR       0x010
-#define TIOCM_CTS      0x020
-#define TIOCM_CAR      0x040
-#define TIOCM_RNG      0x080
-#define TIOCM_DSR      0x100
-#define TIOCM_CD       TIOCM_CAR
-#define TIOCM_RI       TIOCM_RNG
-#define TIOCM_OUT1     0x2000
-#define TIOCM_OUT2     0x4000
-#define TIOCM_LOOP     0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-#define TIOCSER_TEMT    0x01   /* Transmitter physically empty */
-
-
-/* tcflow() and TCXONC use these */
-#define        TCOOFF          0
-#define        TCOON           1
-#define        TCIOFF          2
-#define        TCION           3
-
-/* tcflush() and TCFLSH use these */
-#define        TCIFLUSH        0
-#define        TCOFLUSH        1
-#define        TCIOFLUSH       2
-
-/* tcsetattr uses these */
-#define        TCSANOW         0
-#define        TCSADRAIN       1
-#define        TCSAFLUSH       2
-
-#endif /* !(_SPARC64_TERMBITS_H) */
+#include <asm-sparc/termbits.h>
index 1f5dab25dda5ccbca284f309585ac013e014206f..940495eb05cc04e08967f1e5a965d945d4ea63fa 100644 (file)
@@ -1,186 +1 @@
-#ifndef _SPARC64_TERMIOS_H
-#define _SPARC64_TERMIOS_H
-
-#include <asm/ioctls.h>
-#include <asm/termbits.h>
-
-#if defined(__KERNEL__) || defined(__DEFINE_BSD_TERMIOS)
-struct sgttyb {
-       char    sg_ispeed;
-       char    sg_ospeed;
-       char    sg_erase;
-       char    sg_kill;
-       short   sg_flags;
-};
-
-struct tchars {
-       char    t_intrc;
-       char    t_quitc;
-       char    t_startc;
-       char    t_stopc;
-       char    t_eofc;
-       char    t_brkc;
-};
-
-struct ltchars {
-       char    t_suspc;
-       char    t_dsuspc;
-       char    t_rprntc;
-       char    t_flushc;
-       char    t_werasc;
-       char    t_lnextc;
-};
-#endif /* __KERNEL__ */
-
-struct winsize {
-       unsigned short ws_row;
-       unsigned short ws_col;
-       unsigned short ws_xpixel;
-       unsigned short ws_ypixel;
-};
-
-#ifdef __KERNEL__
-#include <linux/module.h>
-
-/*
- * c_cc characters in the termio structure.  Oh, how I love being
- * backwardly compatible.  Notice that character 4 and 5 are
- * interpreted differently depending on whether ICANON is set in
- * c_lflag.  If it's set, they are used as _VEOF and _VEOL, otherwise
- * as _VMIN and V_TIME.  This is for compatibility with OSF/1 (which
- * is compatible with sysV)...
- */
-#define _VMIN  4
-#define _VTIME 5
-
-/*     intr=^C         quit=^\         erase=del       kill=^U
-       eof=^D          eol=\0          eol2=\0         sxtc=\0
-       start=^Q        stop=^S         susp=^Z         dsusp=^Y
-       reprint=^R      discard=^U      werase=^W       lnext=^V
-       vmin=\1         vtime=\0
-*/
-#define INIT_C_CC "\003\034\177\025\004\000\000\000\021\023\032\031\022\025\027\026\001"
-
-/*
- * Translate a "termio" structure into a "termios". Ugh.
- */
-#define user_termio_to_kernel_termios(termios, termio) \
-({ \
-       unsigned short tmp; \
-       int err; \
-       err = get_user(tmp, &(termio)->c_iflag); \
-       (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
-       err |= get_user(tmp, &(termio)->c_oflag); \
-       (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
-       err |= get_user(tmp, &(termio)->c_cflag); \
-       (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
-       err |= get_user(tmp, &(termio)->c_lflag); \
-       (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
-       err |= copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
-       err; \
-})
-
-/*
- * Translate a "termios" structure into a "termio". Ugh.
- *
- * Note the "fun" _VMIN overloading.
- */
-#define kernel_termios_to_user_termio(termio, termios) \
-({ \
-       int err; \
-       err  = put_user((termios)->c_iflag, &(termio)->c_iflag); \
-       err |= put_user((termios)->c_oflag, &(termio)->c_oflag); \
-       err |= put_user((termios)->c_cflag, &(termio)->c_cflag); \
-       err |= put_user((termios)->c_lflag, &(termio)->c_lflag); \
-       err |= put_user((termios)->c_line,  &(termio)->c_line); \
-       err |= copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
-       if (!((termios)->c_lflag & ICANON)) { \
-               err |= put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
-               err |= put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
-       } \
-       err; \
-})
-
-#define user_termios_to_kernel_termios(k, u) \
-({ \
-       int err; \
-       err  = get_user((k)->c_iflag, &(u)->c_iflag); \
-       err |= get_user((k)->c_oflag, &(u)->c_oflag); \
-       err |= get_user((k)->c_cflag, &(u)->c_cflag); \
-       err |= get_user((k)->c_lflag, &(u)->c_lflag); \
-       err |= get_user((k)->c_line,  &(u)->c_line); \
-       err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
-       if((k)->c_lflag & ICANON) { \
-               err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
-               err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
-       } else { \
-               err |= get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
-               err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
-       } \
-       err |= get_user((k)->c_ispeed,  &(u)->c_ispeed); \
-       err |= get_user((k)->c_ospeed,  &(u)->c_ospeed); \
-       err; \
-})
-
-#define kernel_termios_to_user_termios(u, k) \
-({ \
-       int err; \
-       err  = put_user((k)->c_iflag, &(u)->c_iflag); \
-       err |= put_user((k)->c_oflag, &(u)->c_oflag); \
-       err |= put_user((k)->c_cflag, &(u)->c_cflag); \
-       err |= put_user((k)->c_lflag, &(u)->c_lflag); \
-       err |= put_user((k)->c_line, &(u)->c_line); \
-       err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
-       if(!((k)->c_lflag & ICANON)) { \
-               err |= put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
-               err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
-       } else { \
-               err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
-               err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
-       } \
-       err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \
-       err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \
-       err; \
-})
-
-#define user_termios_to_kernel_termios_1(k, u) \
-({ \
-       int err; \
-       err  = get_user((k)->c_iflag, &(u)->c_iflag); \
-       err |= get_user((k)->c_oflag, &(u)->c_oflag); \
-       err |= get_user((k)->c_cflag, &(u)->c_cflag); \
-       err |= get_user((k)->c_lflag, &(u)->c_lflag); \
-       err |= get_user((k)->c_line,  &(u)->c_line); \
-       err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
-       if((k)->c_lflag & ICANON) { \
-               err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
-               err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
-       } else { \
-               err |= get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
-               err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
-       } \
-       err; \
-})
-
-#define kernel_termios_to_user_termios_1(u, k) \
-({ \
-       int err; \
-       err  = put_user((k)->c_iflag, &(u)->c_iflag); \
-       err |= put_user((k)->c_oflag, &(u)->c_oflag); \
-       err |= put_user((k)->c_cflag, &(u)->c_cflag); \
-       err |= put_user((k)->c_lflag, &(u)->c_lflag); \
-       err |= put_user((k)->c_line, &(u)->c_line); \
-       err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
-       if(!((k)->c_lflag & ICANON)) { \
-               err |= put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
-               err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
-       } else { \
-               err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
-               err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
-       } \
-       err; \
-})
-
-#endif /* __KERNEL__ */
-
-#endif /* _SPARC64_TERMIOS_H */
+#include <asm-sparc/termios.h>
index e5873e3853063c836b01e6e715198f1396bd33f0..92bed791339592e31959720f17cc4d79f06b9ffb 100644 (file)
@@ -1,277 +1 @@
-/* thread_info.h: sparc64 low-level thread information
- *
- * Copyright (C) 2002  David S. Miller (davem@redhat.com)
- */
-
-#ifndef _ASM_THREAD_INFO_H
-#define _ASM_THREAD_INFO_H
-
-#ifdef __KERNEL__
-
-#define NSWINS         7
-
-#define TI_FLAG_BYTE_FAULT_CODE                0
-#define TI_FLAG_FAULT_CODE_SHIFT       56
-#define TI_FLAG_BYTE_WSTATE            1
-#define TI_FLAG_WSTATE_SHIFT           48
-#define TI_FLAG_BYTE_CWP               2
-#define TI_FLAG_CWP_SHIFT              40
-#define TI_FLAG_BYTE_CURRENT_DS                3
-#define TI_FLAG_CURRENT_DS_SHIFT       32
-#define TI_FLAG_BYTE_FPDEPTH           4
-#define TI_FLAG_FPDEPTH_SHIFT          24
-#define TI_FLAG_BYTE_WSAVED            5
-#define TI_FLAG_WSAVED_SHIFT           16
-
-#include <asm/page.h>
-
-#ifndef __ASSEMBLY__
-
-#include <asm/ptrace.h>
-#include <asm/types.h>
-
-struct task_struct;
-struct exec_domain;
-
-struct thread_info {
-       /* D$ line 1 */
-       struct task_struct      *task;
-       unsigned long           flags;
-       __u8                    fpsaved[7];
-       __u8                    status;
-       unsigned long           ksp;
-
-       /* D$ line 2 */
-       unsigned long           fault_address;
-       struct pt_regs          *kregs;
-       struct exec_domain      *exec_domain;
-       int                     preempt_count;  /* 0 => preemptable, <0 => BUG */
-       __u8                    new_child;
-       __u8                    syscall_noerror;
-       __u16                   cpu;
-
-       unsigned long           *utraps;
-
-       struct reg_window       reg_window[NSWINS];
-       unsigned long           rwbuf_stkptrs[NSWINS];
-
-       unsigned long           gsr[7];
-       unsigned long           xfsr[7];
-
-       __u64                   __user *user_cntd0;
-       __u64                   __user *user_cntd1;
-       __u64                   kernel_cntd0, kernel_cntd1;
-       __u64                   pcr_reg;
-
-       struct restart_block    restart_block;
-
-       struct pt_regs          *kern_una_regs;
-       unsigned int            kern_una_insn;
-
-       unsigned long           fpregs[0] __attribute__ ((aligned(64)));
-};
-
-#endif /* !(__ASSEMBLY__) */
-
-/* offsets into the thread_info struct for assembly code access */
-#define TI_TASK                0x00000000
-#define TI_FLAGS       0x00000008
-#define TI_FAULT_CODE  (TI_FLAGS + TI_FLAG_BYTE_FAULT_CODE)
-#define TI_WSTATE      (TI_FLAGS + TI_FLAG_BYTE_WSTATE)
-#define TI_CWP         (TI_FLAGS + TI_FLAG_BYTE_CWP)
-#define TI_CURRENT_DS  (TI_FLAGS + TI_FLAG_BYTE_CURRENT_DS)
-#define TI_FPDEPTH     (TI_FLAGS + TI_FLAG_BYTE_FPDEPTH)
-#define TI_WSAVED      (TI_FLAGS + TI_FLAG_BYTE_WSAVED)
-#define TI_FPSAVED     0x00000010
-#define TI_KSP         0x00000018
-#define TI_FAULT_ADDR  0x00000020
-#define TI_KREGS       0x00000028
-#define TI_EXEC_DOMAIN 0x00000030
-#define TI_PRE_COUNT   0x00000038
-#define TI_NEW_CHILD   0x0000003c
-#define TI_SYS_NOERROR 0x0000003d
-#define TI_CPU         0x0000003e
-#define TI_UTRAPS      0x00000040
-#define TI_REG_WINDOW  0x00000048
-#define TI_RWIN_SPTRS  0x000003c8      
-#define TI_GSR         0x00000400
-#define TI_XFSR                0x00000438
-#define TI_USER_CNTD0  0x00000470
-#define TI_USER_CNTD1  0x00000478
-#define TI_KERN_CNTD0  0x00000480
-#define TI_KERN_CNTD1  0x00000488
-#define TI_PCR         0x00000490
-#define TI_RESTART_BLOCK 0x00000498
-#define TI_KUNA_REGS   0x000004c0
-#define TI_KUNA_INSN   0x000004c8
-#define TI_FPREGS      0x00000500
-
-/* We embed this in the uppermost byte of thread_info->flags */
-#define FAULT_CODE_WRITE       0x01    /* Write access, implies D-TLB     */
-#define FAULT_CODE_DTLB                0x02    /* Miss happened in D-TLB          */
-#define FAULT_CODE_ITLB                0x04    /* Miss happened in I-TLB          */
-#define FAULT_CODE_WINFIXUP    0x08    /* Miss happened during spill/fill */
-#define FAULT_CODE_BLKCOMMIT   0x10    /* Use blk-commit ASI in copy_page */
-
-#if PAGE_SHIFT == 13
-#define THREAD_SIZE (2*PAGE_SIZE)
-#define THREAD_SHIFT (PAGE_SHIFT + 1)
-#else /* PAGE_SHIFT == 13 */
-#define THREAD_SIZE PAGE_SIZE
-#define THREAD_SHIFT PAGE_SHIFT
-#endif /* PAGE_SHIFT == 13 */
-
-#define PREEMPT_ACTIVE         0x4000000
-
-/*
- * macros/functions for gaining access to the thread information structure
- *
- * preempt_count needs to be 1 initially, until the scheduler is functional.
- */
-#ifndef __ASSEMBLY__
-
-#define INIT_THREAD_INFO(tsk)                          \
-{                                                      \
-       .task           =       &tsk,                   \
-       .flags          = ((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT,   \
-       .exec_domain    =       &default_exec_domain,   \
-       .preempt_count  =       1,                      \
-       .restart_block  = {                             \
-               .fn     =       do_no_restart_syscall,  \
-       },                                              \
-}
-
-#define init_thread_info       (init_thread_union.thread_info)
-#define init_stack             (init_thread_union.stack)
-
-/* how to get the thread information struct from C */
-register struct thread_info *current_thread_info_reg asm("g6");
-#define current_thread_info()  (current_thread_info_reg)
-
-/* thread information allocation */
-#if PAGE_SHIFT == 13
-#define __THREAD_INFO_ORDER    1
-#else /* PAGE_SHIFT == 13 */
-#define __THREAD_INFO_ORDER    0
-#endif /* PAGE_SHIFT == 13 */
-
-#ifdef CONFIG_DEBUG_STACK_USAGE
-#define alloc_thread_info(tsk)                                 \
-({                                                             \
-       struct thread_info *ret;                                \
-                                                               \
-       ret = (struct thread_info *)                            \
-         __get_free_pages(GFP_KERNEL, __THREAD_INFO_ORDER);    \
-       if (ret)                                                \
-               memset(ret, 0, PAGE_SIZE<<__THREAD_INFO_ORDER); \
-       ret;                                                    \
-})
-#else
-#define alloc_thread_info(tsk) \
-       ((struct thread_info *)__get_free_pages(GFP_KERNEL, __THREAD_INFO_ORDER))
-#endif
-
-#define free_thread_info(ti) \
-       free_pages((unsigned long)(ti),__THREAD_INFO_ORDER)
-
-#define __thread_flag_byte_ptr(ti)     \
-       ((unsigned char *)(&((ti)->flags)))
-#define __cur_thread_flag_byte_ptr     __thread_flag_byte_ptr(current_thread_info())
-
-#define get_thread_fault_code()                (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FAULT_CODE])
-#define set_thread_fault_code(val)     (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FAULT_CODE] = (val))
-#define get_thread_wstate()            (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE])
-#define set_thread_wstate(val)         (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSTATE] = (val))
-#define get_thread_cwp()               (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP])
-#define set_thread_cwp(val)            (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CWP] = (val))
-#define get_thread_current_ds()                (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS])
-#define set_thread_current_ds(val)     (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_CURRENT_DS] = (val))
-#define get_thread_fpdepth()           (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH])
-#define set_thread_fpdepth(val)                (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_FPDEPTH] = (val))
-#define get_thread_wsaved()            (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED])
-#define set_thread_wsaved(val)         (__cur_thread_flag_byte_ptr[TI_FLAG_BYTE_WSAVED] = (val))
-
-#endif /* !(__ASSEMBLY__) */
-
-/*
- * Thread information flags, only 16 bits are available as we encode
- * other values into the upper 6 bytes.
- *
- * On trap return we need to test several values:
- *
- * user:       need_resched, notify_resume, sigpending, wsaved, perfctr
- * kernel:     fpdepth
- *
- * So to check for work in the kernel case we simply load the fpdepth
- * byte out of the flags and test it.  For the user case we encode the
- * lower 3 bytes of flags as follows:
- *     ----------------------------------------
- *     | wsaved | flags byte 1 | flags byte 2 |
- *     ----------------------------------------
- * This optimizes the user test into:
- *     ldx             [%g6 + TI_FLAGS], REG1
- *     sethi           %hi(_TIF_USER_WORK_MASK), REG2
- *     or              REG2, %lo(_TIF_USER_WORK_MASK), REG2
- *     andcc           REG1, REG2, %g0
- *     be,pt           no_work_to_do
- *      nop
- */
-#define TIF_SYSCALL_TRACE      0       /* syscall trace active */
-/* flags bit 1 is available */
-#define TIF_SIGPENDING         2       /* signal pending */
-#define TIF_NEED_RESCHED       3       /* rescheduling necessary */
-#define TIF_PERFCTR            4       /* performance counters active */
-#define TIF_UNALIGNED          5       /* allowed to do unaligned accesses */
-/* flag bit 6 is available */
-#define TIF_32BIT              7       /* 32-bit binary */
-/* flag bit 8 is available */
-#define TIF_SECCOMP            9       /* secure computing */
-#define TIF_SYSCALL_AUDIT      10      /* syscall auditing active */
-/* flag bit 11 is available */
-/* NOTE: Thread flags >= 12 should be ones we have no interest
- *       in using in assembly, else we can't use the mask as
- *       an immediate value in instructions such as andcc.
- */
-#define TIF_ABI_PENDING                12
-#define TIF_MEMDIE             13
-#define TIF_POLLING_NRFLAG     14
-
-#define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
-#define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
-#define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
-#define _TIF_PERFCTR           (1<<TIF_PERFCTR)
-#define _TIF_UNALIGNED         (1<<TIF_UNALIGNED)
-#define _TIF_32BIT             (1<<TIF_32BIT)
-#define _TIF_SECCOMP           (1<<TIF_SECCOMP)
-#define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
-#define _TIF_ABI_PENDING       (1<<TIF_ABI_PENDING)
-#define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
-
-#define _TIF_USER_WORK_MASK    ((0xff << TI_FLAG_WSAVED_SHIFT) | \
-                                (_TIF_SIGPENDING | \
-                                 _TIF_NEED_RESCHED | _TIF_PERFCTR))
-
-/*
- * Thread-synchronous status.
- *
- * This is different from the flags in that nobody else
- * ever touches our thread-synchronous status, so we don't
- * have to worry about atomic accesses.
- *
- * Note that there are only 8 bits available.
- */
-#define TS_RESTORE_SIGMASK     0x0001  /* restore signal mask in do_signal() */
-
-#ifndef __ASSEMBLY__
-#define HAVE_SET_RESTORE_SIGMASK       1
-static inline void set_restore_sigmask(void)
-{
-       struct thread_info *ti = current_thread_info();
-       ti->status |= TS_RESTORE_SIGMASK;
-       set_bit(TIF_SIGPENDING, &ti->flags);
-}
-#endif /* !__ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_THREAD_INFO_H */
+#include <asm-sparc/thread_info.h>
index 5b779fd1f78828d123ea047164852b547263eeba..88026d83cc937de09c9c91ca1f6c8e2a40b013df 100644 (file)
@@ -1,30 +1 @@
-/* timer.h: System timer definitions for sun5.
- *
- * Copyright (C) 1997, 2008 David S. Miller (davem@davemloft.net)
- */
-
-#ifndef _SPARC64_TIMER_H
-#define _SPARC64_TIMER_H
-
-#include <linux/types.h>
-#include <linux/init.h>
-
-struct sparc64_tick_ops {
-       unsigned long (*get_tick)(void);
-       int (*add_compare)(unsigned long);
-       unsigned long softint_mask;
-       void (*disable_irq)(void);
-
-       void (*init_tick)(void);
-       unsigned long (*add_tick)(unsigned long);
-
-       char *name;
-};
-
-extern struct sparc64_tick_ops *tick_ops;
-
-extern unsigned long sparc64_get_clock_tick(unsigned int cpu);
-extern void __devinit setup_sparc64_timer(void);
-extern void __init time_init(void);
-
-#endif /* _SPARC64_TIMER_H */
+#include <asm-sparc/timer.h>
index c622535c45600bd6c9faab97b40255e71685214d..8dd59ee24b48d26827013f31a37eb93d179a580f 100644 (file)
@@ -1,19 +1 @@
-/*
- * linux/include/asm-sparc64/timex.h
- *
- * sparc64 architecture timex specifications
- */
-#ifndef _ASMsparc64_TIMEX_H
-#define _ASMsparc64_TIMEX_H
-
-#include <asm/timer.h>
-
-#define CLOCK_TICK_RATE        1193180 /* Underlying HZ */
-
-/* Getting on the cycle counter on sparc64. */
-typedef unsigned long cycles_t;
-#define get_cycles()   tick_ops->get_tick()
-
-#define ARCH_HAS_READ_CURRENT_TIMER
-
-#endif
+#include <asm-sparc/timex.h>
index ec81cdedef2c8a94aaea03263371b19c832edf60..ae92fce1093640dde7d2eb107c5808d07580fd71 100644 (file)
@@ -1,111 +1 @@
-#ifndef _SPARC64_TLB_H
-#define _SPARC64_TLB_H
-
-#include <linux/swap.h>
-#include <linux/pagemap.h>
-#include <asm/pgalloc.h>
-#include <asm/tlbflush.h>
-#include <asm/mmu_context.h>
-
-#define TLB_BATCH_NR   192
-
-/*
- * For UP we don't need to worry about TLB flush
- * and page free order so much..
- */
-#ifdef CONFIG_SMP
-  #define FREE_PTE_NR  506
-  #define tlb_fast_mode(bp) ((bp)->pages_nr == ~0U)
-#else
-  #define FREE_PTE_NR  1
-  #define tlb_fast_mode(bp) 1
-#endif
-
-struct mmu_gather {
-       struct mm_struct *mm;
-       unsigned int pages_nr;
-       unsigned int need_flush;
-       unsigned int fullmm;
-       unsigned int tlb_nr;
-       unsigned long vaddrs[TLB_BATCH_NR];
-       struct page *pages[FREE_PTE_NR];
-};
-
-DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
-
-#ifdef CONFIG_SMP
-extern void smp_flush_tlb_pending(struct mm_struct *,
-                                 unsigned long, unsigned long *);
-#endif
-
-extern void __flush_tlb_pending(unsigned long, unsigned long, unsigned long *);
-extern void flush_tlb_pending(void);
-
-static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
-{
-       struct mmu_gather *mp = &get_cpu_var(mmu_gathers);
-
-       BUG_ON(mp->tlb_nr);
-
-       mp->mm = mm;
-       mp->pages_nr = num_online_cpus() > 1 ? 0U : ~0U;
-       mp->fullmm = full_mm_flush;
-
-       return mp;
-}
-
-
-static inline void tlb_flush_mmu(struct mmu_gather *mp)
-{
-       if (mp->need_flush) {
-               free_pages_and_swap_cache(mp->pages, mp->pages_nr);
-               mp->pages_nr = 0;
-               mp->need_flush = 0;
-       }
-
-}
-
-#ifdef CONFIG_SMP
-extern void smp_flush_tlb_mm(struct mm_struct *mm);
-#define do_flush_tlb_mm(mm) smp_flush_tlb_mm(mm)
-#else
-#define do_flush_tlb_mm(mm) __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT)
-#endif
-
-static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, unsigned long end)
-{
-       tlb_flush_mmu(mp);
-
-       if (mp->fullmm)
-               mp->fullmm = 0;
-       else
-               flush_tlb_pending();
-
-       /* keep the page table cache within bounds */
-       check_pgt_cache();
-
-       put_cpu_var(mmu_gathers);
-}
-
-static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page)
-{
-       if (tlb_fast_mode(mp)) {
-               free_page_and_swap_cache(page);
-               return;
-       }
-       mp->need_flush = 1;
-       mp->pages[mp->pages_nr++] = page;
-       if (mp->pages_nr >= FREE_PTE_NR)
-               tlb_flush_mmu(mp);
-}
-
-#define tlb_remove_tlb_entry(mp,ptep,addr) do { } while (0)
-#define pte_free_tlb(mp, ptepage) pte_free((mp)->mm, ptepage)
-#define pmd_free_tlb(mp, pmdp) pmd_free((mp)->mm, pmdp)
-#define pud_free_tlb(tlb,pudp) __pud_free_tlb(tlb,pudp)
-
-#define tlb_migrate_finish(mm) do { } while (0)
-#define tlb_start_vma(tlb, vma) do { } while (0)
-#define tlb_end_vma(tlb, vma)  do { } while (0)
-
-#endif /* _SPARC64_TLB_H */
+#include <asm-sparc/tlb.h>
index fbb675dbe0c92abe8bead2c0a46c58451fa4d0e1..a43979a06cd90d396910e12a6a53c5a28cab2452 100644 (file)
@@ -1,44 +1 @@
-#ifndef _SPARC64_TLBFLUSH_H
-#define _SPARC64_TLBFLUSH_H
-
-#include <linux/mm.h>
-#include <asm/mmu_context.h>
-
-/* TSB flush operations. */
-struct mmu_gather;
-extern void flush_tsb_kernel_range(unsigned long start, unsigned long end);
-extern void flush_tsb_user(struct mmu_gather *mp);
-
-/* TLB flush operations. */
-
-extern void flush_tlb_pending(void);
-
-#define flush_tlb_range(vma,start,end) \
-       do { (void)(start); flush_tlb_pending(); } while (0)
-#define flush_tlb_page(vma,addr)       flush_tlb_pending()
-#define flush_tlb_mm(mm)               flush_tlb_pending()
-
-/* Local cpu only.  */
-extern void __flush_tlb_all(void);
-
-extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end);
-
-#ifndef CONFIG_SMP
-
-#define flush_tlb_kernel_range(start,end) \
-do {   flush_tsb_kernel_range(start,end); \
-       __flush_tlb_kernel_range(start,end); \
-} while (0)
-
-#else /* CONFIG_SMP */
-
-extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end);
-
-#define flush_tlb_kernel_range(start, end) \
-do {   flush_tsb_kernel_range(start,end); \
-       smp_flush_tlb_kernel_range(start, end); \
-} while (0)
-
-#endif /* ! CONFIG_SMP */
-
-#endif /* _SPARC64_TLBFLUSH_H */
+#include <asm-sparc/tlbflush.h>
index 001c04027c82b3f774a8c4aaeed12f5eff8c8835..46999b60fbbabaa8e8fb36eb443200926a82c606 100644 (file)
@@ -1,86 +1 @@
-#ifndef _ASM_SPARC64_TOPOLOGY_H
-#define _ASM_SPARC64_TOPOLOGY_H
-
-#ifdef CONFIG_NUMA
-
-#include <asm/mmzone.h>
-
-static inline int cpu_to_node(int cpu)
-{
-       return numa_cpu_lookup_table[cpu];
-}
-
-#define parent_node(node)      (node)
-
-static inline cpumask_t node_to_cpumask(int node)
-{
-       return numa_cpumask_lookup_table[node];
-}
-
-/* Returns a pointer to the cpumask of CPUs on Node 'node'. */
-#define node_to_cpumask_ptr(v, node)           \
-               cpumask_t *v = &(numa_cpumask_lookup_table[node])
-
-#define node_to_cpumask_ptr_next(v, node)      \
-                          v = &(numa_cpumask_lookup_table[node])
-
-static inline int node_to_first_cpu(int node)
-{
-       cpumask_t tmp;
-       tmp = node_to_cpumask(node);
-       return first_cpu(tmp);
-}
-
-struct pci_bus;
-#ifdef CONFIG_PCI
-extern int pcibus_to_node(struct pci_bus *pbus);
-#else
-static inline int pcibus_to_node(struct pci_bus *pbus)
-{
-       return -1;
-}
-#endif
-
-#define pcibus_to_cpumask(bus) \
-       (pcibus_to_node(bus) == -1 ? \
-        CPU_MASK_ALL : \
-        node_to_cpumask(pcibus_to_node(bus)))
-
-#define SD_NODE_INIT (struct sched_domain) {           \
-       .min_interval           = 8,                    \
-       .max_interval           = 32,                   \
-       .busy_factor            = 32,                   \
-       .imbalance_pct          = 125,                  \
-       .cache_nice_tries       = 2,                    \
-       .busy_idx               = 3,                    \
-       .idle_idx               = 2,                    \
-       .newidle_idx            = 0,                    \
-       .wake_idx               = 1,                    \
-       .forkexec_idx           = 1,                    \
-       .flags                  = SD_LOAD_BALANCE       \
-                               | SD_BALANCE_FORK       \
-                               | SD_BALANCE_EXEC       \
-                               | SD_SERIALIZE          \
-                               | SD_WAKE_BALANCE,      \
-       .last_balance           = jiffies,              \
-       .balance_interval       = 1,                    \
-}
-
-#else /* CONFIG_NUMA */
-
-#include <asm-generic/topology.h>
-
-#endif /* !(CONFIG_NUMA) */
-
-#ifdef CONFIG_SMP
-#define topology_physical_package_id(cpu)      (cpu_data(cpu).proc_id)
-#define topology_core_id(cpu)                  (cpu_data(cpu).core_id)
-#define topology_core_siblings(cpu)            (cpu_core_map[cpu])
-#define topology_thread_siblings(cpu)          (per_cpu(cpu_sibling_map, cpu))
-#define mc_capable()                           (sparc64_multi_core)
-#define smt_capable()                          (sparc64_multi_core)
-#endif /* CONFIG_SMP */
-
-#define cpu_coregroup_map(cpu)                 (cpu_core_map[cpu])
-
-#endif /* _ASM_SPARC64_TOPOLOGY_H */
+#include <asm-sparc/topology.h>
index 76e4299dd9bc957667668bd39b38713d8cb9440e..3677a302ea3eef64a0dc23d182b7244ec6666f35 100644 (file)
@@ -1,283 +1 @@
-#ifndef _SPARC64_TSB_H
-#define _SPARC64_TSB_H
-
-/* The sparc64 TSB is similar to the powerpc hashtables.  It's a
- * power-of-2 sized table of TAG/PTE pairs.  The cpu precomputes
- * pointers into this table for 8K and 64K page sizes, and also a
- * comparison TAG based upon the virtual address and context which
- * faults.
- *
- * TLB miss trap handler software does the actual lookup via something
- * of the form:
- *
- *     ldxa            [%g0] ASI_{D,I}MMU_TSB_8KB_PTR, %g1
- *     ldxa            [%g0] ASI_{D,I}MMU, %g6
- *     sllx            %g6, 22, %g6
- *     srlx            %g6, 22, %g6
- *     ldda            [%g1] ASI_NUCLEUS_QUAD_LDD, %g4
- *     cmp             %g4, %g6
- *     bne,pn  %xcc, tsb_miss_{d,i}tlb
- *      mov            FAULT_CODE_{D,I}TLB, %g3
- *     stxa            %g5, [%g0] ASI_{D,I}TLB_DATA_IN
- *     retry
- *
- *
- * Each 16-byte slot of the TSB is the 8-byte tag and then the 8-byte
- * PTE.  The TAG is of the same layout as the TLB TAG TARGET mmu
- * register which is:
- *
- * -------------------------------------------------
- * |  -  |  CONTEXT |  -  |    VADDR bits 63:22    |
- * -------------------------------------------------
- *  63 61 60      48 47 42 41                     0
- *
- * But actually, since we use per-mm TSB's, we zero out the CONTEXT
- * field.
- *
- * Like the powerpc hashtables we need to use locking in order to
- * synchronize while we update the entries.  PTE updates need locking
- * as well.
- *
- * We need to carefully choose a lock bits for the TSB entry.  We
- * choose to use bit 47 in the tag.  Also, since we never map anything
- * at page zero in context zero, we use zero as an invalid tag entry.
- * When the lock bit is set, this forces a tag comparison failure.
- */
-
-#define TSB_TAG_LOCK_BIT       47
-#define TSB_TAG_LOCK_HIGH      (1 << (TSB_TAG_LOCK_BIT - 32))
-
-#define TSB_TAG_INVALID_BIT    46
-#define TSB_TAG_INVALID_HIGH   (1 << (TSB_TAG_INVALID_BIT - 32))
-
-#define TSB_MEMBAR     membar  #StoreStore
-
-/* Some cpus support physical address quad loads.  We want to use
- * those if possible so we don't need to hard-lock the TSB mapping
- * into the TLB.  We encode some instruction patching in order to
- * support this.
- *
- * The kernel TSB is locked into the TLB by virtue of being in the
- * kernel image, so we don't play these games for swapper_tsb access.
- */
-#ifndef __ASSEMBLY__
-struct tsb_ldquad_phys_patch_entry {
-       unsigned int    addr;
-       unsigned int    sun4u_insn;
-       unsigned int    sun4v_insn;
-};
-extern struct tsb_ldquad_phys_patch_entry __tsb_ldquad_phys_patch,
-       __tsb_ldquad_phys_patch_end;
-
-struct tsb_phys_patch_entry {
-       unsigned int    addr;
-       unsigned int    insn;
-};
-extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
-#endif
-#define TSB_LOAD_QUAD(TSB, REG)        \
-661:   ldda            [TSB] ASI_NUCLEUS_QUAD_LDD, REG; \
-       .section        .tsb_ldquad_phys_patch, "ax"; \
-       .word           661b; \
-       ldda            [TSB] ASI_QUAD_LDD_PHYS, REG; \
-       ldda            [TSB] ASI_QUAD_LDD_PHYS_4V, REG; \
-       .previous
-
-#define TSB_LOAD_TAG_HIGH(TSB, REG) \
-661:   lduwa           [TSB] ASI_N, REG; \
-       .section        .tsb_phys_patch, "ax"; \
-       .word           661b; \
-       lduwa           [TSB] ASI_PHYS_USE_EC, REG; \
-       .previous
-
-#define TSB_LOAD_TAG(TSB, REG) \
-661:   ldxa            [TSB] ASI_N, REG; \
-       .section        .tsb_phys_patch, "ax"; \
-       .word           661b; \
-       ldxa            [TSB] ASI_PHYS_USE_EC, REG; \
-       .previous
-
-#define TSB_CAS_TAG_HIGH(TSB, REG1, REG2) \
-661:   casa            [TSB] ASI_N, REG1, REG2; \
-       .section        .tsb_phys_patch, "ax"; \
-       .word           661b; \
-       casa            [TSB] ASI_PHYS_USE_EC, REG1, REG2; \
-       .previous
-
-#define TSB_CAS_TAG(TSB, REG1, REG2) \
-661:   casxa           [TSB] ASI_N, REG1, REG2; \
-       .section        .tsb_phys_patch, "ax"; \
-       .word           661b; \
-       casxa           [TSB] ASI_PHYS_USE_EC, REG1, REG2; \
-       .previous
-
-#define TSB_STORE(ADDR, VAL) \
-661:   stxa            VAL, [ADDR] ASI_N; \
-       .section        .tsb_phys_patch, "ax"; \
-       .word           661b; \
-       stxa            VAL, [ADDR] ASI_PHYS_USE_EC; \
-       .previous
-
-#define TSB_LOCK_TAG(TSB, REG1, REG2)  \
-99:    TSB_LOAD_TAG_HIGH(TSB, REG1);   \
-       sethi   %hi(TSB_TAG_LOCK_HIGH), REG2;\
-       andcc   REG1, REG2, %g0;        \
-       bne,pn  %icc, 99b;              \
-        nop;                           \
-       TSB_CAS_TAG_HIGH(TSB, REG1, REG2);      \
-       cmp     REG1, REG2;             \
-       bne,pn  %icc, 99b;              \
-        nop;                           \
-       TSB_MEMBAR
-
-#define TSB_WRITE(TSB, TTE, TAG) \
-       add     TSB, 0x8, TSB;   \
-       TSB_STORE(TSB, TTE);     \
-       sub     TSB, 0x8, TSB;   \
-       TSB_MEMBAR;              \
-       TSB_STORE(TSB, TAG);
-
-#define KTSB_LOAD_QUAD(TSB, REG) \
-       ldda            [TSB] ASI_NUCLEUS_QUAD_LDD, REG;
-
-#define KTSB_STORE(ADDR, VAL) \
-       stxa            VAL, [ADDR] ASI_N;
-
-#define KTSB_LOCK_TAG(TSB, REG1, REG2) \
-99:    lduwa   [TSB] ASI_N, REG1;      \
-       sethi   %hi(TSB_TAG_LOCK_HIGH), REG2;\
-       andcc   REG1, REG2, %g0;        \
-       bne,pn  %icc, 99b;              \
-        nop;                           \
-       casa    [TSB] ASI_N, REG1, REG2;\
-       cmp     REG1, REG2;             \
-       bne,pn  %icc, 99b;              \
-        nop;                           \
-       TSB_MEMBAR
-
-#define KTSB_WRITE(TSB, TTE, TAG) \
-       add     TSB, 0x8, TSB;   \
-       stxa    TTE, [TSB] ASI_N;     \
-       sub     TSB, 0x8, TSB;   \
-       TSB_MEMBAR;              \
-       stxa    TAG, [TSB] ASI_N;
-
-       /* Do a kernel page table walk.  Leaves physical PTE pointer in
-        * REG1.  Jumps to FAIL_LABEL on early page table walk termination.
-        * VADDR will not be clobbered, but REG2 will.
-        */
-#define KERN_PGTABLE_WALK(VADDR, REG1, REG2, FAIL_LABEL)       \
-       sethi           %hi(swapper_pg_dir), REG1; \
-       or              REG1, %lo(swapper_pg_dir), REG1; \
-       sllx            VADDR, 64 - (PGDIR_SHIFT + PGDIR_BITS), REG2; \
-       srlx            REG2, 64 - PAGE_SHIFT, REG2; \
-       andn            REG2, 0x3, REG2; \
-       lduw            [REG1 + REG2], REG1; \
-       brz,pn          REG1, FAIL_LABEL; \
-        sllx           VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \
-       srlx            REG2, 64 - PAGE_SHIFT, REG2; \
-       sllx            REG1, 11, REG1; \
-       andn            REG2, 0x3, REG2; \
-       lduwa           [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \
-       brz,pn          REG1, FAIL_LABEL; \
-        sllx           VADDR, 64 - PMD_SHIFT, REG2; \
-       srlx            REG2, 64 - PAGE_SHIFT, REG2; \
-       sllx            REG1, 11, REG1; \
-       andn            REG2, 0x7, REG2; \
-       add             REG1, REG2, REG1;
-
-       /* Do a user page table walk in MMU globals.  Leaves physical PTE
-        * pointer in REG1.  Jumps to FAIL_LABEL on early page table walk
-        * termination.  Physical base of page tables is in PHYS_PGD which
-        * will not be modified.
-        *
-        * VADDR will not be clobbered, but REG1 and REG2 will.
-        */
-#define USER_PGTABLE_WALK_TL1(VADDR, PHYS_PGD, REG1, REG2, FAIL_LABEL) \
-       sllx            VADDR, 64 - (PGDIR_SHIFT + PGDIR_BITS), REG2; \
-       srlx            REG2, 64 - PAGE_SHIFT, REG2; \
-       andn            REG2, 0x3, REG2; \
-       lduwa           [PHYS_PGD + REG2] ASI_PHYS_USE_EC, REG1; \
-       brz,pn          REG1, FAIL_LABEL; \
-        sllx           VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \
-       srlx            REG2, 64 - PAGE_SHIFT, REG2; \
-       sllx            REG1, 11, REG1; \
-       andn            REG2, 0x3, REG2; \
-       lduwa           [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \
-       brz,pn          REG1, FAIL_LABEL; \
-        sllx           VADDR, 64 - PMD_SHIFT, REG2; \
-       srlx            REG2, 64 - PAGE_SHIFT, REG2; \
-       sllx            REG1, 11, REG1; \
-       andn            REG2, 0x7, REG2; \
-       add             REG1, REG2, REG1;
-
-/* Lookup a OBP mapping on VADDR in the prom_trans[] table at TL>0.
- * If no entry is found, FAIL_LABEL will be branched to.  On success
- * the resulting PTE value will be left in REG1.  VADDR is preserved
- * by this routine.
- */
-#define OBP_TRANS_LOOKUP(VADDR, REG1, REG2, REG3, FAIL_LABEL) \
-       sethi           %hi(prom_trans), REG1; \
-       or              REG1, %lo(prom_trans), REG1; \
-97:    ldx             [REG1 + 0x00], REG2; \
-       brz,pn          REG2, FAIL_LABEL; \
-        nop; \
-       ldx             [REG1 + 0x08], REG3; \
-       add             REG2, REG3, REG3; \
-       cmp             REG2, VADDR; \
-       bgu,pt          %xcc, 98f; \
-        cmp            VADDR, REG3; \
-       bgeu,pt         %xcc, 98f; \
-        ldx            [REG1 + 0x10], REG3; \
-       sub             VADDR, REG2, REG2; \
-       ba,pt           %xcc, 99f; \
-        add            REG3, REG2, REG1; \
-98:    ba,pt           %xcc, 97b; \
-        add            REG1, (3 * 8), REG1; \
-99:
-
-       /* We use a 32K TSB for the whole kernel, this allows to
-        * handle about 16MB of modules and vmalloc mappings without
-        * incurring many hash conflicts.
-        */
-#define KERNEL_TSB_SIZE_BYTES  (32 * 1024)
-#define KERNEL_TSB_NENTRIES    \
-       (KERNEL_TSB_SIZE_BYTES / 16)
-#define KERNEL_TSB4M_NENTRIES  4096
-
-       /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL
-        * on TSB hit.  REG1, REG2, REG3, and REG4 are used as temporaries
-        * and the found TTE will be left in REG1.  REG3 and REG4 must
-        * be an even/odd pair of registers.
-        *
-        * VADDR and TAG will be preserved and not clobbered by this macro.
-        */
-#define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
-       sethi           %hi(swapper_tsb), REG1; \
-       or              REG1, %lo(swapper_tsb), REG1; \
-       srlx            VADDR, PAGE_SHIFT, REG2; \
-       and             REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \
-       sllx            REG2, 4, REG2; \
-       add             REG1, REG2, REG2; \
-       KTSB_LOAD_QUAD(REG2, REG3); \
-       cmp             REG3, TAG; \
-       be,a,pt         %xcc, OK_LABEL; \
-        mov            REG4, REG1;
-
-#ifndef CONFIG_DEBUG_PAGEALLOC
-       /* This version uses a trick, the TAG is already (VADDR >> 22) so
-        * we can make use of that for the index computation.
-        */
-#define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
-       sethi           %hi(swapper_4m_tsb), REG1; \
-       or              REG1, %lo(swapper_4m_tsb), REG1; \
-       and             TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \
-       sllx            REG2, 4, REG2; \
-       add             REG1, REG2, REG2; \
-       KTSB_LOAD_QUAD(REG2, REG3); \
-       cmp             REG3, TAG; \
-       be,a,pt         %xcc, OK_LABEL; \
-        mov            REG4, REG1;
-#endif
-
-#endif /* !(_SPARC64_TSB_H) */
+#include <asm-sparc/tsb.h>
index 0ba199587e07ba649555ac747f4e19376ce3d2a0..a550f1bf6f9bb158fbd223f0261f4164ad2fd124 100644 (file)
@@ -1,658 +1 @@
-#ifndef _SPARC64_TTABLE_H
-#define _SPARC64_TTABLE_H
-
-#include <asm/utrap.h>
-
-#ifdef __ASSEMBLY__
-#include <asm/thread_info.h>
-#endif
-
-#define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop;
-
-/* We need a "cleaned" instruction... */
-#define CLEAN_WINDOW                                                   \
-       rdpr    %cleanwin, %l0;         add     %l0, 1, %l0;            \
-       wrpr    %l0, 0x0, %cleanwin;                                    \
-       clr     %o0;    clr     %o1;    clr     %o2;    clr     %o3;    \
-       clr     %o4;    clr     %o5;    clr     %o6;    clr     %o7;    \
-       clr     %l0;    clr     %l1;    clr     %l2;    clr     %l3;    \
-       clr     %l4;    clr     %l5;    clr     %l6;    clr     %l7;    \
-       retry;                                                          \
-       nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
-
-#define TRAP(routine)                                  \
-       sethi   %hi(109f), %g7;                         \
-       ba,pt   %xcc, etrap;                            \
-109:    or     %g7, %lo(109b), %g7;                    \
-       call    routine;                                \
-        add    %sp, PTREGS_OFF, %o0;                   \
-       ba,pt   %xcc, rtrap;                            \
-        nop;                                           \
-       nop;
-
-#define TRAP_7INSNS(routine)                           \
-       sethi   %hi(109f), %g7;                         \
-       ba,pt   %xcc, etrap;                            \
-109:    or     %g7, %lo(109b), %g7;                    \
-       call    routine;                                \
-        add    %sp, PTREGS_OFF, %o0;                   \
-       ba,pt   %xcc, rtrap;                            \
-        nop;
-
-#define TRAP_SAVEFPU(routine)                          \
-       sethi   %hi(109f), %g7;                         \
-       ba,pt   %xcc, do_fptrap;                        \
-109:    or     %g7, %lo(109b), %g7;                    \
-       call    routine;                                \
-        add    %sp, PTREGS_OFF, %o0;                   \
-       ba,pt   %xcc, rtrap;                            \
-        nop;                                           \
-       nop;
-
-#define TRAP_NOSAVE(routine)                           \
-       ba,pt   %xcc, routine;                          \
-        nop;                                           \
-       nop; nop; nop; nop; nop; nop;
-       
-#define TRAP_NOSAVE_7INSNS(routine)                    \
-       ba,pt   %xcc, routine;                          \
-        nop;                                           \
-       nop; nop; nop; nop; nop;
-       
-#define TRAPTL1(routine)                               \
-       sethi   %hi(109f), %g7;                         \
-       ba,pt   %xcc, etraptl1;                         \
-109:    or     %g7, %lo(109b), %g7;                    \
-       call    routine;                                \
-        add    %sp, PTREGS_OFF, %o0;                   \
-       ba,pt   %xcc, rtrap;                            \
-        nop;                                           \
-       nop;
-       
-#define TRAP_ARG(routine, arg)                         \
-       sethi   %hi(109f), %g7;                         \
-       ba,pt   %xcc, etrap;                            \
-109:    or     %g7, %lo(109b), %g7;                    \
-       add     %sp, PTREGS_OFF, %o0;                   \
-       call    routine;                                \
-        mov    arg, %o1;                               \
-       ba,pt   %xcc, rtrap;                            \
-        nop;
-       
-#define TRAPTL1_ARG(routine, arg)                      \
-       sethi   %hi(109f), %g7;                         \
-       ba,pt   %xcc, etraptl1;                         \
-109:    or     %g7, %lo(109b), %g7;                    \
-       add     %sp, PTREGS_OFF, %o0;                   \
-       call    routine;                                \
-        mov    arg, %o1;                               \
-       ba,pt   %xcc, rtrap;                            \
-        nop;
-       
-#define SYSCALL_TRAP(routine, systbl)                  \
-       rdpr    %pil, %g2;                              \
-       mov     TSTATE_SYSCALL, %g3;                    \
-       sethi   %hi(109f), %g7;                         \
-       ba,pt   %xcc, etrap_syscall;                    \
-109:    or     %g7, %lo(109b), %g7;                    \
-       sethi   %hi(systbl), %l7;                       \
-       ba,pt   %xcc, routine;                          \
-        or     %l7, %lo(systbl), %l7;
-       
-#define TRAP_UTRAP(handler,lvl)                                \
-       mov     handler, %g3;                           \
-       ba,pt   %xcc, utrap_trap;                       \
-        mov    lvl, %g4;                               \
-       nop;                                            \
-       nop;                                            \
-       nop;                                            \
-       nop;                                            \
-       nop;
-
-#ifdef CONFIG_COMPAT
-#define        LINUX_32BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall32, sys_call_table32)
-#else
-#define        LINUX_32BIT_SYSCALL_TRAP BTRAP(0x110)
-#endif
-#define LINUX_64BIT_SYSCALL_TRAP SYSCALL_TRAP(linux_sparc_syscall, sys_call_table64)
-#define GETCC_TRAP TRAP(getcc)
-#define SETCC_TRAP TRAP(setcc)
-#define BREAKPOINT_TRAP TRAP(breakpoint_trap)
-
-#ifdef CONFIG_TRACE_IRQFLAGS
-
-#define TRAP_IRQ(routine, level)                       \
-       rdpr    %pil, %g2;                              \
-       wrpr    %g0, 15, %pil;                          \
-       sethi   %hi(1f-4), %g7;                         \
-       ba,pt   %xcc, etrap_irq;                        \
-        or     %g7, %lo(1f-4), %g7;                    \
-       nop;                                            \
-       nop;                                            \
-       nop;                                            \
-       .subsection     2;                              \
-1:     call    trace_hardirqs_off;                     \
-        nop;                                           \
-       mov     level, %o0;                             \
-       call    routine;                                \
-        add    %sp, PTREGS_OFF, %o1;                   \
-       ba,a,pt %xcc, rtrap_irq;                        \
-       .previous;
-
-#else
-
-#define TRAP_IRQ(routine, level)                       \
-       rdpr    %pil, %g2;                              \
-       wrpr    %g0, 15, %pil;                          \
-       ba,pt   %xcc, etrap_irq;                        \
-        rd     %pc, %g7;                               \
-       mov     level, %o0;                             \
-       call    routine;                                \
-        add    %sp, PTREGS_OFF, %o1;                   \
-       ba,a,pt %xcc, rtrap_irq;
-       
-#endif
-
-#define TRAP_IVEC TRAP_NOSAVE(do_ivec)
-
-#define BTRAP(lvl) TRAP_ARG(bad_trap, lvl)
-
-#define BTRAPTL1(lvl) TRAPTL1_ARG(bad_trap_tl1, lvl)
-
-#define FLUSH_WINDOW_TRAP                                              \
-       ba,pt   %xcc, etrap;                                            \
-        rd     %pc, %g7;                                               \
-       flushw;                                                         \
-       ldx     [%sp + PTREGS_OFF + PT_V9_TNPC], %l1;                   \
-       add     %l1, 4, %l2;                                            \
-       stx     %l1, [%sp + PTREGS_OFF + PT_V9_TPC];                    \
-       ba,pt   %xcc, rtrap;                                            \
-        stx    %l2, [%sp + PTREGS_OFF + PT_V9_TNPC];
-               
-#ifdef CONFIG_KPROBES
-#define KPROBES_TRAP(lvl) TRAP_IRQ(kprobe_trap, lvl)
-#else
-#define KPROBES_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
-#endif
-
-#ifdef CONFIG_KGDB
-#define KGDB_TRAP(lvl) TRAP_IRQ(kgdb_trap, lvl)
-#else
-#define KGDB_TRAP(lvl) TRAP_ARG(bad_trap, lvl)
-#endif
-
-#define SUN4V_ITSB_MISS                                        \
-       ldxa    [%g0] ASI_SCRATCHPAD, %g2;              \
-       ldx     [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4;    \
-       ldx     [%g2 + HV_FAULT_I_CTX_OFFSET], %g5;     \
-       srlx    %g4, 22, %g6;                           \
-       ba,pt   %xcc, sun4v_itsb_miss;                  \
-        nop;                                           \
-       nop;                                            \
-       nop;
-
-#define SUN4V_DTSB_MISS                                        \
-       ldxa    [%g0] ASI_SCRATCHPAD, %g2;              \
-       ldx     [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4;    \
-       ldx     [%g2 + HV_FAULT_D_CTX_OFFSET], %g5;     \
-       srlx    %g4, 22, %g6;                           \
-       ba,pt   %xcc, sun4v_dtsb_miss;                  \
-        nop;                                           \
-       nop;                                            \
-       nop;
-
-/* Before touching these macros, you owe it to yourself to go and
- * see how arch/sparc64/kernel/winfixup.S works... -DaveM
- *
- * For the user cases we used to use the %asi register, but
- * it turns out that the "wr xxx, %asi" costs ~5 cycles, so
- * now we use immediate ASI loads and stores instead.  Kudos
- * to Greg Onufer for pointing out this performance anomaly.
- *
- * Further note that we cannot use the g2, g4, g5, and g7 alternate
- * globals in the spill routines, check out the save instruction in
- * arch/sparc64/kernel/etrap.S to see what I mean about g2, and
- * g4/g5 are the globals which are preserved by etrap processing
- * for the caller of it.  The g7 register is the return pc for
- * etrap.  Finally, g6 is the current thread register so we cannot
- * us it in the spill handlers either.  Most of these rules do not
- * apply to fill processing, only g6 is not usable.
- */
-
-/* Normal kernel spill */
-#define SPILL_0_NORMAL                                 \
-       stx     %l0, [%sp + STACK_BIAS + 0x00];         \
-       stx     %l1, [%sp + STACK_BIAS + 0x08];         \
-       stx     %l2, [%sp + STACK_BIAS + 0x10];         \
-       stx     %l3, [%sp + STACK_BIAS + 0x18];         \
-       stx     %l4, [%sp + STACK_BIAS + 0x20];         \
-       stx     %l5, [%sp + STACK_BIAS + 0x28];         \
-       stx     %l6, [%sp + STACK_BIAS + 0x30];         \
-       stx     %l7, [%sp + STACK_BIAS + 0x38];         \
-       stx     %i0, [%sp + STACK_BIAS + 0x40];         \
-       stx     %i1, [%sp + STACK_BIAS + 0x48];         \
-       stx     %i2, [%sp + STACK_BIAS + 0x50];         \
-       stx     %i3, [%sp + STACK_BIAS + 0x58];         \
-       stx     %i4, [%sp + STACK_BIAS + 0x60];         \
-       stx     %i5, [%sp + STACK_BIAS + 0x68];         \
-       stx     %i6, [%sp + STACK_BIAS + 0x70];         \
-       stx     %i7, [%sp + STACK_BIAS + 0x78];         \
-       saved; retry; nop; nop; nop; nop; nop; nop;     \
-       nop; nop; nop; nop; nop; nop; nop; nop;
-
-#define SPILL_0_NORMAL_ETRAP                           \
-etrap_kernel_spill:                                    \
-       stx     %l0, [%sp + STACK_BIAS + 0x00];         \
-       stx     %l1, [%sp + STACK_BIAS + 0x08];         \
-       stx     %l2, [%sp + STACK_BIAS + 0x10];         \
-       stx     %l3, [%sp + STACK_BIAS + 0x18];         \
-       stx     %l4, [%sp + STACK_BIAS + 0x20];         \
-       stx     %l5, [%sp + STACK_BIAS + 0x28];         \
-       stx     %l6, [%sp + STACK_BIAS + 0x30];         \
-       stx     %l7, [%sp + STACK_BIAS + 0x38];         \
-       stx     %i0, [%sp + STACK_BIAS + 0x40];         \
-       stx     %i1, [%sp + STACK_BIAS + 0x48];         \
-       stx     %i2, [%sp + STACK_BIAS + 0x50];         \
-       stx     %i3, [%sp + STACK_BIAS + 0x58];         \
-       stx     %i4, [%sp + STACK_BIAS + 0x60];         \
-       stx     %i5, [%sp + STACK_BIAS + 0x68];         \
-       stx     %i6, [%sp + STACK_BIAS + 0x70];         \
-       stx     %i7, [%sp + STACK_BIAS + 0x78];         \
-       saved;                                          \
-       sub     %g1, 2, %g1;                            \
-       ba,pt   %xcc, etrap_save;                       \
-       wrpr    %g1, %cwp;                              \
-       nop; nop; nop; nop; nop; nop; nop; nop;         \
-       nop; nop; nop; nop;
-
-/* Normal 64bit spill */
-#define SPILL_1_GENERIC(ASI)                           \
-       add     %sp, STACK_BIAS + 0x00, %g1;            \
-       stxa    %l0, [%g1 + %g0] ASI;                   \
-       mov     0x08, %g3;                              \
-       stxa    %l1, [%g1 + %g3] ASI;                   \
-       add     %g1, 0x10, %g1;                         \
-       stxa    %l2, [%g1 + %g0] ASI;                   \
-       stxa    %l3, [%g1 + %g3] ASI;                   \
-       add     %g1, 0x10, %g1;                         \
-       stxa    %l4, [%g1 + %g0] ASI;                   \
-       stxa    %l5, [%g1 + %g3] ASI;                   \
-       add     %g1, 0x10, %g1;                         \
-       stxa    %l6, [%g1 + %g0] ASI;                   \
-       stxa    %l7, [%g1 + %g3] ASI;                   \
-       add     %g1, 0x10, %g1;                         \
-       stxa    %i0, [%g1 + %g0] ASI;                   \
-       stxa    %i1, [%g1 + %g3] ASI;                   \
-       add     %g1, 0x10, %g1;                         \
-       stxa    %i2, [%g1 + %g0] ASI;                   \
-       stxa    %i3, [%g1 + %g3] ASI;                   \
-       add     %g1, 0x10, %g1;                         \
-       stxa    %i4, [%g1 + %g0] ASI;                   \
-       stxa    %i5, [%g1 + %g3] ASI;                   \
-       add     %g1, 0x10, %g1;                         \
-       stxa    %i6, [%g1 + %g0] ASI;                   \
-       stxa    %i7, [%g1 + %g3] ASI;                   \
-       saved;                                          \
-       retry; nop; nop;                                \
-       b,a,pt  %xcc, spill_fixup_dax;                  \
-       b,a,pt  %xcc, spill_fixup_mna;                  \
-       b,a,pt  %xcc, spill_fixup;
-
-#define SPILL_1_GENERIC_ETRAP                          \
-etrap_user_spill_64bit:                                        \
-       stxa    %l0, [%sp + STACK_BIAS + 0x00] %asi;    \
-       stxa    %l1, [%sp + STACK_BIAS + 0x08] %asi;    \
-       stxa    %l2, [%sp + STACK_BIAS + 0x10] %asi;    \
-       stxa    %l3, [%sp + STACK_BIAS + 0x18] %asi;    \
-       stxa    %l4, [%sp + STACK_BIAS + 0x20] %asi;    \
-       stxa    %l5, [%sp + STACK_BIAS + 0x28] %asi;    \
-       stxa    %l6, [%sp + STACK_BIAS + 0x30] %asi;    \
-       stxa    %l7, [%sp + STACK_BIAS + 0x38] %asi;    \
-       stxa    %i0, [%sp + STACK_BIAS + 0x40] %asi;    \
-       stxa    %i1, [%sp + STACK_BIAS + 0x48] %asi;    \
-       stxa    %i2, [%sp + STACK_BIAS + 0x50] %asi;    \
-       stxa    %i3, [%sp + STACK_BIAS + 0x58] %asi;    \
-       stxa    %i4, [%sp + STACK_BIAS + 0x60] %asi;    \
-       stxa    %i5, [%sp + STACK_BIAS + 0x68] %asi;    \
-       stxa    %i6, [%sp + STACK_BIAS + 0x70] %asi;    \
-       stxa    %i7, [%sp + STACK_BIAS + 0x78] %asi;    \
-       saved;                                          \
-       sub     %g1, 2, %g1;                            \
-       ba,pt   %xcc, etrap_save;                       \
-        wrpr   %g1, %cwp;                              \
-       nop; nop; nop; nop; nop;                        \
-       nop; nop; nop; nop;                             \
-       ba,a,pt %xcc, etrap_spill_fixup_64bit;          \
-       ba,a,pt %xcc, etrap_spill_fixup_64bit;          \
-       ba,a,pt %xcc, etrap_spill_fixup_64bit;
-
-#define SPILL_1_GENERIC_ETRAP_FIXUP                    \
-etrap_spill_fixup_64bit:                               \
-       ldub    [%g6 + TI_WSAVED], %g1;                 \
-       sll     %g1, 3, %g3;                            \
-       add     %g6, %g3, %g3;                          \
-       stx     %sp, [%g3 + TI_RWIN_SPTRS];             \
-       sll     %g1, 7, %g3;                            \
-       add     %g6, %g3, %g3;                          \
-       stx     %l0, [%g3 + TI_REG_WINDOW + 0x00];      \
-       stx     %l1, [%g3 + TI_REG_WINDOW + 0x08];      \
-       stx     %l2, [%g3 + TI_REG_WINDOW + 0x10];      \
-       stx     %l3, [%g3 + TI_REG_WINDOW + 0x18];      \
-       stx     %l4, [%g3 + TI_REG_WINDOW + 0x20];      \
-       stx     %l5, [%g3 + TI_REG_WINDOW + 0x28];      \
-       stx     %l6, [%g3 + TI_REG_WINDOW + 0x30];      \
-       stx     %l7, [%g3 + TI_REG_WINDOW + 0x38];      \
-       stx     %i0, [%g3 + TI_REG_WINDOW + 0x40];      \
-       stx     %i1, [%g3 + TI_REG_WINDOW + 0x48];      \
-       stx     %i2, [%g3 + TI_REG_WINDOW + 0x50];      \
-       stx     %i3, [%g3 + TI_REG_WINDOW + 0x58];      \
-       stx     %i4, [%g3 + TI_REG_WINDOW + 0x60];      \
-       stx     %i5, [%g3 + TI_REG_WINDOW + 0x68];      \
-       stx     %i6, [%g3 + TI_REG_WINDOW + 0x70];      \
-       stx     %i7, [%g3 + TI_REG_WINDOW + 0x78];      \
-       add     %g1, 1, %g1;                            \
-       stb     %g1, [%g6 + TI_WSAVED];                 \
-       saved;                                          \
-       rdpr    %cwp, %g1;                              \
-       sub     %g1, 2, %g1;                            \
-       ba,pt   %xcc, etrap_save;                       \
-        wrpr   %g1, %cwp;                              \
-       nop; nop; nop
-
-/* Normal 32bit spill */
-#define SPILL_2_GENERIC(ASI)                           \
-       srl     %sp, 0, %sp;                            \
-       stwa    %l0, [%sp + %g0] ASI;                   \
-       mov     0x04, %g3;                              \
-       stwa    %l1, [%sp + %g3] ASI;                   \
-       add     %sp, 0x08, %g1;                         \
-       stwa    %l2, [%g1 + %g0] ASI;                   \
-       stwa    %l3, [%g1 + %g3] ASI;                   \
-       add     %g1, 0x08, %g1;                         \
-       stwa    %l4, [%g1 + %g0] ASI;                   \
-       stwa    %l5, [%g1 + %g3] ASI;                   \
-       add     %g1, 0x08, %g1;                         \
-       stwa    %l6, [%g1 + %g0] ASI;                   \
-       stwa    %l7, [%g1 + %g3] ASI;                   \
-       add     %g1, 0x08, %g1;                         \
-       stwa    %i0, [%g1 + %g0] ASI;                   \
-       stwa    %i1, [%g1 + %g3] ASI;                   \
-       add     %g1, 0x08, %g1;                         \
-       stwa    %i2, [%g1 + %g0] ASI;                   \
-       stwa    %i3, [%g1 + %g3] ASI;                   \
-       add     %g1, 0x08, %g1;                         \
-       stwa    %i4, [%g1 + %g0] ASI;                   \
-       stwa    %i5, [%g1 + %g3] ASI;                   \
-       add     %g1, 0x08, %g1;                         \
-       stwa    %i6, [%g1 + %g0] ASI;                   \
-       stwa    %i7, [%g1 + %g3] ASI;                   \
-       saved;                                          \
-        retry; nop; nop;                               \
-       b,a,pt  %xcc, spill_fixup_dax;                  \
-       b,a,pt  %xcc, spill_fixup_mna;                  \
-       b,a,pt  %xcc, spill_fixup;
-
-#define SPILL_2_GENERIC_ETRAP          \
-etrap_user_spill_32bit:                        \
-       srl     %sp, 0, %sp;            \
-       stwa    %l0, [%sp + 0x00] %asi; \
-       stwa    %l1, [%sp + 0x04] %asi; \
-       stwa    %l2, [%sp + 0x08] %asi; \
-       stwa    %l3, [%sp + 0x0c] %asi; \
-       stwa    %l4, [%sp + 0x10] %asi; \
-       stwa    %l5, [%sp + 0x14] %asi; \
-       stwa    %l6, [%sp + 0x18] %asi; \
-       stwa    %l7, [%sp + 0x1c] %asi; \
-       stwa    %i0, [%sp + 0x20] %asi; \
-       stwa    %i1, [%sp + 0x24] %asi; \
-       stwa    %i2, [%sp + 0x28] %asi; \
-       stwa    %i3, [%sp + 0x2c] %asi; \
-       stwa    %i4, [%sp + 0x30] %asi; \
-       stwa    %i5, [%sp + 0x34] %asi; \
-       stwa    %i6, [%sp + 0x38] %asi; \
-       stwa    %i7, [%sp + 0x3c] %asi; \
-       saved;                          \
-       sub     %g1, 2, %g1;            \
-       ba,pt   %xcc, etrap_save;       \
-        wrpr   %g1, %cwp;              \
-       nop; nop; nop; nop;             \
-       nop; nop; nop; nop;             \
-       ba,a,pt %xcc, etrap_spill_fixup_32bit; \
-       ba,a,pt %xcc, etrap_spill_fixup_32bit; \
-       ba,a,pt %xcc, etrap_spill_fixup_32bit;
-
-#define SPILL_2_GENERIC_ETRAP_FIXUP                    \
-etrap_spill_fixup_32bit:                               \
-       ldub    [%g6 + TI_WSAVED], %g1;                 \
-       sll     %g1, 3, %g3;                            \
-       add     %g6, %g3, %g3;                          \
-       stx     %sp, [%g3 + TI_RWIN_SPTRS];             \
-       sll     %g1, 7, %g3;                            \
-       add     %g6, %g3, %g3;                          \
-       stw     %l0, [%g3 + TI_REG_WINDOW + 0x00];      \
-       stw     %l1, [%g3 + TI_REG_WINDOW + 0x04];      \
-       stw     %l2, [%g3 + TI_REG_WINDOW + 0x08];      \
-       stw     %l3, [%g3 + TI_REG_WINDOW + 0x0c];      \
-       stw     %l4, [%g3 + TI_REG_WINDOW + 0x10];      \
-       stw     %l5, [%g3 + TI_REG_WINDOW + 0x14];      \
-       stw     %l6, [%g3 + TI_REG_WINDOW + 0x18];      \
-       stw     %l7, [%g3 + TI_REG_WINDOW + 0x1c];      \
-       stw     %i0, [%g3 + TI_REG_WINDOW + 0x20];      \
-       stw     %i1, [%g3 + TI_REG_WINDOW + 0x24];      \
-       stw     %i2, [%g3 + TI_REG_WINDOW + 0x28];      \
-       stw     %i3, [%g3 + TI_REG_WINDOW + 0x2c];      \
-       stw     %i4, [%g3 + TI_REG_WINDOW + 0x30];      \
-       stw     %i5, [%g3 + TI_REG_WINDOW + 0x34];      \
-       stw     %i6, [%g3 + TI_REG_WINDOW + 0x38];      \
-       stw     %i7, [%g3 + TI_REG_WINDOW + 0x3c];      \
-       add     %g1, 1, %g1;                            \
-       stb     %g1, [%g6 + TI_WSAVED];                 \
-       saved;                                          \
-       rdpr    %cwp, %g1;                              \
-       sub     %g1, 2, %g1;                            \
-       ba,pt   %xcc, etrap_save;                       \
-        wrpr   %g1, %cwp;                              \
-       nop; nop; nop
-
-#define SPILL_1_NORMAL SPILL_1_GENERIC(ASI_AIUP)
-#define SPILL_2_NORMAL SPILL_2_GENERIC(ASI_AIUP)
-#define SPILL_3_NORMAL SPILL_0_NORMAL
-#define SPILL_4_NORMAL SPILL_0_NORMAL
-#define SPILL_5_NORMAL SPILL_0_NORMAL
-#define SPILL_6_NORMAL SPILL_0_NORMAL
-#define SPILL_7_NORMAL SPILL_0_NORMAL
-
-#define SPILL_0_OTHER SPILL_0_NORMAL
-#define SPILL_1_OTHER SPILL_1_GENERIC(ASI_AIUS)
-#define SPILL_2_OTHER SPILL_2_GENERIC(ASI_AIUS)
-#define SPILL_3_OTHER SPILL_3_NORMAL
-#define SPILL_4_OTHER SPILL_4_NORMAL
-#define SPILL_5_OTHER SPILL_5_NORMAL
-#define SPILL_6_OTHER SPILL_6_NORMAL
-#define SPILL_7_OTHER SPILL_7_NORMAL
-
-/* Normal kernel fill */
-#define FILL_0_NORMAL                                  \
-       ldx     [%sp + STACK_BIAS + 0x00], %l0;         \
-       ldx     [%sp + STACK_BIAS + 0x08], %l1;         \
-       ldx     [%sp + STACK_BIAS + 0x10], %l2;         \
-       ldx     [%sp + STACK_BIAS + 0x18], %l3;         \
-       ldx     [%sp + STACK_BIAS + 0x20], %l4;         \
-       ldx     [%sp + STACK_BIAS + 0x28], %l5;         \
-       ldx     [%sp + STACK_BIAS + 0x30], %l6;         \
-       ldx     [%sp + STACK_BIAS + 0x38], %l7;         \
-       ldx     [%sp + STACK_BIAS + 0x40], %i0;         \
-       ldx     [%sp + STACK_BIAS + 0x48], %i1;         \
-       ldx     [%sp + STACK_BIAS + 0x50], %i2;         \
-       ldx     [%sp + STACK_BIAS + 0x58], %i3;         \
-       ldx     [%sp + STACK_BIAS + 0x60], %i4;         \
-       ldx     [%sp + STACK_BIAS + 0x68], %i5;         \
-       ldx     [%sp + STACK_BIAS + 0x70], %i6;         \
-       ldx     [%sp + STACK_BIAS + 0x78], %i7;         \
-       restored; retry; nop; nop; nop; nop; nop; nop;  \
-       nop; nop; nop; nop; nop; nop; nop; nop;
-
-#define FILL_0_NORMAL_RTRAP                            \
-kern_rtt_fill:                                         \
-       rdpr    %cwp, %g1;                              \
-       sub     %g1, 1, %g1;                            \
-       wrpr    %g1, %cwp;                              \
-       ldx     [%sp + STACK_BIAS + 0x00], %l0;         \
-       ldx     [%sp + STACK_BIAS + 0x08], %l1;         \
-       ldx     [%sp + STACK_BIAS + 0x10], %l2;         \
-       ldx     [%sp + STACK_BIAS + 0x18], %l3;         \
-       ldx     [%sp + STACK_BIAS + 0x20], %l4;         \
-       ldx     [%sp + STACK_BIAS + 0x28], %l5;         \
-       ldx     [%sp + STACK_BIAS + 0x30], %l6;         \
-       ldx     [%sp + STACK_BIAS + 0x38], %l7;         \
-       ldx     [%sp + STACK_BIAS + 0x40], %i0;         \
-       ldx     [%sp + STACK_BIAS + 0x48], %i1;         \
-       ldx     [%sp + STACK_BIAS + 0x50], %i2;         \
-       ldx     [%sp + STACK_BIAS + 0x58], %i3;         \
-       ldx     [%sp + STACK_BIAS + 0x60], %i4;         \
-       ldx     [%sp + STACK_BIAS + 0x68], %i5;         \
-       ldx     [%sp + STACK_BIAS + 0x70], %i6;         \
-       ldx     [%sp + STACK_BIAS + 0x78], %i7;         \
-       restored;                                       \
-       add     %g1, 1, %g1;                            \
-       ba,pt   %xcc, kern_rtt_restore;                 \
-        wrpr   %g1, %cwp;                              \
-       nop; nop; nop; nop; nop;                        \
-       nop; nop; nop; nop;
-
-
-/* Normal 64bit fill */
-#define FILL_1_GENERIC(ASI)                            \
-       add     %sp, STACK_BIAS + 0x00, %g1;            \
-       ldxa    [%g1 + %g0] ASI, %l0;                   \
-       mov     0x08, %g2;                              \
-       mov     0x10, %g3;                              \
-       ldxa    [%g1 + %g2] ASI, %l1;                   \
-       mov     0x18, %g5;                              \
-       ldxa    [%g1 + %g3] ASI, %l2;                   \
-       ldxa    [%g1 + %g5] ASI, %l3;                   \
-       add     %g1, 0x20, %g1;                         \
-       ldxa    [%g1 + %g0] ASI, %l4;                   \
-       ldxa    [%g1 + %g2] ASI, %l5;                   \
-       ldxa    [%g1 + %g3] ASI, %l6;                   \
-       ldxa    [%g1 + %g5] ASI, %l7;                   \
-       add     %g1, 0x20, %g1;                         \
-       ldxa    [%g1 + %g0] ASI, %i0;                   \
-       ldxa    [%g1 + %g2] ASI, %i1;                   \
-       ldxa    [%g1 + %g3] ASI, %i2;                   \
-       ldxa    [%g1 + %g5] ASI, %i3;                   \
-       add     %g1, 0x20, %g1;                         \
-       ldxa    [%g1 + %g0] ASI, %i4;                   \
-       ldxa    [%g1 + %g2] ASI, %i5;                   \
-       ldxa    [%g1 + %g3] ASI, %i6;                   \
-       ldxa    [%g1 + %g5] ASI, %i7;                   \
-       restored;                                       \
-       retry; nop; nop; nop; nop;                      \
-       b,a,pt  %xcc, fill_fixup_dax;                   \
-       b,a,pt  %xcc, fill_fixup_mna;                   \
-       b,a,pt  %xcc, fill_fixup;
-
-#define FILL_1_GENERIC_RTRAP                           \
-user_rtt_fill_64bit:                                   \
-       ldxa    [%sp + STACK_BIAS + 0x00] %asi, %l0;    \
-       ldxa    [%sp + STACK_BIAS + 0x08] %asi, %l1;    \
-       ldxa    [%sp + STACK_BIAS + 0x10] %asi, %l2;    \
-       ldxa    [%sp + STACK_BIAS + 0x18] %asi, %l3;    \
-       ldxa    [%sp + STACK_BIAS + 0x20] %asi, %l4;    \
-       ldxa    [%sp + STACK_BIAS + 0x28] %asi, %l5;    \
-       ldxa    [%sp + STACK_BIAS + 0x30] %asi, %l6;    \
-       ldxa    [%sp + STACK_BIAS + 0x38] %asi, %l7;    \
-       ldxa    [%sp + STACK_BIAS + 0x40] %asi, %i0;    \
-       ldxa    [%sp + STACK_BIAS + 0x48] %asi, %i1;    \
-       ldxa    [%sp + STACK_BIAS + 0x50] %asi, %i2;    \
-       ldxa    [%sp + STACK_BIAS + 0x58] %asi, %i3;    \
-       ldxa    [%sp + STACK_BIAS + 0x60] %asi, %i4;    \
-       ldxa    [%sp + STACK_BIAS + 0x68] %asi, %i5;    \
-       ldxa    [%sp + STACK_BIAS + 0x70] %asi, %i6;    \
-       ldxa    [%sp + STACK_BIAS + 0x78] %asi, %i7;    \
-       ba,pt   %xcc, user_rtt_pre_restore;             \
-        restored;                                      \
-       nop; nop; nop; nop; nop; nop;                   \
-       nop; nop; nop; nop; nop;                        \
-       ba,a,pt %xcc, user_rtt_fill_fixup;              \
-       ba,a,pt %xcc, user_rtt_fill_fixup;              \
-       ba,a,pt %xcc, user_rtt_fill_fixup;
-
-
-/* Normal 32bit fill */
-#define FILL_2_GENERIC(ASI)                            \
-       srl     %sp, 0, %sp;                            \
-       lduwa   [%sp + %g0] ASI, %l0;                   \
-       mov     0x04, %g2;                              \
-       mov     0x08, %g3;                              \
-       lduwa   [%sp + %g2] ASI, %l1;                   \
-       mov     0x0c, %g5;                              \
-       lduwa   [%sp + %g3] ASI, %l2;                   \
-       lduwa   [%sp + %g5] ASI, %l3;                   \
-       add     %sp, 0x10, %g1;                         \
-       lduwa   [%g1 + %g0] ASI, %l4;                   \
-       lduwa   [%g1 + %g2] ASI, %l5;                   \
-       lduwa   [%g1 + %g3] ASI, %l6;                   \
-       lduwa   [%g1 + %g5] ASI, %l7;                   \
-       add     %g1, 0x10, %g1;                         \
-       lduwa   [%g1 + %g0] ASI, %i0;                   \
-       lduwa   [%g1 + %g2] ASI, %i1;                   \
-       lduwa   [%g1 + %g3] ASI, %i2;                   \
-       lduwa   [%g1 + %g5] ASI, %i3;                   \
-       add     %g1, 0x10, %g1;                         \
-       lduwa   [%g1 + %g0] ASI, %i4;                   \
-       lduwa   [%g1 + %g2] ASI, %i5;                   \
-       lduwa   [%g1 + %g3] ASI, %i6;                   \
-       lduwa   [%g1 + %g5] ASI, %i7;                   \
-       restored;                                       \
-       retry; nop; nop; nop; nop;                      \
-       b,a,pt  %xcc, fill_fixup_dax;                   \
-       b,a,pt  %xcc, fill_fixup_mna;                   \
-       b,a,pt  %xcc, fill_fixup;
-
-#define FILL_2_GENERIC_RTRAP                           \
-user_rtt_fill_32bit:                                   \
-       srl     %sp, 0, %sp;                            \
-       lduwa   [%sp + 0x00] %asi, %l0;                 \
-       lduwa   [%sp + 0x04] %asi, %l1;                 \
-       lduwa   [%sp + 0x08] %asi, %l2;                 \
-       lduwa   [%sp + 0x0c] %asi, %l3;                 \
-       lduwa   [%sp + 0x10] %asi, %l4;                 \
-       lduwa   [%sp + 0x14] %asi, %l5;                 \
-       lduwa   [%sp + 0x18] %asi, %l6;                 \
-       lduwa   [%sp + 0x1c] %asi, %l7;                 \
-       lduwa   [%sp + 0x20] %asi, %i0;                 \
-       lduwa   [%sp + 0x24] %asi, %i1;                 \
-       lduwa   [%sp + 0x28] %asi, %i2;                 \
-       lduwa   [%sp + 0x2c] %asi, %i3;                 \
-       lduwa   [%sp + 0x30] %asi, %i4;                 \
-       lduwa   [%sp + 0x34] %asi, %i5;                 \
-       lduwa   [%sp + 0x38] %asi, %i6;                 \
-       lduwa   [%sp + 0x3c] %asi, %i7;                 \
-       ba,pt   %xcc, user_rtt_pre_restore;             \
-        restored;                                      \
-       nop; nop; nop; nop; nop;                        \
-       nop; nop; nop; nop; nop;                        \
-       ba,a,pt %xcc, user_rtt_fill_fixup;              \
-       ba,a,pt %xcc, user_rtt_fill_fixup;              \
-       ba,a,pt %xcc, user_rtt_fill_fixup;
-               
-
-#define FILL_1_NORMAL FILL_1_GENERIC(ASI_AIUP)
-#define FILL_2_NORMAL FILL_2_GENERIC(ASI_AIUP)
-#define FILL_3_NORMAL FILL_0_NORMAL
-#define FILL_4_NORMAL FILL_0_NORMAL
-#define FILL_5_NORMAL FILL_0_NORMAL
-#define FILL_6_NORMAL FILL_0_NORMAL
-#define FILL_7_NORMAL FILL_0_NORMAL
-
-#define FILL_0_OTHER FILL_0_NORMAL
-#define FILL_1_OTHER FILL_1_GENERIC(ASI_AIUS)
-#define FILL_2_OTHER FILL_2_GENERIC(ASI_AIUS)
-#define FILL_3_OTHER FILL_3_NORMAL
-#define FILL_4_OTHER FILL_4_NORMAL
-#define FILL_5_OTHER FILL_5_NORMAL
-#define FILL_6_OTHER FILL_6_NORMAL
-#define FILL_7_OTHER FILL_7_NORMAL
-
-#endif /* !(_SPARC64_TTABLE_H) */
+#include <asm-sparc/ttable.h>
index b27ccc85202f8aaa9b20faf889dbefbc90382a11..cfbfad5043eb946405c1400afac3f29851d836d7 100644 (file)
@@ -1,34 +1 @@
-#ifndef _SPARC64_TYPES_H
-#define _SPARC64_TYPES_H
-
-/*
- * This file is never included by application software unless
- * explicitly requested (e.g., via linux/types.h) in which case the
- * application is Linux specific so (user-) name space pollution is
- * not a major issue.  However, for interoperability, libraries still
- * need to be careful to avoid a name clashes.
- */
-#include <asm-generic/int-l64.h>
-
-#ifndef __ASSEMBLY__
-
-typedef unsigned short umode_t;
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef __KERNEL__
-
-#define BITS_PER_LONG 64
-
-#ifndef __ASSEMBLY__
-
-/* Dma addresses come in generic and 64-bit flavours.  */
-
-typedef u32 dma_addr_t;
-typedef u64 dma64_addr_t;
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
-#endif /* defined(_SPARC64_TYPES_H) */
+#include <asm-sparc/types.h>
index 5fcbaf68c3f6ba68159019d7d8c3904cc357d9d0..2872d22844f36ba94bb5a1cb8badc2a373152aba 100644 (file)
@@ -1,273 +1 @@
-#ifndef _ASM_UACCESS_H
-#define _ASM_UACCESS_H
-
-/*
- * User space memory access functions
- */
-
-#ifdef __KERNEL__
-#include <linux/compiler.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <asm/asi.h>
-#include <asm/system.h>
-#include <asm/spitfire.h>
-#include <asm-generic/uaccess.h>
-#endif
-
-#ifndef __ASSEMBLY__
-
-/*
- * Sparc64 is segmented, though more like the M68K than the I386. 
- * We use the secondary ASI to address user memory, which references a
- * completely different VM map, thus there is zero chance of the user
- * doing something queer and tricking us into poking kernel memory.
- *
- * What is left here is basically what is needed for the other parts of
- * the kernel that expect to be able to manipulate, erum, "segments".
- * Or perhaps more properly, permissions.
- *
- * "For historical reasons, these macros are grossly misnamed." -Linus
- */
-
-#define KERNEL_DS   ((mm_segment_t) { ASI_P })
-#define USER_DS     ((mm_segment_t) { ASI_AIUS })      /* har har har */
-
-#define VERIFY_READ    0
-#define VERIFY_WRITE   1
-
-#define get_fs() ((mm_segment_t) { get_thread_current_ds() })
-#define get_ds() (KERNEL_DS)
-
-#define segment_eq(a,b)  ((a).seg == (b).seg)
-
-#define set_fs(val)                                                            \
-do {                                                                           \
-       set_thread_current_ds((val).seg);                                       \
-       __asm__ __volatile__ ("wr %%g0, %0, %%asi" : : "r" ((val).seg));        \
-} while(0)
-
-static inline int __access_ok(const void __user * addr, unsigned long size)
-{
-       return 1;
-}
-
-static inline int access_ok(int type, const void __user * addr, unsigned long size)
-{
-       return 1;
-}
-
-/*
- * The exception table consists of pairs of addresses: the first is the
- * address of an instruction that is allowed to fault, and the second is
- * the address at which the program should continue.  No registers are
- * modified, so it is entirely up to the continuation code to figure out
- * what to do.
- *
- * All the routines below use bits of fixup code that are out of line
- * with the main instruction path.  This means when everything is well,
- * we don't even have to jump over them.  Further, they do not intrude
- * on our cache or tlb entries.
- */
-
-struct exception_table_entry {
-        unsigned int insn, fixup;
-};
-
-extern void __ret_efault(void);
-extern void __retl_efault(void);
-
-/* Uh, these should become the main single-value transfer routines..
- * They automatically use the right size if we just have the right
- * pointer type..
- *
- * This gets kind of ugly. We want to return _two_ values in "get_user()"
- * and yet we don't want to do any pointers, because that is too much
- * of a performance impact. Thus we have a few rather ugly macros here,
- * and hide all the ugliness from the user.
- */
-#define put_user(x,ptr) ({ \
-unsigned long __pu_addr = (unsigned long)(ptr); \
-__chk_user_ptr(ptr); \
-__put_user_nocheck((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
-
-#define get_user(x,ptr) ({ \
-unsigned long __gu_addr = (unsigned long)(ptr); \
-__chk_user_ptr(ptr); \
-__get_user_nocheck((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
-
-#define __put_user(x,ptr) put_user(x,ptr)
-#define __get_user(x,ptr) get_user(x,ptr)
-
-struct __large_struct { unsigned long buf[100]; };
-#define __m(x) ((struct __large_struct *)(x))
-
-#define __put_user_nocheck(data,addr,size) ({ \
-register int __pu_ret; \
-switch (size) { \
-case 1: __put_user_asm(data,b,addr,__pu_ret); break; \
-case 2: __put_user_asm(data,h,addr,__pu_ret); break; \
-case 4: __put_user_asm(data,w,addr,__pu_ret); break; \
-case 8: __put_user_asm(data,x,addr,__pu_ret); break; \
-default: __pu_ret = __put_user_bad(); break; \
-} __pu_ret; })
-
-#define __put_user_asm(x,size,addr,ret)                                        \
-__asm__ __volatile__(                                                  \
-       "/* Put user asm, inline. */\n"                                 \
-"1:\t" "st"#size "a %1, [%2] %%asi\n\t"                                \
-       "clr    %0\n"                                                   \
-"2:\n\n\t"                                                             \
-       ".section .fixup,#alloc,#execinstr\n\t"                         \
-       ".align 4\n"                                                    \
-"3:\n\t"                                                               \
-       "sethi  %%hi(2b), %0\n\t"                                       \
-       "jmpl   %0 + %%lo(2b), %%g0\n\t"                                \
-       " mov   %3, %0\n\n\t"                                           \
-       ".previous\n\t"                                                 \
-       ".section __ex_table,\"a\"\n\t"                                 \
-       ".align 4\n\t"                                                  \
-       ".word  1b, 3b\n\t"                                             \
-       ".previous\n\n\t"                                               \
-       : "=r" (ret) : "r" (x), "r" (__m(addr)),                                \
-        "i" (-EFAULT))
-
-extern int __put_user_bad(void);
-
-#define __get_user_nocheck(data,addr,size,type) ({ \
-register int __gu_ret; \
-register unsigned long __gu_val; \
-switch (size) { \
-case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
-case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
-case 4: __get_user_asm(__gu_val,uw,addr,__gu_ret); break; \
-case 8: __get_user_asm(__gu_val,x,addr,__gu_ret); break; \
-default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
-} data = (type) __gu_val; __gu_ret; })
-
-#define __get_user_nocheck_ret(data,addr,size,type,retval) ({ \
-register unsigned long __gu_val __asm__ ("l1"); \
-switch (size) { \
-case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
-case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
-case 4: __get_user_asm_ret(__gu_val,uw,addr,retval); break; \
-case 8: __get_user_asm_ret(__gu_val,x,addr,retval); break; \
-default: if (__get_user_bad()) return retval; \
-} data = (type) __gu_val; })
-
-#define __get_user_asm(x,size,addr,ret)                                        \
-__asm__ __volatile__(                                                  \
-       "/* Get user asm, inline. */\n"                                 \
-"1:\t" "ld"#size "a [%2] %%asi, %1\n\t"                                \
-       "clr    %0\n"                                                   \
-"2:\n\n\t"                                                             \
-       ".section .fixup,#alloc,#execinstr\n\t"                         \
-       ".align 4\n"                                                    \
-"3:\n\t"                                                               \
-       "sethi  %%hi(2b), %0\n\t"                                       \
-       "clr    %1\n\t"                                                 \
-       "jmpl   %0 + %%lo(2b), %%g0\n\t"                                \
-       " mov   %3, %0\n\n\t"                                           \
-       ".previous\n\t"                                                 \
-       ".section __ex_table,\"a\"\n\t"                                 \
-       ".align 4\n\t"                                                  \
-       ".word  1b, 3b\n\n\t"                                           \
-       ".previous\n\t"                                                 \
-       : "=r" (ret), "=r" (x) : "r" (__m(addr)),                       \
-        "i" (-EFAULT))
-
-#define __get_user_asm_ret(x,size,addr,retval)                         \
-if (__builtin_constant_p(retval) && retval == -EFAULT)                 \
-__asm__ __volatile__(                                                  \
-       "/* Get user asm ret, inline. */\n"                             \
-"1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t"                              \
-       ".section __ex_table,\"a\"\n\t"                                 \
-       ".align 4\n\t"                                                  \
-       ".word  1b,__ret_efault\n\n\t"                                  \
-       ".previous\n\t"                                                 \
-       : "=r" (x) : "r" (__m(addr)));                                  \
-else                                                                   \
-__asm__ __volatile__(                                                  \
-       "/* Get user asm ret, inline. */\n"                             \
-"1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t"                              \
-       ".section .fixup,#alloc,#execinstr\n\t"                         \
-       ".align 4\n"                                                    \
-"3:\n\t"                                                               \
-       "ret\n\t"                                                       \
-       " restore %%g0, %2, %%o0\n\n\t"                                 \
-       ".previous\n\t"                                                 \
-       ".section __ex_table,\"a\"\n\t"                                 \
-       ".align 4\n\t"                                                  \
-       ".word  1b, 3b\n\n\t"                                           \
-       ".previous\n\t"                                                 \
-       : "=r" (x) : "r" (__m(addr)), "i" (retval))
-
-extern int __get_user_bad(void);
-
-extern unsigned long __must_check ___copy_from_user(void *to,
-                                                   const void __user *from,
-                                                   unsigned long size);
-extern unsigned long copy_from_user_fixup(void *to, const void __user *from,
-                                         unsigned long size);
-static inline unsigned long __must_check
-copy_from_user(void *to, const void __user *from, unsigned long size)
-{
-       unsigned long ret = ___copy_from_user(to, from, size);
-
-       if (unlikely(ret))
-               ret = copy_from_user_fixup(to, from, size);
-       return ret;
-}
-#define __copy_from_user copy_from_user
-
-extern unsigned long __must_check ___copy_to_user(void __user *to,
-                                                 const void *from,
-                                                 unsigned long size);
-extern unsigned long copy_to_user_fixup(void __user *to, const void *from,
-                                       unsigned long size);
-static inline unsigned long __must_check
-copy_to_user(void __user *to, const void *from, unsigned long size)
-{
-       unsigned long ret = ___copy_to_user(to, from, size);
-
-       if (unlikely(ret))
-               ret = copy_to_user_fixup(to, from, size);
-       return ret;
-}
-#define __copy_to_user copy_to_user
-
-extern unsigned long __must_check ___copy_in_user(void __user *to,
-                                                 const void __user *from,
-                                                 unsigned long size);
-extern unsigned long copy_in_user_fixup(void __user *to, void __user *from,
-                                       unsigned long size);
-static inline unsigned long __must_check
-copy_in_user(void __user *to, void __user *from, unsigned long size)
-{
-       unsigned long ret = ___copy_in_user(to, from, size);
-
-       if (unlikely(ret))
-               ret = copy_in_user_fixup(to, from, size);
-       return ret;
-}
-#define __copy_in_user copy_in_user
-
-extern unsigned long __must_check __clear_user(void __user *, unsigned long);
-
-#define clear_user __clear_user
-
-extern long __must_check __strncpy_from_user(char *dest, const char __user *src, long count);
-
-#define strncpy_from_user __strncpy_from_user
-
-extern long __strlen_user(const char __user *);
-extern long __strnlen_user(const char __user *, long len);
-
-#define strlen_user __strlen_user
-#define strnlen_user __strnlen_user
-#define __copy_to_user_inatomic __copy_to_user
-#define __copy_from_user_inatomic __copy_from_user
-
-#endif  /* __ASSEMBLY__ */
-
-#endif /* _ASM_UACCESS_H */
+#include <asm-sparc/uaccess.h>
index dc937c75ffdda5955f91fbf841732a05aa5d56a1..9e1b5794b07fc8ff4c214d1a9c4363c517287fa5 100644 (file)
@@ -1,71 +1 @@
-/*
- * uctx.h: Sparc64 {set,get}context() register state layouts.
- *
- * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef __SPARC64_UCTX_H
-#define __SPARC64_UCTX_H
-
-#define MC_TSTATE      0
-#define MC_PC          1
-#define MC_NPC         2
-#define MC_Y           3
-#define MC_G1          4
-#define MC_G2          5
-#define MC_G3          6
-#define MC_G4          7
-#define MC_G5          8
-#define MC_G6          9
-#define MC_G7          10
-#define MC_O0          11
-#define MC_O1          12
-#define MC_O2          13
-#define MC_O3          14
-#define MC_O4          15
-#define MC_O5          16
-#define MC_O6          17
-#define MC_O7          18
-#define MC_NGREG       19
-
-typedef unsigned long mc_greg_t;
-typedef mc_greg_t mc_gregset_t[MC_NGREG];
-
-#define MC_MAXFPQ      16
-struct mc_fq {
-       unsigned long   *mcfq_addr;
-       unsigned int    mcfq_insn;
-};
-
-struct mc_fpu {
-       union {
-               unsigned int    sregs[32];
-               unsigned long   dregs[32];
-               long double     qregs[16];
-       } mcfpu_fregs;
-       unsigned long   mcfpu_fsr;
-       unsigned long   mcfpu_fprs;
-       unsigned long   mcfpu_gsr;
-       struct mc_fq    *mcfpu_fq;
-       unsigned char   mcfpu_qcnt;
-       unsigned char   mcfpu_qentsz;
-       unsigned char   mcfpu_enab;
-};
-typedef struct mc_fpu mc_fpu_t;
-
-typedef struct {
-       mc_gregset_t    mc_gregs;
-       mc_greg_t       mc_fp;
-       mc_greg_t       mc_i7;
-       mc_fpu_t        mc_fpregs;
-} mcontext_t;
-
-struct ucontext {
-       struct ucontext         *uc_link;
-       unsigned long           uc_flags;
-       sigset_t                uc_sigmask;
-       mcontext_t              uc_mcontext;
-};
-typedef struct ucontext ucontext_t;
-
-#endif /* __SPARC64_UCTX_H */
+#include <asm-sparc/uctx.h>
index edcebb09441e9e1451c0e1cee3c4329ebd7b2128..19fbf9508acf76492eebf7903ec38896320e0079 100644 (file)
@@ -1,10 +1 @@
-#ifndef _ASM_SPARC64_UNALIGNED_H
-#define _ASM_SPARC64_UNALIGNED_H
-
-#include <linux/unaligned/be_struct.h>
-#include <linux/unaligned/le_byteshift.h>
-#include <linux/unaligned/generic.h>
-#define get_unaligned  __get_unaligned_be
-#define put_unaligned  __put_unaligned_be
-
-#endif /* _ASM_SPARC64_UNALIGNED_H */
+#include <asm-sparc/unaligned.h>
index 13be4453a1f0808f62cfa4cd276e15b664848a9b..ad86e0b7a455513b93c5e0c1dceda23753abdeff 100644 (file)
@@ -1,373 +1 @@
-#ifndef _SPARC64_UNISTD_H
-#define _SPARC64_UNISTD_H
-
-/*
- * System calls under the Sparc.
- *
- * Don't be scared by the ugly clobbers, it is the only way I can
- * think of right now to force the arguments into fixed registers
- * before the trap into the system call with gcc 'asm' statements.
- *
- * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
- *
- * SunOS compatibility based upon preliminary work which is:
- *
- * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
- */
-
-#define __NR_restart_syscall      0 /* Linux Specific                             */
-#define __NR_exit                 1 /* Common                                      */
-#define __NR_fork                 2 /* Common                                      */
-#define __NR_read                 3 /* Common                                      */
-#define __NR_write                4 /* Common                                      */
-#define __NR_open                 5 /* Common                                      */
-#define __NR_close                6 /* Common                                      */
-#define __NR_wait4                7 /* Common                                      */
-#define __NR_creat                8 /* Common                                      */
-#define __NR_link                 9 /* Common                                      */
-#define __NR_unlink              10 /* Common                                      */
-#define __NR_execv               11 /* SunOS Specific                              */
-#define __NR_chdir               12 /* Common                                      */
-#define __NR_chown              13 /* Common                                      */
-#define __NR_mknod               14 /* Common                                      */
-#define __NR_chmod               15 /* Common                                      */
-#define __NR_lchown              16 /* Common                                      */
-#define __NR_brk                 17 /* Common                                      */
-#define __NR_perfctr             18 /* Performance counter operations              */
-#define __NR_lseek               19 /* Common                                      */
-#define __NR_getpid              20 /* Common                                      */
-#define __NR_capget             21 /* Linux Specific                              */
-#define __NR_capset             22 /* Linux Specific                              */
-#define __NR_setuid              23 /* Implemented via setreuid in SunOS           */
-#define __NR_getuid              24 /* Common                                      */
-#define __NR_vmsplice           25 /* ENOSYS under SunOS                          */
-#define __NR_ptrace              26 /* Common                                      */
-#define __NR_alarm               27 /* Implemented via setitimer in SunOS          */
-#define __NR_sigaltstack        28 /* Common                                      */
-#define __NR_pause               29 /* Is sigblock(0)->sigpause() in SunOS         */
-#define __NR_utime               30 /* Implemented via utimes() under SunOS        */
-/* #define __NR_lchown32         31    Linux sparc32 specific                      */
-/* #define __NR_fchown32         32    Linux sparc32 specific                      */
-#define __NR_access              33 /* Common                                      */
-#define __NR_nice                34 /* Implemented via get/setpriority() in SunOS  */
-/* #define __NR_chown32          35    Linux sparc32 specific                      */
-#define __NR_sync                36 /* Common                                      */
-#define __NR_kill                37 /* Common                                      */
-#define __NR_stat                38 /* Common                                      */
-#define __NR_sendfile           39 /* Linux Specific                              */
-#define __NR_lstat               40 /* Common                                      */
-#define __NR_dup                 41 /* Common                                      */
-#define __NR_pipe                42 /* Common                                      */
-#define __NR_times               43 /* Implemented via getrusage() in SunOS        */
-/* #define __NR_getuid32         44    Linux sparc32 specific                      */
-#define __NR_umount2             45 /* Linux Specific                              */
-#define __NR_setgid              46 /* Implemented via setregid() in SunOS         */
-#define __NR_getgid              47 /* Common                                      */
-#define __NR_signal              48 /* Implemented via sigvec() in SunOS           */
-#define __NR_geteuid             49 /* SunOS calls getuid()                        */
-#define __NR_getegid             50 /* SunOS calls getgid()                        */
-#define __NR_acct                51 /* Common                                      */
-#define __NR_memory_ordering    52 /* Linux Specific                              */
-/* #define __NR_getgid32         53    Linux sparc32 specific                      */
-#define __NR_ioctl               54 /* Common                                      */
-#define __NR_reboot              55 /* Common                                      */
-/* #define __NR_mmap2           56    Linux sparc32 Specific                      */
-#define __NR_symlink             57 /* Common                                      */
-#define __NR_readlink            58 /* Common                                      */
-#define __NR_execve              59 /* Common                                      */
-#define __NR_umask               60 /* Common                                      */
-#define __NR_chroot              61 /* Common                                      */
-#define __NR_fstat               62 /* Common                                      */
-#define __NR_fstat64             63 /* Linux Specific                              */
-#define __NR_getpagesize         64 /* Common                                      */
-#define __NR_msync               65 /* Common in newer 1.3.x revs...               */
-#define __NR_vfork               66 /* Common                                      */
-#define __NR_pread64             67 /* Linux Specific                              */
-#define __NR_pwrite64            68 /* Linux Specific                              */
-/* #define __NR_geteuid32        69    Linux sparc32, sbrk under SunOS             */
-/* #define __NR_getegid32        70    Linux sparc32, sstk under SunOS             */
-#define __NR_mmap                71 /* Common                                      */
-/* #define __NR_setreuid32       72    Linux sparc32, vadvise under SunOS          */
-#define __NR_munmap              73 /* Common                                      */
-#define __NR_mprotect            74 /* Common                                      */
-#define __NR_madvise             75 /* Common                                      */
-#define __NR_vhangup             76 /* Common                                      */
-/* #define __NR_truncate64       77    Linux sparc32 Specific                     */
-#define __NR_mincore             78 /* Common                                      */
-#define __NR_getgroups           79 /* Common                                      */
-#define __NR_setgroups           80 /* Common                                      */
-#define __NR_getpgrp             81 /* Common                                      */
-/* #define __NR_setgroups32      82    Linux sparc32, setpgrp under SunOS          */
-#define __NR_setitimer           83 /* Common                                      */
-/* #define __NR_ftruncate64      84    Linux sparc32 Specific                     */
-#define __NR_swapon              85 /* Common                                      */
-#define __NR_getitimer           86 /* Common                                      */
-/* #define __NR_setuid32         87    Linux sparc32, gethostname under SunOS      */
-#define __NR_sethostname         88 /* Common                                      */
-/* #define __NR_setgid32         89    Linux sparc32, getdtablesize under SunOS    */
-#define __NR_dup2                90 /* Common                                      */
-/* #define __NR_setfsuid32       91    Linux sparc32, getdopt under SunOS          */
-#define __NR_fcntl               92 /* Common                                      */
-#define __NR_select              93 /* Common                                      */
-/* #define __NR_setfsgid32       94    Linux sparc32, setdopt under SunOS          */
-#define __NR_fsync               95 /* Common                                      */
-#define __NR_setpriority         96 /* Common                                      */
-#define __NR_socket              97 /* Common                                      */
-#define __NR_connect             98 /* Common                                      */
-#define __NR_accept              99 /* Common                                      */
-#define __NR_getpriority        100 /* Common                                      */
-#define __NR_rt_sigreturn       101 /* Linux Specific                              */
-#define __NR_rt_sigaction       102 /* Linux Specific                              */
-#define __NR_rt_sigprocmask     103 /* Linux Specific                              */
-#define __NR_rt_sigpending      104 /* Linux Specific                              */
-#define __NR_rt_sigtimedwait    105 /* Linux Specific                              */
-#define __NR_rt_sigqueueinfo    106 /* Linux Specific                              */
-#define __NR_rt_sigsuspend      107 /* Linux Specific                              */
-#define __NR_setresuid          108 /* Linux Specific, sigvec under SunOS         */
-#define __NR_getresuid          109 /* Linux Specific, sigblock under SunOS       */
-#define __NR_setresgid          110 /* Linux Specific, sigsetmask under SunOS     */
-#define __NR_getresgid          111 /* Linux Specific, sigpause under SunOS       */
-/* #define __NR_setregid32       75    Linux sparc32, sigstack under SunOS         */
-#define __NR_recvmsg            113 /* Common                                      */
-#define __NR_sendmsg            114 /* Common                                      */
-/* #define __NR_getgroups32     115    Linux sparc32, vtrace under SunOS           */
-#define __NR_gettimeofday       116 /* Common                                      */
-#define __NR_getrusage          117 /* Common                                      */
-#define __NR_getsockopt         118 /* Common                                      */
-#define __NR_getcwd            119 /* Linux Specific                              */
-#define __NR_readv              120 /* Common                                      */
-#define __NR_writev             121 /* Common                                      */
-#define __NR_settimeofday       122 /* Common                                      */
-#define __NR_fchown             123 /* Common                                      */
-#define __NR_fchmod             124 /* Common                                      */
-#define __NR_recvfrom           125 /* Common                                      */
-#define __NR_setreuid           126 /* Common                                      */
-#define __NR_setregid           127 /* Common                                      */
-#define __NR_rename             128 /* Common                                      */
-#define __NR_truncate           129 /* Common                                      */
-#define __NR_ftruncate          130 /* Common                                      */
-#define __NR_flock              131 /* Common                                      */
-#define __NR_lstat64           132 /* Linux Specific                              */
-#define __NR_sendto             133 /* Common                                      */
-#define __NR_shutdown           134 /* Common                                      */
-#define __NR_socketpair         135 /* Common                                      */
-#define __NR_mkdir              136 /* Common                                      */
-#define __NR_rmdir              137 /* Common                                      */
-#define __NR_utimes             138 /* SunOS Specific                              */
-#define __NR_stat64            139 /* Linux Specific                              */
-#define __NR_sendfile64         140 /* adjtime under SunOS                         */
-#define __NR_getpeername        141 /* Common                                      */
-#define __NR_futex              142 /* gethostid under SunOS                       */
-#define __NR_gettid             143 /* ENOSYS under SunOS                          */
-#define __NR_getrlimit         144 /* Common                                      */
-#define __NR_setrlimit          145 /* Common                                      */
-#define __NR_pivot_root                146 /* Linux Specific, killpg under SunOS          */
-#define __NR_prctl             147 /* ENOSYS under SunOS                          */
-#define __NR_pciconfig_read    148 /* ENOSYS under SunOS                          */
-#define __NR_pciconfig_write   149 /* ENOSYS under SunOS                          */
-#define __NR_getsockname        150 /* Common                                      */
-#define __NR_inotify_init       151 /* Linux specific                              */
-#define __NR_inotify_add_watch  152 /* Linux specific                              */
-#define __NR_poll               153 /* Common                                      */
-#define __NR_getdents64                154 /* Linux specific                              */
-/* #define __NR_fcntl64         155    Linux sparc32 Specific                      */
-#define __NR_inotify_rm_watch   156 /* Linux specific                             */
-#define __NR_statfs             157 /* Common                                      */
-#define __NR_fstatfs            158 /* Common                                      */
-#define __NR_umount             159 /* Common                                      */
-#define __NR_sched_set_affinity 160 /* Linux specific, async_daemon under SunOS    */
-#define __NR_sched_get_affinity 161 /* Linux specific, getfh under SunOS           */
-#define __NR_getdomainname      162 /* SunOS Specific                              */
-#define __NR_setdomainname      163 /* Common                                      */
-#define __NR_utrap_install     164 /* SYSV ABI/v9 required                        */
-#define __NR_quotactl           165 /* Common                                      */
-#define __NR_set_tid_address    166 /* Linux specific, exportfs under SunOS        */
-#define __NR_mount              167 /* Common                                      */
-#define __NR_ustat              168 /* Common                                      */
-#define __NR_setxattr           169 /* SunOS: semsys                               */
-#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
-#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
-#define __NR_getxattr           172 /* SunOS: auditsys                             */
-#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
-#define __NR_getdents           174 /* Common                                      */
-#define __NR_setsid             175 /* Common                                      */
-#define __NR_fchdir             176 /* Common                                      */
-#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
-#define __NR_listxattr          178 /* SunOS: vpixsys                              */
-#define __NR_llistxattr         179 /* SunOS: aioread                              */
-#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
-#define __NR_removexattr        181 /* SunOS: aiowait                              */
-#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
-#define __NR_sigpending         183 /* Common                                      */
-#define __NR_query_module      184 /* Linux Specific                              */
-#define __NR_setpgid            185 /* Common                                      */
-#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
-#define __NR_tkill              187 /* SunOS: fpathconf                            */
-#define __NR_exit_group                188 /* Linux specific, sysconf undef SunOS         */
-#define __NR_uname              189 /* Linux Specific                              */
-#define __NR_init_module        190 /* Linux Specific                              */
-#define __NR_personality        191 /* Linux Specific                              */
-#define __NR_remap_file_pages   192 /* Linux Specific                              */
-#define __NR_epoll_create       193 /* Linux Specific                              */
-#define __NR_epoll_ctl          194 /* Linux Specific                              */
-#define __NR_epoll_wait         195 /* Linux Specific                              */
-#define __NR_ioprio_set         196 /* Linux Specific                              */
-#define __NR_getppid            197 /* Linux Specific                              */
-#define __NR_sigaction          198 /* Linux Specific                              */
-#define __NR_sgetmask           199 /* Linux Specific                              */
-#define __NR_ssetmask           200 /* Linux Specific                              */
-#define __NR_sigsuspend         201 /* Linux Specific                              */
-#define __NR_oldlstat           202 /* Linux Specific                              */
-#define __NR_uselib             203 /* Linux Specific                              */
-#define __NR_readdir            204 /* Linux Specific                              */
-#define __NR_readahead          205 /* Linux Specific                              */
-#define __NR_socketcall         206 /* Linux Specific                              */
-#define __NR_syslog             207 /* Linux Specific                              */
-#define __NR_lookup_dcookie     208 /* Linux Specific                              */
-#define __NR_fadvise64          209 /* Linux Specific                              */
-#define __NR_fadvise64_64       210 /* Linux Specific                              */
-#define __NR_tgkill             211 /* Linux Specific                              */
-#define __NR_waitpid            212 /* Linux Specific                              */
-#define __NR_swapoff            213 /* Linux Specific                              */
-#define __NR_sysinfo            214 /* Linux Specific                              */
-#define __NR_ipc                215 /* Linux Specific                              */
-#define __NR_sigreturn          216 /* Linux Specific                              */
-#define __NR_clone              217 /* Linux Specific                              */
-#define __NR_ioprio_get         218 /* Linux Specific                              */
-#define __NR_adjtimex           219 /* Linux Specific                              */
-#define __NR_sigprocmask        220 /* Linux Specific                              */
-#define __NR_create_module      221 /* Linux Specific                              */
-#define __NR_delete_module      222 /* Linux Specific                              */
-#define __NR_get_kernel_syms    223 /* Linux Specific                              */
-#define __NR_getpgid            224 /* Linux Specific                              */
-#define __NR_bdflush            225 /* Linux Specific                              */
-#define __NR_sysfs              226 /* Linux Specific                              */
-#define __NR_afs_syscall        227 /* Linux Specific                              */
-#define __NR_setfsuid           228 /* Linux Specific                              */
-#define __NR_setfsgid           229 /* Linux Specific                              */
-#define __NR__newselect         230 /* Linux Specific                              */
-#ifdef __KERNEL__
-#define __NR_time              231 /* Linux sparc32                               */
-#endif
-#define __NR_splice             232 /* Linux Specific                              */
-#define __NR_stime              233 /* Linux Specific                              */
-#define __NR_statfs64           234 /* Linux Specific                              */
-#define __NR_fstatfs64          235 /* Linux Specific                              */
-#define __NR__llseek            236 /* Linux Specific                              */
-#define __NR_mlock              237
-#define __NR_munlock            238
-#define __NR_mlockall           239
-#define __NR_munlockall         240
-#define __NR_sched_setparam     241
-#define __NR_sched_getparam     242
-#define __NR_sched_setscheduler 243
-#define __NR_sched_getscheduler 244
-#define __NR_sched_yield        245
-#define __NR_sched_get_priority_max 246
-#define __NR_sched_get_priority_min 247
-#define __NR_sched_rr_get_interval  248
-#define __NR_nanosleep          249
-#define __NR_mremap             250
-#define __NR__sysctl            251
-#define __NR_getsid             252
-#define __NR_fdatasync          253
-#define __NR_nfsservctl         254
-#define __NR_sync_file_range   255
-#define __NR_clock_settime     256
-#define __NR_clock_gettime     257
-#define __NR_clock_getres      258
-#define __NR_clock_nanosleep   259
-#define __NR_sched_getaffinity 260
-#define __NR_sched_setaffinity 261
-#define __NR_timer_settime     262
-#define __NR_timer_gettime     263
-#define __NR_timer_getoverrun  264
-#define __NR_timer_delete      265
-#define __NR_timer_create      266
-/* #define __NR_vserver                267 Reserved for VSERVER */
-#define __NR_io_setup          268
-#define __NR_io_destroy                269
-#define __NR_io_submit         270
-#define __NR_io_cancel         271
-#define __NR_io_getevents      272
-#define __NR_mq_open           273
-#define __NR_mq_unlink         274
-#define __NR_mq_timedsend      275
-#define __NR_mq_timedreceive   276
-#define __NR_mq_notify         277
-#define __NR_mq_getsetattr     278
-#define __NR_waitid            279
-#define __NR_tee               280
-#define __NR_add_key           281
-#define __NR_request_key       282
-#define __NR_keyctl            283
-#define __NR_openat            284
-#define __NR_mkdirat           285
-#define __NR_mknodat           286
-#define __NR_fchownat          287
-#define __NR_futimesat         288
-#define __NR_fstatat64         289
-#define __NR_unlinkat          290
-#define __NR_renameat          291
-#define __NR_linkat            292
-#define __NR_symlinkat         293
-#define __NR_readlinkat                294
-#define __NR_fchmodat          295
-#define __NR_faccessat         296
-#define __NR_pselect6          297
-#define __NR_ppoll             298
-#define __NR_unshare           299
-#define __NR_set_robust_list   300
-#define __NR_get_robust_list   301
-#define __NR_migrate_pages     302
-#define __NR_mbind             303
-#define __NR_get_mempolicy     304
-#define __NR_set_mempolicy     305
-#define __NR_kexec_load                306
-#define __NR_move_pages                307
-#define __NR_getcpu            308
-#define __NR_epoll_pwait       309
-#define __NR_utimensat         310
-#define __NR_signalfd          311
-#define __NR_timerfd_create    312
-#define __NR_eventfd           313
-#define __NR_fallocate         314
-#define __NR_timerfd_settime   315
-#define __NR_timerfd_gettime   316
-
-#define NR_SYSCALLS            317
-
-#ifdef __KERNEL__
-#define __ARCH_WANT_IPC_PARSE_VERSION
-#define __ARCH_WANT_OLD_READDIR
-#define __ARCH_WANT_STAT64
-#define __ARCH_WANT_SYS_ALARM
-#define __ARCH_WANT_SYS_GETHOSTNAME
-#define __ARCH_WANT_SYS_PAUSE
-#define __ARCH_WANT_SYS_SGETMASK
-#define __ARCH_WANT_SYS_SIGNAL
-#define __ARCH_WANT_SYS_TIME
-#define __ARCH_WANT_COMPAT_SYS_TIME
-#define __ARCH_WANT_SYS_UTIME
-#define __ARCH_WANT_SYS_WAITPID
-#define __ARCH_WANT_SYS_SOCKETCALL
-#define __ARCH_WANT_SYS_FADVISE64
-#define __ARCH_WANT_SYS_GETPGRP
-#define __ARCH_WANT_SYS_LLSEEK
-#define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_OLDUMOUNT
-#define __ARCH_WANT_SYS_SIGPENDING
-#define __ARCH_WANT_SYS_SIGPROCMASK
-#define __ARCH_WANT_SYS_RT_SIGSUSPEND
-#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
-
-/*
- * "Conditional" syscalls
- *
- * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
- * but it doesn't work on all toolchains, so we just do it by hand
- */
-#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
-
-#endif /* __KERNEL__ */
-#endif /* _SPARC64_UNISTD_H */
+#include <asm-sparc/unistd.h>
index 5b1633223f924444829db76c34eb93f817fe616b..aab72930815a09fd399b3755bed2afac164c207a 100644 (file)
@@ -1,109 +1 @@
-#ifndef _SPARC64_UPA_H
-#define _SPARC64_UPA_H
-
-#include <asm/asi.h>
-
-/* UPA level registers and defines. */
-
-/* UPA Config Register */
-#define UPA_CONFIG_RESV                0xffffffffc0000000 /* Reserved.                    */
-#define UPA_CONFIG_PCON                0x000000003fc00000 /* Depth of various sys queues. */
-#define UPA_CONFIG_MID         0x00000000003e0000 /* Module ID.                   */
-#define UPA_CONFIG_PCAP                0x000000000001ffff /* Port Capabilities.           */
-
-/* UPA Port ID Register */
-#define UPA_PORTID_FNP         0xff00000000000000 /* Hardcoded to 0xfc on ultra.  */
-#define UPA_PORTID_RESV                0x00fffff800000000 /* Reserved.                    */
-#define UPA_PORTID_ECCVALID     0x0000000400000000 /* Zero if mod can generate ECC */
-#define UPA_PORTID_ONEREAD      0x0000000200000000 /* Set if mod generates P_RASB  */
-#define UPA_PORTID_PINTRDQ      0x0000000180000000 /* # outstanding P_INT_REQ's    */
-#define UPA_PORTID_PREQDQ       0x000000007e000000 /* slave-wr's to mod supported  */
-#define UPA_PORTID_PREQRD       0x0000000001e00000 /* # incoming P_REQ's supported */
-#define UPA_PORTID_UPACAP       0x00000000001f0000 /* UPA capabilities of mod      */
-#define UPA_PORTID_ID           0x000000000000ffff /* Module Identification bits  */
-
-/* UPA I/O space accessors */
-#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
-static inline unsigned char _upa_readb(unsigned long addr)
-{
-       unsigned char ret;
-
-       __asm__ __volatile__("lduba\t[%1] %2, %0\t/* upa_readb */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-
-       return ret;
-}
-
-static inline unsigned short _upa_readw(unsigned long addr)
-{
-       unsigned short ret;
-
-       __asm__ __volatile__("lduha\t[%1] %2, %0\t/* upa_readw */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-
-       return ret;
-}
-
-static inline unsigned int _upa_readl(unsigned long addr)
-{
-       unsigned int ret;
-
-       __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* upa_readl */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-
-       return ret;
-}
-
-static inline unsigned long _upa_readq(unsigned long addr)
-{
-       unsigned long ret;
-
-       __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* upa_readq */"
-                            : "=r" (ret)
-                            : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-
-       return ret;
-}
-
-static inline void _upa_writeb(unsigned char b, unsigned long addr)
-{
-       __asm__ __volatile__("stba\t%0, [%1] %2\t/* upa_writeb */"
-                            : /* no outputs */
-                            : "r" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-}
-
-static inline void _upa_writew(unsigned short w, unsigned long addr)
-{
-       __asm__ __volatile__("stha\t%0, [%1] %2\t/* upa_writew */"
-                            : /* no outputs */
-                            : "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-}
-
-static inline void _upa_writel(unsigned int l, unsigned long addr)
-{
-       __asm__ __volatile__("stwa\t%0, [%1] %2\t/* upa_writel */"
-                            : /* no outputs */
-                            : "r" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-}
-
-static inline void _upa_writeq(unsigned long q, unsigned long addr)
-{
-       __asm__ __volatile__("stxa\t%0, [%1] %2\t/* upa_writeq */"
-                            : /* no outputs */
-                            : "r" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
-}
-
-#define upa_readb(__addr)              (_upa_readb((unsigned long)(__addr)))
-#define upa_readw(__addr)              (_upa_readw((unsigned long)(__addr)))
-#define upa_readl(__addr)              (_upa_readl((unsigned long)(__addr)))
-#define upa_readq(__addr)              (_upa_readq((unsigned long)(__addr)))
-#define upa_writeb(__b, __addr)                (_upa_writeb((__b), (unsigned long)(__addr)))
-#define upa_writew(__w, __addr)                (_upa_writew((__w), (unsigned long)(__addr)))
-#define upa_writel(__l, __addr)                (_upa_writel((__l), (unsigned long)(__addr)))
-#define upa_writeq(__q, __addr)                (_upa_writeq((__q), (unsigned long)(__addr)))
-#endif /* __KERNEL__ && !__ASSEMBLY__ */
-
-#endif /* !(_SPARC64_UPA_H) */
+#include <asm-sparc/upa.h>
index e49e5c46ad6862380fb2ba73a843d84bdb0e1d7e..b030a41f1895f9beb6790dfd0abd315086ece5bd 100644 (file)
@@ -1,51 +1 @@
-/*
- * include/asm-sparc64/utrap.h
- *
- * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#ifndef __ASM_SPARC64_UTRAP_H
-#define __ASM_SPARC64_UTRAP_H
-
-#define UT_INSTRUCTION_EXCEPTION               1
-#define UT_INSTRUCTION_ERROR                   2
-#define UT_INSTRUCTION_PROTECTION              3
-#define UT_ILLTRAP_INSTRUCTION                 4
-#define UT_ILLEGAL_INSTRUCTION                 5
-#define UT_PRIVILEGED_OPCODE                   6
-#define UT_FP_DISABLED                         7
-#define UT_FP_EXCEPTION_IEEE_754               8
-#define UT_FP_EXCEPTION_OTHER                  9
-#define UT_TAG_OVERVIEW                                10
-#define UT_DIVISION_BY_ZERO                    11
-#define UT_DATA_EXCEPTION                      12
-#define UT_DATA_ERROR                          13
-#define UT_DATA_PROTECTION                     14
-#define UT_MEM_ADDRESS_NOT_ALIGNED             15
-#define UT_PRIVILEGED_ACTION                   16
-#define UT_ASYNC_DATA_ERROR                    17
-#define UT_TRAP_INSTRUCTION_16                 18
-#define UT_TRAP_INSTRUCTION_17                 19
-#define UT_TRAP_INSTRUCTION_18                 20
-#define UT_TRAP_INSTRUCTION_19                 21
-#define UT_TRAP_INSTRUCTION_20                 22
-#define UT_TRAP_INSTRUCTION_21                 23
-#define UT_TRAP_INSTRUCTION_22                 24
-#define UT_TRAP_INSTRUCTION_23                 25
-#define UT_TRAP_INSTRUCTION_24                 26
-#define UT_TRAP_INSTRUCTION_25                 27
-#define UT_TRAP_INSTRUCTION_26                 28
-#define UT_TRAP_INSTRUCTION_27                 29
-#define UT_TRAP_INSTRUCTION_28                 30
-#define UT_TRAP_INSTRUCTION_29                 31
-#define UT_TRAP_INSTRUCTION_30                 32
-#define UT_TRAP_INSTRUCTION_31                 33
-
-#define        UTH_NOCHANGE                            (-1)
-
-#ifndef __ASSEMBLY__ 
-typedef int utrap_entry_t;
-typedef void *utrap_handler_t;
-#endif /* __ASSEMBLY__ */
-
-#endif /* !(__ASM_SPARC64_PROCESSOR_H) */
+#include <asm-sparc/utrap.h>
index c69d5b2ba19a488ea3abf8a75c25383edd13d562..fbf4d58a56f024c889f1adf85051f3e9450da9c2 100644 (file)
@@ -1,33 +1 @@
-/*
- *     Access to VGA videoram
- *
- *     (c) 1998 Martin Mares <mj@ucw.cz>
- */
-
-#ifndef _LINUX_ASM_VGA_H_
-#define _LINUX_ASM_VGA_H_
-
-#include <asm/types.h>
-
-#define VT_BUF_HAVE_RW
-
-#undef scr_writew
-#undef scr_readw
-
-static inline void scr_writew(u16 val, u16 *addr)
-{
-       BUG_ON((long) addr >= 0);
-
-       *addr = val;
-}
-
-static inline u16 scr_readw(const u16 *addr)
-{
-       BUG_ON((long) addr >= 0);
-
-       return *addr;
-}
-
-#define VGA_MAP_MEM(x,s) (x)
-
-#endif
+#include <asm-sparc/vga.h>
index d4de32f0f8afdb849495f29aff26f3c0f004f7d3..299b26ab81a7ee7bf00aa03ba0f9501bdbc6f6db 100644 (file)
@@ -1,406 +1 @@
-#ifndef _SPARC64_VIO_H
-#define _SPARC64_VIO_H
-
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/mod_devicetable.h>
-#include <linux/timer.h>
-#include <linux/spinlock.h>
-#include <linux/completion.h>
-#include <linux/list.h>
-#include <linux/log2.h>
-
-#include <asm/ldc.h>
-#include <asm/mdesc.h>
-
-struct vio_msg_tag {
-       u8                      type;
-#define VIO_TYPE_CTRL          0x01
-#define VIO_TYPE_DATA          0x02
-#define VIO_TYPE_ERR           0x04
-
-       u8                      stype;
-#define VIO_SUBTYPE_INFO       0x01
-#define VIO_SUBTYPE_ACK                0x02
-#define VIO_SUBTYPE_NACK       0x04
-
-       u16                     stype_env;
-#define VIO_VER_INFO           0x0001
-#define VIO_ATTR_INFO          0x0002
-#define VIO_DRING_REG          0x0003
-#define VIO_DRING_UNREG                0x0004
-#define VIO_RDX                        0x0005
-#define VIO_PKT_DATA           0x0040
-#define VIO_DESC_DATA          0x0041
-#define VIO_DRING_DATA         0x0042
-#define VNET_MCAST_INFO                0x0101
-
-       u32             sid;
-};
-
-struct vio_rdx {
-       struct vio_msg_tag      tag;
-       u64                     resv[6];
-};
-
-struct vio_ver_info {
-       struct vio_msg_tag      tag;
-       u16                     major;
-       u16                     minor;
-       u8                      dev_class;
-#define VDEV_NETWORK           0x01
-#define VDEV_NETWORK_SWITCH    0x02
-#define VDEV_DISK              0x03
-#define VDEV_DISK_SERVER       0x04
-
-       u8                      resv1[3];
-       u64                     resv2[5];
-};
-
-struct vio_dring_register {
-       struct vio_msg_tag      tag;
-       u64                     dring_ident;
-       u32                     num_descr;
-       u32                     descr_size;
-       u16                     options;
-#define VIO_TX_DRING           0x0001
-#define VIO_RX_DRING           0x0002
-       u16                     resv;
-       u32                     num_cookies;
-       struct ldc_trans_cookie cookies[0];
-};
-
-struct vio_dring_unregister {
-       struct vio_msg_tag      tag;
-       u64                     dring_ident;
-       u64                     resv[5];
-};
-
-/* Data transfer modes */
-#define VIO_PKT_MODE           0x01 /* Packet based transfer   */
-#define VIO_DESC_MODE          0x02 /* In-band descriptors     */
-#define VIO_DRING_MODE         0x03 /* Descriptor rings        */
-
-struct vio_dring_data {
-       struct vio_msg_tag      tag;
-       u64                     seq;
-       u64                     dring_ident;
-       u32                     start_idx;
-       u32                     end_idx;
-       u8                      state;
-#define VIO_DRING_ACTIVE       0x01
-#define VIO_DRING_STOPPED      0x02
-
-       u8                      __pad1;
-       u16                     __pad2;
-       u32                     __pad3;
-       u64                     __par4[2];
-};
-
-struct vio_dring_hdr {
-       u8                      state;
-#define VIO_DESC_FREE          0x01
-#define VIO_DESC_READY         0x02
-#define VIO_DESC_ACCEPTED      0x03
-#define VIO_DESC_DONE          0x04
-       u8                      ack;
-#define VIO_ACK_ENABLE         0x01
-#define VIO_ACK_DISABLE                0x00
-
-       u16                     __pad1;
-       u32                     __pad2;
-};
-
-/* VIO disk specific structures and defines */
-struct vio_disk_attr_info {
-       struct vio_msg_tag      tag;
-       u8                      xfer_mode;
-       u8                      vdisk_type;
-#define VD_DISK_TYPE_SLICE     0x01 /* Slice in block device   */
-#define VD_DISK_TYPE_DISK      0x02 /* Entire block device     */
-       u16                     resv1;
-       u32                     vdisk_block_size;
-       u64                     operations;
-       u64                     vdisk_size;
-       u64                     max_xfer_size;
-       u64                     resv2[2];
-};
-
-struct vio_disk_desc {
-       struct vio_dring_hdr    hdr;
-       u64                     req_id;
-       u8                      operation;
-#define VD_OP_BREAD            0x01 /* Block read                      */
-#define VD_OP_BWRITE           0x02 /* Block write                     */
-#define VD_OP_FLUSH            0x03 /* Flush disk contents             */
-#define VD_OP_GET_WCE          0x04 /* Get write-cache status          */
-#define VD_OP_SET_WCE          0x05 /* Enable/disable write-cache      */
-#define VD_OP_GET_VTOC         0x06 /* Get VTOC                        */
-#define VD_OP_SET_VTOC         0x07 /* Set VTOC                        */
-#define VD_OP_GET_DISKGEOM     0x08 /* Get disk geometry               */
-#define VD_OP_SET_DISKGEOM     0x09 /* Set disk geometry               */
-#define VD_OP_SCSICMD          0x0a /* SCSI control command            */
-#define VD_OP_GET_DEVID                0x0b /* Get device ID                   */
-#define VD_OP_GET_EFI          0x0c /* Get EFI                         */
-#define VD_OP_SET_EFI          0x0d /* Set EFI                         */
-       u8                      slice;
-       u16                     resv1;
-       u32                     status;
-       u64                     offset;
-       u64                     size;
-       u32                     ncookies;
-       u32                     resv2;
-       struct ldc_trans_cookie cookies[0];
-};
-
-#define VIO_DISK_VNAME_LEN     8
-#define VIO_DISK_ALABEL_LEN    128
-#define VIO_DISK_NUM_PART      8
-
-struct vio_disk_vtoc {
-       u8                      volume_name[VIO_DISK_VNAME_LEN];
-       u16                     sector_size;
-       u16                     num_partitions;
-       u8                      ascii_label[VIO_DISK_ALABEL_LEN];
-       struct {
-               u16             id;
-               u16             perm_flags;
-               u32             resv;
-               u64             start_block;
-               u64             num_blocks;
-       } partitions[VIO_DISK_NUM_PART];
-};
-
-struct vio_disk_geom {
-       u16                     num_cyl; /* Num data cylinders          */
-       u16                     alt_cyl; /* Num alternate cylinders     */
-       u16                     beg_cyl; /* Cyl off of fixed head area  */
-       u16                     num_hd;  /* Num heads                   */
-       u16                     num_sec; /* Num sectors                 */
-       u16                     ifact;   /* Interleave factor           */
-       u16                     apc;     /* Alts per cylinder (SCSI)    */
-       u16                     rpm;     /* Revolutions per minute      */
-       u16                     phy_cyl; /* Num physical cylinders      */
-       u16                     wr_skip; /* Num sects to skip, writes   */
-       u16                     rd_skip; /* Num sects to skip, writes   */
-};
-
-struct vio_disk_devid {
-       u16                     resv;
-       u16                     type;
-       u32                     len;
-       char                    id[0];
-};
-
-struct vio_disk_efi {
-       u64                     lba;
-       u64                     len;
-       char                    data[0];
-};
-
-/* VIO net specific structures and defines */
-struct vio_net_attr_info {
-       struct vio_msg_tag      tag;
-       u8                      xfer_mode;
-       u8                      addr_type;
-#define VNET_ADDR_ETHERMAC     0x01
-       u16                     ack_freq;
-       u32                     resv1;
-       u64                     addr;
-       u64                     mtu;
-       u64                     resv2[3];
-};
-
-#define VNET_NUM_MCAST         7
-
-struct vio_net_mcast_info {
-       struct vio_msg_tag      tag;
-       u8                      set;
-       u8                      count;
-       u8                      mcast_addr[VNET_NUM_MCAST * 6];
-       u32                     resv;
-};
-
-struct vio_net_desc {
-       struct vio_dring_hdr    hdr;
-       u32                     size;
-       u32                     ncookies;
-       struct ldc_trans_cookie cookies[0];
-};
-
-#define VIO_MAX_RING_COOKIES   24
-
-struct vio_dring_state {
-       u64                     ident;
-       void                    *base;
-       u64                     snd_nxt;
-       u64                     rcv_nxt;
-       u32                     entry_size;
-       u32                     num_entries;
-       u32                     prod;
-       u32                     cons;
-       u32                     pending;
-       int                     ncookies;
-       struct ldc_trans_cookie cookies[VIO_MAX_RING_COOKIES];
-};
-
-static inline void *vio_dring_cur(struct vio_dring_state *dr)
-{
-       return dr->base + (dr->entry_size * dr->prod);
-}
-
-static inline void *vio_dring_entry(struct vio_dring_state *dr,
-                                   unsigned int index)
-{
-       return dr->base + (dr->entry_size * index);
-}
-
-static inline u32 vio_dring_avail(struct vio_dring_state *dr,
-                                 unsigned int ring_size)
-{
-       BUILD_BUG_ON(!is_power_of_2(ring_size));
-
-       return (dr->pending -
-               ((dr->prod - dr->cons) & (ring_size - 1)));
-}
-
-#define VIO_MAX_TYPE_LEN       32
-#define VIO_MAX_COMPAT_LEN     64
-
-struct vio_dev {
-       u64                     mp;
-       struct device_node      *dp;
-
-       char                    type[VIO_MAX_TYPE_LEN];
-       char                    compat[VIO_MAX_COMPAT_LEN];
-       int                     compat_len;
-
-       u64                     dev_no;
-
-       unsigned long           channel_id;
-
-       unsigned int            tx_irq;
-       unsigned int            rx_irq;
-
-       struct device           dev;
-};
-
-struct vio_driver {
-       struct list_head                node;
-       const struct vio_device_id      *id_table;
-       int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
-       int (*remove)(struct vio_dev *dev);
-       void (*shutdown)(struct vio_dev *dev);
-       unsigned long                   driver_data;
-       struct device_driver            driver;
-};
-
-struct vio_version {
-       u16             major;
-       u16             minor;
-};
-
-struct vio_driver_state;
-struct vio_driver_ops {
-       int     (*send_attr)(struct vio_driver_state *vio);
-       int     (*handle_attr)(struct vio_driver_state *vio, void *pkt);
-       void    (*handshake_complete)(struct vio_driver_state *vio);
-};
-
-struct vio_completion {
-       struct completion       com;
-       int                     err;
-       int                     waiting_for;
-};
-
-struct vio_driver_state {
-       /* Protects VIO handshake and, optionally, driver private state.  */
-       spinlock_t              lock;
-
-       struct ldc_channel      *lp;
-
-       u32                     _peer_sid;
-       u32                     _local_sid;
-       struct vio_dring_state  drings[2];
-#define VIO_DRIVER_TX_RING     0
-#define VIO_DRIVER_RX_RING     1
-
-       u8                      hs_state;
-#define VIO_HS_INVALID         0x00
-#define VIO_HS_GOTVERS         0x01
-#define VIO_HS_GOT_ATTR                0x04
-#define VIO_HS_SENT_DREG       0x08
-#define VIO_HS_SENT_RDX                0x10
-#define VIO_HS_GOT_RDX_ACK     0x20
-#define VIO_HS_GOT_RDX         0x40
-#define VIO_HS_SENT_RDX_ACK    0x80
-#define VIO_HS_COMPLETE                (VIO_HS_GOT_RDX_ACK | VIO_HS_SENT_RDX_ACK)
-
-       u8                      dev_class;
-
-       u8                      dr_state;
-#define VIO_DR_STATE_TXREG     0x01
-#define VIO_DR_STATE_RXREG     0x02
-#define VIO_DR_STATE_TXREQ     0x10
-#define VIO_DR_STATE_RXREQ     0x20
-
-       u8                      debug;
-#define VIO_DEBUG_HS           0x01
-#define VIO_DEBUG_DATA         0x02
-
-       void                    *desc_buf;
-       unsigned int            desc_buf_len;
-
-       struct vio_completion   *cmp;
-
-       struct vio_dev          *vdev;
-
-       struct timer_list       timer;
-
-       struct vio_version      ver;
-
-       struct vio_version      *ver_table;
-       int                     ver_table_entries;
-
-       char                    *name;
-
-       struct vio_driver_ops   *ops;
-};
-
-#define viodbg(TYPE, f, a...) \
-do {   if (vio->debug & VIO_DEBUG_##TYPE) \
-               printk(KERN_INFO "vio: ID[%lu] " f, \
-                      vio->vdev->channel_id, ## a); \
-} while (0)
-
-extern int vio_register_driver(struct vio_driver *drv);
-extern void vio_unregister_driver(struct vio_driver *drv);
-
-static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
-{
-       return container_of(drv, struct vio_driver, driver);
-}
-
-static inline struct vio_dev *to_vio_dev(struct device *dev)
-{
-       return container_of(dev, struct vio_dev, dev);
-}
-
-extern int vio_ldc_send(struct vio_driver_state *vio, void *data, int len);
-extern void vio_link_state_change(struct vio_driver_state *vio, int event);
-extern void vio_conn_reset(struct vio_driver_state *vio);
-extern int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt);
-extern int vio_validate_sid(struct vio_driver_state *vio,
-                           struct vio_msg_tag *tp);
-extern u32 vio_send_sid(struct vio_driver_state *vio);
-extern int vio_ldc_alloc(struct vio_driver_state *vio,
-                        struct ldc_channel_config *base_cfg, void *event_arg);
-extern void vio_ldc_free(struct vio_driver_state *vio);
-extern int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev,
-                          u8 dev_class, struct vio_version *ver_table,
-                          int ver_table_size, struct vio_driver_ops *ops,
-                          char *name);
-
-extern void vio_port_up(struct vio_driver_state *vio);
-
-#endif /* _SPARC64_VIO_H */
+#include <asm-sparc/vio.h>
index 34f2ec64933b1e25f7463e587e2070dc26d89175..837a12278f4ac6e0f37105cad2889ff08480406a 100644 (file)
@@ -1,62 +1 @@
-#ifndef _SPARC64_VISASM_H
-#define _SPARC64_VISASM_H
-
-/* visasm.h:  FPU saving macros for VIS routines
- *
- * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
- */
-#include <asm/pstate.h>
-#include <asm/ptrace.h>
-
-/* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc */
-
-#define VISEntry                                       \
-       rd              %fprs, %o5;                     \
-       andcc           %o5, (FPRS_FEF|FPRS_DU), %g0;   \
-       be,pt           %icc, 297f;                     \
-        sethi          %hi(297f), %g7;                 \
-       sethi           %hi(VISenter), %g1;             \
-       jmpl            %g1 + %lo(VISenter), %g0;       \
-        or             %g7, %lo(297f), %g7;            \
-297:   wr              %g0, FPRS_FEF, %fprs;           \
-
-#define VISExit                                                \
-       wr              %g0, 0, %fprs;
-
-/* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc.
- * Must preserve %o5 between VISEntryHalf and VISExitHalf */
-
-#define VISEntryHalf                                   \
-       rd              %fprs, %o5;                     \
-       andcc           %o5, FPRS_FEF, %g0;             \
-       be,pt           %icc, 297f;                     \
-        sethi          %hi(298f), %g7;                 \
-       sethi           %hi(VISenterhalf), %g1;         \
-       jmpl            %g1 + %lo(VISenterhalf), %g0;   \
-        or             %g7, %lo(298f), %g7;            \
-       clr             %o5;                            \
-297:   wr              %o5, FPRS_FEF, %fprs;           \
-298:
-
-#define VISExitHalf                                    \
-       wr              %o5, 0, %fprs;
-
-#ifndef __ASSEMBLY__   
-static inline void save_and_clear_fpu(void) {
-       __asm__ __volatile__ (
-"              rd %%fprs, %%o5\n"
-"              andcc %%o5, %0, %%g0\n"
-"              be,pt %%icc, 299f\n"
-"               sethi %%hi(298f), %%g7\n"
-"              sethi %%hi(VISenter), %%g1\n"
-"              jmpl %%g1 + %%lo(VISenter), %%g0\n"
-"               or %%g7, %%lo(298f), %%g7\n"
-"      298:    wr %%g0, 0, %%fprs\n"
-"      299:\n"
-"              " : : "i" (FPRS_FEF|FPRS_DU) :
-               "o5", "g1", "g2", "g3", "g7", "cc");
-}
-#endif
-
-#endif /* _SPARC64_ASI_H */
+#include <asm-sparc/visasm.h>
index 5baf2d3919cf4a5552bb5e52e7146d461561349b..b0f2857145f7afbbf15c3a3918d5d44069abf981 100644 (file)
@@ -1,31 +1 @@
-/*
- *
- * watchdog - Driver interface for the hardware watchdog timers
- * present on Sun Microsystems boardsets
- *
- * Copyright (c) 2000 Eric Brower <ebrower@usa.net>
- *
- */
-
-#ifndef _SPARC64_WATCHDOG_H
-#define _SPARC64_WATCHDOG_H
-
-#include <linux/watchdog.h>
-
-/* Solaris compatibility ioctls--
- * Ref. <linux/watchdog.h> for standard linux watchdog ioctls
- */
-#define WIOCSTART _IO (WATCHDOG_IOCTL_BASE, 10)                /* Start Timer          */
-#define WIOCSTOP  _IO (WATCHDOG_IOCTL_BASE, 11)                /* Stop Timer           */
-#define WIOCGSTAT _IOR(WATCHDOG_IOCTL_BASE, 12, int)/* Get Timer Status        */
-
-/* Status flags from WIOCGSTAT ioctl
- */
-#define WD_FREERUN     0x01    /* timer is running, interrupts disabled        */
-#define WD_EXPIRED     0x02    /* timer has expired                                            */
-#define WD_RUNNING     0x04    /* timer is running, interrupts enabled         */
-#define WD_STOPPED     0x08    /* timer has not been started                           */
-#define WD_SERVICED 0x10       /* timer interrupt was serviced                         */
-
-#endif /* ifndef _SPARC64_WATCHDOG_H */
-
+#include <asm-sparc/watchdog.h>
index a0233884fc94c6084045b7db829c849ba9a06f24..ef187cc07ed5b150b5de506f3b7dff6a6f300f9c 100644 (file)
@@ -1,70 +1 @@
-/*
- * include/asm-sparc64/xor.h
- *
- * High speed xor_block operation for RAID4/5 utilizing the
- * UltraSparc Visual Instruction Set and Niagara block-init
- * twin-load instructions.
- *
- * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
- * Copyright (C) 2006 David S. Miller <davem@davemloft.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, or (at your option)
- * any later version.
- *
- * You should have received a copy of the GNU General Public License
- * (for example /usr/src/linux/COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <asm/spitfire.h>
-
-extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *);
-extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *,
-                     unsigned long *);
-extern void xor_vis_4(unsigned long, unsigned long *, unsigned long *,
-                     unsigned long *, unsigned long *);
-extern void xor_vis_5(unsigned long, unsigned long *, unsigned long *,
-                     unsigned long *, unsigned long *, unsigned long *);
-
-/* XXX Ugh, write cheetah versions... -DaveM */
-
-static struct xor_block_template xor_block_VIS = {
-        .name  = "VIS",
-        .do_2  = xor_vis_2,
-        .do_3  = xor_vis_3,
-        .do_4  = xor_vis_4,
-        .do_5  = xor_vis_5,
-};
-
-extern void xor_niagara_2(unsigned long, unsigned long *, unsigned long *);
-extern void xor_niagara_3(unsigned long, unsigned long *, unsigned long *,
-                         unsigned long *);
-extern void xor_niagara_4(unsigned long, unsigned long *, unsigned long *,
-                         unsigned long *, unsigned long *);
-extern void xor_niagara_5(unsigned long, unsigned long *, unsigned long *,
-                         unsigned long *, unsigned long *, unsigned long *);
-
-static struct xor_block_template xor_block_niagara = {
-        .name  = "Niagara",
-        .do_2  = xor_niagara_2,
-        .do_3  = xor_niagara_3,
-        .do_4  = xor_niagara_4,
-        .do_5  = xor_niagara_5,
-};
-
-#undef XOR_TRY_TEMPLATES
-#define XOR_TRY_TEMPLATES                              \
-       do {                                            \
-               xor_speed(&xor_block_VIS);              \
-               xor_speed(&xor_block_niagara);          \
-       } while (0)
-
-/* For VIS for everything except Niagara.  */
-#define XOR_SELECT_TEMPLATE(FASTEST) \
-       ((tlb_type == hypervisor && \
-         (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || \
-          sun4v_chip_type == SUN4V_CHIP_NIAGARA2)) ? \
-        &xor_block_niagara : \
-        &xor_block_VIS)
+#include <asm-sparc/xor.h>
index 7bfcb47cc452d5dc27ce2bf34c7cb22acddec7b7..22aa58ca1991c3003565f8fbc0313f3cf37b9d92 100644 (file)
 /*
  * some size calculation constants
  */
-#define DEV_TABLE_ENTRY_SIZE           256
+#define DEV_TABLE_ENTRY_SIZE           32
 #define ALIAS_TABLE_ENTRY_SIZE         2
 #define RLOOKUP_TABLE_ENTRY_SIZE       (sizeof(void *))
 
 /* helper macros */
 #define LOW_U32(x) ((x) & ((1ULL << 32)-1))
-#define HIGH_U32(x) (LOW_U32((x) >> 32))
 
 /* Length of the MMIO region for the AMD IOMMU */
 #define MMIO_REGION_LENGTH       0x4000
 
 #define MAX_DOMAIN_ID 65536
 
+/*
+ * This structure contains generic data for  IOMMU protection domains
+ * independent of their use.
+ */
 struct protection_domain {
-       spinlock_t lock;
-       u16 id;
-       int mode;
-       u64 *pt_root;
-       void *priv;
+       spinlock_t lock; /* mostly used to lock the page table*/
+       u16 id;          /* the domain id written to the device table */
+       int mode;        /* paging mode (0-6 levels) */
+       u64 *pt_root;    /* page table root pointer */
+       void *priv;      /* private data */
 };
 
+/*
+ * Data container for a dma_ops specific protection domain
+ */
 struct dma_ops_domain {
        struct list_head list;
+
+       /* generic protection domain information */
        struct protection_domain domain;
+
+       /* size of the aperture for the mappings */
        unsigned long aperture_size;
+
+       /* address we start to search for free addresses */
        unsigned long next_bit;
+
+       /* address allocation bitmap */
        unsigned long *bitmap;
+
+       /*
+        * Array of PTE pages for the aperture. In this array we save all the
+        * leaf pages of the domain page table used for the aperture. This way
+        * we don't need to walk the page table to find a specific PTE. We can
+        * just calculate its address in constant time.
+        */
        u64 **pte_pages;
 };
 
+/*
+ * Structure where we save information about one hardware AMD IOMMU in the
+ * system.
+ */
 struct amd_iommu {
        struct list_head list;
+
+       /* locks the accesses to the hardware */
        spinlock_t lock;
 
+       /* device id of this IOMMU */
        u16 devid;
+       /*
+        * Capability pointer. There could be more than one IOMMU per PCI
+        * device function if there are more than one AMD IOMMU capability
+        * pointers.
+        */
        u16 cap_ptr;
 
+       /* physical address of MMIO space */
        u64 mmio_phys;
+       /* virtual address of MMIO space */
        u8 *mmio_base;
+
+       /* capabilities of that IOMMU read from ACPI */
        u32 cap;
+
+       /* first device this IOMMU handles. read from PCI */
        u16 first_device;
+       /* last device this IOMMU handles. read from PCI */
        u16 last_device;
+
+       /* start of exclusion range of that IOMMU */
        u64 exclusion_start;
+       /* length of exclusion range of that IOMMU */
        u64 exclusion_length;
 
+       /* command buffer virtual address */
        u8 *cmd_buf;
+       /* size of command buffer */
        u32 cmd_buf_size;
 
+       /* if one, we need to send a completion wait command */
        int need_sync;
 
+       /* default dma_ops domain for that IOMMU */
        struct dma_ops_domain *default_dom;
 };
 
+/*
+ * List with all IOMMUs in the system. This list is not locked because it is
+ * only written and read at driver initialization or suspend time
+ */
 extern struct list_head amd_iommu_list;
 
+/*
+ * Structure defining one entry in the device table
+ */
 struct dev_table_entry {
        u32 data[8];
 };
 
+/*
+ * One entry for unity mappings parsed out of the ACPI table.
+ */
 struct unity_map_entry {
        struct list_head list;
+
+       /* starting device id this entry is used for (including) */
        u16 devid_start;
+       /* end device id this entry is used for (including) */
        u16 devid_end;
+
+       /* start address to unity map (including) */
        u64 address_start;
+       /* end address to unity map (including) */
        u64 address_end;
+
+       /* required protection */
        int prot;
 };
 
+/*
+ * List of all unity mappings. It is not locked because as runtime it is only
+ * read. It is created at ACPI table parsing time.
+ */
 extern struct list_head amd_iommu_unity_map;
 
-/* data structures for device handling */
+/*
+ * Data structures for device handling
+ */
+
+/*
+ * Device table used by hardware. Read and write accesses by software are
+ * locked with the amd_iommu_pd_table lock.
+ */
 extern struct dev_table_entry *amd_iommu_dev_table;
+
+/*
+ * Alias table to find requestor ids to device ids. Not locked because only
+ * read on runtime.
+ */
 extern u16 *amd_iommu_alias_table;
+
+/*
+ * Reverse lookup table to find the IOMMU which translates a specific device.
+ */
 extern struct amd_iommu **amd_iommu_rlookup_table;
 
+/* size of the dma_ops aperture as power of 2 */
 extern unsigned amd_iommu_aperture_order;
 
+/* largest PCI device id we expect translation requests for */
 extern u16 amd_iommu_last_bdf;
 
 /* data structures for protection domain handling */
 extern struct protection_domain **amd_iommu_pd_table;
+
+/* allocation bitmap for domain ids */
 extern unsigned long *amd_iommu_pd_alloc_bitmap;
 
+/* will be 1 if device isolation is enabled */
 extern int amd_iommu_isolate;
 
+/* takes a PCI device id and prints it out in a readable form */
 static inline void print_devid(u16 devid, int nl)
 {
        int bus = devid >> 8;
@@ -241,4 +332,11 @@ static inline void print_devid(u16 devid, int nl)
                printk("\n");
 }
 
+/* takes bus and device/function and returns the device id
+ * FIXME: should that be in generic PCI code? */
+static inline u16 calc_devid(u8 bus, u8 devfn)
+{
+       return (((u16)bus) << 8) | devfn;
+}
+
 #endif
index 4e2c1e517f0652fb1877c378f760fdb03fe6e8bb..133c998161ca4930dae0efe954802a45af2d62d4 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <linux/pm.h>
 #include <linux/delay.h>
+
+#include <asm/alternative.h>
 #include <asm/fixmap.h>
 #include <asm/apicdef.h>
 #include <asm/processor.h>
@@ -10,8 +12,6 @@
 
 #define ARCH_APICTIMER_STOPS_ON_C3     1
 
-#define Dprintk(x...)
-
 /*
  * Debugging macros
  */
@@ -35,7 +35,7 @@ extern void generic_apic_probe(void);
 
 #ifdef CONFIG_X86_LOCAL_APIC
 
-extern int apic_verbosity;
+extern unsigned int apic_verbosity;
 extern int local_apic_timer_c2_ok;
 
 extern int ioapic_force;
@@ -48,7 +48,6 @@ extern int disable_apic;
 #include <asm/paravirt.h>
 #else
 #define apic_write native_apic_write
-#define apic_write_atomic native_apic_write_atomic
 #define apic_read native_apic_read
 #define setup_boot_clock setup_boot_APIC_clock
 #define setup_secondary_clock setup_secondary_APIC_clock
@@ -58,12 +57,11 @@ extern int is_vsmp_box(void);
 
 static inline void native_apic_write(unsigned long reg, u32 v)
 {
-       *((volatile u32 *)(APIC_BASE + reg)) = v;
-}
+       volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
 
-static inline void native_apic_write_atomic(unsigned long reg, u32 v)
-{
-       (void)xchg((u32 *)(APIC_BASE + reg), v);
+       alternative_io("movl %0, %1", "xchgl %0, %1", X86_FEATURE_11AP,
+                      ASM_OUTPUT2("=r" (v), "=m" (*addr)),
+                      ASM_OUTPUT2("0" (v), "m" (*addr)));
 }
 
 static inline u32 native_apic_read(unsigned long reg)
@@ -75,16 +73,6 @@ extern void apic_wait_icr_idle(void);
 extern u32 safe_apic_wait_icr_idle(void);
 extern int get_physical_broadcast(void);
 
-#ifdef CONFIG_X86_GOOD_APIC
-# define FORCE_READ_AROUND_WRITE 0
-# define apic_read_around(x)
-# define apic_write_around(x, y) apic_write((x), (y))
-#else
-# define FORCE_READ_AROUND_WRITE 1
-# define apic_read_around(x) apic_read(x)
-# define apic_write_around(x, y) apic_write_atomic((x), (y))
-#endif
-
 static inline void ack_APIC_irq(void)
 {
        /*
@@ -95,7 +83,7 @@ static inline void ack_APIC_irq(void)
         */
 
        /* Docs say use 0 for future compatibility */
-       apic_write_around(APIC_EOI, 0);
+       apic_write(APIC_EOI, 0);
 }
 
 extern int lapic_get_maxlvt(void);
index 768aee8a04ef85c5cf1c6ee1b22fa0ebcf3dc60d..8411750ceb633763ad2fda66d8f154f9b87cfd7f 100644 (file)
@@ -21,6 +21,7 @@ extern void intr_init_hook(void);
 extern void pre_intr_init_hook(void);
 extern void pre_setup_arch_hook(void);
 extern void trap_init_hook(void);
+extern void pre_time_init_hook(void);
 extern void time_init_hook(void);
 extern void mca_nmi_hook(void);
 
index 96b1829cea15aa0fbc00177e394a9bab47a5a5b7..cfb2b64f76e7d645a8418426f71239b80250c5bb 100644 (file)
@@ -356,7 +356,7 @@ static inline unsigned long ffz(unsigned long word)
  * __fls: find last set bit in word
  * @word: The word to search
  *
- * Undefined if no zero exists, so code should check against ~0UL first.
+ * Undefined if no set bit exists, so code should check against 0 first.
  */
 static inline unsigned long __fls(unsigned long word)
 {
index f13e62e2cb3e75160297459ef182921b170d0850..2bc162e0ec6eb3bd02c685d80e99c24762a002b7 100644 (file)
        .endif
        .endm
 
-       .macro LOAD_ARGS offset
+       .macro LOAD_ARGS offset, skiprax=0
        movq \offset(%rsp),    %r11
        movq \offset+8(%rsp),  %r10
        movq \offset+16(%rsp), %r9
        movq \offset+48(%rsp), %rdx
        movq \offset+56(%rsp), %rsi
        movq \offset+64(%rsp), %rdi
+       .if \skiprax
+       .else
        movq \offset+72(%rsp), %rax
+       .endif
        .endm
 
 #define REST_SKIP      6*8
        .macro icebp
        .byte 0xf1
        .endm
-
index 75ef959db32921922db8f38bac44f8ac960cbc4a..2f5a792b0accafba2c93abc31e28157124a4a322 100644 (file)
@@ -79,6 +79,7 @@
 #define X86_FEATURE_REP_GOOD   (3*32+16) /* rep microcode works well on this CPU */
 #define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */
 #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */
+#define X86_FEATURE_11AP       (3*32+19)  /* Bad local APIC aka 11AP */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */
index a1a4dc7fe6ece75087cc33e33d3c60e2477cd586..c2ddd3d1b8831a98fe139639e131f458bfc41d99 100644 (file)
@@ -14,7 +14,6 @@ extern dma_addr_t bad_dma_address;
 extern int iommu_merge;
 extern struct device fallback_dev;
 extern int panic_on_overflow;
-extern int forbid_dac;
 extern int force_iommu;
 
 struct dma_mapping_ops {
index 06633b01dd5b73685d3bcb0698ffe8442fc5f88b..16a31e2c7c5747888b0c75178bb0683859dbbac1 100644 (file)
@@ -90,6 +90,14 @@ static inline void e820_mark_nosave_regions(unsigned long limit_pfn)
 }
 #endif
 
+#ifdef CONFIG_MEMTEST
+extern void early_memtest(unsigned long start, unsigned long end);
+#else
+static inline void early_memtest(unsigned long start, unsigned long end)
+{
+}
+#endif
+
 extern unsigned long end_user_pfn;
 
 extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align);
index aae2f0501a4006a145ca82e9d65f7999c89aaf5f..f1ac2b2167d7fdf0ba27c450d2c688f05c3b9e02 100644 (file)
@@ -90,13 +90,13 @@ enum fixed_addresses {
         * 256 temporary boot-time mappings, used by early_ioremap(),
         * before ioremap() is functional.
         *
-        * We round it up to the next 512 pages boundary so that we
+        * We round it up to the next 256 pages boundary so that we
         * can have a single pgd entry and a single pte table:
         */
 #define NR_FIX_BTMAPS          64
 #define FIX_BTMAPS_NESTING     4
-       FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 512 -
-                       (__end_of_permanent_fixed_addresses & 511),
+       FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -
+                       (__end_of_permanent_fixed_addresses & 255),
        FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1,
        FIX_WP_TEST,
 #ifdef CONFIG_ACPI
index c184441133f2bbd90075ce3b97562efc0504db4f..5c68b32ee1c81c28a51392303f767f05cf9ae5f3 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef _ASM_X86_FTRACE
-#define _ASM_SPARC64_FTRACE
+#define _ASM_X86_FTRACE
 
 #ifdef CONFIG_FTRACE
 #define MCOUNT_ADDR            ((long)(mcount))
index 33b9aeeb35a2367ba5deb1092622c579c6431c5a..3f62a83887f32c21c0919dd5c255847a8e6c2740 100644 (file)
@@ -2,7 +2,6 @@
 #define _ASM_X8664_GART_H 1
 
 #include <asm/e820.h>
-#include <asm/iommu.h>
 
 extern void set_up_gart_resume(u32, u32);
 
index 068c9a40aa5b10c81f5123bf80c3b212cda32840..d63166fb3ab705a3e294b0b5f4c75bd544d17411 100644 (file)
@@ -25,10 +25,18 @@ extern void gart_iommu_hole_init(void);
 static inline void early_gart_iommu_check(void)
 {
 }
-
+static inline void gart_iommu_init(void)
+{
+}
 static inline void gart_iommu_shutdown(void)
 {
 }
+static inline void gart_parse_options(char *options)
+{
+}
+static inline void gart_iommu_hole_init(void)
+{
+}
 #endif
 
 #endif
index f995783b1fdbfbada4312f2446245ca63e8809b6..fdde0bedaa90dd310e60862a52ef8a73f09a2f47 100644 (file)
@@ -703,9 +703,11 @@ enum {
                                                vcpu, 0, 0, 0, 0, 0, 0)
 
 #ifdef CONFIG_64BIT
-#define KVM_EX_ENTRY ".quad"
+# define KVM_EX_ENTRY ".quad"
+# define KVM_EX_PUSH "pushq"
 #else
-#define KVM_EX_ENTRY ".long"
+# define KVM_EX_ENTRY ".long"
+# define KVM_EX_PUSH "pushl"
 #endif
 
 /*
@@ -719,7 +721,7 @@ asmlinkage void kvm_handle_fault_on_reboot(void);
        "666: " insn "\n\t" \
        ".pushsection .text.fixup, \"ax\" \n" \
        "667: \n\t" \
-       "push $666b \n\t" \
+       KVM_EX_PUSH " $666b \n\t" \
        "jmp kvm_handle_fault_on_reboot \n\t" \
        ".popsection \n\t" \
        ".pushsection __ex_table, \"a\" \n\t" \
index 017c8c19ad8f874e0cc461c388f58716545eda34..c3b9dc6970c95726a3adaafe5502334b9d64c68c 100644 (file)
@@ -63,9 +63,9 @@ static inline void init_apic_ldr(void)
        unsigned long val;
        int cpu = smp_processor_id();
 
-       apic_write_around(APIC_DFR, APIC_DFR_VALUE);
+       apic_write(APIC_DFR, APIC_DFR_VALUE);
        val = calculate_ldr(cpu);
-       apic_write_around(APIC_LDR, val);
+       apic_write(APIC_LDR, val);
 }
 
 static inline void setup_apic_routing(void)
index 0b2cde5e1b74b38641c4cea560784be0d7716a9b..f3226b9a6b823459935a4de2c5b8e82165776e57 100644 (file)
@@ -46,10 +46,10 @@ static inline void init_apic_ldr(void)
 {
        unsigned long val;
 
-       apic_write_around(APIC_DFR, APIC_DFR_VALUE);
+       apic_write(APIC_DFR, APIC_DFR_VALUE);
        val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
        val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id());
-       apic_write_around(APIC_LDR, val);
+       apic_write(APIC_LDR, val);
 }
 
 static inline int apic_id_registered(void)
index 56d001b9dce4f0177b409c72982e902d4d8ef6e9..dbab36d64d48f2b15aa6be7dea09e9feb91f869f 100644 (file)
@@ -12,11 +12,11 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
 {
        CMOS_WRITE(0xa, 0xf);
        local_flush_tlb();
-       Dprintk("1.\n");
+       pr_debug("1.\n");
        *((volatile unsigned short *) TRAMPOLINE_HIGH) = start_eip >> 4;
-       Dprintk("2.\n");
+       pr_debug("2.\n");
        *((volatile unsigned short *) TRAMPOLINE_LOW) = start_eip & 0xf;
-       Dprintk("3.\n");
+       pr_debug("3.\n");
 }
 
 static inline void smpboot_restore_warm_reset_vector(void)
index fbc8ad256f5aadda25deaeb7d7564515ec1e12ca..0a3fdf93067253e448ffa6a39ca8bcc0d1c0ed90 100644 (file)
@@ -66,9 +66,9 @@ static inline void init_apic_ldr(void)
        unsigned long val;
        int cpu = smp_processor_id();
 
-       apic_write_around(APIC_DFR, APIC_DFR_VALUE);
+       apic_write(APIC_DFR, APIC_DFR_VALUE);
        val = calculate_ldr(cpu);
-       apic_write_around(APIC_LDR, val);
+       apic_write(APIC_LDR, val);
 }
 
 #ifndef CONFIG_X86_GENERICARCH
index 9ef0b941bb22ba96559d2653a71ac30ac4e19f72..c83c120be538504f5139228bc53182e3040f43ea 100644 (file)
@@ -7,4 +7,6 @@
 /* Maximum 256 PCI busses, plus 1 ISA bus in each of 4 cabinets. */
 #define MAX_MP_BUSSES 260
 
+extern void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem,
+                               char *productid);
 #endif /* __ASM_MACH_MPSPEC_H */
index 1f76c2e7023226656aeb48539c4985a25af339c9..75d2c95005d74b8eab2c2fce764dfc925f5aa876 100644 (file)
@@ -63,10 +63,10 @@ static inline void init_apic_ldr(void)
         * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
        BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
        id = my_cluster | (1UL << count);
-       apic_write_around(APIC_DFR, APIC_DFR_VALUE);
+       apic_write(APIC_DFR, APIC_DFR_VALUE);
        val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
        val |= SET_APIC_LOGICAL_ID(id);
-       apic_write_around(APIC_LDR, val);
+       apic_write(APIC_LDR, val);
 }
 
 static inline int multi_timer_check(int apic, int irq)
diff --git a/include/asm-x86/mach-visws/entry_arch.h b/include/asm-x86/mach-visws/entry_arch.h
deleted file mode 100644 (file)
index 86be554..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * VISWS uses the standard Linux entry points:
- */
-
-#include "../mach-default/entry_arch.h"
diff --git a/include/asm-x86/mach-visws/mach_apic.h b/include/asm-x86/mach-visws/mach_apic.h
deleted file mode 100644 (file)
index 6943e7a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../mach-default/mach_apic.h"
diff --git a/include/asm-x86/mach-visws/mach_apicdef.h b/include/asm-x86/mach-visws/mach_apicdef.h
deleted file mode 100644 (file)
index 42711d1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../mach-default/mach_apicdef.h"
diff --git a/include/asm-x86/mach-visws/setup_arch.h b/include/asm-x86/mach-visws/setup_arch.h
deleted file mode 100644 (file)
index fa4766c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../mach-default/setup_arch.h"
diff --git a/include/asm-x86/mach-visws/smpboot_hooks.h b/include/asm-x86/mach-visws/smpboot_hooks.h
deleted file mode 100644 (file)
index e4433ca..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../mach-default/smpboot_hooks.h"
index 28d7b4533b1a63fc1c54dc9f69a0db326e3a16f7..6c846228948d54f739ca59385ea647b521e39f32 100644 (file)
    (ie, 32-bit PAE). */
 #define PHYSICAL_PAGE_MASK     (((signed long)PAGE_MASK) & __PHYSICAL_MASK)
 
-/* PTE_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */
-#define PTE_MASK               ((pteval_t)PHYSICAL_PAGE_MASK)
+/* PTE_PFN_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */
+#define PTE_PFN_MASK           ((pteval_t)PHYSICAL_PAGE_MASK)
+
+/* PTE_FLAGS_MASK extracts the flags from a (pte|pmd|pud|pgd)val_t */
+#define PTE_FLAGS_MASK         (~PTE_PFN_MASK)
 
 #define PMD_PAGE_SIZE          (_AC(1, UL) << PMD_SHIFT)
 #define PMD_PAGE_MASK          (~(PMD_PAGE_SIZE-1))
@@ -144,6 +147,11 @@ static inline pteval_t native_pte_val(pte_t pte)
        return pte.pte;
 }
 
+static inline pteval_t native_pte_flags(pte_t pte)
+{
+       return native_pte_val(pte) & PTE_FLAGS_MASK;
+}
+
 #define pgprot_val(x)  ((x).pgprot)
 #define __pgprot(x)    ((pgprot_t) { (x) } )
 
@@ -165,7 +173,7 @@ static inline pteval_t native_pte_val(pte_t pte)
 #endif
 
 #define pte_val(x)     native_pte_val(x)
-#define pte_flags(x)   native_pte_val(x)
+#define pte_flags(x)   native_pte_flags(x)
 #define __pte(x)       native_make_pte(x)
 
 #endif /* CONFIG_PARAVIRT */
index ef5e8ec6a6ab7431f0c799a2b56a4cd5f18fe5e9..fbbde93f12d6d5ad0aaca4fb1e6db0860cb5a351 100644 (file)
@@ -205,7 +205,6 @@ struct pv_apic_ops {
         * these shouldn't be in this interface.
         */
        void (*apic_write)(unsigned long reg, u32 v);
-       void (*apic_write_atomic)(unsigned long reg, u32 v);
        u32 (*apic_read)(unsigned long reg);
        void (*setup_boot_clock)(void);
        void (*setup_secondary_clock)(void);
@@ -326,6 +325,15 @@ struct pv_mmu_ops {
                           unsigned long phys, pgprot_t flags);
 };
 
+struct raw_spinlock;
+struct pv_lock_ops {
+       int (*spin_is_locked)(struct raw_spinlock *lock);
+       int (*spin_is_contended)(struct raw_spinlock *lock);
+       void (*spin_lock)(struct raw_spinlock *lock);
+       int (*spin_trylock)(struct raw_spinlock *lock);
+       void (*spin_unlock)(struct raw_spinlock *lock);
+};
+
 /* This contains all the paravirt structures: we get a convenient
  * number for each function using the offset which we use to indicate
  * what to patch. */
@@ -336,6 +344,7 @@ struct paravirt_patch_template {
        struct pv_irq_ops pv_irq_ops;
        struct pv_apic_ops pv_apic_ops;
        struct pv_mmu_ops pv_mmu_ops;
+       struct pv_lock_ops pv_lock_ops;
 };
 
 extern struct pv_info pv_info;
@@ -345,6 +354,7 @@ extern struct pv_cpu_ops pv_cpu_ops;
 extern struct pv_irq_ops pv_irq_ops;
 extern struct pv_apic_ops pv_apic_ops;
 extern struct pv_mmu_ops pv_mmu_ops;
+extern struct pv_lock_ops pv_lock_ops;
 
 #define PARAVIRT_PATCH(x)                                      \
        (offsetof(struct paravirt_patch_template, x) / sizeof(void *))
@@ -896,11 +906,6 @@ static inline void apic_write(unsigned long reg, u32 v)
        PVOP_VCALL2(pv_apic_ops.apic_write, reg, v);
 }
 
-static inline void apic_write_atomic(unsigned long reg, u32 v)
-{
-       PVOP_VCALL2(pv_apic_ops.apic_write_atomic, reg, v);
-}
-
 static inline u32 apic_read(unsigned long reg)
 {
        return PVOP_CALL1(unsigned long, pv_apic_ops.apic_read, reg);
@@ -1083,6 +1088,9 @@ static inline pteval_t pte_flags(pte_t pte)
                ret = PVOP_CALL1(pteval_t, pv_mmu_ops.pte_flags,
                                 pte.pte);
 
+#ifdef CONFIG_PARAVIRT_DEBUG
+       BUG_ON(ret & PTE_PFN_MASK);
+#endif
        return ret;
 }
 
@@ -1374,6 +1382,37 @@ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
 void _paravirt_nop(void);
 #define paravirt_nop   ((void *)_paravirt_nop)
 
+void paravirt_use_bytelocks(void);
+
+#ifdef CONFIG_SMP
+
+static inline int __raw_spin_is_locked(struct raw_spinlock *lock)
+{
+       return PVOP_CALL1(int, pv_lock_ops.spin_is_locked, lock);
+}
+
+static inline int __raw_spin_is_contended(struct raw_spinlock *lock)
+{
+       return PVOP_CALL1(int, pv_lock_ops.spin_is_contended, lock);
+}
+
+static __always_inline void __raw_spin_lock(struct raw_spinlock *lock)
+{
+       PVOP_VCALL1(pv_lock_ops.spin_lock, lock);
+}
+
+static __always_inline int __raw_spin_trylock(struct raw_spinlock *lock)
+{
+       return PVOP_CALL1(int, pv_lock_ops.spin_trylock, lock);
+}
+
+static __always_inline void __raw_spin_unlock(struct raw_spinlock *lock)
+{
+       PVOP_VCALL1(pv_lock_ops.spin_unlock, lock);
+}
+
+#endif
+
 /* These all sit in the .parainstructions section to tell us what to patch. */
 struct paravirt_patch_site {
        u8 *instr;              /* original instructions */
@@ -1396,8 +1435,8 @@ extern struct paravirt_patch_site __parainstructions[],
  * caller saved registers but the argument parameter */
 #define PV_SAVE_REGS "pushq %%rdi;"
 #define PV_RESTORE_REGS "popq %%rdi;"
-#define PV_EXTRA_CLOBBERS EXTRA_CLOBBERS, "rcx" , "rdx"
-#define PV_VEXTRA_CLOBBERS EXTRA_CLOBBERS, "rdi", "rcx" , "rdx"
+#define PV_EXTRA_CLOBBERS EXTRA_CLOBBERS, "rcx" , "rdx", "rsi"
+#define PV_VEXTRA_CLOBBERS EXTRA_CLOBBERS, "rdi", "rcx" , "rdx", "rsi"
 #define PV_FLAGS_ARG "D"
 #endif
 
@@ -1458,6 +1497,7 @@ static inline unsigned long __raw_local_irq_save(void)
        return f;
 }
 
+
 /* Make sure as little as possible of this mess escapes. */
 #undef PARAVIRT_CALL
 #undef __PVOP_CALL
@@ -1489,8 +1529,26 @@ static inline unsigned long __raw_local_irq_save(void)
 
 
 #ifdef CONFIG_X86_64
-#define PV_SAVE_REGS   pushq %rax; pushq %rdi; pushq %rcx; pushq %rdx
-#define PV_RESTORE_REGS popq %rdx; popq %rcx; popq %rdi; popq %rax
+#define PV_SAVE_REGS                           \
+       push %rax;                              \
+       push %rcx;                              \
+       push %rdx;                              \
+       push %rsi;                              \
+       push %rdi;                              \
+       push %r8;                               \
+       push %r9;                               \
+       push %r10;                              \
+       push %r11
+#define PV_RESTORE_REGS                                \
+       pop %r11;                               \
+       pop %r10;                               \
+       pop %r9;                                \
+       pop %r8;                                \
+       pop %rdi;                               \
+       pop %rsi;                               \
+       pop %rdx;                               \
+       pop %rcx;                               \
+       pop %rax
 #define PARA_PATCH(struct, off)        ((PARAVIRT_PATCH_##struct + (off)) / 8)
 #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .quad, 8)
 #define PARA_INDIRECT(addr)    *addr(%rip)
index 912a3a17b9db85958abee1464d58e64d798f5f31..4e91ee1e37aa170140e92814a08232fef4e6dfd4 100644 (file)
 
 DECLARE_PER_CPU(struct x8664_pda, pda);
 
+/*
+ * These are supposed to be implemented as a single instruction which
+ * operates on the per-cpu data base segment.  x86-64 doesn't have
+ * that yet, so this is a fairly inefficient workaround for the
+ * meantime.  The single instruction is atomic with respect to
+ * preemption and interrupts, so we need to explicitly disable
+ * interrupts here to achieve the same effect.  However, because it
+ * can be used from within interrupt-disable/enable, we can't actually
+ * disable interrupts; disabling preemption is enough.
+ */
+#define x86_read_percpu(var)                                           \
+       ({                                                              \
+               typeof(per_cpu_var(var)) __tmp;                         \
+               preempt_disable();                                      \
+               __tmp = __get_cpu_var(var);                             \
+               preempt_enable();                                       \
+               __tmp;                                                  \
+       })
+
+#define x86_write_percpu(var, val)                                     \
+       do {                                                            \
+               preempt_disable();                                      \
+               __get_cpu_var(var) = (val);                             \
+               preempt_enable();                                       \
+       } while(0)
+
 #else /* CONFIG_X86_64 */
 
 #ifdef __ASSEMBLY__
index c93dbb6c26247dfa76d92b5a5dd8e73c7c41dd3c..105057f34032f0a23610ea5822e32cf12d51b4f7 100644 (file)
@@ -25,7 +25,7 @@ static inline int pud_none(pud_t pud)
 
 static inline int pud_bad(pud_t pud)
 {
-       return (pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER)) != 0;
+       return (pud_val(pud) & ~(PTE_PFN_MASK | _KERNPG_TABLE | _PAGE_USER)) != 0;
 }
 
 static inline int pud_present(pud_t pud)
@@ -120,9 +120,9 @@ static inline void pud_clear(pud_t *pudp)
                write_cr3(pgd);
 }
 
-#define pud_page(pud) ((struct page *) __va(pud_val(pud) & PTE_MASK))
+#define pud_page(pud) ((struct page *) __va(pud_val(pud) & PTE_PFN_MASK))
 
-#define pud_page_vaddr(pud) ((unsigned long) __va(pud_val(pud) & PTE_MASK))
+#define pud_page_vaddr(pud) ((unsigned long) __va(pud_val(pud) & PTE_PFN_MASK))
 
 
 /* Find an entry in the second-level page table.. */
@@ -160,7 +160,7 @@ static inline int pte_none(pte_t pte)
 
 static inline unsigned long pte_pfn(pte_t pte)
 {
-       return (pte_val(pte) & PTE_MASK) >> PAGE_SHIFT;
+       return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT;
 }
 
 /*
index 49cbd76b9547ed3d0bf3075f4f6980a0143858c7..3e5dbc4195f4f71fc61ee906fbcc8f8dec0beb79 100644 (file)
@@ -53,7 +53,7 @@
                         _PAGE_DIRTY)
 
 /* Set of bits not changed in pte_modify */
-#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_PCD | _PAGE_PWT |             \
+#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT |         \
                         _PAGE_ACCESSED | _PAGE_DIRTY)
 
 #define _PAGE_CACHE_MASK       (_PAGE_PCD | _PAGE_PWT)
@@ -286,7 +286,7 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
        return __pgprot(preservebits | addbits);
 }
 
-#define pte_pgprot(x) __pgprot(pte_flags(x) & ~PTE_MASK)
+#define pte_pgprot(x) __pgprot(pte_flags(x) & PTE_FLAGS_MASK)
 
 #define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask)
 
@@ -302,6 +302,14 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
 /* Install a pte for a particular vaddr in kernel space. */
 void set_pte_vaddr(unsigned long vaddr, pte_t pte);
 
+#ifdef CONFIG_X86_32
+extern void native_pagetable_setup_start(pgd_t *base);
+extern void native_pagetable_setup_done(pgd_t *base);
+#else
+static inline void native_pagetable_setup_start(pgd_t *base) {}
+static inline void native_pagetable_setup_done(pgd_t *base) {}
+#endif
+
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
 #else  /* !CONFIG_PARAVIRT */
@@ -333,6 +341,16 @@ void set_pte_vaddr(unsigned long vaddr, pte_t pte);
 
 #define pte_update(mm, addr, ptep)              do { } while (0)
 #define pte_update_defer(mm, addr, ptep)        do { } while (0)
+
+static inline void __init paravirt_pagetable_setup_start(pgd_t *base)
+{
+       native_pagetable_setup_start(base);
+}
+
+static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
+{
+       native_pagetable_setup_done(base);
+}
 #endif /* CONFIG_PARAVIRT */
 
 #endif /* __ASSEMBLY__ */
index ec871c420d7e5c511a41c098c3ffb9895de25a20..5c3b26567a95e46144cb3e2ca68601e572111e87 100644 (file)
@@ -88,7 +88,7 @@ extern unsigned long pg0[];
 /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */
 #define pmd_none(x)    (!(unsigned long)pmd_val((x)))
 #define pmd_present(x) (pmd_val((x)) & _PAGE_PRESENT)
-#define pmd_bad(x) ((pmd_val(x) & (~PTE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
+#define pmd_bad(x) ((pmd_val(x) & (PTE_FLAGS_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
 
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 
@@ -139,7 +139,7 @@ static inline int pud_large(pud_t pud) { return 0; }
 #define pmd_page(pmd) (pfn_to_page(pmd_val((pmd)) >> PAGE_SHIFT))
 
 #define pmd_page_vaddr(pmd)                                    \
-       ((unsigned long)__va(pmd_val((pmd)) & PTE_MASK))
+       ((unsigned long)__va(pmd_val((pmd)) & PTE_PFN_MASK))
 
 #if defined(CONFIG_HIGHPTE)
 #define pte_offset_map(dir, address)                                   \
@@ -171,21 +171,6 @@ do {                                               \
  */
 #define update_mmu_cache(vma, address, pte) do { } while (0)
 
-extern void native_pagetable_setup_start(pgd_t *base);
-extern void native_pagetable_setup_done(pgd_t *base);
-
-#ifndef CONFIG_PARAVIRT
-static inline void __init paravirt_pagetable_setup_start(pgd_t *base)
-{
-       native_pagetable_setup_start(base);
-}
-
-static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
-{
-       native_pagetable_setup_done(base);
-}
-#endif /* !CONFIG_PARAVIRT */
-
 #endif /* !__ASSEMBLY__ */
 
 /*
index fa7208b483cada7c9d735f8381c503b289a02d86..ac5fff4cc58aaf364eb41d5027f8e851aceef915 100644 (file)
@@ -16,6 +16,8 @@
 extern pud_t level3_kernel_pgt[512];
 extern pud_t level3_ident_pgt[512];
 extern pmd_t level2_kernel_pgt[512];
+extern pmd_t level2_fixmap_pgt[512];
+extern pmd_t level2_ident_pgt[512];
 extern pgd_t init_level4_pgt[];
 
 #define swapper_pg_dir init_level4_pgt
@@ -156,17 +158,17 @@ static inline void native_pgd_clear(pgd_t *pgd)
 
 static inline int pgd_bad(pgd_t pgd)
 {
-       return (pgd_val(pgd) & ~(PTE_MASK | _PAGE_USER)) != _KERNPG_TABLE;
+       return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
 }
 
 static inline int pud_bad(pud_t pud)
 {
-       return (pud_val(pud) & ~(PTE_MASK | _PAGE_USER)) != _KERNPG_TABLE;
+       return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
 }
 
 static inline int pmd_bad(pmd_t pmd)
 {
-       return (pmd_val(pmd) & ~(PTE_MASK | _PAGE_USER)) != _KERNPG_TABLE;
+       return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
 }
 
 #define pte_none(x)    (!pte_val((x)))
@@ -191,7 +193,7 @@ static inline int pmd_bad(pmd_t pmd)
  * Level 4 access.
  */
 #define pgd_page_vaddr(pgd)                                            \
-       ((unsigned long)__va((unsigned long)pgd_val((pgd)) & PTE_MASK))
+       ((unsigned long)__va((unsigned long)pgd_val((pgd)) & PTE_PFN_MASK))
 #define pgd_page(pgd)          (pfn_to_page(pgd_val((pgd)) >> PAGE_SHIFT))
 #define pgd_present(pgd) (pgd_val(pgd) & _PAGE_PRESENT)
 static inline int pgd_large(pgd_t pgd) { return 0; }
@@ -214,7 +216,7 @@ static inline int pud_large(pud_t pte)
 }
 
 /* PMD  - Level 2 access */
-#define pmd_page_vaddr(pmd) ((unsigned long) __va(pmd_val((pmd)) & PTE_MASK))
+#define pmd_page_vaddr(pmd) ((unsigned long) __va(pmd_val((pmd)) & PTE_PFN_MASK))
 #define pmd_page(pmd)          (pfn_to_page(pmd_val((pmd)) >> PAGE_SHIFT))
 
 #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
index f92315ed68e1e61ed35b05349fb005c12d21e5f7..5f58da401b43696ee861377fb9aba53500af8b8e 100644 (file)
@@ -722,8 +722,6 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
 
 extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
 
-extern int                     force_mwait;
-
 extern void select_idle_routine(const struct cpuinfo_x86 *c);
 
 extern unsigned long           boot_option_idle_override;
index f224eb3c3157591ac69a53466609ea0841beefbc..72e7b9db29bba0e2cb736d86281ab4f7c24cdd1d 100644 (file)
 
 #ifdef __x86_64__
 # define PTRACE_ARCH_PRCTL       30
-#else
-# define PTRACE_SYSEMU           31
-# define PTRACE_SYSEMU_SINGLESTEP 32
 #endif
 
+#define PTRACE_SYSEMU            31
+#define PTRACE_SYSEMU_SINGLESTEP  32
+
 #define PTRACE_SINGLEBLOCK     33      /* resume execution until next branch */
 
 #ifndef __ASSEMBLY__
index dfc8601c08922f26e6b19a4a28d998a0b1a7c274..646452ea9ea3ede3d7847f5be78c8ca5a0feee48 100644 (file)
@@ -1,6 +1,15 @@
 #ifndef _ASM_X86_SEGMENT_H_
 #define _ASM_X86_SEGMENT_H_
 
+/* Constructor for a conventional segment GDT (or LDT) entry */
+/* This is a macro so it can be used in initializers */
+#define GDT_ENTRY(flags, base, limit)                  \
+       ((((base)  & 0xff000000ULL) << (56-24)) |       \
+        (((flags) & 0x0000f0ffULL) << 40) |            \
+        (((limit) & 0x000f0000ULL) << (48-16)) |       \
+        (((base)  & 0x00ffffffULL) << 16) |            \
+        (((limit) & 0x0000ffffULL)))
+
 /* Simple and small GDT entries for booting only */
 
 #define GDT_ENTRY_BOOT_CS      2
index 90ab2225e71bbefe9fb06c9d85127c555e8a8445..a07c6f1c01e15b9480f14fcca8dc13d875334fc9 100644 (file)
@@ -19,13 +19,28 @@ static inline int is_visws_box(void) { return 0; }
 /*
  * Any setup quirks to be performed?
  */
-extern int (*arch_time_init_quirk)(void);
-extern int (*arch_pre_intr_init_quirk)(void);
-extern int (*arch_intr_init_quirk)(void);
-extern int (*arch_trap_init_quirk)(void);
-extern char * (*arch_memory_setup_quirk)(void);
-extern int (*mach_get_smp_config_quirk)(unsigned int early);
-extern int (*mach_find_smp_config_quirk)(unsigned int reserve);
+struct mpc_config_processor;
+struct mpc_config_bus;
+struct mp_config_oemtable;
+struct x86_quirks {
+       int (*arch_pre_time_init)(void);
+       int (*arch_time_init)(void);
+       int (*arch_pre_intr_init)(void);
+       int (*arch_intr_init)(void);
+       int (*arch_trap_init)(void);
+       char * (*arch_memory_setup)(void);
+       int (*mach_get_smp_config)(unsigned int early);
+       int (*mach_find_smp_config)(unsigned int reserve);
+
+       int *mpc_record;
+       int (*mpc_apic_id)(struct mpc_config_processor *m);
+       void (*mpc_oem_bus_info)(struct mpc_config_bus *m, char *name);
+       void (*mpc_oem_pci_bus)(struct mpc_config_bus *m);
+       void (*smp_read_mpc_oem)(struct mp_config_oemtable *oemtable,
+                                    unsigned short oemsize);
+};
+
+extern struct x86_quirks *x86_quirks;
 
 #ifndef CONFIG_PARAVIRT
 #define paravirt_post_allocator_init() do {} while (0)
@@ -76,6 +91,7 @@ extern unsigned long init_pg_tables_start;
 extern unsigned long init_pg_tables_end;
 
 #else
+void __init x86_64_init_pda(void);
 void __init x86_64_start_kernel(char *real_mode);
 void __init x86_64_start_reservations(char *real_mode_data);
 
index f15186d39c69a0a249bcebf110ac02a9d7ab951c..6dac49364e9528c6e76d9478bf00ab9ed6b6d3bc 100644 (file)
@@ -181,12 +181,12 @@ typedef struct sigaltstack {
 #ifdef __KERNEL__
 #include <asm/sigcontext.h>
 
-#ifdef __386__
+#ifdef __i386__
 
 #define __HAVE_ARCH_SIG_BITOPS
 
 #define sigaddset(set,sig)                 \
-       (__builtin_constantp(sig)           \
+       (__builtin_constant_p(sig)          \
         ? __const_sigaddset((set), (sig))  \
         : __gen_sigaddset((set), (sig)))
 
index c2784b3e0b77e23269a1c61407aaeb2db39cdc9d..3c877f74f279454cd579cf71530ef3bd051b75ff 100644 (file)
@@ -25,6 +25,8 @@ extern cpumask_t cpu_callin_map;
 extern void (*mtrr_hook)(void);
 extern void zap_low_mappings(void);
 
+extern int __cpuinit get_local_pda(int cpu);
+
 extern int smp_num_siblings;
 extern unsigned int num_processors;
 extern cpumask_t cpu_initialized;
index 21e89bf92f1c8cd547b697fcc37021388d8115e2..4f9a9861799ac648d406856a8a5ed1881e678a25 100644 (file)
@@ -6,7 +6,7 @@
 #include <asm/page.h>
 #include <asm/processor.h>
 #include <linux/compiler.h>
-
+#include <asm/paravirt.h>
 /*
  * Your basic SMP spinlocks, allowing only a single CPU anywhere
  *
  * much between them in performance though, especially as locks are out of line.
  */
 #if (NR_CPUS < 256)
-static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
+static inline int __ticket_spin_is_locked(raw_spinlock_t *lock)
 {
        int tmp = ACCESS_ONCE(lock->slock);
 
        return (((tmp >> 8) & 0xff) != (tmp & 0xff));
 }
 
-static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
+static inline int __ticket_spin_is_contended(raw_spinlock_t *lock)
 {
        int tmp = ACCESS_ONCE(lock->slock);
 
        return (((tmp >> 8) & 0xff) - (tmp & 0xff)) > 1;
 }
 
-static __always_inline void __raw_spin_lock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
 {
        short inc = 0x0100;
 
@@ -87,9 +87,7 @@ static __always_inline void __raw_spin_lock(raw_spinlock_t *lock)
                : "memory", "cc");
 }
 
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-
-static __always_inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
 {
        int tmp;
        short new;
@@ -110,7 +108,7 @@ static __always_inline int __raw_spin_trylock(raw_spinlock_t *lock)
        return tmp;
 }
 
-static __always_inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock)
 {
        asm volatile(UNLOCK_LOCK_PREFIX "incb %0"
                     : "+m" (lock->slock)
@@ -118,21 +116,21 @@ static __always_inline void __raw_spin_unlock(raw_spinlock_t *lock)
                     : "memory", "cc");
 }
 #else
-static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
+static inline int __ticket_spin_is_locked(raw_spinlock_t *lock)
 {
        int tmp = ACCESS_ONCE(lock->slock);
 
        return (((tmp >> 16) & 0xffff) != (tmp & 0xffff));
 }
 
-static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
+static inline int __ticket_spin_is_contended(raw_spinlock_t *lock)
 {
        int tmp = ACCESS_ONCE(lock->slock);
 
        return (((tmp >> 16) & 0xffff) - (tmp & 0xffff)) > 1;
 }
 
-static __always_inline void __raw_spin_lock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
 {
        int inc = 0x00010000;
        int tmp;
@@ -153,9 +151,7 @@ static __always_inline void __raw_spin_lock(raw_spinlock_t *lock)
                     : "memory", "cc");
 }
 
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-
-static __always_inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
 {
        int tmp;
        int new;
@@ -177,7 +173,7 @@ static __always_inline int __raw_spin_trylock(raw_spinlock_t *lock)
        return tmp;
 }
 
-static __always_inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock)
 {
        asm volatile(UNLOCK_LOCK_PREFIX "incw %0"
                     : "+m" (lock->slock)
@@ -186,6 +182,98 @@ static __always_inline void __raw_spin_unlock(raw_spinlock_t *lock)
 }
 #endif
 
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+
+#ifdef CONFIG_PARAVIRT
+/*
+ * Define virtualization-friendly old-style lock byte lock, for use in
+ * pv_lock_ops if desired.
+ *
+ * This differs from the pre-2.6.24 spinlock by always using xchgb
+ * rather than decb to take the lock; this allows it to use a
+ * zero-initialized lock structure.  It also maintains a 1-byte
+ * contention counter, so that we can implement
+ * __byte_spin_is_contended.
+ */
+struct __byte_spinlock {
+       s8 lock;
+       s8 spinners;
+};
+
+static inline int __byte_spin_is_locked(raw_spinlock_t *lock)
+{
+       struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
+       return bl->lock != 0;
+}
+
+static inline int __byte_spin_is_contended(raw_spinlock_t *lock)
+{
+       struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
+       return bl->spinners != 0;
+}
+
+static inline void __byte_spin_lock(raw_spinlock_t *lock)
+{
+       struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
+       s8 val = 1;
+
+       asm("1: xchgb %1, %0\n"
+           "   test %1,%1\n"
+           "   jz 3f\n"
+           "   " LOCK_PREFIX "incb %2\n"
+           "2: rep;nop\n"
+           "   cmpb $1, %0\n"
+           "   je 2b\n"
+           "   " LOCK_PREFIX "decb %2\n"
+           "   jmp 1b\n"
+           "3:"
+           : "+m" (bl->lock), "+q" (val), "+m" (bl->spinners): : "memory");
+}
+
+static inline int __byte_spin_trylock(raw_spinlock_t *lock)
+{
+       struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
+       u8 old = 1;
+
+       asm("xchgb %1,%0"
+           : "+m" (bl->lock), "+q" (old) : : "memory");
+
+       return old == 0;
+}
+
+static inline void __byte_spin_unlock(raw_spinlock_t *lock)
+{
+       struct __byte_spinlock *bl = (struct __byte_spinlock *)lock;
+       smp_wmb();
+       bl->lock = 0;
+}
+#else  /* !CONFIG_PARAVIRT */
+static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
+{
+       return __ticket_spin_is_locked(lock);
+}
+
+static inline int __raw_spin_is_contended(raw_spinlock_t *lock)
+{
+       return __ticket_spin_is_contended(lock);
+}
+
+static __always_inline void __raw_spin_lock(raw_spinlock_t *lock)
+{
+       __ticket_spin_lock(lock);
+}
+
+static __always_inline int __raw_spin_trylock(raw_spinlock_t *lock)
+{
+       return __ticket_spin_trylock(lock);
+}
+
+static __always_inline void __raw_spin_unlock(raw_spinlock_t *lock)
+{
+       __ticket_spin_unlock(lock);
+}
+#endif /* CONFIG_PARAVIRT */
+
 static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock)
 {
        while (__raw_spin_is_locked(lock))
index 9029cf78cf5dce2ece4ede3251a300697d74f9b2..06c071c9eee9f1d2e5288930b91e511a3d094d61 100644 (file)
@@ -5,7 +5,7 @@
 # error "please don't include this file directly"
 #endif
 
-typedef struct {
+typedef struct raw_spinlock {
        unsigned int slock;
 } raw_spinlock_t;
 
index f5d9e74b1e4ab70a718886961113cafbdb2f4fcc..c706a7442633f1f3fdf051598f06326157d51b7a 100644 (file)
@@ -45,12 +45,14 @@ extern int swiotlb_force;
 
 #ifdef CONFIG_SWIOTLB
 extern int swiotlb;
+extern void pci_swiotlb_init(void);
 #else
 #define swiotlb 0
+static inline void pci_swiotlb_init(void)
+{
+}
 #endif
 
-extern void pci_swiotlb_init(void);
-
 static inline void dma_mark_clean(void *addr, size_t size) {}
 
 #endif /* _ASM_SWIOTLB_H */
index 895339d2bc0bae799af368ec10efff5050d5afc3..0a8f27d31d0db4eb25075a01525827e540488867 100644 (file)
@@ -75,9 +75,7 @@ struct thread_info {
 #define TIF_NEED_RESCHED       3       /* rescheduling necessary */
 #define TIF_SINGLESTEP         4       /* reenable singlestep on user return*/
 #define TIF_IRET               5       /* force IRET */
-#ifdef CONFIG_X86_32
 #define TIF_SYSCALL_EMU                6       /* syscall emulation active */
-#endif
 #define TIF_SYSCALL_AUDIT      7       /* syscall auditing active */
 #define TIF_SECCOMP            8       /* secure computing */
 #define TIF_MCE_NOTIFY         10      /* notify userspace of an MCE */
@@ -100,11 +98,7 @@ struct thread_info {
 #define _TIF_SINGLESTEP                (1 << TIF_SINGLESTEP)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
 #define _TIF_IRET              (1 << TIF_IRET)
-#ifdef CONFIG_X86_32
 #define _TIF_SYSCALL_EMU       (1 << TIF_SYSCALL_EMU)
-#else
-#define _TIF_SYSCALL_EMU       0
-#endif
 #define _TIF_SYSCALL_AUDIT     (1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP           (1 << TIF_SECCOMP)
 #define _TIF_MCE_NOTIFY                (1 << TIF_MCE_NOTIFY)
@@ -121,18 +115,27 @@ struct thread_info {
 #define _TIF_DS_AREA_MSR       (1 << TIF_DS_AREA_MSR)
 #define _TIF_BTS_TRACE_TS      (1 << TIF_BTS_TRACE_TS)
 
+/* work to do in syscall_trace_enter() */
+#define _TIF_WORK_SYSCALL_ENTRY        \
+       (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | \
+        _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | _TIF_SINGLESTEP)
+
+/* work to do in syscall_trace_leave() */
+#define _TIF_WORK_SYSCALL_EXIT \
+       (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP)
+
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK                                                 \
        (0x0000FFFF &                                                   \
-        ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP|       \
-        _TIF_SECCOMP|_TIF_SYSCALL_EMU))
+        ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|                       \
+          _TIF_SINGLESTEP|_TIF_SECCOMP|_TIF_SYSCALL_EMU))
 
 /* work to do on any return to user space */
 #define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP)
 
 /* Only used for 64 bit */
 #define _TIF_DO_NOTIFY_MASK                                            \
-       (_TIF_SIGPENDING|_TIF_SINGLESTEP|_TIF_MCE_NOTIFY|_TIF_HRTICK_RESCHED)
+       (_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_HRTICK_RESCHED)
 
 /* flags to check in __switch_to() */
 #define _TIF_WORK_CTXSW                                                        \
diff --git a/include/asm-x86/traps.h b/include/asm-x86/traps.h
new file mode 100644 (file)
index 0000000..a4b65a7
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef _ASM_X86_TRAPS_H
+#define _ASM_X86_TRAPS_H
+
+/* Common in X86_32 and X86_64 */
+asmlinkage void divide_error(void);
+asmlinkage void debug(void);
+asmlinkage void nmi(void);
+asmlinkage void int3(void);
+asmlinkage void overflow(void);
+asmlinkage void bounds(void);
+asmlinkage void invalid_op(void);
+asmlinkage void device_not_available(void);
+asmlinkage void coprocessor_segment_overrun(void);
+asmlinkage void invalid_TSS(void);
+asmlinkage void segment_not_present(void);
+asmlinkage void stack_segment(void);
+asmlinkage void general_protection(void);
+asmlinkage void page_fault(void);
+asmlinkage void coprocessor_error(void);
+asmlinkage void simd_coprocessor_error(void);
+asmlinkage void alignment_check(void);
+asmlinkage void spurious_interrupt_bug(void);
+#ifdef CONFIG_X86_MCE
+asmlinkage void machine_check(void);
+#endif /* CONFIG_X86_MCE */
+
+void do_divide_error(struct pt_regs *, long);
+void do_overflow(struct pt_regs *, long);
+void do_bounds(struct pt_regs *, long);
+void do_coprocessor_segment_overrun(struct pt_regs *, long);
+void do_invalid_TSS(struct pt_regs *, long);
+void do_segment_not_present(struct pt_regs *, long);
+void do_stack_segment(struct pt_regs *, long);
+void do_alignment_check(struct pt_regs *, long);
+void do_invalid_op(struct pt_regs *, long);
+void do_general_protection(struct pt_regs *, long);
+void do_nmi(struct pt_regs *, long);
+
+extern int panic_on_unrecovered_nmi;
+extern int kstack_depth_to_print;
+
+#ifdef CONFIG_X86_32
+
+void do_iret_error(struct pt_regs *, long);
+void do_int3(struct pt_regs *, long);
+void do_debug(struct pt_regs *, long);
+void math_error(void __user *);
+void do_coprocessor_error(struct pt_regs *, long);
+void do_simd_coprocessor_error(struct pt_regs *, long);
+void do_spurious_interrupt_bug(struct pt_regs *, long);
+unsigned long patch_espfix_desc(unsigned long, unsigned long);
+asmlinkage void math_emulate(long);
+
+#else /* CONFIG_X86_32 */
+
+asmlinkage void double_fault(void);
+
+asmlinkage void do_int3(struct pt_regs *, long);
+asmlinkage void do_stack_segment(struct pt_regs *, long);
+asmlinkage void do_debug(struct pt_regs *, unsigned long);
+asmlinkage void do_coprocessor_error(struct pt_regs *);
+asmlinkage void do_simd_coprocessor_error(struct pt_regs *);
+asmlinkage void do_spurious_interrupt_bug(struct pt_regs *);
+
+#endif /* CONFIG_X86_32 */
+#endif /* _ASM_X86_TRAPS_H */
diff --git a/include/asm-x86/uv/bios.h b/include/asm-x86/uv/bios.h
new file mode 100644 (file)
index 0000000..aa73362
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef _ASM_X86_BIOS_H
+#define _ASM_X86_BIOS_H
+
+/*
+ * BIOS layer definitions.
+ *
+ *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/rtc.h>
+
+#define BIOS_FREQ_BASE                 0x01000001
+
+enum {
+       BIOS_FREQ_BASE_PLATFORM = 0,
+       BIOS_FREQ_BASE_INTERVAL_TIMER = 1,
+       BIOS_FREQ_BASE_REALTIME_CLOCK = 2
+};
+
+# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7)             \
+       do {                                                            \
+               /* XXX - the real call goes here */                     \
+               result.status = BIOS_STATUS_UNIMPLEMENTED;              \
+               isrv.v0 = 0;                                            \
+               isrv.v1 = 0;                                            \
+       } while (0)
+
+enum {
+       BIOS_STATUS_SUCCESS             =  0,
+       BIOS_STATUS_UNIMPLEMENTED       = -1,
+       BIOS_STATUS_EINVAL              = -2,
+       BIOS_STATUS_ERROR               = -3
+};
+
+struct uv_bios_retval {
+       /*
+        * A zero status value indicates call completed without error.
+        * A negative status value indicates reason of call failure.
+        * A positive status value indicates success but an
+        * informational value should be printed (e.g., "reboot for
+        * change to take effect").
+        */
+       s64 status;
+       u64 v0;
+       u64 v1;
+       u64 v2;
+};
+
+extern long
+x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
+                  unsigned long *drift_info);
+extern const char *x86_bios_strerror(long status);
+
+#endif /* _ASM_X86_BIOS_H */
index 86e085e003d2b6b4ea46c7591d7db8ae0e9c244b..8e18fb80f5e641ac3683b8c84c68cb511c4ab30f 100644 (file)
@@ -36,4 +36,12 @@ extern const char VDSO32_PRELINK[];
 extern void __user __kernel_sigreturn;
 extern void __user __kernel_rt_sigreturn;
 
+/*
+ * These symbols are defined by vdso32.S to mark the bounds
+ * of the ELF DSO images included therein.
+ */
+extern const char vdso32_int80_start, vdso32_int80_end;
+extern const char vdso32_syscall_start, vdso32_syscall_end;
+extern const char vdso32_sysenter_start, vdso32_sysenter_end;
+
 #endif /* asm-x86/vdso.h */
index f8d57ea1f05f5a3c0caeb246e1879daeafc0bbd3..8ded7472002419e1067a663799dff272623190d0 100644 (file)
@@ -5,6 +5,7 @@ enum ipi_vector {
        XEN_RESCHEDULE_VECTOR,
        XEN_CALL_FUNCTION_VECTOR,
        XEN_CALL_FUNCTION_SINGLE_VECTOR,
+       XEN_SPIN_UNLOCK_VECTOR,
 
        XEN_NR_IPIS,
 };
index 2a4f9b41d68499d39004fb238a49a528b1a282be..91cb7fd5c1234be0f549b44f8a93208c7fedd92d 100644 (file)
 #include <xen/interface/sched.h>
 #include <xen/interface/physdev.h>
 
+/*
+ * The hypercall asms have to meet several constraints:
+ * - Work on 32- and 64-bit.
+ *    The two architectures put their arguments in different sets of
+ *    registers.
+ *
+ * - Work around asm syntax quirks
+ *    It isn't possible to specify one of the rNN registers in a
+ *    constraint, so we use explicit register variables to get the
+ *    args into the right place.
+ *
+ * - Mark all registers as potentially clobbered
+ *    Even unused parameters can be clobbered by the hypervisor, so we
+ *    need to make sure gcc knows it.
+ *
+ * - Avoid compiler bugs.
+ *    This is the tricky part.  Because x86_32 has such a constrained
+ *    register set, gcc versions below 4.3 have trouble generating
+ *    code when all the arg registers and memory are trashed by the
+ *    asm.  There are syntactically simpler ways of achieving the
+ *    semantics below, but they cause the compiler to crash.
+ *
+ *    The only combination I found which works is:
+ *     - assign the __argX variables first
+ *     - list all actually used parameters as "+r" (__argX)
+ *     - clobber the rest
+ *
+ * The result certainly isn't pretty, and it really shows up cpp's
+ * weakness as as macro language.  Sorry.  (But let's just give thanks
+ * there aren't more than 5 arguments...)
+ */
+
 extern struct { char _entry[32]; } hypercall_page[];
 
+#define __HYPERCALL            "call hypercall_page+%c[offset]"
+#define __HYPERCALL_ENTRY(x)                                           \
+       [offset] "i" (__HYPERVISOR_##x * sizeof(hypercall_page[0]))
+
+#ifdef CONFIG_X86_32
+#define __HYPERCALL_RETREG     "eax"
+#define __HYPERCALL_ARG1REG    "ebx"
+#define __HYPERCALL_ARG2REG    "ecx"
+#define __HYPERCALL_ARG3REG    "edx"
+#define __HYPERCALL_ARG4REG    "esi"
+#define __HYPERCALL_ARG5REG    "edi"
+#else
+#define __HYPERCALL_RETREG     "rax"
+#define __HYPERCALL_ARG1REG    "rdi"
+#define __HYPERCALL_ARG2REG    "rsi"
+#define __HYPERCALL_ARG3REG    "rdx"
+#define __HYPERCALL_ARG4REG    "r10"
+#define __HYPERCALL_ARG5REG    "r8"
+#endif
+
+#define __HYPERCALL_DECLS                                              \
+       register unsigned long __res  asm(__HYPERCALL_RETREG);          \
+       register unsigned long __arg1 asm(__HYPERCALL_ARG1REG) = __arg1; \
+       register unsigned long __arg2 asm(__HYPERCALL_ARG2REG) = __arg2; \
+       register unsigned long __arg3 asm(__HYPERCALL_ARG3REG) = __arg3; \
+       register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \
+       register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5;
+
+#define __HYPERCALL_0PARAM     "=r" (__res)
+#define __HYPERCALL_1PARAM     __HYPERCALL_0PARAM, "+r" (__arg1)
+#define __HYPERCALL_2PARAM     __HYPERCALL_1PARAM, "+r" (__arg2)
+#define __HYPERCALL_3PARAM     __HYPERCALL_2PARAM, "+r" (__arg3)
+#define __HYPERCALL_4PARAM     __HYPERCALL_3PARAM, "+r" (__arg4)
+#define __HYPERCALL_5PARAM     __HYPERCALL_4PARAM, "+r" (__arg5)
+
+#define __HYPERCALL_0ARG()
+#define __HYPERCALL_1ARG(a1)                                           \
+       __HYPERCALL_0ARG()              __arg1 = (unsigned long)(a1);
+#define __HYPERCALL_2ARG(a1,a2)                                                \
+       __HYPERCALL_1ARG(a1)            __arg2 = (unsigned long)(a2);
+#define __HYPERCALL_3ARG(a1,a2,a3)                                     \
+       __HYPERCALL_2ARG(a1,a2)         __arg3 = (unsigned long)(a3);
+#define __HYPERCALL_4ARG(a1,a2,a3,a4)                                  \
+       __HYPERCALL_3ARG(a1,a2,a3)      __arg4 = (unsigned long)(a4);
+#define __HYPERCALL_5ARG(a1,a2,a3,a4,a5)                               \
+       __HYPERCALL_4ARG(a1,a2,a3,a4)   __arg5 = (unsigned long)(a5);
+
+#define __HYPERCALL_CLOBBER5   "memory"
+#define __HYPERCALL_CLOBBER4   __HYPERCALL_CLOBBER5, __HYPERCALL_ARG5REG
+#define __HYPERCALL_CLOBBER3   __HYPERCALL_CLOBBER4, __HYPERCALL_ARG4REG
+#define __HYPERCALL_CLOBBER2   __HYPERCALL_CLOBBER3, __HYPERCALL_ARG3REG
+#define __HYPERCALL_CLOBBER1   __HYPERCALL_CLOBBER2, __HYPERCALL_ARG2REG
+#define __HYPERCALL_CLOBBER0   __HYPERCALL_CLOBBER1, __HYPERCALL_ARG1REG
+
 #define _hypercall0(type, name)                                                \
 ({                                                                     \
-       long __res;                                                     \
-       asm volatile (                                                  \
-               "call %[call]"                                          \
-               : "=a" (__res)                                          \
-               : [call] "m" (hypercall_page[__HYPERVISOR_##name])      \
-               : "memory" );                                           \
+       __HYPERCALL_DECLS;                                              \
+       __HYPERCALL_0ARG();                                             \
+       asm volatile (__HYPERCALL                                       \
+                     : __HYPERCALL_0PARAM                              \
+                     : __HYPERCALL_ENTRY(name)                         \
+                     : __HYPERCALL_CLOBBER0);                          \
        (type)__res;                                                    \
 })
 
 #define _hypercall1(type, name, a1)                                    \
 ({                                                                     \
-       long __res, __ign1;                                             \
-       asm volatile (                                                  \
-               "call %[call]"                                          \
-               : "=a" (__res), "=b" (__ign1)                           \
-               : "1" ((long)(a1)),                                     \
-                 [call] "m" (hypercall_page[__HYPERVISOR_##name])      \
-               : "memory" );                                           \
+       __HYPERCALL_DECLS;                                              \
+       __HYPERCALL_1ARG(a1);                                           \
+       asm volatile (__HYPERCALL                                       \
+                     : __HYPERCALL_1PARAM                              \
+                     : __HYPERCALL_ENTRY(name)                         \
+                     : __HYPERCALL_CLOBBER1);                          \
        (type)__res;                                                    \
 })
 
 #define _hypercall2(type, name, a1, a2)                                        \
 ({                                                                     \
-       long __res, __ign1, __ign2;                                     \
-       asm volatile (                                                  \
-               "call %[call]"                                          \
-               : "=a" (__res), "=b" (__ign1), "=c" (__ign2)            \
-               : "1" ((long)(a1)), "2" ((long)(a2)),                   \
-                 [call] "m" (hypercall_page[__HYPERVISOR_##name])      \
-               : "memory" );                                           \
+       __HYPERCALL_DECLS;                                              \
+       __HYPERCALL_2ARG(a1, a2);                                       \
+       asm volatile (__HYPERCALL                                       \
+                     : __HYPERCALL_2PARAM                              \
+                     : __HYPERCALL_ENTRY(name)                         \
+                     : __HYPERCALL_CLOBBER2);                          \
        (type)__res;                                                    \
 })
 
 #define _hypercall3(type, name, a1, a2, a3)                            \
 ({                                                                     \
-       long __res, __ign1, __ign2, __ign3;                             \
-       asm volatile (                                                  \
-               "call %[call]"                                          \
-               : "=a" (__res), "=b" (__ign1), "=c" (__ign2),           \
-               "=d" (__ign3)                                           \
-               : "1" ((long)(a1)), "2" ((long)(a2)),                   \
-                 "3" ((long)(a3)),                                     \
-                 [call] "m" (hypercall_page[__HYPERVISOR_##name])      \
-               : "memory" );                                           \
+       __HYPERCALL_DECLS;                                              \
+       __HYPERCALL_3ARG(a1, a2, a3);                                   \
+       asm volatile (__HYPERCALL                                       \
+                     : __HYPERCALL_3PARAM                              \
+                     : __HYPERCALL_ENTRY(name)                         \
+                     : __HYPERCALL_CLOBBER3);                          \
        (type)__res;                                                    \
 })
 
 #define _hypercall4(type, name, a1, a2, a3, a4)                                \
 ({                                                                     \
-       long __res, __ign1, __ign2, __ign3, __ign4;                     \
-       asm volatile (                                                  \
-               "call %[call]"                                          \
-               : "=a" (__res), "=b" (__ign1), "=c" (__ign2),           \
-               "=d" (__ign3), "=S" (__ign4)                            \
-               : "1" ((long)(a1)), "2" ((long)(a2)),                   \
-                 "3" ((long)(a3)), "4" ((long)(a4)),                   \
-                 [call] "m" (hypercall_page[__HYPERVISOR_##name])      \
-               : "memory" );                                           \
+       __HYPERCALL_DECLS;                                              \
+       __HYPERCALL_4ARG(a1, a2, a3, a4);                               \
+       asm volatile (__HYPERCALL                                       \
+                     : __HYPERCALL_4PARAM                              \
+                     : __HYPERCALL_ENTRY(name)                         \
+                     : __HYPERCALL_CLOBBER4);                          \
        (type)__res;                                                    \
 })
 
 #define _hypercall5(type, name, a1, a2, a3, a4, a5)                    \
 ({                                                                     \
-       long __res, __ign1, __ign2, __ign3, __ign4, __ign5;             \
-       asm volatile (                                                  \
-               "call %[call]"                                          \
-               : "=a" (__res), "=b" (__ign1), "=c" (__ign2),           \
-               "=d" (__ign3), "=S" (__ign4), "=D" (__ign5)             \
-               : "1" ((long)(a1)), "2" ((long)(a2)),                   \
-                 "3" ((long)(a3)), "4" ((long)(a4)),                   \
-                 "5" ((long)(a5)),                                     \
-                 [call] "m" (hypercall_page[__HYPERVISOR_##name])      \
-               : "memory" );                                           \
+       __HYPERCALL_DECLS;                                              \
+       __HYPERCALL_5ARG(a1, a2, a3, a4, a5);                           \
+       asm volatile (__HYPERCALL                                       \
+                     : __HYPERCALL_5PARAM                              \
+                     : __HYPERCALL_ENTRY(name)                         \
+                     : __HYPERCALL_CLOBBER5);                          \
        (type)__res;                                                    \
 })
 
@@ -152,6 +226,7 @@ HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
        return _hypercall2(int, stack_switch, ss, esp);
 }
 
+#ifdef CONFIG_X86_32
 static inline int
 HYPERVISOR_set_callbacks(unsigned long event_selector,
                         unsigned long event_address,
@@ -162,6 +237,17 @@ HYPERVISOR_set_callbacks(unsigned long event_selector,
                           event_selector, event_address,
                           failsafe_selector, failsafe_address);
 }
+#else  /* CONFIG_X86_64 */
+static inline int
+HYPERVISOR_set_callbacks(unsigned long event_address,
+                       unsigned long failsafe_address,
+                       unsigned long syscall_address)
+{
+       return _hypercall3(int, set_callbacks,
+                          event_address, failsafe_address,
+                          syscall_address);
+}
+#endif  /* CONFIG_X86_{32,64} */
 
 static inline int
 HYPERVISOR_callback_op(int cmd, void *arg)
@@ -223,12 +309,12 @@ static inline int
 HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val,
                             unsigned long flags)
 {
-       unsigned long pte_hi = 0;
-#ifdef CONFIG_X86_PAE
-       pte_hi = new_val.pte_high;
-#endif
-       return _hypercall4(int, update_va_mapping, va,
-                          new_val.pte_low, pte_hi, flags);
+       if (sizeof(new_val) == sizeof(long))
+               return _hypercall3(int, update_va_mapping, va,
+                                  new_val.pte, flags);
+       else
+               return _hypercall4(int, update_va_mapping, va,
+                                  new_val.pte, new_val.pte >> 32, flags);
 }
 
 static inline int
@@ -281,12 +367,13 @@ static inline int
 HYPERVISOR_update_va_mapping_otherdomain(unsigned long va, pte_t new_val,
                                         unsigned long flags, domid_t domid)
 {
-       unsigned long pte_hi = 0;
-#ifdef CONFIG_X86_PAE
-       pte_hi = new_val.pte_high;
-#endif
-       return _hypercall5(int, update_va_mapping_otherdomain, va,
-                          new_val.pte_low, pte_hi, flags, domid);
+       if (sizeof(new_val) == sizeof(long))
+               return _hypercall4(int, update_va_mapping_otherdomain, va,
+                                  new_val.pte, flags, domid);
+       else
+               return _hypercall5(int, update_va_mapping_otherdomain, va,
+                                  new_val.pte, new_val.pte >> 32,
+                                  flags, domid);
 }
 
 static inline int
@@ -301,6 +388,14 @@ HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args)
        return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
 }
 
+#ifdef CONFIG_X86_64
+static inline int
+HYPERVISOR_set_segment_base(int reg, unsigned long value)
+{
+       return _hypercall2(int, set_segment_base, reg, value);
+}
+#endif
+
 static inline int
 HYPERVISOR_suspend(unsigned long srec)
 {
@@ -327,14 +422,14 @@ MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
 {
        mcl->op = __HYPERVISOR_update_va_mapping;
        mcl->args[0] = va;
-#ifdef CONFIG_X86_PAE
-       mcl->args[1] = new_val.pte_low;
-       mcl->args[2] = new_val.pte_high;
-#else
-       mcl->args[1] = new_val.pte_low;
-       mcl->args[2] = 0;
-#endif
-       mcl->args[3] = flags;
+       if (sizeof(new_val) == sizeof(long)) {
+               mcl->args[1] = new_val.pte;
+               mcl->args[2] = flags;
+       } else {
+               mcl->args[1] = new_val.pte;
+               mcl->args[2] = new_val.pte >> 32;
+               mcl->args[3] = flags;
+       }
 }
 
 static inline void
@@ -354,15 +449,16 @@ MULTI_update_va_mapping_otherdomain(struct multicall_entry *mcl, unsigned long v
 {
        mcl->op = __HYPERVISOR_update_va_mapping_otherdomain;
        mcl->args[0] = va;
-#ifdef CONFIG_X86_PAE
-       mcl->args[1] = new_val.pte_low;
-       mcl->args[2] = new_val.pte_high;
-#else
-       mcl->args[1] = new_val.pte_low;
-       mcl->args[2] = 0;
-#endif
-       mcl->args[3] = flags;
-       mcl->args[4] = domid;
+       if (sizeof(new_val) == sizeof(long)) {
+               mcl->args[1] = new_val.pte;
+               mcl->args[2] = flags;
+               mcl->args[3] = domid;
+       } else {
+               mcl->args[1] = new_val.pte;
+               mcl->args[2] = new_val.pte >> 32;
+               mcl->args[3] = flags;
+               mcl->args[4] = domid;
+       }
 }
 
 static inline void
@@ -370,10 +466,15 @@ MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr,
                        struct desc_struct desc)
 {
        mcl->op = __HYPERVISOR_update_descriptor;
-       mcl->args[0] = maddr;
-       mcl->args[1] = maddr >> 32;
-       mcl->args[2] = desc.a;
-       mcl->args[3] = desc.b;
+       if (sizeof(maddr) == sizeof(long)) {
+               mcl->args[0] = maddr;
+               mcl->args[1] = *(unsigned long *)&desc;
+       } else {
+               mcl->args[0] = maddr;
+               mcl->args[1] = maddr >> 32;
+               mcl->args[2] = desc.a;
+               mcl->args[3] = desc.b;
+       }
 }
 
 static inline void
index 6227000a1e840780512b31e1e246bf7cd14ee716..9d810f2538a2227083bbe8b6bc7a7b753c9add7b 100644 (file)
@@ -1,13 +1,13 @@
 /******************************************************************************
  * arch-x86_32.h
  *
- * Guest OS interface to x86 32-bit Xen.
+ * Guest OS interface to x86 Xen.
  *
  * Copyright (c) 2004, K A Fraser
  */
 
-#ifndef __XEN_PUBLIC_ARCH_X86_32_H__
-#define __XEN_PUBLIC_ARCH_X86_32_H__
+#ifndef __ASM_X86_XEN_INTERFACE_H
+#define __ASM_X86_XEN_INTERFACE_H
 
 #ifdef __XEN__
 #define __DEFINE_GUEST_HANDLE(name, type) \
@@ -57,6 +57,17 @@ DEFINE_GUEST_HANDLE(long);
 DEFINE_GUEST_HANDLE(void);
 #endif
 
+#ifndef HYPERVISOR_VIRT_START
+#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
+#endif
+
+#ifndef machine_to_phys_mapping
+#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
+#endif
+
+/* Maximum number of virtual CPUs in multi-processor guests. */
+#define MAX_VIRT_CPUS 32
+
 /*
  * SEGMENT DESCRIPTOR TABLES
  */
@@ -70,59 +81,22 @@ DEFINE_GUEST_HANDLE(void);
 #define FIRST_RESERVED_GDT_BYTE  (FIRST_RESERVED_GDT_PAGE * 4096)
 #define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8)
 
-/*
- * These flat segments are in the Xen-private section of every GDT. Since these
- * are also present in the initial GDT, many OSes will be able to avoid
- * installing their own GDT.
- */
-#define FLAT_RING1_CS 0xe019    /* GDT index 259 */
-#define FLAT_RING1_DS 0xe021    /* GDT index 260 */
-#define FLAT_RING1_SS 0xe021    /* GDT index 260 */
-#define FLAT_RING3_CS 0xe02b    /* GDT index 261 */
-#define FLAT_RING3_DS 0xe033    /* GDT index 262 */
-#define FLAT_RING3_SS 0xe033    /* GDT index 262 */
-
-#define FLAT_KERNEL_CS FLAT_RING1_CS
-#define FLAT_KERNEL_DS FLAT_RING1_DS
-#define FLAT_KERNEL_SS FLAT_RING1_SS
-#define FLAT_USER_CS    FLAT_RING3_CS
-#define FLAT_USER_DS    FLAT_RING3_DS
-#define FLAT_USER_SS    FLAT_RING3_SS
-
-/* And the trap vector is... */
-#define TRAP_INSTR "int $0x82"
-
-/*
- * Virtual addresses beyond this are not modifiable by guest OSes. The
- * machine->physical mapping table starts at this address, read-only.
- */
-#ifdef CONFIG_X86_PAE
-#define __HYPERVISOR_VIRT_START 0xF5800000
-#else
-#define __HYPERVISOR_VIRT_START 0xFC000000
-#endif
-
-#ifndef HYPERVISOR_VIRT_START
-#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
-#endif
-
-#ifndef machine_to_phys_mapping
-#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
-#endif
-
-/* Maximum number of virtual CPUs in multi-processor guests. */
-#define MAX_VIRT_CPUS 32
-
-#ifndef __ASSEMBLY__
-
 /*
  * Send an array of these to HYPERVISOR_set_trap_table()
+ * The privilege level specifies which modes may enter a trap via a software
+ * interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate
+ * privilege levels as follows:
+ *  Level == 0: Noone may enter
+ *  Level == 1: Kernel may enter
+ *  Level == 2: Kernel may enter
+ *  Level == 3: Everyone may enter
  */
 #define TI_GET_DPL(_ti)                ((_ti)->flags & 3)
 #define TI_GET_IF(_ti)         ((_ti)->flags & 4)
 #define TI_SET_DPL(_ti, _dpl)  ((_ti)->flags |= (_dpl))
 #define TI_SET_IF(_ti, _if)    ((_ti)->flags |= ((!!(_if))<<2))
 
+#ifndef __ASSEMBLY__
 struct trap_info {
     uint8_t       vector;  /* exception vector                              */
     uint8_t       flags;   /* 0-3: privilege level; 4: clear event enable?  */
@@ -131,32 +105,21 @@ struct trap_info {
 };
 DEFINE_GUEST_HANDLE_STRUCT(trap_info);
 
-struct cpu_user_regs {
-    uint32_t ebx;
-    uint32_t ecx;
-    uint32_t edx;
-    uint32_t esi;
-    uint32_t edi;
-    uint32_t ebp;
-    uint32_t eax;
-    uint16_t error_code;    /* private */
-    uint16_t entry_vector;  /* private */
-    uint32_t eip;
-    uint16_t cs;
-    uint8_t  saved_upcall_mask;
-    uint8_t  _pad0;
-    uint32_t eflags;        /* eflags.IF == !saved_upcall_mask */
-    uint32_t esp;
-    uint16_t ss, _pad1;
-    uint16_t es, _pad2;
-    uint16_t ds, _pad3;
-    uint16_t fs, _pad4;
-    uint16_t gs, _pad5;
+struct arch_shared_info {
+    unsigned long max_pfn;                  /* max pfn that appears in table */
+    /* Frame containing list of mfns containing list of mfns containing p2m. */
+    unsigned long pfn_to_mfn_frame_list_list;
+    unsigned long nmi_reason;
 };
-DEFINE_GUEST_HANDLE_STRUCT(cpu_user_regs);
+#endif /* !__ASSEMBLY__ */
 
-typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */
+#ifdef CONFIG_X86_32
+#include "interface_32.h"
+#else
+#include "interface_64.h"
+#endif
 
+#ifndef __ASSEMBLY__
 /*
  * The following is all CPU context. Note that the fpu_ctxt block is filled
  * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used.
@@ -173,33 +136,29 @@ struct vcpu_guest_context {
     unsigned long ldt_base, ldt_ents;       /* LDT (linear address, # ents) */
     unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
     unsigned long kernel_ss, kernel_sp;     /* Virtual TSS (only SS1/SP1)   */
+    /* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */
     unsigned long ctrlreg[8];               /* CR0-CR7 (control registers)  */
     unsigned long debugreg[8];              /* DB0-DB7 (debug registers)    */
+#ifdef __i386__
     unsigned long event_callback_cs;        /* CS:EIP of event callback     */
     unsigned long event_callback_eip;
     unsigned long failsafe_callback_cs;     /* CS:EIP of failsafe callback  */
     unsigned long failsafe_callback_eip;
+#else
+    unsigned long event_callback_eip;
+    unsigned long failsafe_callback_eip;
+    unsigned long syscall_callback_eip;
+#endif
     unsigned long vm_assist;                /* VMASST_TYPE_* bitmap */
+#ifdef __x86_64__
+    /* Segment base addresses. */
+    uint64_t      fs_base;
+    uint64_t      gs_base_kernel;
+    uint64_t      gs_base_user;
+#endif
 };
 DEFINE_GUEST_HANDLE_STRUCT(vcpu_guest_context);
-
-struct arch_shared_info {
-    unsigned long max_pfn;                  /* max pfn that appears in table */
-    /* Frame containing list of mfns containing list of mfns containing p2m. */
-    unsigned long pfn_to_mfn_frame_list_list;
-    unsigned long nmi_reason;
-};
-
-struct arch_vcpu_info {
-    unsigned long cr2;
-    unsigned long pad[5]; /* sizeof(struct vcpu_info) == 64 */
-};
-
-struct xen_callback {
-       unsigned long cs;
-       unsigned long eip;
-};
-#endif /* !__ASSEMBLY__ */
+#endif /* !__ASSEMBLY__ */
 
 /*
  * Prefix forces emulation of some non-trapping instructions.
@@ -213,4 +172,4 @@ struct xen_callback {
 #define XEN_CPUID          XEN_EMULATE_PREFIX "cpuid"
 #endif
 
-#endif
+#endif /* __ASM_X86_XEN_INTERFACE_H */
diff --git a/include/asm-x86/xen/interface_32.h b/include/asm-x86/xen/interface_32.h
new file mode 100644 (file)
index 0000000..d8ac41d
--- /dev/null
@@ -0,0 +1,97 @@
+/******************************************************************************
+ * arch-x86_32.h
+ *
+ * Guest OS interface to x86 32-bit Xen.
+ *
+ * Copyright (c) 2004, K A Fraser
+ */
+
+#ifndef __ASM_X86_XEN_INTERFACE_32_H
+#define __ASM_X86_XEN_INTERFACE_32_H
+
+
+/*
+ * These flat segments are in the Xen-private section of every GDT. Since these
+ * are also present in the initial GDT, many OSes will be able to avoid
+ * installing their own GDT.
+ */
+#define FLAT_RING1_CS 0xe019    /* GDT index 259 */
+#define FLAT_RING1_DS 0xe021    /* GDT index 260 */
+#define FLAT_RING1_SS 0xe021    /* GDT index 260 */
+#define FLAT_RING3_CS 0xe02b    /* GDT index 261 */
+#define FLAT_RING3_DS 0xe033    /* GDT index 262 */
+#define FLAT_RING3_SS 0xe033    /* GDT index 262 */
+
+#define FLAT_KERNEL_CS FLAT_RING1_CS
+#define FLAT_KERNEL_DS FLAT_RING1_DS
+#define FLAT_KERNEL_SS FLAT_RING1_SS
+#define FLAT_USER_CS    FLAT_RING3_CS
+#define FLAT_USER_DS    FLAT_RING3_DS
+#define FLAT_USER_SS    FLAT_RING3_SS
+
+/* And the trap vector is... */
+#define TRAP_INSTR "int $0x82"
+
+/*
+ * Virtual addresses beyond this are not modifiable by guest OSes. The
+ * machine->physical mapping table starts at this address, read-only.
+ */
+#define __HYPERVISOR_VIRT_START 0xF5800000
+
+#ifndef __ASSEMBLY__
+
+struct cpu_user_regs {
+    uint32_t ebx;
+    uint32_t ecx;
+    uint32_t edx;
+    uint32_t esi;
+    uint32_t edi;
+    uint32_t ebp;
+    uint32_t eax;
+    uint16_t error_code;    /* private */
+    uint16_t entry_vector;  /* private */
+    uint32_t eip;
+    uint16_t cs;
+    uint8_t  saved_upcall_mask;
+    uint8_t  _pad0;
+    uint32_t eflags;        /* eflags.IF == !saved_upcall_mask */
+    uint32_t esp;
+    uint16_t ss, _pad1;
+    uint16_t es, _pad2;
+    uint16_t ds, _pad3;
+    uint16_t fs, _pad4;
+    uint16_t gs, _pad5;
+};
+DEFINE_GUEST_HANDLE_STRUCT(cpu_user_regs);
+
+typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */
+
+struct arch_vcpu_info {
+    unsigned long cr2;
+    unsigned long pad[5]; /* sizeof(struct vcpu_info) == 64 */
+};
+
+struct xen_callback {
+       unsigned long cs;
+       unsigned long eip;
+};
+typedef struct xen_callback xen_callback_t;
+
+#define XEN_CALLBACK(__cs, __eip)                              \
+       ((struct xen_callback){ .cs = (__cs), .eip = (unsigned long)(__eip) })
+#endif /* !__ASSEMBLY__ */
+
+
+/*
+ * Page-directory addresses above 4GB do not fit into architectural %cr3.
+ * When accessing %cr3, or equivalent field in vcpu_guest_context, guests
+ * must use the following accessor macros to pack/unpack valid MFNs.
+ *
+ * Note that Xen is using the fact that the pagetable base is always
+ * page-aligned, and putting the 12 MSB of the address into the 12 LSB
+ * of cr3.
+ */
+#define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20))
+#define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20))
+
+#endif /* __ASM_X86_XEN_INTERFACE_32_H */
diff --git a/include/asm-x86/xen/interface_64.h b/include/asm-x86/xen/interface_64.h
new file mode 100644 (file)
index 0000000..842266c
--- /dev/null
@@ -0,0 +1,159 @@
+#ifndef __ASM_X86_XEN_INTERFACE_64_H
+#define __ASM_X86_XEN_INTERFACE_64_H
+
+/*
+ * 64-bit segment selectors
+ * These flat segments are in the Xen-private section of every GDT. Since these
+ * are also present in the initial GDT, many OSes will be able to avoid
+ * installing their own GDT.
+ */
+
+#define FLAT_RING3_CS32 0xe023  /* GDT index 260 */
+#define FLAT_RING3_CS64 0xe033  /* GDT index 261 */
+#define FLAT_RING3_DS32 0xe02b  /* GDT index 262 */
+#define FLAT_RING3_DS64 0x0000  /* NULL selector */
+#define FLAT_RING3_SS32 0xe02b  /* GDT index 262 */
+#define FLAT_RING3_SS64 0xe02b  /* GDT index 262 */
+
+#define FLAT_KERNEL_DS64 FLAT_RING3_DS64
+#define FLAT_KERNEL_DS32 FLAT_RING3_DS32
+#define FLAT_KERNEL_DS   FLAT_KERNEL_DS64
+#define FLAT_KERNEL_CS64 FLAT_RING3_CS64
+#define FLAT_KERNEL_CS32 FLAT_RING3_CS32
+#define FLAT_KERNEL_CS   FLAT_KERNEL_CS64
+#define FLAT_KERNEL_SS64 FLAT_RING3_SS64
+#define FLAT_KERNEL_SS32 FLAT_RING3_SS32
+#define FLAT_KERNEL_SS   FLAT_KERNEL_SS64
+
+#define FLAT_USER_DS64 FLAT_RING3_DS64
+#define FLAT_USER_DS32 FLAT_RING3_DS32
+#define FLAT_USER_DS   FLAT_USER_DS64
+#define FLAT_USER_CS64 FLAT_RING3_CS64
+#define FLAT_USER_CS32 FLAT_RING3_CS32
+#define FLAT_USER_CS   FLAT_USER_CS64
+#define FLAT_USER_SS64 FLAT_RING3_SS64
+#define FLAT_USER_SS32 FLAT_RING3_SS32
+#define FLAT_USER_SS   FLAT_USER_SS64
+
+#define __HYPERVISOR_VIRT_START 0xFFFF800000000000
+#define __HYPERVISOR_VIRT_END   0xFFFF880000000000
+#define __MACH2PHYS_VIRT_START  0xFFFF800000000000
+#define __MACH2PHYS_VIRT_END    0xFFFF804000000000
+
+#ifndef HYPERVISOR_VIRT_START
+#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
+#define HYPERVISOR_VIRT_END   mk_unsigned_long(__HYPERVISOR_VIRT_END)
+#endif
+
+#define MACH2PHYS_VIRT_START  mk_unsigned_long(__MACH2PHYS_VIRT_START)
+#define MACH2PHYS_VIRT_END    mk_unsigned_long(__MACH2PHYS_VIRT_END)
+#define MACH2PHYS_NR_ENTRIES  ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3)
+#ifndef machine_to_phys_mapping
+#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
+#endif
+
+/*
+ * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
+ *  @which == SEGBASE_*  ;  @base == 64-bit base address
+ * Returns 0 on success.
+ */
+#define SEGBASE_FS          0
+#define SEGBASE_GS_USER     1
+#define SEGBASE_GS_KERNEL   2
+#define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */
+
+/*
+ * int HYPERVISOR_iret(void)
+ * All arguments are on the kernel stack, in the following format.
+ * Never returns if successful. Current kernel context is lost.
+ * The saved CS is mapped as follows:
+ *   RING0 -> RING3 kernel mode.
+ *   RING1 -> RING3 kernel mode.
+ *   RING2 -> RING3 kernel mode.
+ *   RING3 -> RING3 user mode.
+ * However RING0 indicates that the guest kernel should return to iteself
+ * directly with
+ *      orb   $3,1*8(%rsp)
+ *      iretq
+ * If flags contains VGCF_in_syscall:
+ *   Restore RAX, RIP, RFLAGS, RSP.
+ *   Discard R11, RCX, CS, SS.
+ * Otherwise:
+ *   Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP.
+ * All other registers are saved on hypercall entry and restored to user.
+ */
+/* Guest exited in SYSCALL context? Return to guest with SYSRET? */
+#define _VGCF_in_syscall 8
+#define VGCF_in_syscall  (1<<_VGCF_in_syscall)
+#define VGCF_IN_SYSCALL  VGCF_in_syscall
+
+#ifndef __ASSEMBLY__
+
+struct iret_context {
+    /* Top of stack (%rsp at point of hypercall). */
+    uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
+    /* Bottom of iret stack frame. */
+};
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+/* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */
+#define __DECL_REG(name) union { \
+    uint64_t r ## name, e ## name; \
+    uint32_t _e ## name; \
+}
+#else
+/* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */
+#define __DECL_REG(name) uint64_t r ## name
+#endif
+
+struct cpu_user_regs {
+    uint64_t r15;
+    uint64_t r14;
+    uint64_t r13;
+    uint64_t r12;
+    __DECL_REG(bp);
+    __DECL_REG(bx);
+    uint64_t r11;
+    uint64_t r10;
+    uint64_t r9;
+    uint64_t r8;
+    __DECL_REG(ax);
+    __DECL_REG(cx);
+    __DECL_REG(dx);
+    __DECL_REG(si);
+    __DECL_REG(di);
+    uint32_t error_code;    /* private */
+    uint32_t entry_vector;  /* private */
+    __DECL_REG(ip);
+    uint16_t cs, _pad0[1];
+    uint8_t  saved_upcall_mask;
+    uint8_t  _pad1[3];
+    __DECL_REG(flags);      /* rflags.IF == !saved_upcall_mask */
+    __DECL_REG(sp);
+    uint16_t ss, _pad2[3];
+    uint16_t es, _pad3[3];
+    uint16_t ds, _pad4[3];
+    uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base.     */
+    uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */
+};
+DEFINE_GUEST_HANDLE_STRUCT(cpu_user_regs);
+
+#undef __DECL_REG
+
+#define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12)
+#define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12)
+
+struct arch_vcpu_info {
+    unsigned long cr2;
+    unsigned long pad; /* sizeof(vcpu_info_t) == 64 */
+};
+
+typedef unsigned long xen_callback_t;
+
+#define XEN_CALLBACK(__cs, __rip)                              \
+       ((unsigned long)(__rip))
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* __ASM_X86_XEN_INTERFACE_64_H */
index 377c04591c15e7b7d7a2584a176e6d2cb4d8bb77..7b3835d3b77d9b910228fc0362b19747eb441e26 100644 (file)
@@ -124,7 +124,7 @@ static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
 
 static inline unsigned long pte_mfn(pte_t pte)
 {
-       return (pte.pte & PTE_MASK) >> PAGE_SHIFT;
+       return (pte.pte & PTE_PFN_MASK) >> PAGE_SHIFT;
 }
 
 static inline pte_t mfn_pte(unsigned long page_nr, pgprot_t pgprot)
@@ -148,13 +148,17 @@ static inline pte_t __pte_ma(pteval_t x)
 }
 
 #define pmd_val_ma(v) ((v).pmd)
+#ifdef __PAGETABLE_PUD_FOLDED
 #define pud_val_ma(v) ((v).pgd.pgd)
+#else
+#define pud_val_ma(v) ((v).pud)
+#endif
 #define __pmd_ma(x)    ((pmd_t) { (x) } )
 
 #define pgd_val_ma(x)  ((x).pgd)
 
 
-xmaddr_t arbitrary_virt_to_machine(unsigned long address);
+xmaddr_t arbitrary_virt_to_machine(void *address);
 void make_lowmem_page_readonly(void *vaddr);
 void make_lowmem_page_readwrite(void *vaddr);
 
index eb640f0acfacd629ee179c4b10e639d56a04b93a..0f50d4cc4360e65d3453704aa400448f99cb95a6 100644 (file)
@@ -101,21 +101,14 @@ async_tx_find_channel(struct dma_async_tx_descriptor *depend_tx,
 
 /**
  * async_tx_sync_epilog - actions to take if an operation is run synchronously
- * @flags: async_tx flags
- * @depend_tx: transaction depends on depend_tx
  * @cb_fn: function to call when the transaction completes
  * @cb_fn_param: parameter to pass to the callback routine
  */
 static inline void
-async_tx_sync_epilog(unsigned long flags,
-       struct dma_async_tx_descriptor *depend_tx,
-       dma_async_tx_callback cb_fn, void *cb_fn_param)
+async_tx_sync_epilog(dma_async_tx_callback cb_fn, void *cb_fn_param)
 {
        if (cb_fn)
                cb_fn(cb_fn_param);
-
-       if (depend_tx && (flags & ASYNC_TX_DEP_ACK))
-               async_tx_ack(depend_tx);
 }
 
 void
@@ -152,4 +145,6 @@ struct dma_async_tx_descriptor *
 async_trigger_callback(enum async_tx_flags flags,
        struct dma_async_tx_descriptor *depend_tx,
        dma_async_tx_callback cb_fn, void *cb_fn_param);
+
+void async_tx_quiesce(struct dma_async_tx_descriptor **tx);
 #endif /* _ASYNC_TX_H_ */
index ad895455ab72cebf26a218910433a34edd53e30d..0da17d14fd139f548cc18c3076a8390a8089918f 100644 (file)
 
 #define AT_SECURE 23   /* secure mode boolean */
 
+#define AT_EXECFN  31  /* filename of program */
 #ifdef __KERNEL__
-#define AT_VECTOR_SIZE_BASE (14 + 2) /* NEW_AUX_ENT entries in auxiliary table */
+#define AT_VECTOR_SIZE_BASE 17 /* NEW_AUX_ENT entries in auxiliary table */
+  /* number of "#define AT_.*" above, minus {AT_NULL, AT_IGNORE, AT_NOTELF} */
 #endif
 
 #endif /* _LINUX_AUXVEC_H */
index e7e91dbfde0f25927490cf1c9d18c3587b8d7ea3..2270ca5ec6315659459c9c8272c05996abdd85e2 100644 (file)
@@ -4,9 +4,6 @@
  *  Copyright (C) 2001 Russell King
  *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
  *            
- *
- * $Id: cpufreq.h,v 1.36 2003/01/20 17:31:48 db Exp $
- *
  * 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.
index af61cd1f37e96c1e019fd812c45a938de03c3944..b00a753eda53e6af1e50e7d892defdcb402913d8 100644 (file)
@@ -10,6 +10,7 @@ void dca_unregister_notify(struct notifier_block *nb);
 #define DCA_PROVIDER_REMOVE  0x0002
 
 struct dca_provider {
+       struct list_head        node;
        struct dca_ops          *ops;
        struct device           *cd;
        int                      id;
@@ -18,7 +19,9 @@ struct dca_provider {
 struct dca_ops {
        int     (*add_requester)    (struct dca_provider *, struct device *);
        int     (*remove_requester) (struct dca_provider *, struct device *);
-       u8      (*get_tag)          (struct dca_provider *, int cpu);
+       u8      (*get_tag)          (struct dca_provider *, struct device *,
+                                    int cpu);
+       int     (*dev_managed)      (struct dca_provider *, struct device *);
 };
 
 struct dca_provider *alloc_dca_provider(struct dca_ops *ops, int priv_size);
@@ -32,9 +35,11 @@ static inline void *dca_priv(struct dca_provider *dca)
 }
 
 /* Requester API */
+#define DCA_GET_TAG_TWO_ARGS
 int dca_add_requester(struct device *dev);
 int dca_remove_requester(struct device *dev);
 u8 dca_get_tag(int cpu);
+u8 dca3_get_tag(struct device *dev, int cpu);
 
 /* internal stuff */
 int __init dca_sysfs_init(void);
index 7266124361b44f24259db727c7dc23d0694fb8de..e1a6c046cea3d8133d3f659a1a85ffbe32844b5b 100644 (file)
@@ -26,6 +26,8 @@ struct debugfs_blob_wrapper {
        unsigned long size;
 };
 
+extern struct dentry *arch_debugfs_dir;
+
 #if defined(CONFIG_DEBUG_FS)
 
 /* declared over in file.c */
@@ -42,6 +44,7 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
                                      const char *dest);
 
 void debugfs_remove(struct dentry *dentry);
+void debugfs_remove_recursive(struct dentry *dentry);
 
 struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
                 struct dentry *new_dir, const char *new_name);
@@ -99,6 +102,9 @@ static inline struct dentry *debugfs_create_symlink(const char *name,
 static inline void debugfs_remove(struct dentry *dentry)
 { }
 
+static inline void debugfs_remove_recursive(struct dentry *dentry)
+{ }
+
 static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
                 struct dentry *new_dir, char *new_name)
 {
index 0d8d419d191ab1022036efee46bd7074968890e3..a90222e3297d807e554ca270b50f097a3a5dfbc7 100644 (file)
@@ -9,11 +9,13 @@
 #define _LINUX_DEVICE_MAPPER_H
 
 #include <linux/bio.h>
+#include <linux/blkdev.h>
 
 struct dm_target;
 struct dm_table;
 struct dm_dev;
 struct mapped_device;
+struct bio_vec;
 
 typedef enum { STATUSTYPE_INFO, STATUSTYPE_TABLE } status_type_t;
 
@@ -72,6 +74,9 @@ typedef int (*dm_ioctl_fn) (struct dm_target *ti, struct inode *inode,
                            struct file *filp, unsigned int cmd,
                            unsigned long arg);
 
+typedef int (*dm_merge_fn) (struct dm_target *ti, struct bvec_merge_data *bvm,
+                           struct bio_vec *biovec, int max_size);
+
 void dm_error(const char *message);
 
 /*
@@ -107,6 +112,7 @@ struct target_type {
        dm_status_fn status;
        dm_message_fn message;
        dm_ioctl_fn ioctl;
+       dm_merge_fn merge;
 };
 
 struct io_restrictions {
index f71a78d123aef9d7b3b03276921d10286e1eceed..d24a47f80f9c67587df13a5a8b57282f7dd2e8dd 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kobject.h>
 #include <linux/klist.h>
 #include <linux/list.h>
+#include <linux/lockdep.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
 #include <linux/module.h>
 #include <asm/atomic.h>
 #include <asm/device.h>
 
-#define DEVICE_NAME_SIZE       50
-/* DEVICE_NAME_HALF is really less than half to accommodate slop */
-#define DEVICE_NAME_HALF       __stringify(20)
-#define DEVICE_ID_SIZE         32
-#define BUS_ID_SIZE            KOBJ_NAME_LEN
-
+#define BUS_ID_SIZE            20
 
 struct device;
 struct device_driver;
 struct driver_private;
 struct class;
+struct class_private;
 struct bus_type;
 struct bus_type_private;
 
@@ -186,13 +183,9 @@ struct class {
        const char              *name;
        struct module           *owner;
 
-       struct kset             subsys;
-       struct list_head        devices;
-       struct list_head        interfaces;
-       struct kset             class_dirs;
-       struct semaphore        sem; /* locks children, devices, interfaces */
        struct class_attribute          *class_attrs;
        struct device_attribute         *dev_attrs;
+       struct kobject                  *dev_kobj;
 
        int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
 
@@ -203,13 +196,28 @@ struct class {
        int (*resume)(struct device *dev);
 
        struct pm_ops *pm;
+       struct class_private *p;
 };
 
-extern int __must_check class_register(struct class *class);
+extern struct kobject *sysfs_dev_block_kobj;
+extern struct kobject *sysfs_dev_char_kobj;
+extern int __must_check __class_register(struct class *class,
+                                        struct lock_class_key *key);
 extern void class_unregister(struct class *class);
-extern int class_for_each_device(struct class *class, void *data,
+
+/* This is a #define to keep the compiler from merging different
+ * instances of the __key variable */
+#define class_register(class)                  \
+({                                             \
+       static struct lock_class_key __key;     \
+       __class_register(class, &__key);        \
+})
+
+extern int class_for_each_device(struct class *class, struct device *start,
+                                void *data,
                                 int (*fn)(struct device *dev, void *data));
-extern struct device *class_find_device(struct class *class, void *data,
+extern struct device *class_find_device(struct class *class,
+                                       struct device *start, void *data,
                                        int (*match)(struct device *, void *));
 
 struct class_attribute {
@@ -237,9 +245,19 @@ struct class_interface {
 extern int __must_check class_interface_register(struct class_interface *);
 extern void class_interface_unregister(struct class_interface *);
 
-extern struct class *class_create(struct module *owner, const char *name);
+extern struct class * __must_check __class_create(struct module *owner,
+                                                 const char *name,
+                                                 struct lock_class_key *key);
 extern void class_destroy(struct class *cls);
 
+/* This is a #define to keep the compiler from merging different
+ * instances of the __key variable */
+#define class_create(owner, name)              \
+({                                             \
+       static struct lock_class_key __key;     \
+       __class_create(owner, name, &__key);    \
+})
+
 /*
  * The type of device, "struct device" is embedded in. A class
  * or bus can contain devices of different types
@@ -468,14 +486,10 @@ extern struct device *device_create_vargs(struct class *cls,
                                          const char *fmt,
                                          va_list vargs);
 extern struct device *device_create(struct class *cls, struct device *parent,
-                                   dev_t devt, const char *fmt, ...)
-                                   __attribute__((format(printf, 4, 5)));
-extern struct device *device_create_drvdata(struct class *cls,
-                                           struct device *parent,
-                                           dev_t devt,
-                                           void *drvdata,
-                                           const char *fmt, ...)
+                                   dev_t devt, void *drvdata,
+                                   const char *fmt, ...)
                                    __attribute__((format(printf, 5, 6)));
+#define device_create_drvdata  device_create
 extern void device_destroy(struct class *cls, dev_t devt);
 
 /*
index b03c41bbfa140a8b1f83bbea29684e5eebed1e35..28c2940eb30d5bf5942563e561c023519afb4982 100644 (file)
@@ -256,9 +256,9 @@ enum {
 #define DM_DEV_SET_GEOMETRY    _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 
 #define DM_VERSION_MAJOR       4
-#define DM_VERSION_MINOR       13
+#define DM_VERSION_MINOR       14
 #define DM_VERSION_PATCHLEVEL  0
-#define DM_VERSION_EXTRA       "-ioctl (2007-10-18)"
+#define DM_VERSION_EXTRA       "-ioctl (2008-04-23)"
 
 /* Status bits */
 #define DM_READONLY_FLAG       (1 << 0) /* In/Out */
index 1677e2bfa00cea03f216b196b32cf42791aa9521..71ad34eca6e3d124f9175e79d536a39379ee02fa 100644 (file)
@@ -12,6 +12,7 @@
  */
 enum dma_attr {
        DMA_ATTR_WRITE_BARRIER,
+       DMA_ATTR_WEAK_ORDERING,
        DMA_ATTR_MAX,
 };
 
index d08a5c5eb928f3f2d8ef8639a518b0ac37fb6c89..adb0b084eb5a413c601d4a8489e006e061906840 100644 (file)
@@ -89,10 +89,23 @@ enum dma_transaction_type {
        DMA_MEMSET,
        DMA_MEMCPY_CRC32C,
        DMA_INTERRUPT,
+       DMA_SLAVE,
 };
 
 /* last transaction type for creation of the capabilities mask */
-#define DMA_TX_TYPE_END (DMA_INTERRUPT + 1)
+#define DMA_TX_TYPE_END (DMA_SLAVE + 1)
+
+/**
+ * enum dma_slave_width - DMA slave register access width.
+ * @DMA_SLAVE_WIDTH_8BIT: Do 8-bit slave register accesses
+ * @DMA_SLAVE_WIDTH_16BIT: Do 16-bit slave register accesses
+ * @DMA_SLAVE_WIDTH_32BIT: Do 32-bit slave register accesses
+ */
+enum dma_slave_width {
+       DMA_SLAVE_WIDTH_8BIT,
+       DMA_SLAVE_WIDTH_16BIT,
+       DMA_SLAVE_WIDTH_32BIT,
+};
 
 /**
  * enum dma_ctrl_flags - DMA flags to augment operation preparation,
@@ -102,10 +115,14 @@ enum dma_transaction_type {
  * @DMA_CTRL_ACK - the descriptor cannot be reused until the client
  *     acknowledges receipt, i.e. has has a chance to establish any
  *     dependency chains
+ * @DMA_COMPL_SKIP_SRC_UNMAP - set to disable dma-unmapping the source buffer(s)
+ * @DMA_COMPL_SKIP_DEST_UNMAP - set to disable dma-unmapping the destination(s)
  */
 enum dma_ctrl_flags {
        DMA_PREP_INTERRUPT = (1 << 0),
        DMA_CTRL_ACK = (1 << 1),
+       DMA_COMPL_SKIP_SRC_UNMAP = (1 << 2),
+       DMA_COMPL_SKIP_DEST_UNMAP = (1 << 3),
 };
 
 /**
@@ -114,6 +131,32 @@ enum dma_ctrl_flags {
  */
 typedef struct { DECLARE_BITMAP(bits, DMA_TX_TYPE_END); } dma_cap_mask_t;
 
+/**
+ * struct dma_slave - Information about a DMA slave
+ * @dev: device acting as DMA slave
+ * @dma_dev: required DMA master device. If non-NULL, the client can not be
+ *     bound to other masters than this.
+ * @tx_reg: physical address of data register used for
+ *     memory-to-peripheral transfers
+ * @rx_reg: physical address of data register used for
+ *     peripheral-to-memory transfers
+ * @reg_width: peripheral register width
+ *
+ * If dma_dev is non-NULL, the client can not be bound to other DMA
+ * masters than the one corresponding to this device. The DMA master
+ * driver may use this to determine if there is controller-specific
+ * data wrapped around this struct. Drivers of platform code that sets
+ * the dma_dev field must therefore make sure to use an appropriate
+ * controller-specific dma slave structure wrapping this struct.
+ */
+struct dma_slave {
+       struct device           *dev;
+       struct device           *dma_dev;
+       dma_addr_t              tx_reg;
+       dma_addr_t              rx_reg;
+       enum dma_slave_width    reg_width;
+};
+
 /**
  * struct dma_chan_percpu - the per-CPU part of struct dma_chan
  * @refcount: local_t used for open-coded "bigref" counting
@@ -139,6 +182,7 @@ struct dma_chan_percpu {
  * @rcu: the DMA channel's RCU head
  * @device_node: used to add this to the device chan list
  * @local: per-cpu pointer to a struct dma_chan_percpu
+ * @client-count: how many clients are using this channel
  */
 struct dma_chan {
        struct dma_device *device;
@@ -154,6 +198,7 @@ struct dma_chan {
 
        struct list_head device_node;
        struct dma_chan_percpu *local;
+       int client_count;
 };
 
 #define to_dma_chan(p) container_of(p, struct dma_chan, dev)
@@ -202,11 +247,14 @@ typedef enum dma_state_client (*dma_event_callback) (struct dma_client *client,
  * @event_callback: func ptr to call when something happens
  * @cap_mask: only return channels that satisfy the requested capabilities
  *  a value of zero corresponds to any capability
+ * @slave: data for preparing slave transfer. Must be non-NULL iff the
+ *  DMA_SLAVE capability is requested.
  * @global_node: list_head for global dma_client_list
  */
 struct dma_client {
        dma_event_callback      event_callback;
        dma_cap_mask_t          cap_mask;
+       struct dma_slave        *slave;
        struct list_head        global_node;
 };
 
@@ -263,6 +311,8 @@ struct dma_async_tx_descriptor {
  * @device_prep_dma_zero_sum: prepares a zero_sum operation
  * @device_prep_dma_memset: prepares a memset operation
  * @device_prep_dma_interrupt: prepares an end of chain interrupt operation
+ * @device_prep_slave_sg: prepares a slave dma operation
+ * @device_terminate_all: terminate all pending operations
  * @device_issue_pending: push pending transactions to hardware
  */
 struct dma_device {
@@ -279,7 +329,8 @@ struct dma_device {
        int dev_id;
        struct device *dev;
 
-       int (*device_alloc_chan_resources)(struct dma_chan *chan);
+       int (*device_alloc_chan_resources)(struct dma_chan *chan,
+                       struct dma_client *client);
        void (*device_free_chan_resources)(struct dma_chan *chan);
 
        struct dma_async_tx_descriptor *(*device_prep_dma_memcpy)(
@@ -297,6 +348,12 @@ struct dma_device {
        struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)(
                struct dma_chan *chan, unsigned long flags);
 
+       struct dma_async_tx_descriptor *(*device_prep_slave_sg)(
+               struct dma_chan *chan, struct scatterlist *sgl,
+               unsigned int sg_len, enum dma_data_direction direction,
+               unsigned long flags);
+       void (*device_terminate_all)(struct dma_chan *chan);
+
        enum dma_status (*device_is_tx_complete)(struct dma_chan *chan,
                        dma_cookie_t cookie, dma_cookie_t *last,
                        dma_cookie_t *used);
@@ -318,16 +375,14 @@ dma_cookie_t dma_async_memcpy_pg_to_pg(struct dma_chan *chan,
 void dma_async_tx_descriptor_init(struct dma_async_tx_descriptor *tx,
        struct dma_chan *chan);
 
-static inline void
-async_tx_ack(struct dma_async_tx_descriptor *tx)
+static inline void async_tx_ack(struct dma_async_tx_descriptor *tx)
 {
        tx->flags |= DMA_CTRL_ACK;
 }
 
-static inline int
-async_tx_test_ack(struct dma_async_tx_descriptor *tx)
+static inline bool async_tx_test_ack(struct dma_async_tx_descriptor *tx)
 {
-       return tx->flags & DMA_CTRL_ACK;
+       return (tx->flags & DMA_CTRL_ACK) == DMA_CTRL_ACK;
 }
 
 #define first_dma_cap(mask) __first_dma_cap(&(mask))
diff --git a/include/linux/dw_dmac.h b/include/linux/dw_dmac.h
new file mode 100644 (file)
index 0000000..04d217b
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Driver for the Synopsys DesignWare DMA Controller (aka DMACA on
+ * AVR32 systems.)
+ *
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef DW_DMAC_H
+#define DW_DMAC_H
+
+#include <linux/dmaengine.h>
+
+/**
+ * struct dw_dma_platform_data - Controller configuration parameters
+ * @nr_channels: Number of channels supported by hardware (max 8)
+ */
+struct dw_dma_platform_data {
+       unsigned int    nr_channels;
+};
+
+/**
+ * struct dw_dma_slave - Controller-specific information about a slave
+ * @slave: Generic information about the slave
+ * @ctl_lo: Platform-specific initializer for the CTL_LO register
+ * @cfg_hi: Platform-specific initializer for the CFG_HI register
+ * @cfg_lo: Platform-specific initializer for the CFG_LO register
+ */
+struct dw_dma_slave {
+       struct dma_slave        slave;
+       u32                     cfg_hi;
+       u32                     cfg_lo;
+};
+
+/* Platform-configurable bits in CFG_HI */
+#define DWC_CFGH_FCMODE                (1 << 0)
+#define DWC_CFGH_FIFO_MODE     (1 << 1)
+#define DWC_CFGH_PROTCTL(x)    ((x) << 2)
+#define DWC_CFGH_SRC_PER(x)    ((x) << 7)
+#define DWC_CFGH_DST_PER(x)    ((x) << 11)
+
+/* Platform-configurable bits in CFG_LO */
+#define DWC_CFGL_PRIO(x)       ((x) << 5)      /* priority */
+#define DWC_CFGL_LOCK_CH_XFER  (0 << 12)       /* scope of LOCK_CH */
+#define DWC_CFGL_LOCK_CH_BLOCK (1 << 12)
+#define DWC_CFGL_LOCK_CH_XACT  (2 << 12)
+#define DWC_CFGL_LOCK_BUS_XFER (0 << 14)       /* scope of LOCK_BUS */
+#define DWC_CFGL_LOCK_BUS_BLOCK        (1 << 14)
+#define DWC_CFGL_LOCK_BUS_XACT (2 << 14)
+#define DWC_CFGL_LOCK_CH       (1 << 15)       /* channel lockout */
+#define DWC_CFGL_LOCK_BUS      (1 << 16)       /* busmaster lockout */
+#define DWC_CFGL_HS_DST_POL    (1 << 18)       /* dst handshake active low */
+#define DWC_CFGL_HS_SRC_POL    (1 << 19)       /* src handshake active low */
+
+static inline struct dw_dma_slave *to_dw_dma_slave(struct dma_slave *slave)
+{
+       return container_of(slave, struct dw_dma_slave, slave);
+}
+
+#endif /* DW_DMAC_H */
index fe806b6f030dfb2d7583751cc33d96f36a8b7d90..e61c0be2a45977fb61e48b0b0eb89f016b7c978d 100644 (file)
@@ -40,7 +40,7 @@ struct eisa_device {
        u64                   dma_mask;
        struct device         dev; /* generic device */
 #ifdef CONFIG_EISA_NAMES
-       char                  pretty_name[DEVICE_NAME_SIZE];
+       char                  pretty_name[50];
 #endif
 };
 
index 9bc045b8c4789a3c621d2eaf4251801796a78d42..8300cab30f9a7c2f5e4fafea7a5fa2955bee1934 100644 (file)
@@ -103,10 +103,6 @@ struct fs_mii_bb_platform_info {
        struct fs_mii_bit       mdio_dir;
        struct fs_mii_bit       mdio_dat;
        struct fs_mii_bit       mdc_dat;
-       int mdio_port;  /* port & bit for MDIO */
-       int mdio_bit;
-       int mdc_port;   /* port & bit for MDC  */
-       int mdc_bit;
        int delay;      /* delay in us         */
        int irq[32];    /* irqs per phy's */
 };
@@ -135,11 +131,7 @@ struct fs_platform_info {
        u32 device_flags;
 
        int phy_addr;           /* the phy address (-1 no phy) */
-#ifdef CONFIG_PPC_CPM_NEW_BINDING
        char bus_id[16];
-#else
-       const char*     bus_id;
-#endif
        int phy_irq;            /* the phy irq (if it exists)  */
 
        const struct fs_mii_bus_info *bus_info;
index c415a496de3a1a08d02ddc6668cf4f49ba98a979..4e625e0094c8b5a4cbc1679f8aa81abdeba5b6fc 100644 (file)
@@ -69,6 +69,7 @@ struct gianfar_mdio_data {
 #define FSL_GIANFAR_DEV_HAS_VLAN               0x00000020
 #define FSL_GIANFAR_DEV_HAS_EXTENDED_HASH      0x00000040
 #define FSL_GIANFAR_DEV_HAS_PADDING            0x00000080
+#define FSL_GIANFAR_DEV_HAS_MAGIC_PACKET       0x00000100
 
 /* Flags in gianfar_platform_data */
 #define FSL_GIANFAR_BRD_HAS_PHY_INTR   0x00000001 /* set or use a timer */
@@ -125,4 +126,10 @@ struct mpc8xx_pcmcia_ops {
        int(*voltage_set)(int slot, int vcc, int vpp);
 };
 
+/* Returns non-zero if the current suspend operation would
+ * lead to a deep sleep (i.e. power removed from the core,
+ * instead of just the clock).
+ */
+int fsl_deep_sleep(void);
+
 #endif /* _FSL_DEVICE_H_ */
index afad95272841827445d8258043351ba0d23fcf4c..f64e29c0ef3f57be1b03aeb0703fe30f58ffbbeb 100644 (file)
@@ -68,7 +68,6 @@ struct gameport_driver {
 
 int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode);
 void gameport_close(struct gameport *gameport);
-void gameport_rescan(struct gameport *gameport);
 
 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
 
index c6d3a9de5634c1d9de24c962b4fada1aaa97b4a2..ec6ecd74781dca68bdf49c3ea1b80cc00b9d4966 100644 (file)
@@ -9,6 +9,7 @@ struct gpio_keys_button {
        char *desc;
        int type;               /* input event type (EV_KEY, EV_SW) */
        int wakeup;             /* configure the button as a wake-up source */
+       int debounce_interval;  /* debounce ticks interval in msecs */
 };
 
 struct gpio_keys_platform_data {
index fe56b86f2c67cc782eb8849324e889805cd9f849..ac4e678a04edb497f9194b7eb4939c88bf8bec10 100644 (file)
@@ -512,7 +512,7 @@ struct hid_descriptor {
 
 /* Applications from HID Usage Tables 4/8/99 Version 1.1 */
 /* We ignore a few input applications that are not widely used */
-#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001))
+#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || (a == 0x000d0002))
 
 /* HID core API */
 
index 4726126f5a59875a831084062e4430ddf73b79a3..d67ccca2b96472b229ffd264642ff420aae66cba 100644 (file)
@@ -178,6 +178,7 @@ typedef struct hw_regs_s {
        ide_ack_intr_t  *ack_intr;              /* acknowledge interrupt */
        hwif_chipset_t  chipset;
        struct device   *dev, *parent;
+       unsigned long   config;
 } hw_regs_t;
 
 void ide_init_port_data(struct hwif_s *, unsigned int);
@@ -307,7 +308,65 @@ struct ide_acpi_drive_link;
 struct ide_acpi_hwif_link;
 #endif
 
-typedef struct ide_drive_s {
+/* ATAPI device flags */
+enum {
+       IDE_AFLAG_DRQ_INTERRUPT         = (1 << 0),
+       IDE_AFLAG_MEDIA_CHANGED         = (1 << 1),
+
+       /* ide-cd */
+       /* Drive cannot lock the door. */
+       IDE_AFLAG_NO_DOORLOCK           = (1 << 2),
+       /* Drive cannot eject the disc. */
+       IDE_AFLAG_NO_EJECT              = (1 << 3),
+       /* Drive is a pre ATAPI 1.2 drive. */
+       IDE_AFLAG_PRE_ATAPI12           = (1 << 4),
+       /* TOC addresses are in BCD. */
+       IDE_AFLAG_TOCADDR_AS_BCD        = (1 << 5),
+       /* TOC track numbers are in BCD. */
+       IDE_AFLAG_TOCTRACKS_AS_BCD      = (1 << 6),
+       /*
+        * Drive does not provide data in multiples of SECTOR_SIZE
+        * when more than one interrupt is needed.
+        */
+       IDE_AFLAG_LIMIT_NFRAMES         = (1 << 7),
+       /* Seeking in progress. */
+       IDE_AFLAG_SEEKING               = (1 << 8),
+       /* Saved TOC information is current. */
+       IDE_AFLAG_TOC_VALID             = (1 << 9),
+       /* We think that the drive door is locked. */
+       IDE_AFLAG_DOOR_LOCKED           = (1 << 10),
+       /* SET_CD_SPEED command is unsupported. */
+       IDE_AFLAG_NO_SPEED_SELECT       = (1 << 11),
+       IDE_AFLAG_VERTOS_300_SSD        = (1 << 12),
+       IDE_AFLAG_VERTOS_600_ESD        = (1 << 13),
+       IDE_AFLAG_SANYO_3CD             = (1 << 14),
+       IDE_AFLAG_FULL_CAPS_PAGE        = (1 << 15),
+       IDE_AFLAG_PLAY_AUDIO_OK         = (1 << 16),
+       IDE_AFLAG_LE_SPEED_FIELDS       = (1 << 17),
+
+       /* ide-floppy */
+       /* Format in progress */
+       IDE_AFLAG_FORMAT_IN_PROGRESS    = (1 << 18),
+       /* Avoid commands not supported in Clik drive */
+       IDE_AFLAG_CLIK_DRIVE            = (1 << 19),
+       /* Requires BH algorithm for packets */
+       IDE_AFLAG_ZIP_DRIVE             = (1 << 20),
+
+       /* ide-tape */
+       IDE_AFLAG_IGNORE_DSC            = (1 << 21),
+       /* 0 When the tape position is unknown */
+       IDE_AFLAG_ADDRESS_VALID         = (1 << 22),
+       /* Device already opened */
+       IDE_AFLAG_BUSY                  = (1 << 23),
+       /* Attempt to auto-detect the current user block size */
+       IDE_AFLAG_DETECT_BS             = (1 << 24),
+       /* Currently on a filemark */
+       IDE_AFLAG_FILEMARK              = (1 << 25),
+       /* 0 = no tape is loaded, so we don't rewind after ejecting */
+       IDE_AFLAG_MEDIUM_PRESENT        = (1 << 26)
+};
+
+struct ide_drive_s {
        char            name[4];        /* drive name, such as "hda" */
         char            driver_req[10];        /* requests specific driver */
 
@@ -355,7 +414,6 @@ typedef struct ide_drive_s {
        unsigned nodma          : 1;    /* disallow DMA */
        unsigned remap_0_to_1   : 1;    /* 0=noremap, 1=remap 0->1 (for EZDrive) */
        unsigned blocked        : 1;    /* 1=powermanagment told us not to do anything, so sleep nicely */
-       unsigned vdma           : 1;    /* 1=doing PIO over DMA 0=doing normal DMA */
        unsigned scsi           : 1;    /* 0=default, 1=ide-scsi emulation */
        unsigned sleeping       : 1;    /* 1=sleeping & sleep field valid */
        unsigned post_reset     : 1;
@@ -400,7 +458,14 @@ typedef struct ide_drive_s {
        struct list_head list;
        struct device   gendev;
        struct completion gendev_rel_comp;      /* to deal with device release() */
-} ide_drive_t;
+
+       /* callback for packet commands */
+       void (*pc_callback)(struct ide_drive_s *);
+
+       unsigned long atapi_flags;
+};
+
+typedef struct ide_drive_s ide_drive_t;
 
 #define to_ide_device(dev)container_of(dev, ide_drive_t, gendev)
 
@@ -408,8 +473,28 @@ typedef struct ide_drive_s {
     ((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
 #define IDE_CHIPSET_IS_PCI(c)  ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
 
+struct ide_task_s;
 struct ide_port_info;
 
+struct ide_tp_ops {
+       void    (*exec_command)(struct hwif_s *, u8);
+       u8      (*read_status)(struct hwif_s *);
+       u8      (*read_altstatus)(struct hwif_s *);
+       u8      (*read_sff_dma_status)(struct hwif_s *);
+
+       void    (*set_irq)(struct hwif_s *, int);
+
+       void    (*tf_load)(ide_drive_t *, struct ide_task_s *);
+       void    (*tf_read)(ide_drive_t *, struct ide_task_s *);
+
+       void    (*input_data)(ide_drive_t *, struct request *, void *,
+                             unsigned int);
+       void    (*output_data)(ide_drive_t *, struct request *, void *,
+                              unsigned int);
+};
+
+extern const struct ide_tp_ops default_tp_ops;
+
 struct ide_port_ops {
        /* host specific initialization of a device */
        void    (*init_dev)(ide_drive_t *);
@@ -447,8 +532,6 @@ struct ide_dma_ops {
        void    (*dma_timeout)(struct ide_drive_s *);
 };
 
-struct ide_task_s;
-
 typedef struct hwif_s {
        struct hwif_s *next;            /* for linked-list in ide_hwgroup_t */
        struct hwif_s *mate;            /* other hwif from same PCI chip */
@@ -486,22 +569,12 @@ typedef struct hwif_s {
 
        void (*rw_disk)(ide_drive_t *, struct request *);
 
+       const struct ide_tp_ops         *tp_ops;
        const struct ide_port_ops       *port_ops;
        const struct ide_dma_ops        *dma_ops;
 
-       void (*tf_load)(ide_drive_t *, struct ide_task_s *);
-       void (*tf_read)(ide_drive_t *, struct ide_task_s *);
-
-       void (*input_data)(ide_drive_t *, struct request *, void *, unsigned);
-       void (*output_data)(ide_drive_t *, struct request *, void *, unsigned);
-
        void (*ide_dma_clear_irq)(ide_drive_t *drive);
 
-       void (*OUTB)(u8 addr, unsigned long port);
-       void (*OUTBSYNC)(struct hwif_s *hwif, u8 addr, unsigned long port);
-
-       u8  (*INB)(unsigned long port);
-
        /* dma physical region descriptor table (cpu view) */
        unsigned int    *dmatable_cpu;
        /* dma physical region descriptor table (dma view) */
@@ -524,8 +597,6 @@ typedef struct hwif_s {
        int             irq;            /* our irq number */
 
        unsigned long   dma_base;       /* base addr for dma ports */
-       unsigned long   dma_command;    /* dma command register */
-       unsigned long   dma_status;     /* dma status register */
 
        unsigned long   config_data;    /* for use by chipset-specific code */
        unsigned long   select_data;    /* for use by chipset-specific code */
@@ -552,6 +623,11 @@ typedef struct hwif_s {
 #endif
 } ____cacheline_internodealigned_in_smp ide_hwif_t;
 
+struct ide_host {
+       ide_hwif_t      *ports[MAX_HWIFS];
+       unsigned int    n_ports;
+};
+
 /*
  *  internal ide interrupt handler type
  */
@@ -611,8 +687,6 @@ enum {
        PC_FLAG_WRITING                 = (1 << 6),
        /* command timed out */
        PC_FLAG_TIMEDOUT                = (1 << 7),
-       PC_FLAG_ZIP_DRIVE               = (1 << 8),
-       PC_FLAG_DRQ_INTERRUPT           = (1 << 9),
 };
 
 struct ide_atapi_pc {
@@ -646,8 +720,6 @@ struct ide_atapi_pc {
         */
        u8 pc_buf[256];
 
-       void (*callback)(ide_drive_t *);
-
        /* idetape only */
        struct idetape_bh *bh;
        char *b_data;
@@ -807,13 +879,6 @@ int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsig
 extern int ide_vlb_clk;
 extern int ide_pci_clk;
 
-ide_hwif_t *ide_find_port_slot(const struct ide_port_info *);
-
-static inline ide_hwif_t *ide_find_port(void)
-{
-       return ide_find_port_slot(NULL);
-}
-
 extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs);
 int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
                             int uptodate, int nr_sectors);
@@ -884,6 +949,7 @@ enum {
        IDE_TFLAG_IN_HOB                = IDE_TFLAG_IN_HOB_FEATURE |
                                          IDE_TFLAG_IN_HOB_NSECT |
                                          IDE_TFLAG_IN_HOB_LBA,
+       IDE_TFLAG_IN_FEATURE            = (1 << 1),
        IDE_TFLAG_IN_NSECT              = (1 << 25),
        IDE_TFLAG_IN_LBAL               = (1 << 26),
        IDE_TFLAG_IN_LBAM               = (1 << 27),
@@ -948,9 +1014,25 @@ typedef struct ide_task_s {
 
 void ide_tf_dump(const char *, struct ide_taskfile *);
 
+void ide_exec_command(ide_hwif_t *, u8);
+u8 ide_read_status(ide_hwif_t *);
+u8 ide_read_altstatus(ide_hwif_t *);
+u8 ide_read_sff_dma_status(ide_hwif_t *);
+
+void ide_set_irq(ide_hwif_t *, int);
+
+void ide_tf_load(ide_drive_t *, ide_task_t *);
+void ide_tf_read(ide_drive_t *, ide_task_t *);
+
+void ide_input_data(ide_drive_t *, struct request *, void *, unsigned int);
+void ide_output_data(ide_drive_t *, struct request *, void *, unsigned int);
+
 extern void SELECT_DRIVE(ide_drive_t *);
 void SELECT_MASK(ide_drive_t *, int);
 
+u8 ide_read_error(ide_drive_t *);
+void ide_read_bcount_and_ireason(ide_drive_t *, u16 *, u8 *);
+
 extern int drive_is_ready(ide_drive_t *);
 
 void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8);
@@ -1000,12 +1082,15 @@ extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *o
 #define ide_pci_register_driver(d) pci_register_driver(d)
 #endif
 
-void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int, u8 *);
+void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int,
+                        hw_regs_t *, hw_regs_t **);
 void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 int ide_pci_set_master(struct pci_dev *, const char *);
 unsigned long ide_pci_dma_base(ide_hwif_t *, const struct ide_port_info *);
+extern const struct ide_dma_ops sff_dma_ops;
+int ide_pci_check_simplex(ide_hwif_t *, const struct ide_port_info *);
 int ide_hwif_setup_dma(ide_hwif_t *, const struct ide_port_info *);
 #else
 static inline int ide_hwif_setup_dma(ide_hwif_t *hwif,
@@ -1015,10 +1100,6 @@ static inline int ide_hwif_setup_dma(ide_hwif_t *hwif,
 }
 #endif
 
-extern void default_hwif_iops(ide_hwif_t *);
-extern void default_hwif_mmiops(ide_hwif_t *);
-extern void default_hwif_transport(ide_hwif_t *);
-
 typedef struct ide_pci_enablebit_s {
        u8      reg;    /* byte pci reg holding the enable-bit */
        u8      mask;   /* mask to isolate the enable-bit */
@@ -1081,7 +1162,6 @@ enum {
        IDE_HFLAG_IO_32BIT              = (1 << 24),
        /* unmask IRQs */
        IDE_HFLAG_UNMASK_IRQS           = (1 << 25),
-       IDE_HFLAG_ABUSE_SET_DMA_MODE    = (1 << 26),
        /* serialize ports if DMA is possible (for sl82c105) */
        IDE_HFLAG_SERIALIZE_DMA         = (1 << 27),
        /* force host out of "simplex" mode */
@@ -1092,8 +1172,6 @@ enum {
        IDE_HFLAG_NO_IO_32BIT           = (1 << 30),
        /* never unmask IRQs */
        IDE_HFLAG_NO_UNMASK_IRQS        = (1 << 31),
-       /* host uses VDMA (disabled for now) */
-       IDE_HFLAG_VDMA                  = 0,
 };
 
 #ifdef CONFIG_BLK_DEV_OFFBOARD
@@ -1110,6 +1188,7 @@ struct ide_port_info {
        int                     (*init_dma)(ide_hwif_t *,
                                            const struct ide_port_info *);
 
+       const struct ide_tp_ops         *tp_ops;
        const struct ide_port_ops       *port_ops;
        const struct ide_dma_ops        *dma_ops;
 
@@ -1163,7 +1242,6 @@ void ide_destroy_dmatable(ide_drive_t *);
 extern int ide_build_dmatable(ide_drive_t *, struct request *);
 int ide_allocate_dma_engine(ide_hwif_t *);
 void ide_release_dma_engine(ide_hwif_t *);
-void ide_setup_dma(ide_hwif_t *, unsigned long);
 
 void ide_dma_host_set(ide_drive_t *, int);
 extern int ide_dma_setup(ide_drive_t *);
@@ -1217,8 +1295,14 @@ void ide_undecoded_slave(ide_drive_t *);
 
 void ide_port_apply_params(ide_hwif_t *);
 
-int ide_device_add_all(u8 *idx, const struct ide_port_info *);
-int ide_device_add(u8 idx[4], const struct ide_port_info *);
+struct ide_host *ide_host_alloc_all(const struct ide_port_info *, hw_regs_t **);
+struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **);
+void ide_host_free(struct ide_host *);
+int ide_host_register(struct ide_host *, const struct ide_port_info *,
+                     hw_regs_t **);
+int ide_host_add(const struct ide_port_info *, hw_regs_t **,
+                struct ide_host **);
+void ide_host_remove(struct ide_host *);
 int ide_legacy_device_add(const struct ide_port_info *, unsigned long);
 void ide_port_unregister_devices(ide_hwif_t *);
 void ide_port_scan(ide_hwif_t *);
@@ -1350,33 +1434,4 @@ static inline ide_drive_t *ide_get_paired_drive(ide_drive_t *drive)
 
        return &hwif->drives[(drive->dn ^ 1) & 1];
 }
-
-static inline void ide_set_irq(ide_drive_t *drive, int on)
-{
-       ide_hwif_t *hwif = drive->hwif;
-
-       hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS | (on ? 0 : 2),
-                      hwif->io_ports.ctl_addr);
-}
-
-static inline u8 ide_read_status(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-
-       return hwif->INB(hwif->io_ports.status_addr);
-}
-
-static inline u8 ide_read_altstatus(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-
-       return hwif->INB(hwif->io_ports.ctl_addr);
-}
-
-static inline u8 ide_read_error(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-
-       return hwif->INB(hwif->io_ports.error_addr);
-}
 #endif /* _IDE_H */
index d150c57e5f0af8653fc2ab96d3b1e3c3a17ec5b5..a5802c9c81a47831996a93cffc00fcb7190d4089 100644 (file)
@@ -373,6 +373,8 @@ struct input_absinfo {
 
 #define KEY_WIMAX              246
 
+/* Range 248 - 255 is reserved for special needs of AT keyboard driver */
+
 #define BTN_MISC               0x100
 #define BTN_0                  0x100
 #define BTN_1                  0x101
@@ -640,6 +642,8 @@ struct input_absinfo {
 #define SW_RFKILL_ALL          0x03  /* rfkill master switch, type "any"
                                         set = radio enabled */
 #define SW_RADIO               SW_RFKILL_ALL   /* deprecated */
+#define SW_MICROPHONE_INSERT   0x04  /* set = inserted */
+#define SW_DOCK                        0x05  /* set = plugged into dock */
 #define SW_MAX                 0x0f
 #define SW_CNT                 (SW_MAX+1)
 
@@ -1215,11 +1219,6 @@ struct input_handle {
        struct list_head        h_node;
 };
 
-#define to_dev(n) container_of(n, struct input_dev, node)
-#define to_handler(n) container_of(n, struct input_handler, node)
-#define to_handle(n) container_of(n, struct input_handle, d_node)
-#define to_handle_h(n) container_of(n, struct input_handle, h_node)
-
 struct input_dev *input_allocate_device(void);
 void input_free_device(struct input_dev *dev);
 
index 391ad0843a46af6b4af10abc5b7b552a26d95c0e..641e026eee8f1e3301a3297b85b0d6bafbcaadf5 100644 (file)
@@ -123,6 +123,7 @@ struct ipv6hdr {
        struct  in6_addr        daddr;
 };
 
+#ifdef __KERNEL__
 /*
  * This structure contains configuration options per IPv6 link.
  */
@@ -167,6 +168,7 @@ struct ipv6_devconf {
        __s32           accept_dad;
        void            *sysctl;
 };
+#endif
 
 /* index values for the variables in ipv6_devconf */
 enum {
index e2d3a18af4566a9cd7dd4e1f123162d894031832..b5e051295a6779c551f40cb6715569819e15a477 100644 (file)
@@ -2,8 +2,6 @@
 #define _LINUX_JOYSTICK_H
 
 /*
- * $Id: joystick.h,v 1.3 2000/11/30 11:07:05 vojtech Exp $
- *
  *  Copyright (C) 1996-2000 Vojtech Pavlik
  *
  *  Sponsored by SuSE
index 5dc13848891b4840cc68678d6cba2f9d232b1aa0..0509c4ce485793e748054aa558e559691a6af79d 100644 (file)
 
 #define KMOD_PATH_LEN 256
 
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
 /* modprobe exit status on success, -ve on error.  Return value
  * usually useless though. */
 extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2)));
+#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
 #else
 static inline int request_module(const char * name, ...) { return -ENOSYS; }
+#define try_then_request_module(x, mod...) (x)
 #endif
 
-#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
 
 struct key;
 struct file;
index 39e709f88aa001b73d1f9e7c6a9d33edac619c1f..60f0d418ae3264c8684accf0f44cbab9c2db700e 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/wait.h>
 #include <asm/atomic.h>
 
-#define KOBJ_NAME_LEN                  20
 #define UEVENT_HELPER_PATH_LEN         256
 #define UEVENT_NUM_ENVP                        32      /* number of env pointers */
 #define UEVENT_BUFFER_SIZE             2048    /* buffer for the variables */
@@ -59,12 +58,12 @@ enum kobject_action {
 
 struct kobject {
        const char              *name;
-       struct kref             kref;
        struct list_head        entry;
        struct kobject          *parent;
        struct kset             *kset;
        struct kobj_type        *ktype;
        struct sysfs_dirent     *sd;
+       struct kref             kref;
        unsigned int state_initialized:1;
        unsigned int state_in_sysfs:1;
        unsigned int state_add_uevent_sent:1;
index f6f301e2b0f58a5f229c62c826f810c8e1177431..afc413369101998ce5010ad56b23c752c68b4870 100644 (file)
@@ -43,7 +43,6 @@ void ps2_init(struct ps2dev *ps2dev, struct serio *serio);
 int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout);
 void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout);
 int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command);
-int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command);
 int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);
 int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data);
 void ps2_cmd_aborted(struct ps2dev *ps2dev);
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
new file mode 100644 (file)
index 0000000..bb3dd05
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef MFD_CORE_H
+#define MFD_CORE_H
+/*
+ * drivers/mfd/mfd-core.h
+ *
+ * core MFD support
+ * Copyright (c) 2006 Ian Molton
+ * Copyright (c) 2007 Dmitry Baryshkov
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/platform_device.h>
+
+/*
+ * This struct describes the MFD part ("cell").
+ * After registration the copy of this structure will become the platform data
+ * of the resulting platform_device
+ */
+struct mfd_cell {
+       const char              *name;
+
+       int                     (*enable)(struct platform_device *dev);
+       int                     (*disable)(struct platform_device *dev);
+       int                     (*suspend)(struct platform_device *dev);
+       int                     (*resume)(struct platform_device *dev);
+
+       void                    *driver_data; /* driver-specific data */
+
+       /*
+        * This resources can be specified relatievly to the parent device.
+        * For accessing device you should use resources from device
+        */
+       int                     num_resources;
+       const struct resource   *resources;
+};
+
+static inline struct mfd_cell *
+mfd_get_cell(struct platform_device *pdev)
+{
+       return (struct mfd_cell *)pdev->dev.platform_data;
+}
+
+extern int mfd_add_devices(
+               struct platform_device *parent,
+               const struct mfd_cell *cells, int n_devs,
+               struct resource *mem_base,
+               int irq_base);
+
+extern void mfd_remove_devices(struct platform_device *parent);
+
+#endif
diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h
new file mode 100644 (file)
index 0000000..7cc824a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Toshiba TC6393XB SoC support
+ *
+ * Copyright(c) 2005-2006 Chris Humbert
+ * Copyright(c) 2005 Dirk Opfer
+ * Copyright(c) 2005 Ian Molton <spyro@f2s.com>
+ * Copyright(c) 2007 Dmitry Baryshkov
+ *
+ * Based on code written by Sharp/Lineo for 2.4 kernels
+ * Based on locomo.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef TC6393XB_H
+#define TC6393XB_H
+
+/* Also one should provide the CK3P6MI clock */
+struct tc6393xb_platform_data {
+       u16     scr_pll2cr;     /* PLL2 Control */
+       u16     scr_gper;       /* GP Enable */
+       u32     scr_gpo_doecr;  /* GPO Data OE Control */
+       u32     scr_gpo_dsr;    /* GPO Data Set */
+
+       int     (*enable)(struct platform_device *dev);
+       int     (*disable)(struct platform_device *dev);
+       int     (*suspend)(struct platform_device *dev);
+       int     (*resume)(struct platform_device *dev);
+
+       int     irq_base;       /* a base for cascaded irq */
+       int     gpio_base;
+
+       struct tmio_nand_data   *nand_data;
+};
+
+/*
+ * Relative to irq_base
+ */
+#define        IRQ_TC6393_NAND         0
+#define        IRQ_TC6393_MMC          1
+#define        IRQ_TC6393_OHCI         2
+#define        IRQ_TC6393_SERIAL       3
+#define        IRQ_TC6393_FB           4
+
+#define        TC6393XB_NR_IRQS        8
+
+#endif
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
new file mode 100644 (file)
index 0000000..9438d8c
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef MFD_TMIO_H
+#define MFD_TMIO_H
+
+/*
+ * data for the NAND controller
+ */
+struct tmio_nand_data {
+       struct nand_bbt_descr   *badblock_pattern;
+       struct mtd_partition    *partition;
+       unsigned int            num_partitions;
+};
+
+#define TMIO_NAND_CONFIG       "tmio-nand-config"
+#define TMIO_NAND_CONTROL      "tmio-nand-control"
+#define TMIO_NAND_IRQ          "tmio-nand"
+
+#endif
index 3e03b1acbc94a8ba7fbbd28e394f442c4710f2f9..fce15ebd0e1cb6eca3831a77bbcc0d1887c50bc6 100644 (file)
@@ -249,27 +249,30 @@ struct module
 
        /* Exported symbols */
        const struct kernel_symbol *syms;
-       unsigned int num_syms;
        const unsigned long *crcs;
+       unsigned int num_syms;
 
        /* GPL-only exported symbols. */
-       const struct kernel_symbol *gpl_syms;
        unsigned int num_gpl_syms;
+       const struct kernel_symbol *gpl_syms;
        const unsigned long *gpl_crcs;
 
+#ifdef CONFIG_UNUSED_SYMBOLS
        /* unused exported symbols. */
        const struct kernel_symbol *unused_syms;
-       unsigned int num_unused_syms;
        const unsigned long *unused_crcs;
+       unsigned int num_unused_syms;
+
        /* GPL-only, unused exported symbols. */
-       const struct kernel_symbol *unused_gpl_syms;
        unsigned int num_unused_gpl_syms;
+       const struct kernel_symbol *unused_gpl_syms;
        const unsigned long *unused_gpl_crcs;
+#endif
 
        /* symbols that will be GPL-only in the near future. */
        const struct kernel_symbol *gpl_future_syms;
-       unsigned int num_gpl_future_syms;
        const unsigned long *gpl_future_crcs;
+       unsigned int num_gpl_future_syms;
 
        /* Exception table */
        unsigned int num_exentries;
@@ -285,10 +288,10 @@ struct module
        void *module_core;
 
        /* Here are the sizes of the init and core sections */
-       unsigned long init_size, core_size;
+       unsigned int init_size, core_size;
 
        /* The size of the executable code in each section.  */
-       unsigned long init_text_size, core_text_size;
+       unsigned int init_text_size, core_text_size;
 
        /* The handle returned from unwind_add_table. */
        void *unwind_info;
@@ -300,29 +303,15 @@ struct module
 
 #ifdef CONFIG_GENERIC_BUG
        /* Support for BUG */
+       unsigned num_bugs;
        struct list_head bug_list;
        struct bug_entry *bug_table;
-       unsigned num_bugs;
-#endif
-
-#ifdef CONFIG_MODULE_UNLOAD
-       /* Reference counts */
-       struct module_ref ref[NR_CPUS];
-
-       /* What modules depend on me? */
-       struct list_head modules_which_use_me;
-
-       /* Who is waiting for us to be unloaded */
-       struct task_struct *waiter;
-
-       /* Destruction function. */
-       void (*exit)(void);
 #endif
 
 #ifdef CONFIG_KALLSYMS
        /* We keep the symbol and string tables for kallsyms. */
        Elf_Sym *symtab;
-       unsigned long num_symtab;
+       unsigned int num_symtab;
        char *strtab;
 
        /* Section attributes */
@@ -342,6 +331,21 @@ struct module
        struct marker *markers;
        unsigned int num_markers;
 #endif
+
+#ifdef CONFIG_MODULE_UNLOAD
+       /* What modules depend on me? */
+       struct list_head modules_which_use_me;
+
+       /* Who is waiting for us to be unloaded */
+       struct task_struct *waiter;
+
+       /* Destruction function. */
+       void (*exit)(void);
+
+       /* Reference counts */
+       struct module_ref ref[NR_CPUS];
+#endif
+
 };
 #ifndef MODULE_ARCH_INIT
 #define MODULE_ARCH_INIT {}
index a9fae032ba8176db0a256aea1160f3c04e78720e..9c1d95491f8b0a7d208257b39f6fd794d713be84 100644 (file)
@@ -189,7 +189,7 @@ typedef union {
 */
 
 struct map_info {
-       char *name;
+       const char *name;
        unsigned long size;
        resource_size_t phys;
 #define NO_XIP (-1UL)
index 245f9098e171cfe2bf5b27860f6be2e0365fa57f..8b5d49133ec616a80fdc7f375b95e9cc244e16cc 100644 (file)
@@ -121,7 +121,7 @@ struct mtd_info {
        u_int32_t oobavail;  // Available OOB bytes per block
 
        // Kernel-only stuff starts here.
-       char *name;
+       const char *name;
        int index;
 
        /* ecc layout structure pointer - read only ! */
index 812bcd8b436323907785b8c0c756807242c1033f..b4d056ceab96d0500d951f7b7f00bee1e1d28627 100644 (file)
@@ -996,17 +996,17 @@ static inline void netif_tx_schedule_all(struct net_device *dev)
                netif_schedule_queue(netdev_get_tx_queue(dev, i));
 }
 
+static inline void netif_tx_start_queue(struct netdev_queue *dev_queue)
+{
+       clear_bit(__QUEUE_STATE_XOFF, &dev_queue->state);
+}
+
 /**
  *     netif_start_queue - allow transmit
  *     @dev: network device
  *
  *     Allow upper layers to call the device hard_start_xmit routine.
  */
-static inline void netif_tx_start_queue(struct netdev_queue *dev_queue)
-{
-       clear_bit(__QUEUE_STATE_XOFF, &dev_queue->state);
-}
-
 static inline void netif_start_queue(struct net_device *dev)
 {
        netif_tx_start_queue(netdev_get_tx_queue(dev, 0));
@@ -1022,13 +1022,6 @@ static inline void netif_tx_start_all_queues(struct net_device *dev)
        }
 }
 
-/**
- *     netif_wake_queue - restart transmit
- *     @dev: network device
- *
- *     Allow upper layers to call the device hard_start_xmit routine.
- *     Used for flow control when transmit resources are available.
- */
 static inline void netif_tx_wake_queue(struct netdev_queue *dev_queue)
 {
 #ifdef CONFIG_NETPOLL_TRAP
@@ -1041,6 +1034,13 @@ static inline void netif_tx_wake_queue(struct netdev_queue *dev_queue)
                __netif_schedule(dev_queue->qdisc);
 }
 
+/**
+ *     netif_wake_queue - restart transmit
+ *     @dev: network device
+ *
+ *     Allow upper layers to call the device hard_start_xmit routine.
+ *     Used for flow control when transmit resources are available.
+ */
 static inline void netif_wake_queue(struct net_device *dev)
 {
        netif_tx_wake_queue(netdev_get_tx_queue(dev, 0));
@@ -1056,6 +1056,11 @@ static inline void netif_tx_wake_all_queues(struct net_device *dev)
        }
 }
 
+static inline void netif_tx_stop_queue(struct netdev_queue *dev_queue)
+{
+       set_bit(__QUEUE_STATE_XOFF, &dev_queue->state);
+}
+
 /**
  *     netif_stop_queue - stop transmitted packets
  *     @dev: network device
@@ -1063,11 +1068,6 @@ static inline void netif_tx_wake_all_queues(struct net_device *dev)
  *     Stop upper layers calling the device hard_start_xmit routine.
  *     Used for flow control when transmit resources are unavailable.
  */
-static inline void netif_tx_stop_queue(struct netdev_queue *dev_queue)
-{
-       set_bit(__QUEUE_STATE_XOFF, &dev_queue->state);
-}
-
 static inline void netif_stop_queue(struct net_device *dev)
 {
        netif_tx_stop_queue(netdev_get_tx_queue(dev, 0));
@@ -1083,17 +1083,17 @@ static inline void netif_tx_stop_all_queues(struct net_device *dev)
        }
 }
 
+static inline int netif_tx_queue_stopped(const struct netdev_queue *dev_queue)
+{
+       return test_bit(__QUEUE_STATE_XOFF, &dev_queue->state);
+}
+
 /**
  *     netif_queue_stopped - test if transmit queue is flowblocked
  *     @dev: network device
  *
  *     Test if transmit queue on device is currently unable to send.
  */
-static inline int netif_tx_queue_stopped(const struct netdev_queue *dev_queue)
-{
-       return test_bit(__QUEUE_STATE_XOFF, &dev_queue->state);
-}
-
 static inline int netif_queue_stopped(const struct net_device *dev)
 {
        return netif_tx_queue_stopped(netdev_get_tx_queue(dev, 0));
@@ -1463,13 +1463,6 @@ static inline void netif_rx_complete(struct net_device *dev,
        local_irq_restore(flags);
 }
 
-/**
- *     netif_tx_lock - grab network device transmit lock
- *     @dev: network device
- *     @cpu: cpu number of lock owner
- *
- * Get network device transmit lock
- */
 static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu)
 {
        spin_lock(&txq->_xmit_lock);
@@ -1482,6 +1475,13 @@ static inline void __netif_tx_lock_bh(struct netdev_queue *txq)
        txq->xmit_lock_owner = smp_processor_id();
 }
 
+/**
+ *     netif_tx_lock - grab network device transmit lock
+ *     @dev: network device
+ *     @cpu: cpu number of lock owner
+ *
+ * Get network device transmit lock
+ */
 static inline void netif_tx_lock(struct net_device *dev)
 {
        int cpu = smp_processor_id();
@@ -1645,6 +1645,8 @@ extern void dev_seq_stop(struct seq_file *seq, void *v);
 extern int netdev_class_create_file(struct class_attribute *class_attr);
 extern void netdev_class_remove_file(struct class_attribute *class_attr);
 
+extern char *netdev_drivername(struct net_device *dev, char *buffer, int len);
+
 extern void linkwatch_run_queue(void);
 
 extern int netdev_compute_features(unsigned long all, unsigned long one);
index bad1eb760f615b8ffbc925fe1b8f2fb215e1bfa3..885cbe282260dcb2658f9e8fe680b066809d3fbe 100644 (file)
@@ -122,7 +122,7 @@ enum ip_conntrack_events
        IPCT_NATINFO_BIT = 10,
        IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
 
-       /* Counter highest bit has been set */
+       /* Counter highest bit has been set, unused */
        IPCT_COUNTER_FILLING_BIT = 11,
        IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
 
@@ -145,12 +145,6 @@ enum ip_conntrack_expect_events {
 };
 
 #ifdef __KERNEL__
-struct ip_conntrack_counter
-{
-       u_int32_t packets;
-       u_int32_t bytes;
-};
-
 struct ip_conntrack_stat
 {
        unsigned int searched;
index 759bc043dc65a9fbf5d3646671efd21b08607551..c19595c8930491d8e0f64a2795d36cb127ee3b60 100644 (file)
@@ -115,10 +115,10 @@ enum ctattr_protoinfo_sctp {
 
 enum ctattr_counters {
        CTA_COUNTERS_UNSPEC,
-       CTA_COUNTERS_PACKETS,           /* old 64bit counters */
-       CTA_COUNTERS_BYTES,             /* old 64bit counters */
-       CTA_COUNTERS32_PACKETS,
-       CTA_COUNTERS32_BYTES,
+       CTA_COUNTERS_PACKETS,           /* 64bit counters */
+       CTA_COUNTERS_BYTES,             /* 64bit counters */
+       CTA_COUNTERS32_PACKETS,         /* old 32bit counters, unused */
+       CTA_COUNTERS32_BYTES,           /* old 32bit counters, unused */
        __CTA_COUNTERS_MAX
 };
 #define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
index a85721332924e934b6f128912f70cf65e32f5911..f661731f3cb161bfb8b1f74e8e0fec4a8facf4b0 100644 (file)
@@ -48,6 +48,9 @@ enum nfulnl_attr_type {
        NFULA_SEQ,                      /* instance-local sequence number */
        NFULA_SEQ_GLOBAL,               /* global sequence number */
        NFULA_GID,                      /* group id of socket */
+       NFULA_HWTYPE,                   /* hardware type */
+       NFULA_HWHEADER,                 /* hardware header */
+       NFULA_HWLEN,                    /* hardware header length */
 
        __NFULA_MAX
 };
index 2ee97e9877a7c40d1b0fba2b6f3e7ff88bcb686d..67db101d0eb83be9321f08498732c16f42057edc 100644 (file)
@@ -15,7 +15,7 @@
 #define __LINUX_OF_GPIO_H
 
 #include <linux/errno.h>
-#include <asm/gpio.h>
+#include <linux/gpio.h>
 
 #ifdef CONFIG_OF_GPIO
 
index d8507eb394cf6f50e4c622b53d13e0c417b6467c..119ae7b8f028cb9795fddb16a28abc7530294764 100644 (file)
 #define PCI_DEVICE_ID_INTEL_ICH9_7     0x2916
 #define PCI_DEVICE_ID_INTEL_ICH9_8     0x2918
 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
+#define PCI_DEVICE_ID_INTEL_IOAT_TBG4  0x3429
+#define PCI_DEVICE_ID_INTEL_IOAT_TBG5  0x342a
+#define PCI_DEVICE_ID_INTEL_IOAT_TBG6  0x342b
+#define PCI_DEVICE_ID_INTEL_IOAT_TBG7  0x342c
+#define PCI_DEVICE_ID_INTEL_IOAT_TBG0  0x3430
+#define PCI_DEVICE_ID_INTEL_IOAT_TBG1  0x3431
+#define PCI_DEVICE_ID_INTEL_IOAT_TBG2  0x3432
+#define PCI_DEVICE_ID_INTEL_IOAT_TBG3  0x3433
 #define PCI_DEVICE_ID_INTEL_82830_HB   0x3575
 #define PCI_DEVICE_ID_INTEL_82830_CGC  0x3577
 #define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580
index fff1d27ddb4c0ba2949d18b945f52d585f5b4469..15a9eaf4a8026101a042be7f67bd67e6d9d4411b 100644 (file)
@@ -305,8 +305,6 @@ static inline struct net *PDE_NET(struct proc_dir_entry *pde)
        return pde->parent->data;
 }
 
-struct net *get_proc_net(const struct inode *inode);
-
 struct proc_maps_private {
        struct pid *pid;
        struct task_struct *task;
index 78bfdea24a8ecd3f2465a031a7956fd8ba43f63a..e98900671ca91d7a4f76ae91ac7393f6613bd5ee 100644 (file)
@@ -221,6 +221,7 @@ struct bitmap {
        unsigned long syncchunk;
 
        __u64   events_cleared;
+       int need_sync;
 
        /* bitmap spinlock */
        spinlock_t lock;
index ba15469daf114e3eb3d75a3ba2cde1659fdfb02e..7e375111d0074b390136c56cdca76a1ce6bb5d3c 100644 (file)
@@ -16,7 +16,7 @@ struct linear_private_data
        struct linear_private_data *prev;       /* earlier version */
        dev_info_t              **hash_table;
        sector_t                hash_spacing;
-       sector_t                array_size;
+       sector_t                array_sectors;
        int                     preshift; /* shift before dividing by hash_spacing */
        dev_info_t              disks[0];
 };
index b7386ae9d288551b979a42a94ae59726563a035b..dc0e3fcb9f281b15bc9d0f040ce38a42191a4ea5 100644 (file)
@@ -95,7 +95,7 @@ extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
                        struct page *page, int rw);
 extern void md_do_sync(mddev_t *mddev);
 extern void md_new_event(mddev_t *mddev);
-extern void md_allow_write(mddev_t *mddev);
+extern int md_allow_write(mddev_t *mddev);
 extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
 
 #endif /* CONFIG_MD */
index 3dea9f545c8f337c516b1713a39e06f59ec767d3..9f2549ac0e2d0133e014739cc7c5843fcb0a4e91 100644 (file)
@@ -59,7 +59,7 @@ struct mdk_rdev_s
        int             sb_loaded;
        __u64           sb_events;
        sector_t        data_offset;    /* start of data in array */
-       sector_t        sb_offset;
+       sector_t        sb_start;       /* offset of the super block (in 512byte sectors) */
        int             sb_size;        /* bytes in the superblock */
        int             preferred_minor;        /* autorun support */
 
@@ -87,6 +87,9 @@ struct mdk_rdev_s
 #define Blocked                8               /* An error occured on an externally
                                         * managed array, don't allow writes
                                         * until it is cleared */
+#define StateChanged   9               /* Faulty or Blocked has changed during
+                                        * interrupt, so it needs to be
+                                        * notified by the thread */
        wait_queue_head_t blocked_wait;
 
        int desc_nr;                    /* descriptor index in the superblock */
@@ -147,7 +150,7 @@ struct mddev_s
        int                             raid_disks;
        int                             max_disks;
        sector_t                        size; /* used size of component devices */
-       sector_t                        array_size; /* exported array size */
+       sector_t                        array_sectors; /* exported array size */
        __u64                           events;
 
        char                            uuid[16];
@@ -188,6 +191,7 @@ struct mddev_s
         * NEEDED:   we might need to start a resync/recover
         * RUNNING:  a thread is running, or about to be started
         * SYNC:     actually doing a resync, not a recovery
+        * RECOVER:  doing recovery, or need to try it.
         * INTR:     resync needs to be aborted for some reason
         * DONE:     thread is done and is waiting to be reaped
         * REQUEST:  user-space has requested a sync (used with SYNC)
@@ -198,6 +202,7 @@ struct mddev_s
         */
 #define        MD_RECOVERY_RUNNING     0
 #define        MD_RECOVERY_SYNC        1
+#define        MD_RECOVERY_RECOVER     2
 #define        MD_RECOVERY_INTR        3
 #define        MD_RECOVERY_DONE        4
 #define        MD_RECOVERY_NEEDED      5
@@ -210,7 +215,8 @@ struct mddev_s
 
        int                             in_sync;        /* know to not need resync */
        struct mutex                    reconfig_mutex;
-       atomic_t                        active;
+       atomic_t                        active;         /* general refcount */
+       atomic_t                        openers;        /* number of active opens */
 
        int                             changed;        /* true if we might need to reread partition info */
        int                             degraded;       /* whether md should consider
@@ -227,6 +233,8 @@ struct mddev_s
        atomic_t                        recovery_active; /* blocks scheduled, but not written */
        wait_queue_head_t               recovery_wait;
        sector_t                        recovery_cp;
+       sector_t                        resync_min;     /* user requested sync
+                                                        * starts here */
        sector_t                        resync_max;     /* resync should pause
                                                         * when it gets here */
 
@@ -331,6 +339,9 @@ static inline char * mdname (mddev_t * mddev)
 #define rdev_for_each(rdev, tmp, mddev)                                \
        rdev_for_each_list(rdev, tmp, (mddev)->disks)
 
+#define rdev_for_each_rcu(rdev, mddev)                         \
+       list_for_each_entry_rcu(rdev, &((mddev)->disks), same_set)
+
 typedef struct mdk_thread_s {
        void                    (*run) (mddev_t *mddev);
        mddev_t                 *mddev;
index 3f2cd98c508bfdff781b361b1b86886bd65ddda8..8b4de4a41ff14c15f33550a2a9ad99955861c31e 100644 (file)
  */
 #define MD_RESERVED_BYTES              (64 * 1024)
 #define MD_RESERVED_SECTORS            (MD_RESERVED_BYTES / 512)
-#define MD_RESERVED_BLOCKS             (MD_RESERVED_BYTES / BLOCK_SIZE)
 
 #define MD_NEW_SIZE_SECTORS(x)         ((x & ~(MD_RESERVED_SECTORS - 1)) - MD_RESERVED_SECTORS)
-#define MD_NEW_SIZE_BLOCKS(x)          ((x & ~(MD_RESERVED_BLOCKS - 1)) - MD_RESERVED_BLOCKS)
 
 #define MD_SB_BYTES                    4096
 #define MD_SB_WORDS                    (MD_SB_BYTES / 4)
-#define MD_SB_BLOCKS                   (MD_SB_BYTES / BLOCK_SIZE)
 #define MD_SB_SECTORS                  (MD_SB_BYTES / 512)
 
 /*
index f0827d31ae6fab718158499c10aaa50979527b17..3b2672792457ff08b991acb78e619f3daa3dab6e 100644 (file)
  *    the compute block completes.
  */
 
+/*
+ * Operations state - intermediate states that are visible outside of sh->lock
+ * In general _idle indicates nothing is running, _run indicates a data
+ * processing operation is active, and _result means the data processing result
+ * is stable and can be acted upon.  For simple operations like biofill and
+ * compute that only have an _idle and _run state they are indicated with
+ * sh->state flags (STRIPE_BIOFILL_RUN and STRIPE_COMPUTE_RUN)
+ */
+/**
+ * enum check_states - handles syncing / repairing a stripe
+ * @check_state_idle - check operations are quiesced
+ * @check_state_run - check operation is running
+ * @check_state_result - set outside lock when check result is valid
+ * @check_state_compute_run - check failed and we are repairing
+ * @check_state_compute_result - set outside lock when compute result is valid
+ */
+enum check_states {
+       check_state_idle = 0,
+       check_state_run, /* parity check */
+       check_state_check_result,
+       check_state_compute_run, /* parity repair */
+       check_state_compute_result,
+};
+
+/**
+ * enum reconstruct_states - handles writing or expanding a stripe
+ */
+enum reconstruct_states {
+       reconstruct_state_idle = 0,
+       reconstruct_state_prexor_drain_run,     /* prexor-write */
+       reconstruct_state_drain_run,            /* write */
+       reconstruct_state_run,                  /* expand */
+       reconstruct_state_prexor_drain_result,
+       reconstruct_state_drain_result,
+       reconstruct_state_result,
+};
+
 struct stripe_head {
        struct hlist_node       hash;
        struct list_head        lru;                    /* inactive_list or handle_list */
@@ -169,19 +206,13 @@ struct stripe_head {
        spinlock_t              lock;
        int                     bm_seq; /* sequence number for bitmap flushes */
        int                     disks;                  /* disks in stripe */
+       enum check_states       check_state;
+       enum reconstruct_states reconstruct_state;
        /* stripe_operations
-        * @pending - pending ops flags (set for request->issue->complete)
-        * @ack - submitted ops flags (set for issue->complete)
-        * @complete - completed ops flags (set for complete)
         * @target - STRIPE_OP_COMPUTE_BLK target
-        * @count - raid5_runs_ops is set to run when this is non-zero
         */
        struct stripe_operations {
-               unsigned long      pending;
-               unsigned long      ack;
-               unsigned long      complete;
                int                target;
-               int                count;
                u32                zero_sum_result;
        } ops;
        struct r5dev {
@@ -202,6 +233,7 @@ struct stripe_head_state {
        int locked, uptodate, to_read, to_write, failed, written;
        int to_fill, compute, req_compute, non_overwrite;
        int failed_num;
+       unsigned long ops_request;
 };
 
 /* r6_state - extra state data only relevant to r6 */
@@ -228,9 +260,7 @@ struct r6_state {
 #define        R5_Wantfill     12 /* dev->toread contains a bio that needs
                                    * filling
                                    */
-#define        R5_Wantprexor   13 /* distinguish blocks ready for rmw from
-                                   * other "towrites"
-                                   */
+#define R5_Wantdrain   13 /* dev->towrite needs to be drained */
 /*
  * Write method
  */
@@ -254,8 +284,10 @@ struct r6_state {
 #define        STRIPE_EXPAND_READY     11
 #define        STRIPE_IO_STARTED       12 /* do not count towards 'bypass_count' */
 #define        STRIPE_FULL_WRITE       13 /* all blocks are set to be overwritten */
+#define        STRIPE_BIOFILL_RUN      14
+#define        STRIPE_COMPUTE_RUN      15
 /*
- * Operations flags (in issue order)
+ * Operation request flags
  */
 #define STRIPE_OP_BIOFILL      0
 #define STRIPE_OP_COMPUTE_BLK  1
@@ -263,14 +295,6 @@ struct r6_state {
 #define STRIPE_OP_BIODRAIN     3
 #define STRIPE_OP_POSTXOR      4
 #define STRIPE_OP_CHECK        5
-#define STRIPE_OP_IO           6
-
-/* modifiers to the base operations
- * STRIPE_OP_MOD_REPAIR_PD - compute the parity block and write it back
- * STRIPE_OP_MOD_DMA_CHECK - parity is not corrupted by the check
- */
-#define STRIPE_OP_MOD_REPAIR_PD 7
-#define STRIPE_OP_MOD_DMA_CHECK 8
 
 /*
  * Plugging:
index 71fc8136004892903bebc866f5aee249e0de06d7..e5996984ddd0f9d8b242f9b7219e6f9006c35548 100644 (file)
@@ -224,4 +224,42 @@ size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents,
  */
 #define SG_MAX_SINGLE_ALLOC            (PAGE_SIZE / sizeof(struct scatterlist))
 
+
+/*
+ * Mapping sg iterator
+ *
+ * Iterates over sg entries mapping page-by-page.  On each successful
+ * iteration, @miter->page points to the mapped page and
+ * @miter->length bytes of data can be accessed at @miter->addr.  As
+ * long as an interation is enclosed between start and stop, the user
+ * is free to choose control structure and when to stop.
+ *
+ * @miter->consumed is set to @miter->length on each iteration.  It
+ * can be adjusted if the user can't consume all the bytes in one go.
+ * Also, a stopped iteration can be resumed by calling next on it.
+ * This is useful when iteration needs to release all resources and
+ * continue later (e.g. at the next interrupt).
+ */
+
+#define SG_MITER_ATOMIC                (1 << 0)         /* use kmap_atomic */
+
+struct sg_mapping_iter {
+       /* the following three fields can be accessed directly */
+       struct page             *page;          /* currently mapped page */
+       void                    *addr;          /* pointer to the mapped area */
+       size_t                  length;         /* length of the mapped area */
+       size_t                  consumed;       /* number of consumed bytes */
+
+       /* these are internal states, keep away */
+       struct scatterlist      *__sg;          /* current entry */
+       unsigned int            __nents;        /* nr of remaining entries */
+       unsigned int            __offset;       /* offset within sg */
+       unsigned int            __flags;
+};
+
+void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl,
+                   unsigned int nents, unsigned int flags);
+bool sg_miter_next(struct sg_mapping_iter *miter);
+void sg_miter_stop(struct sg_mapping_iter *miter);
+
 #endif /* _LINUX_SCATTERLIST_H */
index 1941d8b5cf11cb9731342c5519ac58436e192eab..af443a08431fc271c2983aa3743709a812025e9a 100644 (file)
@@ -295,10 +295,11 @@ extern void softlockup_tick(void);
 extern void spawn_softlockup_task(void);
 extern void touch_softlockup_watchdog(void);
 extern void touch_all_softlockup_watchdogs(void);
-extern unsigned long  softlockup_thresh;
+extern unsigned int  softlockup_panic;
 extern unsigned long sysctl_hung_task_check_count;
 extern unsigned long sysctl_hung_task_timeout_secs;
 extern unsigned long sysctl_hung_task_warnings;
+extern int softlockup_thresh;
 #else
 static inline void softlockup_tick(void)
 {
index 95674d97dabda27a1cdcb361546844b2b993da26..e72716cca57700fe51ab7adff654d799e3531529 100644 (file)
@@ -175,7 +175,7 @@ static inline void serio_unpin_driver(struct serio *serio)
 #define SERIO_8042_XL  0x06
 
 /*
- * Serio types
+ * Serio protocols
  */
 #define SERIO_UNKNOWN  0x00
 #define SERIO_MSC      0x01
@@ -212,5 +212,7 @@ static inline void serio_unpin_driver(struct serio *serio)
 #define SERIO_TAOSEVM  0x34
 #define SERIO_FUJITSU  0x35
 #define SERIO_ZHENHUA  0x36
+#define SERIO_INEXIO   0x37
+#define SERIO_TOUCHIT213       0x37
 
 #endif
index 8e0556b8781c59baf0319a73760a6aa20038df7e..3827b922ba1f8b2d9f688cac0e3095c747793690 100644 (file)
@@ -5,9 +5,19 @@
 #define SMC91X_USE_16BIT (1 << 1)
 #define SMC91X_USE_32BIT (1 << 2)
 
+#define SMC91X_NOWAIT          (1 << 3)
+
+/* two bits for IO_SHIFT, let's hope later designs will keep this sane */
+#define SMC91X_IO_SHIFT_0      (0 << 4)
+#define SMC91X_IO_SHIFT_1      (1 << 4)
+#define SMC91X_IO_SHIFT_2      (2 << 4)
+#define SMC91X_IO_SHIFT_3      (3 << 4)
+#define SMC91X_IO_SHIFT(x)     (((x) >> 4) & 0x3)
+
+#define SMC91X_USE_DMA         (1 << 6)
+
 struct smc91x_platdata {
        unsigned long flags;
-       unsigned long irq_flags; /* IRQF_... */
 };
 
 #endif /* __SMC91X_H__ */
diff --git a/include/linux/spi/max7301.h b/include/linux/spi/max7301.h
new file mode 100644 (file)
index 0000000..6dfd83f
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef LINUX_SPI_MAX7301_H
+#define LINUX_SPI_MAX7301_H
+
+struct max7301_platform_data {
+       /* number assigned to the first GPIO */
+       unsigned        base;
+};
+
+#endif
index 387e428f1cdf233ab3b54b078ba34b20157b2e37..b9a76c9720844105eccc6fe89dc139dd54c8095e 100644 (file)
@@ -733,7 +733,7 @@ struct spi_board_info {
         * controller_data goes to spi_device.controller_data,
         * irq is copied too
         */
-       char            modalias[KOBJ_NAME_LEN];
+       char            modalias[32];
        const void      *platform_data;
        void            *controller_data;
        int             irq;
index 45f6bc82d317237b8f0359e529432695d217d42c..c844a229acc937e42b28d201168847e3ed789e45 100644 (file)
 #define MGSL_INTERFACE_RTS_EN   0x10
 #define MGSL_INTERFACE_LL       0x20
 #define MGSL_INTERFACE_RL       0x40
+#define MGSL_INTERFACE_MSB_FIRST 0x80
 
 typedef struct _MGSL_PARAMS
 {
index f2767bc6b73517bea32d2e34ed362a8e61b794f1..f395bb3fa2f2065375f25c51ea8221d27a4d3dc6 100644 (file)
@@ -99,8 +99,9 @@ extern void sysdev_unregister(struct sys_device *);
 
 struct sysdev_attribute { 
        struct attribute        attr;
-       ssize_t (*show)(struct sys_device *, char *);
-       ssize_t (*store)(struct sys_device *, const char *, size_t);
+       ssize_t (*show)(struct sys_device *, struct sysdev_attribute *, char *);
+       ssize_t (*store)(struct sys_device *, struct sysdev_attribute *,
+                        const char *, size_t);
 };
 
 
@@ -118,4 +119,38 @@ struct sysdev_attribute {
 extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *);
 extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *);
 
+struct sysdev_ext_attribute {
+       struct sysdev_attribute attr;
+       void *var;
+};
+
+/*
+ * Support for simple variable sysdev attributes.
+ * The pointer to the variable is stored in a sysdev_ext_attribute
+ */
+
+/* Add more types as needed */
+
+extern ssize_t sysdev_show_ulong(struct sys_device *, struct sysdev_attribute *,
+                               char *);
+extern ssize_t sysdev_store_ulong(struct sys_device *,
+                       struct sysdev_attribute *, const char *, size_t);
+extern ssize_t sysdev_show_int(struct sys_device *, struct sysdev_attribute *,
+                               char *);
+extern ssize_t sysdev_store_int(struct sys_device *,
+                       struct sysdev_attribute *, const char *, size_t);
+
+#define _SYSDEV_ULONG_ATTR(_name, _mode, _var)                         \
+       { _SYSDEV_ATTR(_name, _mode, sysdev_show_ulong, sysdev_store_ulong), \
+         &(_var) }
+#define SYSDEV_ULONG_ATTR(_name, _mode, _var)                  \
+       struct sysdev_ext_attribute attr_##_name =              \
+               _SYSDEV_ULONG_ATTR(_name, _mode, _var);
+#define _SYSDEV_INT_ATTR(_name, _mode, _var)                           \
+       { _SYSDEV_ATTR(_name, _mode, sysdev_show_int, sysdev_store_int), \
+         &(_var) }
+#define SYSDEV_INT_ATTR(_name, _mode, _var)                    \
+       struct sysdev_ext_attribute attr_##_name =              \
+               _SYSDEV_INT_ATTR(_name, _mode, _var);
+
 #endif /* _SYSDEV_H_ */
index 7858eac40aa7be8e27f9091806f2b194eabedd61..37fa24152bd810f7d9dd67b685e738179b5bfdf9 100644 (file)
@@ -101,6 +101,9 @@ void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);
 
 int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target,
                                   const char *name);
+int __must_check sysfs_create_link_nowarn(struct kobject *kobj,
+                                         struct kobject *target,
+                                         const char *name);
 void sysfs_remove_link(struct kobject *kobj, const char *name);
 
 int __must_check sysfs_create_group(struct kobject *kobj,
@@ -180,6 +183,13 @@ static inline int sysfs_create_link(struct kobject *kobj,
        return 0;
 }
 
+static inline int sysfs_create_link_nowarn(struct kobject *kobj,
+                                          struct kobject *target,
+                                          const char *name)
+{
+       return 0;
+}
+
 static inline void sysfs_remove_link(struct kobject *kobj, const char *name)
 {
 }
index 4e5833073aa679f2e7ca33420b717aa871fd843e..e3579cb086e0b46a294b437198cd4eb479dcbc5a 100644 (file)
@@ -317,8 +317,6 @@ extern void tty_wait_until_sent(struct tty_struct *tty, long timeout);
 extern int tty_check_change(struct tty_struct *tty);
 extern void stop_tty(struct tty_struct *tty);
 extern void start_tty(struct tty_struct *tty);
-extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
-extern int tty_unregister_ldisc(int disc);
 extern int tty_register_driver(struct tty_driver *driver);
 extern int tty_unregister_driver(struct tty_driver *driver);
 extern struct device *tty_register_device(struct tty_driver *driver,
@@ -383,6 +381,15 @@ extern void tty_port_init(struct tty_port *port);
 extern int tty_port_alloc_xmit_buf(struct tty_port *port);
 extern void tty_port_free_xmit_buf(struct tty_port *port);
 
+extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
+extern int tty_unregister_ldisc(int disc);
+extern int tty_set_ldisc(struct tty_struct *tty, int ldisc);
+extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty);
+extern void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty);
+extern void tty_ldisc_init(struct tty_struct *tty);
+extern void tty_ldisc_begin(void);
+/* This last one is just for the tty layer internals and shouldn't be used elsewhere */
+extern void tty_ldisc_enable(struct tty_struct *tty);
 
 
 /* n_tty.c */
index d2a003586761cbef8f5913ec49831c7cf41e7624..e1065ac0d9226c1217dfd142792e3e03f9944d40 100644 (file)
  *
  *     Optional:
  *
- * void (*break_ctl)(struct tty_stuct *tty, int state);
+ * int (*break_ctl)(struct tty_stuct *tty, int state);
  *
  *     This optional routine requests the tty driver to turn on or
  *     off BREAK status on the RS-232 port.  If state is -1,
  *     handle the following ioctls: TCSBRK, TCSBRKP, TIOCSBRK,
  *     TIOCCBRK.
  *
+ *     If the driver sets TTY_DRIVER_HARDWARE_BREAK then the interface
+ *     will also be called with actual times and the hardware is expected
+ *     to do the delay work itself. 0 and -1 are still used for on/off.
+ *
  *     Optional: Required for TCSBRK/BRKP/etc handling.
  *
  * void (*wait_until_sent)(struct tty_struct *tty, int timeout);
@@ -192,7 +196,7 @@ struct tty_operations {
        void (*stop)(struct tty_struct *tty);
        void (*start)(struct tty_struct *tty);
        void (*hangup)(struct tty_struct *tty);
-       void (*break_ctl)(struct tty_struct *tty, int state);
+       int (*break_ctl)(struct tty_struct *tty, int state);
        void (*flush_buffer)(struct tty_struct *tty);
        void (*set_ldisc)(struct tty_struct *tty);
        void (*wait_until_sent)(struct tty_struct *tty, int timeout);
@@ -285,12 +289,18 @@ extern struct tty_driver *tty_find_polling_driver(char *name, int *line);
  * TTY_DRIVER_DEVPTS_MEM -- don't use the standard arrays, instead
  *     use dynamic memory keyed through the devpts filesystem.  This
  *     is only applicable to the pty driver.
+ *
+ * TTY_DRIVER_HARDWARE_BREAK -- hardware handles break signals. Pass
+ *     the requested timeout to the caller instead of using a simple
+ *     on/off interface.
+ *
  */
 #define TTY_DRIVER_INSTALLED           0x0001
 #define TTY_DRIVER_RESET_TERMIOS       0x0002
 #define TTY_DRIVER_REAL_RAW            0x0004
 #define TTY_DRIVER_DYNAMIC_DEV         0x0008
 #define TTY_DRIVER_DEVPTS_MEM          0x0010
+#define TTY_DRIVER_HARDWARE_BREAK      0x0020
 
 /* tty driver types */
 #define TTY_DRIVER_TYPE_SYSTEM         0x0001
index 973386d439da24ffef58636347b3463c5aa038b8..cdf338d94b7f450b42fbb1a12779cdbc7c920248 100644 (file)
@@ -36,7 +36,7 @@ struct uio_mem {
        struct uio_map          *map;
 };
 
-#define MAX_UIO_MAPS   5
+#define MAX_UIO_MAPS   5
 
 struct uio_device;
 
@@ -53,6 +53,7 @@ struct uio_device;
  * @mmap:              mmap operation for this uio device
  * @open:              open operation for this uio device
  * @release:           release operation for this uio device
+ * @irqcontrol:                disable/enable irqs when 0/1 is written to /dev/uioX
  */
 struct uio_info {
        struct uio_device       *uio_dev;
@@ -66,6 +67,7 @@ struct uio_info {
        int (*mmap)(struct uio_info *info, struct vm_area_struct *vma);
        int (*open)(struct uio_info *info, struct inode *inode);
        int (*release)(struct uio_info *info, struct inode *inode);
+       int (*irqcontrol)(struct uio_info *info, s32 irq_on);
 };
 
 extern int __must_check
@@ -80,11 +82,11 @@ static inline int __must_check
 extern void uio_unregister_device(struct uio_info *info);
 extern void uio_event_notify(struct uio_info *info);
 
-/* defines for uio_device->irq */
+/* defines for uio_info->irq */
 #define UIO_IRQ_CUSTOM -1
 #define UIO_IRQ_NONE   -2
 
-/* defines for uio_device->memtype */
+/* defines for uio_mem->memtype */
 #define UIO_MEM_NONE   0
 #define UIO_MEM_PHYS   1
 #define UIO_MEM_LOGICAL        2
index c08689ea9b4bb6027cadb5ffa33b1ea3a3e43c8a..5811c5da69f938275e4ba595a23fc252b4c0fc1a 100644 (file)
@@ -160,6 +160,7 @@ struct usb_interface {
        unsigned is_active:1;           /* the interface is not suspended */
        unsigned sysfs_files_created:1; /* the sysfs attributes exist */
        unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
+       unsigned needs_binding:1;       /* needs delayed unbind/rebind */
 
        struct device dev;              /* interface specific device info */
        struct device *usb_dev;
@@ -293,7 +294,7 @@ struct usb_devmap {
 struct usb_bus {
        struct device *controller;      /* host/master side hardware */
        int busnum;                     /* Bus number (in order of reg) */
-       char *bus_name;                 /* stable id (PCI slot_name etc) */
+       const char *bus_name;           /* stable id (PCI slot_name etc) */
        u8 uses_dma;                    /* Does the host controller use DMA? */
        u8 otg_port;                    /* 0, or number of OTG/HNP port */
        unsigned is_b_host:1;           /* true during some HNP roleswitches */
@@ -497,8 +498,6 @@ extern int usb_lock_device_for_reset(struct usb_device *udev,
 
 /* USB port reset for device reinitialization */
 extern int usb_reset_device(struct usb_device *dev);
-extern int usb_reset_composite_device(struct usb_device *dev,
-               struct usb_interface *iface);
 
 extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id);
 
@@ -958,9 +957,9 @@ struct usbdrv_wrap {
  * @resume: Called when the device is being resumed by the system.
  * @reset_resume: Called when the suspended device has been reset instead
  *     of being resumed.
- * @pre_reset: Called by usb_reset_composite_device() when the device
+ * @pre_reset: Called by usb_reset_device() when the device
  *     is about to be reset.
- * @post_reset: Called by usb_reset_composite_device() after the device
+ * @post_reset: Called by usb_reset_device() after the device
  *     has been reset
  * @id_table: USB drivers use ID table to support hotplugging.
  *     Export this with MODULE_DEVICE_TABLE(usb,...).  This must be set
@@ -972,6 +971,8 @@ struct usbdrv_wrap {
  *     added to this driver by preventing the sysfs file from being created.
  * @supports_autosuspend: if set to 0, the USB core will not allow autosuspend
  *     for interfaces bound to this driver.
+ * @soft_unbind: if set to 1, the USB core will not kill URBs and disable
+ *     endpoints before calling the driver's disconnect method.
  *
  * USB interface drivers must provide a name, probe() and disconnect()
  * methods, and an id_table.  Other driver fields are optional.
@@ -1012,6 +1013,7 @@ struct usb_driver {
        struct usbdrv_wrap drvwrap;
        unsigned int no_dynamic_id:1;
        unsigned int supports_autosuspend:1;
+       unsigned int soft_unbind:1;
 };
 #define        to_usb_driver(d) container_of(d, struct usb_driver, drvwrap.driver)
 
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
new file mode 100644 (file)
index 0000000..747c3a4
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ * composite.h -- framework for usb gadgets which are composite devices
+ *
+ * Copyright (C) 2006-2008 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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        __LINUX_USB_COMPOSITE_H
+#define        __LINUX_USB_COMPOSITE_H
+
+/*
+ * This framework is an optional layer on top of the USB Gadget interface,
+ * making it easier to build (a) Composite devices, supporting multiple
+ * functions within any single configuration, and (b) Multi-configuration
+ * devices, also supporting multiple functions but without necessarily
+ * having more than one function per configuration.
+ *
+ * Example:  a device with a single configuration supporting both network
+ * link and mass storage functions is a composite device.  Those functions
+ * might alternatively be packaged in individual configurations, but in
+ * the composite model the host can use both functions at the same time.
+ */
+
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+
+struct usb_configuration;
+
+/**
+ * struct usb_function - describes one function of a configuration
+ * @name: For diagnostics, identifies the function.
+ * @strings: tables of strings, keyed by identifiers assigned during bind()
+ *     and by language IDs provided in control requests
+ * @descriptors: Table of full (or low) speed descriptors, using interface and
+ *     string identifiers assigned during @bind().  If this pointer is null,
+ *     the function will not be available at full speed (or at low speed).
+ * @hs_descriptors: Table of high speed descriptors, using interface and
+ *     string identifiers assigned during @bind().  If this pointer is null,
+ *     the function will not be available at high speed.
+ * @config: assigned when @usb_add_function() is called; this is the
+ *     configuration with which this function is associated.
+ * @bind: Before the gadget can register, all of its functions bind() to the
+ *     available resources including string and interface identifiers used
+ *     in interface or class descriptors; endpoints; I/O buffers; and so on.
+ * @unbind: Reverses @bind; called as a side effect of unregistering the
+ *     driver which added this function.
+ * @set_alt: (REQUIRED) Reconfigures altsettings; function drivers may
+ *     initialize usb_ep.driver data at this time (when it is used).
+ *     Note that setting an interface to its current altsetting resets
+ *     interface state, and that all interfaces have a disabled state.
+ * @get_alt: Returns the active altsetting.  If this is not provided,
+ *     then only altsetting zero is supported.
+ * @disable: (REQUIRED) Indicates the function should be disabled.  Reasons
+ *     include host resetting or reconfiguring the gadget, and disconnection.
+ * @setup: Used for interface-specific control requests.
+ * @suspend: Notifies functions when the host stops sending USB traffic.
+ * @resume: Notifies functions when the host restarts USB traffic.
+ *
+ * A single USB function uses one or more interfaces, and should in most
+ * cases support operation at both full and high speeds.  Each function is
+ * associated by @usb_add_function() with a one configuration; that function
+ * causes @bind() to be called so resources can be allocated as part of
+ * setting up a gadget driver.  Those resources include endpoints, which
+ * should be allocated using @usb_ep_autoconfig().
+ *
+ * To support dual speed operation, a function driver provides descriptors
+ * for both high and full speed operation.  Except in rare cases that don't
+ * involve bulk endpoints, each speed needs different endpoint descriptors.
+ *
+ * Function drivers choose their own strategies for managing instance data.
+ * The simplest strategy just declares it "static', which means the function
+ * can only be activated once.  If the function needs to be exposed in more
+ * than one configuration at a given speed, it needs to support multiple
+ * usb_function structures (one for each configuration).
+ *
+ * A more complex strategy might encapsulate a @usb_function structure inside
+ * a driver-specific instance structure to allows multiple activations.  An
+ * example of multiple activations might be a CDC ACM function that supports
+ * two or more distinct instances within the same configuration, providing
+ * several independent logical data links to a USB host.
+ */
+struct usb_function {
+       const char                      *name;
+       struct usb_gadget_strings       **strings;
+       struct usb_descriptor_header    **descriptors;
+       struct usb_descriptor_header    **hs_descriptors;
+
+       struct usb_configuration        *config;
+
+       /* REVISIT:  bind() functions can be marked __init, which
+        * makes trouble for section mismatch analysis.  See if
+        * we can't restructure things to avoid mismatching.
+        * Related:  unbind() may kfree() but bind() won't...
+        */
+
+       /* configuration management:  bind/unbind */
+       int                     (*bind)(struct usb_configuration *,
+                                       struct usb_function *);
+       void                    (*unbind)(struct usb_configuration *,
+                                       struct usb_function *);
+
+       /* runtime state management */
+       int                     (*set_alt)(struct usb_function *,
+                                       unsigned interface, unsigned alt);
+       int                     (*get_alt)(struct usb_function *,
+                                       unsigned interface);
+       void                    (*disable)(struct usb_function *);
+       int                     (*setup)(struct usb_function *,
+                                       const struct usb_ctrlrequest *);
+       void                    (*suspend)(struct usb_function *);
+       void                    (*resume)(struct usb_function *);
+
+       /* internals */
+       struct list_head                list;
+};
+
+int usb_add_function(struct usb_configuration *, struct usb_function *);
+
+int usb_interface_id(struct usb_configuration *, struct usb_function *);
+
+/**
+ * ep_choose - select descriptor endpoint at current device speed
+ * @g: gadget, connected and running at some speed
+ * @hs: descriptor to use for high speed operation
+ * @fs: descriptor to use for full or low speed operation
+ */
+static inline struct usb_endpoint_descriptor *
+ep_choose(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,
+               struct usb_endpoint_descriptor *fs)
+{
+       if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
+               return hs;
+       return fs;
+}
+
+#define        MAX_CONFIG_INTERFACES           16      /* arbitrary; max 255 */
+
+/**
+ * struct usb_configuration - represents one gadget configuration
+ * @label: For diagnostics, describes the configuration.
+ * @strings: Tables of strings, keyed by identifiers assigned during @bind()
+ *     and by language IDs provided in control requests.
+ * @descriptors: Table of descriptors preceding all function descriptors.
+ *     Examples include OTG and vendor-specific descriptors.
+ * @bind: Called from @usb_add_config() to allocate resources unique to this
+ *     configuration and to call @usb_add_function() for each function used.
+ * @unbind: Reverses @bind; called as a side effect of unregistering the
+ *     driver which added this configuration.
+ * @setup: Used to delegate control requests that aren't handled by standard
+ *     device infrastructure or directed at a specific interface.
+ * @bConfigurationValue: Copied into configuration descriptor.
+ * @iConfiguration: Copied into configuration descriptor.
+ * @bmAttributes: Copied into configuration descriptor.
+ * @bMaxPower: Copied into configuration descriptor.
+ * @cdev: assigned by @usb_add_config() before calling @bind(); this is
+ *     the device associated with this configuration.
+ *
+ * Configurations are building blocks for gadget drivers structured around
+ * function drivers.  Simple USB gadgets require only one function and one
+ * configuration, and handle dual-speed hardware by always providing the same
+ * functionality.  Slightly more complex gadgets may have more than one
+ * single-function configuration at a given speed; or have configurations
+ * that only work at one speed.
+ *
+ * Composite devices are, by definition, ones with configurations which
+ * include more than one function.
+ *
+ * The lifecycle of a usb_configuration includes allocation, initialization
+ * of the fields described above, and calling @usb_add_config() to set up
+ * internal data and bind it to a specific device.  The configuration's
+ * @bind() method is then used to initialize all the functions and then
+ * call @usb_add_function() for them.
+ *
+ * Those functions would normally be independant of each other, but that's
+ * not mandatory.  CDC WMC devices are an example where functions often
+ * depend on other functions, with some functions subsidiary to others.
+ * Such interdependency may be managed in any way, so long as all of the
+ * descriptors complete by the time the composite driver returns from
+ * its bind() routine.
+ */
+struct usb_configuration {
+       const char                      *label;
+       struct usb_gadget_strings       **strings;
+       const struct usb_descriptor_header **descriptors;
+
+       /* REVISIT:  bind() functions can be marked __init, which
+        * makes trouble for section mismatch analysis.  See if
+        * we can't restructure things to avoid mismatching...
+        */
+
+       /* configuration management:  bind/unbind */
+       int                     (*bind)(struct usb_configuration *);
+       void                    (*unbind)(struct usb_configuration *);
+       int                     (*setup)(struct usb_configuration *,
+                                       const struct usb_ctrlrequest *);
+
+       /* fields in the config descriptor */
+       u8                      bConfigurationValue;
+       u8                      iConfiguration;
+       u8                      bmAttributes;
+       u8                      bMaxPower;
+
+       struct usb_composite_dev        *cdev;
+
+       /* internals */
+       struct list_head        list;
+       struct list_head        functions;
+       u8                      next_interface_id;
+       unsigned                highspeed:1;
+       unsigned                fullspeed:1;
+       struct usb_function     *interface[MAX_CONFIG_INTERFACES];
+};
+
+int usb_add_config(struct usb_composite_dev *,
+               struct usb_configuration *);
+
+/**
+ * struct usb_composite_driver - groups configurations into a gadget
+ * @name: For diagnostics, identifies the driver.
+ * @dev: Template descriptor for the device, including default device
+ *     identifiers.
+ * @strings: tables of strings, keyed by identifiers assigned during bind()
+ *     and language IDs provided in control requests
+ * @bind: (REQUIRED) Used to allocate resources that are shared across the
+ *     whole device, such as string IDs, and add its configurations using
+ *     @usb_add_config().  This may fail by returning a negative errno
+ *     value; it should return zero on successful initialization.
+ * @unbind: Reverses @bind(); called as a side effect of unregistering
+ *     this driver.
+ *
+ * Devices default to reporting self powered operation.  Devices which rely
+ * on bus powered operation should report this in their @bind() method.
+ *
+ * Before returning from @bind, various fields in the template descriptor
+ * may be overridden.  These include the idVendor/idProduct/bcdDevice values
+ * normally to bind the appropriate host side driver, and the three strings
+ * (iManufacturer, iProduct, iSerialNumber) normally used to provide user
+ * meaningful device identifiers.  (The strings will not be defined unless
+ * they are defined in @dev and @strings.)  The correct ep0 maxpacket size
+ * is also reported, as defined by the underlying controller driver.
+ */
+struct usb_composite_driver {
+       const char                              *name;
+       const struct usb_device_descriptor      *dev;
+       struct usb_gadget_strings               **strings;
+
+       /* REVISIT:  bind() functions can be marked __init, which
+        * makes trouble for section mismatch analysis.  See if
+        * we can't restructure things to avoid mismatching...
+        */
+
+       int                     (*bind)(struct usb_composite_dev *);
+       int                     (*unbind)(struct usb_composite_dev *);
+};
+
+extern int usb_composite_register(struct usb_composite_driver *);
+extern void usb_composite_unregister(struct usb_composite_driver *);
+
+
+/**
+ * struct usb_composite_device - represents one composite usb gadget
+ * @gadget: read-only, abstracts the gadget's usb peripheral controller
+ * @req: used for control responses; buffer is pre-allocated
+ * @bufsiz: size of buffer pre-allocated in @req
+ * @config: the currently active configuration
+ *
+ * One of these devices is allocated and initialized before the
+ * associated device driver's bind() is called.
+ *
+ * OPEN ISSUE:  it appears that some WUSB devices will need to be
+ * built by combining a normal (wired) gadget with a wireless one.
+ * This revision of the gadget framework should probably try to make
+ * sure doing that won't hurt too much.
+ *
+ * One notion for how to handle Wireless USB devices involves:
+ * (a) a second gadget here, discovery mechanism TBD, but likely
+ *     needing separate "register/unregister WUSB gadget" calls;
+ * (b) updates to usb_gadget to include flags "is it wireless",
+ *     "is it wired", plus (presumably in a wrapper structure)
+ *     bandgroup and PHY info;
+ * (c) presumably a wireless_ep wrapping a usb_ep, and reporting
+ *     wireless-specific parameters like maxburst and maxsequence;
+ * (d) configurations that are specific to wireless links;
+ * (e) function drivers that understand wireless configs and will
+ *     support wireless for (additional) function instances;
+ * (f) a function to support association setup (like CBAF), not
+ *     necessarily requiring a wireless adapter;
+ * (g) composite device setup that can create one or more wireless
+ *     configs, including appropriate association setup support;
+ * (h) more, TBD.
+ */
+struct usb_composite_dev {
+       struct usb_gadget               *gadget;
+       struct usb_request              *req;
+       unsigned                        bufsiz;
+
+       struct usb_configuration        *config;
+
+       /* internals */
+       struct usb_device_descriptor    desc;
+       struct list_head                configs;
+       struct usb_composite_driver     *driver;
+       u8                              next_string_id;
+
+       spinlock_t                      lock;
+
+       /* REVISIT use and existence of lock ... */
+};
+
+extern int usb_string_id(struct usb_composite_dev *c);
+
+/* messaging utils */
+#define DBG(d, fmt, args...) \
+       dev_dbg(&(d)->gadget->dev , fmt , ## args)
+#define VDBG(d, fmt, args...) \
+       dev_vdbg(&(d)->gadget->dev , fmt , ## args)
+#define ERROR(d, fmt, args...) \
+       dev_err(&(d)->gadget->dev , fmt , ## args)
+#define WARN(d, fmt, args...) \
+       dev_warn(&(d)->gadget->dev , fmt , ## args)
+#define INFO(d, fmt, args...) \
+       dev_info(&(d)->gadget->dev , fmt , ## args)
+
+#endif /* __LINUX_USB_COMPOSITE_H */
index cf468fbdbf8e80b504ecb3ac1d798120c066ca2f..0460a746480ccf338e4f1a714099968e86e52b49 100644 (file)
@@ -33,7 +33,8 @@ struct usb_ep;
  * @short_not_ok: When reading data, makes short packets be
  *     treated as errors (queue stops advancing till cleanup).
  * @complete: Function called when request completes, so this request and
- *     its buffer may be re-used.
+ *     its buffer may be re-used.  The function will always be called with
+ *     interrupts disabled, and it must not sleep.
  *     Reads terminate with a short packet, or when the buffer fills,
  *     whichever comes first.  When writes terminate, some data bytes
  *     will usually still be in flight (often in a hardware fifo).
@@ -271,7 +272,10 @@ static inline void usb_ep_free_request(struct usb_ep *ep,
  * (Note that some USB device controllers disallow protocol stall responses
  * in some cases.)  When control responses are deferred (the response is
  * written after the setup callback returns), then usb_ep_set_halt() may be
- * used on ep0 to trigger protocol stalls.
+ * used on ep0 to trigger protocol stalls.  Depending on the controller,
+ * it may not be possible to trigger a status-stage protocol stall when the
+ * data stage is over, that is, from within the response's completion
+ * routine.
  *
  * For periodic endpoints, like interrupt or isochronous ones, the usb host
  * arranges to poll once per interval, and the gadget driver usually will
@@ -858,6 +862,25 @@ int usb_descriptor_fillbuf(void *, unsigned,
 int usb_gadget_config_buf(const struct usb_config_descriptor *config,
        void *buf, unsigned buflen, const struct usb_descriptor_header **desc);
 
+/* copy a NULL-terminated vector of descriptors */
+struct usb_descriptor_header **usb_copy_descriptors(
+               struct usb_descriptor_header **);
+
+/* return copy of endpoint descriptor given original descriptor set */
+struct usb_endpoint_descriptor *usb_find_endpoint(
+       struct usb_descriptor_header **src,
+       struct usb_descriptor_header **copy,
+       struct usb_endpoint_descriptor *match);
+
+/**
+ * usb_free_descriptors - free descriptors returned by usb_copy_descriptors()
+ * @v: vector of descriptors
+ */
+static inline void usb_free_descriptors(struct usb_descriptor_header **v)
+{
+       kfree(v);
+}
+
 /*-------------------------------------------------------------------------*/
 
 /* utility wrapping a simple endpoint selection policy */
diff --git a/include/linux/usb/irda.h b/include/linux/usb/irda.h
new file mode 100644 (file)
index 0000000..e345cea
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * USB IrDA Bridge Device Definition
+ */
+
+#ifndef __LINUX_USB_IRDA_H
+#define __LINUX_USB_IRDA_H
+
+/* This device should use Application-specific class */
+
+#define USB_SUBCLASS_IRDA                      0x02
+
+/*-------------------------------------------------------------------------*/
+
+/* Class-Specific requests (bRequest field) */
+
+#define USB_REQ_CS_IRDA_RECEIVING              1
+#define USB_REQ_CS_IRDA_CHECK_MEDIA_BUSY       3
+#define USB_REQ_CS_IRDA_RATE_SNIFF             4
+#define USB_REQ_CS_IRDA_UNICAST_LIST           5
+#define USB_REQ_CS_IRDA_GET_CLASS_DESC         6
+
+/*-------------------------------------------------------------------------*/
+
+/* Class-Specific descriptor */
+
+#define USB_DT_CS_IRDA                         0x21
+
+/*-------------------------------------------------------------------------*/
+
+/* Data sizes */
+
+#define USB_IRDA_DS_2048                       (1 << 5)
+#define USB_IRDA_DS_1024                       (1 << 4)
+#define USB_IRDA_DS_512                                (1 << 3)
+#define USB_IRDA_DS_256                                (1 << 2)
+#define USB_IRDA_DS_128                                (1 << 1)
+#define USB_IRDA_DS_64                         (1 << 0)
+
+/* Window sizes */
+
+#define USB_IRDA_WS_7                          (1 << 6)
+#define USB_IRDA_WS_6                          (1 << 5)
+#define USB_IRDA_WS_5                          (1 << 4)
+#define USB_IRDA_WS_4                          (1 << 3)
+#define USB_IRDA_WS_3                          (1 << 2)
+#define USB_IRDA_WS_2                          (1 << 1)
+#define USB_IRDA_WS_1                          (1 << 0)
+
+/* Min turnaround times in usecs */
+
+#define USB_IRDA_MTT_0                         (1 << 7)
+#define USB_IRDA_MTT_10                                (1 << 6)
+#define USB_IRDA_MTT_50                                (1 << 5)
+#define USB_IRDA_MTT_100                       (1 << 4)
+#define USB_IRDA_MTT_500                       (1 << 3)
+#define USB_IRDA_MTT_1000                      (1 << 2)
+#define USB_IRDA_MTT_5000                      (1 << 1)
+#define USB_IRDA_MTT_10000                     (1 << 0)
+
+/* Baud rates */
+
+#define USB_IRDA_BR_4000000                    (1 << 8)
+#define USB_IRDA_BR_1152000                    (1 << 7)
+#define USB_IRDA_BR_576000                     (1 << 6)
+#define USB_IRDA_BR_115200                     (1 << 5)
+#define USB_IRDA_BR_57600                      (1 << 4)
+#define USB_IRDA_BR_38400                      (1 << 3)
+#define USB_IRDA_BR_19200                      (1 << 2)
+#define USB_IRDA_BR_9600                       (1 << 1)
+#define USB_IRDA_BR_2400                       (1 << 0)
+
+/* Additional BOFs */
+
+#define USB_IRDA_AB_0                          (1 << 7)
+#define USB_IRDA_AB_1                          (1 << 6)
+#define USB_IRDA_AB_2                          (1 << 5)
+#define USB_IRDA_AB_3                          (1 << 4)
+#define USB_IRDA_AB_6                          (1 << 3)
+#define USB_IRDA_AB_12                         (1 << 2)
+#define USB_IRDA_AB_24                         (1 << 1)
+#define USB_IRDA_AB_48                         (1 << 0)
+
+/* IRDA Rate Sniff */
+
+#define USB_IRDA_RATE_SNIFF                    1
+
+/*-------------------------------------------------------------------------*/
+
+struct usb_irda_cs_descriptor {
+       __u8    bLength;
+       __u8    bDescriptorType;
+
+       __le16  bcdSpecRevision;
+       __u8    bmDataSize;
+       __u8    bmWindowSize;
+       __u8    bmMinTurnaroundTime;
+       __le16  wBaudRate;
+       __u8    bmAdditionalBOFs;
+       __u8    bIrdaRateSniff;
+       __u8    bMaxUnicastList;
+} __attribute__ ((packed));
+
+/*-------------------------------------------------------------------------*/
+
+/* Data Format */
+
+#define USB_IRDA_STATUS_MEDIA_BUSY     (1 << 7)
+
+/* The following is a 4-bit value used for both
+ * inbound and outbound headers:
+ *
+ * 0 - speed ignored
+ * 1 - 2400 bps
+ * 2 - 9600 bps
+ * 3 - 19200 bps
+ * 4 - 38400 bps
+ * 5 - 57600 bps
+ * 6 - 115200 bps
+ * 7 - 576000 bps
+ * 8 - 1.152 Mbps
+ * 9 - 5 mbps
+ * 10..15 - Reserved
+ */
+#define USB_IRDA_STATUS_LINK_SPEED     0x0f
+
+/* The following is a 4-bit value used only for
+ * outbound header:
+ *
+ * 0 - No change (BOF ignored)
+ * 1 - 48 BOFs
+ * 2 - 24 BOFs
+ * 3 - 12 BOFs
+ * 4 - 6 BOFs
+ * 5 - 3 BOFs
+ * 6 - 2 BOFs
+ * 7 - 1 BOFs
+ * 8 - 0 BOFs
+ * 9..15 - Reserved
+ */
+#define USB_IRDA_EXTRA_BOFS            0xf0
+
+struct usb_irda_inbound_header {
+       __u8            bmStatus;
+};
+
+struct usb_irda_outbound_header {
+       __u8            bmChange;
+};
+
+#endif /* __LINUX_USB_IRDA_H */
+
index 8f891cbaf9abd497f990e5ae68eabb8d2ae99971..09a3e6a7518fc2e043fd3568f95b74d822b78af6 100644 (file)
@@ -62,7 +62,7 @@
  */
 struct usb_serial_port {
        struct usb_serial       *serial;
-       struct tty_struct       *tty;
+       struct tty_port         port;
        spinlock_t              lock;
        struct mutex            mutex;
        unsigned char           number;
@@ -89,7 +89,6 @@ struct usb_serial_port {
 
        wait_queue_head_t       write_wait;
        struct work_struct      work;
-       int                     open_count;
        char                    throttled;
        char                    throttle_req;
        char                    console;
@@ -217,22 +216,27 @@ struct usb_serial_driver {
        int (*resume)(struct usb_serial *serial);
 
        /* serial function calls */
-       int  (*open)(struct usb_serial_port *port, struct file *filp);
-       void (*close)(struct usb_serial_port *port, struct file *filp);
-       int  (*write)(struct usb_serial_port *port, const unsigned char *buf,
-                     int count);
-       int  (*write_room)(struct usb_serial_port *port);
-       int  (*ioctl)(struct usb_serial_port *port, struct file *file,
+       /* Called by console with tty = NULL and by tty */
+       int  (*open)(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+       void (*close)(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
+       int  (*write)(struct tty_struct *tty, struct usb_serial_port *port,
+                       const unsigned char *buf, int count);
+       /* Called only by the tty layer */
+       int  (*write_room)(struct tty_struct *tty);
+       int  (*ioctl)(struct tty_struct *tty, struct file *file,
                      unsigned int cmd, unsigned long arg);
-       void (*set_termios)(struct usb_serial_port *port, struct ktermios *old);
-       void (*break_ctl)(struct usb_serial_port *port, int break_state);
-       int  (*chars_in_buffer)(struct usb_serial_port *port);
-       void (*throttle)(struct usb_serial_port *port);
-       void (*unthrottle)(struct usb_serial_port *port);
-       int  (*tiocmget)(struct usb_serial_port *port, struct file *file);
-       int  (*tiocmset)(struct usb_serial_port *port, struct file *file,
+       void (*set_termios)(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct ktermios *old);
+       void (*break_ctl)(struct tty_struct *tty, int break_state);
+       int  (*chars_in_buffer)(struct tty_struct *tty);
+       void (*throttle)(struct tty_struct *tty);
+       void (*unthrottle)(struct tty_struct *tty);
+       int  (*tiocmget)(struct tty_struct *tty, struct file *file);
+       int  (*tiocmset)(struct tty_struct *tty, struct file *file,
                         unsigned int set, unsigned int clear);
-
+       /* USB events */
        void (*read_int_callback)(struct urb *urb);
        void (*write_int_callback)(struct urb *urb);
        void (*read_bulk_callback)(struct urb *urb);
@@ -270,19 +274,19 @@ static inline void usb_serial_console_disconnect(struct usb_serial *serial) {}
 /* Functions needed by other parts of the usbserial core */
 extern struct usb_serial *usb_serial_get_by_index(unsigned int minor);
 extern void usb_serial_put(struct usb_serial *serial);
-extern int usb_serial_generic_open(struct usb_serial_port *port,
-                                  struct file *filp);
-extern int usb_serial_generic_write(struct usb_serial_port *port,
-                                   const unsigned char *buf, int count);
-extern void usb_serial_generic_close(struct usb_serial_port *port,
-                                    struct file *filp);
+extern int usb_serial_generic_open(struct tty_struct *tty,
+               struct usb_serial_port *port, struct file *filp);
+extern int usb_serial_generic_write(struct tty_struct *tty,
+       struct usb_serial_port *port, const unsigned char *buf, int count);
+extern void usb_serial_generic_close(struct tty_struct *tty,
+                       struct usb_serial_port *port, struct file *filp);
 extern int usb_serial_generic_resume(struct usb_serial *serial);
-extern int usb_serial_generic_write_room(struct usb_serial_port *port);
-extern int usb_serial_generic_chars_in_buffer(struct usb_serial_port *port);
+extern int usb_serial_generic_write_room(struct tty_struct *tty);
+extern int usb_serial_generic_chars_in_buffer(struct tty_struct *tty);
 extern void usb_serial_generic_read_bulk_callback(struct urb *urb);
 extern void usb_serial_generic_write_bulk_callback(struct urb *urb);
-extern void usb_serial_generic_throttle(struct usb_serial_port *port);
-extern void usb_serial_generic_unthrottle(struct usb_serial_port *port);
+extern void usb_serial_generic_throttle(struct tty_struct *tty);
+extern void usb_serial_generic_unthrottle(struct tty_struct *tty);
 extern void usb_serial_generic_shutdown(struct usb_serial *serial);
 extern int usb_serial_generic_register(int debug);
 extern void usb_serial_generic_deregister(void);
index 3118ede2c67b3f35c18b7ea326c63220c0cdc4f1..0044d9b4cb85cb711e6256858ca06221cc774cbe 100644 (file)
@@ -22,8 +22,6 @@
  *
  *  History:
  *   0.1  04.01.2000  Created
- *
- *  $Id: usbdevice_fs.h,v 1.1 2000/01/06 18:40:41 tom Exp $
  */
 
 /*****************************************************************************/
index db66c792774353ccde4d499ba38b9fc31405edff..c8effa4b1feb68eea3e20e303e05021a45874c86 100644 (file)
@@ -193,8 +193,6 @@ struct inet6_dev
        struct rcu_head         rcu;
 };
 
-extern struct ipv6_devconf ipv6_devconf;
-
 static inline void ipv6_eth_mc_map(struct in6_addr *addr, char *buf)
 {
        /*
index 9313491e3dad2212eb7a55126a07b2081e27bb6a..2f8b3c06a10198b7c51d1029965284c802a395b9 100644 (file)
@@ -68,7 +68,7 @@ extern struct rt6_info                *rt6_lookup(struct net *net,
 extern struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
                                         struct neighbour *neigh,
                                         const struct in6_addr *addr);
-extern int icmp6_dst_gc(int *more);
+extern int icmp6_dst_gc(void);
 
 extern void fib6_force_start_gc(struct net *net);
 
index 8f5b75734dd03693752d998c222670c826fbdd00..0741ad592da03d84298b46075fdf2b0e5276dac6 100644 (file)
@@ -88,7 +88,6 @@ struct nf_conn_help {
        u8 expecting[NF_CT_MAX_EXPECT_CLASSES];
 };
 
-
 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
 
@@ -111,11 +110,6 @@ struct nf_conn
        /* Timer function; drops refcnt when it goes off. */
        struct timer_list timeout;
 
-#ifdef CONFIG_NF_CT_ACCT
-       /* Accounting Information (same cache line as other written members) */
-       struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
-#endif
-
 #if defined(CONFIG_NF_CONNTRACK_MARK)
        u_int32_t mark;
 #endif
diff --git a/include/net/netfilter/nf_conntrack_acct.h b/include/net/netfilter/nf_conntrack_acct.h
new file mode 100644 (file)
index 0000000..5d5ae55
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * (C) 2008 Krzysztof Piotr Oledzki <ole@ans.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _NF_CONNTRACK_ACCT_H
+#define _NF_CONNTRACK_ACCT_H
+#include <linux/netfilter/nf_conntrack_common.h>
+#include <linux/netfilter/nf_conntrack_tuple_common.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_extend.h>
+
+struct nf_conn_counter {
+       u_int64_t packets;
+       u_int64_t bytes;
+};
+
+extern int nf_ct_acct;
+
+static inline
+struct nf_conn_counter *nf_conn_acct_find(const struct nf_conn *ct)
+{
+       return nf_ct_ext_find(ct, NF_CT_EXT_ACCT);
+}
+
+static inline
+struct nf_conn_counter *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp)
+{
+       struct nf_conn_counter *acct;
+
+       if (!nf_ct_acct)
+               return NULL;
+
+       acct = nf_ct_ext_add(ct, NF_CT_EXT_ACCT, gfp);
+       if (!acct)
+               pr_debug("failed to add accounting extension area");
+
+
+       return acct;
+};
+
+extern unsigned int
+seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir);
+
+extern int nf_conntrack_acct_init(void);
+extern void nf_conntrack_acct_fini(void);
+
+#endif /* _NF_CONNTRACK_ACCT_H */
index f80c0ed6d870f3514e39f9da71ce399927919465..da8ee52613a59f202e341fb96b1d5c6c097ab37d 100644 (file)
@@ -7,11 +7,13 @@ enum nf_ct_ext_id
 {
        NF_CT_EXT_HELPER,
        NF_CT_EXT_NAT,
+       NF_CT_EXT_ACCT,
        NF_CT_EXT_NUM,
 };
 
 #define NF_CT_EXT_HELPER_TYPE struct nf_conn_help
 #define NF_CT_EXT_NAT_TYPE struct nf_conn_nat
+#define NF_CT_EXT_ACCT_TYPE struct nf_conn_counter
 
 /* Extensions: optional stuff which isn't permanently in struct. */
 struct nf_ct_ext {
index dfc3701dfcc3ecf5c05c5ccfb02bd10363873c9c..18024b8cecb84ed5c23fdb812859f4229e80549c 100644 (file)
@@ -896,6 +896,9 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
 #define NLA_PUT_U64(skb, attrtype, value) \
        NLA_PUT_TYPE(skb, u64, attrtype, value)
 
+#define NLA_PUT_BE64(skb, attrtype, value) \
+       NLA_PUT_TYPE(skb, __be64, attrtype, value)
+
 #define NLA_PUT_STRING(skb, attrtype, value) \
        NLA_PUT(skb, attrtype, strlen(value) + 1, value)
 
index 5bacd838e88bfd7a3d5b84dcc89e74bbcad60226..2932721180c0902e5fdd42076208332a36a0242c 100644 (file)
@@ -39,7 +39,7 @@ struct netns_ipv6 {
 #endif
        struct rt6_info         *ip6_null_entry;
        struct rt6_statistics   *rt6_stats;
-       struct timer_list       *ip6_fib_timer;
+       struct timer_list       ip6_fib_timer;
        struct hlist_head       *fib_table_hash;
        struct fib6_table       *fib6_main_tbl;
        struct dst_ops          *ip6_dst_ops;
index 70eb64a7e1a17a842ec6388b3f7c542ca1852519..535a18f57a134fe9ada157e6a053761cba9d6ccb 100644 (file)
@@ -1161,7 +1161,6 @@ void sctp_outq_init(struct sctp_association *, struct sctp_outq *);
 void sctp_outq_teardown(struct sctp_outq *);
 void sctp_outq_free(struct sctp_outq*);
 int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk);
-int sctp_outq_flush(struct sctp_outq *, int);
 int sctp_outq_sack(struct sctp_outq *, struct sctp_sackhdr *);
 int sctp_outq_is_empty(const struct sctp_outq *);
 void sctp_outq_restart(struct sctp_outq *);
index 1834fdfe82a7d7129880e2a0380c2e99b77adfa3..a594bac4a77db2b5f311470cc2e2324d5cf6bedb 100644 (file)
@@ -623,7 +623,7 @@ struct Scsi_Host {
        /*
         * Optional work queue to be utilized by the transport
         */
-       char work_q_name[KOBJ_NAME_LEN];
+       char work_q_name[20];
        struct workqueue_struct *work_q;
 
        /*
index 06f72bab9df0af520039506ece89079d549178aa..878373c32ef7e434bdb6c840ca15b4ec0412d550 100644 (file)
@@ -489,9 +489,9 @@ struct fc_host_attrs {
        u16 npiv_vports_inuse;
 
        /* work queues for rport state manipulation */
-       char work_q_name[KOBJ_NAME_LEN];
+       char work_q_name[20];
        struct workqueue_struct *work_q;
-       char devloss_work_q_name[KOBJ_NAME_LEN];
+       char devloss_work_q_name[20];
        struct workqueue_struct *devloss_work_q;
 };
 
index f5444e033cc92d7c8707d3b3c59b71b9048463cd..8b6c91df4c7a9057c08aa23569838ac7358ddc89 100644 (file)
@@ -198,7 +198,7 @@ struct iscsi_cls_host {
        atomic_t nr_scans;
        struct mutex mutex;
        struct workqueue_struct *scan_workq;
-       char scan_workq_name[KOBJ_NAME_LEN];
+       char scan_workq_name[20];
 };
 
 extern void iscsi_host_for_each_session(struct Scsi_Host *shost,
index 67c4436554a9b3e80c457cd6c67437604e1613d2..4680ff3fbc91c569990e2c48bec8183ffe7888f3 100644 (file)
@@ -44,4 +44,11 @@ extern void notify_remote_via_irq(int irq);
 
 extern void xen_irq_resume(void);
 
+/* Clear an irq's pending state, in preparation for polling on it */
+void xen_clear_irq_pending(int irq);
+
+/* Poll waiting for an irq to become pending.  In the usual case, the
+   irq will be disabled so it won't deliver an interrupt. */
+void xen_poll_irq(int irq);
+
 #endif /* _XEN_EVENTS_H */
index 98b79bc404ddef529acbab64a6588c1c5998afc5..c3adde32669b49f958b816a5b3b6e757b25a078e 100644 (file)
@@ -5,11 +5,12 @@ extern struct console xenboot_console;
 
 #ifdef CONFIG_HVC_XEN
 void xen_console_resume(void);
+void xen_raw_console_write(const char *str);
+void xen_raw_printk(const char *fmt, ...);
 #else
 static inline void xen_console_resume(void) { }
+static inline void xen_raw_console_write(const char *str) { }
+static inline void xen_raw_printk(const char *fmt, ...) { }
 #endif
 
-void xen_raw_console_write(const char *str);
-void xen_raw_printk(const char *fmt, ...);
-
 #endif /* XEN_HVC_CONSOLE_H */
index 4aadcba31af9810f973760e4ae5f9fc30ada070a..2ae3cd243264c0652cbd3d3e8e815b6363ef756c 100644 (file)
@@ -82,9 +82,9 @@
  */
 #define CALLBACKOP_register                0
 struct callback_register {
-    uint16_t type;
-    uint16_t flags;
-    struct xen_callback address;
+       uint16_t type;
+       uint16_t flags;
+       xen_callback_t address;
 };
 
 /*
index a706d6a7896016c8698698ad1472a26b7551cab9..883a21bba24bac3991e79533f586679de6926a4a 100644 (file)
@@ -11,4 +11,7 @@ void xen_post_suspend(int suspend_cancelled);
 void xen_mm_pin_all(void);
 void xen_mm_unpin_all(void);
 
+void xen_timer_resume(void);
+void xen_arch_resume(void);
+
 #endif /* INCLUDE_XEN_OPS_H */
index 6199d1120900841ca57367cc33a01f36eff72d12..a50bdfed2df7664eacbb4a655b07b381caf64d99 100644 (file)
@@ -856,8 +856,8 @@ config MODULE_UNLOAD
        help
          Without this option you will not be able to unload any
          modules (note that some modules may not be unloadable
-         anyway), which makes your kernel slightly smaller and
-         simpler.  If unsure, say Y.
+         anyway), which makes your kernel smaller, faster
+         and simpler.  If unsure, say Y.
 
 config MODULE_FORCE_UNLOAD
        bool "Forced module unloading"
@@ -893,16 +893,11 @@ config MODULE_SRCVERSION_ALL
          will be created for all modules.  If unsure, say N.
 
 config KMOD
-       bool "Automatic kernel module loading"
+       def_bool y
        depends on MODULES
        help
-         Normally when you have selected some parts of the kernel to
-         be created as kernel modules, you must load them (using the
-         "modprobe" command) before you can use them. If you say Y
-         here, some parts of the kernel will be able to load modules
-         automatically: when a part of the kernel needs a module, it
-         runs modprobe with the appropriate arguments, thereby
-         loading the module if it is available.  If unsure, say Y.
+         This is being removed soon.  These days, CONFIG_MODULES
+         implies CONFIG_KMOD, so use that instead.
 
 config STOP_MACHINE
        bool
index 459d601947a82a29693bbaa7444c74542311919e..d2cc67dac8b1445b47fad8ebf120fafba62ccfdc 100644 (file)
@@ -679,7 +679,9 @@ restart:
                                if (apn == b->pn) {
                                        cpus_or(*dp, *dp, b->cpus_allowed);
                                        b->pn = -1;
-                                       update_domain_attr(dattr, b);
+                                       if (dattr)
+                                               update_domain_attr(dattr
+                                                                  + nslot, b);
                                }
                        }
                        nslot++;
index a9e6bad9f706b05f96b2e7c4e16e6cb75acd6f4e..c1ef192aa65592b6286e6c224969e8af1eed3d81 100644 (file)
@@ -65,7 +65,7 @@ lookup_exec_domain(u_long personality)
                                goto out;
        }
 
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
        read_unlock(&exec_domains_lock);
        request_module("personality-%ld", pers);
        read_lock(&exec_domains_lock);
index 77a51be360103c98c8ce3a165668ea423f69d119..3cfc0fefb5ee671e1565862f1b54ee431af4eb8a 100644 (file)
@@ -217,6 +217,17 @@ void enable_irq(unsigned int irq)
 }
 EXPORT_SYMBOL(enable_irq);
 
+int set_irq_wake_real(unsigned int irq, unsigned int on)
+{
+       struct irq_desc *desc = irq_desc + irq;
+       int ret = -ENXIO;
+
+       if (desc->chip->set_wake)
+               ret = desc->chip->set_wake(irq, on);
+
+       return ret;
+}
+
 /**
  *     set_irq_wake - control irq power management wakeup
  *     @irq:   interrupt to control
@@ -233,30 +244,34 @@ int set_irq_wake(unsigned int irq, unsigned int on)
 {
        struct irq_desc *desc = irq_desc + irq;
        unsigned long flags;
-       int ret = -ENXIO;
-       int (*set_wake)(unsigned, unsigned) = desc->chip->set_wake;
+       int ret = 0;
 
        /* wakeup-capable irqs can be shared between drivers that
         * don't need to have the same sleep mode behaviors.
         */
        spin_lock_irqsave(&desc->lock, flags);
        if (on) {
-               if (desc->wake_depth++ == 0)
-                       desc->status |= IRQ_WAKEUP;
-               else
-                       set_wake = NULL;
+               if (desc->wake_depth++ == 0) {
+                       ret = set_irq_wake_real(irq, on);
+                       if (ret)
+                               desc->wake_depth = 0;
+                       else
+                               desc->status |= IRQ_WAKEUP;
+               }
        } else {
                if (desc->wake_depth == 0) {
                        printk(KERN_WARNING "Unbalanced IRQ %d "
                                        "wake disable\n", irq);
                        WARN_ON(1);
-               } else if (--desc->wake_depth == 0)
-                       desc->status &= ~IRQ_WAKEUP;
-               else
-                       set_wake = NULL;
+               } else if (--desc->wake_depth == 0) {
+                       ret = set_irq_wake_real(irq, on);
+                       if (ret)
+                               desc->wake_depth = 1;
+                       else
+                               desc->status &= ~IRQ_WAKEUP;
+               }
        }
-       if (set_wake)
-               ret = desc->chip->set_wake(irq, on);
+
        spin_unlock_irqrestore(&desc->lock, flags);
        return ret;
 }
index 8df97d3dfda8611423d7cac323cb9ef5dce5170c..90d7af1c16554ce63c49ad64184fb6077f3b96fc 100644 (file)
@@ -42,7 +42,7 @@ extern int max_threads;
 
 static struct workqueue_struct *khelper_wq;
 
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
 
 /*
        modprobe_path is set via /proc/sys.
index 5f80478b746d4eeb1a1dc92040c1e8eacd31bc34..d8b5605132a038114c53a52279a71d7ba33c88b6 100644 (file)
@@ -70,6 +70,9 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq);
 
 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
 
+/* Bounds of module allocation, for speeding __module_text_address */
+static unsigned long module_addr_min = -1UL, module_addr_max = 0;
+
 int register_module_notifier(struct notifier_block * nb)
 {
        return blocking_notifier_chain_register(&module_notify_list, nb);
@@ -134,17 +137,19 @@ extern const struct kernel_symbol __start___ksymtab_gpl[];
 extern const struct kernel_symbol __stop___ksymtab_gpl[];
 extern const struct kernel_symbol __start___ksymtab_gpl_future[];
 extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
-extern const struct kernel_symbol __start___ksymtab_unused[];
-extern const struct kernel_symbol __stop___ksymtab_unused[];
-extern const struct kernel_symbol __start___ksymtab_unused_gpl[];
-extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];
 extern const struct kernel_symbol __start___ksymtab_gpl_future[];
 extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
 extern const unsigned long __start___kcrctab[];
 extern const unsigned long __start___kcrctab_gpl[];
 extern const unsigned long __start___kcrctab_gpl_future[];
+#ifdef CONFIG_UNUSED_SYMBOLS
+extern const struct kernel_symbol __start___ksymtab_unused[];
+extern const struct kernel_symbol __stop___ksymtab_unused[];
+extern const struct kernel_symbol __start___ksymtab_unused_gpl[];
+extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];
 extern const unsigned long __start___kcrctab_unused[];
 extern const unsigned long __start___kcrctab_unused_gpl[];
+#endif
 
 #ifndef CONFIG_MODVERSIONS
 #define symversion(base, idx) NULL
@@ -152,156 +157,186 @@ extern const unsigned long __start___kcrctab_unused_gpl[];
 #define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
 #endif
 
-/* lookup symbol in given range of kernel_symbols */
-static const struct kernel_symbol *lookup_symbol(const char *name,
-       const struct kernel_symbol *start,
-       const struct kernel_symbol *stop)
-{
-       const struct kernel_symbol *ks = start;
-       for (; ks < stop; ks++)
-               if (strcmp(ks->name, name) == 0)
-                       return ks;
-       return NULL;
-}
-
-static bool always_ok(bool gplok, bool warn, const char *name)
-{
-       return true;
-}
-
-static bool printk_unused_warning(bool gplok, bool warn, const char *name)
-{
-       if (warn) {
-               printk(KERN_WARNING "Symbol %s is marked as UNUSED, "
-                      "however this module is using it.\n", name);
-               printk(KERN_WARNING
-                      "This symbol will go away in the future.\n");
-               printk(KERN_WARNING
-                      "Please evalute if this is the right api to use and if "
-                      "it really is, submit a report the linux kernel "
-                      "mailinglist together with submitting your code for "
-                      "inclusion.\n");
-       }
-       return true;
-}
-
-static bool gpl_only_unused_warning(bool gplok, bool warn, const char *name)
-{
-       if (!gplok)
-               return false;
-       return printk_unused_warning(gplok, warn, name);
-}
-
-static bool gpl_only(bool gplok, bool warn, const char *name)
-{
-       return gplok;
-}
-
-static bool warn_if_not_gpl(bool gplok, bool warn, const char *name)
-{
-       if (!gplok && warn) {
-               printk(KERN_WARNING "Symbol %s is being used "
-                      "by a non-GPL module, which will not "
-                      "be allowed in the future\n", name);
-               printk(KERN_WARNING "Please see the file "
-                      "Documentation/feature-removal-schedule.txt "
-                      "in the kernel source tree for more details.\n");
-       }
-       return true;
-}
-
 struct symsearch {
        const struct kernel_symbol *start, *stop;
        const unsigned long *crcs;
-       bool (*check)(bool gplok, bool warn, const char *name);
+       enum {
+               NOT_GPL_ONLY,
+               GPL_ONLY,
+               WILL_BE_GPL_ONLY,
+       } licence;
+       bool unused;
 };
 
-/* Look through this array of symbol tables for a symbol match which
- * passes the check function. */
-static const struct kernel_symbol *search_symarrays(const struct symsearch *arr,
-                                                   unsigned int num,
-                                                   const char *name,
-                                                   bool gplok,
-                                                   bool warn,
-                                                   const unsigned long **crc)
+static bool each_symbol_in_section(const struct symsearch *arr,
+                                  unsigned int arrsize,
+                                  struct module *owner,
+                                  bool (*fn)(const struct symsearch *syms,
+                                             struct module *owner,
+                                             unsigned int symnum, void *data),
+                                  void *data)
 {
-       unsigned int i;
-       const struct kernel_symbol *ks;
+       unsigned int i, j;
 
-       for (i = 0; i < num; i++) {
-               ks = lookup_symbol(name, arr[i].start, arr[i].stop);
-               if (!ks || !arr[i].check(gplok, warn, name))
-                       continue;
-
-               if (crc)
-                       *crc = symversion(arr[i].crcs, ks - arr[i].start);
-               return ks;
+       for (j = 0; j < arrsize; j++) {
+               for (i = 0; i < arr[j].stop - arr[j].start; i++)
+                       if (fn(&arr[j], owner, i, data))
+                               return true;
        }
-       return NULL;
+
+       return false;
 }
 
-/* Find a symbol, return value, (optional) crc and (optional) module
- * which owns it */
-static unsigned long find_symbol(const char *name,
-                                struct module **owner,
-                                const unsigned long **crc,
-                                bool gplok,
-                                bool warn)
+/* Returns true as soon as fn returns true, otherwise false. */
+static bool each_symbol(bool (*fn)(const struct symsearch *arr,
+                                  struct module *owner,
+                                  unsigned int symnum, void *data),
+                       void *data)
 {
        struct module *mod;
-       const struct kernel_symbol *ks;
        const struct symsearch arr[] = {
                { __start___ksymtab, __stop___ksymtab, __start___kcrctab,
-                 always_ok },
+                 NOT_GPL_ONLY, false },
                { __start___ksymtab_gpl, __stop___ksymtab_gpl,
-                 __start___kcrctab_gpl, gpl_only },
+                 __start___kcrctab_gpl,
+                 GPL_ONLY, false },
                { __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future,
-                 __start___kcrctab_gpl_future, warn_if_not_gpl },
+                 __start___kcrctab_gpl_future,
+                 WILL_BE_GPL_ONLY, false },
+#ifdef CONFIG_UNUSED_SYMBOLS
                { __start___ksymtab_unused, __stop___ksymtab_unused,
-                 __start___kcrctab_unused, printk_unused_warning },
+                 __start___kcrctab_unused,
+                 NOT_GPL_ONLY, true },
                { __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl,
-                 __start___kcrctab_unused_gpl, gpl_only_unused_warning },
+                 __start___kcrctab_unused_gpl,
+                 GPL_ONLY, true },
+#endif
        };
 
-       /* Core kernel first. */
-       ks = search_symarrays(arr, ARRAY_SIZE(arr), name, gplok, warn, crc);
-       if (ks) {
-               if (owner)
-                       *owner = NULL;
-               return ks->value;
-       }
+       if (each_symbol_in_section(arr, ARRAY_SIZE(arr), NULL, fn, data))
+               return true;
 
-       /* Now try modules. */
        list_for_each_entry(mod, &modules, list) {
                struct symsearch arr[] = {
                        { mod->syms, mod->syms + mod->num_syms, mod->crcs,
-                         always_ok },
+                         NOT_GPL_ONLY, false },
                        { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
-                         mod->gpl_crcs, gpl_only },
+                         mod->gpl_crcs,
+                         GPL_ONLY, false },
                        { mod->gpl_future_syms,
                          mod->gpl_future_syms + mod->num_gpl_future_syms,
-                         mod->gpl_future_crcs, warn_if_not_gpl },
+                         mod->gpl_future_crcs,
+                         WILL_BE_GPL_ONLY, false },
+#ifdef CONFIG_UNUSED_SYMBOLS
                        { mod->unused_syms,
                          mod->unused_syms + mod->num_unused_syms,
-                         mod->unused_crcs, printk_unused_warning },
+                         mod->unused_crcs,
+                         NOT_GPL_ONLY, true },
                        { mod->unused_gpl_syms,
                          mod->unused_gpl_syms + mod->num_unused_gpl_syms,
-                         mod->unused_gpl_crcs, gpl_only_unused_warning },
+                         mod->unused_gpl_crcs,
+                         GPL_ONLY, true },
+#endif
                };
 
-               ks = search_symarrays(arr, ARRAY_SIZE(arr),
-                                     name, gplok, warn, crc);
-               if (ks) {
-                       if (owner)
-                               *owner = mod;
-                       return ks->value;
+               if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
+                       return true;
+       }
+       return false;
+}
+
+struct find_symbol_arg {
+       /* Input */
+       const char *name;
+       bool gplok;
+       bool warn;
+
+       /* Output */
+       struct module *owner;
+       const unsigned long *crc;
+       unsigned long value;
+};
+
+static bool find_symbol_in_section(const struct symsearch *syms,
+                                  struct module *owner,
+                                  unsigned int symnum, void *data)
+{
+       struct find_symbol_arg *fsa = data;
+
+       if (strcmp(syms->start[symnum].name, fsa->name) != 0)
+               return false;
+
+       if (!fsa->gplok) {
+               if (syms->licence == GPL_ONLY)
+                       return false;
+               if (syms->licence == WILL_BE_GPL_ONLY && fsa->warn) {
+                       printk(KERN_WARNING "Symbol %s is being used "
+                              "by a non-GPL module, which will not "
+                              "be allowed in the future\n", fsa->name);
+                       printk(KERN_WARNING "Please see the file "
+                              "Documentation/feature-removal-schedule.txt "
+                              "in the kernel source tree for more details.\n");
                }
        }
 
+#ifdef CONFIG_UNUSED_SYMBOLS
+       if (syms->unused && fsa->warn) {
+               printk(KERN_WARNING "Symbol %s is marked as UNUSED, "
+                      "however this module is using it.\n", fsa->name);
+               printk(KERN_WARNING
+                      "This symbol will go away in the future.\n");
+               printk(KERN_WARNING
+                      "Please evalute if this is the right api to use and if "
+                      "it really is, submit a report the linux kernel "
+                      "mailinglist together with submitting your code for "
+                      "inclusion.\n");
+       }
+#endif
+
+       fsa->owner = owner;
+       fsa->crc = symversion(syms->crcs, symnum);
+       fsa->value = syms->start[symnum].value;
+       return true;
+}
+
+/* Find a symbol, return value, (optional) crc and (optional) module
+ * which owns it */
+static unsigned long find_symbol(const char *name,
+                                struct module **owner,
+                                const unsigned long **crc,
+                                bool gplok,
+                                bool warn)
+{
+       struct find_symbol_arg fsa;
+
+       fsa.name = name;
+       fsa.gplok = gplok;
+       fsa.warn = warn;
+
+       if (each_symbol(find_symbol_in_section, &fsa)) {
+               if (owner)
+                       *owner = fsa.owner;
+               if (crc)
+                       *crc = fsa.crc;
+               return fsa.value;
+       }
+
        DEBUGP("Failed to find symbol %s\n", name);
        return -ENOENT;
 }
 
+/* lookup symbol in given range of kernel_symbols */
+static const struct kernel_symbol *lookup_symbol(const char *name,
+       const struct kernel_symbol *start,
+       const struct kernel_symbol *stop)
+{
+       const struct kernel_symbol *ks = start;
+       for (; ks < stop; ks++)
+               if (strcmp(ks->name, name) == 0)
+                       return ks;
+       return NULL;
+}
+
 /* Search for module by name: must hold module_mutex. */
 static struct module *find_module(const char *name)
 {
@@ -639,8 +674,8 @@ static int __try_stop_module(void *_sref)
 {
        struct stopref *sref = _sref;
 
-       /* If it's not unused, quit unless we are told to block. */
-       if ((sref->flags & O_NONBLOCK) && module_refcount(sref->mod) != 0) {
+       /* If it's not unused, quit unless we're forcing. */
+       if (module_refcount(sref->mod) != 0) {
                if (!(*sref->forced = try_force_unload(sref->flags)))
                        return -EWOULDBLOCK;
        }
@@ -652,9 +687,16 @@ static int __try_stop_module(void *_sref)
 
 static int try_stop_module(struct module *mod, int flags, int *forced)
 {
-       struct stopref sref = { mod, flags, forced };
+       if (flags & O_NONBLOCK) {
+               struct stopref sref = { mod, flags, forced };
 
-       return stop_machine_run(__try_stop_module, &sref, NR_CPUS);
+               return stop_machine_run(__try_stop_module, &sref, NR_CPUS);
+       } else {
+               /* We don't need to stop the machine for this. */
+               mod->state = MODULE_STATE_GOING;
+               synchronize_sched();
+               return 0;
+       }
 }
 
 unsigned int module_refcount(struct module *mod)
@@ -1445,8 +1487,10 @@ static int verify_export_symbols(struct module *mod)
                { mod->syms, mod->num_syms },
                { mod->gpl_syms, mod->num_gpl_syms },
                { mod->gpl_future_syms, mod->num_gpl_future_syms },
+#ifdef CONFIG_UNUSED_SYMBOLS
                { mod->unused_syms, mod->num_unused_syms },
                { mod->unused_gpl_syms, mod->num_unused_gpl_syms },
+#endif
        };
 
        for (i = 0; i < ARRAY_SIZE(arr); i++) {
@@ -1526,7 +1570,7 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
 }
 
 /* Update size with this section: return offset. */
-static long get_offset(unsigned long *size, Elf_Shdr *sechdr)
+static long get_offset(unsigned int *size, Elf_Shdr *sechdr)
 {
        long ret;
 
@@ -1738,6 +1782,20 @@ static inline void add_kallsyms(struct module *mod,
 }
 #endif /* CONFIG_KALLSYMS */
 
+static void *module_alloc_update_bounds(unsigned long size)
+{
+       void *ret = module_alloc(size);
+
+       if (ret) {
+               /* Update module bounds. */
+               if ((unsigned long)ret < module_addr_min)
+                       module_addr_min = (unsigned long)ret;
+               if ((unsigned long)ret + size > module_addr_max)
+                       module_addr_max = (unsigned long)ret + size;
+       }
+       return ret;
+}
+
 /* 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,
@@ -1764,10 +1822,12 @@ static struct module *load_module(void __user *umod,
        unsigned int gplfutureindex;
        unsigned int gplfuturecrcindex;
        unsigned int unwindex = 0;
+#ifdef CONFIG_UNUSED_SYMBOLS
        unsigned int unusedindex;
        unsigned int unusedcrcindex;
        unsigned int unusedgplindex;
        unsigned int unusedgplcrcindex;
+#endif
        unsigned int markersindex;
        unsigned int markersstringsindex;
        struct module *mod;
@@ -1850,13 +1910,15 @@ static struct module *load_module(void __user *umod,
        exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
        gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
        gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
-       unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused");
-       unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl");
        crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
        gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
        gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
+#ifdef CONFIG_UNUSED_SYMBOLS
+       unusedindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused");
+       unusedgplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_unused_gpl");
        unusedcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused");
        unusedgplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_unused_gpl");
+#endif
        setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
        exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
        obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
@@ -1935,7 +1997,7 @@ static struct module *load_module(void __user *umod,
        layout_sections(mod, hdr, sechdrs, secstrings);
 
        /* Do the allocs. */
-       ptr = module_alloc(mod->core_size);
+       ptr = module_alloc_update_bounds(mod->core_size);
        if (!ptr) {
                err = -ENOMEM;
                goto free_percpu;
@@ -1943,7 +2005,7 @@ static struct module *load_module(void __user *umod,
        memset(ptr, 0, mod->core_size);
        mod->module_core = ptr;
 
-       ptr = module_alloc(mod->init_size);
+       ptr = module_alloc_update_bounds(mod->init_size);
        if (!ptr && mod->init_size) {
                err = -ENOMEM;
                goto free_core;
@@ -2018,14 +2080,15 @@ static struct module *load_module(void __user *umod,
                mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
        mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
                                        sizeof(*mod->gpl_future_syms);
-       mod->num_unused_syms = sechdrs[unusedindex].sh_size /
-                                       sizeof(*mod->unused_syms);
-       mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size /
-                                       sizeof(*mod->unused_gpl_syms);
        mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
        if (gplfuturecrcindex)
                mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;
 
+#ifdef CONFIG_UNUSED_SYMBOLS
+       mod->num_unused_syms = sechdrs[unusedindex].sh_size /
+                                       sizeof(*mod->unused_syms);
+       mod->num_unused_gpl_syms = sechdrs[unusedgplindex].sh_size /
+                                       sizeof(*mod->unused_gpl_syms);
        mod->unused_syms = (void *)sechdrs[unusedindex].sh_addr;
        if (unusedcrcindex)
                mod->unused_crcs = (void *)sechdrs[unusedcrcindex].sh_addr;
@@ -2033,13 +2096,17 @@ static struct module *load_module(void __user *umod,
        if (unusedgplcrcindex)
                mod->unused_gpl_crcs
                        = (void *)sechdrs[unusedgplcrcindex].sh_addr;
+#endif
 
 #ifdef CONFIG_MODVERSIONS
-       if ((mod->num_syms && !crcindex) ||
-           (mod->num_gpl_syms && !gplcrcindex) ||
-           (mod->num_gpl_future_syms && !gplfuturecrcindex) ||
-           (mod->num_unused_syms && !unusedcrcindex) ||
-           (mod->num_unused_gpl_syms && !unusedgplcrcindex)) {
+       if ((mod->num_syms && !crcindex)
+           || (mod->num_gpl_syms && !gplcrcindex)
+           || (mod->num_gpl_future_syms && !gplfuturecrcindex)
+#ifdef CONFIG_UNUSED_SYMBOLS
+           || (mod->num_unused_syms && !unusedcrcindex)
+           || (mod->num_unused_gpl_syms && !unusedgplcrcindex)
+#endif
+               ) {
                printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name);
                err = try_to_force_load(mod, "nocrc");
                if (err)
@@ -2512,7 +2579,7 @@ static int m_show(struct seq_file *m, void *p)
        struct module *mod = list_entry(p, struct module, list);
        char buf[8];
 
-       seq_printf(m, "%s %lu",
+       seq_printf(m, "%s %u",
                   mod->name, mod->init_size + mod->core_size);
        print_unload_info(m, mod);
 
@@ -2595,6 +2662,9 @@ struct module *__module_text_address(unsigned long addr)
 {
        struct module *mod;
 
+       if (addr < module_addr_min || addr > module_addr_max)
+               return NULL;
+
        list_for_each_entry(mod, &modules, list)
                if (within(addr, mod->module_init, mod->init_text_size)
                    || within(addr, mod->module_core, mod->core_text_size))
index b45da40e8d25f6a480fb8366004fcd4de2607ef4..59dfdf1e1d2071ba29b711fbb2b34d28a57cd998 100644 (file)
@@ -82,7 +82,7 @@ config PM_SLEEP_SMP
 
 config PM_SLEEP
        bool
-       depends on SUSPEND || HIBERNATION
+       depends on SUSPEND || HIBERNATION || XEN_SAVE_RESTORE
        default y
 
 config SUSPEND
index 092e4c620af908410a30ef3ee9ece43df72dcb84..a56f629b057a75be4ff0428d265b8c833886dd85 100644 (file)
@@ -297,8 +297,8 @@ static int test_func(void *data)
  *
  * opcode:data
  */
-static ssize_t sysfs_test_command(struct sys_device *dev, const char *buf,
-                                 size_t count)
+static ssize_t sysfs_test_command(struct sys_device *dev, struct sysdev_attribute *attr,
+                                 const char *buf, size_t count)
 {
        struct sched_param schedpar;
        struct test_thread_data *td;
@@ -360,7 +360,8 @@ static ssize_t sysfs_test_command(struct sys_device *dev, const char *buf,
  * @dev:       thread to query
  * @buf:       char buffer to be filled with thread status info
  */
-static ssize_t sysfs_test_status(struct sys_device *dev, char *buf)
+static ssize_t sysfs_test_status(struct sys_device *dev, struct sysdev_attribute *attr,
+                                char *buf)
 {
        struct test_thread_data *td;
        struct task_struct *tsk;
index a6d0a7f3f7c3fd4afd6027ddeb849e4b06fbf8bb..df80bae68152984c39a21db0d0d53e3666639124 100644 (file)
@@ -7737,11 +7737,13 @@ static ssize_t sched_power_savings_store(const char *buf, size_t count, int smt)
 }
 
 #ifdef CONFIG_SCHED_MC
-static ssize_t sched_mc_power_savings_show(struct sys_device *dev, char *page)
+static ssize_t sched_mc_power_savings_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *page)
 {
        return sprintf(page, "%u\n", sched_mc_power_savings);
 }
 static ssize_t sched_mc_power_savings_store(struct sys_device *dev,
+                                           struct sysdev_attribute *attr,
                                            const char *buf, size_t count)
 {
        return sched_power_savings_store(buf, count, 0);
@@ -7751,11 +7753,13 @@ static SYSDEV_ATTR(sched_mc_power_savings, 0644, sched_mc_power_savings_show,
 #endif
 
 #ifdef CONFIG_SCHED_SMT
-static ssize_t sched_smt_power_savings_show(struct sys_device *dev, char *page)
+static ssize_t sched_smt_power_savings_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *page)
 {
        return sprintf(page, "%u\n", sched_smt_power_savings);
 }
 static ssize_t sched_smt_power_savings_store(struct sys_device *dev,
+                                            struct sysdev_attribute *attr,
                                             const char *buf, size_t count)
 {
        return sched_power_savings_store(buf, count, 1);
index a272d78185eb5901449b0e8765f33a3f5723df28..7bd8d1aadd5d3693bd881791e1130b1f603f5bce 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/delay.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
+#include <linux/lockdep.h>
 #include <linux/notifier.h>
 #include <linux/module.h>
 
@@ -25,7 +26,22 @@ static DEFINE_PER_CPU(unsigned long, print_timestamp);
 static DEFINE_PER_CPU(struct task_struct *, watchdog_task);
 
 static int __read_mostly did_panic;
-unsigned long __read_mostly softlockup_thresh = 60;
+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)
@@ -84,6 +100,14 @@ void softlockup_tick(void)
        struct pt_regs *regs = get_irq_regs();
        unsigned long now;
 
+       /* Is detection switched off? */
+       if (!per_cpu(watchdog_task, this_cpu) || softlockup_thresh <= 0) {
+               /* Be sure we don't false trigger if switched back on */
+               if (touch_timestamp)
+                       per_cpu(touch_timestamp, this_cpu) = 0;
+               return;
+       }
+
        if (touch_timestamp == 0) {
                __touch_softlockup_watchdog();
                return;
@@ -92,11 +116,8 @@ void softlockup_tick(void)
        print_timestamp = per_cpu(print_timestamp, this_cpu);
 
        /* report at most once a second */
-       if ((print_timestamp >= touch_timestamp &&
-                       print_timestamp < (touch_timestamp + 1)) ||
-                       did_panic || !per_cpu(watchdog_task, this_cpu)) {
+       if (print_timestamp == touch_timestamp || did_panic)
                return;
-       }
 
        /* do not print during early bootup: */
        if (unlikely(system_state != SYSTEM_RUNNING)) {
@@ -106,8 +127,11 @@ void softlockup_tick(void)
 
        now = get_timestamp(this_cpu);
 
-       /* Wake up the high-prio watchdog task every second: */
-       if (now > (touch_timestamp + 1))
+       /*
+        * Wake up the high-prio watchdog task twice per
+        * threshold timespan.
+        */
+       if (now > touch_timestamp + softlockup_thresh/2)
                wake_up_process(per_cpu(watchdog_task, this_cpu));
 
        /* Warn about unreasonable delays: */
@@ -121,11 +145,15 @@ void softlockup_tick(void)
                        this_cpu, now - touch_timestamp,
                        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");
 }
 
 /*
@@ -178,6 +206,9 @@ static void check_hung_task(struct task_struct *t, unsigned long now)
 
        t->last_switch_timestamp = now;
        touch_nmi_watchdog();
+
+       if (softlockup_panic)
+               panic("softlockup: blocked tasks");
 }
 
 /*
index 5b9b467de070e2b50e0e2da7b09aaacfd6cc417e..0fea0ee12da96875bca1833e0bdf1c07163531d4 100644 (file)
@@ -59,6 +59,7 @@ cond_syscall(sys_epoll_create);
 cond_syscall(sys_epoll_ctl);
 cond_syscall(sys_epoll_wait);
 cond_syscall(sys_epoll_pwait);
+cond_syscall(compat_sys_epoll_pwait);
 cond_syscall(sys_semget);
 cond_syscall(sys_semop);
 cond_syscall(sys_semtimedop);
index 6b16e16428d8f57febcb2e67dde5b6c2fd211a4e..2a7b9d88706b41072e4a8fa7cec9a61d1e1e3381 100644 (file)
@@ -88,12 +88,13 @@ extern int rcutorture_runnable;
 #endif /* #ifdef CONFIG_RCU_TORTURE_TEST */
 
 /* Constants used for minimum and  maximum */
-#if defined(CONFIG_DETECT_SOFTLOCKUP) || defined(CONFIG_HIGHMEM)
+#if defined(CONFIG_HIGHMEM) || defined(CONFIG_DETECT_SOFTLOCKUP)
 static int one = 1;
 #endif
 
 #ifdef CONFIG_DETECT_SOFTLOCKUP
 static int sixty = 60;
+static int neg_one = -1;
 #endif
 
 #ifdef CONFIG_MMU
@@ -110,7 +111,7 @@ static int min_percpu_pagelist_fract = 8;
 
 static int ngroups_max = NGROUPS_MAX;
 
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
 extern char modprobe_path[];
 #endif
 #ifdef CONFIG_CHR_DEV_SG
@@ -475,7 +476,7 @@ static struct ctl_table kern_table[] = {
                .proc_handler   = &ftrace_enable_sysctl,
        },
 #endif
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
        {
                .ctl_name       = KERN_MODPROBE,
                .procname       = "modprobe",
@@ -737,15 +738,26 @@ static struct ctl_table kern_table[] = {
        },
 #endif
 #ifdef CONFIG_DETECT_SOFTLOCKUP
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "softlockup_panic",
+               .data           = &softlockup_panic,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_minmax,
+               .strategy       = &sysctl_intvec,
+               .extra1         = &zero,
+               .extra2         = &one,
+       },
        {
                .ctl_name       = CTL_UNNUMBERED,
                .procname       = "softlockup_thresh",
                .data           = &softlockup_thresh,
-               .maxlen         = sizeof(unsigned long),
+               .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_doulongvec_minmax,
+               .proc_handler   = &proc_dointvec_minmax,
                .strategy       = &sysctl_intvec,
-               .extra1         = &one,
+               .extra1         = &neg_one,
                .extra2         = &sixty,
        },
        {
index 60ceabd53f2ead02e3c04045efc72aa1eac58ba5..093d4acf993b73fde0d575a4e29b06db88935942 100644 (file)
@@ -376,7 +376,8 @@ void clocksource_unregister(struct clocksource *cs)
  * Provides sysfs interface for listing current clocksource.
  */
 static ssize_t
-sysfs_show_current_clocksources(struct sys_device *dev, char *buf)
+sysfs_show_current_clocksources(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        ssize_t count = 0;
 
@@ -397,6 +398,7 @@ sysfs_show_current_clocksources(struct sys_device *dev, char *buf)
  * clocksource selction.
  */
 static ssize_t sysfs_override_clocksource(struct sys_device *dev,
+                                         struct sysdev_attribute *attr,
                                          const char *buf, size_t count)
 {
        struct clocksource *ovr = NULL;
@@ -449,7 +451,9 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
  * Provides sysfs interface for listing registered clocksources
  */
 static ssize_t
-sysfs_show_available_clocksources(struct sys_device *dev, char *buf)
+sysfs_show_available_clocksources(struct sys_device *dev,
+                                 struct sysdev_attribute *attr,
+                                 char *buf)
 {
        struct clocksource *src;
        ssize_t count = 0;
index beef7ccdf842f3cea9994c19b879baa06f3e94f5..942fc7c85283af6592eefc8b8c4baa028bb13c1f 100644 (file)
@@ -140,8 +140,6 @@ void tick_nohz_update_jiffies(void)
        if (!ts->tick_stopped)
                return;
 
-       touch_softlockup_watchdog();
-
        cpu_clear(cpu, nohz_cpu_mask);
        now = ktime_get();
        ts->idle_waketime = now;
@@ -149,6 +147,8 @@ void tick_nohz_update_jiffies(void)
        local_irq_save(flags);
        tick_do_update_jiffies64(now);
        local_irq_restore(flags);
+
+       touch_softlockup_watchdog();
 }
 
 void tick_nohz_stop_idle(int cpu)
index df27132a56f437eacdf53cde9caf93162d87d1d0..882c51048993010ae70049f2628deaa552645ddb 100644 (file)
@@ -74,6 +74,9 @@ config DEBUG_FS
          debugging files into.  Enable this option to be able to read and
          write to these files.
 
+         For detailed documentation on the debugfs API, see
+         Documentation/DocBook/filesystems.
+
          If unsure, say N.
 
 config HEADERS_CHECK
@@ -147,7 +150,7 @@ config DETECT_SOFTLOCKUP
        help
          Say Y here to enable the kernel to detect "soft lockups",
          which are bugs that cause the kernel to loop in kernel
-         mode for more than 10 seconds, without giving other tasks a
+         mode for more than 60 seconds, without giving other tasks a
          chance to run.
 
          When a soft-lockup is detected, the kernel will print the
@@ -159,6 +162,30 @@ config DETECT_SOFTLOCKUP
           can be detected via the NMI-watchdog, on platforms that
           support it.)
 
+config BOOTPARAM_SOFTLOCKUP_PANIC
+       bool "Panic (Reboot) On Soft Lockups"
+       depends on DETECT_SOFTLOCKUP
+       help
+         Say Y here to enable the kernel to panic on "soft lockups",
+         which are bugs that cause the kernel to loop in kernel
+         mode for more than 60 seconds, without giving other tasks a
+         chance to run.
+
+         The panic can be used in combination with panic_timeout,
+         to cause the system to reboot automatically after a
+         lockup has been detected. This feature is useful for
+         high-availability systems that have uptime guarantees and
+         where a lockup must be resolved ASAP.
+
+         Say N if unsure.
+
+config BOOTPARAM_SOFTLOCKUP_PANIC_VALUE
+       int
+       depends on DETECT_SOFTLOCKUP
+       range 0 1
+       default 0 if !BOOTPARAM_SOFTLOCKUP_PANIC
+       default 1 if BOOTPARAM_SOFTLOCKUP_PANIC
+
 config SCHED_DEBUG
        bool "Collect scheduler debugging info"
        depends on DEBUG_KERNEL && PROC_FS
index a5d4b1dac2a574ed09870e2ce25b2e300f07a1d5..2cfd2721f7ed17f0e1e199082616c861bdd3c63e 100644 (file)
@@ -1,7 +1,4 @@
 
-config HAVE_ARCH_KGDB_SHADOW_INFO
-       bool
-
 config HAVE_ARCH_KGDB
        bool
 
index dcade0543bd2a2395ede8f91bf33438348e54f7e..744401571ed76cbd48717f1aa1970804fc33cd9a 100644 (file)
@@ -216,13 +216,19 @@ static int kobject_add_internal(struct kobject *kobj)
 static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
                                  va_list vargs)
 {
-       /* Free the old name, if necessary. */
-       kfree(kobj->name);
+       const char *old_name = kobj->name;
+       char *s;
 
        kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs);
        if (!kobj->name)
                return -ENOMEM;
 
+       /* ewww... some of these buggers have '/' in the name ... */
+       s = strchr(kobj->name, '/');
+       if (s)
+               s[0] = '!';
+
+       kfree(old_name);
        return 0;
 }
 
index 2fa545a631607dc1d0498a7c2bff592ad7d115bb..9f8d599459d11011c0d9b5a7a11030af7c6e2f51 100644 (file)
@@ -245,7 +245,8 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
                if (retval)
                        goto exit;
 
-               call_usermodehelper(argv[0], argv, env->envp, UMH_WAIT_EXEC);
+               retval = call_usermodehelper(argv[0], argv,
+                                            env->envp, UMH_WAIT_EXEC);
        }
 
 exit:
index b80c21100d783ceeee87fa828600d90b322120ab..876ba6d5b6704921866d25cc47b899a045fbe6c3 100644 (file)
@@ -294,6 +294,117 @@ int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask)
 }
 EXPORT_SYMBOL(sg_alloc_table);
 
+/**
+ * sg_miter_start - start mapping iteration over a sg list
+ * @miter: sg mapping iter to be started
+ * @sgl: sg list to iterate over
+ * @nents: number of sg entries
+ *
+ * Description:
+ *   Starts mapping iterator @miter.
+ *
+ * Context:
+ *   Don't care.
+ */
+void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl,
+                   unsigned int nents, unsigned int flags)
+{
+       memset(miter, 0, sizeof(struct sg_mapping_iter));
+
+       miter->__sg = sgl;
+       miter->__nents = nents;
+       miter->__offset = 0;
+       miter->__flags = flags;
+}
+EXPORT_SYMBOL(sg_miter_start);
+
+/**
+ * sg_miter_next - proceed mapping iterator to the next mapping
+ * @miter: sg mapping iter to proceed
+ *
+ * Description:
+ *   Proceeds @miter@ to the next mapping.  @miter@ should have been
+ *   started using sg_miter_start().  On successful return,
+ *   @miter@->page, @miter@->addr and @miter@->length point to the
+ *   current mapping.
+ *
+ * Context:
+ *   IRQ disabled if SG_MITER_ATOMIC.  IRQ must stay disabled till
+ *   @miter@ is stopped.  May sleep if !SG_MITER_ATOMIC.
+ *
+ * Returns:
+ *   true if @miter contains the next mapping.  false if end of sg
+ *   list is reached.
+ */
+bool sg_miter_next(struct sg_mapping_iter *miter)
+{
+       unsigned int off, len;
+
+       /* check for end and drop resources from the last iteration */
+       if (!miter->__nents)
+               return false;
+
+       sg_miter_stop(miter);
+
+       /* get to the next sg if necessary.  __offset is adjusted by stop */
+       if (miter->__offset == miter->__sg->length && --miter->__nents) {
+               miter->__sg = sg_next(miter->__sg);
+               miter->__offset = 0;
+       }
+
+       /* map the next page */
+       off = miter->__sg->offset + miter->__offset;
+       len = miter->__sg->length - miter->__offset;
+
+       miter->page = nth_page(sg_page(miter->__sg), off >> PAGE_SHIFT);
+       off &= ~PAGE_MASK;
+       miter->length = min_t(unsigned int, len, PAGE_SIZE - off);
+       miter->consumed = miter->length;
+
+       if (miter->__flags & SG_MITER_ATOMIC)
+               miter->addr = kmap_atomic(miter->page, KM_BIO_SRC_IRQ) + off;
+       else
+               miter->addr = kmap(miter->page) + off;
+
+       return true;
+}
+EXPORT_SYMBOL(sg_miter_next);
+
+/**
+ * sg_miter_stop - stop mapping iteration
+ * @miter: sg mapping iter to be stopped
+ *
+ * Description:
+ *   Stops mapping iterator @miter.  @miter should have been started
+ *   started using sg_miter_start().  A stopped iteration can be
+ *   resumed by calling sg_miter_next() on it.  This is useful when
+ *   resources (kmap) need to be released during iteration.
+ *
+ * Context:
+ *   IRQ disabled if the SG_MITER_ATOMIC is set.  Don't care otherwise.
+ */
+void sg_miter_stop(struct sg_mapping_iter *miter)
+{
+       WARN_ON(miter->consumed > miter->length);
+
+       /* drop resources from the last iteration */
+       if (miter->addr) {
+               miter->__offset += miter->consumed;
+
+               if (miter->__flags & SG_MITER_ATOMIC) {
+                       WARN_ON(!irqs_disabled());
+                       kunmap_atomic(miter->addr, KM_BIO_SRC_IRQ);
+               } else
+                       kunmap(miter->addr);
+
+               miter->page = NULL;
+               miter->addr = NULL;
+               miter->length = 0;
+               miter->consumed = 0;
+       }
+}
+EXPORT_SYMBOL(sg_miter_stop);
+
 /**
  * sg_copy_buffer - Copy data between a linear buffer and an SG list
  * @sgl:                The SG list
@@ -309,56 +420,29 @@ EXPORT_SYMBOL(sg_alloc_table);
 static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents,
                             void *buf, size_t buflen, int to_buffer)
 {
-       struct scatterlist *sg;
-       size_t buf_off = 0;
-       int i;
-
-       WARN_ON(!irqs_disabled());
-
-       for_each_sg(sgl, sg, nents, i) {
-               struct page *page;
-               int n = 0;
-               unsigned int sg_off = sg->offset;
-               unsigned int sg_copy = sg->length;
-
-               if (sg_copy > buflen)
-                       sg_copy = buflen;
-               buflen -= sg_copy;
-
-               while (sg_copy > 0) {
-                       unsigned int page_copy;
-                       void *p;
-
-                       page_copy = PAGE_SIZE - sg_off;
-                       if (page_copy > sg_copy)
-                               page_copy = sg_copy;
-
-                       page = nth_page(sg_page(sg), n);
-                       p = kmap_atomic(page, KM_BIO_SRC_IRQ);
-
-                       if (to_buffer)
-                               memcpy(buf + buf_off, p + sg_off, page_copy);
-                       else {
-                               memcpy(p + sg_off, buf + buf_off, page_copy);
-                               flush_kernel_dcache_page(page);
-                       }
-
-                       kunmap_atomic(p, KM_BIO_SRC_IRQ);
-
-                       buf_off += page_copy;
-                       sg_off += page_copy;
-                       if (sg_off == PAGE_SIZE) {
-                               sg_off = 0;
-                               n++;
-                       }
-                       sg_copy -= page_copy;
+       unsigned int offset = 0;
+       struct sg_mapping_iter miter;
+
+       sg_miter_start(&miter, sgl, nents, SG_MITER_ATOMIC);
+
+       while (sg_miter_next(&miter) && offset < buflen) {
+               unsigned int len;
+
+               len = min(miter.length, buflen - offset);
+
+               if (to_buffer)
+                       memcpy(buf + offset, miter.addr, len);
+               else {
+                       memcpy(miter.addr, buf + offset, len);
+                       flush_kernel_dcache_page(miter.page);
                }
 
-               if (!buflen)
-                       break;
+               offset += len;
        }
 
-       return buf_off;
+       sg_miter_stop(&miter);
+
+       return offset;
 }
 
 /**
index 4b7c6075256f60e02cbf144029f00142e7411fa4..9fbcb44c554f9edbb2b2b439c20d5e18362cdc6d 100644 (file)
@@ -267,7 +267,7 @@ struct ts_config *textsearch_prepare(const char *algo, const void *pattern,
                return ERR_PTR(-EINVAL);
 
        ops = lookup_ts_algo(algo);
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
        /*
         * Why not always autoload you may ask. Some users are
         * in a situation where requesting a module may deadlock,
index 35ab38a94b46279dc018c14841452f533313702b..6d4a49c1ff2fc27bef0616c03016394d551fc5be 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -492,7 +492,7 @@ static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p)
        if (p > addr + 16)
                print_section("Bytes b4", p - 16, 16);
 
-       print_section("Object", p, min(s->objsize, 128));
+       print_section("Object", p, min_t(unsigned long, s->objsize, PAGE_SIZE));
 
        if (s->flags & SLAB_RED_ZONE)
                print_section("Redzone", p + s->objsize,
@@ -1495,15 +1495,7 @@ static void flush_cpu_slab(void *d)
 
 static void flush_all(struct kmem_cache *s)
 {
-#ifdef CONFIG_SMP
        on_each_cpu(flush_cpu_slab, s, 1);
-#else
-       unsigned long flags;
-
-       local_irq_save(flags);
-       flush_cpu_slab(s);
-       local_irq_restore(flags);
-#endif
 }
 
 /*
index f42bc2b26b85d39ccc20cc59ac6abab807d4158c..4bf014e51f8c5ef0bf91ded6e6d074bb6291d60d 100644 (file)
@@ -569,6 +569,7 @@ static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
  * separate class since they always nest.
  */
 static struct lock_class_key vlan_netdev_xmit_lock_key;
+static struct lock_class_key vlan_netdev_addr_lock_key;
 
 static void vlan_dev_set_lockdep_one(struct net_device *dev,
                                     struct netdev_queue *txq,
@@ -581,6 +582,9 @@ static void vlan_dev_set_lockdep_one(struct net_device *dev,
 
 static void vlan_dev_set_lockdep_class(struct net_device *dev, int subclass)
 {
+       lockdep_set_class_and_subclass(&dev->addr_list_lock,
+                                      &vlan_netdev_addr_lock_key,
+                                      subclass);
        netdev_for_each_tx_queue(dev, vlan_dev_set_lockdep_one, &subclass);
 }
 
index 844ca5f1b2d4d9457dbb24542b4d36e40b586c7c..c85bf8f678dc5f1456788d3ebce5212627211912 100644 (file)
@@ -398,10 +398,6 @@ int hci_register_sysfs(struct hci_dev *hdev)
                if (device_create_file(dev, bt_attrs[i]) < 0)
                        BT_ERR("Failed to create device attribute");
 
-       if (sysfs_create_link(&bt_class->subsys.kobj,
-                               &dev->kobj, kobject_name(&dev->kobj)) < 0)
-               BT_ERR("Failed to create class symlink");
-
        return 0;
 }
 
@@ -409,9 +405,6 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
 {
        BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
-       sysfs_remove_link(&bt_class->subsys.kobj,
-                                       kobject_name(&hdev->dev.kobj));
-
        device_del(&hdev->dev);
 }
 
index 106d5e6d987c6fe47d6b24552e5eeb17b4d141bf..7463a2150b092b85630bd278de12e2ce0c7632af 100644 (file)
 #include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/in.h>
+#include <linux/jhash.h>
+#include <linux/random.h>
 
 #include "net-sysfs.h"
 
@@ -259,7 +261,7 @@ static RAW_NOTIFIER_HEAD(netdev_chain);
 
 DEFINE_PER_CPU(struct softnet_data, softnet_data);
 
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
+#ifdef CONFIG_LOCKDEP
 /*
  * register_netdevice() inits txq->_xmit_lock and sets lockdep class
  * according to dev->type
@@ -299,6 +301,7 @@ static const char *netdev_lock_name[] =
         "_xmit_NONE"};
 
 static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)];
+static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)];
 
 static inline unsigned short netdev_lock_pos(unsigned short dev_type)
 {
@@ -311,8 +314,8 @@ static inline unsigned short netdev_lock_pos(unsigned short dev_type)
        return ARRAY_SIZE(netdev_lock_type) - 1;
 }
 
-static inline void netdev_set_lockdep_class(spinlock_t *lock,
-                                           unsigned short dev_type)
+static inline void netdev_set_xmit_lockdep_class(spinlock_t *lock,
+                                                unsigned short dev_type)
 {
        int i;
 
@@ -320,9 +323,22 @@ static inline void netdev_set_lockdep_class(spinlock_t *lock,
        lockdep_set_class_and_name(lock, &netdev_xmit_lock_key[i],
                                   netdev_lock_name[i]);
 }
+
+static inline void netdev_set_addr_lockdep_class(struct net_device *dev)
+{
+       int i;
+
+       i = netdev_lock_pos(dev->type);
+       lockdep_set_class_and_name(&dev->addr_list_lock,
+                                  &netdev_addr_lock_key[i],
+                                  netdev_lock_name[i]);
+}
 #else
-static inline void netdev_set_lockdep_class(spinlock_t *lock,
-                                           unsigned short dev_type)
+static inline void netdev_set_xmit_lockdep_class(spinlock_t *lock,
+                                                unsigned short dev_type)
+{
+}
+static inline void netdev_set_addr_lockdep_class(struct net_device *dev)
 {
 }
 #endif
@@ -1325,7 +1341,8 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 
 void __netif_schedule(struct Qdisc *q)
 {
-       BUG_ON(q == &noop_qdisc);
+       if (WARN_ON_ONCE(q == &noop_qdisc))
+               return;
 
        if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state)) {
                struct softnet_data *sd;
@@ -1642,60 +1659,37 @@ out_kfree_skb:
        return 0;
 }
 
-/**
- *     dev_queue_xmit - transmit a buffer
- *     @skb: buffer to transmit
- *
- *     Queue a buffer for transmission to a network device. The caller must
- *     have set the device and priority and built the buffer before calling
- *     this function. The function can be called from an interrupt.
- *
- *     A negative errno code is returned on a failure. A success does not
- *     guarantee the frame will be transmitted as it may be dropped due
- *     to congestion or traffic shaping.
- *
- * -----------------------------------------------------------------------------------
- *      I notice this method can also return errors from the queue disciplines,
- *      including NET_XMIT_DROP, which is a positive value.  So, errors can also
- *      be positive.
- *
- *      Regardless of the return value, the skb is consumed, so it is currently
- *      difficult to retry a send to this method.  (You can bump the ref count
- *      before sending to hold a reference for retry if you are careful.)
- *
- *      When calling this method, interrupts MUST be enabled.  This is because
- *      the BH enable code must have IRQs enabled so that it will not deadlock.
- *          --BLG
- */
+static u32 simple_tx_hashrnd;
+static int simple_tx_hashrnd_initialized = 0;
 
 static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
 {
-       u32 *addr, *ports, hash, ihl;
+       u32 addr1, addr2, ports;
+       u32 hash, ihl;
        u8 ip_proto;
-       int alen;
+
+       if (unlikely(!simple_tx_hashrnd_initialized)) {
+               get_random_bytes(&simple_tx_hashrnd, 4);
+               simple_tx_hashrnd_initialized = 1;
+       }
 
        switch (skb->protocol) {
        case __constant_htons(ETH_P_IP):
                ip_proto = ip_hdr(skb)->protocol;
-               addr = &ip_hdr(skb)->saddr;
+               addr1 = ip_hdr(skb)->saddr;
+               addr2 = ip_hdr(skb)->daddr;
                ihl = ip_hdr(skb)->ihl;
-               alen = 2;
                break;
        case __constant_htons(ETH_P_IPV6):
                ip_proto = ipv6_hdr(skb)->nexthdr;
-               addr = &ipv6_hdr(skb)->saddr.s6_addr32[0];
+               addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3];
+               addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3];
                ihl = (40 >> 2);
-               alen = 8;
                break;
        default:
                return 0;
        }
 
-       ports = (u32 *) (skb_network_header(skb) + (ihl * 4));
-
-       hash = 0;
-       while (alen--)
-               hash ^= *addr++;
 
        switch (ip_proto) {
        case IPPROTO_TCP:
@@ -1705,14 +1699,17 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
        case IPPROTO_AH:
        case IPPROTO_SCTP:
        case IPPROTO_UDPLITE:
-               hash ^= *ports;
+               ports = *((u32 *) (skb_network_header(skb) + (ihl * 4)));
                break;
 
        default:
+               ports = 0;
                break;
        }
 
-       return hash % dev->real_num_tx_queues;
+       hash = jhash_3words(addr1, addr2, ports, simple_tx_hashrnd);
+
+       return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32);
 }
 
 static struct netdev_queue *dev_pick_tx(struct net_device *dev,
@@ -1729,6 +1726,31 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev,
        return netdev_get_tx_queue(dev, queue_index);
 }
 
+/**
+ *     dev_queue_xmit - transmit a buffer
+ *     @skb: buffer to transmit
+ *
+ *     Queue a buffer for transmission to a network device. The caller must
+ *     have set the device and priority and built the buffer before calling
+ *     this function. The function can be called from an interrupt.
+ *
+ *     A negative errno code is returned on a failure. A success does not
+ *     guarantee the frame will be transmitted as it may be dropped due
+ *     to congestion or traffic shaping.
+ *
+ * -----------------------------------------------------------------------------------
+ *      I notice this method can also return errors from the queue disciplines,
+ *      including NET_XMIT_DROP, which is a positive value.  So, errors can also
+ *      be positive.
+ *
+ *      Regardless of the return value, the skb is consumed, so it is currently
+ *      difficult to retry a send to this method.  (You can bump the ref count
+ *      before sending to hold a reference for retry if you are careful.)
+ *
+ *      When calling this method, interrupts MUST be enabled.  This is because
+ *      the BH enable code must have IRQs enabled so that it will not deadlock.
+ *          --BLG
+ */
 int dev_queue_xmit(struct sk_buff *skb)
 {
        struct net_device *dev = skb->dev;
@@ -3843,7 +3865,7 @@ static void __netdev_init_queue_locks_one(struct net_device *dev,
                                          void *_unused)
 {
        spin_lock_init(&dev_queue->_xmit_lock);
-       netdev_set_lockdep_class(&dev_queue->_xmit_lock, dev->type);
+       netdev_set_xmit_lockdep_class(&dev_queue->_xmit_lock, dev->type);
        dev_queue->xmit_lock_owner = -1;
 }
 
@@ -3888,6 +3910,7 @@ int register_netdevice(struct net_device *dev)
        net = dev_net(dev);
 
        spin_lock_init(&dev->addr_list_lock);
+       netdev_set_addr_lockdep_class(dev);
        netdev_init_queue_locks(dev);
 
        dev->iflink = -1;
@@ -4198,7 +4221,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
 {
        struct netdev_queue *tx;
        struct net_device *dev;
-       int alloc_size;
+       size_t alloc_size;
        void *p;
 
        BUG_ON(strlen(name) >= sizeof(dev->name));
@@ -4218,7 +4241,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
                return NULL;
        }
 
-       tx = kzalloc(sizeof(struct netdev_queue) * queue_count, GFP_KERNEL);
+       tx = kcalloc(queue_count, sizeof(struct netdev_queue), GFP_KERNEL);
        if (!tx) {
                printk(KERN_ERR "alloc_netdev: Unable to allocate "
                       "tx qdiscs.\n");
@@ -4677,6 +4700,26 @@ err_name:
        return -ENOMEM;
 }
 
+char *netdev_drivername(struct net_device *dev, char *buffer, int len)
+{
+       struct device_driver *driver;
+       struct device *parent;
+
+       if (len <= 0 || !buffer)
+               return buffer;
+       buffer[0] = 0;
+
+       parent = dev->dev.parent;
+
+       if (!parent)
+               return buffer;
+
+       driver = parent->driver;
+       if (driver && driver->name)
+               strlcpy(buffer, driver->name, len);
+       return buffer;
+}
+
 static void __net_exit netdev_exit(struct net *net)
 {
        kfree(net->dev_name_head);
index c77aff9c6eb3cc76fab911cdca097cc5add01d8c..8c6b706963ff01b02c87a54f2c70103e7f7f8f29 100644 (file)
@@ -34,6 +34,7 @@
 #define NET_DMA_DEFAULT_COPYBREAK 4096
 
 int sysctl_tcp_dma_copybreak = NET_DMA_DEFAULT_COPYBREAK;
+EXPORT_SYMBOL(sysctl_tcp_dma_copybreak);
 
 /**
  *     dma_skb_copy_datagram_iovec - Copy a datagram to an iovec.
index 40a46d482490809774e5d3380d3fd57d5046d9d3..3a020720e40b73fdd54add29d972c5f64aa5536b 100644 (file)
 #include <net/netfilter/nf_conntrack_l3proto.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_expect.h>
-
-#ifdef CONFIG_NF_CT_ACCT
-static unsigned int
-seq_print_counters(struct seq_file *s,
-                  const struct ip_conntrack_counter *counter)
-{
-       return seq_printf(s, "packets=%llu bytes=%llu ",
-                         (unsigned long long)counter->packets,
-                         (unsigned long long)counter->bytes);
-}
-#else
-#define seq_print_counters(x, y)       0
-#endif
+#include <net/netfilter/nf_conntrack_acct.h>
 
 struct ct_iter_state {
        unsigned int bucket;
@@ -127,7 +115,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
                        l3proto, l4proto))
                return -ENOSPC;
 
-       if (seq_print_counters(s, &ct->counters[IP_CT_DIR_ORIGINAL]))
+       if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL))
                return -ENOSPC;
 
        if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
@@ -138,7 +126,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
                        l3proto, l4proto))
                return -ENOSPC;
 
-       if (seq_print_counters(s, &ct->counters[IP_CT_DIR_REPLY]))
+       if (seq_print_acct(s, ct, IP_CT_DIR_REPLY))
                return -ENOSPC;
 
        if (test_bit(IPS_ASSURED_BIT, &ct->status))
index d2a887fc8d9b1b53f1539bcfc8c446d248466522..6c6a3cba8d50eab5b32f359e576c34a73ee76697 100644 (file)
@@ -240,12 +240,12 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
           This is only required for source (ie. NAT/masq) mappings.
           So far, we don't do local source mappings, so multiple
           manips not an issue.  */
-       if (maniptype == IP_NAT_MANIP_SRC) {
+       if (maniptype == IP_NAT_MANIP_SRC &&
+           !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) {
                if (find_appropriate_src(orig_tuple, tuple, range)) {
                        pr_debug("get_unique_tuple: Found current src map\n");
-                       if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
-                               if (!nf_nat_used_tuple(tuple, ct))
-                                       return;
+                       if (!nf_nat_used_tuple(tuple, ct))
+                               return;
                }
        }
 
index 4334d5cabc5b17b1eb6ab6a8ec9873ee623c3bc4..14544320c54577233ead8b41369eedc1c65d7720 100644 (file)
@@ -318,11 +318,11 @@ static int mangle_content_len(struct sk_buff *skb,
                             buffer, buflen);
 }
 
-static unsigned mangle_sdp_packet(struct sk_buff *skb, const char **dptr,
-                                 unsigned int dataoff, unsigned int *datalen,
-                                 enum sdp_header_types type,
-                                 enum sdp_header_types term,
-                                 char *buffer, int buflen)
+static int mangle_sdp_packet(struct sk_buff *skb, const char **dptr,
+                            unsigned int dataoff, unsigned int *datalen,
+                            enum sdp_header_types type,
+                            enum sdp_header_types term,
+                            char *buffer, int buflen)
 {
        enum ip_conntrack_info ctinfo;
        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
@@ -330,9 +330,9 @@ static unsigned mangle_sdp_packet(struct sk_buff *skb, const char **dptr,
 
        if (ct_sip_get_sdp_header(ct, *dptr, dataoff, *datalen, type, term,
                                  &matchoff, &matchlen) <= 0)
-               return 0;
+               return -ENOENT;
        return mangle_packet(skb, dptr, datalen, matchoff, matchlen,
-                            buffer, buflen);
+                            buffer, buflen) ? 0 : -EINVAL;
 }
 
 static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr,
@@ -346,8 +346,8 @@ static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr,
        unsigned int buflen;
 
        buflen = sprintf(buffer, NIPQUAD_FMT, NIPQUAD(addr->ip));
-       if (!mangle_sdp_packet(skb, dptr, dataoff, datalen, type, term,
-                              buffer, buflen))
+       if (mangle_sdp_packet(skb, dptr, dataoff, datalen, type, term,
+                             buffer, buflen))
                return 0;
 
        return mangle_content_len(skb, dptr, datalen);
@@ -381,15 +381,27 @@ static unsigned int ip_nat_sdp_session(struct sk_buff *skb, const char **dptr,
 
        /* Mangle session description owner and contact addresses */
        buflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(addr->ip));
-       if (!mangle_sdp_packet(skb, dptr, dataoff, datalen,
+       if (mangle_sdp_packet(skb, dptr, dataoff, datalen,
                               SDP_HDR_OWNER_IP4, SDP_HDR_MEDIA,
                               buffer, buflen))
                return 0;
 
-       if (!mangle_sdp_packet(skb, dptr, dataoff, datalen,
-                              SDP_HDR_CONNECTION_IP4, SDP_HDR_MEDIA,
-                              buffer, buflen))
+       switch (mangle_sdp_packet(skb, dptr, dataoff, datalen,
+                                 SDP_HDR_CONNECTION_IP4, SDP_HDR_MEDIA,
+                                 buffer, buflen)) {
+       case 0:
+       /*
+        * RFC 2327:
+        *
+        * Session description
+        *
+        * c=* (connection information - not required if included in all media)
+        */
+       case -ENOENT:
+               break;
+       default:
                return 0;
+       }
 
        return mangle_content_len(skb, dptr, datalen);
 }
index 1fa683c0ba9bcc558e58a527774823491f4323b7..a00532de2a8c17ce19238681764b518c268c0400 100644 (file)
@@ -472,7 +472,7 @@ static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb,
        }
        if (likely(sysctl_tcp_sack)) {
                opts->options |= OPTION_SACK_ADVERTISE;
-               if (unlikely(!OPTION_TS & opts->options))
+               if (unlikely(!(OPTION_TS & opts->options)))
                        size += TCPOLEN_SACKPERM_ALIGNED;
        }
 
index a751770947a3df550573f01f24acfe3283beb12c..383d17359d01f1a81080df5aabef22266c1dd1c4 100644 (file)
@@ -1325,6 +1325,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
                        return -ENOPROTOOPT;
                if (val != 0 && val < 8) /* Illegal coverage: use default (8) */
                        val = 8;
+               else if (val > USHORT_MAX)
+                       val = USHORT_MAX;
                up->pcslen = val;
                up->pcflag |= UDPLITE_SEND_CC;
                break;
@@ -1337,6 +1339,8 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
                        return -ENOPROTOOPT;
                if (val != 0 && val < 8) /* Avoid silly minimal values.       */
                        val = 8;
+               else if (val > USHORT_MAX)
+                       val = USHORT_MAX;
                up->pcrlen = val;
                up->pcflag |= UDPLITE_RECV_CC;
                break;
index 9f4fcce6379b88d4a6e0b0f388257b8907b4aec3..74d543d504a1d6fcfbe859235e70bd05418b4364 100644 (file)
@@ -153,7 +153,7 @@ static int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
 
 static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
 
-struct ipv6_devconf ipv6_devconf __read_mostly = {
+static struct ipv6_devconf ipv6_devconf __read_mostly = {
        .forwarding             = 0,
        .hop_limit              = IPV6_DEFAULT_HOPLIMIT,
        .mtu6                   = IPV6_MIN_MTU,
index 4de2b9efcacb144da807588975c501e4e291a46f..08ea2de28d63c358eeec0a3b59469914dd3fca4b 100644 (file)
@@ -661,17 +661,17 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
 
 static __inline__ void fib6_start_gc(struct net *net, struct rt6_info *rt)
 {
-       if (net->ipv6.ip6_fib_timer->expires == 0 &&
+       if (!timer_pending(&net->ipv6.ip6_fib_timer) &&
            (rt->rt6i_flags & (RTF_EXPIRES|RTF_CACHE)))
-               mod_timer(net->ipv6.ip6_fib_timer, jiffies +
-                         net->ipv6.sysctl.ip6_rt_gc_interval);
+               mod_timer(&net->ipv6.ip6_fib_timer,
+                         jiffies + net->ipv6.sysctl.ip6_rt_gc_interval);
 }
 
 void fib6_force_start_gc(struct net *net)
 {
-       if (net->ipv6.ip6_fib_timer->expires == 0)
-               mod_timer(net->ipv6.ip6_fib_timer, jiffies +
-                         net->ipv6.sysctl.ip6_rt_gc_interval);
+       if (!timer_pending(&net->ipv6.ip6_fib_timer))
+               mod_timer(&net->ipv6.ip6_fib_timer,
+                         jiffies + net->ipv6.sysctl.ip6_rt_gc_interval);
 }
 
 /*
@@ -1447,27 +1447,23 @@ void fib6_run_gc(unsigned long expires, struct net *net)
                gc_args.timeout = expires ? (int)expires :
                        net->ipv6.sysctl.ip6_rt_gc_interval;
        } else {
-               local_bh_disable();
-               if (!spin_trylock(&fib6_gc_lock)) {
-                       mod_timer(net->ipv6.ip6_fib_timer, jiffies + HZ);
-                       local_bh_enable();
+               if (!spin_trylock_bh(&fib6_gc_lock)) {
+                       mod_timer(&net->ipv6.ip6_fib_timer, jiffies + HZ);
                        return;
                }
                gc_args.timeout = net->ipv6.sysctl.ip6_rt_gc_interval;
        }
-       gc_args.more = 0;
 
-       icmp6_dst_gc(&gc_args.more);
+       gc_args.more = icmp6_dst_gc();
 
        fib6_clean_all(net, fib6_age, 0, NULL);
 
        if (gc_args.more)
-               mod_timer(net->ipv6.ip6_fib_timer, jiffies +
-                         net->ipv6.sysctl.ip6_rt_gc_interval);
-       else {
-               del_timer(net->ipv6.ip6_fib_timer);
-               net->ipv6.ip6_fib_timer->expires = 0;
-       }
+               mod_timer(&net->ipv6.ip6_fib_timer,
+                         round_jiffies(jiffies
+                                       + net->ipv6.sysctl.ip6_rt_gc_interval));
+       else
+               del_timer(&net->ipv6.ip6_fib_timer);
        spin_unlock_bh(&fib6_gc_lock);
 }
 
@@ -1478,24 +1474,15 @@ static void fib6_gc_timer_cb(unsigned long arg)
 
 static int fib6_net_init(struct net *net)
 {
-       int ret;
-       struct timer_list *timer;
-
-       ret = -ENOMEM;
-       timer = kzalloc(sizeof(*timer), GFP_KERNEL);
-       if (!timer)
-               goto out;
-
-       setup_timer(timer, fib6_gc_timer_cb, (unsigned long)net);
-       net->ipv6.ip6_fib_timer = timer;
+       setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net);
 
        net->ipv6.rt6_stats = kzalloc(sizeof(*net->ipv6.rt6_stats), GFP_KERNEL);
        if (!net->ipv6.rt6_stats)
                goto out_timer;
 
-       net->ipv6.fib_table_hash =
-               kzalloc(sizeof(*net->ipv6.fib_table_hash)*FIB_TABLE_HASHSZ,
-                       GFP_KERNEL);
+       net->ipv6.fib_table_hash = kcalloc(FIB_TABLE_HASHSZ,
+                                          sizeof(*net->ipv6.fib_table_hash),
+                                          GFP_KERNEL);
        if (!net->ipv6.fib_table_hash)
                goto out_rt6_stats;
 
@@ -1521,9 +1508,7 @@ static int fib6_net_init(struct net *net)
 #endif
        fib6_tables_init(net);
 
-       ret = 0;
-out:
-       return ret;
+       return 0;
 
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 out_fib6_main_tbl:
@@ -1534,15 +1519,14 @@ out_fib_table_hash:
 out_rt6_stats:
        kfree(net->ipv6.rt6_stats);
 out_timer:
-       kfree(timer);
-       goto out;
+       return -ENOMEM;
  }
 
 static void fib6_net_exit(struct net *net)
 {
        rt6_ifdown(net, NULL);
-       del_timer_sync(net->ipv6.ip6_fib_timer);
-       kfree(net->ipv6.ip6_fib_timer);
+       del_timer_sync(&net->ipv6.ip6_fib_timer);
+
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
        kfree(net->ipv6.fib6_local_tbl);
 #endif
index 615b328de2516cbccdac54debb0cfb47abfb147a..86540b24b27c386454630ecd9143dc09b5fe2cc8 100644 (file)
@@ -978,13 +978,12 @@ out:
        return &rt->u.dst;
 }
 
-int icmp6_dst_gc(int *more)
+int icmp6_dst_gc(void)
 {
        struct dst_entry *dst, *next, **pprev;
-       int freed;
+       int more = 0;
 
        next = NULL;
-       freed = 0;
 
        spin_lock_bh(&icmp6_dst_lock);
        pprev = &icmp6_dst_gc_list;
@@ -993,16 +992,15 @@ int icmp6_dst_gc(int *more)
                if (!atomic_read(&dst->__refcnt)) {
                        *pprev = dst->next;
                        dst_free(dst);
-                       freed++;
                } else {
                        pprev = &dst->next;
-                       (*more)++;
+                       ++more;
                }
        }
 
        spin_unlock_bh(&icmp6_dst_lock);
 
-       return freed;
+       return more;
 }
 
 static int ip6_dst_gc(struct dst_ops *ops)
index 316c7af1d2b1d257f6bb2febc0aeadffd0a76e93..ee898e74808d32f59821e780fc617d9e18af85d2 100644 (file)
@@ -49,6 +49,15 @@ config NF_CT_ACCT
          Those counters can be used for flow-based accounting or the
          `connbytes' match.
 
+         Please note that currently this option only sets a default state.
+         You may change it at boot time with nf_conntrack.acct=0/1 kernel
+         paramater or by loading the nf_conntrack module with acct=0/1.
+
+         You may also disable/enable it on a running system with:
+          sysctl net.netfilter.nf_conntrack_acct=0/1
+
+         This option will be removed in 2.6.29.
+
          If unsure, say `N'.
 
 config NF_CONNTRACK_MARK
index 5c4b183f642207f571c87134524d2234e55e76e4..3bd2cc556aea6fabd720921f30b6c7b1c5c8e3a3 100644 (file)
@@ -1,6 +1,6 @@
 netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o
 
-nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o
+nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o nf_conntrack_acct.o
 nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
 
 obj-$(CONFIG_NETFILTER) = netfilter.o
diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c
new file mode 100644 (file)
index 0000000..59bd8b9
--- /dev/null
@@ -0,0 +1,104 @@
+/* Accouting handling for netfilter. */
+
+/*
+ * (C) 2008 Krzysztof Piotr Oledzki <ole@ans.pl>
+ *
+ * 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/netfilter.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_extend.h>
+#include <net/netfilter/nf_conntrack_acct.h>
+
+#ifdef CONFIG_NF_CT_ACCT
+#define NF_CT_ACCT_DEFAULT 1
+#else
+#define NF_CT_ACCT_DEFAULT 0
+#endif
+
+int nf_ct_acct __read_mostly = NF_CT_ACCT_DEFAULT;
+EXPORT_SYMBOL_GPL(nf_ct_acct);
+
+module_param_named(acct, nf_ct_acct, bool, 0644);
+MODULE_PARM_DESC(acct, "Enable connection tracking flow accounting.");
+
+#ifdef CONFIG_SYSCTL
+static struct ctl_table_header *acct_sysctl_header;
+static struct ctl_table acct_sysctl_table[] = {
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "nf_conntrack_acct",
+               .data           = &nf_ct_acct,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
+       {}
+};
+#endif /* CONFIG_SYSCTL */
+
+unsigned int
+seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir)
+{
+       struct nf_conn_counter *acct;
+
+       acct = nf_conn_acct_find(ct);
+       if (!acct)
+               return 0;
+
+       return seq_printf(s, "packets=%llu bytes=%llu ",
+                         (unsigned long long)acct[dir].packets,
+                         (unsigned long long)acct[dir].bytes);
+};
+EXPORT_SYMBOL_GPL(seq_print_acct);
+
+static struct nf_ct_ext_type acct_extend __read_mostly = {
+       .len    = sizeof(struct nf_conn_counter[IP_CT_DIR_MAX]),
+       .align  = __alignof__(struct nf_conn_counter[IP_CT_DIR_MAX]),
+       .id     = NF_CT_EXT_ACCT,
+};
+
+int nf_conntrack_acct_init(void)
+{
+       int ret;
+
+#ifdef CONFIG_NF_CT_ACCT
+       printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Plase use\n");
+       printk(KERN_WARNING "nf_conntrack.acct=1 kernel paramater, acct=1 nf_conntrack module option or\n");
+       printk(KERN_WARNING "sysctl net.netfilter.nf_conntrack_acct=1 to enable it.\n");
+#endif
+
+       ret = nf_ct_extend_register(&acct_extend);
+       if (ret < 0) {
+               printk(KERN_ERR "nf_conntrack_acct: Unable to register extension\n");
+               return ret;
+       }
+
+#ifdef CONFIG_SYSCTL
+       acct_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path,
+                               acct_sysctl_table);
+
+       if (!acct_sysctl_header) {
+               nf_ct_extend_unregister(&acct_extend);
+
+               printk(KERN_ERR "nf_conntrack_acct: can't register to sysctl.\n");
+               return -ENOMEM;
+       }
+#endif
+
+       return 0;
+}
+
+void nf_conntrack_acct_fini(void)
+{
+#ifdef CONFIG_SYSCTL
+       unregister_sysctl_table(acct_sysctl_header);
+#endif
+       nf_ct_extend_unregister(&acct_extend);
+}
index 28d03e64200b60284d196bfba395ea90d2316f7f..c519d090bdb942a74f6f9508435786b5fcb150c1 100644 (file)
@@ -37,6 +37,7 @@
 #include <net/netfilter/nf_conntrack_helper.h>
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/nf_conntrack_extend.h>
+#include <net/netfilter/nf_conntrack_acct.h>
 
 #define NF_CONNTRACK_VERSION   "0.5.0"
 
@@ -555,6 +556,8 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
                return NULL;
        }
 
+       nf_ct_acct_ext_add(ct, GFP_ATOMIC);
+
        spin_lock_bh(&nf_conntrack_lock);
        exp = nf_ct_find_expectation(tuple);
        if (exp) {
@@ -828,17 +831,16 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
        }
 
 acct:
-#ifdef CONFIG_NF_CT_ACCT
        if (do_acct) {
-               ct->counters[CTINFO2DIR(ctinfo)].packets++;
-               ct->counters[CTINFO2DIR(ctinfo)].bytes +=
-                       skb->len - skb_network_offset(skb);
+               struct nf_conn_counter *acct;
 
-               if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000)
-                   || (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000))
-                       event |= IPCT_COUNTER_FILLING;
+               acct = nf_conn_acct_find(ct);
+               if (acct) {
+                       acct[CTINFO2DIR(ctinfo)].packets++;
+                       acct[CTINFO2DIR(ctinfo)].bytes +=
+                               skb->len - skb_network_offset(skb);
+               }
        }
-#endif
 
        spin_unlock_bh(&nf_conntrack_lock);
 
@@ -853,15 +855,19 @@ bool __nf_ct_kill_acct(struct nf_conn *ct,
                       const struct sk_buff *skb,
                       int do_acct)
 {
-#ifdef CONFIG_NF_CT_ACCT
        if (do_acct) {
+               struct nf_conn_counter *acct;
+
                spin_lock_bh(&nf_conntrack_lock);
-               ct->counters[CTINFO2DIR(ctinfo)].packets++;
-               ct->counters[CTINFO2DIR(ctinfo)].bytes +=
-                       skb->len - skb_network_offset(skb);
+               acct = nf_conn_acct_find(ct);
+               if (acct) {
+                       acct[CTINFO2DIR(ctinfo)].packets++;
+                       acct[CTINFO2DIR(ctinfo)].bytes +=
+                               skb->len - skb_network_offset(skb);
+               }
                spin_unlock_bh(&nf_conntrack_lock);
        }
-#endif
+
        if (del_timer(&ct->timeout)) {
                ct->timeout.function((unsigned long)ct);
                return true;
@@ -1029,6 +1035,7 @@ void nf_conntrack_cleanup(void)
        nf_conntrack_proto_fini();
        nf_conntrack_helper_fini();
        nf_conntrack_expect_fini();
+       nf_conntrack_acct_fini();
 }
 
 struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced)
@@ -1168,6 +1175,10 @@ int __init nf_conntrack_init(void)
        if (ret < 0)
                goto out_fini_expect;
 
+       ret = nf_conntrack_acct_init();
+       if (ret < 0)
+               goto out_fini_helper;
+
        /* For use by REJECT target */
        rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach);
        rcu_assign_pointer(nf_ct_destroy, destroy_conntrack);
@@ -1180,6 +1191,8 @@ int __init nf_conntrack_init(void)
 
        return ret;
 
+out_fini_helper:
+       nf_conntrack_helper_fini();
 out_fini_expect:
        nf_conntrack_expect_fini();
 out_fini_proto:
index 95a7967731f942ae68ea70126ff59fd81cc7b435..105a616c5c7805a2333dd3133f7580845bc556a3 100644 (file)
@@ -37,6 +37,7 @@
 #include <net/netfilter/nf_conntrack_l3proto.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_tuple.h>
+#include <net/netfilter/nf_conntrack_acct.h>
 #ifdef CONFIG_NF_NAT_NEEDED
 #include <net/netfilter/nf_nat_core.h>
 #include <net/netfilter/nf_nat_protocol.h>
@@ -206,22 +207,26 @@ nla_put_failure:
        return -1;
 }
 
-#ifdef CONFIG_NF_CT_ACCT
 static int
 ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
                        enum ip_conntrack_dir dir)
 {
        enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
        struct nlattr *nest_count;
+       const struct nf_conn_counter *acct;
+
+       acct = nf_conn_acct_find(ct);
+       if (!acct)
+               return 0;
 
        nest_count = nla_nest_start(skb, type | NLA_F_NESTED);
        if (!nest_count)
                goto nla_put_failure;
 
-       NLA_PUT_BE32(skb, CTA_COUNTERS32_PACKETS,
-                    htonl(ct->counters[dir].packets));
-       NLA_PUT_BE32(skb, CTA_COUNTERS32_BYTES,
-                    htonl(ct->counters[dir].bytes));
+       NLA_PUT_BE64(skb, CTA_COUNTERS_PACKETS,
+                    cpu_to_be64(acct[dir].packets));
+       NLA_PUT_BE64(skb, CTA_COUNTERS_BYTES,
+                    cpu_to_be64(acct[dir].bytes));
 
        nla_nest_end(skb, nest_count);
 
@@ -230,9 +235,6 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
 nla_put_failure:
        return -1;
 }
-#else
-#define ctnetlink_dump_counters(a, b, c) (0)
-#endif
 
 #ifdef CONFIG_NF_CONNTRACK_MARK
 static inline int
@@ -501,11 +503,6 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
                        goto nla_put_failure;
 #endif
 
-               if (events & IPCT_COUNTER_FILLING &&
-                   (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
-                    ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0))
-                       goto nla_put_failure;
-
                if (events & IPCT_RELATED &&
                    ctnetlink_dump_master(skb, ct) < 0)
                        goto nla_put_failure;
@@ -576,11 +573,15 @@ restart:
                                cb->args[1] = (unsigned long)ct;
                                goto out;
                        }
-#ifdef CONFIG_NF_CT_ACCT
+
                        if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) ==
-                                               IPCTNL_MSG_CT_GET_CTRZERO)
-                               memset(&ct->counters, 0, sizeof(ct->counters));
-#endif
+                                               IPCTNL_MSG_CT_GET_CTRZERO) {
+                               struct nf_conn_counter *acct;
+
+                               acct = nf_conn_acct_find(ct);
+                               if (acct)
+                                       memset(acct, 0, sizeof(struct nf_conn_counter[IP_CT_DIR_MAX]));
+                       }
                }
                if (cb->args[1]) {
                        cb->args[1] = 0;
@@ -832,14 +833,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
        u_int8_t u3 = nfmsg->nfgen_family;
        int err = 0;
 
-       if (nlh->nlmsg_flags & NLM_F_DUMP) {
-#ifndef CONFIG_NF_CT_ACCT
-               if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO)
-                       return -ENOTSUPP;
-#endif
+       if (nlh->nlmsg_flags & NLM_F_DUMP)
                return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table,
                                          ctnetlink_done);
-       }
 
        if (cda[CTA_TUPLE_ORIG])
                err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3);
@@ -1152,6 +1148,8 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
                        goto err;
        }
 
+       nf_ct_acct_ext_add(ct, GFP_KERNEL);
+
 #if defined(CONFIG_NF_CONNTRACK_MARK)
        if (cda[CTA_MARK])
                ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));
index 41183a4d2d621f41ac4662bfc411feebdd673e80..30aa5b94a77184fa8e0b9d017c5ae03b4b5fe376 100644 (file)
@@ -482,11 +482,11 @@ static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
 
        NLA_PUT_BE32(skb,
                     CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
-                    htonl(ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]));
+                    ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]);
 
        NLA_PUT_BE32(skb,
                     CTA_PROTOINFO_SCTP_VTAG_REPLY,
-                    htonl(ct->proto.sctp.vtag[IP_CT_DIR_REPLY]));
+                    ct->proto.sctp.vtag[IP_CT_DIR_REPLY]);
 
        read_unlock_bh(&sctp_lock);
 
@@ -530,9 +530,9 @@ static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
        write_lock_bh(&sctp_lock);
        ct->proto.sctp.state = nla_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
        ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =
-               ntohl(nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]));
+               nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]);
        ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
-               ntohl(nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]));
+               nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]);
        write_unlock_bh(&sctp_lock);
 
        return 0;
index 46ea542d0df999d8fdaaecabac5eaf7340ee8342..869ef9349d0f1c748e3ec7a4619827c9759ccef7 100644 (file)
@@ -25,6 +25,7 @@
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_expect.h>
 #include <net/netfilter/nf_conntrack_helper.h>
+#include <net/netfilter/nf_conntrack_acct.h>
 
 MODULE_LICENSE("GPL");
 
@@ -38,19 +39,6 @@ print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
 }
 EXPORT_SYMBOL_GPL(print_tuple);
 
-#ifdef CONFIG_NF_CT_ACCT
-static unsigned int
-seq_print_counters(struct seq_file *s,
-                  const struct ip_conntrack_counter *counter)
-{
-       return seq_printf(s, "packets=%llu bytes=%llu ",
-                         (unsigned long long)counter->packets,
-                         (unsigned long long)counter->bytes);
-}
-#else
-#define seq_print_counters(x, y)       0
-#endif
-
 struct ct_iter_state {
        unsigned int bucket;
 };
@@ -146,7 +134,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
                        l3proto, l4proto))
                return -ENOSPC;
 
-       if (seq_print_counters(s, &ct->counters[IP_CT_DIR_ORIGINAL]))
+       if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL))
                return -ENOSPC;
 
        if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
@@ -157,7 +145,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
                        l3proto, l4proto))
                return -ENOSPC;
 
-       if (seq_print_counters(s, &ct->counters[IP_CT_DIR_REPLY]))
+       if (seq_print_acct(s, ct, IP_CT_DIR_REPLY))
                return -ENOSPC;
 
        if (test_bit(IPS_ASSURED_BIT, &ct->status))
index b8173af8c24a7d9d1f296123b52dfc05a0063dc0..9a35b57ab76d9ea4bc43b4a37401c9c21bd50ee7 100644 (file)
@@ -453,6 +453,14 @@ __build_packet_message(struct nfulnl_instance *inst,
                }
        }
 
+       if (indev && skb_mac_header_was_set(skb)) {
+               NLA_PUT_BE16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type));
+               NLA_PUT_BE16(inst->skb, NFULA_HWLEN,
+                            htons(skb->dev->hard_header_len));
+               NLA_PUT(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len,
+                       skb_mac_header(skb));
+       }
+
        if (skb->tstamp.tv64) {
                struct nfulnl_msg_packet_timestamp ts;
                struct timeval tv = ktime_to_timeval(skb->tstamp);
index 217e2b6863225acf4353e7cd6f4869df3ce1da56..beb5094703cb5e7c6d897bd34f0ccf4a4b86c7ce 100644 (file)
@@ -147,17 +147,21 @@ tcpmss_mangle_packet(struct sk_buff *skb,
        return TCPOLEN_MSS;
 }
 
-static u_int32_t tcpmss_reverse_mtu4(const struct iphdr *iph)
+static u_int32_t tcpmss_reverse_mtu(const struct sk_buff *skb,
+                                   unsigned int family)
 {
-       struct flowi fl = {
-               .fl4_dst = iph->saddr,
-       };
+       struct flowi fl = {};
        const struct nf_afinfo *ai;
        struct rtable *rt = NULL;
        u_int32_t mtu     = ~0U;
 
+       if (family == PF_INET)
+               fl.fl4_dst = ip_hdr(skb)->saddr;
+       else
+               fl.fl6_dst = ipv6_hdr(skb)->saddr;
+
        rcu_read_lock();
-       ai = nf_get_afinfo(AF_INET);
+       ai = nf_get_afinfo(family);
        if (ai != NULL)
                ai->route((struct dst_entry **)&rt, &fl);
        rcu_read_unlock();
@@ -178,7 +182,8 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
        __be16 newlen;
        int ret;
 
-       ret = tcpmss_mangle_packet(skb, targinfo, tcpmss_reverse_mtu4(iph),
+       ret = tcpmss_mangle_packet(skb, targinfo,
+                                  tcpmss_reverse_mtu(skb, PF_INET),
                                   iph->ihl * 4,
                                   sizeof(*iph) + sizeof(struct tcphdr));
        if (ret < 0)
@@ -193,28 +198,6 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
 }
 
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
-static u_int32_t tcpmss_reverse_mtu6(const struct ipv6hdr *iph)
-{
-       struct flowi fl = {
-               .fl6_dst = iph->saddr,
-       };
-       const struct nf_afinfo *ai;
-       struct rtable *rt = NULL;
-       u_int32_t mtu     = ~0U;
-
-       rcu_read_lock();
-       ai = nf_get_afinfo(AF_INET6);
-       if (ai != NULL)
-               ai->route((struct dst_entry **)&rt, &fl);
-       rcu_read_unlock();
-
-       if (rt != NULL) {
-               mtu = dst_mtu(&rt->u.dst);
-               dst_release(&rt->u.dst);
-       }
-       return mtu;
-}
-
 static unsigned int
 tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
            const struct net_device *out, unsigned int hooknum,
@@ -229,7 +212,8 @@ tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
        tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr);
        if (tcphoff < 0)
                return NF_DROP;
-       ret = tcpmss_mangle_packet(skb, targinfo, tcpmss_reverse_mtu6(ipv6h),
+       ret = tcpmss_mangle_packet(skb, targinfo,
+                                  tcpmss_reverse_mtu(skb, PF_INET6),
                                   tcphoff,
                                   sizeof(*ipv6h) + sizeof(struct tcphdr));
        if (ret < 0)
index d7e8983cd37f6303921edf25bc201eca7e99c4a2..3e39c4fe1931b4f91655b406eee2f5bca9395c7d 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_connbytes.h>
 #include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_acct.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
@@ -27,12 +28,15 @@ connbytes_mt(const struct sk_buff *skb, const struct net_device *in,
        u_int64_t what = 0;     /* initialize to make gcc happy */
        u_int64_t bytes = 0;
        u_int64_t pkts = 0;
-       const struct ip_conntrack_counter *counters;
+       const struct nf_conn_counter *counters;
 
        ct = nf_ct_get(skb, &ctinfo);
        if (!ct)
                return false;
-       counters = ct->counters;
+
+       counters = nf_conn_acct_find(ct);
+       if (!counters)
+               return false;
 
        switch (sinfo->what) {
        case XT_CONNBYTES_PKTS:
index ed76baab47349c609c6de4cdf07c36ec12f98c21..9f328593287eabfcaf8c13e013fbc5458e61da89 100644 (file)
@@ -173,7 +173,7 @@ time_mt(const struct sk_buff *skb, const struct net_device *in,
                __net_timestamp((struct sk_buff *)skb);
 
        stamp = ktime_to_ns(skb->tstamp);
-       do_div(stamp, NSEC_PER_SEC);
+       stamp = div_s64(stamp, NSEC_PER_SEC);
 
        if (info->flags & XT_TIME_LOCAL_TZ)
                /* Adjust for local timezone */
index fccc250f95f5e8e111d17b4dca1f0d2570e28507..532e4faa29f7cac835a854d4180f5d2e6861c794 100644 (file)
@@ -73,6 +73,7 @@ static const struct proto_ops nr_proto_ops;
  * separate class since they always nest.
  */
 static struct lock_class_key nr_netdev_xmit_lock_key;
+static struct lock_class_key nr_netdev_addr_lock_key;
 
 static void nr_set_lockdep_one(struct net_device *dev,
                               struct netdev_queue *txq,
@@ -83,6 +84,7 @@ static void nr_set_lockdep_one(struct net_device *dev,
 
 static void nr_set_lockdep_key(struct net_device *dev)
 {
+       lockdep_set_class(&dev->addr_list_lock, &nr_netdev_addr_lock_key);
        netdev_for_each_tx_queue(dev, nr_set_lockdep_one, NULL);
 }
 
index dbc963b4f5fbb78b7c6167341776faa14f60a634..a7f1ce11bc22d140d52526c11816973d05683729 100644 (file)
@@ -74,6 +74,7 @@ ax25_address rose_callsign;
  * separate class since they always nest.
  */
 static struct lock_class_key rose_netdev_xmit_lock_key;
+static struct lock_class_key rose_netdev_addr_lock_key;
 
 static void rose_set_lockdep_one(struct net_device *dev,
                                 struct netdev_queue *txq,
@@ -84,6 +85,7 @@ static void rose_set_lockdep_one(struct net_device *dev,
 
 static void rose_set_lockdep_key(struct net_device *dev)
 {
+       lockdep_set_class(&dev->addr_list_lock, &rose_netdev_addr_lock_key);
        netdev_for_each_tx_queue(dev, rose_set_lockdep_one, NULL);
 }
 
index 5219d5f9d75444e4a35482d2e707efcf0af2fe1d..b0601642e22759f3f454eb36f53136d5a6c6d90a 100644 (file)
@@ -447,7 +447,7 @@ void qdisc_watchdog_cancel(struct qdisc_watchdog *wd)
 }
 EXPORT_SYMBOL(qdisc_watchdog_cancel);
 
-struct hlist_head *qdisc_class_hash_alloc(unsigned int n)
+static struct hlist_head *qdisc_class_hash_alloc(unsigned int n)
 {
        unsigned int size = n * sizeof(struct hlist_head), i;
        struct hlist_head *h;
index 0ddf69286f9233ce196bef1953f819f0527a543e..4ac7e3a8c253b0e7754ac77071a6c7348a514841 100644 (file)
@@ -212,9 +212,9 @@ static void dev_watchdog(unsigned long arg)
                        if (some_queue_stopped &&
                            time_after(jiffies, (dev->trans_start +
                                                 dev->watchdog_timeo))) {
-                               printk(KERN_INFO "NETDEV WATCHDOG: %s: "
-                                      "transmit timed out\n",
-                                      dev->name);
+                               char drivername[64];
+                               printk(KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit timed out\n",
+                                      dev->name, netdev_drivername(dev, drivername, 64));
                                dev->tx_timeout(dev);
                                WARN_ON_ONCE(1);
                        }
@@ -356,44 +356,99 @@ static struct Qdisc noqueue_qdisc = {
 };
 
 
-static int fifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
+static const u8 prio2band[TC_PRIO_MAX+1] =
+       { 1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1 };
+
+/* 3-band FIFO queue: old style, but should be a bit faster than
+   generic prio+fifo combination.
+ */
+
+#define PFIFO_FAST_BANDS 3
+
+static inline struct sk_buff_head *prio2list(struct sk_buff *skb,
+                                            struct Qdisc *qdisc)
+{
+       struct sk_buff_head *list = qdisc_priv(qdisc);
+       return list + prio2band[skb->priority & TC_PRIO_MAX];
+}
+
+static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
 {
-       struct sk_buff_head *list = &qdisc->q;
+       struct sk_buff_head *list = prio2list(skb, qdisc);
 
-       if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len)
+       if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
+               qdisc->q.qlen++;
                return __qdisc_enqueue_tail(skb, qdisc, list);
+       }
 
        return qdisc_drop(skb, qdisc);
 }
 
-static struct sk_buff *fifo_fast_dequeue(struct Qdisc* qdisc)
+static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc)
 {
-       struct sk_buff_head *list = &qdisc->q;
+       int prio;
+       struct sk_buff_head *list = qdisc_priv(qdisc);
 
-       if (!skb_queue_empty(list))
-               return __qdisc_dequeue_head(qdisc, list);
+       for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
+               if (!skb_queue_empty(list + prio)) {
+                       qdisc->q.qlen--;
+                       return __qdisc_dequeue_head(qdisc, list + prio);
+               }
+       }
 
        return NULL;
 }
 
-static int fifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
+static int pfifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
 {
-       return __qdisc_requeue(skb, qdisc, &qdisc->q);
+       qdisc->q.qlen++;
+       return __qdisc_requeue(skb, qdisc, prio2list(skb, qdisc));
 }
 
-static void fifo_fast_reset(struct Qdisc* qdisc)
+static void pfifo_fast_reset(struct Qdisc* qdisc)
 {
-       __qdisc_reset_queue(qdisc, &qdisc->q);
+       int prio;
+       struct sk_buff_head *list = qdisc_priv(qdisc);
+
+       for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
+               __qdisc_reset_queue(qdisc, list + prio);
+
        qdisc->qstats.backlog = 0;
+       qdisc->q.qlen = 0;
 }
 
-static struct Qdisc_ops fifo_fast_ops __read_mostly = {
-       .id             =       "fifo_fast",
-       .priv_size      =       0,
-       .enqueue        =       fifo_fast_enqueue,
-       .dequeue        =       fifo_fast_dequeue,
-       .requeue        =       fifo_fast_requeue,
-       .reset          =       fifo_fast_reset,
+static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb)
+{
+       struct tc_prio_qopt opt = { .bands = PFIFO_FAST_BANDS };
+
+       memcpy(&opt.priomap, prio2band, TC_PRIO_MAX+1);
+       NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+       return skb->len;
+
+nla_put_failure:
+       return -1;
+}
+
+static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
+{
+       int prio;
+       struct sk_buff_head *list = qdisc_priv(qdisc);
+
+       for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
+               skb_queue_head_init(list + prio);
+
+       return 0;
+}
+
+static struct Qdisc_ops pfifo_fast_ops __read_mostly = {
+       .id             =       "pfifo_fast",
+       .priv_size      =       PFIFO_FAST_BANDS * sizeof(struct sk_buff_head),
+       .enqueue        =       pfifo_fast_enqueue,
+       .dequeue        =       pfifo_fast_dequeue,
+       .requeue        =       pfifo_fast_requeue,
+       .init           =       pfifo_fast_init,
+       .reset          =       pfifo_fast_reset,
+       .dump           =       pfifo_fast_dump,
        .owner          =       THIS_MODULE,
 };
 
@@ -522,7 +577,7 @@ static void attach_one_default_qdisc(struct net_device *dev,
 
        if (dev->tx_queue_len) {
                qdisc = qdisc_create_dflt(dev, dev_queue,
-                                         &fifo_fast_ops, TC_H_ROOT);
+                                         &pfifo_fast_ops, TC_H_ROOT);
                if (!qdisc) {
                        printk(KERN_INFO "%s: activation failed\n", dev->name);
                        return;
@@ -550,9 +605,9 @@ void dev_activate(struct net_device *dev)
        int need_watchdog;
 
        /* No queueing discipline is attached to device;
-        * create default one i.e. fifo_fast for devices,
-        * which need queueing and noqueue_qdisc for
-        * virtual interfaces.
+          create default one i.e. pfifo_fast for devices,
+          which need queueing and noqueue_qdisc for
+          virtual interfaces
         */
 
        if (dev_all_qdisc_sleeping_noop(dev))
@@ -576,7 +631,6 @@ static void dev_deactivate_queue(struct net_device *dev,
                                 void *_qdisc_default)
 {
        struct Qdisc *qdisc_default = _qdisc_default;
-       struct sk_buff *skb = NULL;
        struct Qdisc *qdisc;
 
        qdisc = dev_queue->qdisc;
@@ -588,8 +642,6 @@ static void dev_deactivate_queue(struct net_device *dev,
 
                spin_unlock_bh(qdisc_lock(qdisc));
        }
-
-       kfree_skb(skb);
 }
 
 static bool some_qdisc_is_running(struct net_device *dev, int lock)
index 70ead8dc348591fc1494131120f4509fef372b95..4328ad5439c9fa014f10cea4e9d17ab6b9ffbffd 100644 (file)
@@ -71,6 +71,8 @@ static void sctp_mark_missing(struct sctp_outq *q,
 
 static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 sack_ctsn);
 
+static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout);
+
 /* Add data to the front of the queue. */
 static inline void sctp_outq_head_data(struct sctp_outq *q,
                                        struct sctp_chunk *ch)
@@ -712,7 +714,7 @@ int sctp_outq_uncork(struct sctp_outq *q)
  * locking concerns must be made.  Today we use the sock lock to protect
  * this function.
  */
-int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
+static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
 {
        struct sctp_packet *packet;
        struct sctp_packet singleton;
index 5dd89831eceba6ca38e3b187ac465c2cbf387dc6..f268910620be55d3b7122835fcd3b2ebe629b28f 100644 (file)
@@ -519,8 +519,3 @@ int __init sctp_remaddr_proc_init(void)
 
        return 0;
 }
-
-void sctp_assoc_proc_exit(void)
-{
-       remove_proc_entry("remaddr", proc_net_sctp);
-}
index 9392116e47b009e1ef02f69f85ecff247f5b78b8..e6cf7a43a297f9473b155add043b7bfab56c6938 100644 (file)
@@ -124,7 +124,7 @@ static int fw_setup_class_device(struct class_device *class_dev,
        class_dev->class_id[BUS_ID_SIZE-1] = '\0';
        class_dev->dev = device;
 
-       class_dev->class = &firmware_class,
+       class_dev->class = &firmware_class;
        class_set_devdata(class_dev, fw_priv);
        retval = class_device_register(class_dev);
        if (retval) {
index b0a1b4fe6584a026866233136d69d19bb3f9d468..7395c0bbae18426e119d47bb67e59da293228952 100644 (file)
@@ -211,7 +211,7 @@ static struct foo_obj *create_foo_obj(const char *name)
         */
        retval = kobject_init_and_add(&foo->kobj, &foo_ktype, NULL, "%s", name);
        if (retval) {
-               kfree(foo);
+               kobject_put(&foo->kobj);
                return NULL;
        }
 
index 17092d6c7db3c801c0e6b2979e3ccfab910415bc..9ee9783aea5700810ec575fe5de15936ae664ba2 100644 (file)
@@ -101,6 +101,7 @@ quiet_cmd_kernel-mod = MODPOST $@
       cmd_kernel-mod = $(modpost) $@
 
 vmlinux.o: FORCE
+       @rm -fr $(kernelmarkersfile)
        $(call cmd,kernel-mod)
 
 # Declare generated files as targets for modpost
index 37d5c363fbcd8f0008044a08414721f9710c7442..1fcaf3284a6a2990128f2589b5856cec3997097c 100644 (file)
@@ -340,11 +340,18 @@ static int do_acpi_entry(const char *filename,
 }
 
 /* looks like: "pnp:dD" */
-static int do_pnp_entry(const char *filename,
-                       struct pnp_device_id *id, char *alias)
+static void do_pnp_device_entry(void *symval, unsigned long size,
+                               struct module *mod)
 {
-       sprintf(alias, "pnp:d%s*", id->id);
-       return 1;
+       const unsigned long id_size = sizeof(struct pnp_device_id);
+       const struct pnp_device_id *id = symval;
+
+       device_id_check(mod->name, "pnp", size, id_size, symval);
+
+       buf_printf(&mod->dev_table_buf,
+                  "MODULE_ALIAS(\"pnp:d%s*\");\n", id->id);
+       buf_printf(&mod->dev_table_buf,
+                  "MODULE_ALIAS(\"acpi*:%s:*\");\n", id->id);
 }
 
 /* looks like: "pnp:dD" for every device of the card */
@@ -388,9 +395,12 @@ static void do_pnp_card_entries(void *symval, unsigned long size,
                        }
 
                        /* add an individual alias for every device entry */
-                       if (!dup)
+                       if (!dup) {
                                buf_printf(&mod->dev_table_buf,
                                           "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
+                               buf_printf(&mod->dev_table_buf,
+                                          "MODULE_ALIAS(\"acpi*:%s:*\");\n", id);
+                       }
                }
        }
 }
@@ -701,9 +711,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
                         sizeof(struct acpi_device_id), "acpi",
                         do_acpi_entry, mod);
        else if (sym_is(symname, "__mod_pnp_device_table"))
-               do_table(symval, sym->st_size,
-                        sizeof(struct pnp_device_id), "pnp",
-                        do_pnp_entry, mod);
+               do_pnp_device_entry(symval, sym->st_size, mod);
        else if (sym_is(symname, "__mod_pnp_card_device_table"))
                do_pnp_card_entries(symval, sym->st_size, mod);
        else if (sym_is(symname, "__mod_pcmcia_device_table"))
index a07f91aac920c66e081b925acb52b5c4d4874922..8f038e6d5f986b0ecf0202968559de646c08ea2f 100644 (file)
@@ -1992,7 +1992,8 @@ static void read_markers(const char *fname)
                        mod->skip = 1;
                }
 
-               add_marker(mod, marker, fmt);
+               if (!mod->skip)
+                       add_marker(mod, marker, fmt);
        }
        return;
 fail:
index 5c254d498ae094d452bb0c85a143f468eaedde0a..df46bbc25dc2da7dccf2872abbae76837693e3ba 100644 (file)
@@ -548,8 +548,9 @@ int snd_card_register(struct snd_card *card)
        snd_assert(card != NULL, return -EINVAL);
 #ifndef CONFIG_SYSFS_DEPRECATED
        if (!card->card_dev) {
-               card->card_dev = device_create(sound_class, card->dev, 0,
-                                              "card%i", card->number);
+               card->card_dev = device_create_drvdata(sound_class, card->dev,
+                                                      MKDEV(0, 0), NULL,
+                                                      "card%i", card->number);
                if (IS_ERR(card->card_dev))
                        card->card_dev = NULL;
        }
index a9c23b2502ad4399b9316a900462ba80bf6a3ae7..7d89c081a0866bfe9b7ee22696ee286007cb0a2a 100644 (file)
@@ -560,17 +560,19 @@ static int __init oss_init(void)
        sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
 
        for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
-               device_create(sound_class, NULL,
-                             MKDEV(SOUND_MAJOR, dev_list[i].minor),
-                             "%s", dev_list[i].name);
+               device_create_drvdata(sound_class, NULL,
+                                     MKDEV(SOUND_MAJOR, dev_list[i].minor),
+                                     NULL, "%s", dev_list[i].name);
 
                if (!dev_list[i].num)
                        continue;
 
                for (j = 1; j < *dev_list[i].num; j++)
-                       device_create(sound_class, NULL,
-                                     MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)),
-                                     "%s%d", dev_list[i].name, j);
+                       device_create_drvdata(sound_class, NULL,
+                                             MKDEV(SOUND_MAJOR,
+                                                   dev_list[i].minor + (j*0x10)),
+                                             NULL,
+                                             "%s%d", dev_list[i].name, j);
        }
 
        if (sound_nblocks >= 1024)
index 12f6ac99b04c4386b28f68cbcbe3d404b5cc2efe..9212c37a33b8c8a9275d43e3ddfd45eb34e54456 100644 (file)
@@ -48,6 +48,7 @@ config SND_PXA2XX_SOC_POODLE
 config SND_PXA2XX_SOC_TOSA
        tristate "SoC AC97 Audio support for Tosa"
        depends on SND_PXA2XX_SOC && MACH_TOSA
+       depends on MFD_TC6393XB
        select SND_PXA2XX_SOC_AC97
        select SND_SOC_WM9712
        help
index b6edb61a3a30f8591e89944d002fb7eff1c253ac..fe6cca9c9e760c0424e627e1f208130e47f372ce 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/device.h>
+#include <linux/gpio.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -28,7 +29,7 @@
 #include <sound/soc-dapm.h>
 
 #include <asm/mach-types.h>
-#include <asm/hardware/tmio.h>
+#include <asm/arch/tosa.h>
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/audio.h>
@@ -137,10 +138,7 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol,
 static int tosa_hp_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *k, int event)
 {
-       if (SND_SOC_DAPM_EVENT_ON(event))
-               set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE);
-       else
-               reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE);
+       gpio_set_value(TOSA_GPIO_L_MUTE, SND_SOC_DAPM_EVENT_ON(event) ? 1 :0);
        return 0;
 }
 
@@ -254,16 +252,28 @@ static int __init tosa_init(void)
        if (!machine_is_tosa())
                return -ENODEV;
 
+       ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack");
+       if (ret)
+               return ret;
+       gpio_direction_output(TOSA_GPIO_L_MUTE, 0);
+
        tosa_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!tosa_snd_device)
-               return -ENOMEM;
+       if (!tosa_snd_device) {
+               ret = -ENOMEM;
+               goto err_alloc;
+       }
 
        platform_set_drvdata(tosa_snd_device, &tosa_snd_devdata);
        tosa_snd_devdata.dev = &tosa_snd_device->dev;
        ret = platform_device_add(tosa_snd_device);
 
-       if (ret)
-               platform_device_put(tosa_snd_device);
+       if (!ret)
+               return 0;
+
+       platform_device_put(tosa_snd_device);
+
+err_alloc:
+       gpio_free(TOSA_GPIO_L_MUTE);
 
        return ret;
 }
@@ -271,6 +281,7 @@ static int __init tosa_init(void)
 static void __exit tosa_exit(void)
 {
        platform_device_unregister(tosa_snd_device);
+       gpio_free(TOSA_GPIO_L_MUTE);
 }
 
 module_init(tosa_init);
index dcfc1d5ce63173e5c636cc344d391889a1236611..1b04259a4328486357059acfd892bb3015285203 100644 (file)
@@ -171,8 +171,9 @@ static int sound_insert_unit(struct sound_unit **list, const struct file_operati
        else
                sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP);
 
-       device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor),
-                     s->name+6);
+       device_create_drvdata(sound_class, dev,
+                             MKDEV(SOUND_MAJOR, s->unit_minor),
+                             NULL, s->name+6);
        return r;
 
  fail: